From eaa9284d8ef6589efbf33c28569eb75faeda87a5 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 4 Oct 2024 20:54:05 +0530 Subject: [PATCH] MASA, OMASA, MC-paramupmix path functions and float code cleanup [x] Conversion & Integration of fb_mixer related functions, ivas_fb_mixer_pcm_ingest_fx, ivas_mc_paramupmix_dmx, computeIntensityVector_enc_fx, differential_coding_first_subframe [x] CPE-ENC cleanup [x] Intermediate conversions in ivas_compute_core_buffers cleanup [x] Convert functions in omasa_enc.c [x] ivas_qmetadata_enc_encode path changes --- lib_com/ivas_fb_mixer.c | 196 ++++- lib_com/ivas_prot.h | 25 + lib_com/ivas_prot_fx.h | 30 + lib_com/ivas_stat_com.h | 7 + lib_com/prot_fx.h | 7 + lib_com/tools_fx.c | 31 + lib_enc/init_enc.c | 4 +- lib_enc/ivas_core_enc.c | 5 - lib_enc/ivas_core_pre_proc.c | 785 +++++++++--------- lib_enc/ivas_cpe_enc.c | 84 +- lib_enc/ivas_dirac_enc.c | 26 + lib_enc/ivas_enc.c | 10 +- lib_enc/ivas_masa_enc.c | 338 +++++++- lib_enc/ivas_mc_paramupmix_enc.c | 221 +++++ lib_enc/ivas_omasa_enc.c | 293 ++++++- lib_enc/ivas_qmetadata_enc.c | 1184 +++++++++++++++++++++------ lib_enc/ivas_spar_encoder.c | 84 +- lib_enc/ivas_stat_enc.h | 86 +- lib_enc/ivas_stereo_dft_enc.c | 27 +- lib_enc/ivas_stereo_ica_enc.c | 3 - lib_enc/ivas_stereo_icbwe_enc.c | 9 + lib_enc/ivas_stereo_switching_enc.c | 2 +- lib_enc/ivas_stereo_td_enc.c | 94 ++- lib_enc/speech_music_classif_fx.c | 3 +- 24 files changed, 2738 insertions(+), 816 deletions(-) diff --git a/lib_com/ivas_fb_mixer.c b/lib_com/ivas_fb_mixer.c index bd8135d8e..1c6a82a99 100644 --- a/lib_com/ivas_fb_mixer.c +++ b/lib_com/ivas_fb_mixer.c @@ -359,6 +359,18 @@ ivas_error ivas_FB_mixer_open( { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder" ); } + +#ifdef IVAS_FLOAT_FIXED + if ( ( hFbMixer->ppFilterbank_inFR_re_fx[j] = (Word32 *) malloc( sizeof( Word32 ) * frame_len ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder" ); + } + + if ( ( hFbMixer->ppFilterbank_inFR_im_fx[j] = (Word32 *) malloc( sizeof( Word32 ) * frame_len ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder" ); + } +#endif } } @@ -378,7 +390,25 @@ ivas_error ivas_FB_mixer_open( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder" ); } set_f( hFbMixer->ppFilterbank_prior_input[i], 0, fb_cfg->prior_input_length ); +#ifdef IVAS_FLOAT_FIXED + IF( ( hFbMixer->ppFilterbank_prior_input_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * fb_cfg->prior_input_length ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder" ); + } + set32_fx( hFbMixer->ppFilterbank_prior_input_fx[i], 0, fb_cfg->prior_input_length ); +#endif + } + +#ifdef IVAS_FLOAT_FIXED + FOR( i = 0; i < num_chs_alloc; i++ ) + { + IF( ( hFbMixer->ppFilterbank_prior_input_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * fb_cfg->prior_input_length ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder" ); + } + set32_fx( hFbMixer->ppFilterbank_prior_input_fx[i], 0, fb_cfg->prior_input_length ); } +#endif if ( ( fb_cfg->active_w_mixing != -1 ) && ( fb_cfg->num_out_chans > 0 ) ) { @@ -788,6 +818,13 @@ void ivas_FB_mixer_close( free( hFbMixer->ppFilterbank_inFR_im[j] ); hFbMixer->ppFilterbank_inFR_im[j] = NULL; +#ifdef IVAS_FLOAT_FIXED + free( hFbMixer->ppFilterbank_inFR_re_fx[j] ); + hFbMixer->ppFilterbank_inFR_re_fx[j] = NULL; + + free( hFbMixer->ppFilterbank_inFR_im_fx[j] ); + hFbMixer->ppFilterbank_inFR_im_fx[j] = NULL; +#endif } } @@ -805,7 +842,13 @@ void ivas_FB_mixer_close( free( hFbMixer->ppFilterbank_prior_input[i] ); hFbMixer->ppFilterbank_prior_input[i] = NULL; } - +#ifdef IVAS_FLOAT_FIXED + for ( i = 0; i < num_chs_alloc; i++ ) + { + free( hFbMixer->ppFilterbank_prior_input_fx[i] ); + hFbMixer->ppFilterbank_prior_input_fx[i] = NULL; + } +#endif if ( ( fb_cfg->active_w_mixing != -1 ) && ( fb_cfg->num_out_chans > 0 ) ) { free( hFbMixer->prior_mixer[0][0] ); @@ -1043,8 +1086,78 @@ void ivas_fb_mixer_pcm_ingest( return; } +#ifdef IVAS_FLOAT_FIXED +void ivas_fb_mixer_pcm_ingest_fx( + IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle */ + Word32 *pcm_in[], /* i : input audio channels Qq_data_fix[] */ + Word32 **ppOut_pcm, /* o : output audio channels Qq_ppOut_pcm[] */ + const Word16 frame_len, /* i : frame length */ + const Word16 HOA_md_ind[IVAS_SPAR_MAX_CH], + Word16 q_data_fix[MAX_INPUT_CHANNELS + MAX_NUM_OBJECTS], + Word16 *q_ppOut_pcm ) +{ + Word16 i; + Word16 num_chs_ingest; + IVAS_FB_CFG *fb_cfg = hFbMixer->fb_cfg; + + IF( fb_cfg->active_w_mixing ) + { + num_chs_ingest = fb_cfg->num_in_chans; + move16(); + } + ELSE + { + num_chs_ingest = 1; /* forward Filterbank MDFT only on W */ + move16(); + } + + + FOR( i = 0; i < fb_cfg->num_in_chans; i++ ) + { + Word16 q_temp = s_min( hFbMixer->q_ppFilterbank_prior_input_fx[i], q_data_fix[HOA_md_ind[i]] ); + // mvr2r(&hFbMixer->ppFilterbank_prior_input[i][fb_cfg->prior_input_length - frame_len], ppOut_pcm[i], frame_len); + Copy32( &hFbMixer->ppFilterbank_prior_input_fx[i][fb_cfg->prior_input_length - frame_len], ppOut_pcm[i], frame_len ); + + IF( LT_16( q_temp, hFbMixer->q_ppFilterbank_prior_input_fx[i] ) ) + { + FOR( Word16 x = 0; x < frame_len; x++ ) + { + ppOut_pcm[i][x] = L_shr( ppOut_pcm[i][x], sub( hFbMixer->q_ppFilterbank_prior_input_fx[i], q_temp ) ); + move32(); + } + } + // mvr2r(pcm_in[HOA_md_ind[i]], &ppOut_pcm[i][frame_len], frame_len); + Copy32( pcm_in[HOA_md_ind[i]], &ppOut_pcm[i][frame_len], frame_len ); + + IF( LT_16( q_temp, q_data_fix[HOA_md_ind[i]] ) ) + { + FOR( Word16 x = frame_len; x < shl( frame_len, 1 ); x++ ) + { + ppOut_pcm[i][x] = L_shr( ppOut_pcm[i][x], sub( q_data_fix[HOA_md_ind[i]], q_temp ) ); + move32(); + } + } + q_ppOut_pcm[i] = q_temp; + move16(); + } + + Word16 guard_bits = find_guarded_bits_fx( shl( frame_len, 1 ) ); + + FOR( i = 0; i < num_chs_ingest; i++ ) + { + Word16 q_shift = sub( getScaleFactor32( ppOut_pcm[fb_cfg->remix_order[i]], shl( frame_len, 1 ) ), guard_bits ); + Scale_sig32( ppOut_pcm[fb_cfg->remix_order[i]], shl( frame_len, 1 ), q_shift ); + q_ppOut_pcm[fb_cfg->remix_order[i]] = add( q_ppOut_pcm[fb_cfg->remix_order[i]], q_shift ); + + ivas_mdft_fx( ppOut_pcm[fb_cfg->remix_order[i]], hFbMixer->ppFilterbank_inFR_re_fx[fb_cfg->remix_order[i]], hFbMixer->ppFilterbank_inFR_im_fx[fb_cfg->remix_order[i]], shl( frame_len, 1 ), frame_len ); + } + + return; +} +#endif + /*-----------------------------------------------------------------------------------------* * Function ivas_fb_mixer_update_prior_input() * @@ -1069,6 +1182,26 @@ void ivas_fb_mixer_update_prior_input( return; } +#ifdef IVAS_FLOAT_FIXED +void ivas_fb_mixer_update_prior_input_fx( + IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle */ + Word32 *pcm_in_fx[], /* i : input audio channels */ + const Word16 length, /* i : length of time slot */ + const Word16 nchan_fb_in /* i : number of analysis channels */ +) +{ + Word16 i; + + FOR( i = 0; i < nchan_fb_in; i++ ) + { + Copy32( &hFbMixer->ppFilterbank_prior_input_fx[i][length], hFbMixer->ppFilterbank_prior_input_fx[i], hFbMixer->fb_cfg->prior_input_length - length ); + Copy32( pcm_in_fx[i], &hFbMixer->ppFilterbank_prior_input_fx[i][hFbMixer->fb_cfg->prior_input_length - length], length ); + } + + return; +} +#endif + /*-----------------------------------------------------------------------------------------* * Function ivas_fb_mixer_get_windowed_fr() @@ -1076,6 +1209,61 @@ void ivas_fb_mixer_update_prior_input( * *-----------------------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_fb_mixer_get_windowed_fr_fx( + IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle */ + Word32 *pcm_in_fx[], + Word32 *frame_f_real_fx[], + Word32 *frame_f_imag_fx[], + const Word16 length, /* i : number of new samples in time slot */ + const Word16 mdft_len, /* i : MDFT frame length */ + const Word16 nchan_fb_in, /* i : number of analysis channels */ + Word16 gb ) +{ + Word16 ch_idx, j, offset, rev_offset; + Word16 n_old_samples; + Word16 n_new_samples; + Word32 fr_in_block_fx[L_FRAME48k * 2]; + const Word16 *win_ptr_fx; + + n_old_samples = s_min( ( sub( hFbMixer->fb_cfg->prior_input_length, hFbMixer->fb_cfg->windowed_fr_offset ) ), ( shl( mdft_len, 1 ) ) ); + n_new_samples = s_max( 0, sub( shl( length, 1 ), n_old_samples ) ); + offset = (Word16) ( sub( sub( shl( mdft_len, 1 ), length ), hFbMixer->ana_window_offset ) ); + rev_offset = (Word16) ( sub( shl( mdft_len, 1 ), hFbMixer->ana_window_offset ) ); + set32_fx( fr_in_block_fx, 0, offset ); + + FOR( ch_idx = 0; ch_idx < nchan_fb_in; ch_idx++ ) + { + Copy32( &hFbMixer->ppFilterbank_prior_input_fx[ch_idx][offset + hFbMixer->fb_cfg->windowed_fr_offset], &fr_in_block_fx[offset], n_old_samples - offset ); + Copy32( pcm_in_fx[ch_idx], &fr_in_block_fx[n_old_samples], n_new_samples ); + + win_ptr_fx = hFbMixer->pAna_window_fx; /*Q15*/ + + FOR( j = offset; j < sub( shl( mdft_len, 1 ), length ); j++ ) + { + fr_in_block_fx[j] = Mpy_32_16_1( fr_in_block_fx[j], ( *( win_ptr_fx++ ) ) ); + move16(); + } + + FOR( j = rev_offset; j < shl( mdft_len, 1 ); j++ ) + { + fr_in_block_fx[j] = Mpy_32_16_1( fr_in_block_fx[j], ( *( --win_ptr_fx ) ) ); + move16(); + } + + FOR( Word16 i = 0; i < shl( mdft_len, 1 ); i++ ) + { + fr_in_block_fx[i] = L_shr( fr_in_block_fx[i], gb ); + move16(); + } + + ivas_mdft_fx( fr_in_block_fx, frame_f_real_fx[ch_idx], frame_f_imag_fx[ch_idx], mdft_len << 1, mdft_len ); + } + + return; +} +#endif + void ivas_fb_mixer_get_windowed_fr( IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle */ float *pcm_in[], /* i : input audio channels */ @@ -2056,6 +2244,12 @@ static ivas_error ivas_filterbank_setup( { return error; } +#ifdef IVAS_FLOAT_FIXED + IF( ( error = ivas_fb_mixer_get_window_fx( pCfg->fb_latency, sampling_rate, &( hFbMixer->pAna_window_fx ) ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif if ( ( error = ivas_fb_mixer_get_window( pCfg->fade_len, sampling_rate, &( hFbMixer->pFilterbank_cross_fade ) ) ) != IVAS_ERR_OK ) { diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 8cbf56769..8c011856b 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -5155,12 +5155,22 @@ void calculate_hodirac_sector_parameters( float *ene /* o : array of sector energy values, flat */ ); +#ifdef IVAS_FLOAT_FIXED void ivas_mc_paramupmix_enc( Encoder_Struct *st_ivas, /* i/o: IVAS Encoder handle */ BSTR_ENC_HANDLE hMetaData, /* i/o: IVAS Metadata bitstream handle */ float *data_f[], /* i/o: input/transport MC data */ + Word32 *data_fx[], const int16_t input_frame /* i : input frame length */ ); +#else +void ivas_mc_paramupmix_enc( + Encoder_Struct *st_ivas, /* i/o: IVAS Encoder handle */ + BSTR_ENC_HANDLE hMetaData, /* i/o: IVAS Metadata bitstream handle */ + float *data_f[], /* i/o: input/transport MC data */ + const int16_t input_frame /* i : input frame length */ +); +#endif ivas_error ivas_mc_paramupmix_enc_open( Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ @@ -7932,12 +7942,15 @@ ivas_error ivas_omasa_dec_config( int16_t *data /* o : output synthesis signal */ ); +#ifndef IVAS_FLOAT_FIXED void ivas_omasa_set_config( OMASA_ENC_HANDLE hOMasa, /* i/o: OMASA encoder handle */ MASA_ENCODER_HANDLE hMasa, /* i : MASA encoder handle */ const int32_t input_Fs, /* i : Input sample rate */ const ISM_MODE ism_mode /* i : ISM mode */ ); +#endif // !IVAS_FLOAT_FIXED + void ivas_omasa_enc( OMASA_ENC_HANDLE hOMasa, /* i/o: OMASA encoder handle */ @@ -7985,6 +7998,7 @@ void ivas_set_ism_importance_interformat( int16_t ism_imp[] /* o : ISM importance flags */ ); +#ifndef IVAS_FLOAT_FIXED /*! r: flag for using less bitrate for objects in OMASA */ int16_t ivas_omasa_ener_brate( const int16_t nchan_ism, /* i : number of ISMs */ @@ -7992,6 +8006,7 @@ int16_t ivas_omasa_ener_brate( float *data_f[], /* i : Input / transport audio signals */ const int16_t input_frame /* i : Input frame size */ ); +#endif // !IVAS_FLOAT_FIXED /*! r: adjusted bitrate */ int32_t ivas_interformat_brate( @@ -8220,6 +8235,16 @@ void ivas_fb_mixer_pcm_ingest( const int16_t frame_length, /* i : frame length */ const int16_t HOA_md_ind[IVAS_SPAR_MAX_CH] ); +#ifdef IVAS_FLOAT_FIXED +void ivas_fb_mixer_pcm_ingest_fx( + IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle */ + Word32 *pcm_in[], /* i : input audio channels Qq_data_fix[] */ + Word32 **ppOut_pcm, /* o : output audio channels Qq_ppOut_pcm[] */ + const Word16 frame_len, /* i : frame length */ + const Word16 HOA_md_ind[IVAS_SPAR_MAX_CH], + Word16 q_data_fix[MAX_INPUT_CHANNELS + MAX_NUM_OBJECTS], + Word16 *q_ppOut_pcm ); +#endif void ivas_fb_mixer_update_prior_input( IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle */ diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index b3b2914fc..532d4e5e0 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -3092,4 +3092,34 @@ ISM_MODE ivas_ism_mode_select( const Word16 nchan_inp, /* i : number of input objects */ const Word32 ivas_total_brate /* i : IVAS total bitrate */ ); + +void ivas_fb_mixer_update_prior_input_fx( + IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle */ + Word32 *pcm_in_fx[], /* i : input audio channels */ + const Word16 length, /* i : length of time slot */ + const Word16 nchan_fb_in /* i : number of analysis channels */ +); + +void ivas_fb_mixer_get_windowed_fr_fx( + IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle */ + Word32 *pcm_in_fx[], + Word32 *frame_f_real_fx[], + Word32 *frame_f_imag_fx[], + const int16_t length, /* i : number of new samples in time slot */ + const int16_t mdft_len, /* i : MDFT frame length */ + const int16_t nchan_fb_in, /* i : number of analysis channels */ + Word16 gb ); +void ivas_omasa_set_config_fx( + OMASA_ENC_HANDLE hOMasa, /* i/o: OMASA encoder handle */ + MASA_ENCODER_HANDLE hMasa, /* i : MASA encoder handle */ + const Word32 input_Fs, /* i : Input sample rate */ + const ISM_MODE ism_mode /* i : ISM mode */ +); +Word16 ivas_omasa_ener_brate_fx( + const Word16 nchan_ism, /* i : number of ISMs */ + const Word32 ivas_total_brate, /* i : IVAS total bitrate */ + Word32 *data_f[], /* i : Input / transport audio signals */ + const Word16 input_frame, /* i : Input frame size */ + Word16 data_e /*i:exponent for data_f */ +); #endif diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index a4337b805..e0a60ea7d 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -552,6 +552,10 @@ typedef struct ivas_qdirection_band_data_struct uint16_t elevation_index[MAX_PARAM_SPATIAL_SUBFRAMES]; float q_azimuth[MAX_PARAM_SPATIAL_SUBFRAMES]; float q_elevation[MAX_PARAM_SPATIAL_SUBFRAMES]; +#ifdef IVAS_FLOAT_FIXED + Word32 q_azimuth_fx[MAX_PARAM_SPATIAL_SUBFRAMES]; /* Q22 */ + Word32 q_elevation_fx[MAX_PARAM_SPATIAL_SUBFRAMES]; /* Q22 */ +#endif } IVAS_QDIRECTION_BAND_DATA; @@ -855,6 +859,9 @@ typedef struct ivas_fb_mixer_state_structure Word32 *ppFilterbank_inFR_re_fx[IVAS_MAX_FB_MIXER_IN_CH]; Word32 *ppFilterbank_inFR_im_fx[IVAS_MAX_FB_MIXER_IN_CH]; Word32 *ppFilterbank_prior_input_fx[IVAS_MAX_FB_MIXER_IN_CH]; + Word16 q_ppFilterbank_inFR_re_fx[IVAS_MAX_FB_MIXER_IN_CH]; + Word16 q_ppFilterbank_inFR_im_fx[IVAS_MAX_FB_MIXER_IN_CH]; + Word16 q_ppFilterbank_prior_input_fx[IVAS_MAX_FB_MIXER_IN_CH]; Word32 *prior_mixer_fx[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH]; #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 93723ad48..b70c23b94 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -10138,6 +10138,13 @@ Word16 squant_fx( /* o: index of the winning codeword */ const Word16 cbsize /* i: codebook size */ ); +Word16 squant_int_fx( + UWord8 x, /* i : scalar value to quantize */ + UWord8 *xq, /* o : quantized value */ + const UWord8 *cb, /* i : codebook */ + const Word16 cbsize /* i : codebook size */ +); + void pz_filter_dp_fx( const Word16 b[], const Word16 a[], diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 3015cdf21..92b4048d4 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -2701,6 +2701,37 @@ Word16 squant_fx( /* o: index of the winning codeword */ return idx; } +/*! r: index of the winning codeword */ +Word16 squant_int_fx( + UWord8 x, /* i : scalar value to quantize */ + UWord8 *xq, /* o : quantized value */ + const UWord8 *cb, /* i : codebook */ + const Word16 cbsize /* i : codebook size */ +) +{ + Word16 i, idx; + Word32 mindist, d; + + idx = 0; + move16(); + mindist = 10000000; // Q0 + move32(); + FOR( i = 0; i < cbsize; i++ ) + { + d = L_mult0( sub( x, cb[i] ), sub( x, cb[i] ) ); + IF( LT_32( d, mindist ) ) + { + mindist = d; + move32(); + idx = i; + move16(); + } + } + *xq = cb[idx]; + move16(); + + return idx; +} /*===================================================================*/ /* FUNCTION : pz_filter_dp_fx () */ diff --git a/lib_enc/init_enc.c b/lib_enc/init_enc.c index 18335a91b..c1fabe13e 100644 --- a/lib_enc/init_enc.c +++ b/lib_enc/init_enc.c @@ -327,10 +327,10 @@ ivas_error init_encoder( st->old_inp_12k8 = st->hSignalBuf->old_inp_12k8_flt; st->old_inp_16k = st->hSignalBuf->old_inp_16k_flt; #ifdef IVAS_FLOAT_FIXED - st->Bin_E_old_fx = st->hSignalBuf->Bin_E_old_fx; + st->mem_decim_fx = st->hSignalBuf->mem_decim_fx; + st->mem_decim16k_fx = st->hSignalBuf->mem_decim16k_fx; st->old_inp_12k8_fx = st->hSignalBuf->old_inp_12k8_fx; st->old_inp_16k_fx = st->hSignalBuf->old_inp_16k_fx; - st->mem_decim_fx = st->hSignalBuf->mem_decim_fx; #endif st->buf_speech_enc_pe_flt = st->hSignalBuf->buf_speech_enc_pe_flt; st->buf_synth_flt = st->hSignalBuf->buf_synth_flt; diff --git a/lib_enc/ivas_core_enc.c b/lib_enc/ivas_core_enc.c index 75395ce84..c71606d0a 100644 --- a/lib_enc/ivas_core_enc.c +++ b/lib_enc/ivas_core_enc.c @@ -994,9 +994,6 @@ ivas_error ivas_core_enc( { f2me_buf( hCPE->hStereoDft->DFT[0], hCPE->hStereoDft->DFT_fx[0], &hCPE->hStereoDft->DFT_fx_e[0], STEREO_DFT_N_MAX_ENC ); f2me_buf( hCPE->hStereoDft->DFT[1], hCPE->hStereoDft->DFT_fx[1], &hCPE->hStereoDft->DFT_fx_e[1], STEREO_DFT_N_MAX_ENC ); - f2me( hCPE->hStereoDft->icbweRefEner, &hCPE->hStereoDft->icbweRefEner_fx, &hCPE->hStereoDft->icbweRefEner_fx_e ); - f2me( hCPE->hStereoDft->lbEner, &hCPE->hStereoDft->lbEner_fx, &hCPE->hStereoDft->lbEner_fx_e ); - f2me( hCPE->hStereoDft->icbweRefEner, &hCPE->hStereoDft->icbweRefEner_fx, &hCPE->hStereoDft->icbweRefEner_fx_e ); floatToFixed_arrL( hCPE->hStereoDft->output_mem_res_8k, hCPE->hStereoDft->output_mem_res_8k_fx, 16, STEREO_DFT_OVL_8k ); floatToFixed_arrL( hCPE->hStereoDft->output_mem_dmx, hCPE->hStereoDft->output_mem_dmx_fx, 16, STEREO_DFT_OVL_MAX ); floatToFixed_arrL( hCPE->hStereoDft->output_mem_dmx_12k8, hCPE->hStereoDft->output_mem_dmx_12k8_fx, 16, STEREO_DFT_OVL_12k8 ); @@ -1049,8 +1046,6 @@ ivas_error ivas_core_enc( if ( st->element_mode == IVAS_CPE_DFT ) { - hCPE->hStereoDft->icbweRefEner = me2f( hCPE->hStereoDft->icbweRefEner_fx, hCPE->hStereoDft->icbweRefEner_fx_e ); - hCPE->hStereoDft->lbEner = me2f( hCPE->hStereoDft->lbEner_fx, hCPE->hStereoDft->lbEner_fx_e ); hCPE->hStereoICBWE->icbweRefEner = me2f( hCPE->hStereoICBWE->icbweRefEner_fx, hCPE->hStereoICBWE->icbweRefEner_fx_e ); fixedToFloat_arrL( hCPE->hStereoDft->output_mem_res_8k_fx, hCPE->hStereoDft->output_mem_res_8k, 16, STEREO_DFT_OVL_8k ); fixedToFloat_arrL( hCPE->hStereoDft->output_mem_dmx_fx, hCPE->hStereoDft->output_mem_dmx, 16, STEREO_DFT_OVL_MAX ); diff --git a/lib_enc/ivas_core_pre_proc.c b/lib_enc/ivas_core_pre_proc.c index e0dda8f53..12a7d1d8d 100644 --- a/lib_enc/ivas_core_pre_proc.c +++ b/lib_enc/ivas_core_pre_proc.c @@ -1105,8 +1105,8 @@ ivas_error ivas_compute_core_buffers( float *inp_16k, *new_inp_16k; #ifndef IVAS_FLOAT_FIXED float tmp; -#endif float mem_decim16k_dummy[2 * L_FILT_MAX]; +#endif /*const*/ float *signal_in; int16_t delay, element_mode; #ifdef IVAS_FLOAT_FIXED @@ -1123,35 +1123,59 @@ ivas_error ivas_compute_core_buffers( signal_in = st->input; #ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 new_inp_resamp16k_fx[L_FRAME16k], tmp_fx; + Word16 Q_tmp, mem_decim16k_size, size_modified; + Word16 old_inp_16k_fx[L_INP]; + // Word16 Q_old_inp_16k = 0; + Word16 Q_old_inp_16k = -1; + Word16 *inp_16k_fx, *new_inp_16k_fx; + Word32 epsP_fx[M + 1]; + Word16 epsP_h[M + 1] = { 0 }; + Word16 epsP_l[M + 1] = { 0 }; + Word16 Q_r[2] = { 0 }; + Word32 ener_fx = 0; + Word16 inp16k_out_buf_fx[2][L_FRAME16k]; + Word16 **inp16k_out_fx = (Word16 **) inp16k_out_buf_fx; + Word16 new_inp_resamp16k_out_fx[L_FRAME16k]; + signal_in_32fx = st->input32_fx; signal_in_fx = st->input_fx; - Word16 Q_sig = -1; - move16(); - floatToFixed_arr( signal_in, signal_in_fx, Q_sig, 960 ); + + /* + !!!! ALL BUFFERS CONSIDERED IN Q(-1) for now !!!! + */ + // st->mem_preemph_enc = float_to_fix16( st->mem_preemph_enc_flt, Q_old_inp_16k ); + // st->mem_preemph16k_fx = float_to_fix16( st->mem_preemph16k, Q_old_inp_16k ); + // st->mem_preemph16k_DFT_fx = float_to_fix16( st->mem_preemph16k_DFT, Q_old_inp_16k ); + // st->mem_wsp_enc = float_to_fix16( st->mem_wsp_enc_flt, Q_old_inp_16k ); + + st->mem_preemph_enc = (Word16) floatToFixed( st->mem_preemph_enc_flt, Q_old_inp_16k ); + st->mem_preemph16k_fx = (Word16) floatToFixed( st->mem_preemph16k, Q_old_inp_16k ); + st->mem_preemph16k_DFT_fx = (Word16) floatToFixed( st->mem_preemph16k_DFT, Q_old_inp_16k ); + st->mem_wsp_enc = (Word16) floatToFixed( st->mem_wsp_enc_flt, Q_old_inp_16k ); + floatToFixed_arrL( signal_in, signal_in_32fx, Q11, 960 ); - Word16 mem_decim16k_fx[2 * L_FILT_MAX], exp_mem_decim16k = 0, Q_mem_decim16k = 0; - move16(); - move16(); - f2me_buf_16( st->mem_decim16k, mem_decim16k_fx, &exp_mem_decim16k, 2 * L_FILT_MAX ); - Q_mem_decim16k = sub( 15, exp_mem_decim16k ); - Word16 flag = 0; - FOR( Word16 i = 0; i < L_INP; i++ ) - { - IF( mem_decim16k_fx[i] != 0 ) - { - flag = 1; - move16(); - break; - } - } - if ( flag == 0 ) + floatToFixed_arr16( old_inp_16k, old_inp_16k_fx, Q_old_inp_16k, L_INP ); + floatToFixed_arr16( signal_in, signal_in_fx, Q_old_inp_16k, 960 ); + floatToFixed_arr16( new_inp_resamp16k, new_inp_resamp16k_fx, Q_old_inp_16k, L_FRAME16k ); + + floatToFixed_arr16( st->old_inp_16k, st->old_inp_16k_fx, Q_old_inp_16k, L_INP_MEM ); + floatToFixed_arr16( st->mem_decim16k, st->mem_decim16k_fx, Q_old_inp_16k, 2 * L_FILT_MAX ); + floatToFixed_arr16( st->inp_16k_mem_stereo_sw, st->inp_16k_mem_stereo_sw_fx, Q_old_inp_16k, STEREO_DFT_OVL_16k - L_MEM_RECALC_16K - L_FILT16k ); + floatToFixed_arr16( st->buf_speech_enc_flt, st->buf_speech_enc, Q_old_inp_16k, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k ); + floatToFixed_arr16( st->buf_speech_enc_pe_flt, st->buf_speech_enc_pe, Q_old_inp_16k, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k ); // Should take care of st->speech_enc_pe as wel + floatToFixed_arr16( st->buf_wspeech_enc_flt, st->buf_wspeech_enc, Q_old_inp_16k, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320 ); // Should take care of st->wspeech_enc + // wspeech_enc + + if ( st->hBWE_FD != NULL ) { - exp_mem_decim16k = 15; - Q_mem_decim16k = 0; - move16(); - move16(); + floatToFixed_arr16( st->hBWE_FD->old_wtda_swb, st->hBWE_FD->L_old_wtda_swb_fx, Q_old_inp_16k, L_FRAME48k ); + st->Q_old_wtda = -1; // This reset needs to be looked into + floatToFixed_arr16( st->hBWE_FD->old_input_wb, st->hBWE_FD->old_input_wb_fx, -1, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); } +#endif #endif input_Fs = st->input_Fs; @@ -1159,7 +1183,7 @@ ivas_error ivas_compute_core_buffers( lMemRecalc_16k = 0; lMemRecalc = 0; - if ( element_mode == IVAS_CPE_TD ) + IF( EQ_16( element_mode, IVAS_CPE_TD ) ) { lMemRecalc_16k = NS2SA( INT_FS_16k, L_MEM_RECALC_NS ); lMemRecalc = NS2SA( input_Fs, L_MEM_RECALC_NS ); @@ -1173,43 +1197,26 @@ ivas_error ivas_compute_core_buffers( L_look = NS2SA( sr_core, ACELP_LOOK_NS ); /* lookahead at other sampling rate (16kHz, 25.6kHz, 32kHz) */ -#ifdef IVAS_FLOAT_FIXED - Word16 old_inp_16k_fx[L_INP], exp_old_inp_16k = 0, Q_old_inp_16k = 0; - move16(); - move16(); - Word16 *new_inp_16k_fx; - - f2me_buf_16( old_inp_16k, old_inp_16k_fx, &exp_old_inp_16k, L_INP ); - Word16 flag1 = 0; - move16(); - FOR( Word16 i = 0; i < L_INP; i++ ) - { - IF( old_inp_16k_fx[i] != 0 ) - { - flag1 = 1; - break; - } - } - if ( flag1 == 0 ) - { - exp_old_inp_16k = 15; - move16(); - } - new_inp_16k_fx = old_inp_16k_fx + L_INP_MEM; /* pointer to new samples of the input signal in 16kHz core */ -#endif +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS new_inp_16k = old_inp_16k + L_INP_MEM; /* pointer to new samples of the input signal in 16kHz core */ - inp_16k = new_inp_16k - L_look; /* pointer to the current frame of input signal in 16kHz core */ +#endif + inp_16k_fx = new_inp_16k_fx - L_look; /* pointer to the current frame of input signal in 16kHz core */ +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + inp_16k = new_inp_16k - L_look; /* pointer to the current frame of input signal in 16kHz core */ +#endif /* shift the pointer back to take care of resampler memory update */ - if ( element_mode == IVAS_CPE_TD || element_mode == IVAS_SCE ) + test(); + IF( EQ_16( element_mode, IVAS_CPE_TD ) || EQ_16( element_mode, IVAS_SCE ) ) { +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS new_inp_16k -= NS2SA( sr_core, DELAY_FIR_RESAMPL_NS ); -#ifdef IVAS_FLOAT_FIXED - new_inp_16k_fx -= NS2SA( sr_core, DELAY_FIR_RESAMPL_NS ); #endif + new_inp_16k_fx -= NS2SA( sr_core, DELAY_FIR_RESAMPL_NS ); } +#ifndef IVAS_FLOAT_FIXED if ( element_mode == IVAS_CPE_DFT ) { mvr2r( st->old_inp_16k, old_inp_16k, L_INP_MEM - STEREO_DFT_OVL_16k ); @@ -1222,275 +1229,26 @@ ivas_error ivas_compute_core_buffers( { mvr2r( st->old_inp_16k, old_inp_16k, L_INP_MEM - L_FILT16k ); } - - /*---------------------------------------------------------------* - * Change the sampling frequency to 16/25.6/32 kHz - *----------------------------------------------------------------*/ -#ifdef IVAS_FLOAT_FIXED - Word16 Q_new_inp_16k = 0, prev_Q_mem_decim16k = 0, Q_mem_decim16k_dummy = 0; - move16(); - move16(); - move16(); - Word16 size_mem_decim16k_dummy = 0, length_new_inp_16k = 0, mem_decim16k_size = 0; - move16(); - move16(); - move16(); - /*handle multiple modify_Fs calls updating differnt portions of new_inp_16k_fx*/ - Word16 len_1 = 0, len_2 = 0, len_3 = 0, len_4 = 0; - move16(); - move16(); - move16(); - move16(); - Word16 Q_len_1 = 0, Q_len_2 = 0, Q_len_3 = 0, Q_len_4 = 0; - move16(); - move16(); - move16(); - move16(); -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - IF( EQ_16( element_mode, IVAS_SCE ) ) +#else + IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) { - floatToFixed_arr32( signal_in, signal_in_32fx, Q11, 960 ); - floatToFixed_arr( signal_in, signal_in_fx, -1, 960 ); + Copy( st->old_inp_16k_fx, old_inp_16k_fx, L_INP_MEM - STEREO_DFT_OVL_16k ); } ELSE IF( EQ_16( element_mode, IVAS_CPE_TD ) ) { - IF( EQ_32( input_Fs, sr_core ) ) - { - floatToFixed_arr32( signal_in - lMemRecalc, signal_in_32fx - lMemRecalc, Q11, lMemRecalc + 960 ); - floatToFixed_arr( signal_in - lMemRecalc, signal_in_fx - lMemRecalc, -1, lMemRecalc + 960 ); - } - ELSE IF( EQ_32( input_Fs, 32000 ) || EQ_32( input_Fs, 48000 ) ) - { - Word16 length_inp_tmp = NS2SA( input_Fs, L_MEM_RECALC_SCH_NS - DELAY_FIR_RESAMPL_NS ); - floatToFixed_arr32( signal_in - lMemRecalc - length_inp_tmp - 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), signal_in_32fx - lMemRecalc - length_inp_tmp - 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), Q11, lMemRecalc + length_inp_tmp + 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ) + 960 ); - floatToFixed_arr( signal_in - lMemRecalc - length_inp_tmp - 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), signal_in_fx - lMemRecalc - length_inp_tmp - 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), -1, lMemRecalc + length_inp_tmp + 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ) + 960 ); - - floatToFixed_arr32( signal_in - lMemRecalc + input_frame, signal_in_32fx - lMemRecalc + input_frame, Q11, lMemRecalc ); - floatToFixed_arr( signal_in - lMemRecalc + input_frame, signal_in_fx - lMemRecalc + input_frame, -1, lMemRecalc ); - } + Copy( st->old_inp_16k_fx, old_inp_16k_fx, L_INP_MEM - L_MEM_RECALC_16K - L_FILT16k ); } - ELSE IF( st->idchan == 0 ) + ELSE { - floatToFixed_arr( signal_in + input_frame - NS2SA( input_Fs, L_MEM_RECALC_NS ) - 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), signal_in_fx + input_frame - NS2SA( input_Fs, L_MEM_RECALC_NS ) - 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), -1, 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ) ); + Copy( st->old_inp_16k_fx, old_inp_16k_fx, L_INP_MEM - L_FILT16k ); } #endif - IF( EQ_16( element_mode, IVAS_SCE ) ) - { - test(); - IF( EQ_32( input_Fs, sr_core ) ) - { - /* no resampling needed, only delay adjustment to account for the FIR resampling delay */ - delay = NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ); - move16(); - prev_Q_mem_decim16k = Q_mem_decim16k; - move16(); - Copy( mem_decim16k_fx + delay, new_inp_16k_fx, delay ); - Copy( signal_in_fx, new_inp_16k_fx + delay, input_frame ); - Copy( signal_in_fx + input_frame - shl( delay, 1 ), mem_decim16k_fx, shl( delay, 1 ) ); - Q_mem_decim16k = Q_sig; - move16(); - } - ELSE IF( EQ_32( input_Fs, 32000 ) || EQ_32( input_Fs, 48000 ) ) - { - Word16 scale_factor = sub( getScaleFactor16( signal_in_fx, 960 ), 1 ); - Copy_Scale_sig32_16( signal_in_32fx, signal_in_fx, 960, 16 - Q11 - 1 + scale_factor ); /*-1+scale_factor*/ - Q_sig = sub( scale_factor, 1 ); - - Scale_sig( mem_decim16k_fx, 2 * L_FILT_MAX, sub( sub( scale_factor, 1 ), sub( 15, exp_mem_decim16k ) ) ); - exp_mem_decim16k = sub( 15, add( sub( Q_sig, 1 ), scale_factor ) ); - - mem_decim16k_size = 2 * L_FILT_MAX; - Word16 Q_tmp = 0; - move16(); - Word16 size_new_inp_16k_fx = modify_Fs_fx( signal_in_fx, input_frame, input_Fs, new_inp_16k_fx, sr_core, mem_decim16k_fx, 0, &Q_tmp, &mem_decim16k_size ); - Q_old_inp_16k = add( sub( Q_tmp, 1 ), scale_factor ); - - Copy( mem_decim16k_fx, mem_decim16k_dummy_fx, 2 * L_FILT_MAX ); - set16_fx( temp1F_icatdmResampBuf_fx, 0, L_FILT_MAX ); - Word16 Q_tmp1 = 0; - move16(); - size_mem_decim16k_dummy = 2 * L_FILT_MAX; - move16(); - Word16 size_temp1F_icatdmResampBuf = modify_Fs_fx( temp1F_icatdmResampBuf_fx, NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), input_Fs, new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ), sr_core, mem_decim16k_dummy_fx, 0, &Q_tmp1, &size_mem_decim16k_dummy ); - - length_new_inp_16k = s_max( size_new_inp_16k_fx, size_temp1F_icatdmResampBuf ); - Q_old_inp_16k = add( sub( Q_tmp1, 1 ), scale_factor ); - Q_mem_decim16k = sub( scale_factor, 1 ); - } - } - ELSE IF( EQ_16( element_mode, IVAS_CPE_TD ) ) - { - test(); - IF( EQ_32( input_Fs, sr_core ) ) - { - /* no resampling needed, only delay adjustment to account for the FIR resampling delay */ - delay = NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ); - prev_Q_mem_decim16k = Q_mem_decim16k; - move16(); - Copy( mem_decim16k_fx + delay, new_inp_16k_fx - sub( lMemRecalc, add( delay, L_FILT16k ) ), delay ); - Copy( signal_in_fx - lMemRecalc, new_inp_16k_fx - add( lMemRecalc, L_FILT16k ), add( input_frame, lMemRecalc ) ); - Copy( signal_in_fx + sub( sub( input_frame, lMemRecalc ), shl( delay, 1 ) ), mem_decim16k_fx, shl( delay, 1 ) ); - Q_mem_decim16k = Q_sig; - move16(); - } - ELSE IF( EQ_32( input_Fs, 32000 ) || EQ_32( input_Fs, 48000 ) ) - { - /* reconstruct past segment of input signal when switching from MDCT stereo */ - IF( EQ_16( last_element_mode, IVAS_CPE_MDCT ) /*|| st->idchan == 1*/ ) - { - Word16 length_inp = NS2SA_FX2( input_Fs, L_MEM_RECALC_SCH_NS - DELAY_FIR_RESAMPL_NS ); - Word16 length_16k = NS2SA_FX2( INT_FS_16k, L_MEM_RECALC_SCH_NS - DELAY_FIR_RESAMPL_NS ); - - Word16 scale_factor = getScaleFactor16( signal_in_fx - lMemRecalc - length_inp - 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), lMemRecalc + length_inp + 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ) + 960 ) - 1; - Copy_Scale_sig32_16( signal_in_32fx - lMemRecalc - length_inp - 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), signal_in_fx - lMemRecalc - length_inp - 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), lMemRecalc + length_inp + 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ) + 960, 16 - Q11 - 1 + scale_factor ); /*-1+scale_factor*/ - Q_sig = sub( scale_factor, 1 ); - - Copy( signal_in_fx - lMemRecalc - length_inp - 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), mem_decim16k_fx, 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ) ); - mem_decim16k_size = 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ); - Word16 Q_tmp = 0; - - length_new_inp_16k = modify_Fs_fx( signal_in_fx - lMemRecalc - length_inp - 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), length_inp, input_Fs, new_inp_16k_fx - lMemRecalc_16k - length_16k, sr_core, mem_decim16k_fx, 0, &Q_tmp, &mem_decim16k_size ); - len_1 = length_new_inp_16k; - Q_new_inp_16k = add( sub( Q_tmp, 1 ), scale_factor ); - Q_len_1 = Q_new_inp_16k; - Q_mem_decim16k = sub( scale_factor, 1 ); - } - - Word16 scale_factor = getScaleFactor16( signal_in_fx - lMemRecalc, lMemRecalc + 960 ) - 1; - Copy_Scale_sig32_16( signal_in_32fx - lMemRecalc, signal_in_fx - lMemRecalc, lMemRecalc + 960, 16 - Q11 - 1 + scale_factor ); /*-1+scale_factor*/ - Q_sig = sub( scale_factor, 1 ); - - Scale_sig( mem_decim16k_fx, 2 * L_FILT_MAX, sub( sub( scale_factor, 1 ), sub( 15, exp_mem_decim16k ) ) ); - exp_mem_decim16k = sub( 15, ( add( sub( Q_sig, 1 ), scale_factor ) ) ); - Q_mem_decim16k = sub( scale_factor, 1 ); - mem_decim16k_size = 2 * L_FILT_MAX; - Word16 Q_tmp_1 = 0; - move16(); - move16(); - - length_new_inp_16k = modify_Fs_fx( signal_in_fx - lMemRecalc, input_frame, input_Fs, new_inp_16k_fx - ( lMemRecalc * sr_core ) / st->input_Fs, sr_core, mem_decim16k_fx, 0, &Q_tmp_1, &mem_decim16k_size ); - len_2 = length_new_inp_16k; - Copy( mem_decim16k_fx, mem_decim16k_dummy_fx, 2 * L_FILT_MAX ); - size_mem_decim16k_dummy = 2 * L_FILT_MAX; - move16(); - - Q_new_inp_16k = add( sub( Q_tmp_1, 1 ), scale_factor ); - Q_len_2 = Q_new_inp_16k; - move16(); - - Q_mem_decim16k = sub( scale_factor, 1 ); - Q_mem_decim16k_dummy = Q_mem_decim16k; - move16(); - - IF( lMemRecalc > 0 ) - { - Word16 scale_factor_1 = getScaleFactor16( signal_in_fx - lMemRecalc + input_frame, lMemRecalc ) - 1; - Copy_Scale_sig32_16( signal_in_32fx - lMemRecalc + input_frame, signal_in_fx - lMemRecalc + input_frame, lMemRecalc, 16 - Q11 - 1 + scale_factor_1 ); /*-1+scale_factor*/ - Q_sig = sub( scale_factor_1, 1 ); - Scale_sig( mem_decim16k_dummy_fx, 2 * L_FILT_MAX, ( -1 + scale_factor_1 ) - Q_mem_decim16k ); - exp_mem_decim16k = sub( 15, ( add( sub( Q_sig, 1 ), scale_factor_1 ) ) ); - mem_decim16k_size = 2 * L_FILT_MAX; - move16(); - Q_tmp_1 = 0; - move16(); - length_new_inp_16k = modify_Fs_fx( signal_in_fx - lMemRecalc + input_frame, lMemRecalc, input_Fs, new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ) - ( lMemRecalc * sr_core ) / st->input_Fs, sr_core, mem_decim16k_dummy_fx, 0, &Q_tmp_1, &size_mem_decim16k_dummy ); - len_3 = length_new_inp_16k; - move16(); - Q_new_inp_16k = add( sub( Q_tmp_1, 1 ), scale_factor_1 ); - Q_len_3 = Q_new_inp_16k; - move16(); - Q_mem_decim16k_dummy = sub( scale_factor_1, 1 ); - size_mem_decim16k_dummy = mem_decim16k_size; - move16(); - } - - set16_fx( temp1F_icatdmResampBuf_fx, 0, L_FILT_MAX ); - Word16 Q_tmp_2 = 0; - move16(); - length_new_inp_16k = modify_Fs_fx( temp1F_icatdmResampBuf_fx, NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), input_Fs, new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ), sr_core, mem_decim16k_dummy_fx, 0, &Q_tmp_2, &mem_decim16k_size ); - len_4 = length_new_inp_16k; - Q_new_inp_16k = Q_tmp_2; - Q_len_4 = Q_new_inp_16k; - size_mem_decim16k_dummy = mem_decim16k_size; - move16(); - move16(); - move16(); - move16(); - } - } - ELSE IF( st->idchan == 0 ) - { - /* update the FIR resampling filter memory, needed for switching to time-domain (FIR) resampling */ - Copy( signal_in_fx + input_frame - NS2SA( input_Fs, L_MEM_RECALC_NS ) - 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), mem_decim16k_fx, 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ) ); - Q_mem_decim16k = -1; - move16(); - } - -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - if ( element_mode == IVAS_SCE ) - { - if ( input_Fs == sr_core ) - { - /* no resampling needed, only delay adjustment to account for the FIR resampling delay */ - delay = NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ); - // prev_Q_mem_decim16k = Q_mem_decim16k; - Q_mem_decim16k = Q_sig; - fixedToFloat_arr( mem_decim16k_fx, st->mem_decim16k, Q_mem_decim16k, 2 * delay ); - fixedToFloat_arr( new_inp_16k_fx, new_inp_16k, prev_Q_mem_decim16k, delay ); - for ( int i = delay; i < input_frame; i++ ) - { - new_inp_16k[i] = fixedToFloat( new_inp_16k_fx[i], Q_sig ); - } - } - else if ( input_Fs == 32000 || input_Fs == 48000 ) - { - fixedToFloat_arr( mem_decim16k_fx, st->mem_decim16k, Q_mem_decim16k, mem_decim16k_size ); // can be removed - fixedToFloat_arr( new_inp_16k_fx, new_inp_16k, Q_old_inp_16k, length_new_inp_16k ); // can be removed - fixedToFloat_arr( mem_decim16k_dummy_fx, mem_decim16k_dummy, Q_mem_decim16k_dummy, size_mem_decim16k_dummy ); - } - } - else if ( element_mode == IVAS_CPE_TD ) - { - if ( input_Fs == sr_core ) - { - /* no resampling needed, only delay adjustment to account for the FIR resampling delay */ - delay = NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ); - fixedToFloat_arr( new_inp_16k_fx - lMemRecalc - delay + L_FILT16k, new_inp_16k - lMemRecalc - delay + L_FILT16k, prev_Q_mem_decim16k, delay ); - fixedToFloat_arr( new_inp_16k_fx - lMemRecalc + L_FILT16k, new_inp_16k - lMemRecalc + L_FILT16k, Q_sig, input_frame + lMemRecalc ); - fixedToFloat_arr( mem_decim16k_fx, st->mem_decim16k, -1, 2 * delay ); - } - else if ( input_Fs == 32000 || input_Fs == 48000 ) - { - /* reconstruct past segment of input signal when switching from MDCT stereo */ - if ( last_element_mode == IVAS_CPE_MDCT /*|| st->idchan == 1*/ ) - { - Word16 length_16k = NS2SA( INT_FS_16k, L_MEM_RECALC_SCH_NS - DELAY_FIR_RESAMPL_NS ); - fixedToFloat_arr( mem_decim16k_fx, st->mem_decim16k, Q_mem_decim16k, mem_decim16k_size ); - fixedToFloat_arr( new_inp_16k_fx - lMemRecalc_16k - length_16k, new_inp_16k - lMemRecalc_16k - length_16k, Q_len_1, len_1 ); - } - - - fixedToFloat_arr( mem_decim16k_fx, st->mem_decim16k, Q_mem_decim16k, mem_decim16k_size ); - fixedToFloat_arr( new_inp_16k_fx - ( lMemRecalc * sr_core ) / st->input_Fs, new_inp_16k - ( lMemRecalc * sr_core ) / st->input_Fs, Q_len_2, len_2 ); - - if ( lMemRecalc > 0 ) - { - fixedToFloat_arr( new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ) - ( lMemRecalc * sr_core ) / st->input_Fs, new_inp_16k + NS2SA( sr_core, FRAME_SIZE_NS ) - ( lMemRecalc * sr_core ) / st->input_Fs, Q_len_3, len_3 ); - } - - fixedToFloat_arr( mem_decim16k_dummy_fx, mem_decim16k_dummy, Q_mem_decim16k_dummy, size_mem_decim16k_dummy ); - fixedToFloat_arr( new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ), new_inp_16k + NS2SA( sr_core, FRAME_SIZE_NS ), Q_len_4, len_4 ); - } - } - else if ( st->idchan == 0 ) - { - /* update the FIR resampling filter memory, needed for switching to time-domain (FIR) resampling */ - fixedToFloat_arr( mem_decim16k_fx, st->mem_decim16k, Q_mem_decim16k, 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ) ); - } -#endif + /*---------------------------------------------------------------* + * Change the sampling frequency to 16/25.6/32 kHz + *----------------------------------------------------------------*/ -#else +#ifndef IVAS_FLOAT_FIXED if ( element_mode == IVAS_SCE ) { if ( input_Fs == sr_core ) @@ -1549,8 +1307,6 @@ ivas_error ivas_compute_core_buffers( /* update the FIR resampling filter memory, needed for switching to time-domain (FIR) resampling */ mvr2r( signal_in + input_frame - NS2SA( input_Fs, L_MEM_RECALC_NS ) - 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), st->mem_decim16k, 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ) ); } -#endif - /*------------------------------------------------* * Update BWE memories * @@ -1791,7 +1547,6 @@ ivas_error ivas_compute_core_buffers( * LPC analysis *---------------------------------------------------------------*/ -#ifndef IVAS_FLOAT_FIXED if ( st->last_L_frame == L_FRAME ) { /* this is just an approximation, but it is sufficient */ @@ -1799,91 +1554,299 @@ ivas_error ivas_compute_core_buffers( } analy_lp( inp_16k, L_FRAME16k, L_look, ener, A, epsP, lsp_new, lsp_mid, st->lspold_enc, st->pitch, st->voicing, INT_FS_16k, 0 ); + /*--------------------------------------------------------------* + * Compute Weighted Input + *---------------------------------------------------------------*/ + + find_wsp( L_FRAME16k, L_SUBFR, NB_SUBFR16k, A, Aw, st->speech_enc_pe_flt, PREEMPH_FAC_16k_FLT, st->wspeech_enc_flt, &st->mem_wsp_enc_flt, st->gamma_flt, L_LOOK_16k ); + } + + /*-----------------------------------------------------------------* + * Updates + *-----------------------------------------------------------------*/ + + /* update old input signal @16kHz buffer */ + if ( ( element_mode == IVAS_CPE_TD && st->idchan == 1 ) || element_mode == IVAS_CPE_MDCT ) + { + set_f( st->old_inp_16k, 0, L_INP_MEM ); + } + else if ( input_Fs > 8000 && sr_core == INT_FS_16k ) + { + mvr2r( &old_inp_16k[L_frame_tmp], st->old_inp_16k, L_INP_MEM ); + } + else if ( input_Fs > 8000 ) + { + lerp_flt( st->old_inp_12k8 + L_INP_MEM - L_INP_MEM * 4 / 5, st->old_inp_16k, L_INP_MEM, L_INP_MEM * 4 / 5 ); + } + + if ( inp16k_out != NULL ) + { + *inp16k_out = inp_16k; + } + + if ( new_inp_resamp16k_out != NULL ) + { + mvr2r( new_inp_resamp16k, new_inp_resamp16k_out, L_FRAME16k ); + } #else -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - Word16 *inp_16k_fx; - Word32 epsP_fx[M + 1]; - Word16 epsP_h[M + 1], epsP_l[M + 1]; - Word16 e_esp; - Word16 Q_r[2] = { 0 }; + IF( EQ_16( element_mode, IVAS_SCE ) ) + { + test(); + IF( EQ_32( input_Fs, sr_core ) ) + { + /* no resampling needed, only delay adjustment to account for the FIR resampling delay */ + delay = NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ); + Copy( st->mem_decim16k_fx + delay, new_inp_16k_fx, delay ); + Copy( signal_in_fx, new_inp_16k_fx + delay, input_frame ); + Copy( signal_in_fx + input_frame - shl( delay, 1 ), st->mem_decim16k_fx, shl( delay, 1 ) ); + } + ELSE IF( EQ_32( input_Fs, 32000 ) || EQ_32( input_Fs, 48000 ) ) + { + size_modified = modify_Fs_ivas_fx( signal_in_fx, input_frame, input_Fs, new_inp_16k_fx, sr_core, st->mem_decim16k_fx, 0, &Q_tmp, &mem_decim16k_size ); + Scale_sig( new_inp_16k_fx, size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ - move16(); - move16(); - move16(); - move16(); + Copy( st->mem_decim16k_fx, mem_decim16k_dummy_fx, 2 * L_FILT_MAX ); + set16_fx( temp1F_icatdmResampBuf_fx, 0, L_FILT_MAX ); + size_modified = modify_Fs_ivas_fx( temp1F_icatdmResampBuf_fx, NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), input_Fs, new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ), sr_core, mem_decim16k_dummy_fx, 0, &Q_tmp, &mem_decim16k_size ); + Scale_sig( new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ), size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ + } + } + ELSE IF( EQ_16( element_mode, IVAS_CPE_TD ) ) + { + test(); + IF( EQ_32( input_Fs, sr_core ) ) + { + /* no resampling needed, only delay adjustment to account for the FIR resampling delay */ + delay = NS2SA_FX2( input_Fs, DELAY_FIR_RESAMPL_NS ); + Copy( st->mem_decim16k_fx + delay, new_inp_16k_fx - sub( lMemRecalc, add( delay, L_FILT16k ) ), delay ); + Copy( signal_in_fx - lMemRecalc, new_inp_16k_fx - add( lMemRecalc, L_FILT16k ), add( input_frame, lMemRecalc ) ); + Copy( signal_in_fx + sub( sub( input_frame, lMemRecalc ), shl( delay, 1 ) ), st->mem_decim16k_fx, shl( delay, 1 ) ); + } + ELSE IF( EQ_32( input_Fs, 32000 ) || EQ_32( input_Fs, 48000 ) ) + { + /* reconstruct past segment of input signal when switching from MDCT stereo */ + IF( EQ_16( last_element_mode, IVAS_CPE_MDCT ) /*|| st->idchan == 1*/ ) + { + Word16 length_inp = NS2SA_FX2( input_Fs, L_MEM_RECALC_SCH_NS - DELAY_FIR_RESAMPL_NS ); + Word16 length_16k = NS2SA_FX2( INT_FS_16k, L_MEM_RECALC_SCH_NS - DELAY_FIR_RESAMPL_NS ); - f2me_buf_16( old_inp_16k, old_inp_16k_fx, &exp_old_inp_16k, L_INP ); - f2me_buf( epsP, epsP_fx, &e_esp, M + 1 ); - Q_old_inp_16k = sub( 31, exp_old_inp_16k ); + Copy( signal_in_fx - lMemRecalc - length_inp - 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), st->mem_decim16k_fx, 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ) ); + size_modified = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc - length_inp, length_inp, input_Fs, new_inp_16k_fx - lMemRecalc_16k - length_16k, sr_core, st->mem_decim16k_fx, 0, &Q_tmp, &mem_decim16k_size ); + Scale_sig( new_inp_16k_fx - lMemRecalc_16k - length_16k, size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ + } - Word32 ener_fx[CPE_CHANNELS]; + size_modified = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc, input_frame, input_Fs, new_inp_16k_fx - ( lMemRecalc * sr_core ) / st->input_Fs, sr_core, st->mem_decim16k_fx, 0, &Q_tmp, &mem_decim16k_size ); + Scale_sig( new_inp_16k_fx - ( lMemRecalc * sr_core ) / st->input_Fs, size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ + Copy( st->mem_decim16k_fx, mem_decim16k_dummy_fx, 2 * L_FILT_MAX ); + + IF( lMemRecalc > 0 ) + { + size_modified = modify_Fs_ivas_fx( signal_in_fx - lMemRecalc + input_frame, lMemRecalc, input_Fs, new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ) - ( lMemRecalc * sr_core ) / st->input_Fs, sr_core, mem_decim16k_dummy_fx, 0, &Q_tmp, &mem_decim16k_size ); + Scale_sig( new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ) - ( lMemRecalc * sr_core ) / st->input_Fs, size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ + } + + set16_fx( temp1F_icatdmResampBuf_fx, 0, L_FILT_MAX ); + size_modified = modify_Fs_ivas_fx( temp1F_icatdmResampBuf_fx, NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), input_Fs, new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ), sr_core, mem_decim16k_dummy_fx, 0, &Q_tmp, &mem_decim16k_size ); + Scale_sig( new_inp_16k_fx + NS2SA( sr_core, FRAME_SIZE_NS ), size_modified, negate( Q_tmp ) ); /* scaling back to Q_old_inp_16k */ + } + } + ELSE IF( st->idchan == 0 ) + { + /* update the FIR resampling filter memory, needed for switching to time-domain (FIR) resampling */ + Copy( signal_in_fx + input_frame - NS2SA( input_Fs, L_MEM_RECALC_NS ) - 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), st->mem_decim16k_fx, 2 * NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ) ); + } + + /*------------------------------------------------* + * Update BWE memories * + *------------------------------------------------*/ - Word16 i; - flag1 = 0; + test(); + IF( EQ_32( sr_core, INT_FS_16k ) && NE_16( element_mode, IVAS_CPE_MDCT ) ) + { + delay = NS2SA( INT_FS_16k, DELAY_FD_BWE_ENC_12k8_NS ); move16(); - FOR( i = 0; i < L_INP; i++ ) + IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) { - IF( old_inp_16k_fx[i] != 0 ) + /* save input resampled at 16kHz, non-preemphasised.*/ + Copy( new_inp_16k_fx, new_inp_resamp16k_fx, L_FRAME16k ); + + IF( EQ_16( st->bwidth, WB ) ) { - flag1 = 1; - move16(); - break; + Copy_Scale_sig( new_inp_16k_fx - delay, st->hBWE_FD->old_input_wb_fx, delay, -( Q_old_inp_16k + 1 ) ); /* Scaling to Q(-1) */ + Copy( new_inp_16k_fx - STEREO_DFT_OVL_16k, st->hBWE_FD->L_old_wtda_swb_fx + L_FRAME16k - STEREO_DFT_OVL_16k + delay, STEREO_DFT_OVL_16k - delay ); /* Check Q here once. Q should be Q_old_wtda */ + } + } + ELSE IF( EQ_16( element_mode, IVAS_CPE_TD ) ) + { + /* save input resampled at 16kHz, non-preemphasised */ + Copy( new_inp_16k_fx + L_FILT16k, new_inp_resamp16k_fx, L_FRAME16k ); + + test(); + IF( EQ_16( st->bwidth, WB ) && st->hBWE_FD != NULL ) + { + Copy_Scale_sig( new_inp_16k_fx + L_FILT16k - delay, st->hBWE_FD->old_input_wb_fx, delay, -( Q_old_inp_16k + 1 ) ); /* Scaling to Q(-1) */ + Copy( new_inp_16k_fx - L_MEM_RECALC_16K, st->hBWE_FD->L_old_wtda_swb_fx + L_FRAME16k - L_MEM_RECALC_16K - L_FILT16k + delay, L_MEM_RECALC_16K + L_FILT16k - delay ); /* Check Q here once. Q should be Q_old_wtda */ } } - IF( flag1 == 0 ) + ELSE IF( element_mode == IVAS_SCE ) + { + /* save input resampled at 16kHz, non-preemphasised */ + Copy( new_inp_16k_fx + L_FILT16k, new_inp_resamp16k_fx, L_FRAME16k ); + + IF( EQ_16( st->bwidth, WB ) ) + { + Copy_Scale_sig( new_inp_16k_fx, st->hBWE_FD->old_input_wb_fx + delay - L_FILT16k, L_FILT16k, -( Q_old_inp_16k + 1 ) ); /* Scaling to Q(-1) */ + /* all buffer st->hBWE_FD->old_wtda_swb is correct and does not need to be updated */ + } + } + } + ELSE IF( GT_32( sr_core, INT_FS_16k ) ) + { + /* reset the buffer, the signal is needed for WB BWEs */ + set16_fx( new_inp_resamp16k_fx, 0, L_FRAME16k ); + } + + /*------------------------------------------------------------------* + * Perform fixed preemphasis (16kHz signal) through 1 - g*z^-1 + *-----------------------------------------------------------------*/ + + test(); + test(); + test(); + if ( st->tcxonly == 0 && !( ( EQ_16( element_mode, IVAS_CPE_TD ) && EQ_16( st->idchan, 1 ) ) || EQ_16( element_mode, IVAS_CPE_MDCT ) ) ) + { + st->mem_preemph_enc = new_inp_16k_fx[L_frame_tmp - 1]; + move16(); + } + + test(); + test(); + IF( GT_32( input_Fs, 8000 ) && EQ_32( sr_core, INT_FS_16k ) && NE_16( element_mode, IVAS_CPE_MDCT ) ) + { + IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) { - exp_old_inp_16k = 15; + Copy( new_inp_16k_fx - STEREO_DFT_OVL_16k + L_FRAME16k, st->inp_16k_mem_stereo_sw_fx, STEREO_DFT_OVL_16k - L_MEM_RECALC_16K - L_FILT16k ); /* update for TD/DFT stereo switching */ + + st->mem_preemph16k_fx = st->mem_preemph16k_DFT_fx; + move16(); + st->mem_preemph16k_DFT_fx = old_inp_16k_fx[L_INP_MEM - STEREO_DFT_OVL_16k + L_FRAME16k - 1]; move16(); + + IF( EQ_16( st->L_frame, L_FRAME16k ) ) + { + Copy( new_inp_16k_fx - STEREO_DFT_OVL_16k, st->buf_speech_enc + L_FRAME16k - STEREO_DFT_OVL_16k, L_FRAME16k + STEREO_DFT_OVL_16k ); + } + PREEMPH_FX( new_inp_16k_fx - STEREO_DFT_OVL_16k, PREEMPH_FAC_16k, L_FRAME16k, &( st->mem_preemph16k_fx ) ); + tmp_fx = st->mem_preemph16k_fx; + move16(); + + PREEMPH_FX( new_inp_16k_fx - STEREO_DFT_OVL_16k + L_FRAME16k, PREEMPH_FAC_16k, STEREO_DFT_OVL_16k, &tmp_fx ); } + ELSE IF( EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + IF( EQ_16( last_element_mode, IVAS_CPE_DFT ) ) + { + st->mem_preemph16k_fx = st->mem_preemph16k_DFT_fx; + move16(); + Copy( st->inp_16k_mem_stereo_sw_fx, new_inp_16k_fx - L_MEM_RECALC_16K - ( STEREO_DFT_OVL_16k - L_MEM_RECALC_16K - L_FILT16k ), STEREO_DFT_OVL_16k - L_MEM_RECALC_16K - L_FILT16k ); + PREEMPH_FX( new_inp_16k_fx - L_MEM_RECALC_16K - ( STEREO_DFT_OVL_16k - L_MEM_RECALC_16K - L_FILT16k ), PREEMPH_FAC_16k, STEREO_DFT_OVL_16k - L_MEM_RECALC_16K - L_FILT16k, &st->mem_preemph16k_fx ); + } - new_inp_16k_fx = old_inp_16k_fx + L_INP_MEM; /* pointer to new samples of the input signal in 16kHz core */ - inp_16k_fx = new_inp_16k_fx - L_look; /* pointer to the current frame of input signal in 16kHz core */ + st->mem_preemph16k_DFT_fx = old_inp_16k_fx[L_INP_MEM - STEREO_DFT_OVL_16k + L_FRAME16k - 1]; + move16(); - Word16 exp_ener; - f2me_buf( ener, ener_fx, &exp_ener, CPE_CHANNELS ); -#endif - IF( st->last_L_frame == L_FRAME ) + /* preemphasise past segment of input signal when switching from MDCT stereo */ + IF( EQ_16( last_element_mode, IVAS_CPE_MDCT ) ) + { + Word16 length_16k = NS2SA( INT_FS_16k, L_MEM_RECALC_SCH_NS - DELAY_FIR_RESAMPL_NS ); + + PREEMPH_FX( new_inp_16k_fx - lMemRecalc_16k - length_16k, PREEMPH_FAC, length_16k, &st->mem_preemph16k_fx ); + } + + IF( EQ_16( st->L_frame, L_FRAME16k ) ) + { + Copy( new_inp_16k_fx - lMemRecalc_16k, st->buf_speech_enc + L_FRAME16k - lMemRecalc_16k - L_FILT16k, L_FRAME16k + lMemRecalc_16k + L_FILT16k ); + } + PREEMPH_FX( new_inp_16k_fx - lMemRecalc_16k, PREEMPH_FAC_16k, L_FRAME16k, &( st->mem_preemph16k_fx ) ); + tmp_fx = st->mem_preemph16k_fx; + move16(); + PREEMPH_FX( new_inp_16k_fx - lMemRecalc_16k + L_FRAME16k, PREEMPH_FAC_16k, lMemRecalc_16k + L_FILT16k, &tmp_fx ); + } + ELSE IF( EQ_16( element_mode, IVAS_SCE ) ) { - /* this is just an approximation, but it is sufficient */ - Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); + PREEMPH_FX( new_inp_16k_fx, PREEMPH_FAC_16k, L_FRAME16k, &( st->mem_preemph16k_fx ) ); + tmp_fx = st->mem_preemph16k_fx; + move16(); + PREEMPH_FX( new_inp_16k_fx + L_FRAME16k, PREEMPH_FAC_16k, L_FILT16k, &tmp_fx ); + } + ELSE IF( GT_32( input_Fs, 8000 ) ) /* keep memory up-to-date in case of bitrate switching */ + { + IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) + { + st->mem_preemph16k_fx = new_inp_16k_fx[L_frame_tmp - STEREO_DFT_OVL_16k - 1]; + move16(); + } + ELSE IF( EQ_16( element_mode, IVAS_CPE_TD ) ) + { + st->mem_preemph16k_fx = new_inp_16k_fx[L_frame_tmp - lMemRecalc_16k - 1]; + move16(); + } + ELSE IF( EQ_16( element_mode, IVAS_CPE_MDCT ) ) + { + st->mem_preemph16k_fx = 0; + move16(); + } + ELSE /* SCE */ + { + st->mem_preemph16k_fx = new_inp_16k_fx[L_frame_tmp - 1]; + move16(); + } + st->mem_preemph16k_DFT_fx = st->mem_preemph16k_fx; + move16(); } + } - analy_lp_fx( inp_16k_fx, L_FRAME16k, L_look, ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lspold_enc_fx, st->pitch, st->voicing_fx, INT_FS_16k, 0, Q_old_inp_16k, Q_r ); + /*-----------------------------------------------------------------* + * LP analysis at 16kHz if ACELP@16k core was selected + * update buffers + *-----------------------------------------------------------------*/ -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - me2f_buf_16( old_inp_16k_fx, exp_old_inp_16k, old_inp_16k, L_INP ); - me2f_buf( ener_fx, exp_ener, ener, CPE_CHANNELS ); - for ( i = 0; i < M + 1; i++ ) + test(); + IF( EQ_16( st->L_frame, L_FRAME16k ) && NE_16( element_mode, IVAS_CPE_MDCT ) ) + { + /* update signal buffers */ + IF( EQ_16( element_mode, IVAS_CPE_DFT ) ) { - epsP_fx[i] = L_Comp( epsP_h[i], epsP_l[i] ); - move32(); + Copy( new_inp_16k_fx - STEREO_DFT_OVL_16k, st->buf_speech_enc_pe + L_FRAME16k - STEREO_DFT_OVL_16k, L_FRAME16k + STEREO_DFT_OVL_16k ); } - fixedToFloat_arrL( epsP_fx, epsP, Q_r[0] - Q_r[1], M + 1 ); -#endif -#endif + ELSE IF( EQ_16( element_mode, IVAS_CPE_TD ) ) + { + Copy( new_inp_16k_fx - lMemRecalc_16k, st->buf_speech_enc_pe + L_FRAME16k - lMemRecalc_16k - L_FILT16k, L_FRAME16k + lMemRecalc_16k + L_FILT16k ); + } + ELSE + { + Copy( new_inp_resamp16k_fx, st->buf_speech_enc + L_FRAME16k, L_FRAME16k ); + Copy( new_inp_16k_fx, st->buf_speech_enc_pe + L_FRAME16k, L_FRAME16k ); + } + /*--------------------------------------------------------------* - * Compute Weighted Input + * LPC analysis *---------------------------------------------------------------*/ -#ifndef IVAS_FLOAT_FIXED - find_wsp( L_FRAME16k, L_SUBFR, NB_SUBFR16k, A, Aw, st->speech_enc_pe_flt, PREEMPH_FAC_16k_FLT, st->wspeech_enc_flt, &st->mem_wsp_enc_flt, st->gamma_flt, L_LOOK_16k ); -#else -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - floatToFixed_arr( st->speech_enc_pe_flt - M, st->speech_enc_pe - M, Q9, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k - st->encoderPastSamples_enc + M ); + IF( EQ_16( st->last_L_frame, L_FRAME ) ) + { + /* this is just an approximation, but it is sufficient */ + Copy( st->lsp_old1_fx, st->lspold_enc_fx, M ); + } - floatToFixed_arr( st->wspeech_enc_flt, st->wspeech_enc, Q9, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k - st->L_frame - L_SUBFR ); + analy_lp_fx( inp_16k_fx, L_FRAME16k, L_look, &ener_fx, A_fx, epsP_h, epsP_l, lsp_new_fx, lsp_mid_fx, st->lspold_enc_fx, st->pitch, st->voicing_fx, INT_FS_16k, 0, Q_old_inp_16k, Q_r ); - st->mem_wsp_enc = (Word16) floatToFixed( st->mem_wsp_enc_flt, Q9 ); + /*--------------------------------------------------------------* + * Compute Weighted Input + *---------------------------------------------------------------*/ -#endif ivas_find_wsp( L_FRAME16k, L_SUBFR, NB_SUBFR16k, A_fx, Aw_fx, st->speech_enc_pe, PREEMPH_FAC_16k, st->wspeech_enc, &st->mem_wsp_enc, st->gamma, L_LOOK_16k ); -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - fixedToFloat_arr( st->wspeech_enc, st->wspeech_enc_flt, Q9, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k - st->L_frame - L_SUBFR ); - - st->mem_wsp_enc_flt = fixedToFloat( st->mem_wsp_enc, Q9 ); -#endif -#endif } /*-----------------------------------------------------------------* @@ -1891,45 +1854,81 @@ ivas_error ivas_compute_core_buffers( *-----------------------------------------------------------------*/ /* update old input signal @16kHz buffer */ - if ( ( element_mode == IVAS_CPE_TD && st->idchan == 1 ) || element_mode == IVAS_CPE_MDCT ) + test(); + test(); + test(); + IF( ( EQ_16( element_mode, IVAS_CPE_TD ) && EQ_16( st->idchan, 1 ) ) || EQ_16( element_mode, IVAS_CPE_MDCT ) ) { - set_f( st->old_inp_16k, 0, L_INP_MEM ); + set16_fx( st->old_inp_16k_fx, 0, L_INP_MEM ); } - else if ( input_Fs > 8000 && sr_core == INT_FS_16k ) + ELSE IF( GT_32( input_Fs, 8000 ) && EQ_32( sr_core, INT_FS_16k ) ) { - mvr2r( &old_inp_16k[L_frame_tmp], st->old_inp_16k, L_INP_MEM ); + Copy( &old_inp_16k_fx[L_frame_tmp], st->old_inp_16k_fx, L_INP_MEM ); } - else if ( input_Fs > 8000 ) + ELSE IF( GT_32( input_Fs, 8000 ) ) { -#ifndef IVAS_FLOAT_FIXED - lerp_flt( st->old_inp_12k8 + L_INP_MEM - L_INP_MEM * 4 / 5, st->old_inp_16k, L_INP_MEM, L_INP_MEM * 4 / 5 ); -#else -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - Word16 q_old_inp_12k8 = Q_factor_arr( st->old_inp_12k8, L_INP ); - floatToFixed_arr( st->old_inp_12k8, st->old_inp_12k8_fx, q_old_inp_12k8, L_INP ); - - Word16 q_old_inp_16k = Q_factor_arr( st->old_inp_16k, L_INP ); - floatToFixed_arr( st->old_inp_16k, st->old_inp_16k_fx, q_old_inp_16k, L_INP ); - lerp( st->old_inp_12k8_fx + L_INP_MEM - L_INP_MEM * 4 / 5, st->old_inp_16k_fx, L_INP_MEM, L_INP_MEM * 4 / 5 ); -#endif + } + IF( inp16k_out != NULL ) + { #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - fixedToFloat_arr( st->old_inp_12k8_fx, st->old_inp_12k8, q_old_inp_12k8, L_INP ); - fixedToFloat_arr( st->old_inp_16k_fx, st->old_inp_16k, q_old_inp_12k8, L_INP ); -#endif + *inp16k_out = inp_16k; #endif + *inp16k_out_fx = inp_16k_fx; } - if ( inp16k_out != NULL ) + IF( new_inp_resamp16k_out != NULL ) { - *inp16k_out = inp_16k; + Copy( new_inp_resamp16k_fx, new_inp_resamp16k_out_fx, L_FRAME16k ); + } + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + // No need to do fixed to float for signal_in_fx + st->mem_preemph_enc_flt = fixedToFloat_16( st->mem_preemph_enc, Q_old_inp_16k ); + st->mem_preemph16k = fixedToFloat_16( st->mem_preemph16k_fx, Q_old_inp_16k ); + st->mem_preemph16k_DFT = fixedToFloat_16( st->mem_preemph16k_DFT_fx, Q_old_inp_16k ); + st->mem_wsp_enc_flt = fixedToFloat_16( st->mem_wsp_enc, Q_old_inp_16k ); + + if ( st->L_frame == L_FRAME16k && element_mode != IVAS_CPE_MDCT ) + { + *ener = fixedToFloat( ener_fx, Q_r[0] + 1 ); } + fixedToFloat_arr( old_inp_16k_fx, old_inp_16k, Q_old_inp_16k, L_INP ); + fixedToFloat_arr( signal_in_fx, signal_in, Q_old_inp_16k, 960 ); + fixedToFloat_arr( new_inp_resamp16k_fx, new_inp_resamp16k, Q_old_inp_16k, L_FRAME16k ); + if ( new_inp_resamp16k_out != NULL ) { - mvr2r( new_inp_resamp16k, new_inp_resamp16k_out, L_FRAME16k ); + fixedToFloat_arr( new_inp_resamp16k_out_fx, new_inp_resamp16k_out, Q_old_inp_16k, L_FRAME16k ); + } + + fixedToFloat_arr( st->old_inp_16k_fx, st->old_inp_16k, Q_old_inp_16k, L_INP_MEM ); + fixedToFloat_arr( st->mem_decim16k_fx, st->mem_decim16k, Q_old_inp_16k, 2 * L_FILT_MAX ); + fixedToFloat_arr( st->inp_16k_mem_stereo_sw_fx, st->inp_16k_mem_stereo_sw, Q_old_inp_16k, STEREO_DFT_OVL_16k - L_MEM_RECALC_16K - L_FILT16k ); + fixedToFloat_arr( st->buf_speech_enc, st->buf_speech_enc_flt, Q_old_inp_16k, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k ); + fixedToFloat_arr( st->buf_speech_enc_pe, st->buf_speech_enc_pe_flt, Q_old_inp_16k, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k ); // Should take care of st->speech_enc_pe as wel + fixedToFloat_arr( st->buf_wspeech_enc, st->buf_wspeech_enc_flt, Q_old_inp_16k, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320 ); // Should take care of st->wspeech_enc + + if ( st->hBWE_FD != NULL ) + { + fixedToFloat_arr( st->hBWE_FD->L_old_wtda_swb_fx, st->hBWE_FD->old_wtda_swb, st->Q_old_wtda, L_FRAME48k ); + fixedToFloat_arr( st->hBWE_FD->old_input_wb_fx, st->hBWE_FD->old_input_wb, -1, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); + } + + if ( st->L_frame == L_FRAME16k && element_mode != IVAS_CPE_MDCT ) + { + for ( Word16 i = 0; i < M + 1; i++ ) + { + epsP_fx[i] = L_Comp( epsP_h[i], epsP_l[i] ); + move32(); + } + + fixedToFloat_arrL( epsP_fx, epsP, Q_r[0] + 1, M + 1 ); } +#endif +#endif return IVAS_ERR_OK; } diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index 0370c37e1..b4f4755ca 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -695,9 +695,6 @@ ivas_error ivas_cpe_enc( floatToFixed_arr( &hCPE->hStereoDft->input_mem_itd[i][0], &hCPE->hStereoDft->input_mem_itd_fx[i][0], hCPE->hStereoDft->q_input_mem_itd[i], STEREO_DFT_OVL_MAX ); #endif // MSAN_FIX } - f2me_buf( hCPE->hStereoDft->Spd_L_smooth, hCPE->hStereoDft->Spd_L_smooth_fx, &hCPE->hStereoDft->Spd_L_smooth_fx_e, STEREO_DFT_N_32k_ENC / 2 ); - f2me_buf( hCPE->hStereoDft->Spd_R_smooth, hCPE->hStereoDft->Spd_R_smooth_fx, &hCPE->hStereoDft->Spd_R_smooth_fx_e, STEREO_DFT_N_32k_ENC / 2 ); - 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 @@ -719,8 +716,6 @@ ivas_error ivas_cpe_enc( { floatToFixed_arr( sts[1]->old_inp_12k8, sts[1]->old_inp_12k8_fx, 0, L_INP_MEM ); } - f2me( hCPE->hStereoDft->icbweRefEner, &hCPE->hStereoDft->icbweRefEner_fx, &hCPE->hStereoDft->icbweRefEner_fx_e ); - f2me( hCPE->hStereoDft->lbEner, &hCPE->hStereoDft->lbEner_fx, &hCPE->hStereoDft->lbEner_fx_e ); floatToFixed_arrL( hCPE->hStereoDft->output_mem_res_8k, hCPE->hStereoDft->output_mem_res_8k_fx, 16, STEREO_DFT_OVL_8k ); floatToFixed_arrL( hCPE->hStereoDft->output_mem_dmx, hCPE->hStereoDft->output_mem_dmx_fx, 16, STEREO_DFT_OVL_MAX ); floatToFixed_arrL( hCPE->hStereoDft->output_mem_dmx_12k8, hCPE->hStereoDft->output_mem_dmx_12k8_fx, 16, STEREO_DFT_OVL_12k8 ); @@ -731,6 +726,14 @@ ivas_error ivas_cpe_enc( /*flt2fix end*/ #endif #ifdef IVAS_FLOAT_FIXED + Word16 temp = getScaleFactor32( hCPE->hStereoDft->Spd_L_smooth_fx, STEREO_DFT_N_32k_ENC / 2 ); + scale_sig32( hCPE->hStereoDft->Spd_L_smooth_fx, STEREO_DFT_N_32k_ENC / 2, temp ); + hCPE->hStereoDft->Spd_L_smooth_fx_e = sub( hCPE->hStereoDft->Spd_L_smooth_fx_e, temp ); + + temp = getScaleFactor32( hCPE->hStereoDft->Spd_R_smooth_fx, STEREO_DFT_N_32k_ENC / 2 ); + scale_sig32( hCPE->hStereoDft->Spd_R_smooth_fx, STEREO_DFT_N_32k_ENC / 2, temp ); + hCPE->hStereoDft->Spd_R_smooth_fx_e = sub( hCPE->hStereoDft->Spd_R_smooth_fx_e, temp ); + stereo_dft_hybrid_ITD_flag( hCPE->hStereoDft->hConfig, input_Fs, hCPE->hStereoDft->hItd->hybrid_itd_max ); /* Time Domain ITD compensation using extrapolation */ @@ -759,11 +762,6 @@ ivas_error ivas_cpe_enc( floatToFixed_arr16( sts[0]->input, sts[0]->input_fx, 0, input_frame ); floatToFixed_arr16( sts[1]->input, sts[1]->input_fx, 0, input_frame ); - hCPE->hStereoTD->tdm_lt_rms_L_fx = floatToFixed_32( hCPE->hStereoTD->tdm_lt_rms_L, Q16 ); - hCPE->hStereoTD->tdm_lt_rms_R_fx = floatToFixed_32( hCPE->hStereoTD->tdm_lt_rms_R, Q16 ); - hCPE->hStereoTD->tdm_last_ener_lt_L_fx = floatToFixed_32( hCPE->hStereoTD->tdm_last_ener_lt_L, Q16 ); - hCPE->hStereoTD->tdm_last_ener_lt_R_fx = floatToFixed_32( hCPE->hStereoTD->tdm_last_ener_lt_R, Q16 ); - hCPE->hStereoTD->tdm_LT_es_em_fx = floatToFixed_32( hCPE->hStereoTD->tdm_LT_es_em, Q21 ); sts[0]->hNoiseEst->Etot_last_fx = float_to_fix16( sts[0]->hNoiseEst->Etot_last, Q8 ); sts[1]->hNoiseEst->Etot_last_fx = float_to_fix16( sts[1]->hNoiseEst->Etot_last, Q8 ); sts[0]->old_corr_fx = float_to_fix16( sts[0]->old_corr, Q15 ); @@ -771,47 +769,16 @@ 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 ); - hCPE->hStereoTD->tdm_last_ratio_fx = floatToFixed( hCPE->hStereoTD->tdm_last_ratio, Q31 ); - hCPE->hStereoTD->tdm_lt_corr_LM_fx = floatToFixed_32( hCPE->hStereoTD->tdm_lt_corr_LM, Q24 ); - hCPE->hStereoTD->tdm_lt_corr_RM_fx = floatToFixed_32( hCPE->hStereoTD->tdm_lt_corr_RM, Q24 ); - hCPE->hStereoTD->q_tdm_last_diff_lt_corr = Q31; - hCPE->hStereoTD->tdm_last_diff_lt_corr_fx = floatToFixed_32( hCPE->hStereoTD->tdm_last_diff_lt_corr, hCPE->hStereoTD->q_tdm_last_diff_lt_corr ); floatToFixed_arrL( hCPE->hStereoClassif->unclr_fv, hCPE->hStereoClassif->unclr_fv_fx, Q15, 58 ); IF( hCPE->hStereoTD->tdm_last_SM_flag ) { - IF( hCPE->hStereoTD->tdm_SM_reset_flag ) - { - hCPE->hStereoTD->tdm_lt_corr_RM_SM = 0.01f; - hCPE->hStereoTD->tdm_lt_corr_LM_SM = 0.01f; - hCPE->hStereoTD->tdm_last_ratio_SM = hCPE->hStereoTD->tdm_last_ratio; - - hCPE->hStereoTD->tdm_lt_rms_L_SM = 40.0f; - hCPE->hStereoTD->tdm_lt_rms_R_SM = 40.0f; - hCPE->hStereoTD->tdm_last_diff_lt_corr_SM = 0; - hCPE->hStereoTD->tdm_last_ener_lt_R_SM = 0; - hCPE->hStereoTD->tdm_last_ener_lt_L_SM = 0; - hCPE->hStereoTD->tdm_LT_es_em_SM = 0.1f; - } floatToFixed_arr16( sts[0]->input, sts[0]->input_fx, 0, input_frame ); floatToFixed_arr16( sts[1]->input, sts[1]->input_fx, 0, input_frame ); - - hCPE->hStereoTD->tdm_lt_rms_L_SM_fx = floatToFixed_32( hCPE->hStereoTD->tdm_lt_rms_L_SM, Q16 ); - hCPE->hStereoTD->tdm_lt_rms_R_SM_fx = floatToFixed_32( hCPE->hStereoTD->tdm_lt_rms_R_SM, Q16 ); - hCPE->hStereoTD->tdm_last_ener_lt_L_SM_fx = floatToFixed_32( hCPE->hStereoTD->tdm_last_ener_lt_L_SM, Q16 ); - hCPE->hStereoTD->tdm_last_ener_lt_R_SM_fx = floatToFixed_32( hCPE->hStereoTD->tdm_last_ener_lt_R_SM, Q16 ); - hCPE->hStereoTD->tdm_LT_es_em_SM_fx = floatToFixed_32( hCPE->hStereoTD->tdm_LT_es_em_SM, Q21 ); sts[0]->hNoiseEst->Etot_last_fx = float_to_fix16( sts[0]->hNoiseEst->Etot_last, Q8 ); sts[1]->hNoiseEst->Etot_last_fx = float_to_fix16( sts[1]->hNoiseEst->Etot_last, Q8 ); sts[0]->old_corr_fx = float_to_fix16( sts[0]->old_corr, Q15 ); sts[1]->old_corr_fx = float_to_fix16( sts[1]->old_corr, Q15 ); - - hCPE->hStereoTD->tdm_lt_corr_LM_SM_fx = floatToFixed_32( hCPE->hStereoTD->tdm_lt_corr_LM_SM, Q24 ); - hCPE->hStereoTD->tdm_lt_corr_RM_SM_fx = floatToFixed_32( hCPE->hStereoTD->tdm_lt_corr_RM_SM, Q24 ); - hCPE->hStereoTD->q_tdm_last_diff_lt_corr_SM = Q31; - hCPE->hStereoTD->tdm_last_diff_lt_corr_SM_fx = floatToFixed_32( hCPE->hStereoTD->tdm_last_diff_lt_corr_SM, hCPE->hStereoTD->q_tdm_last_diff_lt_corr_SM ); - - hCPE->hStereoTD->tdm_last_ratio_SM_fx = floatToFixed_32( hCPE->hStereoTD->tdm_last_ratio_SM, Q31 ); } #endif /* Determine the energy ratio between the 2 channels */ @@ -819,30 +786,10 @@ ivas_error ivas_cpe_enc( ivas_format, hCPE, input_frame, &tdm_SM_or_LRTD_Pri, &tdm_ratio_idx_SM ); #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - hCPE->hStereoTD->tdm_lt_rms_L = fixedToFloat_32( hCPE->hStereoTD->tdm_lt_rms_L_fx, Q16 ); - hCPE->hStereoTD->tdm_lt_rms_R = fixedToFloat_32( hCPE->hStereoTD->tdm_lt_rms_R_fx, Q16 ); - hCPE->hStereoTD->tdm_last_ener_lt_L = fixedToFloat_32( hCPE->hStereoTD->tdm_last_ener_lt_L_fx, Q16 ); - hCPE->hStereoTD->tdm_last_ener_lt_R = fixedToFloat_32( hCPE->hStereoTD->tdm_last_ener_lt_R_fx, Q16 ); - hCPE->hStereoTD->tdm_LT_es_em = fixedToFloat_32( hCPE->hStereoTD->tdm_LT_es_em_fx, Q21 ); 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 ); - hCPE->hStereoTD->tdm_lt_corr_LM = fixedToFloat_32( hCPE->hStereoTD->tdm_lt_corr_LM_fx, Q24 ); - hCPE->hStereoTD->tdm_lt_corr_RM = fixedToFloat_32( hCPE->hStereoTD->tdm_lt_corr_RM_fx, Q24 ); - hCPE->hStereoTD->tdm_last_diff_lt_corr = fixedToFloat_32( hCPE->hStereoTD->tdm_last_diff_lt_corr_fx, hCPE->hStereoTD->q_tdm_last_diff_lt_corr ); fixedToFloat_arrL( hCPE->hStereoClassif->unclr_fv_fx, hCPE->hStereoClassif->unclr_fv, Q15, 58 ); - if ( hCPE->hStereoTD->tdm_last_SM_flag ) - { - hCPE->hStereoTD->tdm_lt_rms_L_SM = fixedToFloat_32( hCPE->hStereoTD->tdm_lt_rms_L_SM_fx, Q16 ); - hCPE->hStereoTD->tdm_lt_rms_R_SM = fixedToFloat_32( hCPE->hStereoTD->tdm_lt_rms_R_SM_fx, Q16 ); - hCPE->hStereoTD->tdm_last_ener_lt_L_SM = fixedToFloat_32( hCPE->hStereoTD->tdm_last_ener_lt_L_SM_fx, Q16 ); - hCPE->hStereoTD->tdm_last_ener_lt_R_SM = fixedToFloat_32( hCPE->hStereoTD->tdm_last_ener_lt_R_SM_fx, Q16 ); - hCPE->hStereoTD->tdm_LT_es_em_SM = fixedToFloat_32( hCPE->hStereoTD->tdm_LT_es_em_SM_fx, Q21 ); - - hCPE->hStereoTD->tdm_lt_corr_LM_SM = fixedToFloat_32( hCPE->hStereoTD->tdm_lt_corr_LM_SM_fx, Q24 ); - hCPE->hStereoTD->tdm_lt_corr_RM_SM = fixedToFloat_32( hCPE->hStereoTD->tdm_lt_corr_RM_SM_fx, Q24 ); - hCPE->hStereoTD->tdm_last_diff_lt_corr_SM = fixedToFloat_32( hCPE->hStereoTD->tdm_last_diff_lt_corr_SM_fx, hCPE->hStereoTD->q_tdm_last_diff_lt_corr_SM ); - } #endif /* Compute the downmix signal based on the ratio index */ @@ -851,8 +798,6 @@ ivas_error ivas_cpe_enc( Word16 input_fx[2][L_FRAME48k]; floatToFixed_arr16( sts[1]->input, input_fx[0], 0, input_frame ); floatToFixed_arr16( sts[0]->input, input_fx[1], 0, input_frame ); - hCPE->hStereoTD->tdm_last_ratio_fx = floatToFixed( hCPE->hStereoTD->tdm_last_ratio, Q31 ); - hCPE->hStereoTD->tdm_last_ratio_SM_fx = floatToFixed( hCPE->hStereoTD->tdm_last_ratio_SM, Q31 ); #endif Word16 tdm_SM_flag; IF( hCPE->hStereoTD->tdm_LRTD_flag == 0 ) @@ -868,9 +813,6 @@ ivas_error ivas_cpe_enc( stereo_tdm_downmix_ivas_fx( hCPE->hStereoTD, input_fx[0], input_fx[1], input_frame, tdm_ratio_idx, tdm_SM_flag, tdm_ratio_idx_SM ); #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - hCPE->hStereoTD->tdm_last_ratio = fixedToFloat( hCPE->hStereoTD->tdm_last_ratio_fx, Q31 ); - hCPE->hStereoTD->tdm_last_ratio_SM = fixedToFloat( hCPE->hStereoTD->tdm_last_ratio_SM_fx, Q31 ); - fixedToFloat_arr( input_fx[0], sts[0]->input, 0, input_frame ); fixedToFloat_arr( input_fx[1], sts[1]->input, 0, input_frame ); #endif @@ -991,9 +933,6 @@ ivas_error ivas_cpe_enc( 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 ) ); me2f_buf( hCPE->hStereoDft->DFT_fx[i], hCPE->hStereoDft->DFT_fx_e[i], hCPE->hStereoDft->DFT[i], STEREO_DFT_N_MAX_ENC ); } - me2f_buf( hCPE->hStereoDft->Spd_L_smooth_fx, hCPE->hStereoDft->Spd_L_smooth_fx_e, hCPE->hStereoDft->Spd_L_smooth, STEREO_DFT_N_32k_ENC / 2 ); - me2f_buf( hCPE->hStereoDft->Spd_R_smooth_fx, hCPE->hStereoDft->Spd_R_smooth_fx_e, hCPE->hStereoDft->Spd_R_smooth, STEREO_DFT_N_32k_ENC / 2 ); - 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 ); @@ -1006,8 +945,6 @@ ivas_error ivas_cpe_enc( } /*fix2flt: dft_synthesize*/ - hCPE->hStereoDft->icbweRefEner = me2f( hCPE->hStereoDft->icbweRefEner_fx, hCPE->hStereoDft->icbweRefEner_fx_e ); - hCPE->hStereoDft->lbEner = me2f( hCPE->hStereoDft->lbEner_fx, hCPE->hStereoDft->lbEner_fx_e ); fixedToFloat_arrL( sts[0]->input32_fx + out_start_ind, sts[0]->input + out_start_ind, 16, out_end_ind - out_start_ind ); fixedToFloat_arrL( old_inp_12k8_fx[0] + L_INP_MEM + out_12k8_start_ind[0], old_inp_12k8[0] + L_INP_MEM + out_12k8_start_ind[0], 16, out_12k8_end_ind[0] - out_12k8_start_ind[0] ); fixedToFloat_arrL( old_inp_16k_fx[0] + L_INP_MEM + out_16k_start_ind, old_inp_16k[0] + L_INP_MEM + out_16k_start_ind, 16, out_16k_end_ind - out_16k_start_ind ); @@ -2531,8 +2468,11 @@ ivas_error create_cpe_enc( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD Stereo\n" ) ); } - +#ifndef IVAS_FLOAT_FIXED stereo_td_init_enc( hCPE->hStereoTD, hCPE->last_element_mode ); +#else + stereo_td_init_enc_fx( hCPE->hStereoTD, hCPE->last_element_mode ); +#endif } /*-----------------------------------------------------------------* diff --git a/lib_enc/ivas_dirac_enc.c b/lib_enc/ivas_dirac_enc.c index 61a8092ca..c08e64da0 100644 --- a/lib_enc/ivas_dirac_enc.c +++ b/lib_enc/ivas_dirac_enc.c @@ -490,10 +490,36 @@ ivas_error ivas_dirac_enc( } } +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = 0; i < hQMetaData->no_directions; i++ ) + { + for ( j = hQMetaData->q_direction[0].cfg.start_band; j < hQMetaData->q_direction[0].cfg.nbands; ++j ) + { + floatToFixed_arrL( hQMetaData->q_direction[i].band_data[j].energy_ratio, hQMetaData->q_direction[i].band_data[j].energy_ratio_fx, Q30, MAX_PARAM_SPATIAL_SUBFRAMES ); + floatToFixed_arrL( hQMetaData->q_direction[i].band_data[j].azimuth, hQMetaData->q_direction[i].band_data[j].azimuth_fx, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); + floatToFixed_arrL( hQMetaData->q_direction[i].band_data[j].elevation, hQMetaData->q_direction[i].band_data[j].elevation_fx, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); + floatToFixed_arrL( hQMetaData->q_direction[i].band_data[j].q_azimuth, hQMetaData->q_direction[i].band_data[j].q_azimuth_fx, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); + floatToFixed_arrL( hQMetaData->q_direction[i].band_data[j].q_elevation, hQMetaData->q_direction[i].band_data[j].q_elevation_fx, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); + } + } +#endif if ( ( error = ivas_qmetadata_enc_encode( hMetaData, hQMetaData, hodirac_flag ) ) != IVAS_ERR_OK ) { return error; } +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = 0; i < hQMetaData->no_directions; i++ ) + { + for ( j = hQMetaData->q_direction[0].cfg.start_band; j < hQMetaData->q_direction[0].cfg.nbands; ++j ) + { + fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].energy_ratio_fx, hQMetaData->q_direction[i].band_data[j].energy_ratio, Q30, MAX_PARAM_SPATIAL_SUBFRAMES ); + fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].azimuth_fx, hQMetaData->q_direction[i].band_data[j].azimuth, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); + fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].elevation_fx, hQMetaData->q_direction[i].band_data[j].elevation, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); + fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].q_azimuth_fx, hQMetaData->q_direction[i].band_data[j].q_azimuth, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); + fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].q_elevation_fx, hQMetaData->q_direction[i].band_data[j].q_elevation, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); + } + } +#endif } else { diff --git a/lib_enc/ivas_enc.c b/lib_enc/ivas_enc.c index 479c7a5a5..657b71761 100644 --- a/lib_enc/ivas_enc.c +++ b/lib_enc/ivas_enc.c @@ -931,7 +931,11 @@ ivas_error ivas_enc( } else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) { - flag_omasa_ener_brate = ivas_omasa_ener_brate( st_ivas->hEncoderConfig->nchan_ism, ivas_total_brate, data_f, input_frame ); +#ifdef IVAS_FLOAT_FIXED + flag_omasa_ener_brate = ivas_omasa_ener_brate_fx( st_ivas->hEncoderConfig->nchan_ism, ivas_total_brate, data_fx, input_frame, sub( 31, st_ivas->q_data_fx ) ); +#else + flag_omasa_ener_brate = ivas_omasa_ener_brate( st_ivas->hEncoderConfig->nchan_ism, ivas_total_brate, data_fx, input_frame, sub( 31, st_ivas->q_data_fx ) ); +#endif // IVAS_FLOAT_FIXED /* Analysis, decision about bitrates per channel & core coding */ if ( ( error = ivas_ism_enc( st_ivas, data_f, input_frame, &nb_bits_metadata[1], flag_omasa_ener_brate ) ) != IVAS_ERR_OK ) @@ -1092,8 +1096,12 @@ ivas_error ivas_enc( else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) { /* encode MC ParamUpmix parameters and write bitstream */ +#ifdef IVAS_FLOAT_FIXED + ivas_mc_paramupmix_enc( st_ivas, hMetaData, data_f, data_fx, input_frame ); +#else ivas_mc_paramupmix_enc( st_ivas, hMetaData, data_f, input_frame ); +#endif st_ivas->hLFE->hBstr = ( st_ivas->nSCE > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0]->hBstr : st_ivas->hCPE[0]->hCoreCoder[0]->hBstr; ivas_lfe_enc_fx( st_ivas->hLFE, data_fx[LFE_CHANNEL], st_ivas->q_data_fx, input_frame, st_ivas->hLFE->hBstr ); diff --git a/lib_enc/ivas_masa_enc.c b/lib_enc/ivas_masa_enc.c index 1684d34a1..e460c2265 100644 --- a/lib_enc/ivas_masa_enc.c +++ b/lib_enc/ivas_masa_enc.c @@ -539,10 +539,36 @@ ivas_error ivas_masa_encode( } else { +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = 0; i < hQMetaData->no_directions; i++ ) + { + for ( j = hQMetaData->q_direction[0].cfg.start_band; j < hQMetaData->q_direction[0].cfg.nbands; ++j ) + { + floatToFixed_arrL( hQMetaData->q_direction[i].band_data[j].energy_ratio, hQMetaData->q_direction[i].band_data[j].energy_ratio_fx, Q30, MAX_PARAM_SPATIAL_SUBFRAMES ); + floatToFixed_arrL( hQMetaData->q_direction[i].band_data[j].azimuth, hQMetaData->q_direction[i].band_data[j].azimuth_fx, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); + floatToFixed_arrL( hQMetaData->q_direction[i].band_data[j].elevation, hQMetaData->q_direction[i].band_data[j].elevation_fx, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); + floatToFixed_arrL( hQMetaData->q_direction[i].band_data[j].q_azimuth, hQMetaData->q_direction[i].band_data[j].q_azimuth_fx, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); + floatToFixed_arrL( hQMetaData->q_direction[i].band_data[j].q_elevation, hQMetaData->q_direction[i].band_data[j].q_elevation_fx, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); + } + } +#endif if ( ( error = ivas_qmetadata_enc_encode( hMetaData, hQMetaData, 0 ) ) != IVAS_ERR_OK ) { return error; } +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = 0; i < hQMetaData->no_directions; i++ ) + { + for ( j = hQMetaData->q_direction[0].cfg.start_band; j < hQMetaData->q_direction[0].cfg.nbands; ++j ) + { + fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].energy_ratio_fx, hQMetaData->q_direction[i].band_data[j].energy_ratio, Q30, MAX_PARAM_SPATIAL_SUBFRAMES ); + fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].azimuth_fx, hQMetaData->q_direction[i].band_data[j].azimuth, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); + fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].elevation_fx, hQMetaData->q_direction[i].band_data[j].elevation, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); + fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].q_azimuth_fx, hQMetaData->q_direction[i].band_data[j].q_azimuth, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); + fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].q_elevation_fx, hQMetaData->q_direction[i].band_data[j].q_elevation, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); + } + } +#endif } #ifndef IVAS_FLOAT_FIXED @@ -3202,6 +3228,195 @@ void ivas_merge_masa_metadata( return; } +#ifdef IVAS_FLOAT_FIXED +static void quantize_ratio_ism_vector_ivas_fx( + const Word16 *ratio_ism, /* ratio_ism_e */ + Word16 ratio_ism_e, + Word16 *idx, /* Q0 */ + const Word16 nchan_ism, + const Word32 masa_to_total_energy_ratio, + const Word16 idx_sep_object ) +{ + Word16 i, j, best_i, best_i2; + Word16 dist, div, tmp, dist2, best_dist, temp, temp_e, tmp_e, idx_e, best_dist_e, dist_e, dist2_e; + Word16 part_idx_sum, max_sum_idx; + Word16 ratio_ism_loc[MAX_NUM_OBJECTS]; + Word16 no_ism_loc; + + max_sum_idx = sub( shl( 1, PARAM_ISM_POW_RATIO_NBITS ), 1 ); + + test(); + IF( GT_16( idx_sep_object, -1 ) ) + { + temp = BASOP_Util_Divide1616_Scale( 1, max_sum_idx, &temp_e ); + BASOP_Util_Add_MantExp( ratio_ism[idx_sep_object], ratio_ism_e, negate( temp ), temp_e, &tmp ); + + test(); + IF( tmp < 0 ) + { + /* take it out from quantize function */ + Copy( ratio_ism, ratio_ism_loc, idx_sep_object ); + Copy( &ratio_ism[idx_sep_object + 1], &ratio_ism_loc[idx_sep_object], nchan_ism - idx_sep_object - 1 ); + no_ism_loc = sub( nchan_ism, 1 ); + } + ELSE + { + no_ism_loc = nchan_ism; + move16(); + Copy( ratio_ism, ratio_ism_loc, nchan_ism ); + } + } + ELSE + { + no_ism_loc = nchan_ism; + move16(); + Copy( ratio_ism, ratio_ism_loc, nchan_ism ); + } + + test(); + IF( GT_16( nchan_ism, 1 ) ) + { + test(); + IF( GE_32( masa_to_total_energy_ratio, MASA2TOTAL_THR_Q30 ) ) + { + distribute_evenly_ism_fx( idx, max_sum_idx, nchan_ism ); + } + ELSE + { + test(); + IF( GT_16( no_ism_loc, 1 ) ) + { + + dist = 0; + dist_e = 0; + div = div_s( 1, max_sum_idx ); // Q15 + move16(); + move16(); + + part_idx_sum = 0; + move16(); + + FOR( i = 0; i < no_ism_loc; i++ ) + { + idx[i] = mult( ratio_ism_loc[i], max_sum_idx ); // exponent : ratio_ism_e + 15 + move16(); + idx[i] = shl( idx[i], sub( add( ratio_ism_e, 15 ), 15 ) ); // Q0 + move16(); + part_idx_sum = add( part_idx_sum, idx[i] ); + + tmp_e = BASOP_Util_Add_MantExp( ratio_ism_loc[i], ratio_ism_e, negate( imult1616( idx[i], div ) ), 0, &tmp ); // tmp_e + dist_e = BASOP_Util_Add_MantExp( dist, dist_e, mult( tmp, tmp ), add( tmp_e, tmp_e ), &dist ); // dist_e + } + + best_dist = dist; + best_dist_e = dist_e; + best_i2 = -1; + move16(); + move16(); + move16(); + + WHILE( LT_16( part_idx_sum, max_sum_idx ) ) + { + best_i = -1; + move16(); + /* check which index to increase by 1 for a possible improvement */ + + FOR( i = 0; i < no_ism_loc; i++ ) + { + idx[i] = add( idx[i], 1 ); + move16(); + dist2 = 0; + dist2_e = 0; + move16(); + move16(); + + FOR( j = 0; j < no_ism_loc; j++ ) + { + Word32 temp1 = L_mult( idx[i], div ); // Q : 15 + 0 + 1 + Word16 temp1_n = norm_l( temp1 ); + Word16 temp1_16 = extract_h( L_shl( temp1, temp1_n ) ); // Q : Q + temp1_n - 16 + tmp_e = BASOP_Util_Add_MantExp( ratio_ism_loc[i], ratio_ism_e, negate( temp1_16 ), sub( 15, temp1_n ), &tmp ); // tmp_e + dist2_e = BASOP_Util_Add_MantExp( dist2, dist2_e, mult_sat( tmp, tmp ), add( tmp_e, tmp_e ), &dist2 ); // dist_e + } + + BASOP_Util_Add_MantExp( dist2, dist2_e, negate( best_dist ), best_dist_e, &tmp ); + test(); + IF( tmp < 0 ) + { + best_i2 = best_i; + best_i = i; + best_dist = dist2; + best_dist_e = dist2_e; + move16(); + move16(); + move16(); + move16(); + } + idx[i] = sub( idx[i], 1 ); + move16(); + } + + test(); + IF( GT_16( best_i, -1 ) ) + { + idx[best_i] = add( idx[best_i], 1 ); + move16(); + part_idx_sum = add( part_idx_sum, 1 ); + } + ELSE + { + test(); + IF( GT_16( best_i2, -1 ) ) + { + idx[best_i2] = add( idx[best_i2], 1 ); + move16(); + part_idx_sum = add( part_idx_sum, 1 ); + } + ELSE + { + idx[no_ism_loc - 1] = add( idx[no_ism_loc - 1], sub( max_sum_idx, part_idx_sum ) ); + move16(); + part_idx_sum = max_sum_idx; + move16(); + } + } + } + assert( sum_s( idx, no_ism_loc ) == max_sum_idx ); + } + ELSE + { + idx[0] = max_sum_idx; + move16(); + } + + test(); + IF( LT_16( no_ism_loc, nchan_ism ) ) + { + /* insert back the ratio of the separated object */ + FOR( i = nchan_ism - 1; i > idx_sep_object; i-- ) + { + idx[i] = idx[i - 1]; + move16(); + } + idx[idx_sep_object] = 0; + move16(); + } + } + } + ELSE + { + // idx[0] = (int16_t) ( ( ratio_ism[0] ) * ( ( 1 << PARAM_ISM_POW_RATIO_NBITS ) - 1 ) + 0.5f ); + tmp = imult1616( ratio_ism[0], sub( shl( 1, PARAM_ISM_POW_RATIO_NBITS ), 1 ) ); // tmp_e + tmp_e = ratio_ism_e; + move16(); + idx_e = BASOP_Util_Add_MantExp( tmp, tmp_e, 16384 /* 0.5 in Q15 */, 0, &idx[0] ); // idx_e + idx[0] = shl( idx[0], sub( idx_e, 15 ) ); // Q0 + move16(); + } + + return; +} +#else static void quantize_ratio_ism_vector( const float *ratio_ism, @@ -3338,7 +3553,7 @@ static void quantize_ratio_ism_vector( return; } - +#endif static int16_t index_slice_enum( const int16_t *ratio_ism_idx, @@ -3404,6 +3619,29 @@ static void transform_difference_index( return; } +static void transform_difference_index_ivas_fx( + const Word16 *diff_idx, + Word16 *idx, + const Word16 len ) +{ + Word16 i; + FOR( i = 0; i < len; i++ ) + { + IF( diff_idx[i] <= 0 ) + { + idx[i] = negate( shl( diff_idx[i], 1 ) ); + move16(); + } + ELSE + { + idx[i] = sub( shl( diff_idx[i], 1 ), 1 ); + move16(); + } + } + + return; +} + static void transform_index_and_GR_encode( int16_t *diff_idx, /* i : differenc eindex to encode */ @@ -3427,6 +3665,28 @@ static void transform_index_and_GR_encode( return; } +static void transform_index_and_GR_encode_ivas_fx( + Word16 *diff_idx, /* i : differenc eindex to encode */ + const Word16 len, /* i : input length */ + const Word16 GR_order, /* i : GR order */ + BSTR_ENC_HANDLE hMetaData /* i/o: metadata bitstream handle */ +) +{ + Word16 i; + Word16 idx[IVAS_MAX_NUM_OBJECTS]; + + /* transform difference index into positive */ + transform_difference_index_ivas_fx( diff_idx, idx, len ); + + /* GR encoding */ + FOR( i = 0; i < len; i++ ) + { + ivas_qmetadata_encode_extended_gr( hMetaData, idx[i], 100, GR_order ); + } + + return; +} + static int16_t try_differential( const int16_t numCodingBands, @@ -3478,7 +3738,7 @@ static int16_t try_differential( return nbits0; } - +#ifndef IVAS_FLOAT_FIXED static void differential_coding_first_subframe( BSTR_ENC_HANDLE hMetaData, const float *masa_to_total_energy_ratio, @@ -3517,7 +3777,46 @@ static void differential_coding_first_subframe( return; } +#else +static void differential_coding_first_subframe_ivas_fx( + BSTR_ENC_HANDLE hMetaData, + const Word32 *masa_to_total_energy_ratio, // Q30 + const Word16 b_signif, + Word16 ratio_ism_idx[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], + const Word16 nchan_ism, + const Word16 numCodingBands, + const Word16 bits_index ) +{ + Word16 index, b; + Word16 ratio_ism_idx_ref[MAX_NUM_OBJECTS]; + Word16 diff_idx[MAX_NUM_OBJECTS]; + + /* differential encoding*/ + push_next_indice( hMetaData, 0, 1 ); + IF( LT_16( b_signif, numCodingBands ) ) + { + index = index_slice_enum( ratio_ism_idx[b_signif], nchan_ism ); + push_next_indice( hMetaData, index, bits_index ); + + Copy( ratio_ism_idx[b_signif], ratio_ism_idx_ref, nchan_ism ); + + FOR( b = b_signif + 1; b < numCodingBands; b++ ) + { + IF( LT_32( masa_to_total_energy_ratio[b], MASA2TOTAL_THR_Q30 ) ) + { + v_sub_s16_fx( ratio_ism_idx[b], ratio_ism_idx_ref, diff_idx, nchan_ism ); + Copy( ratio_ism_idx[b], ratio_ism_idx_ref, nchan_ism ); + + /* transform difference index into positive */ + transform_index_and_GR_encode_ivas_fx( diff_idx, sub( nchan_ism, 1 ), 0, hMetaData ); + } + } + } + + return; +} +#endif static void independent_coding_ratio_ism_idx( int16_t ratio_ism_idx[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], /* i : ISM ratios */ @@ -3608,7 +3907,8 @@ static int16_t encode_ratio_ism_subframe( const int16_t sf, int16_t ratio_ism_idx_prev_sf[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], BSTR_ENC_HANDLE hMetaData, - const float *masa_to_total_energy_ratio, + // const float *masa_to_total_energy_ratio, + float *masa_to_total_energy_ratio, const int16_t shift_one, const int16_t idx_separated_obj ) { @@ -3667,7 +3967,15 @@ static int16_t encode_ratio_ism_subframe( { if ( nbits > 0 ) { +#ifndef IVAS_FLOAT_FIXED differential_coding_first_subframe( hMetaData, masa_to_total_energy_ratio, b_signif, ratio_ism_idx, nchan_ism, numCodingBands, bits_index ); +#else +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word32 masa_to_total_energy_ratio_fx[MASA_FREQUENCY_BANDS]; + floatToFixed_arrL( masa_to_total_energy_ratio, masa_to_total_energy_ratio_fx, 30, MASA_FREQUENCY_BANDS ); +#endif + differential_coding_first_subframe_ivas_fx( hMetaData, masa_to_total_energy_ratio_fx, b_signif, ratio_ism_idx, nchan_ism, numCodingBands, bits_index ); +#endif nbits = nbits0 + 1; } } @@ -4031,7 +4339,31 @@ static void ivas_encode_masaism_metadata( } /* Quantize ISM ratios */ +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 ratio_ism_fx[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS]; + + Word16 ratio_ism_fx_q = Q_factor_arr( ratio_ism[band], nchan_ism ); + + floatToFixed_arr( ratio_ism[band], ratio_ism_fx[band], ratio_ism_fx_q, nchan_ism ); + + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + floatToFixed_arrL( hOmasaData->masa_to_total_energy_ratio[i], hOmasaData->masa_to_total_energy_ratio_fx[i], Q30, MASA_FREQUENCY_BANDS ); + } +#endif + quantize_ratio_ism_vector_ivas_fx( ratio_ism_fx[band], sub( Q15, ratio_ism_fx_q ), ratio_ism_idx[band], nchan_ism, hOmasaData->masa_to_total_energy_ratio_fx[sf][band], idx_separated_object ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + fixedToFloat_arr( ratio_ism_fx[band], ratio_ism[band], ratio_ism_fx_q, nchan_ism ); + + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + fixedToFloat_arrL( hOmasaData->masa_to_total_energy_ratio_fx[i], hOmasaData->masa_to_total_energy_ratio[i], Q30, MASA_FREQUENCY_BANDS ); + } +#endif +#else quantize_ratio_ism_vector( ratio_ism[band], ratio_ism_idx[band], nchan_ism, hOmasaData->masa_to_total_energy_ratio[sf][band], idx_separated_object ); +#endif if ( n_ism_tmp == numCodingBands && ratio_ism_idx[band][idx_separated_object] != 0 && hOmasaData->masa_to_total_energy_ratio[sf][band] < MASA2TOTAL_THR ) { i = 0; diff --git a/lib_enc/ivas_mc_paramupmix_enc.c b/lib_enc/ivas_mc_paramupmix_enc.c index 06c9dde4d..6b4618eb0 100644 --- a/lib_enc/ivas_mc_paramupmix_enc.c +++ b/lib_enc/ivas_mc_paramupmix_enc.c @@ -54,7 +54,11 @@ * Local function prototypes *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void ivas_mc_paramupmix_dmx_fx( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, Word32 *data_f[], const Word16 input_frame ); +#else static void ivas_mc_paramupmix_dmx( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, float *data_f[], const int16_t input_frame ); +#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] ); @@ -80,6 +84,75 @@ static void quantize_pars( const float *v, const int16_t nq, const float *data, * MC ParamUpmix Encoder main encoding function *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_mc_paramupmix_enc( + Encoder_Struct *st_ivas, /* i/o: IVAS Encoder handle */ + BSTR_ENC_HANDLE hBStr, /* i/o: IVAS Metadata bitstream handle */ + float *data_f[], /* i/o: input/transport MC data */ + Word32 *data_fx[], + const int16_t input_frame /* i : input frame length */ +) +{ + MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix; + int16_t i; + float alphas[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; + float betas[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; + uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS]; + int16_t bit_pos; + + push_wmops( "mc_paramupmix_enc" ); + + hMCParamUpmix = st_ivas->hMCParamUpmix; + bit_pos = 0; + + /* Parameter estimation */ + ivas_mc_paramupmix_param_est_enc( hMCParamUpmix, data_f, input_frame, alphas, betas ); + + for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) + { + put_ec_data( hMCParamUpmix, i, alphas[i], NULL, ALPHA, bit_buffer, &bit_pos ); + put_ec_data( hMCParamUpmix, i, betas[i], alphas[i], BETA, bit_buffer, &bit_pos ); + } + + /* push the PARAM UPMIX MC side info from the temporary buffer into the medatdata bitstream*/ + push_next_bits( hBStr, bit_buffer, bit_pos ); + + /* DMX generation*/ +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = 4; i < 12; i++ ) + { + for ( int l = 0; l < input_frame; l++ ) + { + data_fx[i][l] = floatToFixed( data_f[i][l], st_ivas->q_data_fx ); + } + } +#endif + ivas_mc_paramupmix_dmx_fx( hMCParamUpmix, data_fx, input_frame ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) + { + for ( int k = 0; k < MC_PARAMUPMIX_NCH; k++ ) + { + fixedToFloat_arrL( hMCParamUpmix->midside_fx[i][k], hMCParamUpmix->midside[i][k], st_ivas->q_data_fx, input_frame ); + } + } + for ( i = 4; i < 12; i++ ) + { + for ( int l = 0; l < input_frame; l++ ) + { + data_f[i][l] = fixedToFloat( data_fx[i][l], st_ivas->q_data_fx ); + } + } +#endif +#else + ivas_mc_paramupmix_dmx( hMCParamUpmix, data_f, input_frame ); +#endif + pop_wmops(); + + return; +} +#else void ivas_mc_paramupmix_enc( Encoder_Struct *st_ivas, /* i/o: IVAS Encoder handle */ BSTR_ENC_HANDLE hBStr, /* i/o: IVAS Metadata bitstream handle */ @@ -118,6 +191,7 @@ void ivas_mc_paramupmix_enc( return; } +#endif /*------------------------------------------------------------------------- @@ -155,6 +229,14 @@ ivas_error ivas_mc_paramupmix_enc_open( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MC_MODE_PARAMUPMIX\n" ) ); } set_zero( hMCParamUpmix->midside[i][k], (int16_t) input_frame ); + +#ifdef IVAS_FLOAT_FIXED + if ( ( hMCParamUpmix->midside_fx[i][k] = (Word32 *) malloc( sizeof( Word32 ) * input_frame ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MC_MODE_PARAMUPMIX\n" ) ); + } + set_zero_fx( hMCParamUpmix->midside_fx[i][k], (Word16) input_frame ); +#endif } } hMCParamUpmix->first_frame = 1; @@ -329,6 +411,9 @@ void ivas_mc_paramupmix_enc_close( { for ( k = 0; k < MC_PARAMUPMIX_NCH; k++ ) { +#ifdef IVAS_FLOAT_FIXED + free( ( *hMCParamUpmix )->midside_fx[i][k] ); +#endif free( ( *hMCParamUpmix )->midside[i][k] ); } } @@ -638,6 +723,66 @@ static void put_ec_data( * Computes the time domain down mix signal *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED + +static void ivas_mc_paramupmix_dmx_fx( + MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, /* i/o: MC ParamUpmix encoder handle */ + Word32 *data_fx[], + /* i/o: Input, downmix out */ // st_ivas->q_data_fx + const Word16 input_frame /* i : Input frame length */ +) +{ + Word16 i, l; + const Word16 chan1s[4] = { 4, 5, 8, 9 }; + const Word16 chan2s[4] = { 6, 7, 10, 11 }; + const Word16 chanOut[4] = { 4, 5, 6, 7 }; + const Word16 chanZero[4] = { 8, 9, 10, 11 }; + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + + /* boxes = { 0 1 2 3 [4 6] [5 7] [8 10] [9 11] }; */ + /* 9+11 -> 7 */ + /* 8+10 -> 6 */ + /* 5+7 -> 5 */ + /* 4+6 -> 4 */ + FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) + { + FOR( l = 0; l < input_frame; l++ ) + { + /* mid */ + hMCParamUpmix->midside_fx[i][0][l] = L_shr( L_add( data_fx[chan1s[i]][l], data_fx[chan2s[i]][l] ), 1 ); // st_ivas->q_data_fx + move32(); + /* side */ + hMCParamUpmix->midside_fx[i][1][l] = L_shr( L_sub( data_fx[chan1s[i]][l], data_fx[chan2s[i]][l] ), 1 ); // st_ivas->q_data_fx + move32(); + data_fx[chanOut[i]][l] = hMCParamUpmix->midside_fx[i][0][l]; + move32(); + } + } + + FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) + { + set_zero_fx( data_fx[chanZero[i]], input_frame ); + } + + return; +} + +#else static void ivas_mc_paramupmix_dmx( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, /* i/o: MC ParamUpmix encoder handle */ float *data_f[], /* i/o: Input, downmix out */ @@ -675,6 +820,7 @@ static void ivas_mc_paramupmix_dmx( return; } +#endif // IVAS_FLOAT_FIXED /*------------------------------------------------------------------------- * ivas_mc_paramupmix_param_est_enc() @@ -708,6 +854,11 @@ static void ivas_mc_paramupmix_param_est_enc( 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 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]; @@ -791,7 +942,76 @@ static void ivas_mc_paramupmix_param_est_enc( 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]; + p_fr_imagbuffer_fx[i] = fr_imagbuffer_fx[i]; + move32(); + move32(); + } + + /* prepare Parameter MDFT analysis */ + FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH; i++ ) + { + pp_in_fr_real_fx[i] = p_fr_realbuffer_fx[i]; + pp_in_fr_imag_fx[i] = p_fr_imagbuffer_fx[i]; + move32(); + move32(); + } + + Word16 gb = find_guarded_bits_fx( hMCParamUpmix->hFbMixer->fb_cfg->num_in_chans ) + 1; +#endif + l_ts = input_frame / MAX_PARAM_SPATIAL_SUBFRAMES; + +#ifdef IVAS_FLOAT_FIXED + 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 ); + + ivas_fb_mixer_update_prior_input_fx( hMCParamUpmix->hFbMixer, pcm_in_fx, l_ts, hMCParamUpmix->hFbMixer->fb_cfg->num_in_chans ); + + FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS * 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; + } + } + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + /*To be removed*/ + for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) + { + for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS * 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 ( 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( 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 ); + } + for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS * 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; + + pcm_in[i] += l_ts; + pp_in_fr_real[i] += l_ts; + pp_in_fr_imag[i] += l_ts; + } + } +#endif +#else 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 ); @@ -805,6 +1025,7 @@ static void ivas_mc_paramupmix_param_est_enc( pp_in_fr_imag[i] += l_ts; } } +#endif /*-----------------------------------------------------------------------------------------* * Covariance process diff --git a/lib_enc/ivas_omasa_enc.c b/lib_enc/ivas_omasa_enc.c index ffaab15e5..73e70cbba 100644 --- a/lib_enc/ivas_omasa_enc.c +++ b/lib_enc/ivas_omasa_enc.c @@ -57,7 +57,17 @@ static void ivas_omasa_energy_and_ratio_est( OMASA_ENC_HANDLE hOMasa, OMASA_ENCO static void ivas_omasa_dmx( float *data_in_f[], float data_out_f[][L_FRAME48k], const int16_t input_frame, const int16_t nchan_transport, const int16_t nchan_ism, ISM_METADATA_HANDLE hIsmMeta[], float prev_gains[][MASA_MAX_TRANSPORT_CHANNELS], const float interpolator[L_FRAME48k] ); +#ifdef IVAS_FLOAT_FIXED +static void computeIntensityVector_enc_fx( + const Word16 *band_grouping, /* i : Band grouping for estimation */ + Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */ + Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal */ + const Word16 num_frequency_bands, /* i : Number of frequency bands */ + Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS], /* o : Intensity vector */ + Word16 guard_bits ); +#else static void computeIntensityVector_enc( const int16_t *band_grouping, float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], const int16_t num_frequency_bands, float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] ); +#endif // IVAS_FLOAT_FIXED #ifndef IVAS_FLOAT_FIXED static void computeReferencePower_omasa( const int16_t *band_grouping, float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], float *reference_power, const int16_t enc_param_start_band, const int16_t num_freq_bands ); #else @@ -324,7 +334,11 @@ ivas_error ivas_omasa_enc_config( if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC ) { /* Configure oMASA analysis based on MASA config */ +#ifdef IVAS_FLOAT_FIXED + ivas_omasa_set_config_fx( st_ivas->hOMasa, st_ivas->hMasa, st_ivas->hEncoderConfig->input_Fs, st_ivas->ism_mode ); +#else ivas_omasa_set_config( st_ivas->hOMasa, st_ivas->hMasa, st_ivas->hEncoderConfig->input_Fs, st_ivas->ism_mode ); +#endif // IVAS_FLOAT_FIXED } return IVAS_ERR_OK; @@ -336,7 +350,78 @@ ivas_error ivas_omasa_enc_config( * * Frame-by-frame config for oMASA *--------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_omasa_set_config_fx( + OMASA_ENC_HANDLE hOMasa, /* i/o: OMASA encoder handle */ + MASA_ENCODER_HANDLE hMasa, /* i : MASA encoder handle */ + const Word32 input_Fs, /* i : Input sample rate */ + const ISM_MODE ism_mode /* i : ISM mode */ +) +{ + UWord8 i, maxBin; + + /* Determine the number of bands */ + test(); + IF( EQ_16( ism_mode, ISM_MODE_NONE ) || EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) ) + { + /* use full resolution for the ISM+MASA merge and reduce later */ + hOMasa->nbands = 24; + } + ELSE + { + hOMasa->nbands = hMasa->config.numCodingBands; + } + move16(); + + hOMasa->nCodingBands = hMasa->config.numCodingBands; + move16(); + + /* Determine the number of subframes */ + IF( EQ_16( hMasa->config.joinedSubframes, TRUE ) ) + hOMasa->nSubframes = 1; + ELSE + hOMasa->nSubframes = MAX_PARAM_SPATIAL_SUBFRAMES; + move16(); + + /* Determine band grouping */ + IF( EQ_16( hOMasa->nbands, 24 ) ) + { + Copy( MASA_band_grouping_24, hOMasa->band_grouping, 24 + 1 ); + } + ELSE + { + FOR( i = 0; i < hOMasa->nbands + 1; i++ ) + { + hOMasa->band_grouping[i] = MASA_band_grouping_24[hMasa->data.band_mapping[i]]; + move16(); + } + } + + maxBin = (UWord8) L_shr( L_add( Mpy_32_32( L_shl( input_Fs, 1 ), INV_CLDFB_BANDWIDTH_Q31 ), 1 ), 1 ); /*(uint8_t) ( input_Fs * INV_CLDFB_BANDWIDTH + 0.5f )*/ + move16(); + + FOR( i = 1; i < hOMasa->nbands + 1; i++ ) + { + IF( GE_16( hOMasa->band_grouping[i], maxBin ) ) + { + hOMasa->band_grouping[i] = maxBin; + hOMasa->nbands = i; + move16(); + move16(); + BREAK; + } + } + Copy( DirAC_block_grouping, hOMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 ); + IF( EQ_16( hOMasa->nSubframes, 1 ) ) + { + hOMasa->block_grouping[1] = hOMasa->block_grouping[MAX_PARAM_SPATIAL_SUBFRAMES]; + move16(); + } + + return; +} +#else void ivas_omasa_set_config( OMASA_ENC_HANDLE hOMasa, /* i/o: OMASA encoder handle */ MASA_ENCODER_HANDLE hMasa, /* i : MASA encoder handle */ @@ -395,6 +480,7 @@ void ivas_omasa_set_config( return; } +#endif // IVAS_FLOAT_FIXED /*--------------------------------------------------------------------------* @@ -759,6 +845,7 @@ void ivas_set_ism_importance_interformat( * set bit-rate surplus in combined format coding *--------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED void ivas_set_surplus_brate_enc( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ #ifdef DEBUG_MODE_INFO @@ -767,7 +854,8 @@ void ivas_set_surplus_brate_enc( #endif ) { - if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + test(); + IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) ) { #ifndef IVAS_FLOAT_FIXED st_ivas->hCPE[0]->brate_surplus = st_ivas->hSCE[0]->element_brate - ivas_interformat_brate( ISM_MASA_MODE_PARAM_ONE_OBJ, 1, st_ivas->hSCE[0]->element_brate, st_ivas->hIsmMetaData[0]->ism_imp, 0 ); @@ -777,13 +865,14 @@ void ivas_set_surplus_brate_enc( #endif /* note: ISM st->total_brate is iset in ivas_sce_enc() */ } - else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) + ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) ) { /* it is already set in ivas_ism_enc() */ } - else + ELSE { st_ivas->hCPE[0]->brate_surplus = 0; + move32(); } #ifdef DEBUG_MODE_INFO @@ -815,6 +904,29 @@ void ivas_set_surplus_brate_enc( return; } +#else +void ivas_set_surplus_brate_enc( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +) +{ + if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + { + st_ivas->hCPE[0]->brate_surplus = st_ivas->hSCE[0]->element_brate - ivas_interformat_brate( ISM_MASA_MODE_PARAM_ONE_OBJ, 1, st_ivas->hSCE[0]->element_brate, st_ivas->hIsmMetaData[0]->ism_imp, 0 ); + /* note: ISM st->total_brate is iset in ivas_sce_enc() */ + } + else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) + { + /* it is already set in ivas_ism_enc() */ + } + else + { + st_ivas->hCPE[0]->brate_surplus = 0; + } + + + return; +} +#endif /*--------------------------------------------------------------------------* * ivas_omasa_ener_brate() @@ -823,6 +935,78 @@ void ivas_set_surplus_brate_enc( *--------------------------------------------------------------------------*/ /*! r: OMASA energy bitrate flag */ +#ifdef IVAS_FLOAT_FIXED +Word16 ivas_omasa_ener_brate_fx( + const Word16 nchan_ism, /* i : number of ISMs */ + const Word32 ivas_total_brate, /* i : IVAS total bitrate */ + Word32 *data_f[], /* i : Input / transport audio signals */ + const Word16 input_frame, /* i : Input frame size */ + Word16 data_e /*i:exponent for data_f */ +) +{ + Word16 i, flag_omasa_ener_brate; + Word32 energy_ism, energy_masa; + Word16 energy_ism_e, energy_masa_e; + Word32 temp_32; + Word16 temp, temp_e; + flag_omasa_ener_brate = 0; + energy_ism_e = 0; + energy_masa_e = 0; + move16(); + move16(); + move16(); + + test(); + IF( GE_16( nchan_ism, 3 ) && EQ_32( ivas_total_brate, IVAS_128k ) ) + { + energy_ism = 0; + move32(); + FOR( i = 0; i < nchan_ism; i++ ) + { + temp_e = data_e; + move16(); + temp_32 = sum2_32_fx( data_f[i], input_frame, &temp_e ); + energy_ism = BASOP_Util_Add_Mant32Exp( energy_ism, energy_ism_e, temp_32, temp_e, &energy_ism_e ); + } + + energy_masa = 0; + move32(); + FOR( i = nchan_ism; i < nchan_ism + MASA_MAXIMUM_DIRECTIONS; i++ ) + { + temp_e = data_e; + move16(); + temp_32 = sum2_32_fx( data_f[i], input_frame, &temp_e ); + energy_masa = BASOP_Util_Add_Mant32Exp( energy_masa, energy_masa_e, temp_32, temp_e, &energy_masa_e ); + } + IF( energy_masa_e < 0 ) + { + energy_masa = L_shl( energy_masa, energy_masa_e ); + energy_masa_e = 0; + move16(); + } + energy_masa = L_shr( energy_masa, 1 ); + energy_masa_e = add( energy_masa_e, 1 ); + temp = divide1616( 2, nchan_ism ); /*q15*/ + energy_ism = BASOP_Util_Divide3232_Scale( energy_ism, L_add( energy_masa, L_shr( ONE_IN_Q31, energy_masa_e ) ), &temp_e ); + energy_ism_e = add( temp_e, sub( energy_ism_e, energy_masa_e ) ); + energy_ism = Mpy_32_16_1( energy_ism, temp ); + IF( energy_ism_e < 0 ) + { + energy_ism = L_shl( energy_ism, energy_ism_e ); + energy_ism_e = 0; + move16(); + } + + IF( LT_32( energy_ism, L_shr( ONE_IN_Q31, energy_ism_e ) ) ) + { + flag_omasa_ener_brate = 1; + move16(); + } + } + + return flag_omasa_ener_brate; +} +#else int16_t ivas_omasa_ener_brate( const int16_t nchan_ism, /* i : number of ISMs */ const int32_t ivas_total_brate, /* i : IVAS total bitrate */ @@ -859,7 +1043,7 @@ int16_t ivas_omasa_ener_brate( return flag_omasa_ener_brate; } - +#endif // IVAS_FLOAT_FIXED /*--------------------------------------------------------------------------* * Local functions @@ -904,6 +1088,12 @@ static void ivas_omasa_param_est_enc( Word32 Foa_ImagBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX]; // Q6 #endif float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; +#ifdef IVAS_FLOAT_FIXED + Word32 intensity_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; + Word16 Foa_RealBuffer_e; /*exponent for Foa_RealBuffer_fx*/ + Word16 Foa_ImagBuffer_e; /*exponent for Foa_ImagBuffer_fx*/ + Word16 intensity_real_e; /*exponent for intensity_real_fx*/ +#endif // IVAS_FLOAT_FIXED float direction_vector[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; float diffuseness_vector[MASA_FREQUENCY_BANDS]; int16_t band_m_idx, block_m_idx; @@ -911,6 +1101,19 @@ static void ivas_omasa_param_est_enc( float norm_tmp; int16_t mrange[2], brange[2]; +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + /*To be removed later*/ + set_f( &Foa_RealBuffer[0][0], 0, FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX ); + set_f( &Foa_ImagBuffer[0][0], 0, FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX ); + set_f( &intensity_real[0][0], 0, DIRAC_NUM_DIMS * MASA_FREQUENCY_BANDS ); + /*To be removed later*/ +#endif + set32_fx( &Foa_RealBuffer_fx[0][0], 0, FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX ); + set32_fx( &Foa_ImagBuffer_fx[0][0], 0, FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX ); + set32_fx( &intensity_real_fx[0][0], 0, DIRAC_NUM_DIMS * MASA_FREQUENCY_BANDS ); +#endif // IVAS_FLOAT_FIXED + num_freq_bins = hOMasa->cldfbAnaEnc[0]->no_channels; num_freq_bands = hOMasa->nbands; l_ts = input_frame / CLDFB_NO_COL_MAX; @@ -1002,7 +1205,38 @@ static void ivas_omasa_param_est_enc( } /* Direction estimation */ - computeIntensityVector_enc( hOMasa->band_grouping, Foa_RealBuffer, Foa_ImagBuffer, num_freq_bands, intensity_real ); +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED + f2me_buf( &Foa_RealBuffer[0][0], &Foa_RealBuffer_fx[0][0], &Foa_RealBuffer_e, FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX ); + f2me_buf( &Foa_ImagBuffer[0][0], &Foa_ImagBuffer_fx[0][0], &Foa_ImagBuffer_e, FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX ); +#endif // IVAS_FLOAT_FIXED_TO_BE_REMOVED + /*scaling real and imaginary buffers so they have same exponent for computeIntensityVector_enc*/ + IF( GT_16( Foa_ImagBuffer_e, Foa_RealBuffer_e ) ) + { + Scale_sig32( &Foa_RealBuffer_fx[0][0], FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX, sub( Foa_RealBuffer_e, Foa_ImagBuffer_e ) ); + Foa_RealBuffer_e = Foa_ImagBuffer_e; + move16(); + } + ELSE + { + Scale_sig32( &Foa_ImagBuffer_fx[0][0], FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX, sub( Foa_ImagBuffer_e, Foa_RealBuffer_e ) ); + Foa_ImagBuffer_e = Foa_RealBuffer_e; + move16(); + } + Word16 band_grouping_diff[MASA_FREQUENCY_BANDS], guard_bits, max_band_grouping_diff; + FOR( i = 0; i < num_freq_bands; i++ ) + { + band_grouping_diff[i] = sub( hOMasa->band_grouping[i + 1], hOMasa->band_grouping[i] ); + move16(); + } + maximum_abs_16_fx( band_grouping_diff, num_freq_bands, &max_band_grouping_diff ); + guard_bits = add( find_guarded_bits_fx( max_band_grouping_diff ), 1 ); + computeIntensityVector_enc_fx( hOMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx, guard_bits ); + intensity_real_e = add( add( Foa_RealBuffer_e, Foa_ImagBuffer_e ), guard_bits ); +#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED + me2f_buf( &intensity_real_fx[0][0], intensity_real_e, &intensity_real[0][0], DIRAC_NUM_DIMS * MASA_FREQUENCY_BANDS ); +#endif // IVAS_FLOAT_FIXED_TO_BE_REMOVED +#endif // IVAS_FLOAT_FIXED computeDirectionVectors( intensity_real[0], intensity_real[1], intensity_real[2], 0, num_freq_bands, direction_vector[0], direction_vector[1], direction_vector[2] ); /* Power estimation for diffuseness */ @@ -1421,6 +1655,54 @@ static void ivas_omasa_dmx( } +#ifdef IVAS_FLOAT_FIXED +void computeIntensityVector_enc_fx( + const Word16 *band_grouping, /* i : Band grouping for estimation */ + Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */ + Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal */ + const Word16 num_frequency_bands, /* i : Number of frequency bands */ + Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS], /* o : Intensity vector */ + Word16 guard_bits ) +{ + /* 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 = 0; i < 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]; + img = Cldfb_ImagBuffer[0][j]; + /* Intensity is XYZ order, audio is WYZX order. */ + intensity_real[0][i] = L_add( intensity_real[0][i], L_add( L_shr( Mpy_32_32( Cldfb_RealBuffer[3][j], real ), guard_bits ), L_shr( Mpy_32_32( Cldfb_ImagBuffer[3][j], img ), guard_bits ) ) ); // output Q= 2* input_q -31-guard_bits + move32(); + intensity_real[1][i] = L_add( intensity_real[1][i], L_add( L_shr( Mpy_32_32( Cldfb_RealBuffer[1][j], real ), guard_bits ), L_shr( Mpy_32_32( Cldfb_ImagBuffer[1][j], img ), guard_bits ) ) ); // output Q= 2* input_q -31-guard_bits + move32(); + intensity_real[2][i] = L_add( intensity_real[2][i], L_add( L_shr( Mpy_32_32( Cldfb_RealBuffer[2][j], real ), guard_bits ), L_shr( Mpy_32_32( Cldfb_ImagBuffer[2][j], img ), guard_bits ) ) ); // output Q= 2* input_q -31-guard_bits + move32(); + } + } + + return; +} +#else static void computeIntensityVector_enc( const int16_t *band_grouping, float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], @@ -1457,6 +1739,7 @@ static void computeIntensityVector_enc( return; } +#endif #ifndef IVAS_FLOAT_FIXED diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc.c index 649e2c733..e7d6079fa 100644 --- a/lib_enc/ivas_qmetadata_enc.c +++ b/lib_enc/ivas_qmetadata_enc.c @@ -37,13 +37,13 @@ #include "ivas_cnst.h" #include "prot.h" #include "ivas_prot.h" +#include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "ivas_stat_enc.h" #include "wmc_auto.h" #include "prot.h" #include "prot_fx.h" -#include "ivas_prot_fx.h" #ifdef IVAS_FLOAT_FIXED #include "ivas_rom_com_fx.h" #endif @@ -52,13 +52,35 @@ * Local function prototypes *-----------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED static void ivas_qmetadata_quantize_diffuseness_nrg_ratios( IVAS_QMETADATA_HANDLE hQMetaData, int16_t *needed_bits, int16_t *nbits_diff, int16_t *dfRatioBits, const int16_t hodirac_flag ); +#else +static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_fx( IVAS_QMETADATA_HANDLE hQMetaData, int16_t *needed_bits, int16_t *nbits_diff, int16_t *dfRatioBits, const int16_t hodirac_flag ); +#endif +#ifdef IVAS_FLOAT_FIXED +static Word16 ivas_qmetadata_entropy_encode_diffuseness_fx( + BSTR_ENC_HANDLE hMetaData, + IVAS_QDIRECTION *q_direction, + UWord16 *diffuseness_index_max_ec_frame ); +#else static int16_t ivas_qmetadata_entropy_encode_diffuseness( BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, uint16_t *diffuseness_index_max_ec_frame ); +#endif +#ifdef IVAS_FLOAT_FIXED +static void ivas_qmetadata_reorder_2dir_bands_fx( IVAS_QMETADATA_HANDLE hQMetaData ); +#else static void ivas_qmetadata_reorder_2dir_bands( IVAS_QMETADATA_HANDLE hQMetaData ); +#endif +#ifdef IVAS_FLOAT_FIXED +static Word16 ivas_qmetadata_entropy_encode_df_ratio_fx( + BSTR_ENC_HANDLE hMetaData, + IVAS_QDIRECTION *q_direction, + Word16 *df_ratio_bits ); +#else static int16_t ivas_qmetadata_entropy_encode_df_ratio( BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, int16_t *df_ratio_bits ); +#endif static int16_t ivas_qmetadata_entropy_encode_dir( BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, const uint16_t diffuseness_index_max_ec_frame, const int16_t nbands, const int16_t start_band, const int16_t direction_bits_raw, int16_t max_bits, const int16_t hrmasa_flag ); @@ -104,23 +126,54 @@ static int16_t encode_coherence_indexesDCT0( uint16_t *idx_dct, const int16_t le static int16_t encode_coherence_indexesDCT1( uint16_t *idx_dct, const int16_t len, BSTR_ENC_HANDLE hMetaData ); +#ifdef IVAS_FLOAT_FIXED +static UWord64 create_combined_index( uint16_t *idx_dct, const int16_t len, const int16_t *no_cb_vec ); +#else static uint64_t create_combined_index( uint16_t *idx_dct, const int16_t len, const int16_t *no_cb_vec ); +#endif +#ifdef IVAS_FLOAT_FIXED +static Word16 encode_surround_coherence_fx( + IVAS_QMETADATA *hQMetaData, /* i : quantized metadata */ + BSTR_ENC_HANDLE hMetaData /* i/o: metadata bitstream handle */ +); +#else static int16_t encode_surround_coherence( IVAS_QMETADATA *hQMetaData, BSTR_ENC_HANDLE hMetaData ); +#endif static int16_t write_fixed_rate_direction( BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, const int16_t j_idx, const int16_t len ); static int16_t common_direction( IVAS_QDIRECTION *q_direction, const int16_t band_idx, const int16_t len, const int16_t bits_allowed, BSTR_ENC_HANDLE hMetaData, float *elevation_orig, float *azimuth_orig ); +#ifdef IVAS_FLOAT_FIXED +static Word16 ivas_diffuseness_huff_ec_encode_fx( + BSTR_ENC_HANDLE hMetaData, + const UWord16 idx ); +#else static int16_t ivas_diffuseness_huff_ec_encode( BSTR_ENC_HANDLE hMetaData, const uint16_t idx ); +#endif +#ifdef IVAS_FLOAT_FIXED +static void ivas_diffuseness_huff_ec_prepare_fx( + IVAS_QDIRECTION *q_direction, + Word16 *best_av, + UWord16 *avr_idx, + Word16 *diffuseness_bits_huff ); +#else static void ivas_diffuseness_huff_ec_prepare( IVAS_QDIRECTION *q_direction, int16_t *best_av, uint16_t *avr_idx, int16_t *diffuseness_bits_huff ); +#endif static int16_t coherence_coding_length( const uint16_t *idx_sur_coh_shift, const uint8_t idx_shift_len, const int16_t coding_subbands, const int16_t *no_cv, uint16_t *mr_idx, int16_t *no_cv_shift, int16_t *p_min_idx, int16_t *GR_ord, int16_t *nbits_fr, int16_t *nbits_fr1 ); static int16_t write_2dir_info( BSTR_ENC_HANDLE hMetaData, uint8_t *twoDirBands, const int16_t n, const int16_t k ); +#ifdef IVAS_FLOAT_FIXED +static void transform_azimuth_dir2_fx( + IVAS_QMETADATA_HANDLE hQMetaData, + Word16 *dir2_bands ); +#else static void transform_azimuth_dir2( IVAS_QMETADATA_HANDLE hQMetaData, int16_t *dir2_bands ); +#endif static int16_t calc_var_azi( const IVAS_QDIRECTION *q_direction, const int16_t diffuseness_index_max_ec_frame, const float avg_azimuth, float *avg_azimuth_out ); #ifndef IVAS_FLOAT_FIXED @@ -155,30 +208,31 @@ ivas_error ivas_qmetadata_enc_encode( const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ ) { - int16_t i, bit_pos_start, bit_pos_start_coh; - int16_t next_ind_start; - uint16_t diffuseness_index_max_ec_frame; - uint16_t diffuseness_index_max_ec_frame_pre[QMETADATA_MAX_NO_DIRECTIONS]; - int16_t bits_dir_raw_pre[QMETADATA_MAX_NO_DIRECTIONS]; - int16_t bits_diff_sum; - int16_t bits_diff[QMETADATA_MAX_NO_DIRECTIONS], bits_coherence[QMETADATA_MAX_NO_DIRECTIONS]; - int16_t bits_dir[QMETADATA_MAX_NO_DIRECTIONS], bits_dir_raw; - int16_t extra_bits; + Word16 i, bit_pos_start, bit_pos_start_coh; + Word16 next_ind_start; + UWord16 diffuseness_index_max_ec_frame; + UWord16 diffuseness_index_max_ec_frame_pre[QMETADATA_MAX_NO_DIRECTIONS]; + Word16 bits_dir_raw_pre[QMETADATA_MAX_NO_DIRECTIONS]; + Word16 bits_diff_sum; + Word16 bits_diff[QMETADATA_MAX_NO_DIRECTIONS], bits_coherence[QMETADATA_MAX_NO_DIRECTIONS]; + Word16 bits_dir[QMETADATA_MAX_NO_DIRECTIONS], bits_dir_raw; + Word16 extra_bits; IVAS_QDIRECTION *q_direction; - int16_t nbands, nblocks, start_band; - int16_t ndirections, d; - float azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; - int16_t all_coherence_zero; - int16_t bit_pos_0, total_bits_1dir, bits_no_dirs_coh; - int16_t bits_signaling[QMETADATA_MAX_NO_DIRECTIONS]; - int16_t indice_coherence; - int16_t bits_dir_bands[MASA_MAXIMUM_CODING_SUBBANDS], raw_flag[MASA_MAXIMUM_CODING_SUBBANDS]; - int16_t diff_bits, bits_ec, next_ind_raw_flag; - int16_t dfRatio_bits[MASA_MAXIMUM_CODING_SUBBANDS]; - int16_t bits_surround_coh, no_TF; - int16_t dir2_bands[MASA_MAXIMUM_TWO_DIR_BANDS]; - int16_t ind_order[MASA_MAXIMUM_CODING_SUBBANDS]; - int16_t reduce_bits; + Word16 nbands, nblocks, start_band; + Word16 ndirections, d; + Word32 azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; + float azimuth_orig_flt[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], elevation_orig_flt[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; + Word16 all_coherence_zero; + Word16 bit_pos_0, total_bits_1dir, bits_no_dirs_coh; + Word16 bits_signaling[QMETADATA_MAX_NO_DIRECTIONS]; + Word16 indice_coherence; + Word16 bits_dir_bands[MASA_MAXIMUM_CODING_SUBBANDS], raw_flag[MASA_MAXIMUM_CODING_SUBBANDS]; + Word16 diff_bits, bits_ec, next_ind_raw_flag; + Word16 dfRatio_bits[MASA_MAXIMUM_CODING_SUBBANDS]; + Word16 bits_surround_coh, no_TF; + Word16 dir2_bands[MASA_MAXIMUM_TWO_DIR_BANDS]; + Word16 ind_order[MASA_MAXIMUM_CODING_SUBBANDS]; + Word16 reduce_bits; ivas_error error; error = IVAS_ERR_OK; @@ -195,7 +249,7 @@ ivas_error ivas_qmetadata_enc_encode( all_coherence_zero = 1; bits_no_dirs_coh = 0; - if ( hQMetaData->coherence_flag ) + IF( hQMetaData->coherence_flag ) { all_coherence_zero = hQMetaData->all_coherence_zero; @@ -203,25 +257,33 @@ ivas_error ivas_qmetadata_enc_encode( bits_no_dirs_coh += 1; } - if ( ndirections > 1 ) + IF( GT_16( ndirections, 1 ) ) { /* Reorder 2dir bands for more efficient encoding. */ - if ( !hodirac_flag ) + IF( !hodirac_flag ) { - ivas_qmetadata_reorder_2dir_bands( hQMetaData ); + ivas_qmetadata_reorder_2dir_bands_fx( hQMetaData ); +#if 0 // def IVAS_FLOAT_FIXED_CONVERSIONS + for (i = 0; i < ndirections; i++) { + for (int j = hQMetaData->q_direction[i].cfg.start_band; j < hQMetaData->q_direction[i].cfg.nbands; ++j) + { + floatToFixed_arrL(hQMetaData->q_direction[i].band_data[j].energy_ratio, hQMetaData->q_direction[i].band_data[j].energy_ratio_fx, Q30, MAX_PARAM_SPATIAL_SUBFRAMES); + } + } +#endif } d = 0; - for ( i = hQMetaData->q_direction[1].cfg.start_band; i < hQMetaData->q_direction[1].cfg.nbands; i++ ) + FOR( i = hQMetaData->q_direction[1].cfg.start_band; i < hQMetaData->q_direction[1].cfg.nbands; i++ ) { - if ( hQMetaData->twoDirBands[i] == 1 ) + IF( hQMetaData->twoDirBands[i] == 1 ) { - mvr2r( hQMetaData->q_direction[1].band_data[i].azimuth, hQMetaData->q_direction[1].band_data[d].azimuth, hQMetaData->q_direction[1].cfg.nblocks ); - mvr2r( hQMetaData->q_direction[1].band_data[i].elevation, hQMetaData->q_direction[1].band_data[d].elevation, hQMetaData->q_direction[1].cfg.nblocks ); - mvr2r( hQMetaData->q_direction[1].band_data[i].energy_ratio, hQMetaData->q_direction[1].band_data[d].energy_ratio, hQMetaData->q_direction[1].cfg.nblocks ); + Copy32( hQMetaData->q_direction[1].band_data[i].azimuth_fx, hQMetaData->q_direction[1].band_data[d].azimuth_fx, hQMetaData->q_direction[1].cfg.nblocks ); + Copy32( hQMetaData->q_direction[1].band_data[i].elevation_fx, hQMetaData->q_direction[1].band_data[d].elevation_fx, hQMetaData->q_direction[1].cfg.nblocks ); + Copy32( hQMetaData->q_direction[1].band_data[i].energy_ratio_fx, hQMetaData->q_direction[1].band_data[d].energy_ratio_fx, hQMetaData->q_direction[1].cfg.nblocks ); dir2_bands[d] = i; - if ( hQMetaData->coherence_flag ) + IF( hQMetaData->coherence_flag ) { mvc2c( hQMetaData->q_direction[1].coherence_band_data[i].spread_coherence, hQMetaData->q_direction[1].coherence_band_data[d].spread_coherence, hQMetaData->q_direction[1].cfg.nblocks ); } @@ -231,57 +293,49 @@ ivas_error ivas_qmetadata_enc_encode( bits_no_dirs_coh += write_2dir_info( hMetaData, hQMetaData->twoDirBands, hQMetaData->q_direction[0].cfg.nbands, hQMetaData->numTwoDirBands ); - for ( i = d; i < hQMetaData->q_direction[0].cfg.nbands; i++ ) + FOR( i = d; i < hQMetaData->q_direction[0].cfg.nbands; i++ ) { - set_f( hQMetaData->q_direction[1].band_data[i].energy_ratio, 0.0f, hQMetaData->q_direction[1].cfg.nblocks ); + set32_fx( hQMetaData->q_direction[1].band_data[i].energy_ratio_fx, 0, hQMetaData->q_direction[1].cfg.nblocks ); } hQMetaData->q_direction[1].cfg.nbands = hQMetaData->numTwoDirBands; } /*Quantization of the Diffuseness */ - ivas_qmetadata_quantize_diffuseness_nrg_ratios( hQMetaData, bits_dir_raw_pre, bits_diff, dfRatio_bits, hodirac_flag ); + ivas_qmetadata_quantize_diffuseness_nrg_ratios_fx( hQMetaData, bits_dir_raw_pre, bits_diff, dfRatio_bits, hodirac_flag ); bits_diff_sum = 0; - bits_diff[0] = ivas_qmetadata_entropy_encode_diffuseness( hMetaData, &( hQMetaData->q_direction[0] ), &diffuseness_index_max_ec_frame_pre[0] ); + // TODO + bits_diff[0] = ivas_qmetadata_entropy_encode_diffuseness_fx( hMetaData, &( hQMetaData->q_direction[0] ), &diffuseness_index_max_ec_frame_pre[0] ); bits_diff_sum += bits_diff[0]; - if ( ndirections == 2 ) + IF( EQ_16( ndirections, 2 ) ) { - bits_diff[1] = ivas_qmetadata_entropy_encode_df_ratio( hMetaData, &( hQMetaData->q_direction[1] ), dfRatio_bits ); + bits_diff[1] = ivas_qmetadata_entropy_encode_df_ratio_fx( hMetaData, &( hQMetaData->q_direction[1] ), dfRatio_bits ); bits_diff_sum += bits_diff[1]; } /* 2dir energy ratio encoding reuses index memory. Now that diffRatio and dFRatio have been encoded, * we retrieve index_dirRatio1Inv and index_dirRatio1Inv for further parameter encoding. This is * necessary only for bands that have two concurrent directions. */ - if ( hQMetaData->no_directions == 2 ) + IF( hQMetaData->no_directions == 2 ) { - int16_t j, k, dir2band, index_dirRatio1Inv, index_dirRatio2Inv; + Word16 j, k, dir2band, index_dirRatio1Inv, index_dirRatio2Inv; dir2band = 0; - for ( j = hQMetaData->q_direction[0].cfg.start_band; j < hQMetaData->q_direction[0].cfg.nbands; ++j ) + FOR( j = hQMetaData->q_direction[0].cfg.start_band; j < hQMetaData->q_direction[0].cfg.nbands; ++j ) { - if ( hQMetaData->twoDirBands[j] == 1 ) + IF( hQMetaData->twoDirBands[j] == 1 ) { -#ifdef IVAS_FLOAT_FIXED - /*=====================================flt-2-fix============================================*/ - hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[0] = floatToFixed( hQMetaData->q_direction[0].band_data[j].energy_ratio[0], Q30 ); - hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_fx[0] = floatToFixed( hQMetaData->q_direction[1].band_data[dir2band].energy_ratio[0], Q30 ); - /*=====================================flt-2-fix============================================*/ - index_dirRatio1Inv = masa_sq_fx( L_sub( ONE_IN_Q30, hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[0] ), diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); index_dirRatio2Inv = masa_sq_fx( L_sub( ONE_IN_Q30, hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_fx[0] ), diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); -#else - index_dirRatio1Inv = masa_sq( 1.0f - hQMetaData->q_direction[0].band_data[j].energy_ratio[0], diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); - index_dirRatio2Inv = masa_sq( 1.0f - hQMetaData->q_direction[1].band_data[dir2band].energy_ratio[0], diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); -#endif - for ( k = 0; k < hQMetaData->q_direction[0].cfg.nblocks; k++ ) + + FOR( k = 0; k < hQMetaData->q_direction[0].cfg.nblocks; k++ ) { hQMetaData->q_direction[0].band_data[j].energy_ratio_index[k] = index_dirRatio1Inv; } - for ( k = 0; k < hQMetaData->q_direction[1].cfg.nblocks; k++ ) + FOR( k = 0; k < hQMetaData->q_direction[1].cfg.nblocks; k++ ) { hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[k] = index_dirRatio2Inv; } @@ -291,20 +345,28 @@ ivas_error ivas_qmetadata_enc_encode( } } +#if 0 // def IVAS_FLOAT_FIXED_CONVERSIONS + for (i = 0; i < ndirections; i++) { + for (int j = hQMetaData->q_direction[i].cfg.start_band; j < hQMetaData->q_direction[i].cfg.nbands; ++j) + { + fixedToFloat_arrL(hQMetaData->q_direction[i].band_data[j].energy_ratio_fx, hQMetaData->q_direction[i].band_data[j].energy_ratio, Q30, MAX_PARAM_SPATIAL_SUBFRAMES); + } + } +#endif /* Encode surround coherence */ - if ( ndirections == 2 ) + IF( EQ_16( ndirections, 2 ) ) { - no_TF = hQMetaData->q_direction[0].cfg.nbands * hQMetaData->q_direction[0].cfg.nblocks + hQMetaData->q_direction[1].cfg.nbands * hQMetaData->q_direction[1].cfg.nblocks; - if ( ( all_coherence_zero == 0 ) && ( hQMetaData->metadata_max_bits - bits_no_dirs_coh - 4.3f * no_TF - sum_s( bits_diff, ndirections ) >= MASA_MIN_BITS_SURR_COH ) ) + no_TF = add( imult1616( hQMetaData->q_direction[0].cfg.nbands, hQMetaData->q_direction[0].cfg.nblocks ), imult1616( hQMetaData->q_direction[1].cfg.nbands, hQMetaData->q_direction[1].cfg.nblocks ) ); + IF( EQ_16( all_coherence_zero, 0 ) && ( hQMetaData->metadata_max_bits - bits_no_dirs_coh - ( ( 43 * no_TF ) / 10 ) - sum_s( bits_diff, ndirections ) >= MASA_MIN_BITS_SURR_COH ) ) { - bits_surround_coh = encode_surround_coherence( hQMetaData, hMetaData ); + bits_surround_coh = encode_surround_coherence_fx( hQMetaData, hMetaData ); } - else + ELSE { bits_surround_coh = 0; - for ( i = 0; i < hQMetaData->q_direction[0].cfg.nbands; i++ ) + FOR( i = 0; i < hQMetaData->q_direction[0].cfg.nbands; i++ ) { - if ( hQMetaData->surcoh_band_data != NULL ) + IF( hQMetaData->surcoh_band_data != NULL ) { set_c( (int8_t *) hQMetaData->surcoh_band_data[i].surround_coherence, 0, hQMetaData->q_direction[0].cfg.nblocks ); } @@ -313,19 +375,19 @@ ivas_error ivas_qmetadata_enc_encode( bits_no_dirs_coh += bits_surround_coh; total_bits_1dir = ( ( hQMetaData->metadata_max_bits - bits_no_dirs_coh ) * hQMetaData->q_direction[0].cfg.nbands * hQMetaData->q_direction[0].cfg.nblocks ) / no_TF; } - else + ELSE { no_TF = hQMetaData->q_direction[0].cfg.nbands * hQMetaData->q_direction[0].cfg.nblocks; - if ( ( all_coherence_zero == 0 ) && ( hQMetaData->metadata_max_bits - bits_no_dirs_coh - 4.3f * no_TF - bits_diff[0] >= MASA_MIN_BITS_SURR_COH ) ) + IF( EQ_16( all_coherence_zero, 0 ) && ( hQMetaData->metadata_max_bits - bits_no_dirs_coh - ( ( 43 * no_TF ) / 10 ) - bits_diff[0] >= MASA_MIN_BITS_SURR_COH ) ) { - bits_surround_coh = encode_surround_coherence( hQMetaData, hMetaData ); + bits_surround_coh = encode_surround_coherence_fx( hQMetaData, hMetaData ); } - else + ELSE { bits_surround_coh = 0; - for ( i = 0; i < hQMetaData->q_direction[0].cfg.nbands; i++ ) + FOR( i = 0; i < hQMetaData->q_direction[0].cfg.nbands; i++ ) { - if ( hQMetaData->surcoh_band_data != NULL ) + IF( hQMetaData->surcoh_band_data != NULL ) { set_c( (int8_t *) hQMetaData->surcoh_band_data[i].surround_coherence, 0, hQMetaData->q_direction[0].cfg.nblocks ); } @@ -335,13 +397,13 @@ ivas_error ivas_qmetadata_enc_encode( } /* Loop over number of directions*/ - for ( d = 0; d < ndirections; d++ ) + FOR( d = 0; d < ndirections; d++ ) { q_direction = &( hQMetaData->q_direction[d] ); - if ( d == 1 ) + IF( EQ_16( d, 1 ) ) { - transform_azimuth_dir2( hQMetaData, dir2_bands ); + transform_azimuth_dir2_fx( hQMetaData, dir2_bands ); } nbands = q_direction->cfg.nbands; @@ -351,11 +413,11 @@ ivas_error ivas_qmetadata_enc_encode( bits_dir_raw = bits_dir_raw_pre[d]; /* This sets bit budget correctly for the second direction */ - if ( d == 0 ) + IF( EQ_16( d, 0 ) ) { bits_diff[d] = bits_diff_sum; } - else + ELSE { bits_diff[d] = 0; } @@ -367,21 +429,22 @@ ivas_error ivas_qmetadata_enc_encode( bits_coherence[d] = 0; bit_pos_start_coh = hMetaData->nb_bits_tot; - if ( all_coherence_zero == 0 ) + IF( EQ_16( all_coherence_zero, 0 ) ) { bits_coherence[d] = ivas_qmetadata_quantize_coherence( hQMetaData, d, all_coherence_zero, hMetaData, 0, &indice_coherence, 0 ); } - if ( q_direction->cfg.mc_ls_setup == MC_LS_SETUP_5_1 || q_direction->cfg.mc_ls_setup == MC_LS_SETUP_7_1 ) + IF( q_direction->cfg.mc_ls_setup == MC_LS_SETUP_5_1 || q_direction->cfg.mc_ls_setup == MC_LS_SETUP_7_1 ) { q_direction->not_in_2D = 0; /* Quantize directions*/ - quantize_direction_frame2D( q_direction, azimuth_orig, elevation_orig ); + // TODO : Remove azimuth_orig_flt and elevation_orig_flt once full fixed point + quantize_direction_frame2D( q_direction, azimuth_orig_flt, elevation_orig_flt ); } - else + ELSE { /* Quantize directions*/ - quantize_direction_frame( q_direction, azimuth_orig, elevation_orig, 0 ); + quantize_direction_frame( q_direction, azimuth_orig_flt, elevation_orig_flt, 0 ); } /* Signalling 2D*/ @@ -393,7 +456,7 @@ ivas_error ivas_qmetadata_enc_encode( next_ind_start = hMetaData->nb_ind_tot; /* Encode quantized directions with EC frame-wise*/ - if ( total_bits_1dir + bits_surround_coh <= hQMetaData->qmetadata_max_bit_req ) + IF( LE_16( ( total_bits_1dir + bits_surround_coh ), hQMetaData->qmetadata_max_bit_req ) ) { push_next_indice( hMetaData, 0, 1 ); /*Write 1 bit to signal EC frame-wise (EC1)*/ bits_signaling[d]++; @@ -407,7 +470,7 @@ ivas_error ivas_qmetadata_enc_encode( reduce_bits = hQMetaData->is_masa_ivas_format ? ( total_bits_1dir - ( bits_diff[d] + bits_coherence[d] + bits_signaling[d] ) - 1 ) : MASA_MAX_BITS; bits_ec = ivas_qmetadata_entropy_encode_dir( hMetaData, q_direction, diffuseness_index_max_ec_frame, q_direction->cfg.nbands, q_direction->cfg.start_band, bits_dir_bands[0], reduce_bits, 0 ); - if ( bits_ec < 0 ) + IF( LT_16( bits_ec, 0 ) ) { hMetaData->ind_list[next_ind_raw_flag].value = 1; /*rewrite flag*/ bits_ec = ivas_qmetadata_raw_encode_dir( hMetaData, q_direction, q_direction->cfg.nbands, q_direction->cfg.start_band ); @@ -416,7 +479,7 @@ ivas_error ivas_qmetadata_enc_encode( extra_bits = hQMetaData->metadata_max_bits - ( hMetaData->nb_bits_tot - bit_pos_0 ); /* Encode quantized directions with EC band-wise */ - if ( ( total_bits_1dir + bits_surround_coh <= hQMetaData->qmetadata_max_bit_req ) && ( bits_dir[d] + bits_diff[d] + bits_coherence[d] + bits_signaling[d] > total_bits_1dir ) && q_direction->cfg.nblocks > 1 ) + IF( LE_16( ( total_bits_1dir + bits_surround_coh ), hQMetaData->qmetadata_max_bit_req ) && GT_16( ( bits_dir[d] + bits_diff[d] + bits_coherence[d] + bits_signaling[d] ), total_bits_1dir ) && GT_16( q_direction->cfg.nblocks, 1 ) ) { restore_metadata_buffer( hMetaData, next_ind_start, bit_pos_start ); @@ -427,37 +490,37 @@ ivas_error ivas_qmetadata_enc_encode( /* Write raw flags */ next_ind_raw_flag = hMetaData->nb_ind_tot; - for ( i = start_band; i < nbands; i++ ) + FOR( i = start_band; i < nbands; i++ ) { push_next_indice( hMetaData, 0, 1 ); /* Raw coding flag*/ } bits_dir[d] = 0; diff_bits = bits_diff[d] + bits_coherence[d] + bits_signaling[d] - total_bits_1dir; - for ( i = start_band; i < nbands; i++ ) + FOR( i = start_band; i < nbands; i++ ) { bits_dir_bands[i] = ivas_qmetadata_raw_encode_dir( NULL, q_direction, i + 1, i ); /* Write ec bits */ bits_ec = ivas_qmetadata_entropy_encode_dir( hMetaData, q_direction, diffuseness_index_max_ec_frame, i + 1, i, bits_dir_bands[i], MASA_MAX_BITS, 0 ); - if ( bits_ec >= 0 ) + IF( GE_16( bits_ec, 0 ) ) { bits_dir_bands[i] = bits_ec; raw_flag[i] = 0; } - else + ELSE { raw_flag[i] = 1; } diff_bits += bits_dir_bands[i] + 1; } - small_requantize_direction_frame( q_direction, azimuth_orig, elevation_orig, raw_flag, bits_dir_bands, &diff_bits ); + small_requantize_direction_frame( q_direction, azimuth_orig_flt, elevation_orig_flt, raw_flag, bits_dir_bands, &diff_bits ); - for ( i = start_band; i < nbands; i++ ) + FOR( i = start_band; i < nbands; i++ ) { - if ( raw_flag[i] ) + IF( raw_flag[i] ) { /* Rewrite raw flag value */ hMetaData->ind_list[next_ind_raw_flag + i - start_band].value = 1; @@ -472,7 +535,7 @@ ivas_error ivas_qmetadata_enc_encode( } /* Requantized directions */ - if ( ( total_bits_1dir + bits_surround_coh <= hQMetaData->qmetadata_max_bit_req ) && ( bits_dir[d] + bits_diff[d] + bits_coherence[d] + bits_signaling[d] > total_bits_1dir ) ) + IF( LE_16( ( total_bits_1dir + bits_surround_coh ), hQMetaData->qmetadata_max_bit_req ) && GT_16( ( bits_dir[d] + bits_diff[d] + bits_coherence[d] + bits_signaling[d] ), total_bits_1dir ) ) { /*Bit budget exceeded, bit reduction strategy?*/ @@ -481,44 +544,40 @@ ivas_error ivas_qmetadata_enc_encode( restore_metadata_buffer( hMetaData, next_ind_start, bit_pos_start ); push_next_indice( hMetaData, 1, 1 ); /*Write 1 bit to signal no EC frame-wise (EC1)*/ - if ( nblocks > 1 ) + IF( GT_16( nblocks, 1 ) ) { push_next_indice( hMetaData, 1, 1 ); /*Write 1 bit to signal requantization stage (EC3)*/ bits_signaling[d] = 3; } - else + ELSE { bits_signaling[d] = 2; } - if ( hQMetaData->is_masa_ivas_format == 0 ) + IF( hQMetaData->is_masa_ivas_format == 0 ) { reduce_bits = bits_dir_raw - ( total_bits_1dir - bits_diff[d] - bits_coherence[d] - bits_signaling[d] ); ind_order[0] = -1; } - else + ELSE { ind_order[0] = 0; reduce_bits = min( nbands * nblocks + MASA_BIT_REDUCT_PARAM, bits_dir_raw - ( total_bits_1dir - bits_diff[d] - bits_coherence[d] - bits_signaling[d] ) ); - if ( reduce_bits > bits_dir_raw - nbands * nblocks ) + IF( GT_16( reduce_bits, ( bits_dir_raw - nbands * nblocks ) ) ) { reduce_bits = bits_dir_raw - nbands * nblocks; } } -#ifdef IVAS_FLOAT_FIXED only_reduce_bits_direction_fx( &extra_bits, q_direction, reduce_bits, nbands, nblocks, ind_order ); -#else - only_reduce_bits_direction( &extra_bits, q_direction, reduce_bits, nbands, nblocks, ind_order ); -#endif bits_dir[d] = hMetaData->nb_bits_tot; - requantize_direction_EC_3( &extra_bits, q_direction, nbands, hMetaData, elevation_orig, azimuth_orig, ind_order ); + requantize_direction_EC_3( &extra_bits, q_direction, nbands, hMetaData, elevation_orig_flt, azimuth_orig_flt, ind_order ); bits_dir[d] = hMetaData->nb_bits_tot - bits_dir[d]; } /* finalize writing coherence */ - if ( ( bits_coherence[d] > 0 ) && ( all_coherence_zero == 0 ) && ( nblocks > 1 ) ) + IF( GT_16( bits_coherence[d], 0 ) && EQ_16( all_coherence_zero, 0 ) && GT_16( nblocks, 1 ) ) { bit_pos_start = hMetaData->nb_bits_tot; hMetaData->nb_bits_tot = bit_pos_start_coh; @@ -526,23 +585,30 @@ ivas_error ivas_qmetadata_enc_encode( hMetaData->nb_bits_tot = bit_pos_start; } - if ( d == 0 ) + IF( EQ_16( d, 0 ) ) { total_bits_1dir = hQMetaData->metadata_max_bits - ( hMetaData->nb_bits_tot - bit_pos_0 ); } /* Save quantized DOAs */ - for ( i = start_band; i < nbands; i++ ) + FOR( i = start_band; i < nbands; i++ ) { - mvr2r( q_direction->band_data[i].azimuth, q_direction->band_data[i].q_azimuth, nblocks ); - mvr2r( q_direction->band_data[i].elevation, q_direction->band_data[i].q_elevation, nblocks ); + Copy32( q_direction->band_data[i].azimuth_fx, q_direction->band_data[i].q_azimuth_fx, nblocks ); + Copy32( q_direction->band_data[i].elevation_fx, q_direction->band_data[i].q_elevation_fx, nblocks ); } /* Copy original DOAs back to q_direction*/ +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS for ( i = start_band; i < nbands; i++ ) { - mvr2r( azimuth_orig[i], q_direction->band_data[i].azimuth, nblocks ); - mvr2r( elevation_orig[i], q_direction->band_data[i].elevation, nblocks ); + floatToFixed_arrL( azimuth_orig_flt[i], azimuth_orig[i], Q22, nblocks ); + floatToFixed_arrL( elevation_orig_flt[i], elevation_orig[i], Q22, nblocks ); + } +#endif + FOR( i = start_band; i < nbands; i++ ) + { + Copy32( azimuth_orig[i], q_direction->band_data[i].azimuth_fx, nblocks ); + Copy32( elevation_orig[i], q_direction->band_data[i].elevation_fx, nblocks ); } } @@ -2028,16 +2094,16 @@ static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_hr_512( *------------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED -static void ivas_qmetadata_quantize_diffuseness_nrg_ratios( +static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_fx( IVAS_QMETADATA_HANDLE hQMetaData, int16_t *needed_bits, int16_t *nbits_diff, int16_t *dfRatioBits, const int16_t hodirac_flag ) { - int16_t j, k, dir2band; - int16_t index_dirRatio1Inv, index_dirRatio2Inv, index_dirRatio1Inv_mod, index_dirRatio2Inv_mod; - int16_t index_diff; + Word16 j, k, dir2band; + Word16 index_dirRatio1Inv, index_dirRatio2Inv, index_dirRatio1Inv_mod, index_dirRatio2Inv_mod; + Word16 index_diff; nbits_diff[0] = 0; nbits_diff[1] = 0; @@ -2045,53 +2111,43 @@ static void ivas_qmetadata_quantize_diffuseness_nrg_ratios( needed_bits[1] = 0; dir2band = 0; - for ( j = hQMetaData->q_direction[0].cfg.start_band; j < hQMetaData->q_direction[0].cfg.nbands; ++j ) + FOR( j = hQMetaData->q_direction[0].cfg.start_band; j < hQMetaData->q_direction[0].cfg.nbands; ++j ) { - if ( hQMetaData->no_directions == 2 && hQMetaData->twoDirBands[j] == 1 ) + IF( hQMetaData->no_directions == 2 && hQMetaData->twoDirBands[j] == 1 ) { - float diffRatio, dfRatio, dfRatioQ, diffRatioQ, dirRatio1Q, dirRatio2Q; -#ifdef IVAS_FLOAT_FIXED - Word32 diffRatio_fx, dirRatio1Q_fx, dirRatio2Q_fx; -#endif - float dirRatio1, dirRatio2, sumRatio; - int16_t dfRatio_index, dfRatio_qsteps, dfRatio_bits; + Word32 diffRatio, dfRatio, dfRatioQ, diffRatioQ, dirRatio1Q, dirRatio2Q; /* Q30 */ + Word32 dirRatio1, dirRatio2, sumRatio; /* Q30 */ + Word16 dfRatio_index, dfRatio_qsteps, dfRatio_bits; /* With 2dir metadata, we quantize and transmit diffuse-to-total ratio (diffRatio) and * distribution factor of direct-to-total ratios (dFRatio). This is more efficient and * accurate than simple separate quantization of each direct-to-total ratio or their * separate inverses. */ - if ( hodirac_flag ) + IF( hodirac_flag ) { /* already encoded as total and ratios in HO-DirAC */ - diffRatio = 1.f - hQMetaData->q_direction[0].band_data[j].energy_ratio[0]; - dfRatio = hQMetaData->q_direction[1].band_data[dir2band].energy_ratio[0]; + diffRatio = ( 1 << 30 ) - hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[0]; + dfRatio = hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_fx[0]; } - else + ELSE { - dirRatio1 = hQMetaData->q_direction[0].band_data[j].energy_ratio[0]; - dirRatio2 = hQMetaData->q_direction[1].band_data[dir2band].energy_ratio[0]; + // TODO + dirRatio1 = hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[0]; + dirRatio2 = hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_fx[0]; sumRatio = dirRatio1 + dirRatio2; - diffRatio = 1.0f - sumRatio; - dfRatio = sumRatio < EPSILON ? 0.5f : dirRatio1 / sumRatio; + diffRatio = ( 1 << 30 ) - sumRatio; + dfRatio = sumRatio < EPSILON_FIX ? ( 1 << 29 ) : ( (Word32) div_l( dirRatio1, extract_h( sumRatio ) ) << 15 ); } -#ifdef IVAS_FLOAT_FIXED - /*=====================================flt-2-fix============================================*/ - diffRatio_fx = floatToFixed( diffRatio, Q30 ); - /*=====================================flt-2-fix============================================*/ - - index_diff = masa_sq_fx( diffRatio_fx, diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); -#else - index_diff = masa_sq( diffRatio, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); -#endif - diffRatioQ = diffuseness_reconstructions[index_diff]; + index_diff = masa_sq_fx( diffRatio, diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); + diffRatioQ = diffuseness_reconstructions_fx[index_diff]; - if ( hodirac_flag ) + IF( hodirac_flag ) { dfRatio_bits = ivas_get_df_ratio_bits_hodirac( index_diff ); } - else + ELSE { dfRatio_bits = ivas_get_df_ratio_bits( index_diff ); } @@ -2099,63 +2155,53 @@ static void ivas_qmetadata_quantize_diffuseness_nrg_ratios( dfRatioBits[dir2band] = dfRatio_bits; dfRatio_qsteps = ( 1 << dfRatio_bits ); - if ( hodirac_flag ) + IF( hodirac_flag ) { - dfRatio_index = usquant( dfRatio, &dfRatioQ, 0.0f, 1.f / ( dfRatio_qsteps - 1 ), dfRatio_qsteps ); - dirRatio1Q = 1.f - diffRatioQ; + // TODO + Word16 dfRatioQ16; /* Q14 */ + dfRatio_index = usquant_fx( extract_h( dfRatio ), &dfRatioQ16, 0, ( div_s( 1, ( dfRatio_qsteps - 1 ) ) >> 2 ), dfRatio_qsteps ); + dfRatioQ = (Word32) dfRatioQ16 << 16; + dirRatio1Q = ( 1 << 30 ) - diffRatioQ; dirRatio2Q = dfRatioQ; } - else + ELSE { - dfRatio_index = usquant( dfRatio, &dfRatioQ, 0.5f, 0.5f / ( dfRatio_qsteps - 1 ), dfRatio_qsteps ); + // TODO + Word16 dfRatioQ16; /* Q14 */ + dfRatio_index = usquant_fx( extract_h( dfRatio ), &dfRatioQ16, ( 1 << 13 ), ( div_s( 1, ( dfRatio_qsteps - 1 ) ) >> 3 ), dfRatio_qsteps ); /* Direction quantization requires also separately quantized direct-to-total ratios. Thus, we calculate them. */ - dirRatio1Q = dfRatioQ * ( 1.0f - diffRatioQ ); - dirRatio2Q = ( 1.0f - diffRatioQ ) - dirRatio1Q; + dirRatio1Q = L_shl( Mpy_32_16_1( ( ( 1 << 30 ) - diffRatioQ ), dfRatioQ16 ), 1 ); + dirRatio2Q = ( ( 1 << 30 ) - diffRatioQ ) - dirRatio1Q; } -#ifdef IVAS_FLOAT_FIXED - /*=====================================flt-2-fix============================================*/ - dirRatio1Q_fx = floatToFixed( dirRatio1Q, Q30 ); - /*=====================================flt-2-fix============================================*/ - - index_dirRatio1Inv = masa_sq_fx( L_sub( ONE_IN_Q30, dirRatio1Q_fx ), diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); -#else - index_dirRatio1Inv = masa_sq( 1.0f - dirRatio1Q, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); -#endif + index_dirRatio1Inv = masa_sq_fx( ( 1 << 30 ) - dirRatio1Q, diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); /* Note: To save memory, we store temporarily index_diff and dfRatio_index into first and second direction * energy ratio index variables until they have been encoded. index_dirRatio1Inv and index_dirRatio2Inv are * then later retrieved for further use in encoding. */ - for ( k = 0; k < hQMetaData->q_direction[0].cfg.nblocks; k++ ) + FOR( k = 0; k < hQMetaData->q_direction[0].cfg.nblocks; k++ ) { hQMetaData->q_direction[0].band_data[j].energy_ratio_index[k] = index_diff; - hQMetaData->q_direction[0].band_data[j].energy_ratio[k] = dirRatio1Q; + hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[k] = dirRatio1Q; } nbits_diff[0] += MASA_BITS_ER; - if ( hodirac_flag ) + IF( hodirac_flag ) { - float tmp; - index_dirRatio2Inv = usquant( dirRatio2Q, &tmp, 0.0f, 1.f / ( DIRAC_DIFFUSE_LEVELS - 1 ), DIRAC_DIFFUSE_LEVELS ); + // TODO + Word16 tmp; /* Q14 */ + index_dirRatio2Inv = usquant_fx( extract_h( dirRatio2Q ), &tmp, 0, ( div_s( 1, ( DIRAC_DIFFUSE_LEVELS - 1 ) ) >> 2 ), DIRAC_DIFFUSE_LEVELS ); } else { -#ifdef IVAS_FLOAT_FIXED - /*=====================================flt-2-fix============================================*/ - dirRatio2Q_fx = floatToFixed( dirRatio2Q, Q30 ); - /*=====================================flt-2-fix============================================*/ - - index_dirRatio2Inv = masa_sq_fx( L_sub( ONE_IN_Q30, dirRatio2Q_fx ), diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); -#else - index_dirRatio2Inv = masa_sq( 1.0f - dirRatio2Q, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); -#endif + index_dirRatio2Inv = masa_sq_fx( ( 1 << 30 ) - dirRatio2Q, diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); } - for ( k = 0; k < hQMetaData->q_direction[1].cfg.nblocks; k++ ) + FOR( k = 0; k < hQMetaData->q_direction[1].cfg.nblocks; k++ ) { hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[k] = dfRatio_index; - hQMetaData->q_direction[1].band_data[dir2band].energy_ratio[k] = dirRatio2Q; + hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_fx[k] = dirRatio2Q; } nbits_diff[1] += dfRatio_bits; @@ -2163,20 +2209,16 @@ static void ivas_qmetadata_quantize_diffuseness_nrg_ratios( * fact that with 2dir data, it is harder to achieve separate high direct-to-total ratio values * which are assumed by the direction quantization system. In practice, this improves direction * accuracy when it is perceptual meaningful. */ -#ifdef IVAS_FLOAT_FIXED masa_compensate_two_dir_energy_ratio_index_fx( index_dirRatio1Inv, index_dirRatio2Inv, &index_dirRatio1Inv_mod, &index_dirRatio2Inv_mod, hodirac_flag ); -#else - masa_compensate_two_dir_energy_ratio_index( index_dirRatio1Inv, index_dirRatio2Inv, &index_dirRatio1Inv_mod, &index_dirRatio2Inv_mod, hodirac_flag ); -#endif - for ( k = 0; k < hQMetaData->q_direction[0].cfg.nblocks; k++ ) + FOR( k = 0; k < hQMetaData->q_direction[0].cfg.nblocks; k++ ) { hQMetaData->q_direction[0].band_data[j].energy_ratio_index_mod[k] = index_dirRatio1Inv_mod; hQMetaData->q_direction[0].band_data[j].bits_sph_idx[k] = bits_direction_masa[index_dirRatio1Inv_mod]; } needed_bits[0] += hQMetaData->q_direction[0].cfg.nblocks * bits_direction_masa[index_dirRatio1Inv_mod]; - for ( k = 0; k < hQMetaData->q_direction[1].cfg.nblocks; k++ ) + FOR( k = 0; k < hQMetaData->q_direction[1].cfg.nblocks; k++ ) { hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index_mod[k] = index_dirRatio2Inv_mod; hQMetaData->q_direction[1].band_data[dir2band].bits_sph_idx[k] = bits_direction_masa[index_dirRatio2Inv_mod]; @@ -2185,23 +2227,15 @@ static void ivas_qmetadata_quantize_diffuseness_nrg_ratios( dir2band++; } - else + ELSE { -#ifdef IVAS_FLOAT_FIXED - /*=====================================flt-2-fix============================================*/ - hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[0] = floatToFixed( hQMetaData->q_direction[0].band_data[j].energy_ratio[0], Q30 ); - /*=====================================flt-2-fix============================================*/ + index_dirRatio1Inv = masa_sq_fx( ( 1 << 30 ) - hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[0], diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); - index_dirRatio1Inv = masa_sq_fx( L_sub( ONE_IN_Q30, hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[0] ), diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); -#else - index_dirRatio1Inv = masa_sq( 1.0f - hQMetaData->q_direction[0].band_data[j].energy_ratio[0], diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); -#endif - - for ( k = 0; k < hQMetaData->q_direction[0].cfg.nblocks; k++ ) + FOR( k = 0; k < hQMetaData->q_direction[0].cfg.nblocks; k++ ) { hQMetaData->q_direction[0].band_data[j].energy_ratio_index[k] = index_dirRatio1Inv; hQMetaData->q_direction[0].band_data[j].energy_ratio_index_mod[k] = index_dirRatio1Inv; - hQMetaData->q_direction[0].band_data[j].energy_ratio[k] = 1.0f - diffuseness_reconstructions[index_dirRatio1Inv]; + hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[k] = ( 1 << 30 ) - diffuseness_reconstructions_fx[index_dirRatio1Inv]; hQMetaData->q_direction[0].band_data[j].bits_sph_idx[k] = bits_direction_masa[index_dirRatio1Inv]; } @@ -2369,7 +2403,33 @@ static void ivas_qmetadata_quantize_diffuseness_nrg_ratios( * * *------------------------------------------------------------------------*/ - +#ifdef IVAS_FLOAT_FIXED +static Word16 ivas_diffuseness_huff_ec_encode_fx( + BSTR_ENC_HANDLE hMetaData, + const UWord16 idx ) +{ + Word16 nbits; + nbits = 0; + move16(); + IF( LE_16( idx, DIFF_EC_HUFF_GR0_LIMIT ) ) + { + IF( idx > 0 ) + { + push_next_indice( hMetaData, ( 1 << idx ) - 1, idx ); + nbits = add( nbits, idx ); + } + push_next_indice( hMetaData, 0, 1 ); + nbits = add( nbits, 1 ); + } + ELSE + { + push_next_indice( hMetaData, 511, DIFF_EC_HUFF_GR0_LIMIT + 1 ); + push_next_indice( hMetaData, idx - DIFF_EC_HUFF_GR0_LIMIT - 1, 2 ); + nbits = add( nbits, DIFF_EC_HUFF_GR0_LIMIT + 3 ); + } + return nbits; +} +#else static int16_t ivas_diffuseness_huff_ec_encode( BSTR_ENC_HANDLE hMetaData, const uint16_t idx ) @@ -2394,14 +2454,98 @@ static int16_t ivas_diffuseness_huff_ec_encode( } return nbits; } - +#endif /*------------------------------------------------------------------------- * ivas_diffuseness_huff_ec_prepare() * * *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void ivas_diffuseness_huff_ec_prepare_fx( + IVAS_QDIRECTION *q_direction, + Word16 *best_av, + UWord16 *avr_idx, + Word16 *diffuseness_bits_huff ) +{ + Word16 bits; + Word16 av_crt; + Word16 av; + Word16 av_e; + Word16 sh_idx; + UWord16 ui_sh_idx[MASA_MAXIMUM_CODING_SUBBANDS]; + Word16 b, start_band, nbands; + + start_band = q_direction->cfg.start_band; + move16(); + nbands = q_direction->cfg.nbands; + move16(); + *diffuseness_bits_huff = 0; + move16(); + av = 0; + move16(); + FOR( b = start_band; b < nbands; b++ ) + { + av = add( av, q_direction->band_data[b].energy_ratio_index[0] ); + } + // av = (int16_t) ( 0.5f + av / (float) nbands ); + av = BASOP_Util_Divide1616_Scale( av, nbands, &av_e ); + av = shr_r( av, sub( 15, av_e ) ); + *best_av = av; + move16(); + + *diffuseness_bits_huff = MAX16B; + move16(); + FOR( av_crt = av - 1; av_crt <= av + 1; av_crt++ ) + { + bits = 0; + move16(); + FOR( b = start_band; b < nbands; b++ ) + { + sh_idx = sub( q_direction->band_data[b].energy_ratio_index[0], av_crt ); + // ui_sh_idx[b] = ( sh_idx <= 0 ) ? ( -2 * sh_idx ) : sh_idx * 2 - 1; + IF( sh_idx <= 0 ) + { + ui_sh_idx[b] = negate( shl( sh_idx, 1 ) ); + } + ELSE + { + ui_sh_idx[b] = sub( shl( sh_idx, 1 ), 1 ); + } + if ( GE_32( ui_sh_idx[b], 2 * DIRAC_DIFFUSE_LEVELS - 3 ) ) + { + bits = 100; /* to avoid difference larger than 6 in absolute value */ + move16(); + } + + // bits += ( ui_sh_idx[b] <= DIFF_EC_HUFF_GR0_LIMIT ) ? ( ui_sh_idx[b] + 1 ) : 11; + IF( LE_32( ui_sh_idx[b], DIFF_EC_HUFF_GR0_LIMIT ) ) + { + bits = add( bits, add( ui_sh_idx[b], 1 ) ); + } + ELSE + { + bits = add( bits, 11 ); + } + } + + IF( LT_16( bits, *diffuseness_bits_huff ) ) + { + *diffuseness_bits_huff = bits; + move16(); + Copy( (Word16 *) ui_sh_idx, (Word16 *) avr_idx, nbands ); + *best_av = av_crt; + move16(); + } + } + + *diffuseness_bits_huff = add( *diffuseness_bits_huff, MASA_BITS_ER ); /* for the average */ + move16(); + + return; +} +#else static void ivas_diffuseness_huff_ec_prepare( IVAS_QDIRECTION *q_direction, int16_t *best_av, @@ -2455,13 +2599,147 @@ static void ivas_diffuseness_huff_ec_prepare( return; } +#endif /*------------------------------------------------------------------------- * ivas_qmetadata_entropy_encode_diffuseness() * * encode diffuseness *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static Word16 ivas_qmetadata_entropy_encode_diffuseness_fx( + BSTR_ENC_HANDLE hMetaData, + IVAS_QDIRECTION *q_direction, + UWord16 *diffuseness_index_max_ec_frame ) +{ + Word16 start_bit_pos; + Word16 diffuseness_bits_raw; + Word16 b; + Word16 min_diffuseness_m_index, max_diffuseness_m_index; + Word16 nbands; + Word16 start_band; + + nbands = q_direction->cfg.nbands; + move16(); + start_band = q_direction->cfg.start_band; + move16(); + + start_bit_pos = hMetaData->nb_bits_tot; + move16(); + IF( EQ_16( nbands, 1 ) ) + { + /* If there is only one band, diffuseness should be coded directly as raw with no signaling. */ + push_next_indice( hMetaData, q_direction->band_data[0].energy_ratio_index[0], MASA_BITS_ER ); + *diffuseness_index_max_ec_frame = 5; + move16(); + return sub( hMetaData->nb_bits_tot, start_bit_pos ); + } + + /* compute the number of raw coding bits */ + diffuseness_bits_raw = 0; + move16(); + FOR( b = start_band; b < nbands; b++ ) + { + diffuseness_bits_raw = add( diffuseness_bits_raw, ivas_qmetadata_encode_quasi_uniform_length( q_direction->band_data[b].energy_ratio_index[0], DIRAC_DIFFUSE_LEVELS ) ); + } + + min_diffuseness_m_index = q_direction->band_data[start_band].energy_ratio_index[0]; + move16(); + max_diffuseness_m_index = q_direction->band_data[start_band].energy_ratio_index[0]; + move16(); + + FOR( b = start_band; b < nbands; b++ ) + { + if ( LT_16( q_direction->band_data[b].energy_ratio_index[0], min_diffuseness_m_index ) ) + { + min_diffuseness_m_index = q_direction->band_data[b].energy_ratio_index[0]; + move16(); + } + + if ( GT_16( q_direction->band_data[b].energy_ratio_index[0], max_diffuseness_m_index ) ) + { + max_diffuseness_m_index = q_direction->band_data[b].energy_ratio_index[0]; + move16(); + } + } + + IF( LT_16( nbands, DIFF_EC_HUFF_BAND_LIMIT ) ) + { + /* Use similarity coding approach or raw coding when there is a low number of bands. */ + /* one bit is used to indicate whether diffuseness values are entropy coded or coded raw */ + IF( EQ_16( min_diffuseness_m_index, max_diffuseness_m_index ) ) /* all values are equal */ + { + push_next_indice( hMetaData, 0, 1 ); /* dif_use_raw_coding */ + push_next_indice( hMetaData, 1, 1 ); /* dif_have_unique_value */ + ivas_qmetadata_encode_quasi_uniform( hMetaData, min_diffuseness_m_index, DIRAC_DIFFUSE_LEVELS ); /* dif_unique_value */ + } + ELSE IF( EQ_16( add( min_diffuseness_m_index, 1 ), max_diffuseness_m_index ) ) /* only two consecutive values are present */ + { + push_next_indice( hMetaData, 0, 1 ); /* dif_use_raw_coding */ + push_next_indice( hMetaData, 0, 1 ); /* dif_have_unique_value */ + ivas_qmetadata_encode_quasi_uniform( hMetaData, min_diffuseness_m_index, DIRAC_DIFFUSE_LEVELS - 1 ); /* dif_min_value */ + + FOR( b = start_band; b < nbands; b++ ) + { + push_next_indice( hMetaData, sub( q_direction->band_data[b].energy_ratio_index[0], min_diffuseness_m_index ), 1 ); /* dif_bit_offset_values */ + } + } + ELSE /* raw coding */ + { + push_next_indice( hMetaData, 1, 1 ); /* dif_use_raw_coding */ + + FOR( b = start_band; b < nbands; b++ ) + { + ivas_qmetadata_encode_quasi_uniform( hMetaData, q_direction->band_data[b].energy_ratio_index[0], DIRAC_DIFFUSE_LEVELS ); /* dif_values */ + } + } + } + ELSE + { + /* Use Huffman-coding approach or raw coding when there is a high number of bands. */ + Word16 diffuseness_bits_huff; + Word16 best_av; + UWord16 avr_idx[MASA_MAXIMUM_CODING_SUBBANDS]; + + /* First, obtain average indices and bit usage for Huffman-coding. */ + ivas_diffuseness_huff_ec_prepare_fx( q_direction, &best_av, avr_idx, &diffuseness_bits_huff ); + + /* If there is benefit, use Huffman-coding. Otherwise, use raw coding. */ + IF( LT_16( diffuseness_bits_huff, diffuseness_bits_raw ) ) + { + /* Signal Huffman EC */ + push_next_indice( hMetaData, 0, 1 ); + push_next_indice( hMetaData, best_av, MASA_BITS_ER ); + FOR( b = start_band; b < nbands; b++ ) + { + ivas_diffuseness_huff_ec_encode_fx( hMetaData, avr_idx[b] ); + } + } + ELSE + { + /* Signal raw */ + push_next_indice( hMetaData, 1, 1 ); + FOR( b = start_band; b < nbands; b++ ) + { + ivas_qmetadata_encode_quasi_uniform( hMetaData, q_direction->band_data[b].energy_ratio_index[0], DIRAC_DIFFUSE_LEVELS ); /* dif_values */ + } + } + } + + *diffuseness_index_max_ec_frame = 5; + move16(); + /* adaptively select the diffuseness_index_max_ec threshold */ + if ( GT_16( min_diffuseness_m_index, 5 ) ) + { + *diffuseness_index_max_ec_frame = DIRAC_DIFFUSE_LEVELS - 1; + move16(); + } + + + return sub( hMetaData->nb_bits_tot, start_bit_pos ); +} +#else static int16_t ivas_qmetadata_entropy_encode_diffuseness( BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, @@ -2583,14 +2861,131 @@ static int16_t ivas_qmetadata_entropy_encode_diffuseness( return ( hMetaData->nb_bits_tot - start_bit_pos ); } - +#endif /*------------------------------------------------------------------------- * ivas_qmetadata_entropy_encode_df_ratio() * * encode dfRatio *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static Word16 ivas_qmetadata_entropy_encode_df_ratio_fx( + BSTR_ENC_HANDLE hMetaData, + IVAS_QDIRECTION *q_direction, + Word16 *df_ratio_bits ) +{ + Word16 start_bit_pos; + Word16 bits_raw; + Word16 b; + Word16 min_index, max_index; + Word16 nbands, start_band; + Word16 max_df_ratio_bits; + Word16 ec_mode = 0; + move16(); + Word16 max_alphabet_size; + + nbands = q_direction->cfg.nbands; + move16(); + start_band = q_direction->cfg.start_band; + move16(); + + start_bit_pos = hMetaData->nb_bits_tot; + move16(); + + IF( EQ_16( nbands, 1 ) ) + { + /* If there is only one band, ratio should be coded directly as raw with no signaling. */ + push_next_indice( hMetaData, q_direction->band_data[0].energy_ratio_index[0], df_ratio_bits[0] ); + + return sub( hMetaData->nb_bits_tot, start_bit_pos ); + } + + /* compute the number of raw coding bits */ + bits_raw = 0; + move16(); + max_df_ratio_bits = 0; + move16(); + FOR( b = start_band; b < nbands; b++ ) + { + bits_raw = add( bits_raw, df_ratio_bits[b] ); + max_df_ratio_bits = s_max( df_ratio_bits[b], max_df_ratio_bits ); + } + + min_index = q_direction->band_data[start_band].energy_ratio_index[0]; + move16(); + max_index = q_direction->band_data[start_band].energy_ratio_index[0]; + move16(); + FOR( b = start_band; b < nbands; b++ ) + { + if ( LT_16( q_direction->band_data[b].energy_ratio_index[0], min_index ) ) + { + min_index = q_direction->band_data[b].energy_ratio_index[0]; + move16(); + } + + if ( GT_16( q_direction->band_data[b].energy_ratio_index[0], max_index ) ) + { + max_index = q_direction->band_data[b].energy_ratio_index[0]; + move16(); + } + } + + /* Decide what modes are possible */ + IF( GE_16( bits_raw, add( add( max_df_ratio_bits, 2 ), nbands ) ) ) + { + ec_mode = 2; + } + ELSE IF( GE_16( bits_raw, add( max_df_ratio_bits, 1 ) ) ) + { + ec_mode = 1; + } + ELSE + { + ec_mode = 0; + } + move16(); + max_alphabet_size = shl( 1, max_df_ratio_bits ); + + test(); + test(); + IF( EQ_16( min_index, max_index ) && ec_mode > 0 ) /* all values are equal */ + { + push_next_indice( hMetaData, 0, 1 ); /* Signal between EC and raw */ + if ( GT_16( ec_mode, 1 ) ) + { + /* Only use bit for signaling if necessary */ + push_next_indice( hMetaData, 0, 1 ); /* Signal between one value or bandwise diff mode */ + } + + ivas_qmetadata_encode_quasi_uniform( hMetaData, min_index, max_alphabet_size ); + } + ELSE IF( EQ_16( add( min_index, 1 ), max_index ) && GT_16( ec_mode, 1 ) ) /* only two consecutive values are present */ + { + push_next_indice( hMetaData, 0, 1 ); + push_next_indice( hMetaData, 1, 1 ); + ivas_qmetadata_encode_quasi_uniform( hMetaData, min_index, max_alphabet_size - 1 ); + + FOR( b = start_band; b < nbands; b++ ) + { + push_next_indice( hMetaData, q_direction->band_data[b].energy_ratio_index[0] - min_index, 1 ); /* Band-wise offset values */ + } + } + ELSE /* raw coding */ + { + IF( ec_mode > 0 ) + { + push_next_indice( hMetaData, 1, 1 ); /* Only signal raw mode if not implicitly using it */ + } + + FOR( b = start_band; b < nbands; b++ ) + { + ivas_qmetadata_encode_quasi_uniform( hMetaData, q_direction->band_data[b].energy_ratio_index[0], shl( 1, df_ratio_bits[b] ) ); /* dif_values */ + } + } + return sub( hMetaData->nb_bits_tot, start_bit_pos ); +} +#else static int16_t ivas_qmetadata_entropy_encode_df_ratio( BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, @@ -2694,7 +3089,7 @@ static int16_t ivas_qmetadata_entropy_encode_df_ratio( return ( hMetaData->nb_bits_tot - start_bit_pos ); } - +#endif /*------------------------------------------------------------------------- * restore_metadata_buffer() @@ -5899,7 +6294,30 @@ static ivas_error write_ec_direction( /*-----------------------------------------------------------------------* * Local functions (coherence Q and coding) *-----------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +/*! r: index */ +static UWord64 create_combined_index( + UWord16 *idx_dct, /* i : indexes to combine */ + const Word16 len, /* i : number of indexes */ + const Word16 *no_cb_vec /* i : how many codewords for each position */ +) +{ + Word16 i; + UWord64 idx, base; + + base = 1; + move64(); + idx = 0; + move64(); + FOR( i = 0; i < len; i++ ) + { + idx = W_add( idx, base * idx_dct[i] ); + base *= no_cb_vec[i]; + } + return idx; +} +#else /*! r: index */ static uint64_t create_combined_index( uint16_t *idx_dct, /* i : indexes to combine */ @@ -5920,7 +6338,7 @@ static uint64_t create_combined_index( return idx; } - +#endif /*-----------------------------------------------------------------------* * encoding DCT0 coeffs with joint index @@ -6004,7 +6422,103 @@ static int16_t encode_coherence_indexesDCT0( * * *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static Word16 coherence_coding_length( + const UWord16 *idx_sur_coh_shift, + const UWord8 idx_shift_len, + const Word16 coding_subbands, + const Word16 *no_cv, + UWord16 *mr_idx, + Word16 *no_cv_shift, + Word16 *p_min_idx, + Word16 *GR_ord, + Word16 *nbits_fr, + Word16 *nbits_fr1 ) +{ + Word16 half_coding_subbands; + Word16 j; + Word16 nbits; + UWord64 no_cb; + Word16 min_idx; + + half_coding_subbands = 0; + move16(); + + IF( GT_16( sum16_fx( no_cv, coding_subbands ), MASA_COH_LIMIT_2IDX ) ) + { + + no_cb = 1; + move16(); + half_coding_subbands = shr( coding_subbands, 1 ); + move16(); + FOR( j = 0; j < half_coding_subbands; j++ ) + { + no_cb = no_cb * no_cv[j]; + } + //*nbits_fr = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); + IF( LE_64( no_cb, 1 ) ) + { + *nbits_fr = 0; + } + ELSE + { + *nbits_fr = sub( 63, W_norm( W_sub( no_cb, 1 ) ) ); + } + move16(); + no_cb = 1; + move16(); + FOR( j = half_coding_subbands; j < coding_subbands; j++ ) + { + no_cb = no_cb * no_cv[j]; + } + //*nbits_fr1 = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); + IF( LE_64( no_cb, 1 ) ) + { + *nbits_fr1 = 0; + } + ELSE + { + *nbits_fr1 = sub( 63, W_norm( W_sub( no_cb, 1 ) ) ); + } + move16(); + } + ELSE + { + no_cb = 1; + FOR( j = 0; j < coding_subbands; j++ ) + { + no_cb = no_cb * no_cv[j]; + } + //*nbits_fr = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); + IF( LE_64( no_cb, 1 ) ) + { + *nbits_fr = 0; + } + ELSE + { + *nbits_fr = sub( 63, W_norm( W_sub( no_cb, 1 ) ) ); + } + move16(); + *nbits_fr1 = 0; + move16(); + } + + + minimum_s( (const Word16 *) idx_sur_coh_shift, (int16_t) idx_shift_len, &min_idx ); + FOR( j = 0; j < idx_shift_len; j++ ) + { + mr_idx[j] = sub( idx_sur_coh_shift[j], min_idx ); + move16(); + no_cv_shift[j] = sub( no_cv_shift[j], min_idx ); + move16(); + } + nbits = add( add( min_idx, 1 ), GR_bits_new( mr_idx, no_cv_shift, idx_shift_len, *GR_ord, 1, GR_ord ) ); + *p_min_idx = min_idx; + move16(); + return nbits; +} +#else static int16_t coherence_coding_length( const uint16_t *idx_sur_coh_shift, const uint8_t idx_shift_len, @@ -6065,7 +6579,7 @@ static int16_t coherence_coding_length( return nbits; } - +#endif /*-------------------------------------------------------------------* * encode_spread_coherence_1sf() @@ -6263,204 +6777,220 @@ static int16_t encode_spread_coherence_1sf( /*! r: number of bits written */ #ifdef IVAS_FLOAT_FIXED -static int16_t encode_surround_coherence( +static Word16 encode_surround_coherence_fx( IVAS_QMETADATA *hQMetaData, /* i : quantized metadata */ BSTR_ENC_HANDLE hMetaData /* i/o: metadata bitstream handle */ ) { - int16_t i, j, k; - int16_t idx_ER, idx16; - int16_t nbits, nbits_fr; - uint16_t idx_sur_coh[MASA_MAXIMUM_CODING_SUBBANDS]; - uint16_t mr_idx_sur_coh[MASA_MAXIMUM_CODING_SUBBANDS]; - int16_t GR_ord, bits_GR; - uint64_t idx, idx1; - int16_t no_idx16; - int16_t no_cv[MASA_MAXIMUM_CODING_SUBBANDS]; - float error_ratio_surr; -#ifdef IVAS_FLOAT_FIXED - Word32 error_ratio_surr_fx; -#endif + Word16 i, j, k; + Word16 idx_ER, idx16; + Word16 nbits, nbits_fr; + UWord16 idx_sur_coh[MASA_MAXIMUM_CODING_SUBBANDS]; + UWord16 mr_idx_sur_coh[MASA_MAXIMUM_CODING_SUBBANDS]; + Word16 GR_ord, bits_GR; + UWord64 idx, idx1; + Word16 no_idx16; + Word16 no_cv[MASA_MAXIMUM_CODING_SUBBANDS]; + Word32 error_ratio_surr; // Q30 IVAS_QDIRECTION *q_direction; - int16_t half_coding_subbands, nbits_fr1, coding_subbands; - int16_t all_coherence_zero; - uint16_t idx_sur_coh_shift[MASA_MAXIMUM_CODING_SUBBANDS]; - uint8_t idx_shift; - int16_t max_val = 0, nbits_max; - int16_t no_cv_shift[MASA_MAXIMUM_CODING_SUBBANDS], min_idx; + Word16 half_coding_subbands, nbits_fr1, coding_subbands; + Word16 all_coherence_zero; + UWord16 idx_sur_coh_shift[MASA_MAXIMUM_CODING_SUBBANDS]; + UWord8 idx_shift; + Word16 max_val = 0, nbits_max; + move16(); + Word16 no_cv_shift[MASA_MAXIMUM_CODING_SUBBANDS], min_idx; coding_subbands = hQMetaData->q_direction[0].cfg.nbands; + move16(); all_coherence_zero = hQMetaData->all_coherence_zero; + move16(); q_direction = &( hQMetaData->q_direction[0] ); nbits = 0; + move16(); - if ( all_coherence_zero == 1 ) + IF( EQ_16( all_coherence_zero, 1 ) ) { nbits = 0; + move16(); } - else + ELSE { GR_ord = 1; + move16(); k = 0; + move16(); idx_shift = 0; - for ( j = 0; j < coding_subbands; j++ ) + move16(); + FOR( j = 0; j < coding_subbands; j++ ) { - if ( hQMetaData->no_directions == 2 ) + IF( EQ_16( hQMetaData->no_directions, 2 ) ) { - k += hQMetaData->twoDirBands[j]; - idx16 = max( k - 1, 0 ); - error_ratio_surr = 1.0f - q_direction[0].band_data[j].energy_ratio[0] - q_direction[1].band_data[idx16].energy_ratio[0] * hQMetaData->twoDirBands[j]; + k = add( k, hQMetaData->twoDirBands[j] ); + idx16 = s_max( sub( k, 1 ), 0 ); + error_ratio_surr = W_sat_l( W_sub( W_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[0] ), W_mult0_32_32( q_direction[1].band_data[idx16].energy_ratio_fx[0], hQMetaData->twoDirBands[j] ) ) ); } - else + ELSE { - error_ratio_surr = 1.0f - q_direction[0].band_data[j].energy_ratio[0]; + error_ratio_surr = L_sub( ONE_IN_Q30, q_direction[0].band_data[j].energy_ratio_fx[0] ); } - if ( error_ratio_surr <= 0 ) + IF( error_ratio_surr <= 0 ) { error_ratio_surr = 0; + move16(); idx_sur_coh[j] = 0; + move16(); no_cv[j] = 1; + move16(); hQMetaData->surcoh_band_data[j].surround_coherence[0] = 0; /* sur_coherence_cb_masa[idx_cb_sur_coh_masa[DIRAC_DIFFUSE_LEVELS - 1] * MASA_MAX_NO_CV_SUR_COH]; */ + move16(); } - else + ELSE { -#ifdef IVAS_FLOAT_FIXED - /*=====================================flt-2-fix============================================*/ - error_ratio_surr_fx = floatToFixed( error_ratio_surr, Q30 ); - /*=====================================flt-2-fix============================================*/ - - idx_ER = masa_sq_fx( error_ratio_surr_fx, diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); -#else - idx_ER = masa_sq( error_ratio_surr, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); -#endif + idx_ER = masa_sq_fx( error_ratio_surr, diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); - idx_sur_coh[j] = squant_int( hQMetaData->surcoh_band_data[j].surround_coherence[0], &hQMetaData->surcoh_band_data[j].surround_coherence[0], - &sur_coherence_cb_masa[idx_cb_sur_coh_masa[idx_ER] * MASA_MAX_NO_CV_SUR_COH], idx_cb_sur_coh_masa[idx_ER] + 2 ); + idx_sur_coh[j] = squant_int_fx( hQMetaData->surcoh_band_data[j].surround_coherence[0], &hQMetaData->surcoh_band_data[j].surround_coherence[0], + &sur_coherence_cb_masa[idx_cb_sur_coh_masa[idx_ER] * MASA_MAX_NO_CV_SUR_COH], add( idx_cb_sur_coh_masa[idx_ER], 2 ) ); + move16(); - no_cv[j] = idx_cb_sur_coh_masa[idx_ER] + 2; + no_cv[j] = add( idx_cb_sur_coh_masa[idx_ER], 2 ); + move16(); no_cv_shift[idx_shift] = no_cv[j]; + move16(); idx_sur_coh_shift[idx_shift++] = idx_sur_coh[j]; + move16(); } } - if ( sum_s( no_cv, coding_subbands ) == coding_subbands ) + IF( EQ_16( sum16_fx( no_cv, coding_subbands ), coding_subbands ) ) { return 0; } nbits_max = 0; - if ( coding_subbands > MASA_LIMIT_NO_BANDS_SUR_COH ) + move16(); + IF( GT_16( coding_subbands, MASA_LIMIT_NO_BANDS_SUR_COH ) ) { - j = maximum_s( (int16_t *) idx_sur_coh, coding_subbands, &max_val ); - for ( j = 0; j < coding_subbands; j++ ) + j = maximum_s( (Word16 *) idx_sur_coh, coding_subbands, &max_val ); + FOR( j = 0; j < coding_subbands; j++ ) { - if ( no_cv[j] > max_val + 1 ) + if ( GT_16( no_cv[j], add( max_val, 1 ) ) ) { - no_cv[j] = max_val + 1; + no_cv[j] = add( max_val, 1 ); + move16(); } } - nbits_max = MASA_MAX_NO_CV_SUR_COH - max_val; /* encoded with GR0 as max_no_vals - no_vals*/ + nbits_max = sub( MASA_MAX_NO_CV_SUR_COH, max_val ); /* encoded with GR0 as max_no_vals - no_vals*/ } nbits = coherence_coding_length( idx_sur_coh_shift, idx_shift, coding_subbands, no_cv, mr_idx_sur_coh, no_cv_shift, &min_idx, &GR_ord, &nbits_fr, &nbits_fr1 ); - half_coding_subbands = coding_subbands / 2; + half_coding_subbands = shr( coding_subbands, 1 ); idx1 = 0; + move16(); /* should check how to encode the average - check distribution */ - if ( nbits_fr + nbits_fr1 + nbits_max < nbits ) + IF( LT_16( add( add( nbits_fr, nbits_fr1 ), nbits_max ), nbits ) ) { /* write flag*/ push_next_indice( hMetaData, 0, 1 ); /* create combined index */ - nbits = nbits_fr + nbits_fr1 + 1; - if ( coding_subbands > MASA_LIMIT_NO_BANDS_SUR_COH ) + nbits = add( add( nbits_fr, nbits_fr1 ), 1 ); + IF( GT_16( coding_subbands, MASA_LIMIT_NO_BANDS_SUR_COH ) ) { /* write max value*/ bits_GR = hMetaData->nb_bits_tot; + move16(); ivas_qmetadata_encode_extended_gr( hMetaData, MASA_MAX_NO_CV_SUR_COH - max_val - 1, MASA_MAX_NO_CV_SUR_COH, 0 ); - nbits += hMetaData->nb_bits_tot - bits_GR; + nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_GR ) ); } - if ( nbits_fr1 > 0 ) + IF( nbits_fr1 > 0 ) { idx = create_combined_index( idx_sur_coh, half_coding_subbands, no_cv ); idx1 = create_combined_index( &idx_sur_coh[half_coding_subbands], half_coding_subbands, &no_cv[half_coding_subbands] ); } - else + ELSE { idx = create_combined_index( idx_sur_coh, coding_subbands, no_cv ); } - if ( nbits_fr % 16 == 0 ) + /*if ( nbits_fr % 16 == 0 ) { no_idx16 = nbits_fr / 16; } else { no_idx16 = (int16_t) round_f( ( nbits_fr / 16.0f + 0.5f ) ); - } + }*/ + no_idx16 = shr_r( nbits_fr, 4 ); /* write combined index */ k = nbits_fr; - for ( i = 0; i < no_idx16 - 1; i++ ) + move16(); + FOR( i = 0; i < no_idx16 - 1; i++ ) { - k -= 16; + k = sub( k, 16 ); push_next_indice( hMetaData, ( ( idx >> k ) & 65535 ), 16 ); /* 16 bits */ } push_next_indice( hMetaData, ( idx & ( ( 1 << k ) - 1 ) ), k ); - if ( nbits_fr1 > 0 ) + IF( nbits_fr1 > 0 ) { - if ( nbits_fr1 % 16 == 0 ) + /*if ( nbits_fr1 % 16 == 0 ) { no_idx16 = nbits_fr1 / 16; } else { no_idx16 = (int16_t) round_f( ( nbits_fr1 / 16.0f + 0.5f ) ); - } + }*/ + no_idx16 = shr_r( nbits_fr1, 4 ); assert( no_idx16 <= 4 ); k = nbits_fr1; - for ( i = 0; i < no_idx16 - 1; i++ ) + move16(); + FOR( i = 0; i < no_idx16 - 1; i++ ) { - k -= 16; + k = sub( k, 16 ); push_next_indice( hMetaData, ( ( idx1 >> k ) & 65535 ), 16 ); /* 16 bits */ } push_next_indice( hMetaData, ( idx1 & ( ( 1 << k ) - 1 ) ), k ); } } - else + ELSE { /* write flag */ nbits = 1; + move16(); /* write flag*/ push_next_indice( hMetaData, 1, 1 ); /* write GR_ord */ push_next_indice( hMetaData, GR_ord, 1 ); - nbits += 1; + nbits = add( nbits, 1 ); /* write the min */ bits_GR = hMetaData->nb_bits_tot; + move16(); ivas_qmetadata_encode_extended_gr( hMetaData, min_idx, MASA_MAX_NO_CV_SUR_COH, 0 ); - nbits += hMetaData->nb_bits_tot - bits_GR; + nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_GR ) ); /* write GR data */ - for ( j = 0; j < idx_shift; j++ ) + FOR( j = 0; j < idx_shift; j++ ) { bits_GR = hMetaData->nb_bits_tot; + move16(); ivas_qmetadata_encode_extended_gr( hMetaData, mr_idx_sur_coh[j], no_cv_shift[j], GR_ord ); - nbits += hMetaData->nb_bits_tot - bits_GR; + nbits = add( nbits, sub( hMetaData->nb_bits_tot, bits_GR ) ); } } } @@ -7641,7 +8171,88 @@ static int16_t ivas_qmetadata_quantize_coherence( * Reorders metadata on 2dir bands such that direct-to-total ratio of first direction is * always larger or equal to direct-to-total ratio of second direction. *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void ivas_qmetadata_reorder_2dir_bands_fx( + IVAS_QMETADATA_HANDLE hQMetaData ) +{ + Word16 nbands; + Word16 nsubframes; + Word16 band, sf; + + nbands = hQMetaData->q_direction[0].cfg.nbands; + move16(); + nsubframes = hQMetaData->q_direction[0].cfg.nblocks; + move16(); + + FOR( band = 0; band < nbands; band++ ) + { + IF( EQ_16( hQMetaData->twoDirBands[band], 1 ) ) + { + IF( LT_32( hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[0], hQMetaData->q_direction[1].band_data[band].energy_ratio_fx[0] ) ) + { + UWord16 uint16_tmp = 0; + move16(); + Word32 fx_tmp = 0; + move32(); + UWord8 uint8_tmp = 0; + move16(); + + FOR( sf = 0; sf < nsubframes; sf++ ) + { + uint16_tmp = hQMetaData->q_direction[0].band_data[band].spherical_index[sf]; + move16(); + hQMetaData->q_direction[0].band_data[band].spherical_index[sf] = hQMetaData->q_direction[1].band_data[band].spherical_index[sf]; + move16(); + hQMetaData->q_direction[1].band_data[band].spherical_index[sf] = uint16_tmp; + move16(); + + fx_tmp = hQMetaData->q_direction[0].band_data[band].azimuth_fx[sf]; + move32(); + hQMetaData->q_direction[0].band_data[band].azimuth_fx[sf] = hQMetaData->q_direction[1].band_data[band].azimuth_fx[sf]; + move32(); + hQMetaData->q_direction[1].band_data[band].azimuth_fx[sf] = fx_tmp; + move32(); + + fx_tmp = hQMetaData->q_direction[0].band_data[band].elevation_fx[sf]; + move32(); + hQMetaData->q_direction[0].band_data[band].elevation_fx[sf] = hQMetaData->q_direction[1].band_data[band].elevation_fx[sf]; + move32(); + hQMetaData->q_direction[1].band_data[band].elevation_fx[sf] = fx_tmp; + move32(); + + uint8_tmp = hQMetaData->q_direction[0].band_data[band].distance[sf]; + move16(); + hQMetaData->q_direction[0].band_data[band].distance[sf] = hQMetaData->q_direction[1].band_data[band].distance[sf]; + move16(); + hQMetaData->q_direction[1].band_data[band].distance[sf] = uint8_tmp; + move16(); + + IF( hQMetaData->coherence_flag ) + { + uint8_tmp = hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[sf]; + move16(); + hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[sf] = hQMetaData->q_direction[1].coherence_band_data[band].spread_coherence[sf]; + move16(); + hQMetaData->q_direction[1].coherence_band_data[band].spread_coherence[sf] = uint8_tmp; + move16(); + } + } + IF( hQMetaData->coherence_flag ) + { + fx_tmp = hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[0]; + move32(); + hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[0] = hQMetaData->q_direction[1].band_data[band].energy_ratio_fx[0]; + move32(); + hQMetaData->q_direction[1].band_data[band].energy_ratio_fx[0] = fx_tmp; + move32(); + } + } + } + } + return; +} +#else static void ivas_qmetadata_reorder_2dir_bands( IVAS_QMETADATA_HANDLE hQMetaData ) { @@ -7699,7 +8310,7 @@ static void ivas_qmetadata_reorder_2dir_bands( return; } - +#endif /*-------------------------------------------------------------------* * write_2dir_info() @@ -7795,7 +8406,44 @@ static int16_t write_2dir_info( * * *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void transform_azimuth_dir2_fx( + IVAS_QMETADATA_HANDLE hQMetaData, + Word16 *dir2_bands ) +{ + Word16 i, b; + + FOR( i = hQMetaData->q_direction[1].cfg.start_band; i < hQMetaData->q_direction[1].cfg.nbands; i++ ) + { + IF( LT_16( hQMetaData->q_direction[0].band_data[dir2_bands[i]].energy_ratio_index[0], 7 ) ) + { + /* 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 ) ) + { + hQMetaData->q_direction[1].band_data[i].azimuth_fx[b] = L_sub( hQMetaData->q_direction[1].band_data[i].azimuth_fx[b], 360 << Q22 ); + } + if ( LT_32( hQMetaData->q_direction[1].band_data[i].azimuth_fx[b], -( 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 ); + } + if ( GE_32( hQMetaData->q_direction[1].band_data[i].azimuth_fx[b], 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 ); + } + if ( LT_32( hQMetaData->q_direction[1].band_data[i].azimuth_fx[b], -( 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 ); + } + } + } + } + return; +} +#else static void transform_azimuth_dir2( IVAS_QMETADATA_HANDLE hQMetaData, int16_t *dir2_bands ) @@ -7832,7 +8480,7 @@ static void transform_azimuth_dir2( return; } - +#endif static int16_t divide_GR_orders( const int16_t *q_idx, diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index ead9c4d25..62778a4dc 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -916,6 +916,15 @@ static ivas_error ivas_spar_enc_process( // Word16 q_pcm_tmp_fx[DIRAC_MAX_ANA_CHANS][L_FRAME48k * 2]; // Word16 *q_p_pcm_tmp_fx[DIRAC_MAX_ANA_CHANS]; Word16 q_pcm_fx[DIRAC_MAX_ANA_CHANS]; +#endif +#ifdef IVAS_FLOAT_FIXED + // Word32 *ppIn_FR_real_fx[IVAS_SPAR_MAX_CH], *ppIn_FR_imag_fx[IVAS_SPAR_MAX_CH]; + // Word32 wyzx_del_buf_fx[FOA_CHANNELS][IVAS_FB_1MS_48K_SAMP]; + Word32 data_fix[MAX_INPUT_CHANNELS + MAX_NUM_OBJECTS][L_FRAME48k]; + Word16 q_data_fix[MAX_INPUT_CHANNELS + MAX_NUM_OBJECTS]; + Word32 *data_fx[MAX_INPUT_CHANNELS + MAX_NUM_OBJECTS]; + // Word16 q_cmplx[IVAS_SPAR_MAX_CH]; + Word16 q_p_pcm_tmp_fx[DIRAC_MAX_ANA_CHANS]; #endif int16_t i, j, input_frame, dtx_vad; int16_t transient_det[2]; @@ -968,12 +977,12 @@ static ivas_error ivas_spar_enc_process( *-----------------------------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED { - Word32 data_fix[L_FRAME48k]; + // Word32 data_fix[L_FRAME48k]; FOR( i = 0; i < input_frame; i++ ) { - data_fix[i] = (Word32) ( data_f[0][i] * ( 1 << Q14 ) ); + data_fix[0][i] = (Word32) ( data_f[0][i] * ( 1 << Q14 ) ); } - ivas_transient_det_process_fx( hSpar->hTranDet, data_fix, input_frame, transient_det ); + ivas_transient_det_process_fx( hSpar->hTranDet, data_fix[0], input_frame, transient_det ); } #else ivas_transient_det_process( hSpar->hTranDet, data_f[0], input_frame, transient_det ); @@ -1014,8 +1023,75 @@ static ivas_error ivas_spar_enc_process( p_pcm_tmp[i] = pcm_tmp[i]; } - /* run Filter Bank overlapping MDFT analysis first, then we can use the temporary buffer for Parameter MDFT analysis*/ + + FOR( i = 0; i < nchan_fb_in; i++ ) + { + + p_pcm_tmp[i] = pcm_tmp[i]; +#ifdef IVAS_FLOAT_FIXED + p_pcm_tmp_fx[i] = pcm_tmp_fx[i]; + move32(); +#endif + } + /* Need to remove flt to fix conversions */ +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + FOR( i = 0; i < hSpar->hFbMixer->fb_cfg->num_in_chans; i++ ) + { + hSpar->hFbMixer->q_ppFilterbank_prior_input_fx[i] = Q_factor_arrL( hSpar->hFbMixer->ppFilterbank_prior_input[i], hSpar->hFbMixer->fb_cfg->prior_input_length ); + + floatToFixed_arrL( hSpar->hFbMixer->ppFilterbank_prior_input[i], + hSpar->hFbMixer->ppFilterbank_prior_input_fx[i], hSpar->hFbMixer->q_ppFilterbank_prior_input_fx[i], hSpar->hFbMixer->fb_cfg->prior_input_length ); + } + /* In order to get the number of channels */ + Word16 num_chs_alloc; + + IF( hSpar->hFbMixer->fb_cfg->active_w_mixing == -1 ) + { + num_chs_alloc = 0; + } + ELSE IF( hSpar->hFbMixer->fb_cfg->active_w_mixing ) + { + num_chs_alloc = hSpar->hFbMixer->fb_cfg->num_in_chans; + } + ELSE + { + num_chs_alloc = 1; /* only W channel processed for predicting YZX */ + } + FOR( Word16 m = 0; m < MAX_INPUT_CHANNELS + MAX_NUM_OBJECTS; m++ ) + { + IF( data_f[m] != NULL && ( m <= nchan_fb_in + nchan_transport ) ) + { + q_data_fix[m] = Q_factor_arrL( data_f[m], input_frame ); + floatToFixed_arrL( data_f[m], data_fix[m], q_data_fix[m], input_frame ); + data_fx[m] = data_fix[m]; + } + } +#endif + ivas_fb_mixer_pcm_ingest_fx( hSpar->hFbMixer, data_fx, p_pcm_tmp_fx, input_frame, hSpar->hMdEnc->HOA_md_ind, q_data_fix, q_p_pcm_tmp_fx ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + FOR( i = 0; i < hSpar->hFbMixer->fb_cfg->num_in_chans; i++ ) + { + me2f_buf( p_pcm_tmp_fx[i], 31 - q_p_pcm_tmp_fx[i], p_pcm_tmp[i], input_frame * 2 ); + } + FOR( Word16 x = 0; x < num_chs_alloc; x++ ) + { + me2f_buf( p_pcm_tmp_fx[hSpar->hFbMixer->fb_cfg->remix_order[x]], 31 - q_p_pcm_tmp_fx[hSpar->hFbMixer->fb_cfg->remix_order[x]], p_pcm_tmp[hSpar->hFbMixer->fb_cfg->remix_order[x]], input_frame * 2 ); + + hSpar->hFbMixer->q_ppFilterbank_inFR_re_fx[hSpar->hFbMixer->fb_cfg->remix_order[x]] = q_p_pcm_tmp_fx[hSpar->hFbMixer->fb_cfg->remix_order[x]]; + hSpar->hFbMixer->q_ppFilterbank_inFR_im_fx[hSpar->hFbMixer->fb_cfg->remix_order[x]] = q_p_pcm_tmp_fx[hSpar->hFbMixer->fb_cfg->remix_order[x]]; + + me2f_buf( hSpar->hFbMixer->ppFilterbank_inFR_re_fx[hSpar->hFbMixer->fb_cfg->remix_order[x]], 31 - q_p_pcm_tmp_fx[hSpar->hFbMixer->fb_cfg->remix_order[x]], + hSpar->hFbMixer->ppFilterbank_inFR_re[hSpar->hFbMixer->fb_cfg->remix_order[x]], input_frame ); + + me2f_buf( hSpar->hFbMixer->ppFilterbank_inFR_im_fx[hSpar->hFbMixer->fb_cfg->remix_order[x]], 31 - q_p_pcm_tmp_fx[hSpar->hFbMixer->fb_cfg->remix_order[x]], + hSpar->hFbMixer->ppFilterbank_inFR_im[hSpar->hFbMixer->fb_cfg->remix_order[x]], input_frame ); + } + /* Need to remove fix to flt conversions */ +#endif +#else ivas_fb_mixer_pcm_ingest( hSpar->hFbMixer, data_f, p_pcm_tmp, input_frame, hSpar->hMdEnc->HOA_md_ind ); +#endif /* prepare Parameter MDFT analysis */ 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 944f72c91..e19ec84af 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -244,9 +244,9 @@ typedef struct stereo_dft_enc_data_struct float xspec_smooth[STEREO_DFT_N_32k_ENC]; float sid_gipd; float prev_sid_gipd; -#endif float Spd_L_smooth[STEREO_DFT_N_32k_ENC / 2]; float Spd_R_smooth[STEREO_DFT_N_32k_ENC / 2]; +#endif int16_t coh_fade_counter; Word32 prev_sid_gipd_fx; // Q13 int16_t prev_sid_no_ipd_flag; @@ -263,6 +263,7 @@ typedef struct stereo_dft_enc_data_struct int16_t no_ipd_cnt1; /* counter */ int16_t attackPresent; int16_t wasTransient; +#ifndef IVAS_FLOAT_FIXED float gainIPD_sm; /* long-term gain IPD for NIPD detection */ float sfm; float sum_dot_prod_real; @@ -271,11 +272,12 @@ typedef struct stereo_dft_enc_data_struct float dot_prod_img_smooth[STEREO_DFT_BAND_MAX]; float ipd_buf[STEREO_DFT_BAND_MAX][STEREO_DFT_IPD_BUF_LEN]; float prev_gipd; - +#endif /*ITD*/ ITD_DATA_HANDLE hItd; - +#ifndef IVAS_FLOAT_FIXED float voicing_lt; +#endif Word32 voicing_lt_fx; // Q31 @@ -289,9 +291,11 @@ typedef struct stereo_dft_enc_data_struct float nrg_DMX[2]; #endif /*Residual prediction*/ - int16_t res_pred_mode[STEREO_DFT_ENC_DFT_NB]; /* mode from 0 (off) to 1 (on) */ + int16_t res_pred_mode[STEREO_DFT_ENC_DFT_NB]; /* mode from 0 (off) to 1 (on) */ +#ifndef IVAS_FLOAT_FIXED float res_pred_gain[STEREO_DFT_ENC_DFT_NB * STEREO_DFT_BAND_MAX]; /*prediction gain for the residual HFs */ - int16_t res_pred_band_min; /* Band min for prediction of residual */ +#endif + int16_t res_pred_band_min; /* Band min for prediction of residual */ int16_t res_pred_flag_1; int16_t res_pred_flag_2; int16_t res_pred_counter; @@ -300,11 +304,12 @@ typedef struct stereo_dft_enc_data_struct int16_t res_pred_index_ECDiff[STEREO_DFT_BAND_MAX]; int16_t res_pred_index_ECprevious[STEREO_DFT_BAND_MAX]; int16_t reverb_flag; +#ifndef IVAS_FLOAT_FIXED float pre_sub_nrg_DMX[STEREO_DFT_BAND_MAX]; float diff_l_h_sm; float diff_r_h_sm; float prev_fac2; - +#endif /*Residual coding*/ int16_t res_cod_mode[STEREO_DFT_ENC_DFT_NB]; /* mode from 0 (off) to 3 */ int16_t res_cod_band_max; /* Band max for coding of residual */ @@ -316,18 +321,24 @@ typedef struct stereo_dft_enc_data_struct int16_t first_frm_flag; /* ADAP first frame flag */ /* flags and data for adaptive wideband residual coding */ +#ifndef IVAS_FLOAT_FIXED float res_dmx_ratio_lt; /* long term energy ratio between RES and DMX */ - int16_t hangover_cnt0; /* counter 0 for hangover */ - int16_t hangover_cnt1; /* counter 1 for hangover */ +#endif + int16_t hangover_cnt0; /* counter 0 for hangover */ + int16_t hangover_cnt1; /* counter 1 for hangover */ +#ifndef IVAS_FLOAT_FIXED float dmx_res_all_prev; /* energy of the previous frame */ - +#endif int16_t last_res_cod_mode_modify_flag; /* a flag to indicate whether the res_cod_mode_flag has been modified for the switching frame in which res_cod_mode_flag should be swithced from 1 to 0 */ int16_t res_cod_sw_flag; /* a flag to indicate whether it is a switching frame */ - float switch_fade_factor; /* Adaptive fade factor for switch frame */ - +#ifndef IVAS_FLOAT_FIXED + float switch_fade_factor; /* Adaptive fade factor for switch frame */ +#endif /*misc*/ +#ifndef IVAS_FLOAT_FIXED float icbweRefEner; float lbEner; +#endif #ifdef IVAS_FLOAT_FIXED Word32 icbweRefEner_fx; Word16 icbweRefEner_fx_e; @@ -463,7 +474,7 @@ typedef struct stereo_td_enc_data_structure Word16 tdm_lp_reuse_flag; /* Flag that indicate if it is possible to reuse the LP coefficient from the primary channel or not */ Word16 tdm_low_rate_mode; /* secondary channel low rate mode flag */ float tdm_Pri_pitch_buf[NB_SUBFR]; - +#ifndef IVAS_FLOAT_FIXED float tdm_lt_corr_RM; /* Long term right-mono correlation */ float tdm_lt_corr_LM; /* Long term left-mono correlation */ float tdm_last_diff_lt_corr; /* long term correlation difference mem */ @@ -473,6 +484,7 @@ typedef struct stereo_td_enc_data_structure float tdm_lt_rms_R; /* Right channel long term rms */ float tdm_last_ener_lt_R; /* Right channel long term energy */ float tdm_last_ener_lt_L; /* Left channel long term energy */ +#endif Word16 tdm_Pitch_reuse_flag; Word32 tdm_lt_corr_RM_fx; /* Long term right-mono correlation */ @@ -485,27 +497,30 @@ typedef struct stereo_td_enc_data_structure Word32 tdm_last_ener_lt_R_fx; /* Right channel long term energy */ /*Q16*/ Word32 tdm_last_ener_lt_L_fx; /* Left channel long term energy */ /*Q16*/ - Word16 tdm_last_ratio_idx; /* last TDM ratio index */ - Word16 tdm_last_SM_flag; /* Flag to signal a SM encoding scheme -> better for some music item */ - Word16 tdm_ratio_transition_mov_flag; /* Flag that indicates that L-R energy is changing */ - Word16 tdm_ratio_transition_cnt; /* Counter */ - Word16 tdm_hyst_cnt; /* Counter */ - Word16 tdm_prev_stable_idx; /* Previous Transmitted ratio index*/ - Word16 tdm_prev_desired_idx; /* Previous Transmitted ratio index*/ - float tdm_LT_es_em; /* Long term evoluation of the side to mono energy ratio */ + Word16 tdm_last_ratio_idx; /* last TDM ratio index */ + Word16 tdm_last_SM_flag; /* Flag to signal a SM encoding scheme -> better for some music item */ + Word16 tdm_ratio_transition_mov_flag; /* Flag that indicates that L-R energy is changing */ + Word16 tdm_ratio_transition_cnt; /* Counter */ + Word16 tdm_hyst_cnt; /* Counter */ + Word16 tdm_prev_stable_idx; /* Previous Transmitted ratio index*/ + Word16 tdm_prev_desired_idx; /* Previous Transmitted ratio index*/ +#ifndef IVAS_FLOAT_FIXED + float tdm_LT_es_em; /* Long term evoluation of the side to mono energy ratio */ +#endif Word32 tdm_LT_es_em_fx; /* Long term evoluation of the side to mono energy ratio */ /*Q21*/ Word16 tdm_use_IAWB_Ave_lpc; /* Flag to indicate the usage of mean inactive LP coefficients */ /* NOOP parameters */ +#ifndef IVAS_FLOAT_FIXED float tdm_lt_corr_RM_SM; /* Long term right-mono correlation in SM mode*/ float tdm_lt_corr_LM_SM; /* Long term left-mono correlation in SM mode*/ float tdm_last_diff_lt_corr_SM; /* long term correlation difference mem in SM mode*/ float tdm_last_ratio_SM; /* Last TDM ratio in SM mode*/ - - float tdm_lt_rms_L_SM; /* Left channel long term rms in SM mode*/ - float tdm_lt_rms_R_SM; /* Right channel long term rms in SM mode*/ - float tdm_last_ener_lt_R_SM; /* Right channel long term energy in SM mode*/ - float tdm_last_ener_lt_L_SM; /* Left channel long term energy in SM mode*/ + float tdm_lt_rms_L_SM; /* Left channel long term rms in SM mode*/ + float tdm_lt_rms_R_SM; /* Right channel long term rms in SM mode*/ + float tdm_last_ener_lt_R_SM; /* Right channel long term energy in SM mode*/ + float tdm_last_ener_lt_L_SM; /* Left channel long term energy in SM mode*/ +#endif Word32 tdm_lt_corr_RM_SM_fx; /* Long term right-mono correlation in SM mode*/ Word32 tdm_lt_corr_LM_SM_fx; /* Long term left-mono correlation in SM mode*/ @@ -524,14 +539,16 @@ typedef struct stereo_td_enc_data_structure Word16 tdm_hyst_cnt_SM; /* Counter in SM mode*/ Word16 tdm_prev_stable_idx_SM; /* Previous Transmitted ratio index in SM mode*/ Word16 tdm_prev_desired_idx_SM; /* Previous Transmitted ratio index in SM mode*/ - float tdm_LT_es_em_SM; /* Long term evoluation of the side to mono energy ratio in SM mode*/ - Word32 tdm_LT_es_em_SM_fx; /* Long term evoluation of the side to mono energy ratio in SM mode*/ - Word16 tdm_NOOP_cnt; /* Counter for channel combination scheme */ - Word16 tdm_SM_flag; /* Flag for channel combination scheme */ - Word16 tdm_SM_last2_clas[2]; /* Class of the frame immediately prior to the previous frame */ - Word16 tdm_SM_last_clas[2]; /* Class of the previous frame */ - Word16 tdm_SM_modi_flag; /* Flag that indicates to modify ratio */ - Word16 tdm_SM_reset_flag; /* Flag that indicates to reset the parameters for SM mode */ +#ifndef IVAS_FLOAT_FIXED + float tdm_LT_es_em_SM; /* Long term evoluation of the side to mono energy ratio in SM mode*/ +#endif + Word32 tdm_LT_es_em_SM_fx; /* Long term evoluation of the side to mono energy ratio in SM mode*/ + Word16 tdm_NOOP_cnt; /* Counter for channel combination scheme */ + Word16 tdm_SM_flag; /* Flag for channel combination scheme */ + Word16 tdm_SM_last2_clas[2]; /* Class of the frame immediately prior to the previous frame */ + Word16 tdm_SM_last_clas[2]; /* Class of the previous frame */ + Word16 tdm_SM_modi_flag; /* Flag that indicates to modify ratio */ + Word16 tdm_SM_reset_flag; /* Flag that indicates to reset the parameters for SM mode */ Word16 tdm_FD2LRTD_SW_cnt; /* Count the number of frames following a FD to LRTD switching */ Word16 tdm_LRTD_flag; /* LRTD stereo mode flag */ @@ -1089,6 +1106,9 @@ typedef struct ivas_mc_paramupmix_enc_data_structure float ***cov_real[MC_PARAMUPMIX_COMBINATIONS]; float ***cov_dtx_real[MC_PARAMUPMIX_COMBINATIONS]; 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) +#endif int32_t alpha_quant_prev[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; int32_t beta_quant_prev[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; int16_t first_frame; diff --git a/lib_enc/ivas_stereo_dft_enc.c b/lib_enc/ivas_stereo_dft_enc.c index 73ceaaa9f..95be17fb5 100644 --- a/lib_enc/ivas_stereo_dft_enc.c +++ b/lib_enc/ivas_stereo_dft_enc.c @@ -979,22 +979,24 @@ void stereo_dft_enc_reset( #endif #ifndef IVAS_FLOAT_FIXED set_zero( hStereoDft->gipd, STEREO_DFT_ENC_DFT_NB ); -#endif set_zero( hStereoDft->dot_prod_real_smooth, STEREO_DFT_BAND_MAX ); set_zero( hStereoDft->dot_prod_img_smooth, STEREO_DFT_BAND_MAX ); +#endif #ifdef IVAS_FLOAT_FIXED set_zero_fx( hStereoDft->dot_prod_real_smooth_fx, STEREO_DFT_BAND_MAX ); set16_zero_fx( hStereoDft->dot_prod_real_smooth_fx_e, STEREO_DFT_BAND_MAX ); set_zero_fx( hStereoDft->dot_prod_img_smooth_fx, STEREO_DFT_BAND_MAX ); set16_zero_fx( hStereoDft->dot_prod_img_smooth_fx_e, STEREO_DFT_BAND_MAX ); #endif +#ifndef IVAS_FLOAT_FIXED for ( i = 0; i < STEREO_DFT_BAND_MAX; i++ ) { set_zero( hStereoDft->ipd_buf[i], STEREO_DFT_IPD_BUF_LEN ); } hStereoDft->prev_gipd = 0.f; - hStereoDft->gipd_index = 0; set_zero( hStereoDft->res_pred_gain, STEREO_DFT_ENC_DFT_NB * STEREO_DFT_BAND_MAX ); +#endif + hStereoDft->gipd_index = 0; set_s( hStereoDft->res_pred_index_EC, 0, STEREO_DFT_BAND_MAX ); set_s( hStereoDft->res_pred_index_ECDiff, 0, STEREO_DFT_BAND_MAX ); set_s( hStereoDft->res_pred_index_ECprevious, 0, STEREO_DFT_BAND_MAX ); @@ -1006,14 +1008,19 @@ void stereo_dft_enc_reset( set_zero( hStereoDft->past_dot_prod_imag, STEREO_DFT_NRG_PAST_LEN * STEREO_DFT_BAND_MAX ); #endif hStereoDft->nrg_past_pos = 0; - +#ifndef IVAS_FLOAT_FIXED hStereoDft->res_dmx_ratio_lt = 1.0f; +#endif hStereoDft->hangover_cnt0 = 0; hStereoDft->hangover_cnt1 = 0; +#ifndef IVAS_FLOAT_FIXED hStereoDft->dmx_res_all_prev = EPSILON; +#endif hStereoDft->last_res_cod_mode_modify_flag = 0; hStereoDft->res_cod_sw_flag = 0; +#ifndef IVAS_FLOAT_FIXED hStereoDft->switch_fade_factor = 0.5f; +#endif hStereoDft->res_cod_mode[STEREO_DFT_OFFSET - 1] = STEREO_DFT_RES_COD_1kHz; for ( i = 0; i < STEREO_DFT_BAND_MAX; i++ ) { @@ -1024,11 +1031,12 @@ void stereo_dft_enc_reset( hStereoDft->reverb_flag = 0; +#ifndef IVAS_FLOAT_FIXED set_zero( hStereoDft->pre_sub_nrg_DMX, STEREO_DFT_BAND_MAX ); hStereoDft->diff_l_h_sm = 0.0f; hStereoDft->diff_r_h_sm = 0.0f; hStereoDft->prev_fac2 = 1.0f; - +#endif set_zero( hStereoDft->res_pred_gain_f, STEREO_DFT_BAND_MAX ); /*misc*/ @@ -1038,25 +1046,26 @@ void stereo_dft_enc_reset( hStereoDft->no_ipd_cnt1 = 0; hStereoDft->attackPresent = 0; hStereoDft->wasTransient = 0; +#ifndef IVAS_FLOAT_FIXED hStereoDft->gainIPD_sm = 1.f; - - hStereoDft->voicing_lt = 0; +#endif - hStereoDft->flip_sign = 1; + hStereoDft->flip_sign = 1; +#ifndef IVAS_FLOAT_FIXED hStereoDft->sfm = 0.f; hStereoDft->sum_dot_prod_real = 0.f; hStereoDft->sum_dot_prod_img = 0.f; - +#endif /*Coherence*/ #ifndef IVAS_FLOAT_FIXED set_f( hStereoDft->xspec_smooth, 1.0f, STEREO_DFT_N_32k_ENC ); hStereoDft->sid_gipd = 0; hStereoDft->prev_sid_gipd = 0; -#endif set_f( hStereoDft->Spd_L_smooth, 1.0f, STEREO_DFT_N_32k_ENC / 2 ); set_f( hStereoDft->Spd_R_smooth, 1.0f, STEREO_DFT_N_32k_ENC / 2 ); +#endif hStereoDft->currentNumUpdates = 0; hStereoDft->expectedNumUpdates = FIXED_SID_RATE; hStereoDft->resetFrames = 0; diff --git a/lib_enc/ivas_stereo_ica_enc.c b/lib_enc/ivas_stereo_ica_enc.c index 9a85c984d..235d1a540 100644 --- a/lib_enc/ivas_stereo_ica_enc.c +++ b/lib_enc/ivas_stereo_ica_enc.c @@ -2597,9 +2597,6 @@ void stereo_tca_enc( floatToFixed_arrL32( sts[0]->input_buff, sts[0]->input_buff32_fx, q_com, 1965 ); floatToFixed_arrL32( sts[1]->input_buff, sts[1]->input_buff32_fx, q_com, 1965 ); - - hCPE->hStereoTD->tdm_last_ratio_SM_fx = floatToFixed_32( hCPE->hStereoTD->tdm_last_ratio_SM, Q31 ); - hCPE->hStereoTD->tdm_last_ratio_fx = floatToFixed_32( hCPE->hStereoTD->tdm_last_ratio, Q31 ); #endif icaMemUpdate_fx( sts, hCPE, input_mem_loc_fx[0], input_mem_loc_fx[1], q_com, lMemRecalc, lMemRecalc_SCh, input_frame ); diff --git a/lib_enc/ivas_stereo_icbwe_enc.c b/lib_enc/ivas_stereo_icbwe_enc.c index 6dc72ed1d..63a5f0e11 100644 --- a/lib_enc/ivas_stereo_icbwe_enc.c +++ b/lib_enc/ivas_stereo_icbwe_enc.c @@ -1689,6 +1689,15 @@ void stereo_icBWE_init_enc_fx( hStereoICBWE->MSFlag = 0; move16(); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + set_f( hStereoICBWE->nlExc16k, 0, L_FRAME16k ); + set16_fx( hStereoICBWE->nlExc16k_fx, 0, L_FRAME16k ); + hStereoICBWE->nlExc16k_e = 0; + set_f( hStereoICBWE->mixExc16k, 0, L_FRAME16k ); + set16_fx( hStereoICBWE->mixExc16k_fx, 0, L_FRAME16k ); + hStereoICBWE->mixExc16k_e = 0; +#endif + return; } /*-------------------------------------------------------------------* diff --git a/lib_enc/ivas_stereo_switching_enc.c b/lib_enc/ivas_stereo_switching_enc.c index c8cabd743..31aadab52 100644 --- a/lib_enc/ivas_stereo_switching_enc.c +++ b/lib_enc/ivas_stereo_switching_enc.c @@ -421,7 +421,7 @@ ivas_error stereo_memory_enc_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD Stereo\n" ) ); } - stereo_td_init_enc( hCPE->hStereoTD, hCPE->last_element_mode ); + stereo_td_init_enc_fx( hCPE->hStereoTD, hCPE->last_element_mode ); /* allocate secondary channel */ #ifdef IVAS_FLOAT_FIXED IF( NE_32( ( error = allocate_CoreCoder_enc_fx( hCPE->hCoreCoder[1] ) ), IVAS_ERR_OK ) ) diff --git a/lib_enc/ivas_stereo_td_enc.c b/lib_enc/ivas_stereo_td_enc.c index a701abb6f..346c78d63 100644 --- a/lib_enc/ivas_stereo_td_enc.c +++ b/lib_enc/ivas_stereo_td_enc.c @@ -55,7 +55,7 @@ * * Initialize TD stereo encoder *-------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED void stereo_td_init_enc( STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ const int16_t last_element_mode /* i : last element mode */ @@ -138,85 +138,149 @@ void stereo_td_init_enc( return; } - +#endif void stereo_td_init_enc_fx( STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */ const Word16 last_element_mode /* i : last element mode */ ) { - hStereoTD->tdm_lt_corr_RM_fx = 167772; // Q24 - hStereoTD->tdm_lt_corr_LM_fx = 167772; // Q24 + hStereoTD->tdm_lt_corr_RM_fx = 167772; // Q24 + move32(); + hStereoTD->tdm_lt_corr_LM_fx = 167772; // Q24 + move32(); hStereoTD->tdm_last_ratio_fx = 1073741824; // Q31 + move32(); hStereoTD->tdm_last_ratio_idx = LRTD_STEREO_MID_IS_PRIM; + move16(); hStereoTD->tdm_lt_rms_L_fx = 2621440; // Q16 + move32(); hStereoTD->tdm_lt_rms_R_fx = 2621440; // Q16 + move32(); hStereoTD->tdm_last_diff_lt_corr_fx = 0; + move32(); hStereoTD->q_tdm_last_diff_lt_corr = Q31; + move16(); hStereoTD->tdm_last_ener_lt_R_fx = 0; + move32(); hStereoTD->tdm_last_ener_lt_L_fx = 0; + move32(); hStereoTD->tdm_ratio_transition_mov_flag = 0; + move16(); hStereoTD->tdm_ratio_transition_cnt = 0; + move16(); hStereoTD->tdm_noop_mov_flag = 0; + move16(); hStereoTD->tdm_noop_cnt = 0; + move16(); hStereoTD->tdm_last_SM_flag = 0; + move16(); hStereoTD->tdm_last_ratio_idx = LRTD_STEREO_MID_IS_PRIM; + move16(); hStereoTD->tdm_prev_stable_idx = LRTD_STEREO_MID_IS_PRIM; + move16(); hStereoTD->tdm_prev_desired_idx = LRTD_STEREO_MID_IS_PRIM; + move16(); hStereoTD->tdm_FD2LRTD_SW_cnt = 0; + move16(); hStereoTD->tdm_LT_es_em_fx = 209715; // Q21 + move32(); hStereoTD->tdm_hyst_cnt = 0; + move16(); /* NOOP parameters */ - hStereoTD->tdm_lt_corr_RM_SM_fx = 21474836; // Q31 - hStereoTD->tdm_lt_corr_LM_SM_fx = 21474836; // Q31 + hStereoTD->tdm_lt_corr_RM_SM_fx = 167772 /*0.01f Q24*/; + move32(); + hStereoTD->tdm_lt_corr_LM_SM_fx = 167772 /*0.01f Q24*/; hStereoTD->tdm_last_ratio_SM_fx = 1073741824; // Q31 + move32(); hStereoTD->tdm_last_ratio_idx_SM = 0; - hStereoTD->tdm_lt_rms_L_SM_fx = 671088640; // Q24 - hStereoTD->tdm_lt_rms_R_SM_fx = 671088640; // Q24 + move16(); + hStereoTD->q_tdm_last_diff_lt_corr_SM = Q31; + move16(); + hStereoTD->tdm_lt_rms_L_SM_fx = 2621440; // Q16 + move32(); + hStereoTD->tdm_lt_rms_R_SM_fx = 2621440; // Q16 + move32(); hStereoTD->tdm_last_diff_lt_corr_SM_fx = 0; + move32(); hStereoTD->q_tdm_last_diff_lt_corr_SM = Q31; + move16(); hStereoTD->tdm_last_ener_lt_R_SM_fx = 0; + move32(); hStereoTD->tdm_last_ener_lt_L_SM_fx = 0; + move32(); hStereoTD->tdm_noop_mov_flag = 0; + move16(); hStereoTD->tdm_NOOP_cnt = 0; + move16(); hStereoTD->tdm_last_SM_flag_noop = 0; + move16(); hStereoTD->tdm_last_ratio_idx_SM = LRTD_STEREO_MID_IS_PRIM; + move16(); hStereoTD->tdm_prev_stable_idx_SM = LRTD_STEREO_MID_IS_PRIM; + move16(); hStereoTD->tdm_prev_desired_idx_SM = LRTD_STEREO_MID_IS_PRIM; - hStereoTD->tdm_LT_es_em_SM_fx = 214748364; // Q31 + move16(); + hStereoTD->tdm_LT_es_em_SM_fx = 209715; // Q21 + move32(); hStereoTD->tdm_hyst_cnt_SM = 0; + move16(); hStereoTD->tdm_noop_cnt = 0; + move16(); hStereoTD->tdm_SM_flag = 0; + move16(); hStereoTD->tdm_SM_last_clas[0] = VOICED_CLAS; + move16(); hStereoTD->tdm_SM_last_clas[1] = VOICED_CLAS; + move16(); hStereoTD->tdm_SM_last2_clas[0] = VOICED_CLAS; + move16(); hStereoTD->tdm_SM_last2_clas[1] = VOICED_CLAS; + move16(); hStereoTD->tdm_SM_modi_flag = 0; + move16(); hStereoTD->tdm_SM_reset_flag = 0; + move16(); hStereoTD->prev_fr_LRTD_TD_dec = 0; + move16(); hStereoTD->tdm_LRTD_flag = 0; + move16(); hStereoTD->tdm_inst_ratio_idx = LRTD_STEREO_RIGHT_IS_PRIM; + move16(); hStereoTD->tdm_last_inst_ratio_idx = LRTD_STEREO_MID_IS_PRIM; + move16(); hStereoTD->tdm_last_LRTD_frame_cnt = 0; + move16(); hStereoTD->tdm_vad_hangover_cnt = 0; + move16(); hStereoTD->tdm_ini_frame_cnt = 0; + move16(); hStereoTD->tdm_last_LRTD_PriCh_cnt = 0; + move16(); hStereoTD->flag_skip_DMX = 0; + move16(); IF( EQ_16( last_element_mode, IVAS_CPE_MDCT ) ) { hStereoTD->flag_skip_DMX = 1; + move16(); hStereoTD->prev_fr_LRTD_TD_dec = 1; + move16(); hStereoTD->tdm_last_ratio_fx = MAX_32; // Q31 + move32(); hStereoTD->tdm_last_ratio_idx = LRTD_STEREO_LEFT_IS_PRIM; + move16(); hStereoTD->tdm_prev_stable_idx = LRTD_STEREO_LEFT_IS_PRIM; + move16(); hStereoTD->tdm_prev_desired_idx = LRTD_STEREO_LEFT_IS_PRIM; + move16(); } hStereoTD->tdm_hBstr_tmp.ind_list = hStereoTD->tdm_ind_list_tmp; hStereoTD->tdm_hBstr_tmp.ivas_ind_list_zero = (Indice **) ( &hStereoTD->tdm_hBstr_tmp.ind_list ); hStereoTD->max_ind_tdm_tmp = MAX_IND_TDM_TMP; + move32(); hStereoTD->tdm_hBstr_tmp.ivas_max_num_indices = &hStereoTD->max_ind_tdm_tmp; hStereoTD->tdm_hBstr_tmp.st_ivas = NULL; reset_indices_enc( &hStereoTD->tdm_hBstr_tmp, MAX_IND_TDM_TMP ); @@ -1295,7 +1359,7 @@ ivas_error signaling_enc_secondary( * * downmix Left+Right to Primary+Secondary channel *-------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED static void tdm_downmix_plain( float FR_Y[], /* o : primary channel */ float LR_X[], /* o : secondary channel */ @@ -1317,7 +1381,7 @@ static void tdm_downmix_plain( return; } - +#endif #ifdef IVAS_FLOAT_FIXED static void tdm_downmix_plain_ivas_fx( @@ -1350,7 +1414,7 @@ static void tdm_downmix_plain_ivas_fx( * * downmix Left+Right to Primary+Secondary channel with fade in/out *-------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED static void tdm_downmix_fade( float FR_Y[], /* o : primary channel */ float LR_X[], /* o : secondary channel */ @@ -1382,7 +1446,7 @@ static void tdm_downmix_fade( return; } - +#endif #ifdef IVAS_FLOAT_FIXED static void tdm_downmix_fade_ivas_fx( Word16 FR_Y_fx[], /* o : primary channel Qx */ @@ -1431,7 +1495,7 @@ static void tdm_downmix_fade_ivas_fx( * * Compute the TD stereo downmix signal based on the ratio index *-------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED void stereo_tdm_downmix( STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i : TD stereo IVAS encoder structure */ float *Left_in, /* i/o: Left channel -> Primary channel */ @@ -1540,7 +1604,7 @@ void stereo_tdm_downmix( return; } - +#endif #ifdef IVAS_FLOAT_FIXED void stereo_tdm_downmix_ivas_fx( STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i : TD stereo IVAS encoder structure */ diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index 21cddef75..ac796e54d 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -1912,7 +1912,8 @@ Word16 ivas_smc_gmm_fx( ps_sta_fx = BASOP_Util_Add_Mant32Exp( temp32, temp_exp, ps_sta_fx, ps_sta_exp, &ps_sta_exp ); } } - temp32_log = L_add( BASOP_Util_Log2( L_add( ps_sta_fx, L_shr( 21475, ps_sta_exp ) ) ), L_shl( ps_sta_exp, Q25 ) ); + // temp32_log = L_add( BASOP_Util_Log2( L_add( ps_sta_fx, L_shr( 21475, ps_sta_exp ) ) ), L_shl( ps_sta_exp, Q25 ) ); + temp32_log = L_add( BASOP_Util_Log2( L_add_sat( ps_sta_fx, L_shr( 21475, ps_sta_exp ) ) ), L_shl( ps_sta_exp, Q25 ) ); temp32_log = Mpy_32_32( temp32_log, 1488522239 ); /*logf(x) = log2(x)*logf(2)*/ *pFV_fx++ = L_shr( temp32_log, Q5 ); // logf( ps_sta + 1e-5f ); move32(); -- GitLab