From b6e38f36e2e65800af41d49142bf98c4b709bd97 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 16 May 2024 19:51:38 +0530 Subject: [PATCH 1/3] msan fixes for SBA, Stereo and MASA cases --- lib_dec/TonalComponentDetection_fx.c | 2 +- lib_dec/hf_synth_fx.c | 10 +- lib_dec/init_dec_fx.c | 10 +- lib_dec/ivas_core_dec.c | 2 +- lib_dec/ivas_init_dec.c | 20 +- lib_dec/ivas_qmetadata_dec.c | 14 + lib_dec/ivas_sba_dirac_stereo_dec_fx.c | 4 + lib_dec/ivas_stereo_cng_dec.c | 7 + lib_dec/ivas_stereo_dft_plc_fx.c | 2 +- lib_dec/ivas_stereo_icbwe_dec.c | 4294 ++++++++++++------------ lib_rend/lib_rend.c | 12 +- 11 files changed, 2212 insertions(+), 2165 deletions(-) diff --git a/lib_dec/TonalComponentDetection_fx.c b/lib_dec/TonalComponentDetection_fx.c index e40828adc..9c7f57f24 100644 --- a/lib_dec/TonalComponentDetection_fx.c +++ b/lib_dec/TonalComponentDetection_fx.c @@ -64,7 +64,7 @@ void ivas_DetectTonalComponents_fx( { Word16 F0; Word16 thresholdModification[L_FRAME_MAX], lastMDCTSpect_exp; - Word32 pScaledMdctSpectrum[L_FRAME_MAX]; + Word32 pScaledMdctSpectrum[L_FRAME_MAX] = { 0 }; Word16 nBands; Word32 sns_int_scf_fx[FDNS_NPTS]; Word16 q_pScaledMdctSpectrum; diff --git a/lib_dec/hf_synth_fx.c b/lib_dec/hf_synth_fx.c index c62767ab8..4cb4399d5 100644 --- a/lib_dec/hf_synth_fx.c +++ b/lib_dec/hf_synth_fx.c @@ -56,7 +56,11 @@ void hf_synth_init_fx( hBWE_zero->seed2 = RANDOM_INITSEED; set16_fx(hBWE_zero->mem_hf_fx, 0, (L_FIR - 1)); set16_fx(hBWE_zero->mem_syn_hf_fx, 0, M); +#ifdef MSAN_FIX + set16_fx(hBWE_zero->mem_hp400_fx, 0, 6); +#else set16_fx(hBWE_zero->mem_hp400_fx, 0, 4); +#endif // MSAN_FIX set16_fx(hBWE_zero->delay_syn_hf_fx, 0, NS2SA(16000, DELAY_CLDFB_NS)); set16_fx(hBWE_zero->mem_hp_interp_fx, 0, INTERP_3_1_MEM_LEN); @@ -75,7 +79,11 @@ void hf_synth_reset_fx( set16_fx(hBWE_zero->mem_hf_fx, 0, (L_FIR - 1)); set16_fx(hBWE_zero->mem_syn_hf_fx, 0, M); - set16_fx(hBWE_zero->mem_hp400_fx, 0, 4); /* TBV -> mem_hp400_fx has a length of 6, but only 4 values initialized in EVS ??? */ +#ifdef MSAN_FIX + set16_fx(hBWE_zero->mem_hp400_fx, 0, 6); +#else + set16_fx(hBWE_zero->mem_hp400_fx, 0, 4); +#endif set16_fx(hBWE_zero->delay_syn_hf_fx, 0, NS2SA(16000, DELAY_CLDFB_NS)); set16_fx(hBWE_zero->mem_hp_interp_fx, 0, INTERP_3_1_MEM_LEN); diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index c5cf8a7bc..bc1fb287d 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -321,6 +321,9 @@ ivas_error init_decoder_fx( move16(); /*1; Q15*/ st_fx->exc_pe_fx = 0; move16(); +#ifdef MSAN_FIX + st_fx->Q_stat_noise = 31; +#endif // MSAN_FIX /*-----------------------------------------------------------------* * LD music post-filter *-----------------------------------------------------------------*/ @@ -1156,7 +1159,10 @@ ivas_error init_decoder_ivas_fx( move16(); /*1; Q15*/ st_fx->exc_pe_fx = 0; move16(); - +#ifdef MSAN_FIX + st_fx->Q_stat_noise = 31; + move16(); +#endif st_fx->prev_coder_type = GENERIC; move16(); @@ -1344,6 +1350,8 @@ ivas_error init_decoder_ivas_fx( } st_fx->masa_sid_format = 0; + move16(); + st_fx->Q_stat_noise_ge = GE_SHIFT; move16(); /*-----------------------------------------------------------------* diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index cd013cff6..fc2bf862c 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -1117,7 +1117,7 @@ ivas_error ivas_core_dec( Scale_sig( tmp_buffer_fx, L_FRAME48k, Q11 - Q_white_exc ); stereo_icBWE_dec_fx( hCPE, hb_synth_32_fx[0], hb_synth_32_fx[1], tmp_buffer_fx /*fb_synth_ref*/, voice_factors_fx[0], output_frame, &q ); #ifdef MSAN_FIX - IF( !( ( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && EQ_16( hCPE->nchan_out, 1 ) ) || ( NE_16( st->core, ACELP_CORE ) || EQ_16( st->extl, -1 ) || ( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) && NE_16( hCPE->hCoreCoder[0]->tdm_LRTD_flag, 0 ) ) ) ) ) + IF( (GT_32( st->core_brate, SID_2k40 ) && ( !( ((EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && EQ_16( hCPE->nchan_out, 1 )) || (( NE_16( st->core, ACELP_CORE ) || EQ_16( st->extl, -1 )) || ( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) && NE_16( hCPE->hCoreCoder[0]->tdm_LRTD_flag, 0 ) ) )) ) )) ) { Scale_sig32( hb_synth_32_fx[0], output_frame, sub( Q11, q ) ); Scale_sig32( hb_synth_32_fx[1], output_frame, sub( Q11, q ) ); diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 46f510cfa..ac39d5247 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -325,7 +325,7 @@ ivas_error ivas_dec_setup( //////////////// Cleanup changes: float to fixed ////////////////// Word16 SrcInd[MAX_NUM_TDREND_CHANNELS]; Word16 num_src = 0; - Word16 i, Q_cldfbSynDec = 21; + Word16 i; Word16 old_ism_mode = ivas_omasa_ism_mode_select(st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->nchan_ism); Word16 new_ism_mode = ivas_omasa_ism_mode_select(st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_ism); @@ -354,8 +354,7 @@ ivas_error ivas_dec_setup( } IF(st_ivas->cldfbSynDec[0]) { - Q_cldfbSynDec = s_min(Q_cldfbSynDec, Q_factor_arrL(st_ivas->cldfbSynDec[0]->cldfb_state, sub(st_ivas->cldfbSynDec[0]->p_filter_length, st_ivas->cldfbSynDec[0]->no_channels))); - floatToFixed_arrL(st_ivas->cldfbSynDec[0]->cldfb_state, st_ivas->cldfbSynDec[0]->cldfb_state_fx, Q_cldfbSynDec, sub(st_ivas->cldfbAnaDec[i]->p_filter_length, st_ivas->cldfbAnaDec[i]->no_channels)); + floatToFixed_arrL(st_ivas->cldfbSynDec[0]->cldfb_state, st_ivas->cldfbSynDec[0]->cldfb_state_fx, Q11, sub(st_ivas->cldfbSynDec[0]->p_filter_length, st_ivas->cldfbSynDec[0]->no_channels)); } } //////////////////////////////////////////////////////////////// @@ -402,7 +401,7 @@ ivas_error ivas_dec_setup( } IF( st_ivas->cldfbSynDec[0] ) { - fixedToFloat_arrL( st_ivas->cldfbSynDec[0]->cldfb_state_fx, st_ivas->cldfbSynDec[0]->cldfb_state, Q_cldfbSynDec, sub( st_ivas->cldfbAnaDec[i]->p_filter_length, st_ivas->cldfbAnaDec[i]->no_channels ) ); + fixedToFloat_arrL( st_ivas->cldfbSynDec[0]->cldfb_state_fx, st_ivas->cldfbSynDec[0]->cldfb_state, Q11, sub( st_ivas->cldfbSynDec[0]->p_filter_length, st_ivas->cldfbSynDec[0]->no_channels ) ); } } //////////////////////////////////////////////////////////////// @@ -433,7 +432,7 @@ ivas_error ivas_dec_setup( //////////////// Cleanup changes: float to fixed ////////////////// Word16 SrcInd[MAX_NUM_TDREND_CHANNELS]; Word16 num_src = 0; - Word16 i, Q_cldfbSynDec = 21; + Word16 i; Word16 old_ism_mode = ivas_omasa_ism_mode_select( st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->nchan_ism ); Word16 new_ism_mode = ivas_omasa_ism_mode_select( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_ism ); @@ -462,8 +461,7 @@ ivas_error ivas_dec_setup( } IF( st_ivas->cldfbSynDec[0] ) { - Q_cldfbSynDec = s_min( Q_cldfbSynDec, Q_factor_arrL( st_ivas->cldfbSynDec[0]->cldfb_state, sub( st_ivas->cldfbSynDec[0]->p_filter_length, st_ivas->cldfbSynDec[0]->no_channels ) ) ); - floatToFixed_arrL( st_ivas->cldfbSynDec[0]->cldfb_state, st_ivas->cldfbSynDec[0]->cldfb_state_fx, Q_cldfbSynDec, sub( st_ivas->cldfbAnaDec[i]->p_filter_length, st_ivas->cldfbAnaDec[i]->no_channels ) ); + floatToFixed_arrL( st_ivas->cldfbSynDec[0]->cldfb_state, st_ivas->cldfbSynDec[0]->cldfb_state_fx, Q11, sub( st_ivas->cldfbSynDec[0]->p_filter_length, st_ivas->cldfbSynDec[0]->no_channels ) ); } } //////////////////////////////////////////////////////////////// @@ -510,7 +508,7 @@ ivas_error ivas_dec_setup( } IF( st_ivas->cldfbSynDec[0] ) { - fixedToFloat_arrL( st_ivas->cldfbSynDec[0]->cldfb_state_fx, st_ivas->cldfbSynDec[0]->cldfb_state, Q_cldfbSynDec, sub( st_ivas->cldfbAnaDec[i]->p_filter_length, st_ivas->cldfbAnaDec[i]->no_channels ) ); + fixedToFloat_arrL( st_ivas->cldfbSynDec[0]->cldfb_state_fx, st_ivas->cldfbSynDec[0]->cldfb_state, Q11, sub( st_ivas->cldfbSynDec[0]->p_filter_length, st_ivas->cldfbSynDec[0]->no_channels ) ); } } //////////////////////////////////////////////////////////////// @@ -1497,6 +1495,10 @@ ivas_error ivas_init_decoder_fx( { return error; } +#ifdef MSAN_FIX + set_f( st_ivas->hSpar->hFbMixer->cldfb_cross_fade, 0.f, CLDFB_NO_COL_MAX ); + set_s( st_ivas->hSpar->hFbMixer->cldfb_cross_fade_fx, 0, CLDFB_NO_COL_MAX ); +#endif IF ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC && st_ivas->hOutSetup.is_loudspeaker_setup ) { @@ -2532,7 +2534,7 @@ ivas_error ivas_init_decoder_fx( } IF( st_ivas->cldfbSynDec[0] ) { - fixedToFloat_arrL( st_ivas->cldfbSynDec[0]->cldfb_state_fx, st_ivas->cldfbSynDec[0]->cldfb_state, Q_cldfbSynDec, sub( st_ivas->cldfbAnaDec[i]->p_filter_length, st_ivas->cldfbAnaDec[i]->no_channels ) ); + fixedToFloat_arrL( st_ivas->cldfbSynDec[0]->cldfb_state_fx, st_ivas->cldfbSynDec[0]->cldfb_state, Q_cldfbSynDec, sub( st_ivas->cldfbSynDec[0]->p_filter_length, st_ivas->cldfbSynDec[0]->no_channels ) ); } IF( st_ivas->hSpar ) { diff --git a/lib_dec/ivas_qmetadata_dec.c b/lib_dec/ivas_qmetadata_dec.c index 8ebb0f619..f97c89461 100644 --- a/lib_dec/ivas_qmetadata_dec.c +++ b/lib_dec/ivas_qmetadata_dec.c @@ -1686,20 +1686,34 @@ Word16 ivas_qmetadata_dec_decode_hr_384_512( } } +#ifdef MSAN_FIX + FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ ) + { + FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ ) + { +#else FOR( b = 0; b < MASA_MAXIMUM_CODING_SUBBANDS; b++ ) { FOR( m = 0; m < MAX_PARAM_SPATIAL_SUBFRAMES; m++ ) { +#endif // MSAN_FIX hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[m] = W_round64_L( W_nrg_ratio[0][b][m] ); move32(); } } IF( EQ_32( hQMetaData->no_directions, 2 ) ) { +#ifdef MSAN_FIX + FOR( b = 0; b < hQMetaData->q_direction[1].cfg.nbands; b++ ) + { + FOR( m = 0; m < hQMetaData->q_direction[1].cfg.nblocks; m++ ) + { +#else FOR( b = 0; b < MASA_MAXIMUM_CODING_SUBBANDS; b++ ) { FOR( m = 0; m < MAX_PARAM_SPATIAL_SUBFRAMES; m++ ) { +#endif // MSAN_FIX hQMetaData->q_direction[1].band_data[b].energy_ratio_fx[m] = W_round64_L( W_nrg_ratio[1][b][m] ); move32(); } diff --git a/lib_dec/ivas_sba_dirac_stereo_dec_fx.c b/lib_dec/ivas_sba_dirac_stereo_dec_fx.c index 7339afde7..c34ba020f 100644 --- a/lib_dec/ivas_sba_dirac_stereo_dec_fx.c +++ b/lib_dec/ivas_sba_dirac_stereo_dec_fx.c @@ -768,6 +768,10 @@ static void ivas_sba_dirac_stereo_compute_td_stefi_nrgs( ELSE { set_val_Word32( hStereoDft->hb_stefi_sig_fx + hStereoDft->hb_stefi_delay, 0, output_frame); +#ifdef MSAN_FIX + hStereoDft->hb_nrg_subr_fx[0] = 0; + hStereoDft->hb_nrg_subr_fx[1] = 0; +#endif // MSAN_FIX } hStereoDft->hb_nrg_subr_fx[0] = hStereoDft->hb_nrg_subr_fx[0]; //imult3216(hStereoDft->hb_nrg_subr_fx[0] , shr(hStereoDft->NFFT, 1)); move32(); diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index 7bc77fd2b..21fda4add 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -1282,9 +1282,16 @@ static void stereo_dft_generate_comfort_noise_fx( { FOR( i = 0; i < numSlots; i++ ) { +#ifndef MSAN_FIX Word16 q_sqrt; +#else + Word16 q_sqrt = hFdCngCom->cngNoiseLevelExp; +#endif /* Real part in FFT bins */ rand_gauss_fx( ptr_r, &st->hTdCngDec->cng_seed, q_dft ); +#ifdef MSAN_FIX + q_sqrt = sub( Q31, q_cngNoiseLevel ); +#endif tmp = Mpy_32_16_1( Sqrt32( *ptr_level, &q_sqrt ), scale ); ( *ptr_r ) = Mpy_32_32( *ptr_r, tmp ); move32(); diff --git a/lib_dec/ivas_stereo_dft_plc_fx.c b/lib_dec/ivas_stereo_dft_plc_fx.c index 318f8e1eb..255066ea3 100644 --- a/lib_dec/ivas_stereo_dft_plc_fx.c +++ b/lib_dec/ivas_stereo_dft_plc_fx.c @@ -76,7 +76,7 @@ void stereo_dft_res_ecu_fx( Word32 *input_mem /* o : Residual DFT buffer input mem */ ) { - Word32 res_buf[L_FRAME8k]; + Word32 res_buf[L_FRAME8k] = { 0 }; Word16 i; Word16 L_res; Word16 step; diff --git a/lib_dec/ivas_stereo_icbwe_dec.c b/lib_dec/ivas_stereo_icbwe_dec.c index e1fedd72f..39ae1386f 100644 --- a/lib_dec/ivas_stereo_icbwe_dec.c +++ b/lib_dec/ivas_stereo_icbwe_dec.c @@ -1,2146 +1,2150 @@ -/****************************************************************************************************** - - (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#include -#include -#include "options.h" -#include -#include "cnst.h" -#include "ivas_cnst.h" -#include "prot.h" -#include "prot_fx1.h" -#include "prot_fx2.h" -#include "ivas_prot.h" -#include "ivas_prot_fx.h" -#include "wmc_auto.h" -#include "rom_com.h" -#include "ivas_rom_com.h" - - -#define Q_icBWE 16 - -/*-------------------------------------------------------------------* - * ic_bwe_dec_reset() - * - * core switching reset of IC BWE memory - *-------------------------------------------------------------------*/ - -#ifndef IVAS_FLOAT_FIXED -static void ic_bwe_dec_reset( - STEREO_ICBWE_DEC_HANDLE hStereoICBWE /* i/o: Stereo ICBWE handle */ -) -{ - /* unscaled & scaled SHB synthesis memory */ - set_f( hStereoICBWE->mem_syn_shb_nonref, 0, L_SHB_LAHEAD ); /* use samples from !acelp) */ - set_f( hStereoICBWE->mem_lpc_shbsynth_nonref, 0, LPC_SHB_ORDER ); - set_f( hStereoICBWE->mem_syn_shb_ola_nonref, 0, L_SHB_LAHEAD ); /* use samples from !acelp) */ - - /* inter-channel BWE SP and GSP mem reset */ - hStereoICBWE->memShbSpecMapping = 0; - - set_f( hStereoICBWE->memShbHilbert_nonref, 0, HILBERT_MEM_SIZE ); - set_f( hStereoICBWE->memShbInterp_nonref, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); - set_f( hStereoICBWE->memShb_fsout_nonref, 0, INTERP_3_2_MEM_LEN ); - hStereoICBWE->syn_dm_phase_nonref = 0; - - return; -} -#else -static void ic_bwe_dec_reset_fx( - STEREO_ICBWE_DEC_HANDLE hStereoICBWE /* i/o: Stereo ICBWE handle */ -) -{ - /* unscaled & scaled SHB synthesis memory */ - set32_fx( hStereoICBWE->mem_syn_shb_nonref_fx, 0, L_SHB_LAHEAD ); /* use samples from !acelp) */ - set32_fx( hStereoICBWE->mem_lpc_shbsynth_nonref_fx, 0, LPC_SHB_ORDER ); - set32_fx( hStereoICBWE->mem_syn_shb_ola_nonref_fx, 0, L_SHB_LAHEAD ); /* use samples from !acelp) */ - - hStereoICBWE->prev_Q_syn_shb_nonref = 31; - move16(); - hStereoICBWE->prev_Q_lpc_shbsynth_nonref = 31; - move16(); - hStereoICBWE->prev_Q_syn_shb_ola_nonref = 31; - move16(); - - /* inter-channel BWE SP and GSP mem reset */ - hStereoICBWE->memShbSpecMapping_fx = 0; - move32(); - hStereoICBWE->prev_Q_memshbspec = 31; - move16(); - - set32_fx( hStereoICBWE->memShbHilbert_nonref_fx, 0, HILBERT_MEM_SIZE ); - set32_fx( hStereoICBWE->memShbInterp_nonref_fx, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); - set32_fx( hStereoICBWE->memShb_fsout_nonref_fx, 0, INTERP_3_2_MEM_LEN ); - - hStereoICBWE->prev_Q_hilb = 31; - move16(); - hStereoICBWE->prev_Q_interp = 31; - move16(); - hStereoICBWE->prev_Q_fsout = 31; - move16(); - - hStereoICBWE->syn_dm_phase_nonref = 0; - move16(); - - return; -} -#endif - - -#ifndef IVAS_FLOAT_FIXED -/*-------------------------------------------------------------------* - * stereo_icBWE_dec() - * - * Spatial mapping of reference to the non-reference channels in SHB - *-------------------------------------------------------------------*/ - -void stereo_icBWE_dec( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *synthRef, /* i/o: Reference channel HB synthesis at output Fs */ - float *synth, /* o : Non reference channel HB synthesis at output Fs */ - const float *fb_synth_ref, /* i : ref. high-band synthesis 16-20 kHz */ - const float *voice_factors, /* i : voicing factors */ - const int16_t output_frame /* i : frame length */ -) -{ - int16_t i, j, k, nbSubFr; - Decoder_State *st; /* i/o: decoder state structure, primary channel */ - int16_t spIndx, gsIndx; - float excSHB_nonref[L_FRAME16k]; - float shb_synth_nonref[L_FRAME16k + L_SHB_LAHEAD]; - float error[L_FRAME32k]; - float nlMixFac[NB_SUBFR16k]; - float gsMapping, specMapping; - float fb_synth_nonref[L_FRAME48k]; - float scale, prev_pow, curr_pow, temp; - float alpha, winSlope, winLen, prevgsMapping; - float temp1, temp2; - float icbweM2Ref, ratio_L; - - STEREO_DFT_DEC_DATA_HANDLE hStereoDft = hCPE->hStereoDft; - STEREO_ICBWE_DEC_HANDLE hStereoICBWE = hCPE->hStereoICBWE; - st = hCPE->hCoreCoder[0]; - - /*--------------------------------------------------------------------* - * skip IC-BWE in case of mono DMX output * - * -------------------------------------------------------------------*/ - - if ( hCPE->element_mode == IVAS_CPE_DFT && hCPE->nchan_out == 1 && hCPE->hStereoDft->hConfig->res_cod_mode > STEREO_DFT_RES_COD_OFF ) - { - hCPE->hStereoDft->core_hist[0] = st->core; - - return; - } - else if ( hCPE->element_mode == IVAS_CPE_DFT && hCPE->nchan_out == 1 ) - { - - return; - } - - /*--------------------------------------------------------------------* - * skip IC-BWE in case of SID or NO_DATA frame - * -------------------------------------------------------------------*/ - - if ( st->core_brate <= SID_2k40 ) - { - return; - } - - /*--------------------------------------------------------------------* - * TD high band stereo filling * - * -------------------------------------------------------------------*/ - - /* update buffers for TD stereo filling */ - if ( hCPE->element_mode == IVAS_CPE_DFT ) - { - float hb_nrg = EPSILON; - float hb_nrg2 = EPSILON; - - if ( st->core == ACELP_CORE || st->last_core == ACELP_CORE ) - { - for ( i = 0; i < output_frame / 2; i++ ) - { - hb_nrg2 += synthRef[i] * synthRef[i]; - } - - hCPE->hStereoDft->hb_nrg_subr[0] = hb_nrg2; - hb_nrg += hb_nrg2; - hb_nrg2 = EPSILON; - - for ( ; i < output_frame; i++ ) - { - hb_nrg2 += synthRef[i] * synthRef[i]; - } - - hCPE->hStereoDft->hb_nrg_subr[1] = hb_nrg2; - hb_nrg += hb_nrg2; - - mvr2r( synthRef, hCPE->hStereoDft->hb_stefi_sig + hCPE->hStereoDft->hb_stefi_delay, output_frame ); - } - else - { - set_zero( hCPE->hStereoDft->hb_stefi_sig + hCPE->hStereoDft->hb_stefi_delay, output_frame ); - } - hCPE->hStereoDft->hb_nrg_subr[0] *= hCPE->hStereoDft->NFFT / 2; - hCPE->hStereoDft->hb_nrg_subr[1] *= hCPE->hStereoDft->NFFT / 2; - hCPE->hStereoDft->hb_nrg[0] = hb_nrg; - hCPE->hStereoDft->td_gain[0] = 0; - hCPE->hStereoDft->core_hist[0] = st->core; - } - - /*--------------------------------------------------------------------* - * IC-BWE * - * -------------------------------------------------------------------*/ - - if ( st->core != ACELP_CORE || st->extl == -1 || ( hCPE->element_mode == IVAS_CPE_TD && hCPE->hCoreCoder[0]->tdm_LRTD_flag ) ) - { - return; - } - else if ( hCPE->element_mode == IVAS_CPE_DFT && st->core_brate <= SID_2k40 ) - { - mvr2r( synthRef, synth, output_frame ); - return; - } - - - set_f( fb_synth_nonref, 0, L_FRAME48k ); - - /* core switching reset */ - if ( st->last_core != ACELP_CORE || st->bwidth == WB ) - { - ic_bwe_dec_reset( hStereoICBWE ); - - if ( st->last_core != ACELP_CORE ) - { - hStereoICBWE->prevSpecMapping = 0.0f; - hStereoICBWE->prevgsMapping = 1.0f; - hStereoICBWE->icbweM2Ref_prev = 1.0f; - } - - if ( st->bwidth == WB ) - { - /* copy to outputHB and reset hb_synth values */ - mvr2r( synthRef, synth, output_frame ); - - if ( st->element_mode == IVAS_CPE_TD ) - { - hStereoICBWE->prevSpecMapping = 0.0f; - hStereoICBWE->prevgsMapping = 1.0f; - hStereoICBWE->icbweM2Ref_prev = 1.0f; - } - else if ( st->element_mode == IVAS_CPE_DFT ) - { - hStereoICBWE->refChanIndx_bwe = L_CH_INDX; - hStereoICBWE->prevSpecMapping = 0.0f; - - prevgsMapping = hStereoICBWE->prevgsMapping; - temp1 = hStereoDft->side_gain[2 * STEREO_DFT_BAND_MAX + hStereoDft->nbands - 1]; - icbweM2Ref = 1.f + temp1; - gsMapping = 1.f - temp1; - - winLen = (int16_t) ( ( SHB_OVERLAP_LEN * st->output_Fs ) / 16000 ); - winSlope = 1.0f / winLen; - alpha = winSlope; - for ( i = 0; i < winLen; i++ ) - { - synthRef[i] *= ( alpha * ( icbweM2Ref ) + ( 1.0f - alpha ) * ( hStereoICBWE->icbweM2Ref_prev ) ); - synth[i] *= ( alpha * ( gsMapping ) + ( 1.0f - alpha ) * ( prevgsMapping ) ); - alpha += winSlope; - } - for ( ; i < NS2SA( st->output_Fs, FRAME_SIZE_NS ); i++ ) - { - synthRef[i] *= ( icbweM2Ref ); - synth[i] *= ( gsMapping ); - } - hStereoICBWE->icbweM2Ref_prev = icbweM2Ref; - hStereoICBWE->prevgsMapping = gsMapping; - } - - return; - } - } - - if ( !st->bfi ) - { - hStereoICBWE->refChanIndx_bwe = get_next_indice( st, STEREO_ICBWE_REFBITS ); - if ( st->flag_ACELP16k == 1 ) - { - spIndx = get_next_indice( st, STEREO_ICBWE_SPBITS ); - } - else - { - spIndx = 3; - } - if ( st->element_mode == IVAS_CPE_TD ) - { - gsIndx = get_next_indice( st, STEREO_ICBWE_GSBITS ); - } - else - { - gsIndx = get_next_indice( st, STEREO_ICBWE_GSBITS_DFT ); - } - - /* Store indices in case of frame loss */ - hStereoICBWE->prev_spIndx = spIndx; - hStereoICBWE->prev_gsIndx = gsIndx; - } - else /*bfi*/ - { - /* Retrieve last decoded indices */ - spIndx = hStereoICBWE->prev_spIndx; - gsIndx = hStereoICBWE->prev_gsIndx; - hStereoICBWE->refChanIndx_bwe = hStereoICBWE->prev_refChanIndx_bwe; - } - - /* IC-BWE parameter de-quant */ - /* sp Mapping */ - hStereoICBWE->prevSpecMapping = usdequant( spIndx, -0.6f, 0.2f ); - - /* gs Mapping */ - prevgsMapping = hStereoICBWE->prevgsMapping; - - if ( st->element_mode == IVAS_CPE_TD ) - { - hStereoICBWE->prevgsMapping = icbwe_gsMapping_tbl[gsIndx]; - } - else - { - hStereoICBWE->prevgsMapping = icbwe_gsMappingDFT_tbl[gsIndx]; - } - - hStereoICBWE->prevgsMapping = powf( 10, hStereoICBWE->prevgsMapping ); - - specMapping = hStereoICBWE->prevSpecMapping; - gsMapping = hStereoICBWE->prevgsMapping; - - if ( ( st->extl == SWB_TBE || st->extl == FB_TBE ) && st->flag_ACELP16k == 1 ) - { - mvr2r( voice_factors, nlMixFac, NB_SUBFR16k ); - if ( hCPE->hStereoDftDmx != NULL ) - { - if ( hCPE->hStereoDftDmx->targetGain < 0.5f || hCPE->hStereoDftDmx->targetGain > 2.0f ) - { - v_multc( voice_factors, 0.5f, nlMixFac, NB_SUBFR16k ); - } - } - else - { - if ( hCPE->hStereoTCA->targetGain < 0.5f || hCPE->hStereoTCA->targetGain > 2.0f ) - { - v_multc( voice_factors, 0.5f, nlMixFac, NB_SUBFR16k ); - } - } - - nbSubFr = ( st->flag_ACELP16k == 0 ) ? NB_SUBFR : NB_SUBFR16k; - for ( i = 0, k = 0; i < nbSubFr; i++ ) - { - if ( hCPE->hCoreCoder[0]->coder_type == UNVOICED || hStereoICBWE->MSFlag == 1 ) - { - temp1 = 0; - temp2 = 1.0f; - } - else - { - temp1 = sqrtf( nlMixFac[i] ); - temp2 = sqrtf( 1.0f - nlMixFac[i] ); - } - - for ( j = 0; j < L_FRAME16k / nbSubFr; j++, k++ ) - { - excSHB_nonref[k] = temp1 * hStereoICBWE->nlExc16k[k] + temp2 * hStereoICBWE->mixExc16k[k]; - } - } - - /* LP synthesis */ - mvr2r( hStereoICBWE->mem_syn_shb_nonref, shb_synth_nonref, L_SHB_LAHEAD ); - syn_filt( hStereoICBWE->lpSHBRef, LPC_SHB_ORDER, excSHB_nonref, shb_synth_nonref + L_SHB_LAHEAD, L_FRAME16k, hStereoICBWE->mem_lpc_shbsynth_nonref, 1 ); - - prev_pow = sum2_f( shb_synth_nonref, L_SHB_LAHEAD + 10 ); - curr_pow = sum2_f( shb_synth_nonref + L_SHB_LAHEAD + 10, L_SHB_LAHEAD + 10 ); - - if ( prev_pow == 0 ) - { - scale = 0; - } - else - { - scale = sqrtf( curr_pow / prev_pow ); - } - - for ( i = 0; i < L_SHB_LAHEAD; i++ ) - { - shb_synth_nonref[i] *= scale; - } - - for ( ; i < L_SHB_LAHEAD + 10; i++ ) - { - temp = ( i - 19 ) / 10.0f; - shb_synth_nonref[i] *= ( temp * 1.0f + ( 1.0f - temp ) * scale ); - } - /* spec and gs adjustment */ - deemph( shb_synth_nonref + L_SHB_LAHEAD, specMapping, L_FRAME16k, &( hStereoICBWE->memShbSpecMapping ) ); - mvr2r( shb_synth_nonref + L_FRAME16k, hStereoICBWE->mem_syn_shb_nonref, L_SHB_LAHEAD ); - - ScaleShapedSHB( SHB_OVERLAP_LEN, shb_synth_nonref, hStereoICBWE->mem_syn_shb_ola_nonref, hStereoICBWE->gshapeRef, ( hStereoICBWE->gFrameRef * gsMapping * 0.9f ), window_shb, subwin_shb ); - - if ( st->extl == FB_TBE ) - { - v_multc( fb_synth_ref, gsMapping, fb_synth_nonref, L_FRAME48k ); - } - - /* generate 32kHz SHB synthesis from 12.8(16)kHz signal */ - GenSHBSynth( shb_synth_nonref, error, hStereoICBWE->memShbHilbert_nonref, hStereoICBWE->memShbInterp_nonref, st->L_frame, &( hStereoICBWE->syn_dm_phase_nonref ) ); - } - else - { - mvr2r( synthRef, synth, output_frame ); - - winLen = (int16_t) ( ( SHB_OVERLAP_LEN * st->output_Fs ) / 16000 ); - winSlope = 1.0f / winLen; - alpha = winSlope; - - ratio_L = ( hCPE->element_mode == IVAS_CPE_DFT ) ? ( 0.5f ) : ( tdm_ratio_tabl[hCPE->hStereoTD->tdm_last_ratio_idx] ); - - icbweM2Ref = gsMapping; - if ( hStereoICBWE->refChanIndx_bwe == L_CH_INDX ) - { - if ( ratio_L >= 0.1f ) - { - icbweM2Ref = sqrtf( 0.5f - min( 0.5f, ( 1 - ratio_L ) * ( 1 - ratio_L ) * gsMapping * gsMapping ) ) / ratio_L; - } - } - else - { - if ( ratio_L <= 0.9f ) - { - icbweM2Ref = sqrtf( 0.5f - min( 0.5f, ratio_L * ratio_L * gsMapping * gsMapping ) ) / ( 1 - ratio_L ); - } - } - - icbweM2Ref = max( gsMapping, icbweM2Ref ); - - for ( i = 0; i < winLen; i++ ) - { - synthRef[i] *= ( alpha * ( icbweM2Ref ) + ( 1.0f - alpha ) * ( hStereoICBWE->icbweM2Ref_prev ) ); - synth[i] *= ( alpha * ( gsMapping ) + ( 1.0f - alpha ) * ( prevgsMapping ) ); - alpha += winSlope; - } - for ( ; i < NS2SA( st->output_Fs, FRAME_SIZE_NS ); i++ ) - { - synthRef[i] *= ( icbweM2Ref ); - synth[i] *= ( gsMapping ); - } - hStereoICBWE->icbweM2Ref_prev = icbweM2Ref; - - ic_bwe_dec_reset( hStereoICBWE ); - hStereoICBWE->prevSpecMapping = 0.0f; - - return; - } - - /* resample to output FS */ - if ( st->output_Fs == 48000 ) - { - interpolate_3_over_2_allpass( error, L_FRAME32k, synth, hStereoICBWE->memShb_fsout_nonref ); - } - else if ( st->output_Fs == 32000 ) - { - mvr2r( error, synth, L_FRAME32k ); - } - else if ( st->output_Fs == 16000 ) - { - Decimate_allpass_steep( error, hStereoICBWE->memShb_fsout_nonref, L_FRAME32k, synth ); - } - - - if ( st->extl == FB_TBE && st->output_Fs == 48000 ) - { - v_add( fb_synth_nonref, synth, synth, L_FRAME48k ); - } - - /* copy to outputHB and reset hb_synth values */ - ratio_L = ( hCPE->element_mode == IVAS_CPE_DFT ) ? ( 0.5f ) : ( tdm_ratio_tabl[hCPE->hStereoTD->tdm_last_ratio_idx] ); - - icbweM2Ref = gsMapping; - if ( hStereoICBWE->refChanIndx_bwe == L_CH_INDX ) - { - if ( ratio_L >= 0.1f ) - { - icbweM2Ref = sqrtf( 0.5f - min( 0.5f, ( 1 - ratio_L ) * ( 1 - ratio_L ) * gsMapping * gsMapping ) ) / ratio_L; - } - } - else - { - if ( ratio_L <= 0.9f ) - { - icbweM2Ref = sqrtf( 0.5f - min( 0.5f, ratio_L * ratio_L * gsMapping * gsMapping ) ) / ( 1 - ratio_L ); - } - } - - icbweM2Ref = max( gsMapping, icbweM2Ref ); - - winLen = (int16_t) ( ( SHB_OVERLAP_LEN * st->output_Fs ) / 16000 ); - winSlope = 1.0f / winLen; - alpha = winSlope; - for ( i = 0; i < winLen; i++ ) - { - synthRef[i] *= ( alpha * ( icbweM2Ref ) + ( 1.0f - alpha ) * ( hStereoICBWE->icbweM2Ref_prev ) ); - alpha += winSlope; - } - - for ( ; i < NS2SA( st->output_Fs, FRAME_SIZE_NS ); i++ ) - { - synthRef[i] *= ( icbweM2Ref ); - } - - hStereoICBWE->icbweM2Ref_prev = icbweM2Ref; - - return; -} -#else -static Word16 FindScale( - Word32 *buff, - Word16 len, - Word16 Q_buff, - Word16 Q_prev ) -{ - Word32 maxVal; - Word16 norm_shift, Q_out; - - maximum_abs_32_fx( buff, len, &maxVal ); - norm_shift = norm_l( maxVal ); - IF( EQ_32( maxVal, 0 ) ) - { - norm_shift = 31; - move16(); - } - - Q_out = s_min( Q_prev, add( Q_buff, norm_shift ) ); - - return Q_out; -} - - -void stereo_icBWE_dec_fx( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - Word32 *synthRef_fx, /* i/o: Reference channel HB synthesis at output Fs Q_syn/Q_syn - 1 */ - Word32 *synth_fx, /* o : Non reference channel HB synthesis at output Fs Q_syn/Q_syn - 1 */ - const Word16 *fb_synth_ref_fx, /* i : ref. high-band synthesis 16-20 kHz Qx */ - const Word16 *voice_factors_fx, /* i : voicing factors Q15 */ - const Word16 output_frame, /* i : frame length */ - Word16 *Q_syn /* i : Q of synth and synthRef buffers */ -) -{ - Word16 i, j, k, nbSubFr; - Decoder_State *st; /* i/o: decoder state structure, primary channel */ - Word16 spIndx, gsIndx; - Word32 excSHB_nonref_fx[L_FRAME16k]; - Word32 shb_synth_nonref_fx[L_FRAME16k + L_SHB_LAHEAD]; - Word32 error_fx[L_FRAME32k]; - Word16 nlMixFac_fx[NB_SUBFR16k]; - Word16 specMapping_fx; - Word16 fb_synth_nonref_fx[L_FRAME48k]; - Word32 prev_pow_fx, curr_pow_fx, maxVal1, maxVal; - Word16 scale_fx, e_scale_fx; - Word16 alpha_fx, winSlope_fx, winLen_fx; - Word16 prevgsMapping_fx; - Word16 temp1_fx, temp2_fx; - Word16 icbweM2Ref_fx, ratio_L_fx; - Word16 gsMapping_fx; - Word32 hb_nrg_fx, hb_nrg2_fx; - Word16 Q_syn_shb; - Word16 shift_prev_pow, synthRef_shift; - Word32 L_tmp; - Word16 tmp; - Word32 L_nlExc16k, L_mixExc16k; - - STEREO_DFT_DEC_DATA_HANDLE hStereoDft = hCPE->hStereoDft; - STEREO_ICBWE_DEC_HANDLE hStereoICBWE = hCPE->hStereoICBWE; - st = hCPE->hCoreCoder[0]; - - /*--------------------------------------------------------------------* - * skip IC-BWE in case of mono DMX output * - * -------------------------------------------------------------------*/ - - test(); - test(); - test(); - IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && EQ_16( hCPE->nchan_out, 1 ) && GT_16( hCPE->hStereoDft->hConfig->res_cod_mode, STEREO_DFT_RES_COD_OFF ) ) - { - hCPE->hStereoDft->core_hist[0] = st->core; - move16(); - - return; - } - ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && EQ_16( hCPE->nchan_out, 1 ) ) - { - return; - } - - /*--------------------------------------------------------------------* - * skip IC-BWE in case of SID or NO_DATA frame - * -------------------------------------------------------------------*/ - - IF( LE_32( st->core_brate, SID_2k40 ) ) - { - return; - } - - /*--------------------------------------------------------------------* - * TD high band stereo filling * - * -------------------------------------------------------------------*/ - - /* update buffers for TD stereo filling */ - IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) - { - hb_nrg_fx = 0; - move32(); - hb_nrg2_fx = 0; - move32(); - maximum_abs_32_fx( synthRef_fx, output_frame, &maxVal ); - synthRef_shift = norm_l( maxVal ); - IF( EQ_32( maxVal, 0 ) ) - { - synthRef_shift = 31; - move16(); - } - synthRef_shift = sub( synthRef_shift, shr( add( find_guarded_bits_fx( output_frame ), 1 ), 1 ) ); - test(); - IF( EQ_16( st->core, ACELP_CORE ) || EQ_16( st->last_core, ACELP_CORE ) ) - { - FOR( i = 0; i < output_frame / 2; i++ ) - { - // needed to be adjusted for q - L_tmp = L_shl( synthRef_fx[i], synthRef_shift ); - hb_nrg2_fx = L_add( hb_nrg2_fx, Mpy_32_32( L_tmp, L_tmp ) ); // 2*(Qx + SynthRef_shift) - 31 - } - - hCPE->hStereoDft->hb_nrg_subr_fx[0] = hb_nrg2_fx; - move32(); - hStereoDft->q_hb_nrg_subr = sub(add(*Q_syn, synthRef_shift), 31); - hb_nrg_fx = L_add( hb_nrg_fx, hb_nrg2_fx ); - hb_nrg2_fx = 0; - move32(); - - FOR( ; i < output_frame; i++ ) - { - L_tmp = L_shl( synthRef_fx[i], synthRef_shift ); - hb_nrg2_fx = L_add( hb_nrg2_fx, Mpy_32_32( L_tmp, L_tmp ) ); - } - - hCPE->hStereoDft->hb_nrg_subr_fx[1] = hb_nrg2_fx; // 2*(Qx + SynthRef_shift) - 31 - move32(); - hb_nrg_fx = L_add( hb_nrg_fx, hb_nrg2_fx ); - - Copy32( synthRef_fx, hCPE->hStereoDft->hb_stefi_sig_fx + hCPE->hStereoDft->hb_stefi_delay, output_frame ); - - Scale_sig32(hCPE->hStereoDft->hb_stefi_sig_fx + hCPE->hStereoDft->hb_stefi_delay, output_frame, -5); - } - ELSE - { - set32_fx( hCPE->hStereoDft->hb_stefi_sig_fx + hCPE->hStereoDft->hb_stefi_delay, 0, output_frame ); - } - hCPE->hStereoDft->hb_nrg_subr_fx[0] = ( Mpy_32_16_1( hCPE->hStereoDft->hb_nrg_subr_fx[0], shl( hCPE->hStereoDft->NFFT / 2, 6 ) ) ); // 2 * (Qx + SynthRef_shift) - 40 // 2 * (Qx + SynthRef_shift) - 31 - 15 - move32(); - hCPE->hStereoDft->hb_nrg_subr_fx[1] = ( Mpy_32_16_1( hCPE->hStereoDft->hb_nrg_subr_fx[1], shl( hCPE->hStereoDft->NFFT / 2, 6 ) ) ); // 2 * (Qx + SynthRef_shift) - 40 - move32(); - hCPE->hStereoDft->q_hb_nrg_subr = sub( shl( ( *Q_syn + synthRef_shift ), 1 ), 40 ); - hCPE->hStereoDft->hb_nrg_fx[0] = hb_nrg_fx; // 2 * (Qx + SynthRef_shift) - 31 - move32(); - hCPE->hStereoDft->td_gain_fx[0] = 0; - move32(); - hCPE->hStereoDft->core_hist[0] = st->core; - move16(); - } - - /*--------------------------------------------------------------------* - * IC-BWE * - * -------------------------------------------------------------------*/ - test(); - test(); - test(); - test(); - IF( NE_16( st->core, ACELP_CORE ) || EQ_16( st->extl, -1 ) || ( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) && NE_16( hCPE->hCoreCoder[0]->tdm_LRTD_flag, 0 ) ) ) - { - return; - } - ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && LE_32( st->core_brate, SID_2k40 ) ) - { - Copy32( synthRef_fx, synth_fx, output_frame ); - return; - } - - - set16_fx( fb_synth_nonref_fx, 0, L_FRAME48k ); - - /* core switching reset */ - test(); - IF( NE_16( st->last_core, ACELP_CORE ) || EQ_16( st->bwidth, (Word16) WB ) ) - { - ic_bwe_dec_reset_fx( hStereoICBWE ); - - IF( NE_16( st->last_core, ACELP_CORE ) ) - { - hStereoICBWE->prevSpecMapping_fx = 0; - move16(); - hStereoICBWE->prevgsMapping_fx = 16384; - move16(); - hStereoICBWE->icbweM2Ref_prev_fx = 16384; - move16(); - } - - IF( EQ_16( st->bwidth, WB ) ) - { - /* copy to outputHB and reset hb_synth values */ - Copy32( synthRef_fx, synth_fx, output_frame ); - - IF( EQ_16( st->element_mode, IVAS_CPE_TD ) ) - { - hStereoICBWE->prevSpecMapping_fx = 0; - move16(); - hStereoICBWE->prevgsMapping_fx = 16384; - move16(); - hStereoICBWE->icbweM2Ref_prev_fx = 16384; - move16(); - } - ELSE IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) - { - hStereoICBWE->refChanIndx_bwe = L_CH_INDX; - move16(); - hStereoICBWE->prevSpecMapping_fx = 0; - move16(); - - prevgsMapping_fx = hStereoICBWE->prevgsMapping_fx; - move16(); - temp1_fx = shr( extract_h( hStereoDft->side_gain_fx[2 * STEREO_DFT_BAND_MAX + hStereoDft->nbands - 1] ), 1 ); - icbweM2Ref_fx = add( 16384, temp1_fx ); - gsMapping_fx = sub( 16384, temp1_fx ); - - winLen_fx = extract_l( Mpy_32_16_1( st->output_Fs, 41 ) ); //(int16_t)((SHB_OVERLAP_LEN * st->output_Fs) / 16000); - winSlope_fx = div_s( 1, winLen_fx ); - alpha_fx = winSlope_fx; - move16(); - FOR( i = 0; i < winLen_fx; i++ ) - { - L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); // Q15 + Q14 - L_tmp = L_mac0( L_tmp, sub( 32767, alpha_fx ), ( hStereoICBWE->icbweM2Ref_prev_fx ) ); // Q15 + Q14; - tmp = shl( round_fx( L_tmp ), 1 ); // Q = 15 + 14 - 16 + 1 = Q14 - synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], tmp ); - move32(); - L_tmp = L_mult0( alpha_fx, gsMapping_fx ); - L_tmp = L_mac0( L_tmp, ( sub( 32767, alpha_fx ) ), ( prevgsMapping_fx ) ); - tmp = shl( round_fx( L_tmp ), 1 ); // Q = 15 + 14 - 16 + 1 = Q14 - synth_fx[i] = Mpy_32_16_1( synth_fx[i], tmp ); - move32(); - IF( LE_16( alpha_fx, sub( 32767, winSlope_fx ) ) ) - { - alpha_fx = add( alpha_fx, winSlope_fx ); - } - } - FOR( ; i < NS2SA( st->output_Fs, FRAME_SIZE_NS ); i++ ) - { - synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], icbweM2Ref_fx ); - move32(); - synth_fx[i] = Mpy_32_16_1( synth_fx[i], gsMapping_fx ); - move32(); - } - hStereoICBWE->icbweM2Ref_prev_fx = icbweM2Ref_fx; - move16(); - hStereoICBWE->prevgsMapping_fx = gsMapping_fx; - move16(); - - *Q_syn = sub( *Q_syn, 1 ); - } - - return; - } - } - - IF( EQ_16( st->bfi, 0 ) ) - { - hStereoICBWE->refChanIndx_bwe = get_next_indice_fx( st, STEREO_ICBWE_REFBITS ); - IF( EQ_16( st->flag_ACELP16k, 1 ) ) - { - spIndx = get_next_indice_fx( st, STEREO_ICBWE_SPBITS ); - } - ELSE - { - spIndx = 3; - move16(); - } - IF( EQ_16( st->element_mode, IVAS_CPE_TD ) ) - { - gsIndx = get_next_indice_fx( st, STEREO_ICBWE_GSBITS ); - } - ELSE - { - gsIndx = get_next_indice_fx( st, STEREO_ICBWE_GSBITS_DFT ); - } - - /* Store indices in case of frame loss */ - hStereoICBWE->prev_spIndx = spIndx; - move16(); - hStereoICBWE->prev_gsIndx = gsIndx; - move16(); - } - ELSE /*bfi*/ - { - /* Retrieve last decoded indices */ - spIndx = hStereoICBWE->prev_spIndx; - move16(); - gsIndx = hStereoICBWE->prev_gsIndx; - move16(); - hStereoICBWE->refChanIndx_bwe = hStereoICBWE->prev_refChanIndx_bwe; - move16(); - } - - /* IC-BWE parameter de-quant */ - /* sp Mapping */ - hStereoICBWE->prevSpecMapping_fx = usdequant_fx( spIndx, -19661, 3277 ); // Q15 - - /* gs Mapping */ - prevgsMapping_fx = hStereoICBWE->prevgsMapping_fx; // Q14 - move16(); - - IF( EQ_16( st->element_mode, IVAS_CPE_TD ) ) - { - hStereoICBWE->prevgsMapping_fx = pow_10_icbwe_gsMapping_tbl_fx[gsIndx]; - move16(); - } - ELSE - { - hStereoICBWE->prevgsMapping_fx = pow_10_icbwe_gsMappingDFT_tbl_fx[gsIndx]; - move16(); - } - - // hStereoICBWE->prevgsMapping = powf( 10, hStereoICBWE->prevgsMapping ); - - specMapping_fx = hStereoICBWE->prevSpecMapping_fx; // Q15 - move16(); - gsMapping_fx = hStereoICBWE->prevgsMapping_fx; // Q14 - move16(); - - test(); - test(); - IF( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && EQ_16( st->flag_ACELP16k, 1 ) ) - { - Copy( voice_factors_fx, nlMixFac_fx, NB_SUBFR16k ); // Q15 - IF( hCPE->hStereoDftDmx != NULL ) - { - test(); - IF( LT_32( hCPE->hStereoDftDmx->targetGain_fx, 268435456 ) || GT_32( hCPE->hStereoDftDmx->targetGain_fx, 1073741824 ) ) - { - v_multc_fixed_16_16( voice_factors_fx, 16384, nlMixFac_fx, NB_SUBFR16k ); - } - } - ELSE - { - test(); - IF( LT_32( hCPE->hStereoTCA->targetGain_fx, 268435456 ) || GT_32( hCPE->hStereoTCA->targetGain_fx, 1073741824 ) ) - { - v_multc_fixed_16_16( voice_factors_fx, 16384, nlMixFac_fx, NB_SUBFR16k ); - } - } - - // nbSubFr = ( st->flag_ACELP16k == 0 ) ? NB_SUBFR : NB_SUBFR16k; - IF( EQ_16( st->flag_ACELP16k, 0 ) ) - { - nbSubFr = NB_SUBFR; - move16(); - } - ELSE - { - nbSubFr = NB_SUBFR16k; - move16(); - } - k = 0; - move16(); - FOR( i = 0; i < nbSubFr; i++ ) - { - IF( EQ_16( hCPE->hCoreCoder[0]->coder_type, UNVOICED ) || EQ_16( hStereoICBWE->MSFlag, 1 ) ) - { - temp1_fx = 0; - move16(); - temp2_fx = 32767; - move16(); - } - ELSE - { - tmp = 0; - move16(); - temp1_fx = Sqrt16( nlMixFac_fx[i], &tmp ); - IF( LT_16( tmp, 0 ) ) - { - temp1_fx = shl( temp1_fx, tmp ); - } - tmp = 0; - move16(); - temp2_fx = Sqrt16( sub( 32767, nlMixFac_fx[i] ), &tmp ); - IF( LT_16( tmp, 0 ) ) - { - temp2_fx = shl( temp2_fx, tmp ); - } - } - - FOR( j = 0; j < L_FRAME16k / nbSubFr; j++ ) - { - // common Q for addition - L_nlExc16k = L_deposit_l( hStereoICBWE->nlExc16k_fx[k] ); // prev_q_bwe_exc - 16 - L_mixExc16k = L_deposit_l( hStereoICBWE->mixExc16k_fx[k] ); // Q_exc - L_nlExc16k = L_shl( L_nlExc16k, Q_icBWE - ( st->prev_Q_bwe_exc - 16 ) ); // Q_icBWE -#ifndef FIX_736_BWE_SECT_C - L_mixExc16k = L_shl( L_mixExc16k, Q_icBWE - st->Q_exc ); // Q_icBWE -#else - L_mixExc16k = L_shl( L_mixExc16k, Q_icBWE - ( st->prev_Q_bwe_exc - 25 ) ); // Q_icBWE -#endif - excSHB_nonref_fx[k] = L_add( Mpy_32_16_1( L_nlExc16k, temp1_fx ), Mpy_32_16_1( L_mixExc16k, temp2_fx ) ); // Q_icBWE - move32(); - k++; - } - } - - /* LP synthesis */ - Q_syn_shb = 31; - move16(); - - Q_syn_shb = FindScale( hStereoICBWE->mem_syn_shb_nonref_fx, LPC_SHB_ORDER, hStereoICBWE->prev_Q_syn_shb_nonref, Q_syn_shb ); - Q_syn_shb = FindScale( hStereoICBWE->lpSHBRef_fx, LPC_SHB_ORDER + 1, 12, Q_syn_shb ); - Q_syn_shb = FindScale( excSHB_nonref_fx, L_FRAME16k, Q_icBWE, Q_syn_shb ); - Q_syn_shb = FindScale( hStereoICBWE->mem_lpc_shbsynth_nonref_fx, LPC_SHB_ORDER, hStereoICBWE->prev_Q_lpc_shbsynth_nonref, Q_syn_shb ); - - Q_syn_shb = sub( Q_syn_shb, 3 ); // gaurded bits - - Scale_sig32( hStereoICBWE->lpSHBRef_fx, LPC_SHB_ORDER + 1, sub( Q_syn_shb, 12 ) ); - Scale_sig32( excSHB_nonref_fx, L_FRAME16k, sub( Q_syn_shb, Q_icBWE ) ); - Scale_sig32( hStereoICBWE->mem_lpc_shbsynth_nonref_fx, LPC_SHB_ORDER, sub( Q_syn_shb, hStereoICBWE->prev_Q_lpc_shbsynth_nonref ) ); - Scale_sig32( hStereoICBWE->mem_syn_shb_nonref_fx, L_SHB_LAHEAD, sub( Q_syn_shb, hStereoICBWE->prev_Q_syn_shb_nonref ) ); - - - Copy32( hStereoICBWE->mem_syn_shb_nonref_fx, shb_synth_nonref_fx, L_SHB_LAHEAD ); - - E_UTIL_synthesis_fx( 0, hStereoICBWE->lpSHBRef_fx, excSHB_nonref_fx, shb_synth_nonref_fx + L_SHB_LAHEAD, L_FRAME16k, hStereoICBWE->mem_lpc_shbsynth_nonref_fx, 1, LPC_SHB_ORDER ); - - hStereoICBWE->prev_Q_lpc_shbsynth_nonref = Q_syn_shb; - move16(); - - maximum_abs_32_fx( shb_synth_nonref_fx, L_SHB_LAHEAD + 10 + L_SHB_LAHEAD + 10, &maxVal1 ); // Qsyn_shb - - shift_prev_pow = sub( norm_l( maxVal1 ), find_guarded_bits_fx( L_SHB_LAHEAD + 10 ) ); - - prev_pow_fx = 0; - move32(); - curr_pow_fx = 0; - move32(); - FOR( i = 0; i < L_SHB_LAHEAD + 10; i++ ) - { - L_tmp = L_shl( shb_synth_nonref_fx[i], shift_prev_pow ); - prev_pow_fx = L_add( prev_pow_fx, Mpy_32_32( L_tmp, L_tmp ) ); - } - FOR( i = 0; i < L_SHB_LAHEAD + 10; i++ ) - { - L_tmp = L_shl( shb_synth_nonref_fx[L_SHB_LAHEAD + 10 + i], shift_prev_pow ); - curr_pow_fx = L_add( curr_pow_fx, Mpy_32_32( L_tmp, L_tmp ) ); - } - - IF( EQ_32( prev_pow_fx, 0 ) ) - { - e_scale_fx = 0; - move16(); - scale_fx = 0; - move16(); - } - ELSE - { - e_scale_fx = 0; - move16(); - scale_fx = BASOP_Util_Divide3232_Scale( curr_pow_fx, prev_pow_fx, &e_scale_fx ); - scale_fx = Sqrt16( scale_fx, &e_scale_fx ); - } - IF( LT_16( e_scale_fx, 0 ) ) - { - scale_fx = shl( scale_fx, e_scale_fx ); - e_scale_fx = 0; - move16(); - } - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - shb_synth_nonref_fx[i] = Mpy_32_16_1( shb_synth_nonref_fx[i], scale_fx ); - move32(); - } - tmp = 3276; - move16(); - FOR( ; i < L_SHB_LAHEAD + 10; i++ ) - { - IF( EQ_16( e_scale_fx, 0 ) ) - { - temp1_fx = 32767; - move16(); - } - ELSE - { - temp1_fx = shl( 1, sub( 15, e_scale_fx ) ); - move16(); - } - L_tmp = L_mult0( tmp, temp1_fx ); - L_tmp = L_mac0( L_tmp, sub( 32767, tmp ), scale_fx ); - shb_synth_nonref_fx[i] = Mpy_32_16_1( shb_synth_nonref_fx[i], shl( round_fx( L_tmp ), 1 ) ); - move32(); - IF( LT_16( tmp, 29492 ) ) - { - tmp = add( tmp, 3276 ); - } - } - - /* spec and gs adjustment */ - Q_syn_shb = sub( Q_syn_shb, e_scale_fx ); - Scale_sig32( shb_synth_nonref_fx + L_SHB_LAHEAD + 10, L_FRAME16k - 10, -e_scale_fx ); - - tmp = 31; - move16(); - tmp = FindScale( shb_synth_nonref_fx, L_FRAME16k + L_SHB_LAHEAD, Q_syn_shb, tmp ); - temp1_fx = norm_l( hStereoICBWE->memShbSpecMapping_fx ); - IF( EQ_32( hStereoICBWE->memShbSpecMapping_fx, 0 ) ) - { - temp1_fx = 31; - move16(); - } - temp1_fx = add( temp1_fx, hStereoICBWE->prev_Q_memshbspec ); - tmp = s_min( temp1_fx, tmp ); - - tmp = sub( tmp, 9 ); - - Scale_sig32( shb_synth_nonref_fx, L_FRAME16k + L_SHB_LAHEAD, tmp - Q_syn_shb ); - hStereoICBWE->memShbSpecMapping_fx = L_shl( hStereoICBWE->memShbSpecMapping_fx, tmp - hStereoICBWE->prev_Q_memshbspec ); - - hStereoICBWE->prev_Q_memshbspec = tmp; - move16(); - Q_syn_shb = tmp; - move16(); - - deemph_fx_32( 0, shb_synth_nonref_fx + L_SHB_LAHEAD, specMapping_fx, L_FRAME16k, &( hStereoICBWE->memShbSpecMapping_fx ) ); - hStereoICBWE->prev_Q_memshbspec = Q_syn_shb; - move16(); - Copy32( shb_synth_nonref_fx + L_FRAME16k, hStereoICBWE->mem_syn_shb_nonref_fx, L_SHB_LAHEAD ); - hStereoICBWE->prev_Q_syn_shb_nonref = Q_syn_shb; - move16(); - - tmp = 31; - move16(); - tmp = FindScale( shb_synth_nonref_fx, L_FRAME16k + L_SHB_LAHEAD, Q_syn_shb, tmp ); - tmp = FindScale( hStereoICBWE->mem_syn_shb_ola_nonref_fx, L_SHB_LAHEAD, hStereoICBWE->prev_Q_syn_shb_ola_nonref, tmp ); - - tmp = sub( tmp, 3 ); - - Scale_sig32( shb_synth_nonref_fx, L_FRAME16k + L_SHB_LAHEAD, tmp - Q_syn_shb ); - Scale_sig32( hStereoICBWE->mem_syn_shb_ola_nonref_fx, L_SHB_LAHEAD, tmp - hStereoICBWE->prev_Q_syn_shb_ola_nonref ); - - ScaleShapedSHB_32( SHB_OVERLAP_LEN, shb_synth_nonref_fx, hStereoICBWE->mem_syn_shb_ola_nonref_fx, hStereoICBWE->gshapeRef_fx, ( Mpy_32_16_1( L_shl( hStereoICBWE->gFrameRef_fx, 1 ), mult_r( gsMapping_fx, 29492 ) ) ), window_shb_fx, subwin_shb_fx, &tmp, &temp1_fx ); - - hStereoICBWE->prev_Q_syn_shb_ola_nonref = tmp; - move16(); - Q_syn_shb = tmp; - move16(); - - IF( EQ_16( st->extl, FB_TBE ) ) - { - v_multc_fixed_16_16( fb_synth_ref_fx, gsMapping_fx, fb_synth_nonref_fx, L_FRAME48k ); - } - - /* generate 32kHz SHB synthesis from 12.8(16)kHz signal */ - - tmp = 31; - move16(); - tmp = FindScale( shb_synth_nonref_fx, L_FRAME16k + L_SHB_LAHEAD, Q_syn_shb, tmp ); - tmp = FindScale( hStereoICBWE->memShbHilbert_nonref_fx, HILBERT_MEM_SIZE, hStereoICBWE->prev_Q_hilb, tmp ); - tmp = FindScale( hStereoICBWE->memShbInterp_nonref_fx, 2 * ALLPASSSECTIONS_STEEP + 1, hStereoICBWE->prev_Q_interp, tmp ); - - tmp = sub( tmp, 3 ); - - Scale_sig32( shb_synth_nonref_fx, L_FRAME16k + L_SHB_LAHEAD, sub( tmp, Q_syn_shb ) ); - Scale_sig32( hStereoICBWE->memShbHilbert_nonref_fx, HILBERT_MEM_SIZE, sub( tmp, hStereoICBWE->prev_Q_hilb ) ); - Scale_sig32( hStereoICBWE->memShbInterp_nonref_fx, 2 * ALLPASSSECTIONS_STEEP + 1, sub( tmp, hStereoICBWE->prev_Q_interp ) ); - - hStereoICBWE->prev_Q_hilb = tmp; - move16(); - hStereoICBWE->prev_Q_interp = tmp; - move16(); - - Q_syn_shb = tmp; - move16(); - - GenSHBSynth_fx_32( shb_synth_nonref_fx, error_fx, hStereoICBWE->memShbHilbert_nonref_fx, hStereoICBWE->memShbInterp_nonref_fx, st->L_frame, &( hStereoICBWE->syn_dm_phase_nonref ) ); - } - ELSE - { - Copy32( synthRef_fx, synth_fx, output_frame ); - - winLen_fx = extract_l( Mpy_32_16_1( st->output_Fs, 41 ) ); - winSlope_fx = div_s( 1, winLen_fx ); - alpha_fx = winSlope_fx; - move16(); - - - IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) - { - ratio_L_fx = 16384; - move16(); - } - ELSE - { - ratio_L_fx = extract_h( tdm_ratio_tabl_fx[hCPE->hStereoTD->tdm_last_ratio_idx] ); - move16(); - } - - icbweM2Ref_fx = gsMapping_fx; - move16(); - IF( EQ_16( hStereoICBWE->refChanIndx_bwe, L_CH_INDX ) ) - { - - IF( GE_16( ratio_L_fx, 3276 ) ) - { - tmp = mult_r( sub( 32767, ratio_L_fx ), sub( 32767, ratio_L_fx ) ); // Q15 - tmp = mult_r( tmp, gsMapping_fx ); // Q14 - tmp = mult_r( tmp, gsMapping_fx ); // Q13 - IF( LT_16( tmp, 4096 ) ) - { - temp1_fx = 0; - move16(); - temp2_fx = 0; - move16(); - tmp = shl( tmp, 2 ); - icbweM2Ref_fx = Sqrt16( sub( 16384, tmp ), &temp1_fx ); - icbweM2Ref_fx = BASOP_Util_Divide1616_Scale( icbweM2Ref_fx, ratio_L_fx, &temp2_fx ); - icbweM2Ref_fx = shl( icbweM2Ref_fx, add( temp2_fx, sub( temp1_fx, 1 ) ) ); // Q14 - } - ELSE - { - icbweM2Ref_fx = 0; - move16(); - } - } - } - ELSE - { - IF( LE_16( ratio_L_fx, 29490 ) ) - { -#ifdef FIX_TMP_714 - tmp = mult_r( ratio_L_fx, ratio_L_fx ); // Q15 -#else - tmp = mult_r( sub( 32767, ratio_L_fx ), sub( 32767, ratio_L_fx ) ); // Q15 -#endif - tmp = mult_r( tmp, gsMapping_fx ); // Q14 - tmp = mult_r( tmp, gsMapping_fx ); // Q13 - IF( LT_16( tmp, 4096 ) ) - { - temp1_fx = 0; - move16(); - temp2_fx = 0; - move16(); - tmp = shl( tmp, 2 ); - icbweM2Ref_fx = Sqrt16( sub( 16384, tmp ), &temp1_fx ); - icbweM2Ref_fx = BASOP_Util_Divide1616_Scale( icbweM2Ref_fx, sub( 32767, ratio_L_fx ), &temp2_fx ); - icbweM2Ref_fx = shl( icbweM2Ref_fx, add( temp2_fx, sub( temp1_fx, 1 ) ) ); // Q14 - } - ELSE - { - icbweM2Ref_fx = 0; - move16(); - } - } - } - - icbweM2Ref_fx = s_max( gsMapping_fx, icbweM2Ref_fx ); - - FOR( i = 0; i < winLen_fx; i++ ) - { - L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); - L_tmp = L_mac0( L_tmp, sub( 32767, alpha_fx ), hStereoICBWE->icbweM2Ref_prev_fx ); - tmp = shl( round_fx( L_tmp ), 1 ); - synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], tmp ); - move32(); - L_tmp = L_mult0( alpha_fx, gsMapping_fx ); - L_tmp = L_mac0( L_tmp, sub( 32767, alpha_fx ), prevgsMapping_fx ); - tmp = shl( round_fx( L_tmp ), 1 ); - synth_fx[i] = Mpy_32_16_1( synth_fx[i], tmp ); - move32(); - IF( LE_16( alpha_fx, sub( 32767, winSlope_fx ) ) ) - { - alpha_fx = add( alpha_fx, winSlope_fx ); - } - } - FOR( ; i < NS2SA( st->output_Fs, FRAME_SIZE_NS ); i++ ) - { - synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], icbweM2Ref_fx ); - move32(); - synth_fx[i] = Mpy_32_16_1( synth_fx[i], gsMapping_fx ); - move32(); - } - hStereoICBWE->icbweM2Ref_prev_fx = icbweM2Ref_fx; - move16(); - - ic_bwe_dec_reset_fx( hStereoICBWE ); - hStereoICBWE->prevSpecMapping_fx = 0; - move16(); - - *Q_syn = sub( *Q_syn, 1 ); - - return; - } - - /* resample to output FS */ - - - IF( EQ_32( st->output_Fs, 48000 ) ) - { - tmp = 31; - move16(); - tmp = FindScale( error_fx, L_FRAME32k, Q_syn_shb, tmp ); - tmp = FindScale( hStereoICBWE->memShb_fsout_nonref_fx, INTERP_3_2_MEM_LEN, hStereoICBWE->prev_Q_fsout, tmp ); - tmp = sub( tmp, 4 ); - - Scale_sig32( error_fx, L_FRAME32k, sub( tmp, Q_syn_shb ) ); - Scale_sig32( hStereoICBWE->memShb_fsout_nonref_fx, INTERP_3_2_MEM_LEN, sub( tmp, hStereoICBWE->prev_Q_fsout ) ); - interpolate_3_over_2_allpass_32( error_fx, L_FRAME32k, synth_fx, hStereoICBWE->memShb_fsout_nonref_fx ); - hStereoICBWE->prev_Q_fsout = tmp; - move16(); - } - ELSE IF( EQ_32( st->output_Fs, 32000 ) ) - { - Copy32( error_fx, synth_fx, L_FRAME32k ); - } - ELSE IF( EQ_32( st->output_Fs, 16000 ) ) - { - tmp = 31; - move16(); - tmp = FindScale( error_fx, L_FRAME32k, Q_syn_shb, tmp ); - tmp = FindScale( hStereoICBWE->memShb_fsout_nonref_fx, INTERP_3_2_MEM_LEN, hStereoICBWE->prev_Q_fsout, tmp ); - tmp = sub( tmp, 4 ); - - Scale_sig32( error_fx, L_FRAME32k, sub( tmp, Q_syn_shb ) ); - Scale_sig32( hStereoICBWE->memShb_fsout_nonref_fx, INTERP_3_2_MEM_LEN, sub( tmp, hStereoICBWE->prev_Q_fsout ) ); - Decimate_allpass_steep_fx32( error_fx, hStereoICBWE->memShb_fsout_nonref_fx, L_FRAME32k, synth_fx ); - hStereoICBWE->prev_Q_fsout = tmp; - move16(); - } -#ifndef MSAN_FIX - Scale_sig32( synth_fx, L_FRAME48k, sub( *Q_syn, add( 1, tmp ) ) ); -#else - Scale_sig32( synth_fx, output_frame, sub( *Q_syn, add( 1, tmp ) ) ); -#endif - - *Q_syn = sub( *Q_syn, 1 ); - - test(); - IF( EQ_16( st->extl, FB_TBE ) && EQ_32( st->output_Fs, 48000 ) ) - { - - // v_add( fb_synth_nonref_fx, synth_fx, synth_fx, L_FRAME48k, 0 ); - FOR( i = 0; i < L_FRAME48k; i++ ) - { - synth_fx[i] = L_add( synth_fx[i], L_deposit_l( fb_synth_nonref_fx[i] ) ); - move32(); - } - } - - /* copy to outputHB and reset hb_synth values */ - - IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) - { - ratio_L_fx = 16384; - move16(); - } - ELSE - { - ratio_L_fx = extract_h( tdm_ratio_tabl_fx[hCPE->hStereoTD->tdm_last_ratio_idx] ); - move16(); - } - - icbweM2Ref_fx = gsMapping_fx; - move16(); - IF( EQ_16( hStereoICBWE->refChanIndx_bwe, L_CH_INDX ) ) - { - IF( GE_16( ratio_L_fx, 3276 ) ) - { - tmp = mult_r( sub( 32767, ratio_L_fx ), sub( 32767, ratio_L_fx ) ); // Q15 - tmp = mult_r( tmp, gsMapping_fx ); // Q14 - tmp = mult_r( tmp, gsMapping_fx ); // Q13 - IF( LT_16( tmp, 4096 ) ) - { - temp1_fx = 0; - move16(); - temp2_fx = 0; - move16(); - tmp = shl( tmp, 2 ); - icbweM2Ref_fx = Sqrt16( sub( 16384, tmp ), &temp1_fx ); - icbweM2Ref_fx = BASOP_Util_Divide1616_Scale( icbweM2Ref_fx, ratio_L_fx, &temp2_fx ); - icbweM2Ref_fx = shl( icbweM2Ref_fx, add( temp1_fx, sub( temp2_fx, 1 ) ) ); // Q14 - } - ELSE - { - icbweM2Ref_fx = 0; - move16(); - } - } - } - ELSE - { - IF( LE_16( ratio_L_fx, 29490 ) ) - { -#ifdef FIX_TMP_714 - tmp = mult_r( ratio_L_fx, ratio_L_fx ); // Q15 -#else - tmp = mult_r( sub( 32767, ratio_L_fx ), sub( 32767, ratio_L_fx ) ); // Q15 -#endif - tmp = mult_r( tmp, gsMapping_fx ); // Q14 - tmp = mult_r( tmp, gsMapping_fx ); // Q13 - IF( LT_16( tmp, 4096 ) ) - { - temp1_fx = 0; - move16(); - temp2_fx = 0; - move16(); - tmp = shl( tmp, 2 ); - icbweM2Ref_fx = Sqrt16( sub( 16384, tmp ), &temp1_fx ); - icbweM2Ref_fx = BASOP_Util_Divide1616_Scale( icbweM2Ref_fx, sub( 32767, ratio_L_fx ), &temp2_fx ); - icbweM2Ref_fx = shl( icbweM2Ref_fx, add( temp2_fx, sub( temp1_fx, 1 ) ) ); // Q14 - } - ELSE - { - icbweM2Ref_fx = 0; - move16(); - } - } - } - - icbweM2Ref_fx = s_max( gsMapping_fx, icbweM2Ref_fx ); - - winLen_fx = extract_l( Mpy_32_16_1( st->output_Fs, 41 ) ); - winSlope_fx = div_s( 1, winLen_fx ); - alpha_fx = winSlope_fx; - move16(); - FOR( i = 0; i < winLen_fx; i++ ) - { - L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); - L_tmp = L_mac0( L_tmp, sub( 32767, alpha_fx ), hStereoICBWE->icbweM2Ref_prev_fx ); - tmp = shl( round_fx( L_tmp ), 1 ); - synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], tmp ); - move32(); - IF( LE_16( alpha_fx, sub( 32767, winSlope_fx ) ) ) - { - alpha_fx = add( alpha_fx, winSlope_fx ); - } - } - - FOR( ; i < NS2SA( st->output_Fs, FRAME_SIZE_NS ); i++ ) - { - synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], icbweM2Ref_fx ); - move32(); - } - - hStereoICBWE->icbweM2Ref_prev_fx = icbweM2Ref_fx; - move16(); - - return; -} -#endif - -/*-------------------------------------------------------------------* - * stereo_icBWE_decproc() - * - * Stereo (inter-channel) BWE mapping - decoder initialization - *-------------------------------------------------------------------*/ - -#ifndef IVAS_FLOAT_FIXED -void stereo_icBWE_decproc( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - float *output[CPE_CHANNELS], /* i/o: output synthesis */ - float outputHB[CPE_CHANNELS][L_FRAME48k], /* i : HB synthesis */ - const int16_t last_core, /* i : last core, primary channel */ - const int16_t last_bwidth, /* i : last bandwidth */ - const int16_t output_frame /* i : frame length */ -) -{ - int16_t i, j, n, decoderDelay, icbweOLASize, dftOvlLen; - int16_t core, memOffset, refChanIndx_bwe; - float temp0[L_FRAME48k + NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS )], temp1[L_FRAME48k + NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS )]; - float winSlope, alpha; - const float *win_dft; - int32_t extl_brate, output_Fs; - - STEREO_ICBWE_DEC_HANDLE hStereoICBWE = hCPE->hStereoICBWE; - - - /*--------------------------------------------------------------------* - * skip IC-BWE in case of SID or NO_DATA frame - * -------------------------------------------------------------------*/ - - if ( ( hCPE->element_mode == IVAS_CPE_TD || hCPE->element_mode == IVAS_CPE_DFT ) && hCPE->nchan_out == 2 /*&& hCPE->hCoreCoder[0]->core_brate > SID_2k40*/ && hCPE->hCoreCoder[0]->last_core_brate <= SID_2k40 ) - { - stereo_icBWE_init_dec( hCPE->hStereoICBWE ); - } - - if ( hCPE->hCoreCoder[0]->core_brate <= SID_2k40 ) - { - return; - } - - /*--------------------------------------------------------------------* - * skip IC-BWE in case of mono DMX output * - * -------------------------------------------------------------------*/ - - if ( hCPE->nchan_out == 1 && hCPE->element_mode == IVAS_CPE_DFT ) - { - add_HB_to_mono_dmx( hCPE, output[0], outputHB[0], last_core, output_frame ); - - return; - } - else if ( hCPE->nchan_out == 1 && hCPE->element_mode != IVAS_CPE_TD ) - { - return; - } - - /*--------------------------------------------------------------------* - * IC-BWE processing - * -------------------------------------------------------------------*/ - - core = hCPE->hCoreCoder[0]->core; - extl_brate = hCPE->hCoreCoder[0]->extl_brate; - output_Fs = hCPE->hCoreCoder[0]->output_Fs; - - memOffset = NS2SA( output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ); - - /* LRTD stereo mode - 2xBWEs used */ - if ( hCPE->element_mode == IVAS_CPE_TD && hCPE->hCoreCoder[0]->tdm_LRTD_flag ) - { - /* delay HB synth */ - for ( n = 0; n < CPE_CHANNELS; n++ ) - { - mvr2r( outputHB[n] + output_frame - memOffset, temp0, memOffset ); - mvr2r( outputHB[n], outputHB[n] + memOffset, output_frame - memOffset ); - mvr2r( hCPE->prev_hb_synth[n], outputHB[n], memOffset ); - mvr2r( temp0, hCPE->prev_hb_synth[n], memOffset ); - } - - if ( hCPE->nchan_out == 1 ) - { - /* stereo to mono downmix */ - for ( i = 0; i < output_frame; i++ ) - { - outputHB[0][i] = ( outputHB[0][i] + outputHB[1][i] ) * 0.5f; - } - v_add( output[0], outputHB[0], output[0], output_frame ); - } - else - { - /* Add the delayed hb_synth component to the delayed ACELP synthesis */ - for ( n = 0; n < CPE_CHANNELS; n++ ) - { - v_add( output[n], outputHB[n], output[n], output_frame ); - } - } - } - else - { - for ( n = 0; n < CPE_CHANNELS; n++ ) - { - set_f( hCPE->prev_hb_synth[n], 0, memOffset ); - } - } - - if ( hCPE->element_mode != IVAS_CPE_MDCT && !( hCPE->element_mode == IVAS_CPE_TD && hCPE->hCoreCoder[0]->tdm_LRTD_flag ) ) - { - if ( hCPE->last_element_mode == IVAS_CPE_MDCT ) - { - set_f( hStereoICBWE->memOutHB[0], 0, memOffset ); - set_f( hStereoICBWE->memOutHB[1], 0, memOffset ); - - set_f( hStereoICBWE->memTransitionHB[0], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); - set_f( hStereoICBWE->memTransitionHB[1], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); - } - - if ( core == ACELP_CORE && extl_brate > 0 ) - { - refChanIndx_bwe = hStereoICBWE->refChanIndx_bwe; - - if ( hCPE->element_mode == IVAS_CPE_DFT && hCPE->hCoreCoder[0]->bwidth > WB && last_bwidth == WB && hCPE->hCoreCoder[0]->ini_frame > 1 /* counter wass already updated */ ) - { - /* fad-in reference HB signal */ - winSlope = ( memOffset > 0 ) ? ( 1.0f / memOffset ) : 0; - for ( i = 0; i < memOffset; i++ ) - { - outputHB[refChanIndx_bwe][i] *= ( i + 1 ) * winSlope; - } - } - /* Resampled LB and HB offset */ - mvr2r( outputHB[refChanIndx_bwe], temp0 + memOffset, output_frame - memOffset ); - mvr2r( outputHB[!refChanIndx_bwe], temp1 + memOffset, output_frame - memOffset ); - - decoderDelay = NS2SA( output_Fs, IVAS_DEC_DELAY_NS ); - - if ( last_core != ACELP_CORE && hCPE->element_mode == IVAS_CPE_DFT ) - { - /* hb_synth of mid band is faded out in the 1.25 ms prior to DFT analysis and the icbwe is faded in time domain */ - icbweOLASize = NS2SA( output_Fs, STEREO_DFT_DELAY_DEC_BWE_NS ); - - for ( i = 0; i < decoderDelay; i++ ) - { - temp0[i] = 0; - temp1[i] = 0; - } - - assert( icbweOLASize > 0 ); - winSlope = 1.0f / icbweOLASize; - alpha = winSlope; - for ( ; i < decoderDelay + icbweOLASize; i++ ) - { - temp0[i] *= alpha; - temp1[i] *= alpha; - alpha += winSlope; - } - } - else - { - if ( refChanIndx_bwe != hStereoICBWE->prev_refChanIndx_bwe ) - { - winSlope = ( memOffset > 0 ) ? ( 1.0f / memOffset ) : 0; - for ( i = 0; i < memOffset; i++ ) - { - temp0[i] = ( ( i + 1 ) * winSlope ) * hStereoICBWE->memOutHB[refChanIndx_bwe][i] + - ( 1 - ( i + 1 ) * winSlope ) * hStereoICBWE->memOutHB[hStereoICBWE->prev_refChanIndx_bwe][i]; - temp1[i] = ( ( i + 1 ) * winSlope ) * hStereoICBWE->memOutHB[hStereoICBWE->prev_refChanIndx_bwe][i] + - ( 1 - ( i + 1 ) * winSlope ) * hStereoICBWE->memOutHB[refChanIndx_bwe][i]; - } - } - else - { - mvr2r( hStereoICBWE->memOutHB[refChanIndx_bwe], temp0, memOffset ); - mvr2r( hStereoICBWE->memOutHB[!refChanIndx_bwe], temp1, memOffset ); - } - } - - if ( hCPE->nchan_out == 1 ) - { - /* stereo to mono downmix */ - for ( i = 0; i < output_frame; i++ ) - { - temp0[i] = ( temp0[i] + temp1[i] ) * 0.5f; - output[0][i] += temp0[i]; - } - } - else - { - - v_add( temp0, output[0], output[0], output_frame ); - v_add( temp1, output[1], output[1], output_frame ); - } - mvr2r( outputHB[0] + output_frame - memOffset, hStereoICBWE->memOutHB[0], memOffset ); - mvr2r( outputHB[1] + output_frame - memOffset, hStereoICBWE->memOutHB[1], memOffset ); - - if ( hCPE->element_mode == IVAS_CPE_DFT ) - { - win_dft = hCPE->hStereoDft->win32ms; - dftOvlLen = hCPE->hStereoDft->dft32ms_ovl; - - /* Preparing buffers in anticipation of an ACELP to TCX switch */ - j = 0; - for ( i = 0; i < memOffset; i++ ) - { - hStereoICBWE->memTransitionHB[0][i] = hStereoICBWE->memOutHB[0][i] * win_dft[STEREO_DFT32MS_STEP * ( dftOvlLen - 1 - j )]; - hStereoICBWE->memTransitionHB[1][i] = hStereoICBWE->memOutHB[1][i] * win_dft[STEREO_DFT32MS_STEP * ( dftOvlLen - 1 - j )]; - j++; - } - - for ( i = 0; j < dftOvlLen; i++ ) - { - hStereoICBWE->memTransitionHB[0][memOffset + i] = outputHB[0][output_frame - i - 1] * win_dft[STEREO_DFT32MS_STEP * ( dftOvlLen - 1 - j )]; - hStereoICBWE->memTransitionHB[1][memOffset + i] = outputHB[1][output_frame - i - 1] * win_dft[STEREO_DFT32MS_STEP * ( dftOvlLen - 1 - j )]; - j++; - } - } - - hStereoICBWE->prev_refChanIndx_bwe = refChanIndx_bwe; - } - else - { - if ( last_core == ACELP_CORE ) - { - if ( hCPE->element_mode == IVAS_CPE_TD ) - { - v_add( output[0], hStereoICBWE->memOutHB[hStereoICBWE->prev_refChanIndx_bwe], output[0], memOffset ); - v_add( output[1], hStereoICBWE->memOutHB[!hStereoICBWE->prev_refChanIndx_bwe], output[1], memOffset ); - } - else - { - /* This is generated in the ACELP frame and windowed. This process is akin to GenTransition for IC-BWE */ - v_add( output[0], hStereoICBWE->memTransitionHB[hStereoICBWE->prev_refChanIndx_bwe], output[0], NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); - v_add( output[1], hStereoICBWE->memTransitionHB[!hStereoICBWE->prev_refChanIndx_bwe], output[1], NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); - } - - set_f( hStereoICBWE->memOutHB[0], 0, memOffset ); - set_f( hStereoICBWE->memOutHB[1], 0, memOffset ); - - set_f( hStereoICBWE->memTransitionHB[0], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); - set_f( hStereoICBWE->memTransitionHB[1], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); - } - } - } - else if ( hCPE->element_mode == IVAS_CPE_TD && hCPE->hCoreCoder[0]->tdm_LRTD_flag && hStereoICBWE != NULL ) - { - stereo_icBWE_init_dec( hCPE->hStereoICBWE ); - } - else if ( hCPE->element_mode == IVAS_CPE_MDCT && hCPE->last_element_mode == IVAS_CPE_DFT && last_core == ACELP_CORE ) - { - int16_t delay_tdbwe = NS2SA( output_Fs, DELAY_BWE_TOTAL_NS ); - - for ( n = 0; n < hCPE->nchan_out; n++ ) - { - for ( i = 0; i < delay_tdbwe; i++ ) - { - output[n][NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe + i] += outputHB[0][i]; - } - } - /* reset BWE structs as they are only needed in the transition frame in MDCT Stereo */ - td_bwe_dec_init( hCPE->hCoreCoder[0]->hBWE_TD, -1, output_Fs ); - - fd_bwe_dec_init_flt( hCPE->hCoreCoder[0]->hBWE_FD ); - } - - if ( hCPE->element_mode == IVAS_CPE_DFT && ( max( hCPE->hStereoDft->td_gain[0], hCPE->hStereoDft->td_gain[1] ) > 0 ) ) - { - float win_in, win_out, tmp; - - win_dft = hCPE->hStereoDft->win32ms; - dftOvlLen = hCPE->hStereoDft->dft32ms_ovl; - - for ( i = 0; i < dftOvlLen; i++ ) - { - win_in = win_dft[STEREO_DFT32MS_STEP * i] * win_dft[STEREO_DFT32MS_STEP * i]; - win_out = 1 - win_in; - tmp = ( win_in * hCPE->hStereoDft->td_gain[0] + win_out * hCPE->hStereoDft->td_gain[1] ) * hCPE->hStereoDft->hb_stefi_sig[i]; - - output[0][i] += tmp; - output[1][i] -= tmp; - } - for ( i = dftOvlLen; i < output_frame; i++ ) - { - tmp = hCPE->hStereoDft->td_gain[0] * hCPE->hStereoDft->hb_stefi_sig[i]; - output[0][i] += tmp; - output[1][i] -= tmp; - } - } - - return; -} -#else -void stereo_icBWE_decproc_fx( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - Word32 *output[CPE_CHANNELS], /* i/o: output synthesis */ - Word32 outputHB[CPE_CHANNELS][L_FRAME48k], /* i : HB synthesis */ - const Word16 last_core, /* i : last core, primary channel */ - const Word16 last_bwidth, /* i : last bandwidth */ - const Word16 output_frame, /* i : frame length */ - Word16 q_output /* i : Q-fac of output */ -) -{ - Word16 i, j, n, decoderDelay, icbweOLASize, dftOvlLen; - Word16 core, memOffset, refChanIndx_bwe; - - Word32 temp0_fx[L_FRAME48k + NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS )], temp1_fx[L_FRAME48k + NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS )]; - Word32 winSlope_fx = 0, alpha_fx; - const Word16 *win_dft_fx; - Word32 extl_brate, output_Fs; - - STEREO_ICBWE_DEC_HANDLE hStereoICBWE = hCPE->hStereoICBWE; - - /*--------------------------------------------------------------------* - * skip IC-BWE in case of SID or NO_DATA frame - * -------------------------------------------------------------------*/ - - test(); - test(); - test(); - IF( ( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) || EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) && EQ_16( hCPE->nchan_out, 2 ) /*&& hCPE->hCoreCoder[0]->core_brate > SID_2k40*/ && LE_32( hCPE->hCoreCoder[0]->last_core_brate, SID_2k40 ) ) - { - stereo_icBWE_init_dec_fx( hCPE->hStereoICBWE ); - } - - IF( LE_32( hCPE->hCoreCoder[0]->core_brate, SID_2k40 ) ) - { - return; - } - - /*--------------------------------------------------------------------* - * skip IC-BWE in case of mono DMX output * - * -------------------------------------------------------------------*/ - - test(); - test(); - IF( EQ_16( hCPE->nchan_out, 1 ) && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) - { - add_HB_to_mono_dmx_fx( hCPE, output[0], outputHB[0], last_core, output_frame ); - return; - } - ELSE IF( EQ_16( hCPE->nchan_out, 1 ) && NE_16( hCPE->element_mode, IVAS_CPE_TD ) ) - { - return; - } - - /*--------------------------------------------------------------------* - * IC-BWE processing - * -------------------------------------------------------------------*/ - - core = hCPE->hCoreCoder[0]->core; - move16(); - extl_brate = hCPE->hCoreCoder[0]->extl_brate; - move32(); - output_Fs = hCPE->hCoreCoder[0]->output_Fs; - move32(); - - memOffset = NS2SA( output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ); - - /* LRTD stereo mode - 2xBWEs used */ - test(); - IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) && hCPE->hCoreCoder[0]->tdm_LRTD_flag ) - { - /* delay HB synth */ - FOR( n = 0; n < CPE_CHANNELS; n++ ) - { - Copy32( outputHB[n] + output_frame - memOffset, temp0_fx, memOffset ); - Copy32( outputHB[n], outputHB[n] + memOffset, output_frame - memOffset ); - Copy32( hCPE->prev_hb_synth_fx[n], outputHB[n], memOffset ); - Copy32( temp0_fx, hCPE->prev_hb_synth_fx[n], memOffset ); - } - - IF( EQ_16( hCPE->nchan_out, 1 ) ) - { - /* stereo to mono downmix */ - FOR( i = 0; i < output_frame; i++ ) - { - outputHB[0][i] = L_shr( ( outputHB[0][i] + outputHB[1][i] ), 1 ); - move32(); - } - v_add_32( output[0], outputHB[0], output[0], output_frame ); - } - ELSE - { - /* Add the delayed hb_synth component to the delayed ACELP synthesis */ - FOR( n = 0; n < CPE_CHANNELS; n++ ) - { - v_add_32( output[n], outputHB[n], output[n], output_frame ); - } - } - } - ELSE - { - FOR( n = 0; n < CPE_CHANNELS; n++ ) - { - set32_fx( hCPE->prev_hb_synth_fx[n], 0, memOffset ); - } - } - - test(); - test(); - test(); - test(); - test(); - test(); - IF( NE_16( hCPE->element_mode, IVAS_CPE_MDCT ) && !( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) && hCPE->hCoreCoder[0]->tdm_LRTD_flag ) ) - { - IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_MDCT ) ) - { - set32_fx( hStereoICBWE->memOutHB_fx[0], 0, memOffset ); - set32_fx( hStereoICBWE->memOutHB_fx[1], 0, memOffset ); - - set32_fx( hStereoICBWE->memTransitionHB_fx[0], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); - set32_fx( hStereoICBWE->memTransitionHB_fx[1], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); - } - - test(); - IF( EQ_16( core, ACELP_CORE ) && GT_32( extl_brate, 0 ) ) - { - refChanIndx_bwe = hStereoICBWE->refChanIndx_bwe; - move16(); - - test(); - test(); - test(); - IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && GT_16( hCPE->hCoreCoder[0]->bwidth, WB ) && EQ_16( last_bwidth, WB ) && GT_16( hCPE->hCoreCoder[0]->ini_frame, 1 ) /* counter wass already updated */ ) - { - /* fad-in reference HB signal */ - IF( GT_16( memOffset, 0 ) ) - { - SWITCH( memOffset ) - { - case 15: - winSlope_fx = 71582792; - move32(); - BREAK; - case 30: - winSlope_fx = 35791396; - move32(); - BREAK; - case 45: - winSlope_fx = 23860930; - move32(); - BREAK; - } - // memOffset for 16K 32K 48K are 15 30 45 respectively.camera - } - ELSE - { - winSlope_fx = 0; - move32(); - } - FOR( i = 0; i < memOffset; i++ ) - { - Word32 mul_win = Mpy_32_16_1( winSlope_fx, ( i + 1 ) ); // Q30 + Q0 - 15 = Q15 - mul_win = L_shl( mul_win, 15 ); // Q30 - outputHB[refChanIndx_bwe][i] = L_shl( Mpy_32_32( outputHB[refChanIndx_bwe][i] /* Q11 + Q30 - 31 = Q10)*/, mul_win ), 1 ); // - move32(); - } - } - /* Resampled LB and HB offset */ - Copy32( outputHB[refChanIndx_bwe], temp0_fx + memOffset, output_frame - memOffset ); - Copy32( outputHB[!refChanIndx_bwe], temp1_fx + memOffset, output_frame - memOffset ); - - decoderDelay = NS2SA( output_Fs, IVAS_DEC_DELAY_NS ); - - test(); - IF( NE_16( last_core, ACELP_CORE ) && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) - { - /* hb_synth of mid band is faded out in the 1.25 ms prior to DFT analysis and the icbwe is faded in time domain */ - icbweOLASize = NS2SA( output_Fs, STEREO_DFT_DELAY_DEC_BWE_NS ); - - FOR( i = 0; i < decoderDelay; i++ ) - { - temp0_fx[i] = 0; - move32(); - temp1_fx[i] = 0; - move32(); - } - - assert( icbweOLASize > 0 ); - SWITCH( icbweOLASize ) - { - case 60: - winSlope_fx = 17895698; - move32(); - BREAK; - case 40: - winSlope_fx = 26843546; - move32(); - BREAK; - case 20: - winSlope_fx = 53687092; - move32(); - BREAK; - } - alpha_fx = winSlope_fx; // Q30 - move32(); - FOR( ; i < decoderDelay + icbweOLASize; i++ ) - { - temp0_fx[i] = L_shl_sat( Mpy_32_32( temp0_fx[i], alpha_fx ), 1 ); // Q11 - move32(); - temp1_fx[i] = L_shl_sat( Mpy_32_32( temp1_fx[i], alpha_fx ), 1 ); - move32(); - alpha_fx = L_add( alpha_fx, winSlope_fx ); - } - } - ELSE - { - IF( NE_16( refChanIndx_bwe, hStereoICBWE->prev_refChanIndx_bwe ) ) - { - IF( GT_16( memOffset, 0 ) ) - { - SWITCH( memOffset ) - { - case 15: - winSlope_fx = 71582792; - BREAK; - case 30: - winSlope_fx = 35791396; - BREAK; - case 45: - winSlope_fx = 23860930; // Q30 - BREAK; - } - // memOffset for 16K 32K 48K are 15 30 45 respectively.camera - } - ELSE - { - winSlope_fx = 0; - move32(); - } - FOR( i = 0; i < memOffset; i++ ) - { - temp0_fx[i] = L_add( L_shl( Mpy_32_32( Mpy_32_16_1( winSlope_fx, ( i + 1 ) ), hStereoICBWE->memOutHB_fx[refChanIndx_bwe][i] ), 16 ), - L_shl( Mpy_32_32( Mpy_32_16_1( winSlope_fx, 1 - ( i + 1 ) ), hStereoICBWE->memOutHB_fx[hStereoICBWE->prev_refChanIndx_bwe][i] ), 16 ) ); - move32(); - - temp1_fx[i] = L_add( L_shl( Mpy_32_32( Mpy_32_16_1( winSlope_fx, ( i + 1 ) ), hStereoICBWE->memOutHB_fx[hStereoICBWE->prev_refChanIndx_bwe][i] ), 16 ), - L_shl( Mpy_32_32( Mpy_32_16_1( winSlope_fx, ( 1 - ( i + 1 ) ) ), hStereoICBWE->memOutHB_fx[refChanIndx_bwe][i] ), 16 ) ); - move32(); - } - } - ELSE - { - Copy32( hStereoICBWE->memOutHB_fx[refChanIndx_bwe], temp0_fx, memOffset ); - Copy32( hStereoICBWE->memOutHB_fx[!refChanIndx_bwe], temp1_fx, memOffset ); - } - } - - IF( EQ_16( hCPE->nchan_out, 1 ) ) - { - /* stereo to mono downmix */ - FOR( i = 0; i < output_frame; i++ ) - { - temp0_fx[i] = L_add( temp0_fx[i], temp1_fx[i] ); - move32(); - temp0_fx[i] = L_shr( temp0_fx[i], 1 ); - move32(); - output[0][i] = L_add( output[0][i], temp0_fx[i] ); - move32(); - } - } - ELSE - { - v_add_32( temp0_fx, output[0], output[0], output_frame ); - v_add_32( temp1_fx, output[1], output[1], output_frame ); - } - - Copy32( outputHB[0] + output_frame - memOffset, hStereoICBWE->memOutHB_fx[0], memOffset ); - Copy32( outputHB[1] + output_frame - memOffset, hStereoICBWE->memOutHB_fx[1], memOffset ); - - IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) - { - /*win_dft = hCPE->hStereoDft->win32ms;*/ - win_dft_fx = hCPE->hStereoDft->win32ms_fx; - dftOvlLen = hCPE->hStereoDft->dft32ms_ovl; - move16(); - - /* Preparing buffers in anticipation of an ACELP to TCX switch */ - j = 0; - move16(); - FOR( i = 0; i < memOffset; i++ ) - { - Word16 tmp_mul = mult0( STEREO_DFT32MS_STEP, ( sub( dftOvlLen, add( 1, j ) ) ) ); - hStereoICBWE->memTransitionHB_fx[0][i] = Mpy_32_16_1( hStereoICBWE->memOutHB_fx[0][i], win_dft_fx[tmp_mul] ); - move32(); - hStereoICBWE->memTransitionHB_fx[1][i] = Mpy_32_16_1( hStereoICBWE->memOutHB_fx[1][i], win_dft_fx[tmp_mul] ); - move32(); - j++; - } - - FOR( i = 0; j < dftOvlLen; i++ ) - { - Word16 tmp_mul = mult0( STEREO_DFT32MS_STEP, ( sub( dftOvlLen, add( 1, j ) ) ) ); - hStereoICBWE->memTransitionHB_fx[0][memOffset + i] = Mpy_32_16_1( outputHB[0][output_frame - i - 1], win_dft_fx[tmp_mul] ); - move32(); - hStereoICBWE->memTransitionHB_fx[1][memOffset + i] = Mpy_32_16_1( outputHB[1][output_frame - i - 1], win_dft_fx[tmp_mul] ); - move32(); - j++; - } - } - - hStereoICBWE->prev_refChanIndx_bwe = refChanIndx_bwe; - move16(); - } - ELSE - { - IF( EQ_16( last_core, ACELP_CORE ) ) - { - IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) ) - { - v_add_32( output[0], hStereoICBWE->memOutHB_fx[hStereoICBWE->prev_refChanIndx_bwe], output[0], memOffset ); - v_add_32( output[1], hStereoICBWE->memOutHB_fx[!hStereoICBWE->prev_refChanIndx_bwe], output[1], memOffset ); - } - ELSE - { - /* This is generated in the ACELP frame and windowed. This process is akin to GenTransition for IC-BWE */ - v_add_32( output[0], hStereoICBWE->memTransitionHB_fx[hStereoICBWE->prev_refChanIndx_bwe], output[0], NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); - v_add_32( output[1], hStereoICBWE->memTransitionHB_fx[!hStereoICBWE->prev_refChanIndx_bwe], output[1], NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); - } - - set32_fx( hStereoICBWE->memOutHB_fx[0], 0, memOffset ); - set32_fx( hStereoICBWE->memOutHB_fx[1], 0, memOffset ); - - set32_fx( hStereoICBWE->memTransitionHB_fx[0], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); - set32_fx( hStereoICBWE->memTransitionHB_fx[1], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); - } - } - } - ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) && hCPE->hCoreCoder[0]->tdm_LRTD_flag && hStereoICBWE != NULL ) - { - stereo_icBWE_init_dec_fx( hCPE->hStereoICBWE ); - } - ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) && EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) && EQ_16( last_core, ACELP_CORE ) ) - { - Word16 delay_tdbwe = NS2SA( output_Fs, DELAY_BWE_TOTAL_NS ); - - FOR( n = 0; n < hCPE->nchan_out; n++ ) - { - FOR( i = 0; i < delay_tdbwe; i++ ) - { - output[n][NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe + i] = L_add_sat( output[n][NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe + i], outputHB[0][i] ); - move32(); - } - } - /* reset BWE structs as they are only needed in the transition frame in MDCT Stereo */ - td_bwe_dec_init_ivas_fx( hCPE->hCoreCoder[0], hCPE->hCoreCoder[0]->hBWE_TD, output_Fs ); - fd_bwe_dec_init( hCPE->hCoreCoder[0], hCPE->hCoreCoder[0]->hBWE_FD ); - } - - test(); - IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && GT_32( L_max( hCPE->hStereoDft->td_gain_fx[0], hCPE->hStereoDft->td_gain_fx[1] ), 0 ) ) - { - Word32 win_in_fx, win_out_fx, tmp_fx, gain0_fx, gain1_fx; - - win_dft_fx = hCPE->hStereoDft->win32ms_fx; - dftOvlLen = hCPE->hStereoDft->dft32ms_ovl; - move16(); - - //Scale_sig32(hCPE->hStereoDft->td_gain_fx, STEREO_DFT_CORE_HIST_MAX, -12); - - FOR( i = 0; i < dftOvlLen; i++ ) - { - win_in_fx = L_mult( win_dft_fx[mult0( STEREO_DFT32MS_STEP, i )], win_dft_fx[mult0( STEREO_DFT32MS_STEP, i )] ); /* Q31 */ - win_out_fx = L_sub( ONE_IN_Q31, win_in_fx ); /* Q31 */ - - gain0_fx = Mpy_32_32( win_in_fx, hCPE->hStereoDft->td_gain_fx[0] ); /* Q --> q_td_gain[0] */ -#ifdef FIX_736_BWE_SECT_C - gain0_fx = (Word32) W_shr( ( (Word64) gain0_fx * hCPE->hStereoDft->hb_stefi_sig_fx[i] ), sub( add( (Word16) hCPE->hStereoDft->q_td_gain[0], hCPE->hStereoDft->q_hb_stefi_sig_fx ), 2 * q_output + 14 ) ); /* Q --> q_output */ - gain1_fx = Mpy_32_32( win_out_fx, hCPE->hStereoDft->td_gain_fx[1] ); /* Q --> q_td_gain[1] */ - gain1_fx = (Word32) W_shr( ( (Word64) gain1_fx * hCPE->hStereoDft->hb_stefi_sig_fx[i] ), sub( add( (Word16) hCPE->hStereoDft->q_td_gain[1], hCPE->hStereoDft->q_hb_stefi_sig_fx ), 2 * q_output + 14 ) ); /* Q --> q_output */ -#else - gain0_fx = (Word32) W_shr( ( (Word64) gain0_fx * hCPE->hStereoDft->hb_stefi_sig_fx[i] ), sub( add( (Word16) hCPE->hStereoDft->q_td_gain[0], hCPE->hStereoDft->q_hb_stefi_sig_fx ), q_output ) ); /* Q --> q_output */ - gain1_fx = Mpy_32_32( win_out_fx, hCPE->hStereoDft->td_gain_fx[1] ); /* Q --> q_td_gain[1] */ - gain1_fx = (Word32) W_shr( ( (Word64) gain1_fx * hCPE->hStereoDft->hb_stefi_sig_fx[i] ), sub( add( (Word16) hCPE->hStereoDft->q_td_gain[1], hCPE->hStereoDft->q_hb_stefi_sig_fx ), q_output ) ); /* Q --> q_output */ -#endif - tmp_fx = L_add_sat( gain0_fx, gain1_fx ); /* Q --> q_output */ - - output[0][i] = L_add_sat( output[0][i], tmp_fx ); - move32(); - output[1][i] = L_sub_sat( output[1][i], tmp_fx ); - move32(); - } - FOR( i = dftOvlLen; i < output_frame; i++ ) - { -#ifdef FIX_736_BWE_SECT_C - tmp_fx = (Word32) W_shr( ( (Word64) hCPE->hStereoDft->td_gain_fx[0] * hCPE->hStereoDft->hb_stefi_sig_fx[i] ), sub( add( (Word16) hCPE->hStereoDft->q_td_gain[0], hCPE->hStereoDft->q_hb_stefi_sig_fx ), 2 * q_output + 14 ) ); /* Q --> q_output */ -#else - tmp_fx = (Word32) W_shr( ( (Word64) hCPE->hStereoDft->td_gain_fx[0] * hCPE->hStereoDft->hb_stefi_sig_fx[i] ), sub( add( (Word16) hCPE->hStereoDft->q_td_gain[0], hCPE->hStereoDft->q_hb_stefi_sig_fx ), q_output ) ); /* Q --> q_output */ -#endif - output[0][i] = L_add_sat( output[0][i], tmp_fx ); - move32(); - output[1][i] = L_sub_sat( output[1][i], tmp_fx ); - move32(); - } - } - - return; -} -#endif - -/*-------------------------------------------------------------------* - * stereo_icBWE_init_dec() - * - * Stereo (inter-channel) BWE mapping - decoder initialization - *-------------------------------------------------------------------*/ - -#ifndef IVAS_FLOAT_FIXED -void stereo_icBWE_init_dec( - STEREO_ICBWE_DEC_HANDLE hStereoICBWE /* i/o: Stereo inter-channel BWE handle */ -) -{ - /* BWE ref channel */ - hStereoICBWE->refChanIndx_bwe = L_CH_INDX; - hStereoICBWE->prev_refChanIndx_bwe = L_CH_INDX; - - /* SHB output memory */ - set_f( hStereoICBWE->memOutHB[0], 0, NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ) ); - set_f( hStereoICBWE->memOutHB[1], 0, NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ) ); - - - /* SHB output memory */ - set_f( hStereoICBWE->memTransitionHB[0], 0, NS2SA( 48000, STEREO_DFT32MS_OVL_NS ) ); - set_f( hStereoICBWE->memTransitionHB[1], 0, NS2SA( 48000, STEREO_DFT32MS_OVL_NS ) ); - - /* inter-channel BWE spectral shape adj. */ - hStereoICBWE->prevSpecMapping = 0; - hStereoICBWE->prevgsMapping = 1.0f; - - hStereoICBWE->icbweM2Ref_prev = 1.0f; - - hStereoICBWE->prev_spIndx = 0; - hStereoICBWE->prev_gsIndx = 0; - - ic_bwe_dec_reset( hStereoICBWE ); - return; -} -#else -void stereo_icBWE_init_dec_fx( - STEREO_ICBWE_DEC_HANDLE hStereoICBWE /* i/o: Stereo inter-channel BWE handle */ -) -{ - /* BWE ref channel */ - hStereoICBWE->refChanIndx_bwe = L_CH_INDX; - move16(); - hStereoICBWE->prev_refChanIndx_bwe = L_CH_INDX; - move16(); - - /* SHB output memory */ - set32_fx( hStereoICBWE->memOutHB_fx[0], 0, NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ) ); - set32_fx( hStereoICBWE->memOutHB_fx[1], 0, NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ) ); - - - /* SHB output memory */ - set32_fx( hStereoICBWE->memTransitionHB_fx[0], 0, NS2SA( 48000, STEREO_DFT32MS_OVL_NS ) ); - set32_fx( hStereoICBWE->memTransitionHB_fx[1], 0, NS2SA( 48000, STEREO_DFT32MS_OVL_NS ) ); - - /* inter-channel BWE spectral shape adj. */ - hStereoICBWE->prevSpecMapping_fx = 0; - move16(); - hStereoICBWE->prevgsMapping_fx = 16384; - move16(); - hStereoICBWE->icbweM2Ref_prev_fx = 16384; - move16(); - - hStereoICBWE->prev_spIndx = 0; - move16(); - hStereoICBWE->prev_gsIndx = 0; - move16(); - - ic_bwe_dec_reset_fx( hStereoICBWE ); - - return; -} +/****************************************************************************************************** + + (C) 2022-2024 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include +#include "options.h" +#include +#include "cnst.h" +#include "ivas_cnst.h" +#include "prot.h" +#include "prot_fx1.h" +#include "prot_fx2.h" +#include "ivas_prot.h" +#include "ivas_prot_fx.h" +#include "wmc_auto.h" +#include "rom_com.h" +#include "ivas_rom_com.h" + + +#define Q_icBWE 16 + +/*-------------------------------------------------------------------* + * ic_bwe_dec_reset() + * + * core switching reset of IC BWE memory + *-------------------------------------------------------------------*/ + +#ifndef IVAS_FLOAT_FIXED +static void ic_bwe_dec_reset( + STEREO_ICBWE_DEC_HANDLE hStereoICBWE /* i/o: Stereo ICBWE handle */ +) +{ + /* unscaled & scaled SHB synthesis memory */ + set_f( hStereoICBWE->mem_syn_shb_nonref, 0, L_SHB_LAHEAD ); /* use samples from !acelp) */ + set_f( hStereoICBWE->mem_lpc_shbsynth_nonref, 0, LPC_SHB_ORDER ); + set_f( hStereoICBWE->mem_syn_shb_ola_nonref, 0, L_SHB_LAHEAD ); /* use samples from !acelp) */ + + /* inter-channel BWE SP and GSP mem reset */ + hStereoICBWE->memShbSpecMapping = 0; + + set_f( hStereoICBWE->memShbHilbert_nonref, 0, HILBERT_MEM_SIZE ); + set_f( hStereoICBWE->memShbInterp_nonref, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); + set_f( hStereoICBWE->memShb_fsout_nonref, 0, INTERP_3_2_MEM_LEN ); + hStereoICBWE->syn_dm_phase_nonref = 0; + + return; +} +#else +static void ic_bwe_dec_reset_fx( + STEREO_ICBWE_DEC_HANDLE hStereoICBWE /* i/o: Stereo ICBWE handle */ +) +{ + /* unscaled & scaled SHB synthesis memory */ + set32_fx( hStereoICBWE->mem_syn_shb_nonref_fx, 0, L_SHB_LAHEAD ); /* use samples from !acelp) */ + set32_fx( hStereoICBWE->mem_lpc_shbsynth_nonref_fx, 0, LPC_SHB_ORDER ); + set32_fx( hStereoICBWE->mem_syn_shb_ola_nonref_fx, 0, L_SHB_LAHEAD ); /* use samples from !acelp) */ + + hStereoICBWE->prev_Q_syn_shb_nonref = 31; + move16(); + hStereoICBWE->prev_Q_lpc_shbsynth_nonref = 31; + move16(); + hStereoICBWE->prev_Q_syn_shb_ola_nonref = 31; + move16(); + + /* inter-channel BWE SP and GSP mem reset */ + hStereoICBWE->memShbSpecMapping_fx = 0; + move32(); + hStereoICBWE->prev_Q_memshbspec = 31; + move16(); + + set32_fx( hStereoICBWE->memShbHilbert_nonref_fx, 0, HILBERT_MEM_SIZE ); + set32_fx( hStereoICBWE->memShbInterp_nonref_fx, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); + set32_fx( hStereoICBWE->memShb_fsout_nonref_fx, 0, INTERP_3_2_MEM_LEN ); + + hStereoICBWE->prev_Q_hilb = 31; + move16(); + hStereoICBWE->prev_Q_interp = 31; + move16(); + hStereoICBWE->prev_Q_fsout = 31; + move16(); + + hStereoICBWE->syn_dm_phase_nonref = 0; + move16(); + + return; +} +#endif + + +#ifndef IVAS_FLOAT_FIXED +/*-------------------------------------------------------------------* + * stereo_icBWE_dec() + * + * Spatial mapping of reference to the non-reference channels in SHB + *-------------------------------------------------------------------*/ + +void stereo_icBWE_dec( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + float *synthRef, /* i/o: Reference channel HB synthesis at output Fs */ + float *synth, /* o : Non reference channel HB synthesis at output Fs */ + const float *fb_synth_ref, /* i : ref. high-band synthesis 16-20 kHz */ + const float *voice_factors, /* i : voicing factors */ + const int16_t output_frame /* i : frame length */ +) +{ + int16_t i, j, k, nbSubFr; + Decoder_State *st; /* i/o: decoder state structure, primary channel */ + int16_t spIndx, gsIndx; + float excSHB_nonref[L_FRAME16k]; + float shb_synth_nonref[L_FRAME16k + L_SHB_LAHEAD]; + float error[L_FRAME32k]; + float nlMixFac[NB_SUBFR16k]; + float gsMapping, specMapping; + float fb_synth_nonref[L_FRAME48k]; + float scale, prev_pow, curr_pow, temp; + float alpha, winSlope, winLen, prevgsMapping; + float temp1, temp2; + float icbweM2Ref, ratio_L; + + STEREO_DFT_DEC_DATA_HANDLE hStereoDft = hCPE->hStereoDft; + STEREO_ICBWE_DEC_HANDLE hStereoICBWE = hCPE->hStereoICBWE; + st = hCPE->hCoreCoder[0]; + + /*--------------------------------------------------------------------* + * skip IC-BWE in case of mono DMX output * + * -------------------------------------------------------------------*/ + + if ( hCPE->element_mode == IVAS_CPE_DFT && hCPE->nchan_out == 1 && hCPE->hStereoDft->hConfig->res_cod_mode > STEREO_DFT_RES_COD_OFF ) + { + hCPE->hStereoDft->core_hist[0] = st->core; + + return; + } + else if ( hCPE->element_mode == IVAS_CPE_DFT && hCPE->nchan_out == 1 ) + { + + return; + } + + /*--------------------------------------------------------------------* + * skip IC-BWE in case of SID or NO_DATA frame + * -------------------------------------------------------------------*/ + + if ( st->core_brate <= SID_2k40 ) + { + return; + } + + /*--------------------------------------------------------------------* + * TD high band stereo filling * + * -------------------------------------------------------------------*/ + + /* update buffers for TD stereo filling */ + if ( hCPE->element_mode == IVAS_CPE_DFT ) + { + float hb_nrg = EPSILON; + float hb_nrg2 = EPSILON; + + if ( st->core == ACELP_CORE || st->last_core == ACELP_CORE ) + { + for ( i = 0; i < output_frame / 2; i++ ) + { + hb_nrg2 += synthRef[i] * synthRef[i]; + } + + hCPE->hStereoDft->hb_nrg_subr[0] = hb_nrg2; + hb_nrg += hb_nrg2; + hb_nrg2 = EPSILON; + + for ( ; i < output_frame; i++ ) + { + hb_nrg2 += synthRef[i] * synthRef[i]; + } + + hCPE->hStereoDft->hb_nrg_subr[1] = hb_nrg2; + hb_nrg += hb_nrg2; + + mvr2r( synthRef, hCPE->hStereoDft->hb_stefi_sig + hCPE->hStereoDft->hb_stefi_delay, output_frame ); + } + else + { + set_zero( hCPE->hStereoDft->hb_stefi_sig + hCPE->hStereoDft->hb_stefi_delay, output_frame ); + } + hCPE->hStereoDft->hb_nrg_subr[0] *= hCPE->hStereoDft->NFFT / 2; + hCPE->hStereoDft->hb_nrg_subr[1] *= hCPE->hStereoDft->NFFT / 2; + hCPE->hStereoDft->hb_nrg[0] = hb_nrg; + hCPE->hStereoDft->td_gain[0] = 0; + hCPE->hStereoDft->core_hist[0] = st->core; + } + + /*--------------------------------------------------------------------* + * IC-BWE * + * -------------------------------------------------------------------*/ + + if ( st->core != ACELP_CORE || st->extl == -1 || ( hCPE->element_mode == IVAS_CPE_TD && hCPE->hCoreCoder[0]->tdm_LRTD_flag ) ) + { + return; + } + else if ( hCPE->element_mode == IVAS_CPE_DFT && st->core_brate <= SID_2k40 ) + { + mvr2r( synthRef, synth, output_frame ); + return; + } + + + set_f( fb_synth_nonref, 0, L_FRAME48k ); + + /* core switching reset */ + if ( st->last_core != ACELP_CORE || st->bwidth == WB ) + { + ic_bwe_dec_reset( hStereoICBWE ); + + if ( st->last_core != ACELP_CORE ) + { + hStereoICBWE->prevSpecMapping = 0.0f; + hStereoICBWE->prevgsMapping = 1.0f; + hStereoICBWE->icbweM2Ref_prev = 1.0f; + } + + if ( st->bwidth == WB ) + { + /* copy to outputHB and reset hb_synth values */ + mvr2r( synthRef, synth, output_frame ); + + if ( st->element_mode == IVAS_CPE_TD ) + { + hStereoICBWE->prevSpecMapping = 0.0f; + hStereoICBWE->prevgsMapping = 1.0f; + hStereoICBWE->icbweM2Ref_prev = 1.0f; + } + else if ( st->element_mode == IVAS_CPE_DFT ) + { + hStereoICBWE->refChanIndx_bwe = L_CH_INDX; + hStereoICBWE->prevSpecMapping = 0.0f; + + prevgsMapping = hStereoICBWE->prevgsMapping; + temp1 = hStereoDft->side_gain[2 * STEREO_DFT_BAND_MAX + hStereoDft->nbands - 1]; + icbweM2Ref = 1.f + temp1; + gsMapping = 1.f - temp1; + + winLen = (int16_t) ( ( SHB_OVERLAP_LEN * st->output_Fs ) / 16000 ); + winSlope = 1.0f / winLen; + alpha = winSlope; + for ( i = 0; i < winLen; i++ ) + { + synthRef[i] *= ( alpha * ( icbweM2Ref ) + ( 1.0f - alpha ) * ( hStereoICBWE->icbweM2Ref_prev ) ); + synth[i] *= ( alpha * ( gsMapping ) + ( 1.0f - alpha ) * ( prevgsMapping ) ); + alpha += winSlope; + } + for ( ; i < NS2SA( st->output_Fs, FRAME_SIZE_NS ); i++ ) + { + synthRef[i] *= ( icbweM2Ref ); + synth[i] *= ( gsMapping ); + } + hStereoICBWE->icbweM2Ref_prev = icbweM2Ref; + hStereoICBWE->prevgsMapping = gsMapping; + } + + return; + } + } + + if ( !st->bfi ) + { + hStereoICBWE->refChanIndx_bwe = get_next_indice( st, STEREO_ICBWE_REFBITS ); + if ( st->flag_ACELP16k == 1 ) + { + spIndx = get_next_indice( st, STEREO_ICBWE_SPBITS ); + } + else + { + spIndx = 3; + } + if ( st->element_mode == IVAS_CPE_TD ) + { + gsIndx = get_next_indice( st, STEREO_ICBWE_GSBITS ); + } + else + { + gsIndx = get_next_indice( st, STEREO_ICBWE_GSBITS_DFT ); + } + + /* Store indices in case of frame loss */ + hStereoICBWE->prev_spIndx = spIndx; + hStereoICBWE->prev_gsIndx = gsIndx; + } + else /*bfi*/ + { + /* Retrieve last decoded indices */ + spIndx = hStereoICBWE->prev_spIndx; + gsIndx = hStereoICBWE->prev_gsIndx; + hStereoICBWE->refChanIndx_bwe = hStereoICBWE->prev_refChanIndx_bwe; + } + + /* IC-BWE parameter de-quant */ + /* sp Mapping */ + hStereoICBWE->prevSpecMapping = usdequant( spIndx, -0.6f, 0.2f ); + + /* gs Mapping */ + prevgsMapping = hStereoICBWE->prevgsMapping; + + if ( st->element_mode == IVAS_CPE_TD ) + { + hStereoICBWE->prevgsMapping = icbwe_gsMapping_tbl[gsIndx]; + } + else + { + hStereoICBWE->prevgsMapping = icbwe_gsMappingDFT_tbl[gsIndx]; + } + + hStereoICBWE->prevgsMapping = powf( 10, hStereoICBWE->prevgsMapping ); + + specMapping = hStereoICBWE->prevSpecMapping; + gsMapping = hStereoICBWE->prevgsMapping; + + if ( ( st->extl == SWB_TBE || st->extl == FB_TBE ) && st->flag_ACELP16k == 1 ) + { + mvr2r( voice_factors, nlMixFac, NB_SUBFR16k ); + if ( hCPE->hStereoDftDmx != NULL ) + { + if ( hCPE->hStereoDftDmx->targetGain < 0.5f || hCPE->hStereoDftDmx->targetGain > 2.0f ) + { + v_multc( voice_factors, 0.5f, nlMixFac, NB_SUBFR16k ); + } + } + else + { + if ( hCPE->hStereoTCA->targetGain < 0.5f || hCPE->hStereoTCA->targetGain > 2.0f ) + { + v_multc( voice_factors, 0.5f, nlMixFac, NB_SUBFR16k ); + } + } + + nbSubFr = ( st->flag_ACELP16k == 0 ) ? NB_SUBFR : NB_SUBFR16k; + for ( i = 0, k = 0; i < nbSubFr; i++ ) + { + if ( hCPE->hCoreCoder[0]->coder_type == UNVOICED || hStereoICBWE->MSFlag == 1 ) + { + temp1 = 0; + temp2 = 1.0f; + } + else + { + temp1 = sqrtf( nlMixFac[i] ); + temp2 = sqrtf( 1.0f - nlMixFac[i] ); + } + + for ( j = 0; j < L_FRAME16k / nbSubFr; j++, k++ ) + { + excSHB_nonref[k] = temp1 * hStereoICBWE->nlExc16k[k] + temp2 * hStereoICBWE->mixExc16k[k]; + } + } + + /* LP synthesis */ + mvr2r( hStereoICBWE->mem_syn_shb_nonref, shb_synth_nonref, L_SHB_LAHEAD ); + syn_filt( hStereoICBWE->lpSHBRef, LPC_SHB_ORDER, excSHB_nonref, shb_synth_nonref + L_SHB_LAHEAD, L_FRAME16k, hStereoICBWE->mem_lpc_shbsynth_nonref, 1 ); + + prev_pow = sum2_f( shb_synth_nonref, L_SHB_LAHEAD + 10 ); + curr_pow = sum2_f( shb_synth_nonref + L_SHB_LAHEAD + 10, L_SHB_LAHEAD + 10 ); + + if ( prev_pow == 0 ) + { + scale = 0; + } + else + { + scale = sqrtf( curr_pow / prev_pow ); + } + + for ( i = 0; i < L_SHB_LAHEAD; i++ ) + { + shb_synth_nonref[i] *= scale; + } + + for ( ; i < L_SHB_LAHEAD + 10; i++ ) + { + temp = ( i - 19 ) / 10.0f; + shb_synth_nonref[i] *= ( temp * 1.0f + ( 1.0f - temp ) * scale ); + } + /* spec and gs adjustment */ + deemph( shb_synth_nonref + L_SHB_LAHEAD, specMapping, L_FRAME16k, &( hStereoICBWE->memShbSpecMapping ) ); + mvr2r( shb_synth_nonref + L_FRAME16k, hStereoICBWE->mem_syn_shb_nonref, L_SHB_LAHEAD ); + + ScaleShapedSHB( SHB_OVERLAP_LEN, shb_synth_nonref, hStereoICBWE->mem_syn_shb_ola_nonref, hStereoICBWE->gshapeRef, ( hStereoICBWE->gFrameRef * gsMapping * 0.9f ), window_shb, subwin_shb ); + + if ( st->extl == FB_TBE ) + { + v_multc( fb_synth_ref, gsMapping, fb_synth_nonref, L_FRAME48k ); + } + + /* generate 32kHz SHB synthesis from 12.8(16)kHz signal */ + GenSHBSynth( shb_synth_nonref, error, hStereoICBWE->memShbHilbert_nonref, hStereoICBWE->memShbInterp_nonref, st->L_frame, &( hStereoICBWE->syn_dm_phase_nonref ) ); + } + else + { + mvr2r( synthRef, synth, output_frame ); + + winLen = (int16_t) ( ( SHB_OVERLAP_LEN * st->output_Fs ) / 16000 ); + winSlope = 1.0f / winLen; + alpha = winSlope; + + ratio_L = ( hCPE->element_mode == IVAS_CPE_DFT ) ? ( 0.5f ) : ( tdm_ratio_tabl[hCPE->hStereoTD->tdm_last_ratio_idx] ); + + icbweM2Ref = gsMapping; + if ( hStereoICBWE->refChanIndx_bwe == L_CH_INDX ) + { + if ( ratio_L >= 0.1f ) + { + icbweM2Ref = sqrtf( 0.5f - min( 0.5f, ( 1 - ratio_L ) * ( 1 - ratio_L ) * gsMapping * gsMapping ) ) / ratio_L; + } + } + else + { + if ( ratio_L <= 0.9f ) + { + icbweM2Ref = sqrtf( 0.5f - min( 0.5f, ratio_L * ratio_L * gsMapping * gsMapping ) ) / ( 1 - ratio_L ); + } + } + + icbweM2Ref = max( gsMapping, icbweM2Ref ); + + for ( i = 0; i < winLen; i++ ) + { + synthRef[i] *= ( alpha * ( icbweM2Ref ) + ( 1.0f - alpha ) * ( hStereoICBWE->icbweM2Ref_prev ) ); + synth[i] *= ( alpha * ( gsMapping ) + ( 1.0f - alpha ) * ( prevgsMapping ) ); + alpha += winSlope; + } + for ( ; i < NS2SA( st->output_Fs, FRAME_SIZE_NS ); i++ ) + { + synthRef[i] *= ( icbweM2Ref ); + synth[i] *= ( gsMapping ); + } + hStereoICBWE->icbweM2Ref_prev = icbweM2Ref; + + ic_bwe_dec_reset( hStereoICBWE ); + hStereoICBWE->prevSpecMapping = 0.0f; + + return; + } + + /* resample to output FS */ + if ( st->output_Fs == 48000 ) + { + interpolate_3_over_2_allpass( error, L_FRAME32k, synth, hStereoICBWE->memShb_fsout_nonref ); + } + else if ( st->output_Fs == 32000 ) + { + mvr2r( error, synth, L_FRAME32k ); + } + else if ( st->output_Fs == 16000 ) + { + Decimate_allpass_steep( error, hStereoICBWE->memShb_fsout_nonref, L_FRAME32k, synth ); + } + + + if ( st->extl == FB_TBE && st->output_Fs == 48000 ) + { + v_add( fb_synth_nonref, synth, synth, L_FRAME48k ); + } + + /* copy to outputHB and reset hb_synth values */ + ratio_L = ( hCPE->element_mode == IVAS_CPE_DFT ) ? ( 0.5f ) : ( tdm_ratio_tabl[hCPE->hStereoTD->tdm_last_ratio_idx] ); + + icbweM2Ref = gsMapping; + if ( hStereoICBWE->refChanIndx_bwe == L_CH_INDX ) + { + if ( ratio_L >= 0.1f ) + { + icbweM2Ref = sqrtf( 0.5f - min( 0.5f, ( 1 - ratio_L ) * ( 1 - ratio_L ) * gsMapping * gsMapping ) ) / ratio_L; + } + } + else + { + if ( ratio_L <= 0.9f ) + { + icbweM2Ref = sqrtf( 0.5f - min( 0.5f, ratio_L * ratio_L * gsMapping * gsMapping ) ) / ( 1 - ratio_L ); + } + } + + icbweM2Ref = max( gsMapping, icbweM2Ref ); + + winLen = (int16_t) ( ( SHB_OVERLAP_LEN * st->output_Fs ) / 16000 ); + winSlope = 1.0f / winLen; + alpha = winSlope; + for ( i = 0; i < winLen; i++ ) + { + synthRef[i] *= ( alpha * ( icbweM2Ref ) + ( 1.0f - alpha ) * ( hStereoICBWE->icbweM2Ref_prev ) ); + alpha += winSlope; + } + + for ( ; i < NS2SA( st->output_Fs, FRAME_SIZE_NS ); i++ ) + { + synthRef[i] *= ( icbweM2Ref ); + } + + hStereoICBWE->icbweM2Ref_prev = icbweM2Ref; + + return; +} +#else +static Word16 FindScale( + Word32 *buff, + Word16 len, + Word16 Q_buff, + Word16 Q_prev ) +{ + Word32 maxVal; + Word16 norm_shift, Q_out; + + maximum_abs_32_fx( buff, len, &maxVal ); + norm_shift = norm_l( maxVal ); + IF( EQ_32( maxVal, 0 ) ) + { + norm_shift = 31; + move16(); + } + + Q_out = s_min( Q_prev, add( Q_buff, norm_shift ) ); + + return Q_out; +} + + +void stereo_icBWE_dec_fx( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + Word32 *synthRef_fx, /* i/o: Reference channel HB synthesis at output Fs Q_syn/Q_syn - 1 */ + Word32 *synth_fx, /* o : Non reference channel HB synthesis at output Fs Q_syn/Q_syn - 1 */ + const Word16 *fb_synth_ref_fx, /* i : ref. high-band synthesis 16-20 kHz Qx */ + const Word16 *voice_factors_fx, /* i : voicing factors Q15 */ + const Word16 output_frame, /* i : frame length */ + Word16 *Q_syn /* i : Q of synth and synthRef buffers */ +) +{ + Word16 i, j, k, nbSubFr; + Decoder_State *st; /* i/o: decoder state structure, primary channel */ + Word16 spIndx, gsIndx; + Word32 excSHB_nonref_fx[L_FRAME16k]; + Word32 shb_synth_nonref_fx[L_FRAME16k + L_SHB_LAHEAD]; + Word32 error_fx[L_FRAME32k]; + Word16 nlMixFac_fx[NB_SUBFR16k]; + Word16 specMapping_fx; + Word16 fb_synth_nonref_fx[L_FRAME48k]; + Word32 prev_pow_fx, curr_pow_fx, maxVal1, maxVal; + Word16 scale_fx, e_scale_fx; + Word16 alpha_fx, winSlope_fx, winLen_fx; + Word16 prevgsMapping_fx; + Word16 temp1_fx, temp2_fx; + Word16 icbweM2Ref_fx, ratio_L_fx; + Word16 gsMapping_fx; + Word32 hb_nrg_fx, hb_nrg2_fx; + Word16 Q_syn_shb; + Word16 shift_prev_pow, synthRef_shift; + Word32 L_tmp; + Word16 tmp; + Word32 L_nlExc16k, L_mixExc16k; + + STEREO_DFT_DEC_DATA_HANDLE hStereoDft = hCPE->hStereoDft; + STEREO_ICBWE_DEC_HANDLE hStereoICBWE = hCPE->hStereoICBWE; + st = hCPE->hCoreCoder[0]; + + /*--------------------------------------------------------------------* + * skip IC-BWE in case of mono DMX output * + * -------------------------------------------------------------------*/ + + test(); + test(); + test(); + IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && EQ_16( hCPE->nchan_out, 1 ) && GT_16( hCPE->hStereoDft->hConfig->res_cod_mode, STEREO_DFT_RES_COD_OFF ) ) + { + hCPE->hStereoDft->core_hist[0] = st->core; + move16(); + + return; + } + ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && EQ_16( hCPE->nchan_out, 1 ) ) + { + return; + } + + /*--------------------------------------------------------------------* + * skip IC-BWE in case of SID or NO_DATA frame + * -------------------------------------------------------------------*/ + + IF( LE_32( st->core_brate, SID_2k40 ) ) + { + return; + } + + /*--------------------------------------------------------------------* + * TD high band stereo filling * + * -------------------------------------------------------------------*/ + + /* update buffers for TD stereo filling */ + IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) + { + hb_nrg_fx = 0; + move32(); + hb_nrg2_fx = 0; + move32(); + maximum_abs_32_fx( synthRef_fx, output_frame, &maxVal ); + synthRef_shift = norm_l( maxVal ); + IF( EQ_32( maxVal, 0 ) ) + { + synthRef_shift = 31; + move16(); + } + synthRef_shift = sub( synthRef_shift, shr( add( find_guarded_bits_fx( output_frame ), 1 ), 1 ) ); + test(); + IF( EQ_16( st->core, ACELP_CORE ) || EQ_16( st->last_core, ACELP_CORE ) ) + { + FOR( i = 0; i < output_frame / 2; i++ ) + { + // needed to be adjusted for q + L_tmp = L_shl( synthRef_fx[i], synthRef_shift ); + hb_nrg2_fx = L_add( hb_nrg2_fx, Mpy_32_32( L_tmp, L_tmp ) ); // 2*(Qx + SynthRef_shift) - 31 + } + + hCPE->hStereoDft->hb_nrg_subr_fx[0] = hb_nrg2_fx; + move32(); + hStereoDft->q_hb_nrg_subr = sub(add(*Q_syn, synthRef_shift), 31); + hb_nrg_fx = L_add( hb_nrg_fx, hb_nrg2_fx ); + hb_nrg2_fx = 0; + move32(); + + FOR( ; i < output_frame; i++ ) + { + L_tmp = L_shl( synthRef_fx[i], synthRef_shift ); + hb_nrg2_fx = L_add( hb_nrg2_fx, Mpy_32_32( L_tmp, L_tmp ) ); + } + + hCPE->hStereoDft->hb_nrg_subr_fx[1] = hb_nrg2_fx; // 2*(Qx + SynthRef_shift) - 31 + move32(); + hb_nrg_fx = L_add( hb_nrg_fx, hb_nrg2_fx ); + + Copy32( synthRef_fx, hCPE->hStereoDft->hb_stefi_sig_fx + hCPE->hStereoDft->hb_stefi_delay, output_frame ); + + Scale_sig32(hCPE->hStereoDft->hb_stefi_sig_fx + hCPE->hStereoDft->hb_stefi_delay, output_frame, -5); + } + ELSE + { + set32_fx( hCPE->hStereoDft->hb_stefi_sig_fx + hCPE->hStereoDft->hb_stefi_delay, 0, output_frame ); +#ifdef MSAN_FIX + hCPE->hStereoDft->hb_nrg_subr_fx[0] = 0; + hCPE->hStereoDft->hb_nrg_subr_fx[1] = 0; +#endif // MSAN_FIX + } + hCPE->hStereoDft->hb_nrg_subr_fx[0] = ( Mpy_32_16_1( hCPE->hStereoDft->hb_nrg_subr_fx[0], shl( hCPE->hStereoDft->NFFT / 2, 6 ) ) ); // 2 * (Qx + SynthRef_shift) - 40 // 2 * (Qx + SynthRef_shift) - 31 - 15 + move32(); + hCPE->hStereoDft->hb_nrg_subr_fx[1] = ( Mpy_32_16_1( hCPE->hStereoDft->hb_nrg_subr_fx[1], shl( hCPE->hStereoDft->NFFT / 2, 6 ) ) ); // 2 * (Qx + SynthRef_shift) - 40 + move32(); + hCPE->hStereoDft->q_hb_nrg_subr = sub( shl( ( *Q_syn + synthRef_shift ), 1 ), 40 ); + hCPE->hStereoDft->hb_nrg_fx[0] = hb_nrg_fx; // 2 * (Qx + SynthRef_shift) - 31 + move32(); + hCPE->hStereoDft->td_gain_fx[0] = 0; + move32(); + hCPE->hStereoDft->core_hist[0] = st->core; + move16(); + } + + /*--------------------------------------------------------------------* + * IC-BWE * + * -------------------------------------------------------------------*/ + test(); + test(); + test(); + test(); + IF( NE_16( st->core, ACELP_CORE ) || EQ_16( st->extl, -1 ) || ( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) && NE_16( hCPE->hCoreCoder[0]->tdm_LRTD_flag, 0 ) ) ) + { + return; + } + ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && LE_32( st->core_brate, SID_2k40 ) ) + { + Copy32( synthRef_fx, synth_fx, output_frame ); + return; + } + + + set16_fx( fb_synth_nonref_fx, 0, L_FRAME48k ); + + /* core switching reset */ + test(); + IF( NE_16( st->last_core, ACELP_CORE ) || EQ_16( st->bwidth, (Word16) WB ) ) + { + ic_bwe_dec_reset_fx( hStereoICBWE ); + + IF( NE_16( st->last_core, ACELP_CORE ) ) + { + hStereoICBWE->prevSpecMapping_fx = 0; + move16(); + hStereoICBWE->prevgsMapping_fx = 16384; + move16(); + hStereoICBWE->icbweM2Ref_prev_fx = 16384; + move16(); + } + + IF( EQ_16( st->bwidth, WB ) ) + { + /* copy to outputHB and reset hb_synth values */ + Copy32( synthRef_fx, synth_fx, output_frame ); + + IF( EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + hStereoICBWE->prevSpecMapping_fx = 0; + move16(); + hStereoICBWE->prevgsMapping_fx = 16384; + move16(); + hStereoICBWE->icbweM2Ref_prev_fx = 16384; + move16(); + } + ELSE IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) + { + hStereoICBWE->refChanIndx_bwe = L_CH_INDX; + move16(); + hStereoICBWE->prevSpecMapping_fx = 0; + move16(); + + prevgsMapping_fx = hStereoICBWE->prevgsMapping_fx; + move16(); + temp1_fx = shr( extract_h( hStereoDft->side_gain_fx[2 * STEREO_DFT_BAND_MAX + hStereoDft->nbands - 1] ), 1 ); + icbweM2Ref_fx = add( 16384, temp1_fx ); + gsMapping_fx = sub( 16384, temp1_fx ); + + winLen_fx = extract_l( Mpy_32_16_1( st->output_Fs, 41 ) ); //(int16_t)((SHB_OVERLAP_LEN * st->output_Fs) / 16000); + winSlope_fx = div_s( 1, winLen_fx ); + alpha_fx = winSlope_fx; + move16(); + FOR( i = 0; i < winLen_fx; i++ ) + { + L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); // Q15 + Q14 + L_tmp = L_mac0( L_tmp, sub( 32767, alpha_fx ), ( hStereoICBWE->icbweM2Ref_prev_fx ) ); // Q15 + Q14; + tmp = shl( round_fx( L_tmp ), 1 ); // Q = 15 + 14 - 16 + 1 = Q14 + synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], tmp ); + move32(); + L_tmp = L_mult0( alpha_fx, gsMapping_fx ); + L_tmp = L_mac0( L_tmp, ( sub( 32767, alpha_fx ) ), ( prevgsMapping_fx ) ); + tmp = shl( round_fx( L_tmp ), 1 ); // Q = 15 + 14 - 16 + 1 = Q14 + synth_fx[i] = Mpy_32_16_1( synth_fx[i], tmp ); + move32(); + IF( LE_16( alpha_fx, sub( 32767, winSlope_fx ) ) ) + { + alpha_fx = add( alpha_fx, winSlope_fx ); + } + } + FOR( ; i < NS2SA( st->output_Fs, FRAME_SIZE_NS ); i++ ) + { + synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], icbweM2Ref_fx ); + move32(); + synth_fx[i] = Mpy_32_16_1( synth_fx[i], gsMapping_fx ); + move32(); + } + hStereoICBWE->icbweM2Ref_prev_fx = icbweM2Ref_fx; + move16(); + hStereoICBWE->prevgsMapping_fx = gsMapping_fx; + move16(); + + *Q_syn = sub( *Q_syn, 1 ); + } + + return; + } + } + + IF( EQ_16( st->bfi, 0 ) ) + { + hStereoICBWE->refChanIndx_bwe = get_next_indice_fx( st, STEREO_ICBWE_REFBITS ); + IF( EQ_16( st->flag_ACELP16k, 1 ) ) + { + spIndx = get_next_indice_fx( st, STEREO_ICBWE_SPBITS ); + } + ELSE + { + spIndx = 3; + move16(); + } + IF( EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + gsIndx = get_next_indice_fx( st, STEREO_ICBWE_GSBITS ); + } + ELSE + { + gsIndx = get_next_indice_fx( st, STEREO_ICBWE_GSBITS_DFT ); + } + + /* Store indices in case of frame loss */ + hStereoICBWE->prev_spIndx = spIndx; + move16(); + hStereoICBWE->prev_gsIndx = gsIndx; + move16(); + } + ELSE /*bfi*/ + { + /* Retrieve last decoded indices */ + spIndx = hStereoICBWE->prev_spIndx; + move16(); + gsIndx = hStereoICBWE->prev_gsIndx; + move16(); + hStereoICBWE->refChanIndx_bwe = hStereoICBWE->prev_refChanIndx_bwe; + move16(); + } + + /* IC-BWE parameter de-quant */ + /* sp Mapping */ + hStereoICBWE->prevSpecMapping_fx = usdequant_fx( spIndx, -19661, 3277 ); // Q15 + + /* gs Mapping */ + prevgsMapping_fx = hStereoICBWE->prevgsMapping_fx; // Q14 + move16(); + + IF( EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + hStereoICBWE->prevgsMapping_fx = pow_10_icbwe_gsMapping_tbl_fx[gsIndx]; + move16(); + } + ELSE + { + hStereoICBWE->prevgsMapping_fx = pow_10_icbwe_gsMappingDFT_tbl_fx[gsIndx]; + move16(); + } + + // hStereoICBWE->prevgsMapping = powf( 10, hStereoICBWE->prevgsMapping ); + + specMapping_fx = hStereoICBWE->prevSpecMapping_fx; // Q15 + move16(); + gsMapping_fx = hStereoICBWE->prevgsMapping_fx; // Q14 + move16(); + + test(); + test(); + IF( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && EQ_16( st->flag_ACELP16k, 1 ) ) + { + Copy( voice_factors_fx, nlMixFac_fx, NB_SUBFR16k ); // Q15 + IF( hCPE->hStereoDftDmx != NULL ) + { + test(); + IF( LT_32( hCPE->hStereoDftDmx->targetGain_fx, 268435456 ) || GT_32( hCPE->hStereoDftDmx->targetGain_fx, 1073741824 ) ) + { + v_multc_fixed_16_16( voice_factors_fx, 16384, nlMixFac_fx, NB_SUBFR16k ); + } + } + ELSE + { + test(); + IF( LT_32( hCPE->hStereoTCA->targetGain_fx, 268435456 ) || GT_32( hCPE->hStereoTCA->targetGain_fx, 1073741824 ) ) + { + v_multc_fixed_16_16( voice_factors_fx, 16384, nlMixFac_fx, NB_SUBFR16k ); + } + } + + // nbSubFr = ( st->flag_ACELP16k == 0 ) ? NB_SUBFR : NB_SUBFR16k; + IF( EQ_16( st->flag_ACELP16k, 0 ) ) + { + nbSubFr = NB_SUBFR; + move16(); + } + ELSE + { + nbSubFr = NB_SUBFR16k; + move16(); + } + k = 0; + move16(); + FOR( i = 0; i < nbSubFr; i++ ) + { + IF( EQ_16( hCPE->hCoreCoder[0]->coder_type, UNVOICED ) || EQ_16( hStereoICBWE->MSFlag, 1 ) ) + { + temp1_fx = 0; + move16(); + temp2_fx = 32767; + move16(); + } + ELSE + { + tmp = 0; + move16(); + temp1_fx = Sqrt16( nlMixFac_fx[i], &tmp ); + IF( LT_16( tmp, 0 ) ) + { + temp1_fx = shl( temp1_fx, tmp ); + } + tmp = 0; + move16(); + temp2_fx = Sqrt16( sub( 32767, nlMixFac_fx[i] ), &tmp ); + IF( LT_16( tmp, 0 ) ) + { + temp2_fx = shl( temp2_fx, tmp ); + } + } + + FOR( j = 0; j < L_FRAME16k / nbSubFr; j++ ) + { + // common Q for addition + L_nlExc16k = L_deposit_l( hStereoICBWE->nlExc16k_fx[k] ); // prev_q_bwe_exc - 16 + L_mixExc16k = L_deposit_l( hStereoICBWE->mixExc16k_fx[k] ); // Q_exc + L_nlExc16k = L_shl( L_nlExc16k, Q_icBWE - ( st->prev_Q_bwe_exc - 16 ) ); // Q_icBWE +#ifndef FIX_736_BWE_SECT_C + L_mixExc16k = L_shl( L_mixExc16k, Q_icBWE - st->Q_exc ); // Q_icBWE +#else + L_mixExc16k = L_shl( L_mixExc16k, Q_icBWE - ( st->prev_Q_bwe_exc - 25 ) ); // Q_icBWE +#endif + excSHB_nonref_fx[k] = L_add( Mpy_32_16_1( L_nlExc16k, temp1_fx ), Mpy_32_16_1( L_mixExc16k, temp2_fx ) ); // Q_icBWE + move32(); + k++; + } + } + + /* LP synthesis */ + Q_syn_shb = 31; + move16(); + + Q_syn_shb = FindScale( hStereoICBWE->mem_syn_shb_nonref_fx, LPC_SHB_ORDER, hStereoICBWE->prev_Q_syn_shb_nonref, Q_syn_shb ); + Q_syn_shb = FindScale( hStereoICBWE->lpSHBRef_fx, LPC_SHB_ORDER + 1, 12, Q_syn_shb ); + Q_syn_shb = FindScale( excSHB_nonref_fx, L_FRAME16k, Q_icBWE, Q_syn_shb ); + Q_syn_shb = FindScale( hStereoICBWE->mem_lpc_shbsynth_nonref_fx, LPC_SHB_ORDER, hStereoICBWE->prev_Q_lpc_shbsynth_nonref, Q_syn_shb ); + + Q_syn_shb = sub( Q_syn_shb, 3 ); // gaurded bits + + Scale_sig32( hStereoICBWE->lpSHBRef_fx, LPC_SHB_ORDER + 1, sub( Q_syn_shb, 12 ) ); + Scale_sig32( excSHB_nonref_fx, L_FRAME16k, sub( Q_syn_shb, Q_icBWE ) ); + Scale_sig32( hStereoICBWE->mem_lpc_shbsynth_nonref_fx, LPC_SHB_ORDER, sub( Q_syn_shb, hStereoICBWE->prev_Q_lpc_shbsynth_nonref ) ); + Scale_sig32( hStereoICBWE->mem_syn_shb_nonref_fx, L_SHB_LAHEAD, sub( Q_syn_shb, hStereoICBWE->prev_Q_syn_shb_nonref ) ); + + + Copy32( hStereoICBWE->mem_syn_shb_nonref_fx, shb_synth_nonref_fx, L_SHB_LAHEAD ); + + E_UTIL_synthesis_fx( 0, hStereoICBWE->lpSHBRef_fx, excSHB_nonref_fx, shb_synth_nonref_fx + L_SHB_LAHEAD, L_FRAME16k, hStereoICBWE->mem_lpc_shbsynth_nonref_fx, 1, LPC_SHB_ORDER ); + + hStereoICBWE->prev_Q_lpc_shbsynth_nonref = Q_syn_shb; + move16(); + + maximum_abs_32_fx( shb_synth_nonref_fx, L_SHB_LAHEAD + 10 + L_SHB_LAHEAD + 10, &maxVal1 ); // Qsyn_shb + + shift_prev_pow = sub( norm_l( maxVal1 ), find_guarded_bits_fx( L_SHB_LAHEAD + 10 ) ); + + prev_pow_fx = 0; + move32(); + curr_pow_fx = 0; + move32(); + FOR( i = 0; i < L_SHB_LAHEAD + 10; i++ ) + { + L_tmp = L_shl( shb_synth_nonref_fx[i], shift_prev_pow ); + prev_pow_fx = L_add( prev_pow_fx, Mpy_32_32( L_tmp, L_tmp ) ); + } + FOR( i = 0; i < L_SHB_LAHEAD + 10; i++ ) + { + L_tmp = L_shl( shb_synth_nonref_fx[L_SHB_LAHEAD + 10 + i], shift_prev_pow ); + curr_pow_fx = L_add( curr_pow_fx, Mpy_32_32( L_tmp, L_tmp ) ); + } + + IF( EQ_32( prev_pow_fx, 0 ) ) + { + e_scale_fx = 0; + move16(); + scale_fx = 0; + move16(); + } + ELSE + { + e_scale_fx = 0; + move16(); + scale_fx = BASOP_Util_Divide3232_Scale( curr_pow_fx, prev_pow_fx, &e_scale_fx ); + scale_fx = Sqrt16( scale_fx, &e_scale_fx ); + } + IF( LT_16( e_scale_fx, 0 ) ) + { + scale_fx = shl( scale_fx, e_scale_fx ); + e_scale_fx = 0; + move16(); + } + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + shb_synth_nonref_fx[i] = Mpy_32_16_1( shb_synth_nonref_fx[i], scale_fx ); + move32(); + } + tmp = 3276; + move16(); + FOR( ; i < L_SHB_LAHEAD + 10; i++ ) + { + IF( EQ_16( e_scale_fx, 0 ) ) + { + temp1_fx = 32767; + move16(); + } + ELSE + { + temp1_fx = shl( 1, sub( 15, e_scale_fx ) ); + move16(); + } + L_tmp = L_mult0( tmp, temp1_fx ); + L_tmp = L_mac0( L_tmp, sub( 32767, tmp ), scale_fx ); + shb_synth_nonref_fx[i] = Mpy_32_16_1( shb_synth_nonref_fx[i], shl( round_fx( L_tmp ), 1 ) ); + move32(); + IF( LT_16( tmp, 29492 ) ) + { + tmp = add( tmp, 3276 ); + } + } + + /* spec and gs adjustment */ + Q_syn_shb = sub( Q_syn_shb, e_scale_fx ); + Scale_sig32( shb_synth_nonref_fx + L_SHB_LAHEAD + 10, L_FRAME16k - 10, -e_scale_fx ); + + tmp = 31; + move16(); + tmp = FindScale( shb_synth_nonref_fx, L_FRAME16k + L_SHB_LAHEAD, Q_syn_shb, tmp ); + temp1_fx = norm_l( hStereoICBWE->memShbSpecMapping_fx ); + IF( EQ_32( hStereoICBWE->memShbSpecMapping_fx, 0 ) ) + { + temp1_fx = 31; + move16(); + } + temp1_fx = add( temp1_fx, hStereoICBWE->prev_Q_memshbspec ); + tmp = s_min( temp1_fx, tmp ); + + tmp = sub( tmp, 9 ); + + Scale_sig32( shb_synth_nonref_fx, L_FRAME16k + L_SHB_LAHEAD, tmp - Q_syn_shb ); + hStereoICBWE->memShbSpecMapping_fx = L_shl( hStereoICBWE->memShbSpecMapping_fx, tmp - hStereoICBWE->prev_Q_memshbspec ); + + hStereoICBWE->prev_Q_memshbspec = tmp; + move16(); + Q_syn_shb = tmp; + move16(); + + deemph_fx_32( 0, shb_synth_nonref_fx + L_SHB_LAHEAD, specMapping_fx, L_FRAME16k, &( hStereoICBWE->memShbSpecMapping_fx ) ); + hStereoICBWE->prev_Q_memshbspec = Q_syn_shb; + move16(); + Copy32( shb_synth_nonref_fx + L_FRAME16k, hStereoICBWE->mem_syn_shb_nonref_fx, L_SHB_LAHEAD ); + hStereoICBWE->prev_Q_syn_shb_nonref = Q_syn_shb; + move16(); + + tmp = 31; + move16(); + tmp = FindScale( shb_synth_nonref_fx, L_FRAME16k + L_SHB_LAHEAD, Q_syn_shb, tmp ); + tmp = FindScale( hStereoICBWE->mem_syn_shb_ola_nonref_fx, L_SHB_LAHEAD, hStereoICBWE->prev_Q_syn_shb_ola_nonref, tmp ); + + tmp = sub( tmp, 3 ); + + Scale_sig32( shb_synth_nonref_fx, L_FRAME16k + L_SHB_LAHEAD, tmp - Q_syn_shb ); + Scale_sig32( hStereoICBWE->mem_syn_shb_ola_nonref_fx, L_SHB_LAHEAD, tmp - hStereoICBWE->prev_Q_syn_shb_ola_nonref ); + + ScaleShapedSHB_32( SHB_OVERLAP_LEN, shb_synth_nonref_fx, hStereoICBWE->mem_syn_shb_ola_nonref_fx, hStereoICBWE->gshapeRef_fx, ( Mpy_32_16_1( L_shl( hStereoICBWE->gFrameRef_fx, 1 ), mult_r( gsMapping_fx, 29492 ) ) ), window_shb_fx, subwin_shb_fx, &tmp, &temp1_fx ); + + hStereoICBWE->prev_Q_syn_shb_ola_nonref = tmp; + move16(); + Q_syn_shb = tmp; + move16(); + + IF( EQ_16( st->extl, FB_TBE ) ) + { + v_multc_fixed_16_16( fb_synth_ref_fx, gsMapping_fx, fb_synth_nonref_fx, L_FRAME48k ); + } + + /* generate 32kHz SHB synthesis from 12.8(16)kHz signal */ + + tmp = 31; + move16(); + tmp = FindScale( shb_synth_nonref_fx, L_FRAME16k + L_SHB_LAHEAD, Q_syn_shb, tmp ); + tmp = FindScale( hStereoICBWE->memShbHilbert_nonref_fx, HILBERT_MEM_SIZE, hStereoICBWE->prev_Q_hilb, tmp ); + tmp = FindScale( hStereoICBWE->memShbInterp_nonref_fx, 2 * ALLPASSSECTIONS_STEEP + 1, hStereoICBWE->prev_Q_interp, tmp ); + + tmp = sub( tmp, 3 ); + + Scale_sig32( shb_synth_nonref_fx, L_FRAME16k + L_SHB_LAHEAD, sub( tmp, Q_syn_shb ) ); + Scale_sig32( hStereoICBWE->memShbHilbert_nonref_fx, HILBERT_MEM_SIZE, sub( tmp, hStereoICBWE->prev_Q_hilb ) ); + Scale_sig32( hStereoICBWE->memShbInterp_nonref_fx, 2 * ALLPASSSECTIONS_STEEP + 1, sub( tmp, hStereoICBWE->prev_Q_interp ) ); + + hStereoICBWE->prev_Q_hilb = tmp; + move16(); + hStereoICBWE->prev_Q_interp = tmp; + move16(); + + Q_syn_shb = tmp; + move16(); + + GenSHBSynth_fx_32( shb_synth_nonref_fx, error_fx, hStereoICBWE->memShbHilbert_nonref_fx, hStereoICBWE->memShbInterp_nonref_fx, st->L_frame, &( hStereoICBWE->syn_dm_phase_nonref ) ); + } + ELSE + { + Copy32( synthRef_fx, synth_fx, output_frame ); + + winLen_fx = extract_l( Mpy_32_16_1( st->output_Fs, 41 ) ); + winSlope_fx = div_s( 1, winLen_fx ); + alpha_fx = winSlope_fx; + move16(); + + + IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) + { + ratio_L_fx = 16384; + move16(); + } + ELSE + { + ratio_L_fx = extract_h( tdm_ratio_tabl_fx[hCPE->hStereoTD->tdm_last_ratio_idx] ); + move16(); + } + + icbweM2Ref_fx = gsMapping_fx; + move16(); + IF( EQ_16( hStereoICBWE->refChanIndx_bwe, L_CH_INDX ) ) + { + + IF( GE_16( ratio_L_fx, 3276 ) ) + { + tmp = mult_r( sub( 32767, ratio_L_fx ), sub( 32767, ratio_L_fx ) ); // Q15 + tmp = mult_r( tmp, gsMapping_fx ); // Q14 + tmp = mult_r( tmp, gsMapping_fx ); // Q13 + IF( LT_16( tmp, 4096 ) ) + { + temp1_fx = 0; + move16(); + temp2_fx = 0; + move16(); + tmp = shl( tmp, 2 ); + icbweM2Ref_fx = Sqrt16( sub( 16384, tmp ), &temp1_fx ); + icbweM2Ref_fx = BASOP_Util_Divide1616_Scale( icbweM2Ref_fx, ratio_L_fx, &temp2_fx ); + icbweM2Ref_fx = shl( icbweM2Ref_fx, add( temp2_fx, sub( temp1_fx, 1 ) ) ); // Q14 + } + ELSE + { + icbweM2Ref_fx = 0; + move16(); + } + } + } + ELSE + { + IF( LE_16( ratio_L_fx, 29490 ) ) + { +#ifdef FIX_TMP_714 + tmp = mult_r( ratio_L_fx, ratio_L_fx ); // Q15 +#else + tmp = mult_r( sub( 32767, ratio_L_fx ), sub( 32767, ratio_L_fx ) ); // Q15 +#endif + tmp = mult_r( tmp, gsMapping_fx ); // Q14 + tmp = mult_r( tmp, gsMapping_fx ); // Q13 + IF( LT_16( tmp, 4096 ) ) + { + temp1_fx = 0; + move16(); + temp2_fx = 0; + move16(); + tmp = shl( tmp, 2 ); + icbweM2Ref_fx = Sqrt16( sub( 16384, tmp ), &temp1_fx ); + icbweM2Ref_fx = BASOP_Util_Divide1616_Scale( icbweM2Ref_fx, sub( 32767, ratio_L_fx ), &temp2_fx ); + icbweM2Ref_fx = shl( icbweM2Ref_fx, add( temp2_fx, sub( temp1_fx, 1 ) ) ); // Q14 + } + ELSE + { + icbweM2Ref_fx = 0; + move16(); + } + } + } + + icbweM2Ref_fx = s_max( gsMapping_fx, icbweM2Ref_fx ); + + FOR( i = 0; i < winLen_fx; i++ ) + { + L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); + L_tmp = L_mac0( L_tmp, sub( 32767, alpha_fx ), hStereoICBWE->icbweM2Ref_prev_fx ); + tmp = shl( round_fx( L_tmp ), 1 ); + synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], tmp ); + move32(); + L_tmp = L_mult0( alpha_fx, gsMapping_fx ); + L_tmp = L_mac0( L_tmp, sub( 32767, alpha_fx ), prevgsMapping_fx ); + tmp = shl( round_fx( L_tmp ), 1 ); + synth_fx[i] = Mpy_32_16_1( synth_fx[i], tmp ); + move32(); + IF( LE_16( alpha_fx, sub( 32767, winSlope_fx ) ) ) + { + alpha_fx = add( alpha_fx, winSlope_fx ); + } + } + FOR( ; i < NS2SA( st->output_Fs, FRAME_SIZE_NS ); i++ ) + { + synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], icbweM2Ref_fx ); + move32(); + synth_fx[i] = Mpy_32_16_1( synth_fx[i], gsMapping_fx ); + move32(); + } + hStereoICBWE->icbweM2Ref_prev_fx = icbweM2Ref_fx; + move16(); + + ic_bwe_dec_reset_fx( hStereoICBWE ); + hStereoICBWE->prevSpecMapping_fx = 0; + move16(); + + *Q_syn = sub( *Q_syn, 1 ); + + return; + } + + /* resample to output FS */ + + + IF( EQ_32( st->output_Fs, 48000 ) ) + { + tmp = 31; + move16(); + tmp = FindScale( error_fx, L_FRAME32k, Q_syn_shb, tmp ); + tmp = FindScale( hStereoICBWE->memShb_fsout_nonref_fx, INTERP_3_2_MEM_LEN, hStereoICBWE->prev_Q_fsout, tmp ); + tmp = sub( tmp, 4 ); + + Scale_sig32( error_fx, L_FRAME32k, sub( tmp, Q_syn_shb ) ); + Scale_sig32( hStereoICBWE->memShb_fsout_nonref_fx, INTERP_3_2_MEM_LEN, sub( tmp, hStereoICBWE->prev_Q_fsout ) ); + interpolate_3_over_2_allpass_32( error_fx, L_FRAME32k, synth_fx, hStereoICBWE->memShb_fsout_nonref_fx ); + hStereoICBWE->prev_Q_fsout = tmp; + move16(); + } + ELSE IF( EQ_32( st->output_Fs, 32000 ) ) + { + Copy32( error_fx, synth_fx, L_FRAME32k ); + } + ELSE IF( EQ_32( st->output_Fs, 16000 ) ) + { + tmp = 31; + move16(); + tmp = FindScale( error_fx, L_FRAME32k, Q_syn_shb, tmp ); + tmp = FindScale( hStereoICBWE->memShb_fsout_nonref_fx, INTERP_3_2_MEM_LEN, hStereoICBWE->prev_Q_fsout, tmp ); + tmp = sub( tmp, 4 ); + + Scale_sig32( error_fx, L_FRAME32k, sub( tmp, Q_syn_shb ) ); + Scale_sig32( hStereoICBWE->memShb_fsout_nonref_fx, INTERP_3_2_MEM_LEN, sub( tmp, hStereoICBWE->prev_Q_fsout ) ); + Decimate_allpass_steep_fx32( error_fx, hStereoICBWE->memShb_fsout_nonref_fx, L_FRAME32k, synth_fx ); + hStereoICBWE->prev_Q_fsout = tmp; + move16(); + } +#ifndef MSAN_FIX + Scale_sig32( synth_fx, L_FRAME48k, sub( *Q_syn, add( 1, tmp ) ) ); +#else + Scale_sig32( synth_fx, output_frame, sub( *Q_syn, add( 1, tmp ) ) ); +#endif + + *Q_syn = sub( *Q_syn, 1 ); + + test(); + IF( EQ_16( st->extl, FB_TBE ) && EQ_32( st->output_Fs, 48000 ) ) + { + + // v_add( fb_synth_nonref_fx, synth_fx, synth_fx, L_FRAME48k, 0 ); + FOR( i = 0; i < L_FRAME48k; i++ ) + { + synth_fx[i] = L_add( synth_fx[i], L_deposit_l( fb_synth_nonref_fx[i] ) ); + move32(); + } + } + + /* copy to outputHB and reset hb_synth values */ + + IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) + { + ratio_L_fx = 16384; + move16(); + } + ELSE + { + ratio_L_fx = extract_h( tdm_ratio_tabl_fx[hCPE->hStereoTD->tdm_last_ratio_idx] ); + move16(); + } + + icbweM2Ref_fx = gsMapping_fx; + move16(); + IF( EQ_16( hStereoICBWE->refChanIndx_bwe, L_CH_INDX ) ) + { + IF( GE_16( ratio_L_fx, 3276 ) ) + { + tmp = mult_r( sub( 32767, ratio_L_fx ), sub( 32767, ratio_L_fx ) ); // Q15 + tmp = mult_r( tmp, gsMapping_fx ); // Q14 + tmp = mult_r( tmp, gsMapping_fx ); // Q13 + IF( LT_16( tmp, 4096 ) ) + { + temp1_fx = 0; + move16(); + temp2_fx = 0; + move16(); + tmp = shl( tmp, 2 ); + icbweM2Ref_fx = Sqrt16( sub( 16384, tmp ), &temp1_fx ); + icbweM2Ref_fx = BASOP_Util_Divide1616_Scale( icbweM2Ref_fx, ratio_L_fx, &temp2_fx ); + icbweM2Ref_fx = shl( icbweM2Ref_fx, add( temp1_fx, sub( temp2_fx, 1 ) ) ); // Q14 + } + ELSE + { + icbweM2Ref_fx = 0; + move16(); + } + } + } + ELSE + { + IF( LE_16( ratio_L_fx, 29490 ) ) + { +#ifdef FIX_TMP_714 + tmp = mult_r( ratio_L_fx, ratio_L_fx ); // Q15 +#else + tmp = mult_r( sub( 32767, ratio_L_fx ), sub( 32767, ratio_L_fx ) ); // Q15 +#endif + tmp = mult_r( tmp, gsMapping_fx ); // Q14 + tmp = mult_r( tmp, gsMapping_fx ); // Q13 + IF( LT_16( tmp, 4096 ) ) + { + temp1_fx = 0; + move16(); + temp2_fx = 0; + move16(); + tmp = shl( tmp, 2 ); + icbweM2Ref_fx = Sqrt16( sub( 16384, tmp ), &temp1_fx ); + icbweM2Ref_fx = BASOP_Util_Divide1616_Scale( icbweM2Ref_fx, sub( 32767, ratio_L_fx ), &temp2_fx ); + icbweM2Ref_fx = shl( icbweM2Ref_fx, add( temp2_fx, sub( temp1_fx, 1 ) ) ); // Q14 + } + ELSE + { + icbweM2Ref_fx = 0; + move16(); + } + } + } + + icbweM2Ref_fx = s_max( gsMapping_fx, icbweM2Ref_fx ); + + winLen_fx = extract_l( Mpy_32_16_1( st->output_Fs, 41 ) ); + winSlope_fx = div_s( 1, winLen_fx ); + alpha_fx = winSlope_fx; + move16(); + FOR( i = 0; i < winLen_fx; i++ ) + { + L_tmp = L_mult0( alpha_fx, icbweM2Ref_fx ); + L_tmp = L_mac0( L_tmp, sub( 32767, alpha_fx ), hStereoICBWE->icbweM2Ref_prev_fx ); + tmp = shl( round_fx( L_tmp ), 1 ); + synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], tmp ); + move32(); + IF( LE_16( alpha_fx, sub( 32767, winSlope_fx ) ) ) + { + alpha_fx = add( alpha_fx, winSlope_fx ); + } + } + + FOR( ; i < NS2SA( st->output_Fs, FRAME_SIZE_NS ); i++ ) + { + synthRef_fx[i] = Mpy_32_16_1( synthRef_fx[i], icbweM2Ref_fx ); + move32(); + } + + hStereoICBWE->icbweM2Ref_prev_fx = icbweM2Ref_fx; + move16(); + + return; +} +#endif + +/*-------------------------------------------------------------------* + * stereo_icBWE_decproc() + * + * Stereo (inter-channel) BWE mapping - decoder initialization + *-------------------------------------------------------------------*/ + +#ifndef IVAS_FLOAT_FIXED +void stereo_icBWE_decproc( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + float *output[CPE_CHANNELS], /* i/o: output synthesis */ + float outputHB[CPE_CHANNELS][L_FRAME48k], /* i : HB synthesis */ + const int16_t last_core, /* i : last core, primary channel */ + const int16_t last_bwidth, /* i : last bandwidth */ + const int16_t output_frame /* i : frame length */ +) +{ + int16_t i, j, n, decoderDelay, icbweOLASize, dftOvlLen; + int16_t core, memOffset, refChanIndx_bwe; + float temp0[L_FRAME48k + NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS )], temp1[L_FRAME48k + NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS )]; + float winSlope, alpha; + const float *win_dft; + int32_t extl_brate, output_Fs; + + STEREO_ICBWE_DEC_HANDLE hStereoICBWE = hCPE->hStereoICBWE; + + + /*--------------------------------------------------------------------* + * skip IC-BWE in case of SID or NO_DATA frame + * -------------------------------------------------------------------*/ + + if ( ( hCPE->element_mode == IVAS_CPE_TD || hCPE->element_mode == IVAS_CPE_DFT ) && hCPE->nchan_out == 2 /*&& hCPE->hCoreCoder[0]->core_brate > SID_2k40*/ && hCPE->hCoreCoder[0]->last_core_brate <= SID_2k40 ) + { + stereo_icBWE_init_dec( hCPE->hStereoICBWE ); + } + + if ( hCPE->hCoreCoder[0]->core_brate <= SID_2k40 ) + { + return; + } + + /*--------------------------------------------------------------------* + * skip IC-BWE in case of mono DMX output * + * -------------------------------------------------------------------*/ + + if ( hCPE->nchan_out == 1 && hCPE->element_mode == IVAS_CPE_DFT ) + { + add_HB_to_mono_dmx( hCPE, output[0], outputHB[0], last_core, output_frame ); + + return; + } + else if ( hCPE->nchan_out == 1 && hCPE->element_mode != IVAS_CPE_TD ) + { + return; + } + + /*--------------------------------------------------------------------* + * IC-BWE processing + * -------------------------------------------------------------------*/ + + core = hCPE->hCoreCoder[0]->core; + extl_brate = hCPE->hCoreCoder[0]->extl_brate; + output_Fs = hCPE->hCoreCoder[0]->output_Fs; + + memOffset = NS2SA( output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ); + + /* LRTD stereo mode - 2xBWEs used */ + if ( hCPE->element_mode == IVAS_CPE_TD && hCPE->hCoreCoder[0]->tdm_LRTD_flag ) + { + /* delay HB synth */ + for ( n = 0; n < CPE_CHANNELS; n++ ) + { + mvr2r( outputHB[n] + output_frame - memOffset, temp0, memOffset ); + mvr2r( outputHB[n], outputHB[n] + memOffset, output_frame - memOffset ); + mvr2r( hCPE->prev_hb_synth[n], outputHB[n], memOffset ); + mvr2r( temp0, hCPE->prev_hb_synth[n], memOffset ); + } + + if ( hCPE->nchan_out == 1 ) + { + /* stereo to mono downmix */ + for ( i = 0; i < output_frame; i++ ) + { + outputHB[0][i] = ( outputHB[0][i] + outputHB[1][i] ) * 0.5f; + } + v_add( output[0], outputHB[0], output[0], output_frame ); + } + else + { + /* Add the delayed hb_synth component to the delayed ACELP synthesis */ + for ( n = 0; n < CPE_CHANNELS; n++ ) + { + v_add( output[n], outputHB[n], output[n], output_frame ); + } + } + } + else + { + for ( n = 0; n < CPE_CHANNELS; n++ ) + { + set_f( hCPE->prev_hb_synth[n], 0, memOffset ); + } + } + + if ( hCPE->element_mode != IVAS_CPE_MDCT && !( hCPE->element_mode == IVAS_CPE_TD && hCPE->hCoreCoder[0]->tdm_LRTD_flag ) ) + { + if ( hCPE->last_element_mode == IVAS_CPE_MDCT ) + { + set_f( hStereoICBWE->memOutHB[0], 0, memOffset ); + set_f( hStereoICBWE->memOutHB[1], 0, memOffset ); + + set_f( hStereoICBWE->memTransitionHB[0], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + set_f( hStereoICBWE->memTransitionHB[1], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + } + + if ( core == ACELP_CORE && extl_brate > 0 ) + { + refChanIndx_bwe = hStereoICBWE->refChanIndx_bwe; + + if ( hCPE->element_mode == IVAS_CPE_DFT && hCPE->hCoreCoder[0]->bwidth > WB && last_bwidth == WB && hCPE->hCoreCoder[0]->ini_frame > 1 /* counter wass already updated */ ) + { + /* fad-in reference HB signal */ + winSlope = ( memOffset > 0 ) ? ( 1.0f / memOffset ) : 0; + for ( i = 0; i < memOffset; i++ ) + { + outputHB[refChanIndx_bwe][i] *= ( i + 1 ) * winSlope; + } + } + /* Resampled LB and HB offset */ + mvr2r( outputHB[refChanIndx_bwe], temp0 + memOffset, output_frame - memOffset ); + mvr2r( outputHB[!refChanIndx_bwe], temp1 + memOffset, output_frame - memOffset ); + + decoderDelay = NS2SA( output_Fs, IVAS_DEC_DELAY_NS ); + + if ( last_core != ACELP_CORE && hCPE->element_mode == IVAS_CPE_DFT ) + { + /* hb_synth of mid band is faded out in the 1.25 ms prior to DFT analysis and the icbwe is faded in time domain */ + icbweOLASize = NS2SA( output_Fs, STEREO_DFT_DELAY_DEC_BWE_NS ); + + for ( i = 0; i < decoderDelay; i++ ) + { + temp0[i] = 0; + temp1[i] = 0; + } + + assert( icbweOLASize > 0 ); + winSlope = 1.0f / icbweOLASize; + alpha = winSlope; + for ( ; i < decoderDelay + icbweOLASize; i++ ) + { + temp0[i] *= alpha; + temp1[i] *= alpha; + alpha += winSlope; + } + } + else + { + if ( refChanIndx_bwe != hStereoICBWE->prev_refChanIndx_bwe ) + { + winSlope = ( memOffset > 0 ) ? ( 1.0f / memOffset ) : 0; + for ( i = 0; i < memOffset; i++ ) + { + temp0[i] = ( ( i + 1 ) * winSlope ) * hStereoICBWE->memOutHB[refChanIndx_bwe][i] + + ( 1 - ( i + 1 ) * winSlope ) * hStereoICBWE->memOutHB[hStereoICBWE->prev_refChanIndx_bwe][i]; + temp1[i] = ( ( i + 1 ) * winSlope ) * hStereoICBWE->memOutHB[hStereoICBWE->prev_refChanIndx_bwe][i] + + ( 1 - ( i + 1 ) * winSlope ) * hStereoICBWE->memOutHB[refChanIndx_bwe][i]; + } + } + else + { + mvr2r( hStereoICBWE->memOutHB[refChanIndx_bwe], temp0, memOffset ); + mvr2r( hStereoICBWE->memOutHB[!refChanIndx_bwe], temp1, memOffset ); + } + } + + if ( hCPE->nchan_out == 1 ) + { + /* stereo to mono downmix */ + for ( i = 0; i < output_frame; i++ ) + { + temp0[i] = ( temp0[i] + temp1[i] ) * 0.5f; + output[0][i] += temp0[i]; + } + } + else + { + + v_add( temp0, output[0], output[0], output_frame ); + v_add( temp1, output[1], output[1], output_frame ); + } + mvr2r( outputHB[0] + output_frame - memOffset, hStereoICBWE->memOutHB[0], memOffset ); + mvr2r( outputHB[1] + output_frame - memOffset, hStereoICBWE->memOutHB[1], memOffset ); + + if ( hCPE->element_mode == IVAS_CPE_DFT ) + { + win_dft = hCPE->hStereoDft->win32ms; + dftOvlLen = hCPE->hStereoDft->dft32ms_ovl; + + /* Preparing buffers in anticipation of an ACELP to TCX switch */ + j = 0; + for ( i = 0; i < memOffset; i++ ) + { + hStereoICBWE->memTransitionHB[0][i] = hStereoICBWE->memOutHB[0][i] * win_dft[STEREO_DFT32MS_STEP * ( dftOvlLen - 1 - j )]; + hStereoICBWE->memTransitionHB[1][i] = hStereoICBWE->memOutHB[1][i] * win_dft[STEREO_DFT32MS_STEP * ( dftOvlLen - 1 - j )]; + j++; + } + + for ( i = 0; j < dftOvlLen; i++ ) + { + hStereoICBWE->memTransitionHB[0][memOffset + i] = outputHB[0][output_frame - i - 1] * win_dft[STEREO_DFT32MS_STEP * ( dftOvlLen - 1 - j )]; + hStereoICBWE->memTransitionHB[1][memOffset + i] = outputHB[1][output_frame - i - 1] * win_dft[STEREO_DFT32MS_STEP * ( dftOvlLen - 1 - j )]; + j++; + } + } + + hStereoICBWE->prev_refChanIndx_bwe = refChanIndx_bwe; + } + else + { + if ( last_core == ACELP_CORE ) + { + if ( hCPE->element_mode == IVAS_CPE_TD ) + { + v_add( output[0], hStereoICBWE->memOutHB[hStereoICBWE->prev_refChanIndx_bwe], output[0], memOffset ); + v_add( output[1], hStereoICBWE->memOutHB[!hStereoICBWE->prev_refChanIndx_bwe], output[1], memOffset ); + } + else + { + /* This is generated in the ACELP frame and windowed. This process is akin to GenTransition for IC-BWE */ + v_add( output[0], hStereoICBWE->memTransitionHB[hStereoICBWE->prev_refChanIndx_bwe], output[0], NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + v_add( output[1], hStereoICBWE->memTransitionHB[!hStereoICBWE->prev_refChanIndx_bwe], output[1], NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + } + + set_f( hStereoICBWE->memOutHB[0], 0, memOffset ); + set_f( hStereoICBWE->memOutHB[1], 0, memOffset ); + + set_f( hStereoICBWE->memTransitionHB[0], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + set_f( hStereoICBWE->memTransitionHB[1], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + } + } + } + else if ( hCPE->element_mode == IVAS_CPE_TD && hCPE->hCoreCoder[0]->tdm_LRTD_flag && hStereoICBWE != NULL ) + { + stereo_icBWE_init_dec( hCPE->hStereoICBWE ); + } + else if ( hCPE->element_mode == IVAS_CPE_MDCT && hCPE->last_element_mode == IVAS_CPE_DFT && last_core == ACELP_CORE ) + { + int16_t delay_tdbwe = NS2SA( output_Fs, DELAY_BWE_TOTAL_NS ); + + for ( n = 0; n < hCPE->nchan_out; n++ ) + { + for ( i = 0; i < delay_tdbwe; i++ ) + { + output[n][NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe + i] += outputHB[0][i]; + } + } + /* reset BWE structs as they are only needed in the transition frame in MDCT Stereo */ + td_bwe_dec_init( hCPE->hCoreCoder[0]->hBWE_TD, -1, output_Fs ); + + fd_bwe_dec_init_flt( hCPE->hCoreCoder[0]->hBWE_FD ); + } + + if ( hCPE->element_mode == IVAS_CPE_DFT && ( max( hCPE->hStereoDft->td_gain[0], hCPE->hStereoDft->td_gain[1] ) > 0 ) ) + { + float win_in, win_out, tmp; + + win_dft = hCPE->hStereoDft->win32ms; + dftOvlLen = hCPE->hStereoDft->dft32ms_ovl; + + for ( i = 0; i < dftOvlLen; i++ ) + { + win_in = win_dft[STEREO_DFT32MS_STEP * i] * win_dft[STEREO_DFT32MS_STEP * i]; + win_out = 1 - win_in; + tmp = ( win_in * hCPE->hStereoDft->td_gain[0] + win_out * hCPE->hStereoDft->td_gain[1] ) * hCPE->hStereoDft->hb_stefi_sig[i]; + + output[0][i] += tmp; + output[1][i] -= tmp; + } + for ( i = dftOvlLen; i < output_frame; i++ ) + { + tmp = hCPE->hStereoDft->td_gain[0] * hCPE->hStereoDft->hb_stefi_sig[i]; + output[0][i] += tmp; + output[1][i] -= tmp; + } + } + + return; +} +#else +void stereo_icBWE_decproc_fx( + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + Word32 *output[CPE_CHANNELS], /* i/o: output synthesis */ + Word32 outputHB[CPE_CHANNELS][L_FRAME48k], /* i : HB synthesis */ + const Word16 last_core, /* i : last core, primary channel */ + const Word16 last_bwidth, /* i : last bandwidth */ + const Word16 output_frame, /* i : frame length */ + Word16 q_output /* i : Q-fac of output */ +) +{ + Word16 i, j, n, decoderDelay, icbweOLASize, dftOvlLen; + Word16 core, memOffset, refChanIndx_bwe; + + Word32 temp0_fx[L_FRAME48k + NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS )], temp1_fx[L_FRAME48k + NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS )]; + Word32 winSlope_fx = 0, alpha_fx; + const Word16 *win_dft_fx; + Word32 extl_brate, output_Fs; + + STEREO_ICBWE_DEC_HANDLE hStereoICBWE = hCPE->hStereoICBWE; + + /*--------------------------------------------------------------------* + * skip IC-BWE in case of SID or NO_DATA frame + * -------------------------------------------------------------------*/ + + test(); + test(); + test(); + IF( ( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) || EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) && EQ_16( hCPE->nchan_out, 2 ) /*&& hCPE->hCoreCoder[0]->core_brate > SID_2k40*/ && LE_32( hCPE->hCoreCoder[0]->last_core_brate, SID_2k40 ) ) + { + stereo_icBWE_init_dec_fx( hCPE->hStereoICBWE ); + } + + IF( LE_32( hCPE->hCoreCoder[0]->core_brate, SID_2k40 ) ) + { + return; + } + + /*--------------------------------------------------------------------* + * skip IC-BWE in case of mono DMX output * + * -------------------------------------------------------------------*/ + + test(); + test(); + IF( EQ_16( hCPE->nchan_out, 1 ) && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) + { + add_HB_to_mono_dmx_fx( hCPE, output[0], outputHB[0], last_core, output_frame ); + return; + } + ELSE IF( EQ_16( hCPE->nchan_out, 1 ) && NE_16( hCPE->element_mode, IVAS_CPE_TD ) ) + { + return; + } + + /*--------------------------------------------------------------------* + * IC-BWE processing + * -------------------------------------------------------------------*/ + + core = hCPE->hCoreCoder[0]->core; + move16(); + extl_brate = hCPE->hCoreCoder[0]->extl_brate; + move32(); + output_Fs = hCPE->hCoreCoder[0]->output_Fs; + move32(); + + memOffset = NS2SA( output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ); + + /* LRTD stereo mode - 2xBWEs used */ + test(); + IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) && hCPE->hCoreCoder[0]->tdm_LRTD_flag ) + { + /* delay HB synth */ + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + Copy32( outputHB[n] + output_frame - memOffset, temp0_fx, memOffset ); + Copy32( outputHB[n], outputHB[n] + memOffset, output_frame - memOffset ); + Copy32( hCPE->prev_hb_synth_fx[n], outputHB[n], memOffset ); + Copy32( temp0_fx, hCPE->prev_hb_synth_fx[n], memOffset ); + } + + IF( EQ_16( hCPE->nchan_out, 1 ) ) + { + /* stereo to mono downmix */ + FOR( i = 0; i < output_frame; i++ ) + { + outputHB[0][i] = L_shr( ( outputHB[0][i] + outputHB[1][i] ), 1 ); + move32(); + } + v_add_32( output[0], outputHB[0], output[0], output_frame ); + } + ELSE + { + /* Add the delayed hb_synth component to the delayed ACELP synthesis */ + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + v_add_32( output[n], outputHB[n], output[n], output_frame ); + } + } + } + ELSE + { + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + set32_fx( hCPE->prev_hb_synth_fx[n], 0, memOffset ); + } + } + + test(); + test(); + test(); + test(); + test(); + test(); + IF( NE_16( hCPE->element_mode, IVAS_CPE_MDCT ) && !( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) && hCPE->hCoreCoder[0]->tdm_LRTD_flag ) ) + { + IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_MDCT ) ) + { + set32_fx( hStereoICBWE->memOutHB_fx[0], 0, memOffset ); + set32_fx( hStereoICBWE->memOutHB_fx[1], 0, memOffset ); + + set32_fx( hStereoICBWE->memTransitionHB_fx[0], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + set32_fx( hStereoICBWE->memTransitionHB_fx[1], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + } + + test(); + IF( EQ_16( core, ACELP_CORE ) && GT_32( extl_brate, 0 ) ) + { + refChanIndx_bwe = hStereoICBWE->refChanIndx_bwe; + move16(); + + test(); + test(); + test(); + IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && GT_16( hCPE->hCoreCoder[0]->bwidth, WB ) && EQ_16( last_bwidth, WB ) && GT_16( hCPE->hCoreCoder[0]->ini_frame, 1 ) /* counter wass already updated */ ) + { + /* fad-in reference HB signal */ + IF( GT_16( memOffset, 0 ) ) + { + SWITCH( memOffset ) + { + case 15: + winSlope_fx = 71582792; + move32(); + BREAK; + case 30: + winSlope_fx = 35791396; + move32(); + BREAK; + case 45: + winSlope_fx = 23860930; + move32(); + BREAK; + } + // memOffset for 16K 32K 48K are 15 30 45 respectively.camera + } + ELSE + { + winSlope_fx = 0; + move32(); + } + FOR( i = 0; i < memOffset; i++ ) + { + Word32 mul_win = Mpy_32_16_1( winSlope_fx, ( i + 1 ) ); // Q30 + Q0 - 15 = Q15 + mul_win = L_shl( mul_win, 15 ); // Q30 + outputHB[refChanIndx_bwe][i] = L_shl( Mpy_32_32( outputHB[refChanIndx_bwe][i] /* Q11 + Q30 - 31 = Q10)*/, mul_win ), 1 ); // + move32(); + } + } + /* Resampled LB and HB offset */ + Copy32( outputHB[refChanIndx_bwe], temp0_fx + memOffset, output_frame - memOffset ); + Copy32( outputHB[!refChanIndx_bwe], temp1_fx + memOffset, output_frame - memOffset ); + + decoderDelay = NS2SA( output_Fs, IVAS_DEC_DELAY_NS ); + + test(); + IF( NE_16( last_core, ACELP_CORE ) && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) + { + /* hb_synth of mid band is faded out in the 1.25 ms prior to DFT analysis and the icbwe is faded in time domain */ + icbweOLASize = NS2SA( output_Fs, STEREO_DFT_DELAY_DEC_BWE_NS ); + + FOR( i = 0; i < decoderDelay; i++ ) + { + temp0_fx[i] = 0; + move32(); + temp1_fx[i] = 0; + move32(); + } + + assert( icbweOLASize > 0 ); + SWITCH( icbweOLASize ) + { + case 60: + winSlope_fx = 17895698; + move32(); + BREAK; + case 40: + winSlope_fx = 26843546; + move32(); + BREAK; + case 20: + winSlope_fx = 53687092; + move32(); + BREAK; + } + alpha_fx = winSlope_fx; // Q30 + move32(); + FOR( ; i < decoderDelay + icbweOLASize; i++ ) + { + temp0_fx[i] = L_shl_sat( Mpy_32_32( temp0_fx[i], alpha_fx ), 1 ); // Q11 + move32(); + temp1_fx[i] = L_shl_sat( Mpy_32_32( temp1_fx[i], alpha_fx ), 1 ); + move32(); + alpha_fx = L_add( alpha_fx, winSlope_fx ); + } + } + ELSE + { + IF( NE_16( refChanIndx_bwe, hStereoICBWE->prev_refChanIndx_bwe ) ) + { + IF( GT_16( memOffset, 0 ) ) + { + SWITCH( memOffset ) + { + case 15: + winSlope_fx = 71582792; + BREAK; + case 30: + winSlope_fx = 35791396; + BREAK; + case 45: + winSlope_fx = 23860930; // Q30 + BREAK; + } + // memOffset for 16K 32K 48K are 15 30 45 respectively.camera + } + ELSE + { + winSlope_fx = 0; + move32(); + } + FOR( i = 0; i < memOffset; i++ ) + { + temp0_fx[i] = L_add( L_shl( Mpy_32_32( Mpy_32_16_1( winSlope_fx, ( i + 1 ) ), hStereoICBWE->memOutHB_fx[refChanIndx_bwe][i] ), 16 ), + L_shl( Mpy_32_32( Mpy_32_16_1( winSlope_fx, 1 - ( i + 1 ) ), hStereoICBWE->memOutHB_fx[hStereoICBWE->prev_refChanIndx_bwe][i] ), 16 ) ); + move32(); + + temp1_fx[i] = L_add( L_shl( Mpy_32_32( Mpy_32_16_1( winSlope_fx, ( i + 1 ) ), hStereoICBWE->memOutHB_fx[hStereoICBWE->prev_refChanIndx_bwe][i] ), 16 ), + L_shl( Mpy_32_32( Mpy_32_16_1( winSlope_fx, ( 1 - ( i + 1 ) ) ), hStereoICBWE->memOutHB_fx[refChanIndx_bwe][i] ), 16 ) ); + move32(); + } + } + ELSE + { + Copy32( hStereoICBWE->memOutHB_fx[refChanIndx_bwe], temp0_fx, memOffset ); + Copy32( hStereoICBWE->memOutHB_fx[!refChanIndx_bwe], temp1_fx, memOffset ); + } + } + + IF( EQ_16( hCPE->nchan_out, 1 ) ) + { + /* stereo to mono downmix */ + FOR( i = 0; i < output_frame; i++ ) + { + temp0_fx[i] = L_add( temp0_fx[i], temp1_fx[i] ); + move32(); + temp0_fx[i] = L_shr( temp0_fx[i], 1 ); + move32(); + output[0][i] = L_add( output[0][i], temp0_fx[i] ); + move32(); + } + } + ELSE + { + v_add_32( temp0_fx, output[0], output[0], output_frame ); + v_add_32( temp1_fx, output[1], output[1], output_frame ); + } + + Copy32( outputHB[0] + output_frame - memOffset, hStereoICBWE->memOutHB_fx[0], memOffset ); + Copy32( outputHB[1] + output_frame - memOffset, hStereoICBWE->memOutHB_fx[1], memOffset ); + + IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) + { + /*win_dft = hCPE->hStereoDft->win32ms;*/ + win_dft_fx = hCPE->hStereoDft->win32ms_fx; + dftOvlLen = hCPE->hStereoDft->dft32ms_ovl; + move16(); + + /* Preparing buffers in anticipation of an ACELP to TCX switch */ + j = 0; + move16(); + FOR( i = 0; i < memOffset; i++ ) + { + Word16 tmp_mul = mult0( STEREO_DFT32MS_STEP, ( sub( dftOvlLen, add( 1, j ) ) ) ); + hStereoICBWE->memTransitionHB_fx[0][i] = Mpy_32_16_1( hStereoICBWE->memOutHB_fx[0][i], win_dft_fx[tmp_mul] ); + move32(); + hStereoICBWE->memTransitionHB_fx[1][i] = Mpy_32_16_1( hStereoICBWE->memOutHB_fx[1][i], win_dft_fx[tmp_mul] ); + move32(); + j++; + } + + FOR( i = 0; j < dftOvlLen; i++ ) + { + Word16 tmp_mul = mult0( STEREO_DFT32MS_STEP, ( sub( dftOvlLen, add( 1, j ) ) ) ); + hStereoICBWE->memTransitionHB_fx[0][memOffset + i] = Mpy_32_16_1( outputHB[0][output_frame - i - 1], win_dft_fx[tmp_mul] ); + move32(); + hStereoICBWE->memTransitionHB_fx[1][memOffset + i] = Mpy_32_16_1( outputHB[1][output_frame - i - 1], win_dft_fx[tmp_mul] ); + move32(); + j++; + } + } + + hStereoICBWE->prev_refChanIndx_bwe = refChanIndx_bwe; + move16(); + } + ELSE + { + IF( EQ_16( last_core, ACELP_CORE ) ) + { + IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) ) + { + v_add_32( output[0], hStereoICBWE->memOutHB_fx[hStereoICBWE->prev_refChanIndx_bwe], output[0], memOffset ); + v_add_32( output[1], hStereoICBWE->memOutHB_fx[!hStereoICBWE->prev_refChanIndx_bwe], output[1], memOffset ); + } + ELSE + { + /* This is generated in the ACELP frame and windowed. This process is akin to GenTransition for IC-BWE */ + v_add_32( output[0], hStereoICBWE->memTransitionHB_fx[hStereoICBWE->prev_refChanIndx_bwe], output[0], NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + v_add_32( output[1], hStereoICBWE->memTransitionHB_fx[!hStereoICBWE->prev_refChanIndx_bwe], output[1], NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + } + + set32_fx( hStereoICBWE->memOutHB_fx[0], 0, memOffset ); + set32_fx( hStereoICBWE->memOutHB_fx[1], 0, memOffset ); + + set32_fx( hStereoICBWE->memTransitionHB_fx[0], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + set32_fx( hStereoICBWE->memTransitionHB_fx[1], 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ); + } + } + } + ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) && hCPE->hCoreCoder[0]->tdm_LRTD_flag && hStereoICBWE != NULL ) + { + stereo_icBWE_init_dec_fx( hCPE->hStereoICBWE ); + } + ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) && EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) && EQ_16( last_core, ACELP_CORE ) ) + { + Word16 delay_tdbwe = NS2SA( output_Fs, DELAY_BWE_TOTAL_NS ); + + FOR( n = 0; n < hCPE->nchan_out; n++ ) + { + FOR( i = 0; i < delay_tdbwe; i++ ) + { + output[n][NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe + i] = L_add_sat( output[n][NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) - delay_tdbwe + i], outputHB[0][i] ); + move32(); + } + } + /* reset BWE structs as they are only needed in the transition frame in MDCT Stereo */ + td_bwe_dec_init_ivas_fx( hCPE->hCoreCoder[0], hCPE->hCoreCoder[0]->hBWE_TD, output_Fs ); + fd_bwe_dec_init( hCPE->hCoreCoder[0], hCPE->hCoreCoder[0]->hBWE_FD ); + } + + test(); + IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && GT_32( L_max( hCPE->hStereoDft->td_gain_fx[0], hCPE->hStereoDft->td_gain_fx[1] ), 0 ) ) + { + Word32 win_in_fx, win_out_fx, tmp_fx, gain0_fx, gain1_fx; + + win_dft_fx = hCPE->hStereoDft->win32ms_fx; + dftOvlLen = hCPE->hStereoDft->dft32ms_ovl; + move16(); + + //Scale_sig32(hCPE->hStereoDft->td_gain_fx, STEREO_DFT_CORE_HIST_MAX, -12); + + FOR( i = 0; i < dftOvlLen; i++ ) + { + win_in_fx = L_mult( win_dft_fx[mult0( STEREO_DFT32MS_STEP, i )], win_dft_fx[mult0( STEREO_DFT32MS_STEP, i )] ); /* Q31 */ + win_out_fx = L_sub( ONE_IN_Q31, win_in_fx ); /* Q31 */ + + gain0_fx = Mpy_32_32( win_in_fx, hCPE->hStereoDft->td_gain_fx[0] ); /* Q --> q_td_gain[0] */ +#ifdef FIX_736_BWE_SECT_C + gain0_fx = (Word32) W_shr( ( (Word64) gain0_fx * hCPE->hStereoDft->hb_stefi_sig_fx[i] ), sub( add( (Word16) hCPE->hStereoDft->q_td_gain[0], hCPE->hStereoDft->q_hb_stefi_sig_fx ), 2 * q_output + 14 ) ); /* Q --> q_output */ + gain1_fx = Mpy_32_32( win_out_fx, hCPE->hStereoDft->td_gain_fx[1] ); /* Q --> q_td_gain[1] */ + gain1_fx = (Word32) W_shr( ( (Word64) gain1_fx * hCPE->hStereoDft->hb_stefi_sig_fx[i] ), sub( add( (Word16) hCPE->hStereoDft->q_td_gain[1], hCPE->hStereoDft->q_hb_stefi_sig_fx ), 2 * q_output + 14 ) ); /* Q --> q_output */ +#else + gain0_fx = (Word32) W_shr( ( (Word64) gain0_fx * hCPE->hStereoDft->hb_stefi_sig_fx[i] ), sub( add( (Word16) hCPE->hStereoDft->q_td_gain[0], hCPE->hStereoDft->q_hb_stefi_sig_fx ), q_output ) ); /* Q --> q_output */ + gain1_fx = Mpy_32_32( win_out_fx, hCPE->hStereoDft->td_gain_fx[1] ); /* Q --> q_td_gain[1] */ + gain1_fx = (Word32) W_shr( ( (Word64) gain1_fx * hCPE->hStereoDft->hb_stefi_sig_fx[i] ), sub( add( (Word16) hCPE->hStereoDft->q_td_gain[1], hCPE->hStereoDft->q_hb_stefi_sig_fx ), q_output ) ); /* Q --> q_output */ +#endif + tmp_fx = L_add_sat( gain0_fx, gain1_fx ); /* Q --> q_output */ + + output[0][i] = L_add_sat( output[0][i], tmp_fx ); + move32(); + output[1][i] = L_sub_sat( output[1][i], tmp_fx ); + move32(); + } + FOR( i = dftOvlLen; i < output_frame; i++ ) + { +#ifdef FIX_736_BWE_SECT_C + tmp_fx = (Word32) W_shr( ( (Word64) hCPE->hStereoDft->td_gain_fx[0] * hCPE->hStereoDft->hb_stefi_sig_fx[i] ), sub( add( (Word16) hCPE->hStereoDft->q_td_gain[0], hCPE->hStereoDft->q_hb_stefi_sig_fx ), 2 * q_output + 14 ) ); /* Q --> q_output */ +#else + tmp_fx = (Word32) W_shr( ( (Word64) hCPE->hStereoDft->td_gain_fx[0] * hCPE->hStereoDft->hb_stefi_sig_fx[i] ), sub( add( (Word16) hCPE->hStereoDft->q_td_gain[0], hCPE->hStereoDft->q_hb_stefi_sig_fx ), q_output ) ); /* Q --> q_output */ +#endif + output[0][i] = L_add_sat( output[0][i], tmp_fx ); + move32(); + output[1][i] = L_sub_sat( output[1][i], tmp_fx ); + move32(); + } + } + + return; +} +#endif + +/*-------------------------------------------------------------------* + * stereo_icBWE_init_dec() + * + * Stereo (inter-channel) BWE mapping - decoder initialization + *-------------------------------------------------------------------*/ + +#ifndef IVAS_FLOAT_FIXED +void stereo_icBWE_init_dec( + STEREO_ICBWE_DEC_HANDLE hStereoICBWE /* i/o: Stereo inter-channel BWE handle */ +) +{ + /* BWE ref channel */ + hStereoICBWE->refChanIndx_bwe = L_CH_INDX; + hStereoICBWE->prev_refChanIndx_bwe = L_CH_INDX; + + /* SHB output memory */ + set_f( hStereoICBWE->memOutHB[0], 0, NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ) ); + set_f( hStereoICBWE->memOutHB[1], 0, NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ) ); + + + /* SHB output memory */ + set_f( hStereoICBWE->memTransitionHB[0], 0, NS2SA( 48000, STEREO_DFT32MS_OVL_NS ) ); + set_f( hStereoICBWE->memTransitionHB[1], 0, NS2SA( 48000, STEREO_DFT32MS_OVL_NS ) ); + + /* inter-channel BWE spectral shape adj. */ + hStereoICBWE->prevSpecMapping = 0; + hStereoICBWE->prevgsMapping = 1.0f; + + hStereoICBWE->icbweM2Ref_prev = 1.0f; + + hStereoICBWE->prev_spIndx = 0; + hStereoICBWE->prev_gsIndx = 0; + + ic_bwe_dec_reset( hStereoICBWE ); + return; +} +#else +void stereo_icBWE_init_dec_fx( + STEREO_ICBWE_DEC_HANDLE hStereoICBWE /* i/o: Stereo inter-channel BWE handle */ +) +{ + /* BWE ref channel */ + hStereoICBWE->refChanIndx_bwe = L_CH_INDX; + move16(); + hStereoICBWE->prev_refChanIndx_bwe = L_CH_INDX; + move16(); + + /* SHB output memory */ + set32_fx( hStereoICBWE->memOutHB_fx[0], 0, NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ) ); + set32_fx( hStereoICBWE->memOutHB_fx[1], 0, NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS ) ); + + + /* SHB output memory */ + set32_fx( hStereoICBWE->memTransitionHB_fx[0], 0, NS2SA( 48000, STEREO_DFT32MS_OVL_NS ) ); + set32_fx( hStereoICBWE->memTransitionHB_fx[1], 0, NS2SA( 48000, STEREO_DFT32MS_OVL_NS ) ); + + /* inter-channel BWE spectral shape adj. */ + hStereoICBWE->prevSpecMapping_fx = 0; + move16(); + hStereoICBWE->prevgsMapping_fx = 16384; + move16(); + hStereoICBWE->icbweM2Ref_prev_fx = 16384; + move16(); + + hStereoICBWE->prev_spIndx = 0; + move16(); + hStereoICBWE->prev_gsIndx = 0; + move16(); + + ic_bwe_dec_reset_fx( hStereoICBWE ); + + return; +} #endif \ No newline at end of file diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 26bbeede5..1d745cfb7 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -525,7 +525,7 @@ static Word32 *getSmplPtr_fx( { return buffer.data_fx + chnlIdx * buffer.config.numSamplesPerChannel + smplIdx; } -#endif +#else static float *getSmplPtr( IVAS_REND_AudioBuffer buffer, const uint32_t chnlIdx, @@ -533,6 +533,7 @@ static float *getSmplPtr( { return buffer.data + chnlIdx * buffer.config.numSamplesPerChannel + smplIdx; } +#endif #ifdef IVAS_FLOAT_FIXED static void copyBufferTo2dArray_fx( const IVAS_REND_AudioBuffer buffer, @@ -1980,6 +1981,7 @@ static void closeHeadRotation( } #endif +#ifndef IVAS_FLOAT_FIXED static void initRotMatrix( rotation_matrix rot_mat ) { @@ -1994,6 +1996,7 @@ static void initRotMatrix( return; } +#endif #ifdef IVAS_FLOAT_FIXED @@ -7744,6 +7747,7 @@ ivas_error IVAS_REND_GetCombinedOrientation( This function takes 2 gain vectors - one for the beginning and one for the end of the buffer. Gain values are lineraly interpolated for all samples in between. */ +#ifndef IVAS_FLOAT_FIXED static void renderBufferChannelLerp( const IVAS_REND_AudioBuffer inAudio, const int32_t inChannelIdx, @@ -7810,6 +7814,7 @@ static void renderBufferChannelLerp( return; } +#endif #ifdef IVAS_FLOAT_FIXED /* Take one channel from input buffer and copy it to each channel in output buffer, with different gain applied per output channel. @@ -8705,19 +8710,15 @@ static ivas_error renderIsmToBinauralRoom( Copy32( currentPanGains, ismInput->prev_pan_gains_fx, MAX_OUTPUT_CHANNELS ); } // Crend_process porting - Word16 nchan_in = 12, subframe_len; move16(); CREND_HANDLE hCrend; hCrend = ismInput->crendWrapper->hCrend; - subframe_len = (Word16) ( *ismInput->base.ctx.pOutSampleRate / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ); move16(); - Word16 nchan = nchan_in; move16(); IF( hCrend->reflections != NULL ) { IF( hCrend->reflections->use_er == 1 && hCrend->reflections->is_ready == 1 ) { - nchan = add( hCrend->reflections->shoebox_data.n_sources, 1 ); FOR( i = 0; i < 150; i++ ) { hCrend->reflections->shoebox_data.gains.data_fx[i] = L_shl( hCrend->reflections->shoebox_data.gains.data_fx[i], 9 ); @@ -8725,7 +8726,6 @@ static ivas_error renderIsmToBinauralRoom( } } - nchan = nchan_in; move16(); /* render 7_1_4 with BRIRs */ -- GitLab From 827a6910ef6c91f798a9b75cf67d8c264aa27fb3 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 16 May 2024 20:06:48 +0530 Subject: [PATCH 2/3] EVS bitexactness preserving change --- lib_dec/hf_synth_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/hf_synth_fx.c b/lib_dec/hf_synth_fx.c index 4cb4399d5..f2eea7d24 100644 --- a/lib_dec/hf_synth_fx.c +++ b/lib_dec/hf_synth_fx.c @@ -56,7 +56,7 @@ void hf_synth_init_fx( hBWE_zero->seed2 = RANDOM_INITSEED; set16_fx(hBWE_zero->mem_hf_fx, 0, (L_FIR - 1)); set16_fx(hBWE_zero->mem_syn_hf_fx, 0, M); -#ifdef MSAN_FIX +#ifndef MSAN_FIX // Disabled to maintain EVS Bit-exactness set16_fx(hBWE_zero->mem_hp400_fx, 0, 6); #else set16_fx(hBWE_zero->mem_hp400_fx, 0, 4); -- GitLab From d59eab386cf26c29ab573a7ee4287a38ca9dee07 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 16 May 2024 21:16:47 +0530 Subject: [PATCH 3/3] EVS bitexactness fix --- lib_dec/hf_synth_fx.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lib_dec/hf_synth_fx.c b/lib_dec/hf_synth_fx.c index f2eea7d24..e10145bfd 100644 --- a/lib_dec/hf_synth_fx.c +++ b/lib_dec/hf_synth_fx.c @@ -56,11 +56,7 @@ void hf_synth_init_fx( hBWE_zero->seed2 = RANDOM_INITSEED; set16_fx(hBWE_zero->mem_hf_fx, 0, (L_FIR - 1)); set16_fx(hBWE_zero->mem_syn_hf_fx, 0, M); -#ifndef MSAN_FIX // Disabled to maintain EVS Bit-exactness - set16_fx(hBWE_zero->mem_hp400_fx, 0, 6); -#else set16_fx(hBWE_zero->mem_hp400_fx, 0, 4); -#endif // MSAN_FIX set16_fx(hBWE_zero->delay_syn_hf_fx, 0, NS2SA(16000, DELAY_CLDFB_NS)); set16_fx(hBWE_zero->mem_hp_interp_fx, 0, INTERP_3_1_MEM_LEN); @@ -79,11 +75,7 @@ void hf_synth_reset_fx( set16_fx(hBWE_zero->mem_hf_fx, 0, (L_FIR - 1)); set16_fx(hBWE_zero->mem_syn_hf_fx, 0, M); -#ifdef MSAN_FIX - set16_fx(hBWE_zero->mem_hp400_fx, 0, 6); -#else set16_fx(hBWE_zero->mem_hp400_fx, 0, 4); -#endif set16_fx(hBWE_zero->delay_syn_hf_fx, 0, NS2SA(16000, DELAY_CLDFB_NS)); set16_fx(hBWE_zero->mem_hp_interp_fx, 0, INTERP_3_1_MEM_LEN); -- GitLab