diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 07d63e7c4ec93c4083716cb643023e628766db68..4cde97344461936ff7bd58ee2bea1d17a0288397 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -776,12 +776,15 @@ void destroy_cpe_dec( ); ivas_error ivas_cpe_dec_fx( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const Word16 cpe_id, /* i : CPE # identifier */ - Word32 *output[CPE_CHANNELS], /* o : output synthesis signal */ - const Word16 output_frame, /* i : output frame length per channel */ - const Word16 nb_bits_metadata, /* i : number of metadata bits */ - Word16 *q_output /* i/o : Q of output synthesis signal */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const Word16 cpe_id, /* i : CPE # identifier */ + Word32 *output[CPE_CHANNELS], /* o : output synthesis signal */ + const Word16 output_frame, /* i : output frame length per channel */ + const Word16 nb_bits_metadata /* i : number of metadata bits */ +#ifndef FIX_826_PRECISION_LOST_AND_COMPL + , + Word16 *q_output /* i/o : Q of output synthesis signal */ +#endif ); void ivas_post_proc_fx( @@ -1326,8 +1329,11 @@ void stereo_icBWE_decproc_fx( 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 */ + const Word16 output_frame /* i : frame length */ +#ifndef FIX_826_PRECISION_LOST_AND_COMPL + , + Word16 q_output /* i : Q-fac of output */ +#endif ); void add_HB_to_mono_dmx_fx( diff --git a/lib_com/options.h b/lib_com/options.h index fdd0757d33b150df9e0b2d8f23fa3ccfd486bc2d..b27eb7ad7e113cebb76ab79accd330856a1926c5 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -151,6 +151,7 @@ #define FIX_802__NON_BE_DECODING /* Fix possible difference float and fixed point when computing the GSC bit allocation */ #define FIX_802_1137_1137_GSC_IVAS_FXFLT_DECODING /* VA: ISSUES 802 and 1137 Made sure that float and fixed point GCS bit allocation is the same during IVAS modes */ #define FIX_810_PREVENT_UNECESSARY_SAT_IN_TC /* VA : Prevent an unnecessary saturation that can happen in TC, have a minimal impact on most cases. Significant improvement for the last segment of LTV when TC is triggered */ +#define FIX_826_PRECISION_LOST_AND_COMPL /* VA : Fix lost of precision that leads to unnecessary high noise floor and to some framing artifacts */ /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index b8fec2d9ed17267f587a2e8dda795a0e7b24e86f..5ed51a26c6429c6b38ef68fe8b66e622682d8ea1 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -1,2344 +1,2354 @@ -/****************************************************************************************************** - - (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 "options.h" -#include -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_prot_fx.h" -#include "ivas_rom_com.h" -#include "wmc_auto.h" -#ifdef IVAS_FLOAT_FIXED -#include "prot_fx.h" -#include "ivas_prot_fx.h" -#endif - -/*-------------------------------------------------------------------* - * ivas_core_dec() - * - * Principal IVAS core decoder routine, where number of core channels is 1 or 2 - *-------------------------------------------------------------------*/ -#ifdef IVAS_FLOAT_FIXED -ivas_error ivas_core_dec_fx( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - SCE_DEC_HANDLE hSCE, /* i/o: SCE decoder structure */ - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */ - const Word16 n_channels, /* i : number of channels to be decoded */ - Word32 *output_32_fx[], /* o : output synthesis signal */ - Word32 hb_synth_32_fx[][L_FRAME48k], /* o : output HB synthesis signal */ - Word32 DFT_fx[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* o : DFT buffers */ - const Word16 sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ -) -{ - Word16 i, n, output_frame; - Decoder_State **sts, *st; - STEREO_ICBWE_DEC_HANDLE hStereoICBWE; - STEREO_TD_DEC_DATA_HANDLE hStereoTD; - Word16 sharpFlag[CPE_CHANNELS]; - Word16 tmp_buffer_fx[L_FRAME48k]; - set16_fx( tmp_buffer_fx, 0, L_FRAME48k ); - Word16 tmp16, tmp16_2, j; - tmp16 = 0; - move16(); - Word16 Q_white_exc; - Q_white_exc = 0; - move16(); - - Word16 tmps, incr; - Word32 bwe_exc_extended_fx[CPE_CHANNELS][L_FRAME32k + NL_BUFF_OFFSET]; - - Word16 voice_factors_fx[CPE_CHANNELS][NB_SUBFR16k]; - Word16 core_switching_flag[CPE_CHANNELS]; - - Word16 pitch_buf_fx[CPE_CHANNELS][NB_SUBFR16k]; - Word32 old_syn_12k8_16k_fx[CPE_CHANNELS][L_FRAME16k]; - - Word16 unbits[CPE_CHANNELS]; - Word16 sid_bw[CPE_CHANNELS]; - FRAME_MODE frameMode[CPE_CHANNELS]; - Word16 tdm_LRTD_flag; - Word32 element_brate, output_Fs; - Word32 last_element_brate; - Word16 use_cldfb_for_dft; - Word32 *p_output_mem_fx; - Word16 flag_sec_CNA; - Word16 read_sid_info; - Word16 last_element_mode; - Word16 nchan_out; - Word32 *save_hb_synth_32_fx; - ivas_error error; - Word32 L_tmp; - Word16 Q_synth; - Word16 output_16_fx[CPE_CHANNELS][L_FRAME48k]; - Word16 hb_synth_16_fx[CPE_CHANNELS][L_FRAME48k]; - - Word16 synth_16_fx[CPE_CHANNELS][L_FRAME48k]; - Word32 synth_32_fx[CPE_CHANNELS][L_FRAME48k]; - - FOR( i = 0; i < CPE_CHANNELS; i++ ) - { - set16_fx( pitch_buf_fx[i], 0, NB_SUBFR16k ); - set16_fx( output_16_fx[i], 0, L_FRAME48k ); - } - - Word16 tdm_lsfQ_PCh_fx[M], tdm_lspQ_PCh_fx[M]; - Word32 conceal_eof_gain32; - -#ifdef BASOP_NOGLOB - Flag Overflow; -#endif - - error = IVAS_ERR_OK; - move32(); - push_wmops( "ivas_core_dec" ); - - /*------------------------------------------------------------------* - * General initialization - *-----------------------------------------------------------------*/ - - use_cldfb_for_dft = 0; - move16(); - tdm_LRTD_flag = -1; - move16(); - read_sid_info = 1; /* read SID by default */ - move16(); - - IF( hSCE != NULL ) - { - sts = hSCE->hCoreCoder; - hStereoICBWE = NULL; - element_brate = hSCE->element_brate; - move32(); - last_element_brate = hSCE->last_element_brate; /* note: this parameter is unused */ - move32(); - last_element_mode = IVAS_SCE; - move16(); - hStereoTD = NULL; - p_output_mem_fx = NULL; - nchan_out = 1; - move16(); - test(); - IF( st_ivas != NULL && EQ_32( st_ivas->ivas_format, ISM_FORMAT ) ) - { - if ( NE_16( st_ivas->hISMDTX.sce_id_dtx, hSCE->sce_id ) ) - { - read_sid_info = 0; - move16(); - } - } - } - ELSE - { - sts = hCPE->hCoreCoder; - element_brate = hCPE->element_brate; - move32(); - last_element_brate = hCPE->last_element_brate; - move32(); - last_element_mode = hCPE->last_element_mode; - move16(); - hStereoICBWE = hCPE->hStereoICBWE; - hStereoTD = hCPE->hStereoTD; - p_output_mem_fx = hCPE->output_mem_fx[1]; - - nchan_out = hCPE->nchan_out; - move16(); - - if ( hCPE->hStereoTD != NULL ) - { - tdm_LRTD_flag = hCPE->hCoreCoder[0]->tdm_LRTD_flag; - move16(); - } - - IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) ) - { - test(); - IF( EQ_16( hCPE->nchan_out, 1 ) && EQ_16( hCPE->hStereoDft->hConfig->res_cod_mode, STEREO_DFT_RES_COD_OFF ) ) - { - use_cldfb_for_dft = 1; - move16(); - } - ELSE - { - use_cldfb_for_dft = 0; - move16(); - } - } - } - - FOR( n = 0; n < n_channels; n++ ) - { - st = sts[n]; - IF( st->cldfbAna ) - { - scale_sig32( st->cldfbAna->cldfb_state_fx, st->cldfbAna->cldfb_size, sub( Q10, Q11 ) ); - st->cldfbAna->Q_cldfb_state = Q10; - move16(); - } - IF( st->cldfbSynHB ) - { - scale_sig32( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->cldfb_size, sub( Q10, Q11 ) ); - st->cldfbSynHB->Q_cldfb_state = Q10; - move16(); - } - } - - output_Fs = sts[0]->output_Fs; - move32(); - output_frame = extract_l( Mpy_32_16_1( output_Fs, INV_FRAME_PER_SEC_Q15 ) ); - - FOR( n = 0; n < n_channels; n++ ) - { - st = sts[n]; - - /*------------------------------------------------------------------* - * Initialization per core-decoder channel - *-----------------------------------------------------------------*/ - - frameMode[n] = FRAMEMODE_NORMAL; - move32(); - st->rate_switching_reset = 0; - move16(); - st->mdct_sw = MODE1; - move16(); - sid_bw[n] = -1; - move16(); - core_switching_flag[n] = 0; - move16(); - sharpFlag[n] = 0; - move16(); - unbits[n] = 0; - move16(); - st->GSC_IVAS_mode = 0; - move16(); - st->element_brate = element_brate; - move32(); - st->use_partial_copy = 0; - move16(); - st->rf_flag = 0; - move16(); - st->rf_frame_type = RF_NO_DATA; - move16(); - - IF( EQ_16( st->bfi, 1 ) ) - { - frameMode[n] = FRAMEMODE_MISSING; - move32(); - st->coder_type = st->last_coder_type; - move16(); - } - ELSE - { - test(); - IF( !( EQ_16( st->element_mode, IVAS_CPE_TD ) && EQ_16( n, 1 ) ) ) /* coder_type for SCh in TD stereo is already read in tdm_configure_dec() */ - { - st->coder_type = INACTIVE; - move16(); - } - st->extl = -1; - move16(); - st->flagGuidedAcelp = 0; - move16(); - } - - test(); - test(); - test(); - test(); - test(); -#ifdef NONBE_MDCT_ST_PLC_DO_NOT_SCALE_OLD_OUT_IF_FIRST_GOOD_IS_SID - IF( !st->bfi && st->prev_bfi && GT_32( st->total_brate, SID_2k40 ) && ( EQ_16( st->last_core_bfi, TCX_20_CORE ) || EQ_16( st->last_core_bfi, TCX_10_CORE ) ) && st->hTcxDec != NULL ) -#else - IF( !st->bfi && st->prev_bfi && ( EQ_16( st->last_core_bfi, TCX_20_CORE ) || EQ_16( st->last_core_bfi, TCX_10_CORE ) ) && st->hTcxDec != NULL ) -#endif - { - conceal_eof_gain32 = L_shl( L_deposit_l( st->hTcxDec->conceal_eof_gain ), 1 ); - - FOR( i = 0; i < st->hTcxDec->L_frameTCX; i++ ) - { - L_tmp = Mpy_32_16_1( conceal_eof_gain32, st->hHQ_core->old_out_fx[i] ); - L_tmp = Mpy_32_16_1( L_tmp, st->last_concealed_gain_syn_deemph ); - L_tmp = L_shl( L_tmp, st->last_concealed_gain_syn_deemph_e ); - st->hHQ_core->old_out_fx[i] = extract_l( L_tmp ); // Q0 - move16(); - } - - FOR( i = 0; i < st->L_frame; i++ ) - { - L_tmp = Mpy_32_16_1( conceal_eof_gain32, st->hHQ_core->old_out_LB_fx[i] ); - L_tmp = Mpy_32_16_1( L_tmp, st->last_concealed_gain_syn_deemph ); - L_tmp = L_shl( L_tmp, st->last_concealed_gain_syn_deemph_e ); - st->hHQ_core->old_out_LB_fx[i] = extract_l( L_tmp ); // Q0 - move16(); - } - } - - set16_fx( voice_factors_fx[n], 0, NB_SUBFR16k ); - set32_fx( hb_synth_32_fx[n], 0, L_FRAME48k ); - set16_fx( hb_synth_16_fx[n], 0, L_FRAME48k ); - /*------------------------------------------------------------------* - * Decision matrix (selection of technologies) - *-----------------------------------------------------------------*/ - - test(); - test(); - IF( NE_16( st->bfi, 1 ) ) - { - ivas_decision_matrix_dec_fx( st, &sharpFlag[n], &core_switching_flag[n], element_brate, nchan_out ); - - synchonize_channels_mdct_sid_fx( sts, n ); - - IF( NE_16( st->bfi, 1 ) ) /* note: st->bfi can be changed from 0 to 1 in ivas_decision_matrix_dec() when BER is detected */ - { - st->sr_core = L_mult0( st->L_frame, FRAMES_PER_SEC ); - move32(); - st->fscale_old = st->fscale; - move16(); - st->fscale = sr2fscale_fx( st->sr_core ); - move16(); - } - ELSE - { - frameMode[n] = FRAMEMODE_MISSING; - move32(); - } - } - ELSE IF( GE_16( st->element_mode, IVAS_SCE ) && EQ_16( st->prev_bfi, 1 ) && EQ_16( st->last_con_tcx, 1 ) ) - { - st->core = TCX_20_CORE; - move16(); - } - } /* n_channels loop */ - - /* MDCT stereo -> DFT stereo switching */ - test(); - test(); - IF( hCPE != NULL && EQ_16( hCPE->last_element_mode, IVAS_CPE_MDCT ) && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) - { - Word16 ovl, fade_len; - IF( NE_16( sts[0]->L_frame, sts[0]->last_L_frame ) ) - { - Copy_Scale_sig_16_32( sts[0]->hHQ_core->old_out_LB_fx, sts[0]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, sts[0]->hHQ_core->Q_old_wtda_LB ) ); - L_lerp_fx_q11( sts[0]->hHQ_core->old_outLB_fx, sts[0]->hHQ_core->old_outLB_fx, sts[0]->L_frame, sts[0]->last_L_frame ); - Copy_Scale_sig_32_16( sts[0]->hHQ_core->old_outLB_fx, sts[0]->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( sts[0]->hHQ_core->Q_old_wtda_LB, Q11 ) ); - } - IF( NE_16( sts[0]->L_frame, L_FRAME16k ) ) - { - ovl = mult( sts[0]->L_frame, 5120 ); /*STEREO_DFT32MS_OVL_16k/L_FRAME16k = 5/32 = 5120 (Q15)*/ - L_lerp_fx_q11( hCPE->input_mem_LB_fx[0], hCPE->input_mem_LB_fx[0], ovl, STEREO_DFT32MS_OVL_16k ); - - fade_len = mult( sts[0]->L_frame, 12288 ); /* STEREO_MDCT2DFT_FADE_LEN_48k/L_FRAME16k = 3/8 = 12288 (Q15)*/ - L_lerp_fx_q11( hCPE->old_outLB_mdct_fx, hCPE->old_outLB_mdct_fx, fade_len, STEREO_MDCT2DFT_FADE_LEN_48k ); - } - } - - test(); - IF( hCPE != NULL && hCPE->hStereoCng != NULL ) - { - hCPE->hStereoCng->flag_cna_fade = 0; - move16(); - } - - test(); - test(); - test(); - IF( sba_dirac_stereo_flag && hSCE && LE_32( sts[0]->total_brate, SID_2k40 ) && EQ_16( sts[0]->cng_type, FD_CNG ) ) - { - save_hb_synth_32_fx = hSCE->save_hb_synth_fx; - } - ELSE - { - save_hb_synth_32_fx = NULL; - } - - /*------------------------------------------------------------------* - * Decode SID for MDCT-Stereo DTX mode - *-----------------------------------------------------------------*/ - - test(); - IF( EQ_16( sts[0]->element_mode, IVAS_CPE_MDCT ) && EQ_32( sts[0]->total_brate, SID_2k40 ) ) - { - IF( sts[0]->cng_sba_flag ) - { - FdCngDecodeDiracMDCTStereoSID_fx( hCPE ); - } - ELSE - { - FdCngDecodeMDCTStereoSID_fx( hCPE ); - } - } - - /*------------------------------------------------------------------* - * Sanity check in combined format coding - *-----------------------------------------------------------------*/ - - test(); - test(); - IF( hCPE != NULL && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && hCPE->brate_surplus > 0 ) - { - ivas_combined_format_brate_sanity_fx( hCPE->element_brate, sts[0]->core, sts[0]->total_brate, &( sts[0]->core_brate ), &( sts[0]->inactive_coder_type_flag ), &tmps ); - } - - /*------------------------------------------------------------------* - * Core Decoding - *-----------------------------------------------------------------*/ - - FOR( n = 0; n < n_channels; n++ ) - { - st = sts[n]; - - /*------------------------------------------------------------------* - * Initialization - *-----------------------------------------------------------------*/ - - IF( EQ_16( st->bfi, 1 ) ) - { - st->nbLostCmpt = add( st->nbLostCmpt, 1 ); - move16(); - } - ELSE - { - IF( EQ_16( st->prev_bfi, 1 ) ) - { - st->prev_nbLostCmpt = st->nbLostCmpt; - move16(); - } - ELSE - { - st->prev_nbLostCmpt = 0; - move16(); - } - - st->nbLostCmpt = 0; - move16(); - } - st->enablePlcWaveadjust = 0; - move16(); - - IF( EQ_16( n, 1 ) ) - { - sts[1]->BER_detect = s_or( sts[1]->BER_detect, sts[0]->BER_detect ); - move16(); - } - - /*---------------------------------------------------------------------* - * Detect bandwidth switching - *---------------------------------------------------------------------*/ - - bandwidth_switching_detect_ivas_fx( st ); - - /*---------------------------------------------------------------------* - * Preprocessing (preparing) for ACELP/HQ core switching - *---------------------------------------------------------------------*/ - Word16 Q_olapBufferSynth, Q_olapBufferSynth2; - - Q_olapBufferSynth = Q15; /*Initializing with max values to avoid warnings*/ - Q_olapBufferSynth2 = Q15; /*Initializing with max values to avoid warnings*/ - move16(); - move16(); - - Copy_Scale_sig_16_32( st->previoussynth_fx, st->previoussynth_fx_32, L_FRAME48k, 0 ); - - IF( NE_32( ( error = core_switching_pre_dec_ivas_fx( st, output_frame, sts[0]->last_core_brate, nchan_out, last_element_mode, last_element_brate, st->Q_syn, &Q_olapBufferSynth, &Q_olapBufferSynth2 ) ), IVAS_ERR_OK ) ) - { - return error; - } - - flag_sec_CNA = -1; - move16(); - IF( hCPE != NULL ) - { - flag_sec_CNA = sts[1]->flag_cna; - move16(); - } - - /*---------------------------------------------------------------------* - * ACELP core decoding - * TCX core decoding - * HQ core decoding - *---------------------------------------------------------------------*/ - - IF( EQ_16( st->core, ACELP_CORE ) ) - { - /* ACELP core decoder */ - Word16 old_syn_12k8_16k_fx_16[L_FRAME16k]; - set16_fx( output_16_fx[n], 0, L_FRAME48k ); - Word16 save_hb_synth_fx_arr[L_FRAME48k], *save_hb_synth_16_fx; - IF( save_hb_synth_32_fx ) - { - save_hb_synth_16_fx = save_hb_synth_fx_arr; - } - ELSE - { - save_hb_synth_16_fx = NULL; - } - - IF( st->cldfbAna ) - { - scale_sig32( st->cldfbAna->cldfb_state_fx, st->cldfbAna->cldfb_size, sub( Q11, Q10 ) ); - st->cldfbAna->Q_cldfb_state = Q11; - move16(); - } - IF( st->cldfbBPF ) - { - scale_sig32( st->cldfbBPF->cldfb_state_fx, st->cldfbBPF->cldfb_size, sub( Q10, Q11 ) ); - st->cldfbBPF->Q_cldfb_state = Q10; - move16(); - } - IF( st->cldfbSyn ) - { - scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->cldfb_size, sub( Q10, Q11 ) ); - st->cldfbSyn->Q_cldfb_state = Q10; - move16(); - } - - IF( st->hFdCngDec != NULL ) - { - Scale_sig32( st->hFdCngDec->msNoiseEst, NPART_SHAPING, sub( st->hFdCngDec->msNoiseEst_exp, 27 ) ); - st->hFdCngDec->msNoiseEst_exp = 27; - move16(); - - Scale_sig( st->hFdCngDec->hFdCngCom->A_cng, add( M, 1 ), sub( norm_s( sub( st->hFdCngDec->hFdCngCom->A_cng[0], 1 ) ), 3 ) ); - } - - IF( hCPE == NULL ) - { - IF( NE_32( ( error = acelp_core_dec_ivas_fx( st, output_16_fx[n], synth_16_fx[n], save_hb_synth_16_fx, bwe_exc_extended_fx[n], voice_factors_fx[n], old_syn_12k8_16k_fx_16, sharpFlag[n], pitch_buf_fx[n], &unbits[n], &sid_bw[n], hStereoTD, tdm_lspQ_PCh_fx, tdm_lsfQ_PCh_fx, use_cldfb_for_dft, last_element_mode, last_element_brate, flag_sec_CNA, nchan_out, NULL, read_sid_info ) ), IVAS_ERR_OK ) ) - { - return error; - } - } - ELSE - { - IF( NE_32( ( error = acelp_core_dec_ivas_fx( st, output_16_fx[n], synth_16_fx[n], save_hb_synth_16_fx, bwe_exc_extended_fx[n], voice_factors_fx[n], old_syn_12k8_16k_fx_16, sharpFlag[n], pitch_buf_fx[n], &unbits[n], &sid_bw[n], hStereoTD, tdm_lspQ_PCh_fx, tdm_lsfQ_PCh_fx, use_cldfb_for_dft, last_element_mode, last_element_brate, flag_sec_CNA, nchan_out, hCPE->hStereoCng, read_sid_info ) ), IVAS_ERR_OK ) ) - { - return error; - } - } - - Copy_Scale_sig_16_32( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, st->Q_syn2 ) ); - Scale_sig( output_16_fx[n], L_FRAME48k, negate( st->Q_syn2 ) ); - IF( st->cldfbAna ) - { - scale_sig32( st->cldfbAna->cldfb_state_fx, st->cldfbAna->cldfb_size, sub( Q10, Q11 ) ); /* 9 * (Word16)(st->L_frame * FRAMES_PER_SEC * INV_CLDFB_BANDWIDTH + 0.5f) */ - st->cldfbAna->Q_cldfb_state = Q10; - move16(); - } - IF( st->cldfbBPF ) - { - scale_sig32( st->cldfbBPF->cldfb_state_fx, st->cldfbBPF->cldfb_size, sub( Q11, Q10 ) ); - st->cldfbBPF->Q_cldfb_state = Q11; - move16(); - } - IF( st->cldfbSyn ) - { - scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->cldfb_size, sub( Q11, Q10 ) ); - st->cldfbSyn->Q_cldfb_state = Q11; - move16(); - } - st->prev_Q_syn = st->Q_syn; - move16(); - - if ( save_hb_synth_32_fx ) - { - Copy_Scale_sig_16_32( save_hb_synth_16_fx, save_hb_synth_32_fx, output_frame, Q11 ); - hSCE->q_save_hb_synth_fx = Q11; - move16(); - } - - Copy_Scale_sig_16_32( old_syn_12k8_16k_fx_16, old_syn_12k8_16k_fx[n], L_FRAME16k, sub( Q11, negate( Q1 ) ) ); - } - - Copy_Scale_sig_32_16( st->previoussynth_fx_32, st->previoussynth_fx, L_FRAME48k, 0 ); - - test(); - test(); - test(); - IF( ( EQ_16( st->core, TCX_20_CORE ) || EQ_16( st->core, TCX_10_CORE ) ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - Word16 Qsyn_temp; - STEREO_CNG_DEC_HANDLE hStereoCng; - IVAS_FORMAT ivas_format; - - Qsyn_temp = st->Q_syn; - move16(); - st->Q_syn = 0; - move16(); - st->prev_Q_syn = st->Q_syn; - move16(); - st->hTcxDec->conNoiseLevelIndex = st->hTcxDec->NoiseLevelIndex_bfi; - move16(); - st->hTcxDec->conCurrLevelIndex = st->hTcxDec->CurrLevelIndex_bfi; - move16(); - st->mem_error = st->hBPF->pst_mem_deemp_err_fx; - move32(); - - /* TCX decoder */ - Scale_sig( st->hPFstat->mem_stp, L_SUBFR, -Qsyn_temp ); - Scale_sig( st->hPFstat->mem_pf_in, L_SUBFR, -Qsyn_temp ); - Scale_sig32( st->hFdCngDec->msNoiseEst, NPART_SHAPING, sub( st->hFdCngDec->msNoiseEst_exp, 27 ) ); - st->hFdCngDec->msNoiseEst_exp = 27; - move16(); - Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, -st->hHQ_core->Q_old_wtda_LB ); - Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, -st->hHQ_core->Q_old_wtda ); - - IF( hCPE == NULL ) - { - hStereoCng = NULL; - } - ELSE - { - hStereoCng = hCPE->hStereoCng; - } - IF( st_ivas == NULL ) - { - ivas_format = 0; - move32(); - } - ELSE - { - ivas_format = st_ivas->ivas_format; - move32(); - } - stereo_tcx_core_dec_fx( st, frameMode[n], output_16_fx[n], synth_16_fx[n], pitch_buf_fx[n], sba_dirac_stereo_flag, hStereoTD, last_element_mode, flag_sec_CNA, hStereoCng, nchan_out, ivas_format ); - st->hHQ_core->Q_old_wtda_LB = st->hHQ_core->Q_old_wtda; - move16(); - Copy_Scale_sig_16_32( output_16_fx[n], output_32_fx[n], L_FRAME48k, Q11 ); - - IF( st->hTcxDec ) - { - st->hTcxDec->conNoiseLevelIndex = st->hTcxDec->NoiseLevelIndex_bfi; - move16(); - st->hTcxDec->conCurrLevelIndex = st->hTcxDec->CurrLevelIndex_bfi; - move16(); - st->hTcxDec->conLastFrameLevel = st->hTcxDec->LastFrameLevel_bfi_fx; - move16(); - } - st->hBPF->pst_mem_deemp_err_fx = extract_l( st->mem_error ); - move16(); - } - - IF( EQ_16( st->core, HQ_CORE ) ) - { - /* HQ core decoder */ - Word16 Q_output; - - Q_output = 0; - move16(); - Q_synth = 0; - move16(); - - ivas_hq_core_dec_fx( st, synth_16_fx[n], &Q_synth, output_frame, NORMAL_HQ_CORE, core_switching_flag[n], output_16_fx[n], &Q_output ); - - Copy_Scale_sig_16_32( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_output ) ); -#ifdef MSAN_FIX - Scale_sig( synth_16_fx[n], output_frame, negate( Q_synth ) ); -#else - Scale_sig( synth_16_fx[n], L_FRAME48k, negate( Q_synth ) ); -#endif - Scale_sig( output_16_fx[n], L_FRAME48k, negate( Q_output ) ); - } - - /*---------------------------------------------------------------------* - * TD stereo updates - *---------------------------------------------------------------------*/ - - test(); - IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && n == 0 ) - { - Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->old_pitch_buf_fx, hCPE->hCoreCoder[0]->old_pitch_buf_16_fx, add( imult1616( 2, NB_SUBFR16k ), 2 ), negate( Q10 ) ); - - td_stereo_param_updt_fx( st->lsp_old_fx, st->lsf_old_fx, st->old_pitch_buf_16_fx + st->nb_subfr, - tdm_lspQ_PCh_fx, tdm_lsfQ_PCh_fx, hStereoTD->tdm_Pri_pitch_buf_fx, st->flag_ACELP16k, hStereoTD->tdm_use_IAWB_Ave_lpc -#ifndef FIX_798_WRONG_CPY_OF_PITCH - , - Q6 -#endif - ); - - Copy_Scale_sig_16_32( hCPE->hCoreCoder[0]->old_pitch_buf_16_fx, hCPE->hCoreCoder[0]->old_pitch_buf_fx, add( imult1616( 2, NB_SUBFR16k ), 2 ), Q10 ); - } - - } /* n_channels loop */ - - - /*---------------------------------------------------------------------* - * MDCT stereo: joint TCX Core Decoding - *---------------------------------------------------------------------*/ - - IF( EQ_16( sts[0]->element_mode, IVAS_CPE_MDCT ) ) - { - /* active-frame decoding */ - IF( GT_32( sts[0]->core_brate, SID_2k40 ) ) - { - IF( hMCT ) - { - FOR( n = 0; n < n_channels; n++ ) - { - st = sts[n]; - IF( st->cldfbAna ) - { - scale_sig32( st->cldfbAna->cldfb_state_fx, st->cldfbAna->cldfb_size, sub( Q11, Q10 ) ); - st->cldfbAna->Q_cldfb_state = Q11; - move16(); - } - IF( st->cldfbSynHB ) - { - scale_sig32( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->cldfb_size, sub( Q11, Q10 ) ); - st->cldfbSynHB->Q_cldfb_state = Q11; - move16(); - } - } - - pop_wmops(); - return error; - } - ELSE - { - Word16 e_sig; - Word16 ch; - - e_sig = 17; - move16(); - sts = hCPE->hCoreCoder; - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - st = sts[ch]; - - st->last_gain_syn_deemph = 0; - move16(); - IF( st->hHQ_core ) - { - st->hHQ_core->Q_fer_samples = 0; - move16(); - } -#ifdef FIX_778_STEREO_BRATE_SWITCHING - st->Q_syn = 0; - move16(); -#endif - st->prev_Q_syn = st->Q_syn; - move16(); - - Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( st->Q_syn, st->hHQ_core->Q_old_wtda_LB ) ); - Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, sub( st->Q_syn, st->hHQ_core->Q_old_wtda ) ); - - IF( st->hTcxDec ) - { - st->hTcxDec->conNoiseLevelIndex = st->hTcxDec->NoiseLevelIndex_bfi; - move16(); - } - IF( st->hTcxDec ) - { - st->hTcxDec->conCurrLevelIndex = st->hTcxDec->CurrLevelIndex_bfi; - move16(); - } - } - - stereo_mdct_core_dec_fx( st_ivas, hCPE, output_32_fx, synth_16_fx ); - - FOR( ch = 0; ch < 2; ch++ ) - { - st = hCPE->hCoreCoder[ch]; - st->hHQ_core->Q_old_wtda_LB = st->Q_syn; - move16(); - st->hHQ_core->Q_old_wtda = st->Q_syn; - move16(); - } - -#ifdef MSAN_FIX - Scale_sig( synth_16_fx[0], hCPE->hCoreCoder[0]->hTcxDec->L_frameTCX, sub( e_sig, 15 ) ); - Scale_sig( synth_16_fx[1], hCPE->hCoreCoder[1]->hTcxDec->L_frameTCX, sub( e_sig, 15 ) ); -#else - Scale_sig( synth_16_fx[0], L_FRAME48k, sub( e_sig, 15 ) ); - Scale_sig( synth_16_fx[1], L_FRAME48k, sub( e_sig, 15 ) ); -#endif - } - } - /* for inactive frames with mono output, copy and (if necessary) downmix buffers */ - ELSE IF( EQ_16( hCPE->nchan_out, 1 ) ) - { - sts[0] = hCPE->hCoreCoder[0]; - sts[1] = hCPE->hCoreCoder[1]; - - IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) ) - { - sts[0]->hHQ_core->exp_old_out = sub( 15, sts[0]->hHQ_core->Q_old_wtda ); - move16(); - sts[1]->hHQ_core->exp_old_out = sub( 15, sts[1]->hHQ_core->Q_old_wtda ); - move16(); - } - updateBuffersForDmxMdctStereo_fx( hCPE, output_frame, output_32_fx[0], output_32_fx[1], synth_16_fx ); - - IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) ) - { - sts[0]->hHQ_core->Q_old_wtda = sub( 15, sts[0]->hHQ_core->exp_old_out ); - move16(); - sts[1]->hHQ_core->Q_old_wtda = sub( 15, sts[1]->hHQ_core->exp_old_out ); - move16(); - } - } - - test(); - test(); -#ifdef NONBE_MDCT_ST_DTX_SKIP_DEWHITENING_OF_NOISE_SHAPES_ON_SID_FRAMES - /* On first good active frame after frameloss undo the whitening of the bg noise shape */ - IF( GT_32( sts[0]->core_brate, SID_2k40 ) && sts[0]->bfi == 0 && EQ_16( sts[0]->prev_bfi, 1 ) ) -#else - IF( sts[0]->bfi == 0 && EQ_16( sts[0]->prev_bfi, 1 ) ) - /* On first good frame after frameloss undo the whitening of the bg noise shape */ -#endif - { - FOR( n = 0; n < n_channels; ++n ) - { - IF( NE_16( sts[n]->last_core_bfi, ACELP_CORE ) ) - { - Scale_sig32( sts[n]->hFdCngDec->hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, sub( sts[n]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, 27 ) ); - sts[n]->hFdCngDec->hFdCngCom->cngNoiseLevelExp = 27; - move16(); - - TonalMdctConceal_whiten_noise_shape_ivas_fx( sts[n], L_FRAME16k, ON_FIRST_GOOD_FRAME ); - } - } - } - } - - /*---------------------------------------------------------------------* - * Stereo CNG updates - *---------------------------------------------------------------------*/ - - test(); - IF( EQ_16( sts[0]->element_mode, IVAS_CPE_TD ) && hCPE->hStereoCng != NULL ) - { - /* To be cleaned up once the caller function is converted // These changes are for system testing of fixed changes made */ - Word16 Q_c_PS_LT, Q_output; - Word32 c_PS_LT_fx; - - Q_c_PS_LT = 31; - move16(); - Q_output = 11; - move16(); - c_PS_LT_fx = L_deposit_h( hCPE->hStereoCng->c_PS_LT_fx ); - Q_c_PS_LT = Q31; - move16(); - - stereo_cng_compute_PScorr_fx( output_32_fx[0], output_32_fx[1], &Q_output, &c_PS_LT_fx, Q_c_PS_LT, sts[0]->L_frame, sts[1]->L_frame ); - - hCPE->hStereoCng->c_PS_LT_fx = extract_h( c_PS_LT_fx ); - } - - /*---------------------------------------------------------------------* - * Postprocessing, BWEs and updates - *---------------------------------------------------------------------*/ - - FOR( n = 0; n < n_channels; n++ ) - { - st = sts[n]; - - /*---------------------------------------------------------------------* - * TD-BWE for ACELP to TCX transitions - *---------------------------------------------------------------------*/ - - /*core_switching_post_dec*/ - Q_synth = 0; - move16(); - if ( st->hHQ_core != NULL ) - { - st->hHQ_core->Q_old_postdec = 0; - move16(); - } - - /*------------------fix-to-fix-end-----------------------*/ - - Word16 output_mem_16_fx[L_FRAME48k]; - Word16 *p_output_mem_16; - - IF( p_output_mem_fx != NULL ) - { - p_output_mem_16 = output_mem_16_fx; - Copy_Scale_sig_32_16( p_output_mem_fx, p_output_mem_16, NS2SA_FX2( output_Fs, STEREO_DFT32MS_OVL_NS ), negate( Q11 ) ); - } - ELSE - { - p_output_mem_16 = NULL; - set16_fx( output_mem_16_fx, 0, NS2SA( st->output_Fs, 3125000 ) ); - } - - Scale_sig32( output_32_fx[n], L_FRAME48k, sub( Q4, Q11 ) ); - - IF( st->hHQ_core != NULL ) - { - Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, negate( st->hHQ_core->Q_old_wtda ) ); - st->hHQ_core->Q_old_wtda = 0; - move16(); - } - - /*size of synth is choosen as delay comp to start with*/ - /*-------------------cldfb-start-------------------------*/ - - IF( st->cldfbSyn != NULL ) - { - scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q4, Q11 ) ); - st->cldfbSyn->Q_cldfb_state = Q4; - move16(); - } - - Word16 q_audio, old_syn_fx; - old_syn_fx = Q11; - move16(); - q_audio = Q12; - move16(); - test(); - test(); - test(); - test(); - IF( EQ_16( st->last_core, ACELP_CORE ) && ( EQ_16( st->core, TCX_20_CORE ) || EQ_16( st->core, TCX_10_CORE ) || EQ_16( st->core, HQ_CORE ) ) && st->hBWE_TD != NULL ) - { - test(); - test(); - test(); - test(); - IF( ( EQ_16( st->bwidth, SWB ) || EQ_16( st->bwidth, FB ) ) && ( EQ_16( st->last_extl, SWB_TBE ) || EQ_16( st->last_extl, FB_TBE ) ) ) - { - GenTransition_fixed( st->hBWE_TD, hb_synth_32_fx[n], output_Fs, st->element_mode, st->L_frame, st->rf_flag, st->total_brate ); - } - ELSE IF( EQ_16( st->bwidth, WB ) && EQ_16( st->last_extl, WB_TBE ) ) - { - GenTransition_WB_fixed( st->hBWE_TD, hb_synth_32_fx[n], output_Fs ); - } - - /* Memories Scaling */ - Copy_Scale_sig_32_16( st->hBWE_TD->syn_overlap_fx_32, st->hBWE_TD->syn_overlap_fx, L_SHB_LAHEAD, sub( st->prev_Q_bwe_syn2, Q11 ) ); - Copy_Scale_sig_32_16( st->hBWE_TD->old_tbe_synth_fx_32, st->hBWE_TD->old_tbe_synth_fx, L_SHB_TRANSITION_LENGTH, sub( st->prev_Qx, Q11 ) ); - Copy_Scale_sig_32_16( st->hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, st->hBWE_TD->state_lsyn_filt_dwn_shb_fx, shl( ALLPASSSECTIONS_STEEP, 1 ), sub( st->prev_Qx, Q11 ) ); - Copy_Scale_sig_32_16( st->hBWE_TD->state_lsyn_filt_shb_fx_32, st->hBWE_TD->state_lsyn_filt_shb_fx, shl( ALLPASSSECTIONS_STEEP, 1 ), sub( st->prev_Qx, Q11 ) ); - Copy_Scale_sig_32_16( st->hBWE_TD->mem_resamp_HB_fx_32, st->hBWE_TD->mem_resamp_HB_fx, INTERP_3_1_MEM_LEN, sub( st->prev_Qx, Q11 ) ); - } - - /* Memories Re-Scaling */ - IF( st->hBWE_TD != NULL ) - { - Copy_Scale_sig_16_32( st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->syn_overlap_fx_32, L_SHB_LAHEAD, sub( Q11, st->prev_Q_bwe_syn2 ) ); - Copy_Scale_sig_16_32( st->hBWE_TD->old_tbe_synth_fx, st->hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, st->prev_Qx ) ); - Copy_Scale_sig_16_32( st->hBWE_TD->state_lsyn_filt_dwn_shb_fx, st->hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, shl( ALLPASSSECTIONS_STEEP, 1 ), sub( Q11, st->prev_Qx ) ); - Copy_Scale_sig_16_32( st->hBWE_TD->state_lsyn_filt_shb_fx, st->hBWE_TD->state_lsyn_filt_shb_fx_32, shl( ALLPASSSECTIONS_STEEP, 1 ), sub( Q11, st->prev_Qx ) ); - Copy_Scale_sig_16_32( st->hBWE_TD->mem_resamp_HB_fx, st->hBWE_TD->mem_resamp_HB_fx_32, INTERP_3_1_MEM_LEN, sub( Q11, st->prev_Qx ) ); - Copy( st->hBWE_TD->mem_resamp_HB_fx, st->hBWE_TD->state_32and48k_WB_upsample_fx, imult1616( 2, ALLPASSSECTIONS_STEEP ) ); - } - /*---------------------------------------------------------------------* - * Postprocessing for ACELP/MDCT core switching - *---------------------------------------------------------------------*/ - - /* save synth and output in case of SBA DirAC stereo output as core switching is done outside of core decoder */ - test(); - test(); - test(); - IF( sba_dirac_stereo_flag && NE_16( st->element_mode, IVAS_CPE_MDCT ) && !( EQ_32( st->core_brate, SID_2k40 ) && EQ_16( st->cng_type, FD_CNG ) ) ) - { - Copy_Scale_sig_16_32( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); - } - - IVAS_FORMAT ivas_format; - IF( st_ivas != NULL ) - { - ivas_format = st_ivas->ivas_format; - move32(); - } - ELSE - { - ivas_format = UNDEFINED_FORMAT; - move32(); - } - IF( hCPE != NULL ) - { - last_element_mode = hCPE->last_element_mode; - move16(); - } - ELSE - { - last_element_mode = IVAS_SCE; - move16(); - } - IF( NE_32( ( error = core_switching_post_dec_ivas_fx( st, synth_16_fx[n], output_32_fx[n], p_output_mem_16, ivas_format, use_cldfb_for_dft, output_frame, 0 /*core_switching_flag*/, sba_dirac_stereo_flag, nchan_out, last_element_mode, &Q_synth ) ), IVAS_ERR_OK ) ) - { - return error; - } - - /* for FD-CNG we need the delay compensation in the synth, so do this afterwards */ - test(); - test(); - test(); - IF( sba_dirac_stereo_flag && hSCE && EQ_32( st->core_brate, SID_2k40 ) && EQ_16( st->cng_type, FD_CNG ) ) - { - Copy_Scale_sig_16_32( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); - } - - /* if we transition from inactive to active coding in MDCT-Stereo DTX and the output format is mono DMX, we need to sync the upsampled buffer between channels here */ - test(); - test(); - test(); - test(); - test(); - test(); - IF( n == 0 && EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_16( st->last_core, ACELP_CORE ) && NE_16( st->core, ACELP_CORE ) && ( EQ_16( nchan_out, 1 ) || ( hCPE != NULL && EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) ) ) ) - { - Copy( sts[0]->previoussynth_fx, sts[1]->previoussynth_fx, st->hTcxDec->L_frameTCX ); - } - /*---------------------------------------------------------------------* - * Pre-processing for bandwidth switching - *---------------------------------------------------------------------*/ - - ivas_bw_switching_pre_proc_fx( st, last_element_brate, nchan_out, old_syn_12k8_16k_fx[n], old_syn_fx, q_audio ); - - Copy_Scale_sig_16_32( st->delay_buf_out_fx, st->delay_buf_out32_fx, imult1616( HQ_DELTA_MAX, HQ_DELAY_COMP ), Q11 ); - Scale_sig32( output_32_fx[n], L_FRAME48k, sub( Q11, Q4 ) ); - - - /*note : cldfb_size here signifies the original size which was assigned to cldfb_state_fx buffer not its current size*/ - - IF( st->cldfbSyn != NULL ) - { - scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q11, Q4 ) ); - st->cldfbSyn->Q_cldfb_state = Q11; - move16(); - } - -#ifdef MSAN_FIX - Scale_sig( synth_16_fx[n], output_frame, negate( Q_synth ) ); -#else - Scale_sig( synth_16_fx[n], L_FRAME48k, negate( Q_synth ) ); -#endif - - /*------------------reset-code-start---------------------*/ - - test(); - test(); - IF( NE_16( st->last_extl, WB_BWE ) && EQ_16( st->extl, WB_BWE ) && st->hBWE_FD != NULL ) - { - test(); - if ( NE_16( st->last_extl, SWB_BWE ) && NE_16( st->last_extl, FB_BWE ) ) - { - st->hBWE_FD->prev_mode = st->hBWE_FD->prev_mode; - move16(); - } - st->hBWE_FD->prev_L_swb_norm = st->hBWE_FD->prev_L_swb_norm; - move16(); - st->hBWE_FD->prev_flag = st->hBWE_FD->prev_flag; - move16(); - } - - /*---------------------------------------------------------------------* - * WB TBE decoding - * WB BWE decoding - *---------------------------------------------------------------------*/ - - Word16 Q_input, Q_hb_synth_fx, Q_synth_fx; - Word16 Q_syn_hb; - - Q_input = 0; - move16(); - Q_hb_synth_fx = 0; - move16(); - Q_synth_fx = 0; - move16(); - - FD_BWE_DEC_HANDLE hBWE_FD; - hBWE_FD = st->hBWE_FD; - - Copy_Scale_sig_32_16( output_32_fx[n], output_16_fx[n], L_FRAME48k, negate( Q11 ) ); - Copy_Scale_sig_32_16( hb_synth_32_fx[n], hb_synth_16_fx[n], L_FRAME48k, negate( Q11 ) ); - test(); - test(); - test(); - test(); - test(); - test(); - IF( EQ_16( st->extl, WB_TBE ) ) - { - /* WB TBE decoder */ - - ivas_wb_tbe_dec_fx( st, st->coder_type, bwe_exc_extended_fx[n], st->Q_exc, voice_factors_fx[n], hb_synth_16_fx[n], &Q_hb_synth_fx ); - } - ELSE IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && EQ_16( n, 1 ) && !tdm_LRTD_flag && NE_16( st->extl, -1 ) && st->bws_cnt == 0 && st->extl_brate == 0 ) - { - /* do nothing */ - } - ELSE IF( EQ_16( st->extl, WB_BWE ) && st->bws_cnt == 0 ) - { - /* WB BWE decoder */ - Q_hb_synth_fx = ivas_wb_bwe_dec_fx( st, output_16_fx[n], synth_16_fx[n], hb_synth_16_fx[n], use_cldfb_for_dft, output_frame, voice_factors_fx[n], pitch_buf_fx[n], &Q_synth_fx ); - } - - /* Memories Re-Scaling */ - Copy_Scale_sig_16_32( hb_synth_16_fx[n], hb_synth_32_fx[n], L_FRAME48k, sub( Q11, Q_hb_synth_fx ) ); - Copy_Scale_sig_16_32( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_input ) ); - Copy_Scale_sig_16_32( synth_16_fx[n], synth_32_fx[n], L_FRAME48k, sub( Q11, Q_synth_fx ) ); - - IF( hBWE_FD != NULL ) - { - Copy_Scale_sig_16_32( hBWE_FD->L_old_wtda_swb_fx, hBWE_FD->L_old_wtda_swb_fx32, L_FRAME48k, sub( Q11, hBWE_FD->old_wtda_swb_fx_exp ) ); - } - IF( st->hBWE_TD != NULL ) - { - Copy_Scale_sig_16_32( st->hBWE_TD->old_tbe_synth_fx, st->hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, st->prev_Qx ) ); - } - - /*---------------------------------------------------------------------* - * SWB(FB) TBE decoding - * SWB(FB) BWE decoding - *---------------------------------------------------------------------*/ - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) || ( NE_16( st->coder_type, AUDIO ) && NE_16( st->coder_type, INACTIVE ) && GE_32( st->core_brate, SID_2k40 ) && EQ_16( st->core, ACELP_CORE ) && !st->con_tcx && GE_32( output_Fs, 32000 ) && GT_16( st->bwidth, NB ) && st->bws_cnt > 0 ) ) - { - /* SWB TBE decoder */ - Q_white_exc = 0; - move16(); - - ivas_swb_tbe_dec_fx( st, hStereoICBWE, bwe_exc_extended_fx[n], st->Q_exc, voice_factors_fx[n], old_syn_12k8_16k_fx[n], tmp_buffer_fx /*fb_exc*/, hb_synth_32_fx[n], pitch_buf_fx[n], &Q_white_exc ); - - Copy_Scale_sig_32_16( st->hBWE_TD->old_tbe_synth_fx_32, st->hBWE_TD->old_tbe_synth_fx, L_SHB_TRANSITION_LENGTH, sub( st->prev_Qx, Q11 ) ); - - IF( GT_16( Q_white_exc, 31 ) ) - { - Scale_sig( tmp_buffer_fx, L_FRAME48k, sub( 31, Q_white_exc ) ); - Q_white_exc = 31; - move16(); - } - - /* FB TBE decoder */ - IF( EQ_16( st->extl, FB_TBE ) ) - { - fb_tbe_dec_ivas_fx( st, tmp_buffer_fx /*fb_exc*/, Q_white_exc, hb_synth_32_fx[n], 0, tmp_buffer_fx /*fb_synth_ref*/, Q_white_exc, output_frame ); - } - } - ELSE IF( EQ_16( st->extl, SWB_BWE ) || EQ_16( st->extl, FB_BWE ) || ( GE_32( output_Fs, 32000 ) && st->core == ACELP_CORE && st->bwidth > NB && st->bws_cnt > 0 && !st->ppp_mode_dec && !( EQ_16( st->nelp_mode_dec, 1 ) && EQ_16( st->bfi, 1 ) ) ) ) - { - /* SWB BWE decoder */ - Q_syn_hb = swb_bwe_dec_fx32( st, output_32_fx[n], synth_32_fx[n], hb_synth_32_fx[n], use_cldfb_for_dft, output_frame ); - - Scale_sig32( hb_synth_32_fx[n], output_frame, sub( Q11, Q_syn_hb ) ); - - Copy_Scale_sig_32_16( st->hBWE_FD->L_old_wtda_swb_fx32, st->hBWE_FD->L_old_wtda_swb_fx, output_frame, sub( hBWE_FD->old_wtda_swb_fx_exp, Q11 ) ); - } - - /*---------------------------------------------------------------------* - * FEC - recovery after lost HQ core (smoothing of the BWE component) - *---------------------------------------------------------------------*/ - - test(); - test(); - IF( st->prev_bfi && EQ_16( st->last_core, HQ_CORE ) && NE_16( st->extl, -1 ) ) - { - /*tmp = FRAC_BWE_SMOOTH/output_frame;*/ - tmp16 = shr( 410, shr( output_frame, 8 ) ); /* Q15 */ - IF( EQ_16( output_frame, L_FRAME48k ) ) - { - tmp16 = 68; - move16(); - } - /*output_frame/FRAC_BWE_SMOOTH*/ - j = shr( output_frame, 1 ); - tmp16_2 = 0; - move16(); - FOR( i = 0; i < j; i++ ) - { - hb_synth_32_fx[n][i] = Mpy_32_16_1( hb_synth_32_fx[n][i], tmp16_2 ); /* Q11 */ - move32(); -#ifdef BASOP_NOGLOB - tmp16_2 = add_o( tmp16_2, tmp16, &Overflow ); /* Q15 */ -#else - tmp16_2 = add( tmp16_2, tmp16 ); -#endif - } - } - - /*---------------------------------------------------------------------* - * SWB CNG - *---------------------------------------------------------------------*/ - - test(); - test(); - test(); - test(); - IF( ( GE_16( output_frame, L_FRAME32k ) && st->hTdCngDec != NULL ) || ( EQ_16( st->element_mode, IVAS_CPE_DFT ) && GE_16( st->bwidth, SWB ) && st->hTdCngDec != NULL ) ) - { - /* SHB CNG decoder */ - Word16 synth_fxl[960]; /* Q-2 */ - Word16 q; - - q = 2; - move16(); - Copy_Scale_sig_32_16( hb_synth_32_fx[n], hb_synth_16_fx[n], L_FRAME48k, negate( add( Q11, q ) ) ); -#ifdef MSAN_FIX - Copy_Scale_sig_32_16( synth_32_fx[n], synth_fxl, output_frame, negate( add( Q11, q ) ) ); -#else - Copy_Scale_sig_32_16( synth_32_fx[n], synth_fxl, L_FRAME48k, negate( add( Q11, q ) ) ); -#endif - Scale_sig( st->hBWE_TD->state_lpc_syn_fx, LPC_SHB_ORDER, sub( Q8, st->prev_Q_bwe_syn ) ); - Scale_sig32( st->hBWE_TD->genSHBsynth_Hilbert_Mem_fx, HILBERT_MEM_SIZE, sub( st->prev_Q_bwe_syn2, Q11 ) ); - Copy_Scale_sig_32_16( st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, imult1616( 2, ALLPASSSECTIONS_STEEP ), sub( st->prev_Q_bwe_syn2, Q11 ) ); - - swb_CNG_dec_ivas_fx( st, synth_fxl, hb_synth_16_fx[n], sid_bw[n], negate( q ) ); - - test(); - IF( st->core_brate == FRAME_NO_DATA || EQ_32( st->core_brate, SID_2k40 ) ) - { - Copy_Scale_sig_16_32( hb_synth_16_fx[n], hb_synth_32_fx[n], L_FRAME48k, ( Q11 + q ) ); - } - Copy_Scale_sig_16_32( synth_fxl, synth_32_fx[n], L_FRAME48k, add( Q11, q ) ); - Scale_sig( st->hBWE_TD->state_lpc_syn_fx, LPC_SHB_ORDER, sub( st->prev_Q_bwe_syn, Q8 ) ); - Scale_sig32( st->hBWE_TD->genSHBsynth_Hilbert_Mem_fx, HILBERT_MEM_SIZE, sub( Q11, st->prev_Q_bwe_syn2 ) ); - Copy_Scale_sig_16_32( st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, 2 * ALLPASSSECTIONS_STEEP, sub( Q11, st->prev_Q_bwe_syn2 ) ); - } - - /*-------------------------------------------------------------------* - * Inter-channel BWE decoding - *-------------------------------------------------------------------*/ - test(); - IF( n == 0 && GE_16( st->element_mode, IVAS_CPE_DFT ) ) - { - Word16 q; - q = 11; - move16(); - - IF( hCPE->hStereoDft != NULL ) - { - hCPE->hStereoDft->td_gain_fx[0] = 1; - move32(); - } - Scale_sig( tmp_buffer_fx, L_FRAME48k, sub( 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 - test(); - test(); - test(); - test(); - test(); - test(); - 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 ) && 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 ) ); - } -#else - Scale_sig32( hb_synth_32_fx[0], L_FRAME48k, sub( Q11, q ) ); - Scale_sig32( hb_synth_32_fx[1], L_FRAME48k, sub( Q11, q ) ); -#endif - } - - IF( EQ_16( st->element_mode, EVS_MONO ) ) - { - /*----------------------------------------------------------------* - * BFI waveform adjustment - *----------------------------------------------------------------*/ - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( EQ_16( st->core, ACELP_CORE ) && !st->bfi && st->prev_bfi && GE_32( st->last_total_brate, HQ_48k ) && EQ_16( st->last_codec_mode, MODE2 ) && ( EQ_16( st->last_core_bfi, TCX_20_CORE ) || EQ_16( st->last_core_bfi, TCX_10_CORE ) ) && EQ_16( st->hPlcInfo->concealment_method, TCX_NONTONAL ) && LT_16( st->hPlcInfo->nbLostCmpt, 4 ) ) - { - tmps = NS2SA_FX2( output_Fs, DELAY_CLDFB_NS ); - - waveform_adj2_fix( st->hTonalMDCTConc->secondLastPcmOut, synth_16_fx[n] + tmps, st->plcInfo.data_noise, &st->plcInfo.outx_new_n1_fx, - &st->plcInfo.nsapp_gain_fx, &st->plcInfo.nsapp_gain_n_fx, &st->plcInfo.recovery_gain, st->plcInfo.step_concealgain_fx, - st->plcInfo.Pitch_fx, st->plcInfo.FrameSize, tmps, add( st->hPlcInfo->nbLostCmpt, 1 ), st->bfi ); - - st->hPlcInfo->Pitch = 0; - move16(); - } - } - - /*----------------------------------------------------------------* - * Transition and synchronization of BWE components - *----------------------------------------------------------------*/ - - test(); - test(); - test(); - test(); - IF( ( NE_16( st->extl, -1 ) && ( NE_16( st->extl, IGF_BWE ) || st->last_core == ACELP_CORE ) ) || ( st->bws_cnt > 0 && st->core == ACELP_CORE ) ) - { - /* Calculate an additional delay of extension layer components to be synchronized with ACELP synthesis */ - IF( EQ_16( st->L_frame, L_FRAME ) ) - { - /* TBE on top of ACELP@12.8kHz */ - tmps = NS2SA( output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_12k8_NS ); - } - ELSE - { - test(); - IF( EQ_16( st->extl, SWB_BWE_HIGHRATE ) || EQ_16( st->extl, FB_BWE_HIGHRATE ) ) - { - /* HR SWB BWE on top of ACELP@16kHz */ - tmps = NS2SA( output_Fs, DELAY_BWE_TOTAL_NS ); - } - ELSE - { - /* TBE on top of ACELP@16kHz */ - tmps = NS2SA( output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_16k_NS ); - } - } - - /* Smooth transitions when switching between different technologies */ - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( !( ( EQ_16( st->core, TCX_20_CORE ) || EQ_16( st->core, TCX_10_CORE ) || EQ_16( st->core, HQ_CORE ) ) && st->last_core == ACELP_CORE ) && - ( NE_16( st->extl, st->last_extl ) || ( EQ_16( st->extl, st->last_extl ) && s_xor( st->core, st->last_core ) == HQ_CORE ) ) && !( EQ_16( st->extl, SWB_CNG ) && EQ_16( st->last_extl, SWB_TBE ) ) && ( NE_16( st->element_mode, IVAS_CPE_TD ) || ( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) && tdm_LRTD_flag ) ) ) - { - /* switching between BWE and TBE technologies */ - incr = idiv1616( imult1616( L_FRAME, 2 ), add( shl( tmps, 1 ), 1 ) ); - tmp16 = 0; - move16(); - FOR( i = 0; i < tmps; i++ ) - { - hb_synth_32_fx[n][i] = Mpy_32_16_1( hb_synth_32_fx[n][i], sin_table256_fx[tmp16] ); - move16(); - tmp16 = add( tmp16, incr ); - } - - set16_fx( st->hb_prev_synth_buffer_fx, 0, tmps ); - } - ELSE IF( LT_16( tmps, st->old_bwe_delay ) ) - { - /* the previous frame was TBE on top of ACELP@16kHz and the current frame is TBE on top of ACELP@12.8kHz */ - - incr = idiv1616( imult1616( L_FRAME, 2 ), add( shl( tmps, 1 ), 1 ) ); - tmp16 = 0; - move16(); - FOR( i = 0; i < tmps; i++ ) - { - tmp_buffer_fx[i] = round_fx( L_add( L_shr( L_mult( st->hb_prev_synth_buffer_fx[i], sin_table256_fx[255 - tmp16] ), 1 ), L_shr( L_mult( st->hb_prev_synth_buffer_fx[sub( sub( st->old_bwe_delay, 1 ), i )], sin_table256_fx[tmp16] ), 1 ) ) ); - move16(); - tmp_buffer_fx[i] = shl_sat( tmp_buffer_fx[i], 1 ); - move16(); - tmp16 = add( tmp16, incr ); - } - Copy( tmp_buffer_fx, st->hb_prev_synth_buffer_fx, tmps ); - } - ELSE IF( GT_16( tmps, st->old_bwe_delay ) ) - { - /* the previous frame was TBE on top of ACELP@12.8kHz and the current frame is TBE on top of ACELP@16kHz */ - incr = idiv1616( imult1616( L_FRAME, 2 ), add( shl( st->old_bwe_delay, 1 ), 1 ) ); - tmp16 = 0; - move16(); - FOR( i = 0; i < st->old_bwe_delay; i++ ) - { - tmp_buffer_fx[i] = mult_r( st->hb_prev_synth_buffer_fx[i], sin_table256_fx[255 - tmp16] ); - move16(); - tmp16 = add( tmp16, incr ); - } - FOR( ; i < tmps; i++ ) - { - tmp_buffer_fx[i] = 0; - move16(); - } - tmp16 = 0; - move16(); - FOR( i = 0; i < st->old_bwe_delay; i++ ) - { - tmp_buffer_fx[sub( sub( tmps, 1 ), i )] = round_fx( L_mac( L_mult( tmp_buffer_fx[sub( sub( tmps, 1 ), i )], 32767 ), st->hb_prev_synth_buffer_fx[sub( sub( st->old_bwe_delay, 1 ), i )], sin_table256_fx[tmp16 /*i * incr*/] ) ); - move16(); - tmp16 = add( tmp16, incr ); - } - - Copy( tmp_buffer_fx, st->hb_prev_synth_buffer_fx, tmps ); - } - - test(); - test(); - test(); - IF( ( NE_16( st->element_mode, IVAS_CPE_TD ) && !use_cldfb_for_dft ) || ( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) && tdm_LRTD_flag ) ) - { - /* Delay hb_synth */ - Word32 hb_prev_synth_buffer_fx_32[111]; - - Copy_Scale_sig_16_32( st->hb_prev_synth_buffer_fx, hb_prev_synth_buffer_fx_32, 111, 11 ); - delay_signal_fx( hb_synth_32_fx[n], output_frame, hb_prev_synth_buffer_fx_32, tmps ); - Copy_Scale_sig_32_16( hb_prev_synth_buffer_fx_32, st->hb_prev_synth_buffer_fx, 111, negate( 11 ) ); - } - ELSE - { - Copy_Scale_sig_32_16( hb_synth_32_fx[n] + sub( output_frame, tmps ), st->hb_prev_synth_buffer_fx, tmps, negate( Q11 ) ); - } - - st->old_bwe_delay = tmps; - - /* SWB CNG/DTX - calculate SHB energy */ - test(); - test(); - test(); - IF( GE_16( output_frame, L_FRAME32k ) && GT_16( st->extl, SWB_CNG ) && st->core == ACELP_CORE && st->hTdCngDec != NULL ) - { - Word16 exp; - Word32 fra; - SWITCH( output_frame ) - { - case L_FRAME8k: - tmp16 = 205; - move16(); - BREAK; /*Q15*/ - case L_FRAME16k: - tmp16 = 102; - move16(); - BREAK; /*Q15*/ - case L_FRAME32k: - tmp16 = 51; - move16(); - BREAK; /*Q15*/ - case L_FRAME48k: - tmp16 = 34; - move16(); - BREAK; /*Q15*/ - } - - L_tmp = L_deposit_l( 2 ); /*0.001 in Q11*/ - - Word16 exp2; - exp = 20; - move16(); - Word32 L_tmp2 = sum2_32_fx( hb_synth_32_fx[n], output_frame, &exp ); - L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, 20, L_tmp2, exp, &exp ); - L_tmp = Mpy_32_16_1( L_tmp, tmp16 ); - exp2 = norm_l( L_tmp ); - exp = sub( exp, exp2 ); - fra = BASOP_Util_Log2( L_shl_sat( L_tmp, exp2 ) ); - exp2 = norm_l( exp ); - L_tmp = L_shl( exp, exp2 ); - exp = sub( Q31, exp2 ); - L_tmp = BASOP_Util_Add_Mant32Exp( fra, 6, L_tmp, exp, &exp ); - // exp = sub( sub( 30, shl( sub( Q11, 0 ), 1 ) ), exp ); - L_tmp = Mpy_32_16_1( L_tmp, 24660 ); - exp = add( exp, 2 ); - st->last_shb_ener_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 7 ) ) ); /*Q8*/ - move16(); - st->hTdCngDec->last_shb_ener_fx = L_shl_sat( L_tmp, sub( exp, 20 ) ); /*Q11*/ - move32(); - } - } - - test(); - IF( sba_dirac_stereo_flag && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - /* for SBA DirAC stereo output DFT Stereo core switching and updates are done in ivas_sba_dirac_stereo_dec() as hCPE is not available at this point */ - break; - } - - /*----------------------------------------------------------------* - * Post-processing - * - TCX-LTP Postfilter (except DFT stereo) - * - core switching in DFT stereo - * - updates for potential TD->DFT stereo switching - *----------------------------------------------------------------*/ - IF( hCPE != NULL ) - { - FOR( Word32 ch_ind = 0; ch_ind < n_channels; ch_ind++ ) - { - IF( hCPE->hCoreCoder[ch_ind] != NULL ) - { - IF( hCPE->hCoreCoder[ch_ind]->hHQ_core != NULL ) - { - Copy_Scale_sig_16_32( hCPE->hCoreCoder[ch_ind]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[ch_ind]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, hCPE->hCoreCoder[ch_ind]->hHQ_core->Q_old_wtda_LB ) ); - Copy_Scale_sig_16_32( hCPE->hCoreCoder[ch_ind]->hHQ_core->old_out_fx, hCPE->hCoreCoder[ch_ind]->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, hCPE->hCoreCoder[ch_ind]->hHQ_core->Q_old_wtda ) ); - } - } - } - } - IF( hSCE != NULL ) - { - IF( hSCE->hCoreCoder[0] != NULL ) - { - IF( hSCE->hCoreCoder[0]->hHQ_core != NULL ) - { - Copy_Scale_sig_16_32( hSCE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hSCE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, hSCE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ) ); - Copy_Scale_sig_16_32( hSCE->hCoreCoder[0]->hHQ_core->old_out_fx, hSCE->hCoreCoder[0]->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, hSCE->hCoreCoder[0]->hHQ_core->Q_old_wtda ) ); - } - } - } - - Word16 exp_max; - Word32 output_fx_loc[L_FRAME48k]; - - exp_max = 0; - move16(); - IF( NE_16( st->element_mode, IVAS_CPE_DFT ) ) - { - test(); - IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) || sba_dirac_stereo_flag ) - { - ivas_post_proc_fx( hSCE, hCPE, n, synth_32_fx[n], NULL, output_frame, sba_dirac_stereo_flag ); - } - - /* update OLA buffers - needed for switching to DFT stereo */ - IF( !sba_dirac_stereo_flag ) - { - IF( hCPE != NULL ) - { - stereo_td2dft_update_fx( hCPE, n, output_32_fx[n], synth_32_fx[n], hb_synth_32_fx[n], output_frame ); - } - } - } - ELSE /* IVAS_CPE_DFT */ - { - Word16 q; - q = 11; - move16(); - IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_MDCT ) ) - { - stereo_mdct2dft_update_fx( hCPE, output_32_fx[0], synth_32_fx[0] ); - } - Word16 q_DFT[2] = { 3, 3 }; - move16(); - move16(); - - stereo_dft_dec_core_switching_fx( hCPE, output_32_fx[0], synth_32_fx[0], hb_synth_32_fx[0], DFT_fx, output_frame, use_cldfb_for_dft, 0, &q, q_DFT ); - - hCPE->hStereoDft->q_dft = s_min( q_DFT[0], q_DFT[1] ); - move16(); - - IF( DFT_fx != NULL ) - { - Scale_sig32( DFT_fx[0], STEREO_DFT_BUF_MAX, sub( hCPE->hStereoDft->q_dft, q_DFT[0] ) ); - Scale_sig32( DFT_fx[1], STEREO_DFT_BUF_MAX, sub( hCPE->hStereoDft->q_dft, q_DFT[1] ) ); - } - - test(); - IF( EQ_16( hCPE->nchan_out, 1 ) && EQ_16( hCPE->hStereoDft->hConfig->res_cod_mode, STEREO_DFT_RES_COD_OFF ) ) - { - /* mono output for non-residual coding modes uses CLDFB instead of DFT - requires DFT buffer update in case of bitrate switching */ - stereo_td2dft_update_fx( hCPE, n, output_32_fx[n], synth_32_fx[n], hb_synth_32_fx[n], output_frame ); - } - } - - Copy32( synth_32_fx[n], output_32_fx[n], output_frame ); - - /*--------------------------------------------------------* - * Common updates - *--------------------------------------------------------*/ - - /*Scale Memories*/ - - test(); - test(); - test(); - test(); - test(); - IF( ( EQ_16( st->codec_mode, MODE1 ) && st->hTcxDec != NULL ) && ( ( EQ_16( st->core, ACELP_CORE ) && !( EQ_16( st->bfi, 1 ) && EQ_16( st->con_tcx, 1 ) ) ) || EQ_16( st->core, HQ_CORE ) ) ) - { - Word16 exp_prev_synth_buffer = 0, exp_old_out = 0, exp_delay_buf_out = 0, exp_ouput = 0, exp_synth_history = 0; - move16(); - move16(); - move16(); - move16(); - move16(); - - Copy_Scale_sig32_16( st->prev_synth_buffer32_fx, st->prev_synth_buffer_fx, NS2SA( 48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), negate( Q11 ) ); - st->q_prev_synth_buffer_fx = 0; - move16(); - - exp_ouput = Find_Max_Norm32( output_32_fx[n], output_frame ); - exp_ouput = add( exp_ouput, Q11 ); - exp_prev_synth_buffer = Find_Max_Norm16( st->prev_synth_buffer_fx, NS2SA( 48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); - exp_prev_synth_buffer = add( exp_prev_synth_buffer, st->q_prev_synth_buffer_fx ); - exp_old_out = Find_Max_Norm16( st->hHQ_core->old_out_fx + NS2SA( st->output_Fs, N_ZERO_MDCT_NS ), sub( add( NS2SA( st->output_Fs, N_ZERO_MDCT_NS ), NS2SA( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ), NS2SA( st->output_Fs, N_ZERO_MDCT_NS ) ) ); - exp_delay_buf_out = Find_Max_Norm16( st->delay_buf_out_fx, NS2SA( st->output_Fs, DELAY_CLDFB_NS ) ); - exp_synth_history = Find_Max_Norm16( st->hTcxDec->synth_history_fx + output_frame, sub( add( sub( imult1616( 2, output_frame ), NS2SA( st->output_Fs, DELAY_CLDFB_NS ) ), NS2SA( st->output_Fs, PH_ECU_MEM_NS ) ), output_frame ) ); -#ifndef FIX_740_HQ_CORE_OVA - exp_synth_history += st->hTcxDec->q_synth_history_fx; -#endif - exp_max = s_min( exp_synth_history, exp_ouput ); - exp_max = s_min( exp_max, exp_prev_synth_buffer ); - exp_max = s_min( exp_max, exp_old_out ); - exp_max = s_min( exp_max, exp_delay_buf_out ); - - Copy32( output_32_fx[n], output_fx_loc, output_frame ); - - Scale_sig32( output_fx_loc, output_frame, sub( exp_max, Q11 ) ); - Scale_sig( st->delay_buf_out_fx, NS2SA( st->output_Fs, DELAY_CLDFB_NS ), exp_max ); - Scale_sig( st->hHQ_core->old_out_fx + NS2SA( st->output_Fs, N_ZERO_MDCT_NS ), sub( NS2SA( st->output_Fs, PH_ECU_LOOKAHEAD_NS ), NS2SA( st->output_Fs, N_ZERO_MDCT_NS ) ), exp_max ); - Scale_sig( st->prev_synth_buffer_fx, NS2SA( 48000, L_sub( DELAY_BWE_TOTAL_NS, DELAY_CLDFB_NS ) ), sub( exp_max, st->q_prev_synth_buffer_fx ) ); - Scale_sig( st->hTcxDec->synth_history_fx + output_frame, sub( add( sub( imult1616( 2, output_frame ), NS2SA( st->output_Fs, DELAY_CLDFB_NS ) ), NS2SA( st->output_Fs, PH_ECU_MEM_NS ) ), output_frame ), sub( exp_max, st->Q_syn ) ); - - st->q_prev_synth_buffer_fx = sub( exp_max, st->q_prev_synth_buffer_fx ); - } - /* Save synthesis for HQ FEC */ - save_synthesis_hq_fec_fx( st, output_fx_loc, output_frame, hCPE ); - - /* Updates */ - - ivas_updt_dec_common_fx( st, NORMAL_HQ_CORE, -1, output_32_fx[n], Q11 ); - - Scale_sig( st->delay_buf_out_fx, NS2SA( st->output_Fs, DELAY_CLDFB_NS ), negate( exp_max ) ); - - } /* n_channels loop */ - - FOR( n = 0; n < n_channels; n++ ) - { - st = sts[n]; - IF( st->cldfbAna ) - { - scale_sig32( st->cldfbAna->cldfb_state_fx, st->cldfbAna->cldfb_size, sub( Q11, Q10 ) ); - st->cldfbAna->Q_cldfb_state = Q11; - move16(); - } - IF( st->cldfbSynHB ) - { - scale_sig32( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->cldfb_size, sub( Q11, Q10 ) ); - st->cldfbSynHB->Q_cldfb_state = Q11; - move16(); - } - } - - pop_wmops(); - return error; -} -#else -ivas_error ivas_core_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - SCE_DEC_HANDLE hSCE, /* i/o: SCE decoder structure */ - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */ - const int16_t n_channels, /* i : number of channels to be decoded */ - float *output[], /* o : output synthesis signal */ - float hb_synth[][L_FRAME48k], /* o : output HB synthesis signal */ - float DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* o : DFT buffers */ - const int16_t sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ -) -{ - int16_t i, n, output_frame; - Decoder_State **sts, *st; - STEREO_ICBWE_DEC_HANDLE hStereoICBWE; - STEREO_TD_DEC_DATA_HANDLE hStereoTD; - int16_t sharpFlag[CPE_CHANNELS]; - float synth[CPE_CHANNELS][L_FRAME48k]; - float tmp_buffer[L_FRAME48k]; - int16_t tmps, incr; - float bwe_exc_extended[CPE_CHANNELS][L_FRAME32k + NL_BUFF_OFFSET]; - float voice_factors[CPE_CHANNELS][NB_SUBFR16k]; - int16_t core_switching_flag[CPE_CHANNELS]; - float old_syn_12k8_16k[CPE_CHANNELS][L_FRAME16k]; - float tmp; - float pitch_buf[CPE_CHANNELS][NB_SUBFR16k]; - int16_t unbits[CPE_CHANNELS]; - int16_t sid_bw[CPE_CHANNELS]; - FRAME_MODE frameMode[CPE_CHANNELS]; - float tdm_lspQ_PCh[M], tdm_lsfQ_PCh[M]; - int16_t tdm_LRTD_flag; - int32_t element_brate, output_Fs; - int32_t last_element_brate; - int16_t use_cldfb_for_dft; - float *p_output_mem; - int16_t flag_sec_CNA; - int16_t read_sid_info; - int16_t last_element_mode; - int16_t nchan_out; - float *save_hb_synth; - ivas_error error; - - error = IVAS_ERR_OK; - push_wmops( "ivas_core_dec" ); - - /*------------------------------------------------------------------* - * General initialization - *-----------------------------------------------------------------*/ - - use_cldfb_for_dft = 0; - tdm_LRTD_flag = -1; - read_sid_info = 1; /* read SID by default */ - - if ( hSCE != NULL ) - { - sts = hSCE->hCoreCoder; - hStereoICBWE = NULL; - element_brate = hSCE->element_brate; - last_element_brate = hSCE->last_element_brate; /* note: this parameter is unused */ - last_element_mode = IVAS_SCE; - hStereoTD = NULL; - p_output_mem = NULL; - nchan_out = 1; - if ( st_ivas != NULL && st_ivas->ivas_format == ISM_FORMAT ) - { - if ( st_ivas->hISMDTX.sce_id_dtx != hSCE->sce_id ) - { - read_sid_info = 0; - } - } - } - else - { - sts = hCPE->hCoreCoder; - element_brate = hCPE->element_brate; - last_element_brate = hCPE->last_element_brate; - last_element_mode = hCPE->last_element_mode; - hStereoICBWE = hCPE->hStereoICBWE; - hStereoTD = hCPE->hStereoTD; - p_output_mem = hCPE->output_mem[1]; - nchan_out = hCPE->nchan_out; - - if ( hCPE->hStereoTD != NULL ) - { - tdm_LRTD_flag = hCPE->hCoreCoder[0]->tdm_LRTD_flag; - } - - if ( sts[0]->element_mode == IVAS_CPE_DFT ) - { - use_cldfb_for_dft = ( hCPE->nchan_out == 1 && hCPE->hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF ) ? 1 : 0; - } - } - - output_Fs = sts[0]->output_Fs; - output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC ); - - for ( n = 0; n < n_channels; n++ ) - { - st = sts[n]; - - /*------------------------------------------------------------------* - * Initialization per core-decoder channel - *-----------------------------------------------------------------*/ - - frameMode[n] = FRAMEMODE_NORMAL; - st->rate_switching_reset = 0; - - st->mdct_sw = MODE1; - - sid_bw[n] = -1; - core_switching_flag[n] = 0; - sharpFlag[n] = 0; - unbits[n] = 0; - st->GSC_IVAS_mode = 0; - st->element_brate = element_brate; - - st->use_partial_copy = 0; - st->rf_flag = 0; - st->rf_frame_type = RF_NO_DATA; - - if ( st->bfi == 1 ) - { - frameMode[n] = FRAMEMODE_MISSING; - st->coder_type = st->last_coder_type; - } - else - { - if ( !( st->element_mode == IVAS_CPE_TD && n == 1 ) ) /* coder_type for SCh in TD stereo is already read in tdm_configure_dec() */ - { - st->coder_type = INACTIVE; - } - st->extl = -1; - st->flagGuidedAcelp = 0; - } - -#ifdef NONBE_MDCT_ST_PLC_DO_NOT_SCALE_OLD_OUT_IF_FIRST_GOOD_IS_SID - if ( !st->bfi && st->prev_bfi && st->total_brate > SID_2k40 && ( st->last_core_bfi == TCX_20_CORE || st->last_core_bfi == TCX_10_CORE ) && st->hTcxDec != NULL ) -#else - if ( !st->bfi && st->prev_bfi && ( st->last_core_bfi == TCX_20_CORE || st->last_core_bfi == TCX_10_CORE ) && st->hTcxDec != NULL ) -#endif - { - v_multc( st->hHQ_core->old_out, st->hTcxDec->conceal_eof_gain_float * st->last_concealed_gain_syn_deemph_float, st->hHQ_core->old_out, st->hTcxDec->L_frameTCX ); - v_multc( st->hHQ_core->old_outLB, st->hTcxDec->conceal_eof_gain_float * st->last_concealed_gain_syn_deemph_float, st->hHQ_core->old_outLB, st->L_frame ); - } - - set_f( voice_factors[n], 0.f, NB_SUBFR16k ); - set_f( hb_synth[n], 0.0f, L_FRAME48k ); - - /*------------------------------------------------------------------* - * Decision matrix (selection of technologies) - *-----------------------------------------------------------------*/ - - if ( st->bfi != 1 ) - { - ivas_decision_matrix_dec( st, &sharpFlag[n], &core_switching_flag[n], element_brate, nchan_out ); - - synchonize_channels_mdct_sid( sts, n ); - - if ( st->bfi != 1 ) /* note: st->bfi can be changed from 0 to 1 in ivas_decision_matrix_dec() when BER is detected */ - { - st->sr_core = st->L_frame * FRAMES_PER_SEC; - st->fscale_old = st->fscale; - st->fscale = sr2fscale( st->sr_core ); - } - else - { - frameMode[n] = FRAMEMODE_MISSING; - } - } - else if ( st->element_mode >= IVAS_SCE && st->prev_bfi == 1 && st->last_con_tcx == 1 ) - { - st->core = TCX_20_CORE; - } - } /* n_channels loop */ - - /* MDCT stereo -> DFT stereo switching */ - if ( hCPE != NULL && hCPE->last_element_mode == IVAS_CPE_MDCT && hCPE->element_mode == IVAS_CPE_DFT ) - { - int16_t ovl, fade_len; - if ( sts[0]->L_frame != sts[0]->last_L_frame ) - { - lerp_flt( sts[0]->hHQ_core->old_outLB, sts[0]->hHQ_core->old_outLB, sts[0]->L_frame, sts[0]->last_L_frame ); - } - if ( sts[0]->L_frame != L_FRAME16k ) - { - ovl = (int16_t) ( STEREO_DFT32MS_OVL_16k * ( (float) sts[0]->L_frame / L_FRAME16k ) ); - lerp_flt( hCPE->input_mem_LB[0], hCPE->input_mem_LB[0], ovl, STEREO_DFT32MS_OVL_16k ); - - fade_len = (int16_t) ( STEREO_MDCT2DFT_FADE_LEN_48k * ( (float) sts[0]->L_frame / L_FRAME16k ) ); - lerp_flt( hCPE->old_outLB_mdct, hCPE->old_outLB_mdct, fade_len, STEREO_MDCT2DFT_FADE_LEN_48k ); - } - } - - if ( hCPE != NULL && hCPE->hStereoCng != NULL ) - { - hCPE->hStereoCng->flag_cna_fade = 0; - } - - if ( sba_dirac_stereo_flag && hSCE && sts[0]->total_brate <= SID_2k40 && sts[0]->cng_type == FD_CNG ) - { - save_hb_synth = hSCE->save_hb_synth; - } - else - { - save_hb_synth = NULL; - } - - /*------------------------------------------------------------------* - * Decode SID for MDCT-Stereo DTX mode - *-----------------------------------------------------------------*/ - - if ( sts[0]->element_mode == IVAS_CPE_MDCT && sts[0]->total_brate == SID_2k40 ) - { - if ( sts[0]->cng_sba_flag ) - { - FdCngDecodeDiracMDCTStereoSID( hCPE ); - } - else - { - FdCngDecodeMDCTStereoSID( hCPE ); - } - } - - /*------------------------------------------------------------------* - * Sanity check in combined format coding - *-----------------------------------------------------------------*/ - - if ( hCPE != NULL && hCPE->element_mode == IVAS_CPE_DFT && hCPE->brate_surplus > 0 ) - { - ivas_combined_format_brate_sanity( hCPE->element_brate, sts[0]->core, sts[0]->total_brate, &( sts[0]->core_brate ), &( sts[0]->inactive_coder_type_flag ), &tmps ); - } - - /*------------------------------------------------------------------* - * Core Decoding - *-----------------------------------------------------------------*/ - - for ( n = 0; n < n_channels; n++ ) - { - st = sts[n]; - - /*------------------------------------------------------------------* - * Initialization - *-----------------------------------------------------------------*/ - - if ( st->bfi == 1 ) - { - st->nbLostCmpt++; - } - else - { - if ( st->prev_bfi == 1 ) - { - st->prev_nbLostCmpt = st->nbLostCmpt; - } - else - { - st->prev_nbLostCmpt = 0; - } - - st->nbLostCmpt = 0; - } - st->enablePlcWaveadjust = 0; - - if ( n == 1 ) - { - sts[1]->BER_detect |= sts[0]->BER_detect; - } - - /*---------------------------------------------------------------------* - * Detect bandwidth switching - *---------------------------------------------------------------------*/ - - bandwidth_switching_detect( st ); - - /*---------------------------------------------------------------------* - * Preprocessing (preparing) for ACELP/HQ core switching - *---------------------------------------------------------------------*/ - - if ( ( error = core_switching_pre_dec( st, output_frame, sts[0]->last_core_brate, nchan_out, last_element_mode, last_element_brate ) ) != IVAS_ERR_OK ) - { - return error; - } - - flag_sec_CNA = -1; - if ( hCPE != NULL ) - { - flag_sec_CNA = sts[1]->flag_cna; - } - - /*---------------------------------------------------------------------* - * ACELP core decoding - * TCX core decoding - * HQ core decoding - *---------------------------------------------------------------------*/ - - if ( st->core == ACELP_CORE ) - { - /* ACELP core decoder */ - if ( ( error = acelp_core_dec( st, output[n], synth[n], save_hb_synth, bwe_exc_extended[n], voice_factors[n], old_syn_12k8_16k[n], sharpFlag[n], pitch_buf[n], &unbits[n], &sid_bw[n], hStereoTD, tdm_lspQ_PCh, tdm_lsfQ_PCh, use_cldfb_for_dft, last_element_mode, last_element_brate, flag_sec_CNA, nchan_out, hCPE == NULL ? NULL : hCPE->hStereoCng, read_sid_info ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - if ( ( st->core == TCX_20_CORE || st->core == TCX_10_CORE ) && st->element_mode != IVAS_CPE_MDCT ) - { - /* TCX decoder */ - stereo_tcx_core_dec( st, frameMode[n], output[n], synth[n], pitch_buf[n], sba_dirac_stereo_flag, hStereoTD, last_element_mode, flag_sec_CNA, hCPE == NULL ? NULL : hCPE->hStereoCng, nchan_out, st_ivas == NULL ? 0 : st_ivas->ivas_format ); - } - - if ( st->core == HQ_CORE ) - { - /* HQ core decoder */ - hq_core_dec( st, synth[n], output_frame, NORMAL_HQ_CORE, core_switching_flag[n], output[n] ); - } - - /*---------------------------------------------------------------------* - * TD stereo updates - *---------------------------------------------------------------------*/ - - if ( st->element_mode == IVAS_CPE_TD && n == 0 ) - { - td_stereo_param_updt( st->lsp_old, st->lsf_old, st->old_pitch_buf + st->nb_subfr, tdm_lspQ_PCh, tdm_lsfQ_PCh, hStereoTD->tdm_Pri_pitch_buf, st->flag_ACELP16k, hStereoTD->tdm_use_IAWB_Ave_lpc ); - } - - } /* n_channels loop */ - - /*---------------------------------------------------------------------* - * MDCT stereo: joint TCX Core Decoding - *---------------------------------------------------------------------*/ - - if ( sts[0]->element_mode == IVAS_CPE_MDCT ) - { - /* active-frame decoding */ - if ( sts[0]->core_brate > SID_2k40 ) - { - if ( hMCT ) - { - pop_wmops(); - - return error; - } - else - { - stereo_mdct_core_dec( st_ivas, hCPE, output, synth ); - } - } - /* for inactive frames with mono output, copy and (if necessary) downmix buffers */ - else if ( hCPE->nchan_out == 1 ) - { - updateBuffersForDmxMdctStereo( hCPE, output_frame, output, synth ); - } - -#ifdef NONBE_MDCT_ST_DTX_SKIP_DEWHITENING_OF_NOISE_SHAPES_ON_SID_FRAMES - - /* On first good active frame after frameloss undo the whitening of the bg noise shape */ - if ( sts[0]->core_brate > SID_2k40 && sts[0]->bfi == 0 && sts[0]->prev_bfi == 1 ) -#else - if ( sts[0]->bfi == 0 && sts[0]->prev_bfi == 1 ) - /* On first good frame after frameloss undo the whitening of the bg noise shape */ -#endif - { - for ( n = 0; n < n_channels; ++n ) - { - if ( sts[n]->last_core_bfi != ACELP_CORE ) - { - TonalMdctConceal_whiten_noise_shape_ivas( sts[n], L_FRAME16k, ON_FIRST_GOOD_FRAME ); - } - } - } - } - - /*---------------------------------------------------------------------* - * Stereo CNG updates - *---------------------------------------------------------------------*/ - - if ( sts[0]->element_mode == IVAS_CPE_TD && hCPE->hStereoCng != NULL ) - { - stereo_cng_compute_PScorr( output, &hCPE->hStereoCng->c_PS_LT, sts[0]->L_frame, sts[1]->L_frame ); - } - - /*---------------------------------------------------------------------* - * Postprocessing, BWEs and updates - *---------------------------------------------------------------------*/ - - for ( n = 0; n < n_channels; n++ ) - { - st = sts[n]; - - /*---------------------------------------------------------------------* - * TD-BWE for ACELP to TCX transitions - *---------------------------------------------------------------------*/ - - if ( st->last_core == ACELP_CORE && ( st->core == TCX_20_CORE || st->core == TCX_10_CORE || st->core == HQ_CORE ) && st->hBWE_TD != NULL ) - { - if ( ( st->bwidth == SWB || st->bwidth == FB ) && ( st->last_extl == SWB_TBE || st->last_extl == FB_TBE ) ) - { - GenTransition( st->hBWE_TD, hb_synth[n], output_Fs, st->element_mode, st->L_frame, st->rf_flag, st->total_brate ); - } - else if ( st->bwidth == WB && st->last_extl == WB_TBE ) - { - GenTransition_WB( st->hBWE_TD, hb_synth[n], output_Fs ); - } - } - - /*---------------------------------------------------------------------* - * Postprocessing for ACELP/MDCT core switching - *---------------------------------------------------------------------*/ - - /* save synth and output in case of SBA DirAC stereo output as core switching is done outside of core decoder */ - if ( sba_dirac_stereo_flag && st->element_mode != IVAS_CPE_MDCT && !( st->core_brate == SID_2k40 && st->cng_type == FD_CNG ) ) - { - mvr2r( synth[n], hSCE->save_synth, output_frame ); - } - - if ( ( error = core_switching_post_dec( st, synth[n], output[n], p_output_mem, ( st_ivas != NULL ) ? st_ivas->ivas_format : UNDEFINED_FORMAT, use_cldfb_for_dft, output_frame, 0 /*core_switching_flag*/, sba_dirac_stereo_flag, nchan_out, ( hCPE != NULL ) ? hCPE->last_element_mode : IVAS_SCE ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* for FD-CNG we need the delay compensation in the synth, so do this afterwards */ - if ( sba_dirac_stereo_flag && hSCE && st->core_brate == SID_2k40 && st->cng_type == FD_CNG ) - { - mvr2r( synth[n], hSCE->save_synth, output_frame ); - } - - /* if we transition from inactive to active coding in MDCT-Stereo DTX and the output format is mono DMX, we need to sync the upsampled buffer between channels here */ - if ( n == 0 && st->element_mode == IVAS_CPE_MDCT && st->last_core == ACELP_CORE && st->core != ACELP_CORE && ( nchan_out == 1 || ( hCPE != NULL && hCPE->last_element_mode == IVAS_CPE_DFT ) ) ) - { - mvr2r( sts[0]->previoussynth, sts[1]->previoussynth, st->hTcxDec->L_frameTCX ); - } - - /*---------------------------------------------------------------------* - * Pre-processing for bandwidth switching - *---------------------------------------------------------------------*/ - - bw_switching_pre_proc( st, old_syn_12k8_16k[n], last_element_brate, nchan_out ); - - /*---------------------------------------------------------------------* - * WB TBE decoding - * WB BWE decoding - *---------------------------------------------------------------------*/ - - if ( st->extl == WB_TBE ) - { - /* WB TBE decoder */ - wb_tbe_dec( st, bwe_exc_extended[n], voice_factors[n], hb_synth[n] ); - } - else if ( st->element_mode == IVAS_CPE_TD && n == 1 && !tdm_LRTD_flag && st->extl != -1 && st->bws_cnt == 0 && st->extl_brate == 0 ) - { - /* do nothing */ - } - else if ( st->extl == WB_BWE && st->bws_cnt == 0 ) - { - /* WB BWE decoder */ - wb_bwe_dec_flt( st, output[n], synth[n], hb_synth[n], use_cldfb_for_dft, output_frame, voice_factors[n], pitch_buf[n] ); - } - - /*---------------------------------------------------------------------* - * SWB(FB) TBE decoding - * SWB(FB) BWE decoding - *---------------------------------------------------------------------*/ - - if ( st->extl == SWB_TBE || st->extl == FB_TBE || ( st->coder_type != AUDIO && st->coder_type != INACTIVE && st->core_brate >= SID_2k40 && st->core == ACELP_CORE && !st->con_tcx && output_Fs >= 32000 && st->bwidth > NB && st->bws_cnt > 0 ) ) - { - /* SWB TBE decoder */ - swb_tbe_dec( st, hStereoICBWE, bwe_exc_extended[n], voice_factors[n], old_syn_12k8_16k[n], tmp_buffer /*fb_exc*/, hb_synth[n], pitch_buf[n] ); - - /* FB TBE decoder */ - if ( st->extl == FB_TBE ) - { - fb_tbe_dec( st, tmp_buffer /*fb_exc*/, hb_synth[n], tmp_buffer /*fb_synth_ref*/, output_frame ); - } - } - else if ( st->extl == SWB_BWE || st->extl == FB_BWE || ( output_Fs >= 32000 && st->core == ACELP_CORE && st->bwidth > NB && st->bws_cnt > 0 && !st->ppp_mode_dec && !( st->nelp_mode_dec == 1 && st->bfi == 1 ) ) ) - { - /* SWB BWE decoder */ - swb_bwe_dec_flt( st, output[n], synth[n], hb_synth[n], use_cldfb_for_dft, output_frame ); - } - - /*---------------------------------------------------------------------* - * FEC - recovery after lost HQ core (smoothing of the BWE component) - *---------------------------------------------------------------------*/ - - if ( st->prev_bfi && st->last_core == HQ_CORE && st->extl != -1 ) - { - tmp = FRAC_BWE_SMOOTH / output_frame; - - for ( i = 0; i < output_frame / FRAC_BWE_SMOOTH; i++ ) - { - hb_synth[n][i] *= ( i * tmp ); - } - } - - /*---------------------------------------------------------------------* - * SWB CNG - *---------------------------------------------------------------------*/ - - if ( ( output_frame >= L_FRAME32k && st->hTdCngDec != NULL ) || ( st->element_mode == IVAS_CPE_DFT && st->bwidth >= SWB && st->hTdCngDec != NULL ) ) - { - /* SHB CNG decoder */ - swb_CNG_dec( st, synth[n], hb_synth[n], sid_bw[n] ); - } - - /*-------------------------------------------------------------------* - * Inter-channel BWE decoding - *-------------------------------------------------------------------*/ - - if ( n == 0 && st->element_mode >= IVAS_CPE_DFT ) - { - stereo_icBWE_dec( hCPE, hb_synth[0], hb_synth[1], tmp_buffer /*fb_synth_ref*/, voice_factors[0], output_frame ); - } - - if ( st->element_mode == EVS_MONO ) - { - /*----------------------------------------------------------------* - * BFI waveform adjustment - *----------------------------------------------------------------*/ - - if ( st->core == ACELP_CORE && !st->bfi && st->prev_bfi && st->last_total_brate >= HQ_48k && st->last_codec_mode == MODE2 && ( st->last_core_bfi == TCX_20_CORE || st->last_core_bfi == TCX_10_CORE ) && st->hPlcInfo->concealment_method == TCX_NONTONAL && st->hPlcInfo->nbLostCmpt < 4 ) - { - tmps = NS2SA( output_Fs, DELAY_CLDFB_NS ); - - waveform_adj2( st->hPlcInfo, st->hTonalMDCTConc->secondLastPcmOut_float, synth[n] + tmps, tmps, st->hPlcInfo->nbLostCmpt + 1, st->bfi ); - - st->hPlcInfo->Pitch = 0; - } - } - - /*----------------------------------------------------------------* - * Transition and synchronization of BWE components - *----------------------------------------------------------------*/ - - if ( ( st->extl != -1 && ( st->extl != IGF_BWE || st->last_core == ACELP_CORE ) ) || ( st->bws_cnt > 0 && st->core == ACELP_CORE ) ) - { - /* Calculate an additional delay of extension layer components to be synchronized with ACELP synthesis */ - if ( st->L_frame == L_FRAME ) - { - /* TBE on top of ACELP@12.8kHz */ - tmps = NS2SA( output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_12k8_NS ); - } - else - { - if ( st->extl == SWB_BWE_HIGHRATE || st->extl == FB_BWE_HIGHRATE ) - { - /* HR SWB BWE on top of ACELP@16kHz */ - tmps = NS2SA( output_Fs, DELAY_BWE_TOTAL_NS ); - } - else - { - /* TBE on top of ACELP@16kHz */ - tmps = NS2SA( output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_16k_NS ); - } - } - - /* Smooth transitions when switching between different technologies */ - if ( !( ( st->core == TCX_20_CORE || st->core == TCX_10_CORE || st->core == HQ_CORE ) && st->last_core == ACELP_CORE ) && - ( st->extl != st->last_extl || ( st->extl == st->last_extl && ( st->core ^ st->last_core ) == HQ_CORE ) ) && !( st->extl == SWB_CNG && st->last_extl == SWB_TBE ) && ( st->element_mode != IVAS_CPE_TD || ( hCPE->element_mode == IVAS_CPE_TD && tdm_LRTD_flag ) ) ) - { - /* switching between BWE and TBE technologies */ - incr = (int16_t) ( L_FRAME / ( tmps + 0.5f ) ); - for ( i = 0; i < tmps; i++ ) - { - hb_synth[n][i] *= sin_table256[i * incr]; - } - - set_f( st->hb_prev_synth_buffer, 0.0f, tmps ); - } - else if ( tmps < st->old_bwe_delay ) - { - /* the previous frame was TBE on top of ACELP@16kHz and the current frame is TBE on top of ACELP@12.8kHz */ - incr = (int16_t) ( L_FRAME / ( tmps + 0.5f ) ); - for ( i = 0; i < tmps; i++ ) - { - tmp_buffer[i] = st->hb_prev_synth_buffer[i] * sin_table256[255 - i * incr] + - st->hb_prev_synth_buffer[st->old_bwe_delay - 1 - i] * sin_table256[i * incr]; - } - - mvr2r( tmp_buffer, st->hb_prev_synth_buffer, tmps ); - } - else if ( tmps > st->old_bwe_delay ) - { - /* the previous frame was TBE on top of ACELP@12.8kHz and the current frame is TBE on top of ACELP@16kHz */ - incr = (int16_t) ( L_FRAME / ( st->old_bwe_delay + 0.5f ) ); - for ( i = 0; i < st->old_bwe_delay; i++ ) - { - tmp_buffer[i] = st->hb_prev_synth_buffer[i] * sin_table256[255 - i * incr]; - } - - for ( ; i < tmps; i++ ) - { - tmp_buffer[i] = 0.0f; - } - - for ( i = 0; i < st->old_bwe_delay; i++ ) - { - tmp_buffer[tmps - 1 - i] += st->hb_prev_synth_buffer[st->old_bwe_delay - 1 - i] * sin_table256[i * incr]; - } - - mvr2r( tmp_buffer, st->hb_prev_synth_buffer, tmps ); - } - - if ( ( st->element_mode != IVAS_CPE_TD && !use_cldfb_for_dft ) || ( hCPE->element_mode == IVAS_CPE_TD && tdm_LRTD_flag ) ) - { - /* Delay hb_synth */ - delay_signal_float( hb_synth[n], output_frame, st->hb_prev_synth_buffer, tmps ); - } - else - { - mvr2r( hb_synth[n] + output_frame - tmps, st->hb_prev_synth_buffer, tmps ); - } - - st->old_bwe_delay = tmps; - if ( st->hBWE_TD != NULL ) - { - mvr2r( hb_synth[n], st->hBWE_TD->old_hb_synth, output_frame ); - } - - /* SWB CNG/DTX - calculate SHB energy */ - if ( output_frame >= L_FRAME32k && st->extl > SWB_CNG && st->core == ACELP_CORE && st->hTdCngDec != NULL ) - { - st->hTdCngDec->last_shb_ener = sum2_f( hb_synth[n], output_frame ) + 0.001f; - st->hTdCngDec->last_shb_ener /= (float) output_frame; - st->hTdCngDec->last_shb_ener = 10 * log10f( st->hTdCngDec->last_shb_ener ); - } - } - - if ( sba_dirac_stereo_flag && st->element_mode != IVAS_CPE_MDCT ) - { - /* for SBA DirAC stereo output DFT Stereo core switching and updates are done in ivas_sba_dirac_stereo_dec() as hCPE is not available at this point */ - break; - } - - /*----------------------------------------------------------------* - * Post-processing - * - TCX-LTP Postfilter (except DFT stereo) - * - core switching in DFT stereo - * - updates for potential TD->DFT stereo switching - *----------------------------------------------------------------*/ - - if ( st->element_mode != IVAS_CPE_DFT ) - { - if ( st->element_mode != IVAS_CPE_MDCT || sba_dirac_stereo_flag ) - { - ivas_post_proc( hSCE, hCPE, n, synth[n], NULL, output_frame, sba_dirac_stereo_flag ); - } - - /* update OLA buffers - needed for switching to DFT stereo */ - if ( !sba_dirac_stereo_flag ) - { - stereo_td2dft_update( hCPE, n, output[n], synth[n], hb_synth[n], output_frame ); - } - } - else /* IVAS_CPE_DFT */ - { - if ( hCPE->last_element_mode == IVAS_CPE_MDCT ) - { - stereo_mdct2dft_update( hCPE, output[0], synth[0] ); - } - - stereo_dft_dec_core_switching( hCPE, output[0], synth[0], hb_synth[0], DFT, output_frame, use_cldfb_for_dft, 0 ); - - if ( hCPE->nchan_out == 1 && hCPE->hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF ) - { - /* mono output for non-residual coding modes uses CLDFB instead of DFT - requires DFT buffer update in case of bitrate switching */ - stereo_td2dft_update( hCPE, n, output[n], synth[n], hb_synth[n], output_frame ); - } - } - - mvr2r( synth[n], output[n], output_frame ); - - /*--------------------------------------------------------* - * Common updates - *--------------------------------------------------------*/ - - /* Save synthesis for HQ FEC */ - save_synthesis_hq_fec( st, output[n], output_frame, hCPE ); - - /* Updates */ - updt_dec_common( st, NORMAL_HQ_CORE, -1, output[n] ); - - } /* n_channels loop */ - - - pop_wmops(); - return error; -} -#endif +/****************************************************************************************************** + + (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 "options.h" +#include +#include +#include "cnst.h" +#include "rom_com.h" +#include "prot.h" +#include "ivas_prot.h" +#include "ivas_prot_fx.h" +#include "ivas_rom_com.h" +#include "wmc_auto.h" +#ifdef IVAS_FLOAT_FIXED +#include "prot_fx.h" +#include "ivas_prot_fx.h" +#endif + +/*-------------------------------------------------------------------* + * ivas_core_dec() + * + * Principal IVAS core decoder routine, where number of core channels is 1 or 2 + *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_core_dec_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + SCE_DEC_HANDLE hSCE, /* i/o: SCE decoder structure */ + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */ + const Word16 n_channels, /* i : number of channels to be decoded */ + Word32 *output_32_fx[], /* o : output synthesis signal */ + Word32 hb_synth_32_fx[][L_FRAME48k], /* o : output HB synthesis signal */ + Word32 DFT_fx[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* o : DFT buffers */ + const Word16 sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ +) +{ + Word16 i, n, output_frame; + Decoder_State **sts, *st; + STEREO_ICBWE_DEC_HANDLE hStereoICBWE; + STEREO_TD_DEC_DATA_HANDLE hStereoTD; + Word16 sharpFlag[CPE_CHANNELS]; + Word16 tmp_buffer_fx[L_FRAME48k]; + set16_fx( tmp_buffer_fx, 0, L_FRAME48k ); + Word16 tmp16, tmp16_2, j; + tmp16 = 0; + move16(); + Word16 Q_white_exc; + Q_white_exc = 0; + move16(); + + Word16 tmps, incr; + Word32 bwe_exc_extended_fx[CPE_CHANNELS][L_FRAME32k + NL_BUFF_OFFSET]; + + Word16 voice_factors_fx[CPE_CHANNELS][NB_SUBFR16k]; + Word16 core_switching_flag[CPE_CHANNELS]; + + Word16 pitch_buf_fx[CPE_CHANNELS][NB_SUBFR16k]; + Word32 old_syn_12k8_16k_fx[CPE_CHANNELS][L_FRAME16k]; + + Word16 unbits[CPE_CHANNELS]; + Word16 sid_bw[CPE_CHANNELS]; + FRAME_MODE frameMode[CPE_CHANNELS]; + Word16 tdm_LRTD_flag; + Word32 element_brate, output_Fs; + Word32 last_element_brate; + Word16 use_cldfb_for_dft; + Word32 *p_output_mem_fx; + Word16 flag_sec_CNA; + Word16 read_sid_info; + Word16 last_element_mode; + Word16 nchan_out; + Word32 *save_hb_synth_32_fx; + ivas_error error; + Word32 L_tmp; + Word16 Q_synth; + Word16 output_16_fx[CPE_CHANNELS][L_FRAME48k]; + Word16 hb_synth_16_fx[CPE_CHANNELS][L_FRAME48k]; + + Word16 synth_16_fx[CPE_CHANNELS][L_FRAME48k]; + Word32 synth_32_fx[CPE_CHANNELS][L_FRAME48k]; + + FOR( i = 0; i < CPE_CHANNELS; i++ ) + { + set16_fx( pitch_buf_fx[i], 0, NB_SUBFR16k ); + set16_fx( output_16_fx[i], 0, L_FRAME48k ); + } + + Word16 tdm_lsfQ_PCh_fx[M], tdm_lspQ_PCh_fx[M]; + Word32 conceal_eof_gain32; + +#ifdef BASOP_NOGLOB + Flag Overflow; +#endif + + error = IVAS_ERR_OK; + move32(); + push_wmops( "ivas_core_dec" ); + + /*------------------------------------------------------------------* + * General initialization + *-----------------------------------------------------------------*/ + + use_cldfb_for_dft = 0; + move16(); + tdm_LRTD_flag = -1; + move16(); + read_sid_info = 1; /* read SID by default */ + move16(); + + IF( hSCE != NULL ) + { + sts = hSCE->hCoreCoder; + hStereoICBWE = NULL; + element_brate = hSCE->element_brate; + move32(); + last_element_brate = hSCE->last_element_brate; /* note: this parameter is unused */ + move32(); + last_element_mode = IVAS_SCE; + move16(); + hStereoTD = NULL; + p_output_mem_fx = NULL; + nchan_out = 1; + move16(); + test(); + IF( st_ivas != NULL && EQ_32( st_ivas->ivas_format, ISM_FORMAT ) ) + { + if ( NE_16( st_ivas->hISMDTX.sce_id_dtx, hSCE->sce_id ) ) + { + read_sid_info = 0; + move16(); + } + } + } + ELSE + { + sts = hCPE->hCoreCoder; + element_brate = hCPE->element_brate; + move32(); + last_element_brate = hCPE->last_element_brate; + move32(); + last_element_mode = hCPE->last_element_mode; + move16(); + hStereoICBWE = hCPE->hStereoICBWE; + hStereoTD = hCPE->hStereoTD; + p_output_mem_fx = hCPE->output_mem_fx[1]; + + nchan_out = hCPE->nchan_out; + move16(); + + if ( hCPE->hStereoTD != NULL ) + { + tdm_LRTD_flag = hCPE->hCoreCoder[0]->tdm_LRTD_flag; + move16(); + } + + IF( EQ_16( sts[0]->element_mode, IVAS_CPE_DFT ) ) + { + test(); + IF( EQ_16( hCPE->nchan_out, 1 ) && EQ_16( hCPE->hStereoDft->hConfig->res_cod_mode, STEREO_DFT_RES_COD_OFF ) ) + { + use_cldfb_for_dft = 1; + move16(); + } + ELSE + { + use_cldfb_for_dft = 0; + move16(); + } + } + } + + FOR( n = 0; n < n_channels; n++ ) + { + st = sts[n]; + IF( st->cldfbAna ) + { + scale_sig32( st->cldfbAna->cldfb_state_fx, st->cldfbAna->cldfb_size, sub( Q10, Q11 ) ); + st->cldfbAna->Q_cldfb_state = Q10; + move16(); + } + IF( st->cldfbSynHB ) + { + scale_sig32( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->cldfb_size, sub( Q10, Q11 ) ); + st->cldfbSynHB->Q_cldfb_state = Q10; + move16(); + } + } + + output_Fs = sts[0]->output_Fs; + move32(); + output_frame = extract_l( Mpy_32_16_1( output_Fs, INV_FRAME_PER_SEC_Q15 ) ); + + FOR( n = 0; n < n_channels; n++ ) + { + st = sts[n]; + + /*------------------------------------------------------------------* + * Initialization per core-decoder channel + *-----------------------------------------------------------------*/ + + frameMode[n] = FRAMEMODE_NORMAL; + move32(); + st->rate_switching_reset = 0; + move16(); + st->mdct_sw = MODE1; + move16(); + sid_bw[n] = -1; + move16(); + core_switching_flag[n] = 0; + move16(); + sharpFlag[n] = 0; + move16(); + unbits[n] = 0; + move16(); + st->GSC_IVAS_mode = 0; + move16(); + st->element_brate = element_brate; + move32(); + st->use_partial_copy = 0; + move16(); + st->rf_flag = 0; + move16(); + st->rf_frame_type = RF_NO_DATA; + move16(); + + IF( EQ_16( st->bfi, 1 ) ) + { + frameMode[n] = FRAMEMODE_MISSING; + move32(); + st->coder_type = st->last_coder_type; + move16(); + } + ELSE + { + test(); + IF( !( EQ_16( st->element_mode, IVAS_CPE_TD ) && EQ_16( n, 1 ) ) ) /* coder_type for SCh in TD stereo is already read in tdm_configure_dec() */ + { + st->coder_type = INACTIVE; + move16(); + } + st->extl = -1; + move16(); + st->flagGuidedAcelp = 0; + move16(); + } + + test(); + test(); + test(); + test(); + test(); +#ifdef NONBE_MDCT_ST_PLC_DO_NOT_SCALE_OLD_OUT_IF_FIRST_GOOD_IS_SID + IF( !st->bfi && st->prev_bfi && GT_32( st->total_brate, SID_2k40 ) && ( EQ_16( st->last_core_bfi, TCX_20_CORE ) || EQ_16( st->last_core_bfi, TCX_10_CORE ) ) && st->hTcxDec != NULL ) +#else + IF( !st->bfi && st->prev_bfi && ( EQ_16( st->last_core_bfi, TCX_20_CORE ) || EQ_16( st->last_core_bfi, TCX_10_CORE ) ) && st->hTcxDec != NULL ) +#endif + { + conceal_eof_gain32 = L_shl( L_deposit_l( st->hTcxDec->conceal_eof_gain ), 1 ); + + FOR( i = 0; i < st->hTcxDec->L_frameTCX; i++ ) + { + L_tmp = Mpy_32_16_1( conceal_eof_gain32, st->hHQ_core->old_out_fx[i] ); + L_tmp = Mpy_32_16_1( L_tmp, st->last_concealed_gain_syn_deemph ); + L_tmp = L_shl( L_tmp, st->last_concealed_gain_syn_deemph_e ); + st->hHQ_core->old_out_fx[i] = extract_l( L_tmp ); // Q0 + move16(); + } + + FOR( i = 0; i < st->L_frame; i++ ) + { + L_tmp = Mpy_32_16_1( conceal_eof_gain32, st->hHQ_core->old_out_LB_fx[i] ); + L_tmp = Mpy_32_16_1( L_tmp, st->last_concealed_gain_syn_deemph ); + L_tmp = L_shl( L_tmp, st->last_concealed_gain_syn_deemph_e ); + st->hHQ_core->old_out_LB_fx[i] = extract_l( L_tmp ); // Q0 + move16(); + } + } + + set16_fx( voice_factors_fx[n], 0, NB_SUBFR16k ); + set32_fx( hb_synth_32_fx[n], 0, L_FRAME48k ); + set16_fx( hb_synth_16_fx[n], 0, L_FRAME48k ); + /*------------------------------------------------------------------* + * Decision matrix (selection of technologies) + *-----------------------------------------------------------------*/ + + test(); + test(); + IF( NE_16( st->bfi, 1 ) ) + { + ivas_decision_matrix_dec_fx( st, &sharpFlag[n], &core_switching_flag[n], element_brate, nchan_out ); + + synchonize_channels_mdct_sid_fx( sts, n ); + + IF( NE_16( st->bfi, 1 ) ) /* note: st->bfi can be changed from 0 to 1 in ivas_decision_matrix_dec() when BER is detected */ + { + st->sr_core = L_mult0( st->L_frame, FRAMES_PER_SEC ); + move32(); + st->fscale_old = st->fscale; + move16(); + st->fscale = sr2fscale_fx( st->sr_core ); + move16(); + } + ELSE + { + frameMode[n] = FRAMEMODE_MISSING; + move32(); + } + } + ELSE IF( GE_16( st->element_mode, IVAS_SCE ) && EQ_16( st->prev_bfi, 1 ) && EQ_16( st->last_con_tcx, 1 ) ) + { + st->core = TCX_20_CORE; + move16(); + } + } /* n_channels loop */ + + /* MDCT stereo -> DFT stereo switching */ + test(); + test(); + IF( hCPE != NULL && EQ_16( hCPE->last_element_mode, IVAS_CPE_MDCT ) && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) ) + { + Word16 ovl, fade_len; + IF( NE_16( sts[0]->L_frame, sts[0]->last_L_frame ) ) + { + Copy_Scale_sig_16_32( sts[0]->hHQ_core->old_out_LB_fx, sts[0]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, sts[0]->hHQ_core->Q_old_wtda_LB ) ); + L_lerp_fx_q11( sts[0]->hHQ_core->old_outLB_fx, sts[0]->hHQ_core->old_outLB_fx, sts[0]->L_frame, sts[0]->last_L_frame ); + Copy_Scale_sig_32_16( sts[0]->hHQ_core->old_outLB_fx, sts[0]->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( sts[0]->hHQ_core->Q_old_wtda_LB, Q11 ) ); + } + IF( NE_16( sts[0]->L_frame, L_FRAME16k ) ) + { + ovl = mult( sts[0]->L_frame, 5120 ); /*STEREO_DFT32MS_OVL_16k/L_FRAME16k = 5/32 = 5120 (Q15)*/ + L_lerp_fx_q11( hCPE->input_mem_LB_fx[0], hCPE->input_mem_LB_fx[0], ovl, STEREO_DFT32MS_OVL_16k ); + + fade_len = mult( sts[0]->L_frame, 12288 ); /* STEREO_MDCT2DFT_FADE_LEN_48k/L_FRAME16k = 3/8 = 12288 (Q15)*/ + L_lerp_fx_q11( hCPE->old_outLB_mdct_fx, hCPE->old_outLB_mdct_fx, fade_len, STEREO_MDCT2DFT_FADE_LEN_48k ); + } + } + + test(); + IF( hCPE != NULL && hCPE->hStereoCng != NULL ) + { + hCPE->hStereoCng->flag_cna_fade = 0; + move16(); + } + + test(); + test(); + test(); + IF( sba_dirac_stereo_flag && hSCE && LE_32( sts[0]->total_brate, SID_2k40 ) && EQ_16( sts[0]->cng_type, FD_CNG ) ) + { + save_hb_synth_32_fx = hSCE->save_hb_synth_fx; + } + ELSE + { + save_hb_synth_32_fx = NULL; + } + + /*------------------------------------------------------------------* + * Decode SID for MDCT-Stereo DTX mode + *-----------------------------------------------------------------*/ + + test(); + IF( EQ_16( sts[0]->element_mode, IVAS_CPE_MDCT ) && EQ_32( sts[0]->total_brate, SID_2k40 ) ) + { + IF( sts[0]->cng_sba_flag ) + { + FdCngDecodeDiracMDCTStereoSID_fx( hCPE ); + } + ELSE + { + FdCngDecodeMDCTStereoSID_fx( hCPE ); + } + } + + /*------------------------------------------------------------------* + * Sanity check in combined format coding + *-----------------------------------------------------------------*/ + + test(); + test(); + IF( hCPE != NULL && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && hCPE->brate_surplus > 0 ) + { + ivas_combined_format_brate_sanity_fx( hCPE->element_brate, sts[0]->core, sts[0]->total_brate, &( sts[0]->core_brate ), &( sts[0]->inactive_coder_type_flag ), &tmps ); + } + + /*------------------------------------------------------------------* + * Core Decoding + *-----------------------------------------------------------------*/ + + FOR( n = 0; n < n_channels; n++ ) + { + st = sts[n]; + + /*------------------------------------------------------------------* + * Initialization + *-----------------------------------------------------------------*/ + + IF( EQ_16( st->bfi, 1 ) ) + { + st->nbLostCmpt = add( st->nbLostCmpt, 1 ); + move16(); + } + ELSE + { + IF( EQ_16( st->prev_bfi, 1 ) ) + { + st->prev_nbLostCmpt = st->nbLostCmpt; + move16(); + } + ELSE + { + st->prev_nbLostCmpt = 0; + move16(); + } + + st->nbLostCmpt = 0; + move16(); + } + st->enablePlcWaveadjust = 0; + move16(); + + IF( EQ_16( n, 1 ) ) + { + sts[1]->BER_detect = s_or( sts[1]->BER_detect, sts[0]->BER_detect ); + move16(); + } + + /*---------------------------------------------------------------------* + * Detect bandwidth switching + *---------------------------------------------------------------------*/ + + bandwidth_switching_detect_ivas_fx( st ); + + /*---------------------------------------------------------------------* + * Preprocessing (preparing) for ACELP/HQ core switching + *---------------------------------------------------------------------*/ + Word16 Q_olapBufferSynth, Q_olapBufferSynth2; + + Q_olapBufferSynth = Q15; /*Initializing with max values to avoid warnings*/ + Q_olapBufferSynth2 = Q15; /*Initializing with max values to avoid warnings*/ + move16(); + move16(); + + Copy_Scale_sig_16_32( st->previoussynth_fx, st->previoussynth_fx_32, L_FRAME48k, 0 ); + + IF( NE_32( ( error = core_switching_pre_dec_ivas_fx( st, output_frame, sts[0]->last_core_brate, nchan_out, last_element_mode, last_element_brate, st->Q_syn, &Q_olapBufferSynth, &Q_olapBufferSynth2 ) ), IVAS_ERR_OK ) ) + { + return error; + } + + flag_sec_CNA = -1; + move16(); + IF( hCPE != NULL ) + { + flag_sec_CNA = sts[1]->flag_cna; + move16(); + } + + /*---------------------------------------------------------------------* + * ACELP core decoding + * TCX core decoding + * HQ core decoding + *---------------------------------------------------------------------*/ + + IF( EQ_16( st->core, ACELP_CORE ) ) + { + /* ACELP core decoder */ + Word16 old_syn_12k8_16k_fx_16[L_FRAME16k]; + set16_fx( output_16_fx[n], 0, L_FRAME48k ); + Word16 save_hb_synth_fx_arr[L_FRAME48k], *save_hb_synth_16_fx; + IF( save_hb_synth_32_fx ) + { + save_hb_synth_16_fx = save_hb_synth_fx_arr; + } + ELSE + { + save_hb_synth_16_fx = NULL; + } + + IF( st->cldfbAna ) + { + scale_sig32( st->cldfbAna->cldfb_state_fx, st->cldfbAna->cldfb_size, sub( Q11, Q10 ) ); + st->cldfbAna->Q_cldfb_state = Q11; + move16(); + } + IF( st->cldfbBPF ) + { + scale_sig32( st->cldfbBPF->cldfb_state_fx, st->cldfbBPF->cldfb_size, sub( Q10, Q11 ) ); + st->cldfbBPF->Q_cldfb_state = Q10; + move16(); + } + IF( st->cldfbSyn ) + { + scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->cldfb_size, sub( Q10, Q11 ) ); + st->cldfbSyn->Q_cldfb_state = Q10; + move16(); + } + + IF( st->hFdCngDec != NULL ) + { + Scale_sig32( st->hFdCngDec->msNoiseEst, NPART_SHAPING, sub( st->hFdCngDec->msNoiseEst_exp, 27 ) ); + st->hFdCngDec->msNoiseEst_exp = 27; + move16(); + + Scale_sig( st->hFdCngDec->hFdCngCom->A_cng, add( M, 1 ), sub( norm_s( sub( st->hFdCngDec->hFdCngCom->A_cng[0], 1 ) ), 3 ) ); + } + + IF( hCPE == NULL ) + { + IF( NE_32( ( error = acelp_core_dec_ivas_fx( st, output_16_fx[n], synth_16_fx[n], save_hb_synth_16_fx, bwe_exc_extended_fx[n], voice_factors_fx[n], old_syn_12k8_16k_fx_16, sharpFlag[n], pitch_buf_fx[n], &unbits[n], &sid_bw[n], hStereoTD, tdm_lspQ_PCh_fx, tdm_lsfQ_PCh_fx, use_cldfb_for_dft, last_element_mode, last_element_brate, flag_sec_CNA, nchan_out, NULL, read_sid_info ) ), IVAS_ERR_OK ) ) + { + return error; + } + } + ELSE + { + IF( NE_32( ( error = acelp_core_dec_ivas_fx( st, output_16_fx[n], synth_16_fx[n], save_hb_synth_16_fx, bwe_exc_extended_fx[n], voice_factors_fx[n], old_syn_12k8_16k_fx_16, sharpFlag[n], pitch_buf_fx[n], &unbits[n], &sid_bw[n], hStereoTD, tdm_lspQ_PCh_fx, tdm_lsfQ_PCh_fx, use_cldfb_for_dft, last_element_mode, last_element_brate, flag_sec_CNA, nchan_out, hCPE->hStereoCng, read_sid_info ) ), IVAS_ERR_OK ) ) + { + return error; + } + } + + Copy_Scale_sig_16_32( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, st->Q_syn2 ) ); + Scale_sig( output_16_fx[n], L_FRAME48k, negate( st->Q_syn2 ) ); + IF( st->cldfbAna ) + { + scale_sig32( st->cldfbAna->cldfb_state_fx, st->cldfbAna->cldfb_size, sub( Q10, Q11 ) ); /* 9 * (Word16)(st->L_frame * FRAMES_PER_SEC * INV_CLDFB_BANDWIDTH + 0.5f) */ + st->cldfbAna->Q_cldfb_state = Q10; + move16(); + } + IF( st->cldfbBPF ) + { + scale_sig32( st->cldfbBPF->cldfb_state_fx, st->cldfbBPF->cldfb_size, sub( Q11, Q10 ) ); + st->cldfbBPF->Q_cldfb_state = Q11; + move16(); + } + IF( st->cldfbSyn ) + { + scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->cldfb_size, sub( Q11, Q10 ) ); + st->cldfbSyn->Q_cldfb_state = Q11; + move16(); + } + st->prev_Q_syn = st->Q_syn; + move16(); + + if ( save_hb_synth_32_fx ) + { + Copy_Scale_sig_16_32( save_hb_synth_16_fx, save_hb_synth_32_fx, output_frame, Q11 ); + hSCE->q_save_hb_synth_fx = Q11; + move16(); + } + + Copy_Scale_sig_16_32( old_syn_12k8_16k_fx_16, old_syn_12k8_16k_fx[n], L_FRAME16k, sub( Q11, negate( Q1 ) ) ); + } + + Copy_Scale_sig_32_16( st->previoussynth_fx_32, st->previoussynth_fx, L_FRAME48k, 0 ); + + test(); + test(); + test(); + IF( ( EQ_16( st->core, TCX_20_CORE ) || EQ_16( st->core, TCX_10_CORE ) ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + Word16 Qsyn_temp; + STEREO_CNG_DEC_HANDLE hStereoCng; + IVAS_FORMAT ivas_format; + + Qsyn_temp = st->Q_syn; + move16(); + st->Q_syn = 0; + move16(); + st->prev_Q_syn = st->Q_syn; + move16(); + st->hTcxDec->conNoiseLevelIndex = st->hTcxDec->NoiseLevelIndex_bfi; + move16(); + st->hTcxDec->conCurrLevelIndex = st->hTcxDec->CurrLevelIndex_bfi; + move16(); + st->mem_error = st->hBPF->pst_mem_deemp_err_fx; + move32(); + + /* TCX decoder */ + Scale_sig( st->hPFstat->mem_stp, L_SUBFR, -Qsyn_temp ); + Scale_sig( st->hPFstat->mem_pf_in, L_SUBFR, -Qsyn_temp ); + Scale_sig32( st->hFdCngDec->msNoiseEst, NPART_SHAPING, sub( st->hFdCngDec->msNoiseEst_exp, 27 ) ); + st->hFdCngDec->msNoiseEst_exp = 27; + move16(); + Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, -st->hHQ_core->Q_old_wtda_LB ); + Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, -st->hHQ_core->Q_old_wtda ); + + IF( hCPE == NULL ) + { + hStereoCng = NULL; + } + ELSE + { + hStereoCng = hCPE->hStereoCng; + } + IF( st_ivas == NULL ) + { + ivas_format = 0; + move32(); + } + ELSE + { + ivas_format = st_ivas->ivas_format; + move32(); + } + stereo_tcx_core_dec_fx( st, frameMode[n], output_16_fx[n], synth_16_fx[n], pitch_buf_fx[n], sba_dirac_stereo_flag, hStereoTD, last_element_mode, flag_sec_CNA, hStereoCng, nchan_out, ivas_format ); + st->hHQ_core->Q_old_wtda_LB = st->hHQ_core->Q_old_wtda; + move16(); + Copy_Scale_sig_16_32( output_16_fx[n], output_32_fx[n], L_FRAME48k, Q11 ); + + IF( st->hTcxDec ) + { + st->hTcxDec->conNoiseLevelIndex = st->hTcxDec->NoiseLevelIndex_bfi; + move16(); + st->hTcxDec->conCurrLevelIndex = st->hTcxDec->CurrLevelIndex_bfi; + move16(); + st->hTcxDec->conLastFrameLevel = st->hTcxDec->LastFrameLevel_bfi_fx; + move16(); + } + st->hBPF->pst_mem_deemp_err_fx = extract_l( st->mem_error ); + move16(); + } + + IF( EQ_16( st->core, HQ_CORE ) ) + { + /* HQ core decoder */ + Word16 Q_output; + + Q_output = 0; + move16(); + Q_synth = 0; + move16(); + + ivas_hq_core_dec_fx( st, synth_16_fx[n], &Q_synth, output_frame, NORMAL_HQ_CORE, core_switching_flag[n], output_16_fx[n], &Q_output ); + + Copy_Scale_sig_16_32( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_output ) ); +#ifdef MSAN_FIX + Scale_sig( synth_16_fx[n], output_frame, negate( Q_synth ) ); +#else + Scale_sig( synth_16_fx[n], L_FRAME48k, negate( Q_synth ) ); +#endif + Scale_sig( output_16_fx[n], L_FRAME48k, negate( Q_output ) ); + } + + /*---------------------------------------------------------------------* + * TD stereo updates + *---------------------------------------------------------------------*/ + + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && n == 0 ) + { + Copy_Scale_sig_32_16( hCPE->hCoreCoder[0]->old_pitch_buf_fx, hCPE->hCoreCoder[0]->old_pitch_buf_16_fx, add( imult1616( 2, NB_SUBFR16k ), 2 ), negate( Q10 ) ); + + td_stereo_param_updt_fx( st->lsp_old_fx, st->lsf_old_fx, st->old_pitch_buf_16_fx + st->nb_subfr, + tdm_lspQ_PCh_fx, tdm_lsfQ_PCh_fx, hStereoTD->tdm_Pri_pitch_buf_fx, st->flag_ACELP16k, hStereoTD->tdm_use_IAWB_Ave_lpc +#ifndef FIX_798_WRONG_CPY_OF_PITCH + , + Q6 +#endif + ); + + Copy_Scale_sig_16_32( hCPE->hCoreCoder[0]->old_pitch_buf_16_fx, hCPE->hCoreCoder[0]->old_pitch_buf_fx, add( imult1616( 2, NB_SUBFR16k ), 2 ), Q10 ); + } + + } /* n_channels loop */ + + + /*---------------------------------------------------------------------* + * MDCT stereo: joint TCX Core Decoding + *---------------------------------------------------------------------*/ + + IF( EQ_16( sts[0]->element_mode, IVAS_CPE_MDCT ) ) + { + /* active-frame decoding */ + IF( GT_32( sts[0]->core_brate, SID_2k40 ) ) + { + IF( hMCT ) + { + FOR( n = 0; n < n_channels; n++ ) + { + st = sts[n]; + IF( st->cldfbAna ) + { + scale_sig32( st->cldfbAna->cldfb_state_fx, st->cldfbAna->cldfb_size, sub( Q11, Q10 ) ); + st->cldfbAna->Q_cldfb_state = Q11; + move16(); + } + IF( st->cldfbSynHB ) + { + scale_sig32( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->cldfb_size, sub( Q11, Q10 ) ); + st->cldfbSynHB->Q_cldfb_state = Q11; + move16(); + } + } + + pop_wmops(); + return error; + } + ELSE + { + Word16 e_sig; + Word16 ch; + + e_sig = 17; + move16(); + sts = hCPE->hCoreCoder; + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + st = sts[ch]; + + st->last_gain_syn_deemph = 0; + move16(); + IF( st->hHQ_core ) + { + st->hHQ_core->Q_fer_samples = 0; + move16(); + } +#ifdef FIX_778_STEREO_BRATE_SWITCHING + st->Q_syn = 0; + move16(); +#endif + st->prev_Q_syn = st->Q_syn; + move16(); + + Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, sub( st->Q_syn, st->hHQ_core->Q_old_wtda_LB ) ); + Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, sub( st->Q_syn, st->hHQ_core->Q_old_wtda ) ); + + IF( st->hTcxDec ) + { + st->hTcxDec->conNoiseLevelIndex = st->hTcxDec->NoiseLevelIndex_bfi; + move16(); + } + IF( st->hTcxDec ) + { + st->hTcxDec->conCurrLevelIndex = st->hTcxDec->CurrLevelIndex_bfi; + move16(); + } + } + + stereo_mdct_core_dec_fx( st_ivas, hCPE, output_32_fx, synth_16_fx ); + + FOR( ch = 0; ch < 2; ch++ ) + { + st = hCPE->hCoreCoder[ch]; + st->hHQ_core->Q_old_wtda_LB = st->Q_syn; + move16(); + st->hHQ_core->Q_old_wtda = st->Q_syn; + move16(); + } + +#ifdef MSAN_FIX + Scale_sig( synth_16_fx[0], hCPE->hCoreCoder[0]->hTcxDec->L_frameTCX, sub( e_sig, 15 ) ); + Scale_sig( synth_16_fx[1], hCPE->hCoreCoder[1]->hTcxDec->L_frameTCX, sub( e_sig, 15 ) ); +#else + Scale_sig( synth_16_fx[0], L_FRAME48k, sub( e_sig, 15 ) ); + Scale_sig( synth_16_fx[1], L_FRAME48k, sub( e_sig, 15 ) ); +#endif + } + } + /* for inactive frames with mono output, copy and (if necessary) downmix buffers */ + ELSE IF( EQ_16( hCPE->nchan_out, 1 ) ) + { + sts[0] = hCPE->hCoreCoder[0]; + sts[1] = hCPE->hCoreCoder[1]; + + IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) ) + { + sts[0]->hHQ_core->exp_old_out = sub( 15, sts[0]->hHQ_core->Q_old_wtda ); + move16(); + sts[1]->hHQ_core->exp_old_out = sub( 15, sts[1]->hHQ_core->Q_old_wtda ); + move16(); + } + updateBuffersForDmxMdctStereo_fx( hCPE, output_frame, output_32_fx[0], output_32_fx[1], synth_16_fx ); + + IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) ) + { + sts[0]->hHQ_core->Q_old_wtda = sub( 15, sts[0]->hHQ_core->exp_old_out ); + move16(); + sts[1]->hHQ_core->Q_old_wtda = sub( 15, sts[1]->hHQ_core->exp_old_out ); + move16(); + } + } + + test(); + test(); +#ifdef NONBE_MDCT_ST_DTX_SKIP_DEWHITENING_OF_NOISE_SHAPES_ON_SID_FRAMES + /* On first good active frame after frameloss undo the whitening of the bg noise shape */ + IF( GT_32( sts[0]->core_brate, SID_2k40 ) && sts[0]->bfi == 0 && EQ_16( sts[0]->prev_bfi, 1 ) ) +#else + IF( sts[0]->bfi == 0 && EQ_16( sts[0]->prev_bfi, 1 ) ) + /* On first good frame after frameloss undo the whitening of the bg noise shape */ +#endif + { + FOR( n = 0; n < n_channels; ++n ) + { + IF( NE_16( sts[n]->last_core_bfi, ACELP_CORE ) ) + { + Scale_sig32( sts[n]->hFdCngDec->hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, sub( sts[n]->hFdCngDec->hFdCngCom->cngNoiseLevelExp, 27 ) ); + sts[n]->hFdCngDec->hFdCngCom->cngNoiseLevelExp = 27; + move16(); + + TonalMdctConceal_whiten_noise_shape_ivas_fx( sts[n], L_FRAME16k, ON_FIRST_GOOD_FRAME ); + } + } + } + } + + /*---------------------------------------------------------------------* + * Stereo CNG updates + *---------------------------------------------------------------------*/ + + test(); + IF( EQ_16( sts[0]->element_mode, IVAS_CPE_TD ) && hCPE->hStereoCng != NULL ) + { + /* To be cleaned up once the caller function is converted // These changes are for system testing of fixed changes made */ + Word16 Q_c_PS_LT, Q_output; + Word32 c_PS_LT_fx; + + Q_c_PS_LT = 31; + move16(); + Q_output = 11; + move16(); + c_PS_LT_fx = L_deposit_h( hCPE->hStereoCng->c_PS_LT_fx ); + Q_c_PS_LT = Q31; + move16(); + + stereo_cng_compute_PScorr_fx( output_32_fx[0], output_32_fx[1], &Q_output, &c_PS_LT_fx, Q_c_PS_LT, sts[0]->L_frame, sts[1]->L_frame ); + + hCPE->hStereoCng->c_PS_LT_fx = extract_h( c_PS_LT_fx ); + } + + /*---------------------------------------------------------------------* + * Postprocessing, BWEs and updates + *---------------------------------------------------------------------*/ + + FOR( n = 0; n < n_channels; n++ ) + { + st = sts[n]; + + /*---------------------------------------------------------------------* + * TD-BWE for ACELP to TCX transitions + *---------------------------------------------------------------------*/ + + /*core_switching_post_dec*/ + Q_synth = 0; + move16(); + if ( st->hHQ_core != NULL ) + { + st->hHQ_core->Q_old_postdec = 0; + move16(); + } + + /*------------------fix-to-fix-end-----------------------*/ + + Word16 output_mem_16_fx[L_FRAME48k]; + Word16 *p_output_mem_16; + + IF( p_output_mem_fx != NULL ) + { + p_output_mem_16 = output_mem_16_fx; + Copy_Scale_sig_32_16( p_output_mem_fx, p_output_mem_16, NS2SA_FX2( output_Fs, STEREO_DFT32MS_OVL_NS ), negate( Q11 ) ); + } + ELSE + { + p_output_mem_16 = NULL; + set16_fx( output_mem_16_fx, 0, NS2SA( st->output_Fs, 3125000 ) ); + } + + Scale_sig32( output_32_fx[n], L_FRAME48k, sub( Q4, Q11 ) ); + + IF( st->hHQ_core != NULL ) + { + Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, negate( st->hHQ_core->Q_old_wtda ) ); + st->hHQ_core->Q_old_wtda = 0; + move16(); + } + + /*size of synth is choosen as delay comp to start with*/ + /*-------------------cldfb-start-------------------------*/ + + IF( st->cldfbSyn != NULL ) + { + scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q4, Q11 ) ); + st->cldfbSyn->Q_cldfb_state = Q4; + move16(); + } + + Word16 q_audio, old_syn_fx; + old_syn_fx = Q11; + move16(); + q_audio = Q12; + move16(); + test(); + test(); + test(); + test(); + IF( EQ_16( st->last_core, ACELP_CORE ) && ( EQ_16( st->core, TCX_20_CORE ) || EQ_16( st->core, TCX_10_CORE ) || EQ_16( st->core, HQ_CORE ) ) && st->hBWE_TD != NULL ) + { + test(); + test(); + test(); + test(); + IF( ( EQ_16( st->bwidth, SWB ) || EQ_16( st->bwidth, FB ) ) && ( EQ_16( st->last_extl, SWB_TBE ) || EQ_16( st->last_extl, FB_TBE ) ) ) + { + GenTransition_fixed( st->hBWE_TD, hb_synth_32_fx[n], output_Fs, st->element_mode, st->L_frame, st->rf_flag, st->total_brate ); + } + ELSE IF( EQ_16( st->bwidth, WB ) && EQ_16( st->last_extl, WB_TBE ) ) + { + GenTransition_WB_fixed( st->hBWE_TD, hb_synth_32_fx[n], output_Fs ); + } + + /* Memories Scaling */ + Copy_Scale_sig_32_16( st->hBWE_TD->syn_overlap_fx_32, st->hBWE_TD->syn_overlap_fx, L_SHB_LAHEAD, sub( st->prev_Q_bwe_syn2, Q11 ) ); + Copy_Scale_sig_32_16( st->hBWE_TD->old_tbe_synth_fx_32, st->hBWE_TD->old_tbe_synth_fx, L_SHB_TRANSITION_LENGTH, sub( st->prev_Qx, Q11 ) ); + Copy_Scale_sig_32_16( st->hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, st->hBWE_TD->state_lsyn_filt_dwn_shb_fx, shl( ALLPASSSECTIONS_STEEP, 1 ), sub( st->prev_Qx, Q11 ) ); + Copy_Scale_sig_32_16( st->hBWE_TD->state_lsyn_filt_shb_fx_32, st->hBWE_TD->state_lsyn_filt_shb_fx, shl( ALLPASSSECTIONS_STEEP, 1 ), sub( st->prev_Qx, Q11 ) ); + Copy_Scale_sig_32_16( st->hBWE_TD->mem_resamp_HB_fx_32, st->hBWE_TD->mem_resamp_HB_fx, INTERP_3_1_MEM_LEN, sub( st->prev_Qx, Q11 ) ); + } + + /* Memories Re-Scaling */ + IF( st->hBWE_TD != NULL ) + { + Copy_Scale_sig_16_32( st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->syn_overlap_fx_32, L_SHB_LAHEAD, sub( Q11, st->prev_Q_bwe_syn2 ) ); + Copy_Scale_sig_16_32( st->hBWE_TD->old_tbe_synth_fx, st->hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, st->prev_Qx ) ); + Copy_Scale_sig_16_32( st->hBWE_TD->state_lsyn_filt_dwn_shb_fx, st->hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, shl( ALLPASSSECTIONS_STEEP, 1 ), sub( Q11, st->prev_Qx ) ); + Copy_Scale_sig_16_32( st->hBWE_TD->state_lsyn_filt_shb_fx, st->hBWE_TD->state_lsyn_filt_shb_fx_32, shl( ALLPASSSECTIONS_STEEP, 1 ), sub( Q11, st->prev_Qx ) ); + Copy_Scale_sig_16_32( st->hBWE_TD->mem_resamp_HB_fx, st->hBWE_TD->mem_resamp_HB_fx_32, INTERP_3_1_MEM_LEN, sub( Q11, st->prev_Qx ) ); + Copy( st->hBWE_TD->mem_resamp_HB_fx, st->hBWE_TD->state_32and48k_WB_upsample_fx, imult1616( 2, ALLPASSSECTIONS_STEEP ) ); + } + /*---------------------------------------------------------------------* + * Postprocessing for ACELP/MDCT core switching + *---------------------------------------------------------------------*/ + + /* save synth and output in case of SBA DirAC stereo output as core switching is done outside of core decoder */ + test(); + test(); + test(); + IF( sba_dirac_stereo_flag && NE_16( st->element_mode, IVAS_CPE_MDCT ) && !( EQ_32( st->core_brate, SID_2k40 ) && EQ_16( st->cng_type, FD_CNG ) ) ) + { + Copy_Scale_sig_16_32( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); + } + + IVAS_FORMAT ivas_format; + IF( st_ivas != NULL ) + { + ivas_format = st_ivas->ivas_format; + move32(); + } + ELSE + { + ivas_format = UNDEFINED_FORMAT; + move32(); + } + IF( hCPE != NULL ) + { + last_element_mode = hCPE->last_element_mode; + move16(); + } + ELSE + { + last_element_mode = IVAS_SCE; + move16(); + } + IF( NE_32( ( error = core_switching_post_dec_ivas_fx( st, synth_16_fx[n], output_32_fx[n], p_output_mem_16, ivas_format, use_cldfb_for_dft, output_frame, 0 /*core_switching_flag*/, sba_dirac_stereo_flag, nchan_out, last_element_mode, &Q_synth ) ), IVAS_ERR_OK ) ) + { + return error; + } + + /* for FD-CNG we need the delay compensation in the synth, so do this afterwards */ + test(); + test(); + test(); + IF( sba_dirac_stereo_flag && hSCE && EQ_32( st->core_brate, SID_2k40 ) && EQ_16( st->cng_type, FD_CNG ) ) + { + Copy_Scale_sig_16_32( synth_16_fx[n], hSCE->save_synth_fx, output_frame, sub( hSCE->q_save_synth_fx, Q_synth ) ); + } + + /* if we transition from inactive to active coding in MDCT-Stereo DTX and the output format is mono DMX, we need to sync the upsampled buffer between channels here */ + test(); + test(); + test(); + test(); + test(); + test(); + IF( n == 0 && EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_16( st->last_core, ACELP_CORE ) && NE_16( st->core, ACELP_CORE ) && ( EQ_16( nchan_out, 1 ) || ( hCPE != NULL && EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) ) ) ) + { + Copy( sts[0]->previoussynth_fx, sts[1]->previoussynth_fx, st->hTcxDec->L_frameTCX ); + } + /*---------------------------------------------------------------------* + * Pre-processing for bandwidth switching + *---------------------------------------------------------------------*/ + + ivas_bw_switching_pre_proc_fx( st, last_element_brate, nchan_out, old_syn_12k8_16k_fx[n], old_syn_fx, q_audio ); + + Copy_Scale_sig_16_32( st->delay_buf_out_fx, st->delay_buf_out32_fx, imult1616( HQ_DELTA_MAX, HQ_DELAY_COMP ), Q11 ); + Scale_sig32( output_32_fx[n], L_FRAME48k, sub( Q11, Q4 ) ); + + + /*note : cldfb_size here signifies the original size which was assigned to cldfb_state_fx buffer not its current size*/ + + IF( st->cldfbSyn != NULL ) + { + scale_sig32( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->p_filter_length, sub( Q11, Q4 ) ); + st->cldfbSyn->Q_cldfb_state = Q11; + move16(); + } + +#ifdef MSAN_FIX + Scale_sig( synth_16_fx[n], output_frame, negate( Q_synth ) ); +#else + Scale_sig( synth_16_fx[n], L_FRAME48k, negate( Q_synth ) ); +#endif + + /*------------------reset-code-start---------------------*/ + + test(); + test(); + IF( NE_16( st->last_extl, WB_BWE ) && EQ_16( st->extl, WB_BWE ) && st->hBWE_FD != NULL ) + { + test(); + if ( NE_16( st->last_extl, SWB_BWE ) && NE_16( st->last_extl, FB_BWE ) ) + { + st->hBWE_FD->prev_mode = st->hBWE_FD->prev_mode; + move16(); + } + st->hBWE_FD->prev_L_swb_norm = st->hBWE_FD->prev_L_swb_norm; + move16(); + st->hBWE_FD->prev_flag = st->hBWE_FD->prev_flag; + move16(); + } + + /*---------------------------------------------------------------------* + * WB TBE decoding + * WB BWE decoding + *---------------------------------------------------------------------*/ + + Word16 Q_input, Q_hb_synth_fx, Q_synth_fx; + Word16 Q_syn_hb; + + Q_input = 0; + move16(); + Q_hb_synth_fx = 0; + move16(); + Q_synth_fx = 0; + move16(); + + FD_BWE_DEC_HANDLE hBWE_FD; + hBWE_FD = st->hBWE_FD; + + Copy_Scale_sig_32_16( output_32_fx[n], output_16_fx[n], L_FRAME48k, negate( Q11 ) ); + Copy_Scale_sig_32_16( hb_synth_32_fx[n], hb_synth_16_fx[n], L_FRAME48k, negate( Q11 ) ); + test(); + test(); + test(); + test(); + test(); + test(); + IF( EQ_16( st->extl, WB_TBE ) ) + { + /* WB TBE decoder */ + + ivas_wb_tbe_dec_fx( st, st->coder_type, bwe_exc_extended_fx[n], st->Q_exc, voice_factors_fx[n], hb_synth_16_fx[n], &Q_hb_synth_fx ); + } + ELSE IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && EQ_16( n, 1 ) && !tdm_LRTD_flag && NE_16( st->extl, -1 ) && st->bws_cnt == 0 && st->extl_brate == 0 ) + { + /* do nothing */ + } + ELSE IF( EQ_16( st->extl, WB_BWE ) && st->bws_cnt == 0 ) + { + /* WB BWE decoder */ + Q_hb_synth_fx = ivas_wb_bwe_dec_fx( st, output_16_fx[n], synth_16_fx[n], hb_synth_16_fx[n], use_cldfb_for_dft, output_frame, voice_factors_fx[n], pitch_buf_fx[n], &Q_synth_fx ); + } + + /* Memories Re-Scaling */ + Copy_Scale_sig_16_32( hb_synth_16_fx[n], hb_synth_32_fx[n], L_FRAME48k, sub( Q11, Q_hb_synth_fx ) ); + Copy_Scale_sig_16_32( output_16_fx[n], output_32_fx[n], L_FRAME48k, sub( Q11, Q_input ) ); + Copy_Scale_sig_16_32( synth_16_fx[n], synth_32_fx[n], L_FRAME48k, sub( Q11, Q_synth_fx ) ); + + IF( hBWE_FD != NULL ) + { + Copy_Scale_sig_16_32( hBWE_FD->L_old_wtda_swb_fx, hBWE_FD->L_old_wtda_swb_fx32, L_FRAME48k, sub( Q11, hBWE_FD->old_wtda_swb_fx_exp ) ); + } + IF( st->hBWE_TD != NULL ) + { + Copy_Scale_sig_16_32( st->hBWE_TD->old_tbe_synth_fx, st->hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH, sub( Q11, st->prev_Qx ) ); + } + + /*---------------------------------------------------------------------* + * SWB(FB) TBE decoding + * SWB(FB) BWE decoding + *---------------------------------------------------------------------*/ + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) || ( NE_16( st->coder_type, AUDIO ) && NE_16( st->coder_type, INACTIVE ) && GE_32( st->core_brate, SID_2k40 ) && EQ_16( st->core, ACELP_CORE ) && !st->con_tcx && GE_32( output_Fs, 32000 ) && GT_16( st->bwidth, NB ) && st->bws_cnt > 0 ) ) + { + /* SWB TBE decoder */ + Q_white_exc = 0; + move16(); + + ivas_swb_tbe_dec_fx( st, hStereoICBWE, bwe_exc_extended_fx[n], st->Q_exc, voice_factors_fx[n], old_syn_12k8_16k_fx[n], tmp_buffer_fx /*fb_exc*/, hb_synth_32_fx[n], pitch_buf_fx[n], &Q_white_exc ); + + Copy_Scale_sig_32_16( st->hBWE_TD->old_tbe_synth_fx_32, st->hBWE_TD->old_tbe_synth_fx, L_SHB_TRANSITION_LENGTH, sub( st->prev_Qx, Q11 ) ); + + IF( GT_16( Q_white_exc, 31 ) ) + { + Scale_sig( tmp_buffer_fx, L_FRAME48k, sub( 31, Q_white_exc ) ); + Q_white_exc = 31; + move16(); + } + + /* FB TBE decoder */ + IF( EQ_16( st->extl, FB_TBE ) ) + { + fb_tbe_dec_ivas_fx( st, tmp_buffer_fx /*fb_exc*/, Q_white_exc, hb_synth_32_fx[n], 0, tmp_buffer_fx /*fb_synth_ref*/, Q_white_exc, output_frame ); + } + } + ELSE IF( EQ_16( st->extl, SWB_BWE ) || EQ_16( st->extl, FB_BWE ) || ( GE_32( output_Fs, 32000 ) && st->core == ACELP_CORE && st->bwidth > NB && st->bws_cnt > 0 && !st->ppp_mode_dec && !( EQ_16( st->nelp_mode_dec, 1 ) && EQ_16( st->bfi, 1 ) ) ) ) + { + /* SWB BWE decoder */ + Q_syn_hb = swb_bwe_dec_fx32( st, output_32_fx[n], synth_32_fx[n], hb_synth_32_fx[n], use_cldfb_for_dft, output_frame ); + + Scale_sig32( hb_synth_32_fx[n], output_frame, sub( Q11, Q_syn_hb ) ); + + Copy_Scale_sig_32_16( st->hBWE_FD->L_old_wtda_swb_fx32, st->hBWE_FD->L_old_wtda_swb_fx, output_frame, sub( hBWE_FD->old_wtda_swb_fx_exp, Q11 ) ); + } + + /*---------------------------------------------------------------------* + * FEC - recovery after lost HQ core (smoothing of the BWE component) + *---------------------------------------------------------------------*/ + + test(); + test(); + IF( st->prev_bfi && EQ_16( st->last_core, HQ_CORE ) && NE_16( st->extl, -1 ) ) + { + /*tmp = FRAC_BWE_SMOOTH/output_frame;*/ + tmp16 = shr( 410, shr( output_frame, 8 ) ); /* Q15 */ + IF( EQ_16( output_frame, L_FRAME48k ) ) + { + tmp16 = 68; + move16(); + } + /*output_frame/FRAC_BWE_SMOOTH*/ + j = shr( output_frame, 1 ); + tmp16_2 = 0; + move16(); + FOR( i = 0; i < j; i++ ) + { + hb_synth_32_fx[n][i] = Mpy_32_16_1( hb_synth_32_fx[n][i], tmp16_2 ); /* Q11 */ + move32(); +#ifdef BASOP_NOGLOB + tmp16_2 = add_o( tmp16_2, tmp16, &Overflow ); /* Q15 */ +#else + tmp16_2 = add( tmp16_2, tmp16 ); +#endif + } + } + + /*---------------------------------------------------------------------* + * SWB CNG + *---------------------------------------------------------------------*/ + + test(); + test(); + test(); + test(); + IF( ( GE_16( output_frame, L_FRAME32k ) && st->hTdCngDec != NULL ) || ( EQ_16( st->element_mode, IVAS_CPE_DFT ) && GE_16( st->bwidth, SWB ) && st->hTdCngDec != NULL ) ) + { + /* SHB CNG decoder */ + Word16 synth_fxl[960]; /* Q-2 */ + Word16 q; + + q = 2; + move16(); + Copy_Scale_sig_32_16( hb_synth_32_fx[n], hb_synth_16_fx[n], L_FRAME48k, negate( add( Q11, q ) ) ); +#ifdef MSAN_FIX + Copy_Scale_sig_32_16( synth_32_fx[n], synth_fxl, output_frame, negate( add( Q11, q ) ) ); +#else + Copy_Scale_sig_32_16( synth_32_fx[n], synth_fxl, L_FRAME48k, negate( add( Q11, q ) ) ); +#endif + Scale_sig( st->hBWE_TD->state_lpc_syn_fx, LPC_SHB_ORDER, sub( Q8, st->prev_Q_bwe_syn ) ); + Scale_sig32( st->hBWE_TD->genSHBsynth_Hilbert_Mem_fx, HILBERT_MEM_SIZE, sub( st->prev_Q_bwe_syn2, Q11 ) ); + Copy_Scale_sig_32_16( st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, imult1616( 2, ALLPASSSECTIONS_STEEP ), sub( st->prev_Q_bwe_syn2, Q11 ) ); + + swb_CNG_dec_ivas_fx( st, synth_fxl, hb_synth_16_fx[n], sid_bw[n], negate( q ) ); + + test(); + IF( st->core_brate == FRAME_NO_DATA || EQ_32( st->core_brate, SID_2k40 ) ) + { + Copy_Scale_sig_16_32( hb_synth_16_fx[n], hb_synth_32_fx[n], L_FRAME48k, ( Q11 + q ) ); + } + +#ifndef FIX_826_PRECISION_LOST_AND_COMPL + Copy_Scale_sig_16_32( synth_fxl, synth_32_fx[n], L_FRAME48k, ( Q11 + q ) ); +#endif + Scale_sig( st->hBWE_TD->state_lpc_syn_fx, LPC_SHB_ORDER, -( Q8 - st->prev_Q_bwe_syn ) ); + Scale_sig32( st->hBWE_TD->genSHBsynth_Hilbert_Mem_fx, HILBERT_MEM_SIZE, -( st->prev_Q_bwe_syn2 - Q11 ) ); + Copy_Scale_sig_16_32( st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, 2 * ALLPASSSECTIONS_STEEP, -( st->prev_Q_bwe_syn2 - Q11 ) ); + } + + /*-------------------------------------------------------------------* + * Inter-channel BWE decoding + *-------------------------------------------------------------------*/ + test(); + IF( n == 0 && GE_16( st->element_mode, IVAS_CPE_DFT ) ) + { + Word16 q; + q = 11; + move16(); + + IF( hCPE->hStereoDft != NULL ) + { + hCPE->hStereoDft->td_gain_fx[0] = 1; + move32(); + } + Scale_sig( tmp_buffer_fx, L_FRAME48k, sub( 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 + test(); + test(); + test(); + test(); + test(); + test(); + 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 ) && 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 ) ); + } +#else + Scale_sig32( hb_synth_32_fx[0], L_FRAME48k, sub( Q11, q ) ); + Scale_sig32( hb_synth_32_fx[1], L_FRAME48k, sub( Q11, q ) ); +#endif + } + + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + /*----------------------------------------------------------------* + * BFI waveform adjustment + *----------------------------------------------------------------*/ + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( EQ_16( st->core, ACELP_CORE ) && !st->bfi && st->prev_bfi && GE_32( st->last_total_brate, HQ_48k ) && EQ_16( st->last_codec_mode, MODE2 ) && ( EQ_16( st->last_core_bfi, TCX_20_CORE ) || EQ_16( st->last_core_bfi, TCX_10_CORE ) ) && EQ_16( st->hPlcInfo->concealment_method, TCX_NONTONAL ) && LT_16( st->hPlcInfo->nbLostCmpt, 4 ) ) + { + tmps = NS2SA_FX2( output_Fs, DELAY_CLDFB_NS ); + + waveform_adj2_fix( st->hTonalMDCTConc->secondLastPcmOut, synth_16_fx[n] + tmps, st->plcInfo.data_noise, &st->plcInfo.outx_new_n1_fx, + &st->plcInfo.nsapp_gain_fx, &st->plcInfo.nsapp_gain_n_fx, &st->plcInfo.recovery_gain, st->plcInfo.step_concealgain_fx, + st->plcInfo.Pitch_fx, st->plcInfo.FrameSize, tmps, add( st->hPlcInfo->nbLostCmpt, 1 ), st->bfi ); + + st->hPlcInfo->Pitch = 0; + move16(); + } + } + + /*----------------------------------------------------------------* + * Transition and synchronization of BWE components + *----------------------------------------------------------------*/ + + test(); + test(); + test(); + test(); + IF( ( NE_16( st->extl, -1 ) && ( NE_16( st->extl, IGF_BWE ) || st->last_core == ACELP_CORE ) ) || ( st->bws_cnt > 0 && st->core == ACELP_CORE ) ) + { + /* Calculate an additional delay of extension layer components to be synchronized with ACELP synthesis */ + IF( EQ_16( st->L_frame, L_FRAME ) ) + { + /* TBE on top of ACELP@12.8kHz */ + tmps = NS2SA( output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_12k8_NS ); + } + ELSE + { + test(); + IF( EQ_16( st->extl, SWB_BWE_HIGHRATE ) || EQ_16( st->extl, FB_BWE_HIGHRATE ) ) + { + /* HR SWB BWE on top of ACELP@16kHz */ + tmps = NS2SA( output_Fs, DELAY_BWE_TOTAL_NS ); + } + ELSE + { + /* TBE on top of ACELP@16kHz */ + tmps = NS2SA( output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_16k_NS ); + } + } + + /* Smooth transitions when switching between different technologies */ + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( !( ( EQ_16( st->core, TCX_20_CORE ) || EQ_16( st->core, TCX_10_CORE ) || EQ_16( st->core, HQ_CORE ) ) && st->last_core == ACELP_CORE ) && + ( NE_16( st->extl, st->last_extl ) || ( EQ_16( st->extl, st->last_extl ) && s_xor( st->core, st->last_core ) == HQ_CORE ) ) && !( EQ_16( st->extl, SWB_CNG ) && EQ_16( st->last_extl, SWB_TBE ) ) && ( NE_16( st->element_mode, IVAS_CPE_TD ) || ( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) && tdm_LRTD_flag ) ) ) + { + /* switching between BWE and TBE technologies */ + incr = idiv1616( imult1616( L_FRAME, 2 ), add( shl( tmps, 1 ), 1 ) ); + tmp16 = 0; + move16(); + FOR( i = 0; i < tmps; i++ ) + { + hb_synth_32_fx[n][i] = Mpy_32_16_1( hb_synth_32_fx[n][i], sin_table256_fx[tmp16] ); + move16(); + tmp16 = add( tmp16, incr ); + } + + set16_fx( st->hb_prev_synth_buffer_fx, 0, tmps ); + } + ELSE IF( LT_16( tmps, st->old_bwe_delay ) ) + { + /* the previous frame was TBE on top of ACELP@16kHz and the current frame is TBE on top of ACELP@12.8kHz */ + + incr = idiv1616( imult1616( L_FRAME, 2 ), add( shl( tmps, 1 ), 1 ) ); + tmp16 = 0; + move16(); + FOR( i = 0; i < tmps; i++ ) + { + +#ifndef FIX_826_PRECISION_LOST_AND_COMPL + tmp_buffer_fx[i] = round_fx( L_add( L_shr( L_mult( st->hb_prev_synth_buffer_fx[i], sin_table256_fx[255 - tmp16] ), 1 ), L_shr( L_mult( st->hb_prev_synth_buffer_fx[sub( sub( st->old_bwe_delay, 1 ), i )], sin_table256_fx[tmp16] ), 1 ) ) ); + move16(); + tmp_buffer_fx[i] = shl_sat( tmp_buffer_fx[i], 1 ); + move16(); +#else + tmp_buffer_fx[i] = round_fx_sat( L_mac_sat( L_mult( st->hb_prev_synth_buffer_fx[i], sin_table256_fx[255 - tmp16] ), st->hb_prev_synth_buffer_fx[sub( sub( st->old_bwe_delay, 1 ), i )], sin_table256_fx[tmp16] ) ); + move16(); +#endif + + tmp16 = add( tmp16, incr ); + } + Copy( tmp_buffer_fx, st->hb_prev_synth_buffer_fx, tmps ); + } + ELSE IF( GT_16( tmps, st->old_bwe_delay ) ) + { + /* the previous frame was TBE on top of ACELP@12.8kHz and the current frame is TBE on top of ACELP@16kHz */ + incr = idiv1616( imult1616( L_FRAME, 2 ), add( shl( st->old_bwe_delay, 1 ), 1 ) ); + tmp16 = 0; + move16(); + FOR( i = 0; i < st->old_bwe_delay; i++ ) + { + tmp_buffer_fx[i] = mult_r( st->hb_prev_synth_buffer_fx[i], sin_table256_fx[255 - tmp16] ); + move16(); + tmp16 = add( tmp16, incr ); + } + FOR( ; i < tmps; i++ ) + { + tmp_buffer_fx[i] = 0; + move16(); + } + tmp16 = 0; + move16(); + FOR( i = 0; i < st->old_bwe_delay; i++ ) + { + tmp_buffer_fx[sub( sub( tmps, 1 ), i )] = round_fx( L_mac( L_mult( tmp_buffer_fx[sub( sub( tmps, 1 ), i )], 32767 ), st->hb_prev_synth_buffer_fx[sub( sub( st->old_bwe_delay, 1 ), i )], sin_table256_fx[tmp16 /*i * incr*/] ) ); + move16(); + tmp16 = add( tmp16, incr ); + } + + Copy( tmp_buffer_fx, st->hb_prev_synth_buffer_fx, tmps ); + } + + test(); + test(); + test(); + IF( ( NE_16( st->element_mode, IVAS_CPE_TD ) && !use_cldfb_for_dft ) || ( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) && tdm_LRTD_flag ) ) + { + /* Delay hb_synth */ + Word32 hb_prev_synth_buffer_fx_32[111]; + + Copy_Scale_sig_16_32( st->hb_prev_synth_buffer_fx, hb_prev_synth_buffer_fx_32, 111, 11 ); + delay_signal_fx( hb_synth_32_fx[n], output_frame, hb_prev_synth_buffer_fx_32, tmps ); + Copy_Scale_sig_32_16( hb_prev_synth_buffer_fx_32, st->hb_prev_synth_buffer_fx, 111, negate( 11 ) ); + } + ELSE + { + Copy_Scale_sig_32_16( hb_synth_32_fx[n] + sub( output_frame, tmps ), st->hb_prev_synth_buffer_fx, tmps, negate( Q11 ) ); + } + + st->old_bwe_delay = tmps; + + /* SWB CNG/DTX - calculate SHB energy */ + test(); + test(); + test(); + IF( GE_16( output_frame, L_FRAME32k ) && GT_16( st->extl, SWB_CNG ) && st->core == ACELP_CORE && st->hTdCngDec != NULL ) + { + Word16 exp; + Word32 fra; + SWITCH( output_frame ) + { + case L_FRAME8k: + tmp16 = 205; + move16(); + BREAK; /*Q15*/ + case L_FRAME16k: + tmp16 = 102; + move16(); + BREAK; /*Q15*/ + case L_FRAME32k: + tmp16 = 51; + move16(); + BREAK; /*Q15*/ + case L_FRAME48k: + tmp16 = 34; + move16(); + BREAK; /*Q15*/ + } + + L_tmp = L_deposit_l( 2 ); /*0.001 in Q11*/ + + Word16 exp2; + exp = 20; + move16(); + Word32 L_tmp2 = sum2_32_fx( hb_synth_32_fx[n], output_frame, &exp ); + L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, 20, L_tmp2, exp, &exp ); + L_tmp = Mpy_32_16_1( L_tmp, tmp16 ); + exp2 = norm_l( L_tmp ); + exp = sub( exp, exp2 ); + fra = BASOP_Util_Log2( L_shl_sat( L_tmp, exp2 ) ); + exp2 = norm_l( exp ); + L_tmp = L_shl( exp, exp2 ); + exp = sub( Q31, exp2 ); + L_tmp = BASOP_Util_Add_Mant32Exp( fra, 6, L_tmp, exp, &exp ); + // exp = sub( sub( 30, shl( sub( Q11, 0 ), 1 ) ), exp ); + L_tmp = Mpy_32_16_1( L_tmp, 24660 ); + exp = add( exp, 2 ); + st->last_shb_ener_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 7 ) ) ); /*Q8*/ + move16(); + st->hTdCngDec->last_shb_ener_fx = L_shl_sat( L_tmp, sub( exp, 20 ) ); /*Q11*/ + move32(); + } + } + + test(); + IF( sba_dirac_stereo_flag && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + /* for SBA DirAC stereo output DFT Stereo core switching and updates are done in ivas_sba_dirac_stereo_dec() as hCPE is not available at this point */ + break; + } + + /*----------------------------------------------------------------* + * Post-processing + * - TCX-LTP Postfilter (except DFT stereo) + * - core switching in DFT stereo + * - updates for potential TD->DFT stereo switching + *----------------------------------------------------------------*/ + IF( hCPE != NULL ) + { + FOR( Word32 ch_ind = 0; ch_ind < n_channels; ch_ind++ ) + { + IF( hCPE->hCoreCoder[ch_ind] != NULL ) + { + IF( hCPE->hCoreCoder[ch_ind]->hHQ_core != NULL ) + { + Copy_Scale_sig_16_32( hCPE->hCoreCoder[ch_ind]->hHQ_core->old_out_LB_fx, hCPE->hCoreCoder[ch_ind]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, hCPE->hCoreCoder[ch_ind]->hHQ_core->Q_old_wtda_LB ) ); + Copy_Scale_sig_16_32( hCPE->hCoreCoder[ch_ind]->hHQ_core->old_out_fx, hCPE->hCoreCoder[ch_ind]->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, hCPE->hCoreCoder[ch_ind]->hHQ_core->Q_old_wtda ) ); + } + } + } + } + IF( hSCE != NULL ) + { + IF( hSCE->hCoreCoder[0] != NULL ) + { + IF( hSCE->hCoreCoder[0]->hHQ_core != NULL ) + { + Copy_Scale_sig_16_32( hSCE->hCoreCoder[0]->hHQ_core->old_out_LB_fx, hSCE->hCoreCoder[0]->hHQ_core->old_outLB_fx, L_FRAME32k, sub( Q11, hSCE->hCoreCoder[0]->hHQ_core->Q_old_wtda_LB ) ); + Copy_Scale_sig_16_32( hSCE->hCoreCoder[0]->hHQ_core->old_out_fx, hSCE->hCoreCoder[0]->hHQ_core->oldOut_fx, L_FRAME48k, sub( Q11, hSCE->hCoreCoder[0]->hHQ_core->Q_old_wtda ) ); + } + } + } + + Word16 exp_max; + Word32 output_fx_loc[L_FRAME48k]; + + exp_max = 0; + move16(); + IF( NE_16( st->element_mode, IVAS_CPE_DFT ) ) + { + test(); + IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) || sba_dirac_stereo_flag ) + { + ivas_post_proc_fx( hSCE, hCPE, n, synth_32_fx[n], NULL, output_frame, sba_dirac_stereo_flag ); + } + + /* update OLA buffers - needed for switching to DFT stereo */ + IF( !sba_dirac_stereo_flag ) + { + IF( hCPE != NULL ) + { + stereo_td2dft_update_fx( hCPE, n, output_32_fx[n], synth_32_fx[n], hb_synth_32_fx[n], output_frame ); + } + } + } + ELSE /* IVAS_CPE_DFT */ + { + Word16 q; + q = 11; + move16(); + IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_MDCT ) ) + { + stereo_mdct2dft_update_fx( hCPE, output_32_fx[0], synth_32_fx[0] ); + } + Word16 q_DFT[2] = { 3, 3 }; + move16(); + move16(); + + stereo_dft_dec_core_switching_fx( hCPE, output_32_fx[0], synth_32_fx[0], hb_synth_32_fx[0], DFT_fx, output_frame, use_cldfb_for_dft, 0, &q, q_DFT ); + + hCPE->hStereoDft->q_dft = s_min( q_DFT[0], q_DFT[1] ); + move16(); + + IF( DFT_fx != NULL ) + { + Scale_sig32( DFT_fx[0], STEREO_DFT_BUF_MAX, sub( hCPE->hStereoDft->q_dft, q_DFT[0] ) ); + Scale_sig32( DFT_fx[1], STEREO_DFT_BUF_MAX, sub( hCPE->hStereoDft->q_dft, q_DFT[1] ) ); + } + + test(); + IF( EQ_16( hCPE->nchan_out, 1 ) && EQ_16( hCPE->hStereoDft->hConfig->res_cod_mode, STEREO_DFT_RES_COD_OFF ) ) + { + /* mono output for non-residual coding modes uses CLDFB instead of DFT - requires DFT buffer update in case of bitrate switching */ + stereo_td2dft_update_fx( hCPE, n, output_32_fx[n], synth_32_fx[n], hb_synth_32_fx[n], output_frame ); + } + } + + Copy32( synth_32_fx[n], output_32_fx[n], output_frame ); + + /*--------------------------------------------------------* + * Common updates + *--------------------------------------------------------*/ + + /*Scale Memories*/ + + test(); + test(); + test(); + test(); + test(); + IF( ( EQ_16( st->codec_mode, MODE1 ) && st->hTcxDec != NULL ) && ( ( EQ_16( st->core, ACELP_CORE ) && !( EQ_16( st->bfi, 1 ) && EQ_16( st->con_tcx, 1 ) ) ) || EQ_16( st->core, HQ_CORE ) ) ) + { + Word16 exp_prev_synth_buffer = 0, exp_old_out = 0, exp_delay_buf_out = 0, exp_ouput = 0, exp_synth_history = 0; + move16(); + move16(); + move16(); + move16(); + move16(); + + Copy_Scale_sig32_16( st->prev_synth_buffer32_fx, st->prev_synth_buffer_fx, NS2SA( 48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), negate( Q11 ) ); + st->q_prev_synth_buffer_fx = 0; + move16(); + + exp_ouput = Find_Max_Norm32( output_32_fx[n], output_frame ); + exp_ouput = add( exp_ouput, Q11 ); + exp_prev_synth_buffer = Find_Max_Norm16( st->prev_synth_buffer_fx, NS2SA( 48000, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); + exp_prev_synth_buffer = add( exp_prev_synth_buffer, st->q_prev_synth_buffer_fx ); + exp_old_out = Find_Max_Norm16( st->hHQ_core->old_out_fx + NS2SA( st->output_Fs, N_ZERO_MDCT_NS ), sub( add( NS2SA( st->output_Fs, N_ZERO_MDCT_NS ), NS2SA( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ), NS2SA( st->output_Fs, N_ZERO_MDCT_NS ) ) ); + exp_delay_buf_out = Find_Max_Norm16( st->delay_buf_out_fx, NS2SA( st->output_Fs, DELAY_CLDFB_NS ) ); + exp_synth_history = Find_Max_Norm16( st->hTcxDec->synth_history_fx + output_frame, sub( add( sub( imult1616( 2, output_frame ), NS2SA( st->output_Fs, DELAY_CLDFB_NS ) ), NS2SA( st->output_Fs, PH_ECU_MEM_NS ) ), output_frame ) ); +#ifndef FIX_740_HQ_CORE_OVA + exp_synth_history += st->hTcxDec->q_synth_history_fx; +#endif + exp_max = s_min( exp_synth_history, exp_ouput ); + exp_max = s_min( exp_max, exp_prev_synth_buffer ); + exp_max = s_min( exp_max, exp_old_out ); + exp_max = s_min( exp_max, exp_delay_buf_out ); + + Copy32( output_32_fx[n], output_fx_loc, output_frame ); + + Scale_sig32( output_fx_loc, output_frame, sub( exp_max, Q11 ) ); + Scale_sig( st->delay_buf_out_fx, NS2SA( st->output_Fs, DELAY_CLDFB_NS ), exp_max ); + Scale_sig( st->hHQ_core->old_out_fx + NS2SA( st->output_Fs, N_ZERO_MDCT_NS ), sub( NS2SA( st->output_Fs, PH_ECU_LOOKAHEAD_NS ), NS2SA( st->output_Fs, N_ZERO_MDCT_NS ) ), exp_max ); + Scale_sig( st->prev_synth_buffer_fx, NS2SA( 48000, L_sub( DELAY_BWE_TOTAL_NS, DELAY_CLDFB_NS ) ), sub( exp_max, st->q_prev_synth_buffer_fx ) ); + Scale_sig( st->hTcxDec->synth_history_fx + output_frame, sub( add( sub( imult1616( 2, output_frame ), NS2SA( st->output_Fs, DELAY_CLDFB_NS ) ), NS2SA( st->output_Fs, PH_ECU_MEM_NS ) ), output_frame ), sub( exp_max, st->Q_syn ) ); + + st->q_prev_synth_buffer_fx = sub( exp_max, st->q_prev_synth_buffer_fx ); + } + /* Save synthesis for HQ FEC */ + save_synthesis_hq_fec_fx( st, output_fx_loc, output_frame, hCPE ); + + /* Updates */ + + ivas_updt_dec_common_fx( st, NORMAL_HQ_CORE, -1, output_32_fx[n], Q11 ); + + Scale_sig( st->delay_buf_out_fx, NS2SA( st->output_Fs, DELAY_CLDFB_NS ), negate( exp_max ) ); + + } /* n_channels loop */ + + FOR( n = 0; n < n_channels; n++ ) + { + st = sts[n]; + IF( st->cldfbAna ) + { + scale_sig32( st->cldfbAna->cldfb_state_fx, st->cldfbAna->cldfb_size, sub( Q11, Q10 ) ); + st->cldfbAna->Q_cldfb_state = Q11; + move16(); + } + IF( st->cldfbSynHB ) + { + scale_sig32( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->cldfb_size, sub( Q11, Q10 ) ); + st->cldfbSynHB->Q_cldfb_state = Q11; + move16(); + } + } + + pop_wmops(); + return error; +} +#else +ivas_error ivas_core_dec( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + SCE_DEC_HANDLE hSCE, /* i/o: SCE decoder structure */ + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */ + const int16_t n_channels, /* i : number of channels to be decoded */ + float *output[], /* o : output synthesis signal */ + float hb_synth[][L_FRAME48k], /* o : output HB synthesis signal */ + float DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* o : DFT buffers */ + const int16_t sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ +) +{ + int16_t i, n, output_frame; + Decoder_State **sts, *st; + STEREO_ICBWE_DEC_HANDLE hStereoICBWE; + STEREO_TD_DEC_DATA_HANDLE hStereoTD; + int16_t sharpFlag[CPE_CHANNELS]; + float synth[CPE_CHANNELS][L_FRAME48k]; + float tmp_buffer[L_FRAME48k]; + int16_t tmps, incr; + float bwe_exc_extended[CPE_CHANNELS][L_FRAME32k + NL_BUFF_OFFSET]; + float voice_factors[CPE_CHANNELS][NB_SUBFR16k]; + int16_t core_switching_flag[CPE_CHANNELS]; + float old_syn_12k8_16k[CPE_CHANNELS][L_FRAME16k]; + float tmp; + float pitch_buf[CPE_CHANNELS][NB_SUBFR16k]; + int16_t unbits[CPE_CHANNELS]; + int16_t sid_bw[CPE_CHANNELS]; + FRAME_MODE frameMode[CPE_CHANNELS]; + float tdm_lspQ_PCh[M], tdm_lsfQ_PCh[M]; + int16_t tdm_LRTD_flag; + int32_t element_brate, output_Fs; + int32_t last_element_brate; + int16_t use_cldfb_for_dft; + float *p_output_mem; + int16_t flag_sec_CNA; + int16_t read_sid_info; + int16_t last_element_mode; + int16_t nchan_out; + float *save_hb_synth; + ivas_error error; + + error = IVAS_ERR_OK; + push_wmops( "ivas_core_dec" ); + + /*------------------------------------------------------------------* + * General initialization + *-----------------------------------------------------------------*/ + + use_cldfb_for_dft = 0; + tdm_LRTD_flag = -1; + read_sid_info = 1; /* read SID by default */ + + if ( hSCE != NULL ) + { + sts = hSCE->hCoreCoder; + hStereoICBWE = NULL; + element_brate = hSCE->element_brate; + last_element_brate = hSCE->last_element_brate; /* note: this parameter is unused */ + last_element_mode = IVAS_SCE; + hStereoTD = NULL; + p_output_mem = NULL; + nchan_out = 1; + if ( st_ivas != NULL && st_ivas->ivas_format == ISM_FORMAT ) + { + if ( st_ivas->hISMDTX.sce_id_dtx != hSCE->sce_id ) + { + read_sid_info = 0; + } + } + } + else + { + sts = hCPE->hCoreCoder; + element_brate = hCPE->element_brate; + last_element_brate = hCPE->last_element_brate; + last_element_mode = hCPE->last_element_mode; + hStereoICBWE = hCPE->hStereoICBWE; + hStereoTD = hCPE->hStereoTD; + p_output_mem = hCPE->output_mem[1]; + nchan_out = hCPE->nchan_out; + + if ( hCPE->hStereoTD != NULL ) + { + tdm_LRTD_flag = hCPE->hCoreCoder[0]->tdm_LRTD_flag; + } + + if ( sts[0]->element_mode == IVAS_CPE_DFT ) + { + use_cldfb_for_dft = ( hCPE->nchan_out == 1 && hCPE->hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF ) ? 1 : 0; + } + } + + output_Fs = sts[0]->output_Fs; + output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC ); + + for ( n = 0; n < n_channels; n++ ) + { + st = sts[n]; + + /*------------------------------------------------------------------* + * Initialization per core-decoder channel + *-----------------------------------------------------------------*/ + + frameMode[n] = FRAMEMODE_NORMAL; + st->rate_switching_reset = 0; + + st->mdct_sw = MODE1; + + sid_bw[n] = -1; + core_switching_flag[n] = 0; + sharpFlag[n] = 0; + unbits[n] = 0; + st->GSC_IVAS_mode = 0; + st->element_brate = element_brate; + + st->use_partial_copy = 0; + st->rf_flag = 0; + st->rf_frame_type = RF_NO_DATA; + + if ( st->bfi == 1 ) + { + frameMode[n] = FRAMEMODE_MISSING; + st->coder_type = st->last_coder_type; + } + else + { + if ( !( st->element_mode == IVAS_CPE_TD && n == 1 ) ) /* coder_type for SCh in TD stereo is already read in tdm_configure_dec() */ + { + st->coder_type = INACTIVE; + } + st->extl = -1; + st->flagGuidedAcelp = 0; + } + +#ifdef NONBE_MDCT_ST_PLC_DO_NOT_SCALE_OLD_OUT_IF_FIRST_GOOD_IS_SID + if ( !st->bfi && st->prev_bfi && st->total_brate > SID_2k40 && ( st->last_core_bfi == TCX_20_CORE || st->last_core_bfi == TCX_10_CORE ) && st->hTcxDec != NULL ) +#else + if ( !st->bfi && st->prev_bfi && ( st->last_core_bfi == TCX_20_CORE || st->last_core_bfi == TCX_10_CORE ) && st->hTcxDec != NULL ) +#endif + { + v_multc( st->hHQ_core->old_out, st->hTcxDec->conceal_eof_gain_float * st->last_concealed_gain_syn_deemph_float, st->hHQ_core->old_out, st->hTcxDec->L_frameTCX ); + v_multc( st->hHQ_core->old_outLB, st->hTcxDec->conceal_eof_gain_float * st->last_concealed_gain_syn_deemph_float, st->hHQ_core->old_outLB, st->L_frame ); + } + + set_f( voice_factors[n], 0.f, NB_SUBFR16k ); + set_f( hb_synth[n], 0.0f, L_FRAME48k ); + + /*------------------------------------------------------------------* + * Decision matrix (selection of technologies) + *-----------------------------------------------------------------*/ + + if ( st->bfi != 1 ) + { + ivas_decision_matrix_dec( st, &sharpFlag[n], &core_switching_flag[n], element_brate, nchan_out ); + + synchonize_channels_mdct_sid( sts, n ); + + if ( st->bfi != 1 ) /* note: st->bfi can be changed from 0 to 1 in ivas_decision_matrix_dec() when BER is detected */ + { + st->sr_core = st->L_frame * FRAMES_PER_SEC; + st->fscale_old = st->fscale; + st->fscale = sr2fscale( st->sr_core ); + } + else + { + frameMode[n] = FRAMEMODE_MISSING; + } + } + else if ( st->element_mode >= IVAS_SCE && st->prev_bfi == 1 && st->last_con_tcx == 1 ) + { + st->core = TCX_20_CORE; + } + } /* n_channels loop */ + + /* MDCT stereo -> DFT stereo switching */ + if ( hCPE != NULL && hCPE->last_element_mode == IVAS_CPE_MDCT && hCPE->element_mode == IVAS_CPE_DFT ) + { + int16_t ovl, fade_len; + if ( sts[0]->L_frame != sts[0]->last_L_frame ) + { + lerp_flt( sts[0]->hHQ_core->old_outLB, sts[0]->hHQ_core->old_outLB, sts[0]->L_frame, sts[0]->last_L_frame ); + } + if ( sts[0]->L_frame != L_FRAME16k ) + { + ovl = (int16_t) ( STEREO_DFT32MS_OVL_16k * ( (float) sts[0]->L_frame / L_FRAME16k ) ); + lerp_flt( hCPE->input_mem_LB[0], hCPE->input_mem_LB[0], ovl, STEREO_DFT32MS_OVL_16k ); + + fade_len = (int16_t) ( STEREO_MDCT2DFT_FADE_LEN_48k * ( (float) sts[0]->L_frame / L_FRAME16k ) ); + lerp_flt( hCPE->old_outLB_mdct, hCPE->old_outLB_mdct, fade_len, STEREO_MDCT2DFT_FADE_LEN_48k ); + } + } + + if ( hCPE != NULL && hCPE->hStereoCng != NULL ) + { + hCPE->hStereoCng->flag_cna_fade = 0; + } + + if ( sba_dirac_stereo_flag && hSCE && sts[0]->total_brate <= SID_2k40 && sts[0]->cng_type == FD_CNG ) + { + save_hb_synth = hSCE->save_hb_synth; + } + else + { + save_hb_synth = NULL; + } + + /*------------------------------------------------------------------* + * Decode SID for MDCT-Stereo DTX mode + *-----------------------------------------------------------------*/ + + if ( sts[0]->element_mode == IVAS_CPE_MDCT && sts[0]->total_brate == SID_2k40 ) + { + if ( sts[0]->cng_sba_flag ) + { + FdCngDecodeDiracMDCTStereoSID( hCPE ); + } + else + { + FdCngDecodeMDCTStereoSID( hCPE ); + } + } + + /*------------------------------------------------------------------* + * Sanity check in combined format coding + *-----------------------------------------------------------------*/ + + if ( hCPE != NULL && hCPE->element_mode == IVAS_CPE_DFT && hCPE->brate_surplus > 0 ) + { + ivas_combined_format_brate_sanity( hCPE->element_brate, sts[0]->core, sts[0]->total_brate, &( sts[0]->core_brate ), &( sts[0]->inactive_coder_type_flag ), &tmps ); + } + + /*------------------------------------------------------------------* + * Core Decoding + *-----------------------------------------------------------------*/ + + for ( n = 0; n < n_channels; n++ ) + { + st = sts[n]; + + /*------------------------------------------------------------------* + * Initialization + *-----------------------------------------------------------------*/ + + if ( st->bfi == 1 ) + { + st->nbLostCmpt++; + } + else + { + if ( st->prev_bfi == 1 ) + { + st->prev_nbLostCmpt = st->nbLostCmpt; + } + else + { + st->prev_nbLostCmpt = 0; + } + + st->nbLostCmpt = 0; + } + st->enablePlcWaveadjust = 0; + + if ( n == 1 ) + { + sts[1]->BER_detect |= sts[0]->BER_detect; + } + + /*---------------------------------------------------------------------* + * Detect bandwidth switching + *---------------------------------------------------------------------*/ + + bandwidth_switching_detect( st ); + + /*---------------------------------------------------------------------* + * Preprocessing (preparing) for ACELP/HQ core switching + *---------------------------------------------------------------------*/ + + if ( ( error = core_switching_pre_dec( st, output_frame, sts[0]->last_core_brate, nchan_out, last_element_mode, last_element_brate ) ) != IVAS_ERR_OK ) + { + return error; + } + + flag_sec_CNA = -1; + if ( hCPE != NULL ) + { + flag_sec_CNA = sts[1]->flag_cna; + } + + /*---------------------------------------------------------------------* + * ACELP core decoding + * TCX core decoding + * HQ core decoding + *---------------------------------------------------------------------*/ + + if ( st->core == ACELP_CORE ) + { + /* ACELP core decoder */ + if ( ( error = acelp_core_dec( st, output[n], synth[n], save_hb_synth, bwe_exc_extended[n], voice_factors[n], old_syn_12k8_16k[n], sharpFlag[n], pitch_buf[n], &unbits[n], &sid_bw[n], hStereoTD, tdm_lspQ_PCh, tdm_lsfQ_PCh, use_cldfb_for_dft, last_element_mode, last_element_brate, flag_sec_CNA, nchan_out, hCPE == NULL ? NULL : hCPE->hStereoCng, read_sid_info ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + if ( ( st->core == TCX_20_CORE || st->core == TCX_10_CORE ) && st->element_mode != IVAS_CPE_MDCT ) + { + /* TCX decoder */ + stereo_tcx_core_dec( st, frameMode[n], output[n], synth[n], pitch_buf[n], sba_dirac_stereo_flag, hStereoTD, last_element_mode, flag_sec_CNA, hCPE == NULL ? NULL : hCPE->hStereoCng, nchan_out, st_ivas == NULL ? 0 : st_ivas->ivas_format ); + } + + if ( st->core == HQ_CORE ) + { + /* HQ core decoder */ + hq_core_dec( st, synth[n], output_frame, NORMAL_HQ_CORE, core_switching_flag[n], output[n] ); + } + + /*---------------------------------------------------------------------* + * TD stereo updates + *---------------------------------------------------------------------*/ + + if ( st->element_mode == IVAS_CPE_TD && n == 0 ) + { + td_stereo_param_updt( st->lsp_old, st->lsf_old, st->old_pitch_buf + st->nb_subfr, tdm_lspQ_PCh, tdm_lsfQ_PCh, hStereoTD->tdm_Pri_pitch_buf, st->flag_ACELP16k, hStereoTD->tdm_use_IAWB_Ave_lpc ); + } + + } /* n_channels loop */ + + /*---------------------------------------------------------------------* + * MDCT stereo: joint TCX Core Decoding + *---------------------------------------------------------------------*/ + + if ( sts[0]->element_mode == IVAS_CPE_MDCT ) + { + /* active-frame decoding */ + if ( sts[0]->core_brate > SID_2k40 ) + { + if ( hMCT ) + { + pop_wmops(); + + return error; + } + else + { + stereo_mdct_core_dec( st_ivas, hCPE, output, synth ); + } + } + /* for inactive frames with mono output, copy and (if necessary) downmix buffers */ + else if ( hCPE->nchan_out == 1 ) + { + updateBuffersForDmxMdctStereo( hCPE, output_frame, output, synth ); + } + +#ifdef NONBE_MDCT_ST_DTX_SKIP_DEWHITENING_OF_NOISE_SHAPES_ON_SID_FRAMES + + /* On first good active frame after frameloss undo the whitening of the bg noise shape */ + if ( sts[0]->core_brate > SID_2k40 && sts[0]->bfi == 0 && sts[0]->prev_bfi == 1 ) +#else + if ( sts[0]->bfi == 0 && sts[0]->prev_bfi == 1 ) + /* On first good frame after frameloss undo the whitening of the bg noise shape */ +#endif + { + for ( n = 0; n < n_channels; ++n ) + { + if ( sts[n]->last_core_bfi != ACELP_CORE ) + { + TonalMdctConceal_whiten_noise_shape_ivas( sts[n], L_FRAME16k, ON_FIRST_GOOD_FRAME ); + } + } + } + } + + /*---------------------------------------------------------------------* + * Stereo CNG updates + *---------------------------------------------------------------------*/ + + if ( sts[0]->element_mode == IVAS_CPE_TD && hCPE->hStereoCng != NULL ) + { + stereo_cng_compute_PScorr( output, &hCPE->hStereoCng->c_PS_LT, sts[0]->L_frame, sts[1]->L_frame ); + } + + /*---------------------------------------------------------------------* + * Postprocessing, BWEs and updates + *---------------------------------------------------------------------*/ + + for ( n = 0; n < n_channels; n++ ) + { + st = sts[n]; + + /*---------------------------------------------------------------------* + * TD-BWE for ACELP to TCX transitions + *---------------------------------------------------------------------*/ + + if ( st->last_core == ACELP_CORE && ( st->core == TCX_20_CORE || st->core == TCX_10_CORE || st->core == HQ_CORE ) && st->hBWE_TD != NULL ) + { + if ( ( st->bwidth == SWB || st->bwidth == FB ) && ( st->last_extl == SWB_TBE || st->last_extl == FB_TBE ) ) + { + GenTransition( st->hBWE_TD, hb_synth[n], output_Fs, st->element_mode, st->L_frame, st->rf_flag, st->total_brate ); + } + else if ( st->bwidth == WB && st->last_extl == WB_TBE ) + { + GenTransition_WB( st->hBWE_TD, hb_synth[n], output_Fs ); + } + } + + /*---------------------------------------------------------------------* + * Postprocessing for ACELP/MDCT core switching + *---------------------------------------------------------------------*/ + + /* save synth and output in case of SBA DirAC stereo output as core switching is done outside of core decoder */ + if ( sba_dirac_stereo_flag && st->element_mode != IVAS_CPE_MDCT && !( st->core_brate == SID_2k40 && st->cng_type == FD_CNG ) ) + { + mvr2r( synth[n], hSCE->save_synth, output_frame ); + } + + if ( ( error = core_switching_post_dec( st, synth[n], output[n], p_output_mem, ( st_ivas != NULL ) ? st_ivas->ivas_format : UNDEFINED_FORMAT, use_cldfb_for_dft, output_frame, 0 /*core_switching_flag*/, sba_dirac_stereo_flag, nchan_out, ( hCPE != NULL ) ? hCPE->last_element_mode : IVAS_SCE ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* for FD-CNG we need the delay compensation in the synth, so do this afterwards */ + if ( sba_dirac_stereo_flag && hSCE && st->core_brate == SID_2k40 && st->cng_type == FD_CNG ) + { + mvr2r( synth[n], hSCE->save_synth, output_frame ); + } + + /* if we transition from inactive to active coding in MDCT-Stereo DTX and the output format is mono DMX, we need to sync the upsampled buffer between channels here */ + if ( n == 0 && st->element_mode == IVAS_CPE_MDCT && st->last_core == ACELP_CORE && st->core != ACELP_CORE && ( nchan_out == 1 || ( hCPE != NULL && hCPE->last_element_mode == IVAS_CPE_DFT ) ) ) + { + mvr2r( sts[0]->previoussynth, sts[1]->previoussynth, st->hTcxDec->L_frameTCX ); + } + + /*---------------------------------------------------------------------* + * Pre-processing for bandwidth switching + *---------------------------------------------------------------------*/ + + bw_switching_pre_proc( st, old_syn_12k8_16k[n], last_element_brate, nchan_out ); + + /*---------------------------------------------------------------------* + * WB TBE decoding + * WB BWE decoding + *---------------------------------------------------------------------*/ + + if ( st->extl == WB_TBE ) + { + /* WB TBE decoder */ + wb_tbe_dec( st, bwe_exc_extended[n], voice_factors[n], hb_synth[n] ); + } + else if ( st->element_mode == IVAS_CPE_TD && n == 1 && !tdm_LRTD_flag && st->extl != -1 && st->bws_cnt == 0 && st->extl_brate == 0 ) + { + /* do nothing */ + } + else if ( st->extl == WB_BWE && st->bws_cnt == 0 ) + { + /* WB BWE decoder */ + wb_bwe_dec_flt( st, output[n], synth[n], hb_synth[n], use_cldfb_for_dft, output_frame, voice_factors[n], pitch_buf[n] ); + } + + /*---------------------------------------------------------------------* + * SWB(FB) TBE decoding + * SWB(FB) BWE decoding + *---------------------------------------------------------------------*/ + + if ( st->extl == SWB_TBE || st->extl == FB_TBE || ( st->coder_type != AUDIO && st->coder_type != INACTIVE && st->core_brate >= SID_2k40 && st->core == ACELP_CORE && !st->con_tcx && output_Fs >= 32000 && st->bwidth > NB && st->bws_cnt > 0 ) ) + { + /* SWB TBE decoder */ + swb_tbe_dec( st, hStereoICBWE, bwe_exc_extended[n], voice_factors[n], old_syn_12k8_16k[n], tmp_buffer /*fb_exc*/, hb_synth[n], pitch_buf[n] ); + + /* FB TBE decoder */ + if ( st->extl == FB_TBE ) + { + fb_tbe_dec( st, tmp_buffer /*fb_exc*/, hb_synth[n], tmp_buffer /*fb_synth_ref*/, output_frame ); + } + } + else if ( st->extl == SWB_BWE || st->extl == FB_BWE || ( output_Fs >= 32000 && st->core == ACELP_CORE && st->bwidth > NB && st->bws_cnt > 0 && !st->ppp_mode_dec && !( st->nelp_mode_dec == 1 && st->bfi == 1 ) ) ) + { + /* SWB BWE decoder */ + swb_bwe_dec_flt( st, output[n], synth[n], hb_synth[n], use_cldfb_for_dft, output_frame ); + } + + /*---------------------------------------------------------------------* + * FEC - recovery after lost HQ core (smoothing of the BWE component) + *---------------------------------------------------------------------*/ + + if ( st->prev_bfi && st->last_core == HQ_CORE && st->extl != -1 ) + { + tmp = FRAC_BWE_SMOOTH / output_frame; + + for ( i = 0; i < output_frame / FRAC_BWE_SMOOTH; i++ ) + { + hb_synth[n][i] *= ( i * tmp ); + } + } + + /*---------------------------------------------------------------------* + * SWB CNG + *---------------------------------------------------------------------*/ + + if ( ( output_frame >= L_FRAME32k && st->hTdCngDec != NULL ) || ( st->element_mode == IVAS_CPE_DFT && st->bwidth >= SWB && st->hTdCngDec != NULL ) ) + { + /* SHB CNG decoder */ + swb_CNG_dec( st, synth[n], hb_synth[n], sid_bw[n] ); + } + + /*-------------------------------------------------------------------* + * Inter-channel BWE decoding + *-------------------------------------------------------------------*/ + + if ( n == 0 && st->element_mode >= IVAS_CPE_DFT ) + { + stereo_icBWE_dec( hCPE, hb_synth[0], hb_synth[1], tmp_buffer /*fb_synth_ref*/, voice_factors[0], output_frame ); + } + + if ( st->element_mode == EVS_MONO ) + { + /*----------------------------------------------------------------* + * BFI waveform adjustment + *----------------------------------------------------------------*/ + + if ( st->core == ACELP_CORE && !st->bfi && st->prev_bfi && st->last_total_brate >= HQ_48k && st->last_codec_mode == MODE2 && ( st->last_core_bfi == TCX_20_CORE || st->last_core_bfi == TCX_10_CORE ) && st->hPlcInfo->concealment_method == TCX_NONTONAL && st->hPlcInfo->nbLostCmpt < 4 ) + { + tmps = NS2SA( output_Fs, DELAY_CLDFB_NS ); + + waveform_adj2( st->hPlcInfo, st->hTonalMDCTConc->secondLastPcmOut_float, synth[n] + tmps, tmps, st->hPlcInfo->nbLostCmpt + 1, st->bfi ); + + st->hPlcInfo->Pitch = 0; + } + } + + /*----------------------------------------------------------------* + * Transition and synchronization of BWE components + *----------------------------------------------------------------*/ + + if ( ( st->extl != -1 && ( st->extl != IGF_BWE || st->last_core == ACELP_CORE ) ) || ( st->bws_cnt > 0 && st->core == ACELP_CORE ) ) + { + /* Calculate an additional delay of extension layer components to be synchronized with ACELP synthesis */ + if ( st->L_frame == L_FRAME ) + { + /* TBE on top of ACELP@12.8kHz */ + tmps = NS2SA( output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_12k8_NS ); + } + else + { + if ( st->extl == SWB_BWE_HIGHRATE || st->extl == FB_BWE_HIGHRATE ) + { + /* HR SWB BWE on top of ACELP@16kHz */ + tmps = NS2SA( output_Fs, DELAY_BWE_TOTAL_NS ); + } + else + { + /* TBE on top of ACELP@16kHz */ + tmps = NS2SA( output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_16k_NS ); + } + } + + /* Smooth transitions when switching between different technologies */ + if ( !( ( st->core == TCX_20_CORE || st->core == TCX_10_CORE || st->core == HQ_CORE ) && st->last_core == ACELP_CORE ) && + ( st->extl != st->last_extl || ( st->extl == st->last_extl && ( st->core ^ st->last_core ) == HQ_CORE ) ) && !( st->extl == SWB_CNG && st->last_extl == SWB_TBE ) && ( st->element_mode != IVAS_CPE_TD || ( hCPE->element_mode == IVAS_CPE_TD && tdm_LRTD_flag ) ) ) + { + /* switching between BWE and TBE technologies */ + incr = (int16_t) ( L_FRAME / ( tmps + 0.5f ) ); + for ( i = 0; i < tmps; i++ ) + { + hb_synth[n][i] *= sin_table256[i * incr]; + } + + set_f( st->hb_prev_synth_buffer, 0.0f, tmps ); + } + else if ( tmps < st->old_bwe_delay ) + { + /* the previous frame was TBE on top of ACELP@16kHz and the current frame is TBE on top of ACELP@12.8kHz */ + incr = (int16_t) ( L_FRAME / ( tmps + 0.5f ) ); + for ( i = 0; i < tmps; i++ ) + { + tmp_buffer[i] = st->hb_prev_synth_buffer[i] * sin_table256[255 - i * incr] + + st->hb_prev_synth_buffer[st->old_bwe_delay - 1 - i] * sin_table256[i * incr]; + } + + mvr2r( tmp_buffer, st->hb_prev_synth_buffer, tmps ); + } + else if ( tmps > st->old_bwe_delay ) + { + /* the previous frame was TBE on top of ACELP@12.8kHz and the current frame is TBE on top of ACELP@16kHz */ + incr = (int16_t) ( L_FRAME / ( st->old_bwe_delay + 0.5f ) ); + for ( i = 0; i < st->old_bwe_delay; i++ ) + { + tmp_buffer[i] = st->hb_prev_synth_buffer[i] * sin_table256[255 - i * incr]; + } + + for ( ; i < tmps; i++ ) + { + tmp_buffer[i] = 0.0f; + } + + for ( i = 0; i < st->old_bwe_delay; i++ ) + { + tmp_buffer[tmps - 1 - i] += st->hb_prev_synth_buffer[st->old_bwe_delay - 1 - i] * sin_table256[i * incr]; + } + + mvr2r( tmp_buffer, st->hb_prev_synth_buffer, tmps ); + } + + if ( ( st->element_mode != IVAS_CPE_TD && !use_cldfb_for_dft ) || ( hCPE->element_mode == IVAS_CPE_TD && tdm_LRTD_flag ) ) + { + /* Delay hb_synth */ + delay_signal_float( hb_synth[n], output_frame, st->hb_prev_synth_buffer, tmps ); + } + else + { + mvr2r( hb_synth[n] + output_frame - tmps, st->hb_prev_synth_buffer, tmps ); + } + + st->old_bwe_delay = tmps; + if ( st->hBWE_TD != NULL ) + { + mvr2r( hb_synth[n], st->hBWE_TD->old_hb_synth, output_frame ); + } + + /* SWB CNG/DTX - calculate SHB energy */ + if ( output_frame >= L_FRAME32k && st->extl > SWB_CNG && st->core == ACELP_CORE && st->hTdCngDec != NULL ) + { + st->hTdCngDec->last_shb_ener = sum2_f( hb_synth[n], output_frame ) + 0.001f; + st->hTdCngDec->last_shb_ener /= (float) output_frame; + st->hTdCngDec->last_shb_ener = 10 * log10f( st->hTdCngDec->last_shb_ener ); + } + } + + if ( sba_dirac_stereo_flag && st->element_mode != IVAS_CPE_MDCT ) + { + /* for SBA DirAC stereo output DFT Stereo core switching and updates are done in ivas_sba_dirac_stereo_dec() as hCPE is not available at this point */ + break; + } + + /*----------------------------------------------------------------* + * Post-processing + * - TCX-LTP Postfilter (except DFT stereo) + * - core switching in DFT stereo + * - updates for potential TD->DFT stereo switching + *----------------------------------------------------------------*/ + + if ( st->element_mode != IVAS_CPE_DFT ) + { + if ( st->element_mode != IVAS_CPE_MDCT || sba_dirac_stereo_flag ) + { + ivas_post_proc( hSCE, hCPE, n, synth[n], NULL, output_frame, sba_dirac_stereo_flag ); + } + + /* update OLA buffers - needed for switching to DFT stereo */ + if ( !sba_dirac_stereo_flag ) + { + stereo_td2dft_update( hCPE, n, output[n], synth[n], hb_synth[n], output_frame ); + } + } + else /* IVAS_CPE_DFT */ + { + if ( hCPE->last_element_mode == IVAS_CPE_MDCT ) + { + stereo_mdct2dft_update( hCPE, output[0], synth[0] ); + } + + stereo_dft_dec_core_switching( hCPE, output[0], synth[0], hb_synth[0], DFT, output_frame, use_cldfb_for_dft, 0 ); + + if ( hCPE->nchan_out == 1 && hCPE->hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF ) + { + /* mono output for non-residual coding modes uses CLDFB instead of DFT - requires DFT buffer update in case of bitrate switching */ + stereo_td2dft_update( hCPE, n, output[n], synth[n], hb_synth[n], output_frame ); + } + } + + mvr2r( synth[n], output[n], output_frame ); + + /*--------------------------------------------------------* + * Common updates + *--------------------------------------------------------*/ + + /* Save synthesis for HQ FEC */ + save_synthesis_hq_fec( st, output[n], output_frame, hCPE ); + + /* Updates */ + updt_dec_common( st, NORMAL_HQ_CORE, -1, output[n] ); + + } /* n_channels loop */ + + + pop_wmops(); + return error; +} +#endif diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index 31c723eab8d115b5600db24356c930433f2547d5..f33bb4fc7b8cb4fc922746076873bce5e6412d5e 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -62,12 +62,15 @@ static void stereo_mode_combined_format_dec_fx( const Decoder_Struct *st_ivas, C *--------------------------------------------------------------------------*/ ivas_error ivas_cpe_dec_fx( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const Word16 cpe_id, /* i : CPE # identifier */ - Word32 *output[CPE_CHANNELS], /* o : output synthesis signal */ - const Word16 output_frame, /* i : output frame length per channel */ - const Word16 nb_bits_metadata, /* i : number of metadata bits */ - Word16 *q_output /* i/o : Q of output synthesis signal */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const Word16 cpe_id, /* i : CPE # identifier */ + Word32 *output[CPE_CHANNELS], /* o : output synthesis signal */ + const Word16 output_frame, /* i : output frame length per channel */ + const Word16 nb_bits_metadata /* i : number of metadata bits */ +#ifndef FIX_826_PRECISION_LOST_AND_COMPL + , + Word16 *q_output /* i/o : Q of output synthesis signal */ +#endif ) { Word16 i, n, n_channels; @@ -848,7 +851,11 @@ ivas_error ivas_cpe_dec_fx( * IC-BWE: output LB and HB mix in ACELP mode *----------------------------------------------------------------*/ +#ifndef FIX_826_PRECISION_LOST_AND_COMPL stereo_icBWE_decproc_fx( hCPE, output, outputHB_fx, last_core, last_bwidth, output_frame, *q_output ); +#else + stereo_icBWE_decproc_fx( hCPE, output, outputHB_fx, last_core, last_bwidth, output_frame ); +#endif smooth_dft2td_transition_fx( hCPE, output, output_frame ); diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 7300334388a2443148e0ee5d0cb5ddf821f4db02..3e8ff12c1af4083849430ad67092e42904385b0d 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -175,7 +175,11 @@ ivas_error ivas_jbm_dec_tc_fx( set32_fx( &p_output_fx[0][0], 0, L_FRAME48k ); set32_fx( &p_output_fx[1][0], 0, L_FRAME48k ); +#ifndef FIX_826_PRECISION_LOST_AND_COMPL IF( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, 0, &q_output ) ) != IVAS_ERR_OK ) +#else + IF( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, 0 ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -338,7 +342,11 @@ ivas_error ivas_jbm_dec_tc_fx( set32_fx( &p_output_fx[0][0], 0, L_FRAME48k ); set32_fx( &p_output_fx[1][0], 0, L_FRAME48k ); +#ifndef FIX_826_PRECISION_LOST_AND_COMPL IF( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0], &q_output ) ) != IVAS_ERR_OK ) +#else + IF( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -719,7 +727,11 @@ ivas_error ivas_jbm_dec_tc_fx( } /* decode MASA channels */ +#ifndef FIX_826_PRECISION_LOST_AND_COMPL IF( ( error = ivas_cpe_dec_fx( st_ivas, 0, p_output_fx, output_frame, nb_bits_metadata[0], &q_output ) ) != IVAS_ERR_OK ) +#else + IF( ( error = ivas_cpe_dec_fx( st_ivas, 0, p_output_fx, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -823,7 +835,11 @@ ivas_error ivas_jbm_dec_tc_fx( ELSE IF( EQ_16( st_ivas->nCPE, 1 ) ) { +#ifndef FIX_826_PRECISION_LOST_AND_COMPL IF( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] + nb_bits_metadata[1], &q_output ) ) != IVAS_ERR_OK ) +#else + IF( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1142,7 +1158,11 @@ ivas_error ivas_jbm_dec_tc_fx( { Word16 q_output = 11; +#ifndef FIX_826_PRECISION_LOST_AND_COMPL IF( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0], &q_output ) ) != IVAS_ERR_OK ) +#else + IF( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1202,7 +1222,11 @@ ivas_error ivas_jbm_dec_tc_fx( /* Decode the transport audio signals */ Word16 q_output = 11; +#ifndef FIX_826_PRECISION_LOST_AND_COMPL IF( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0], &q_output ) ) != IVAS_ERR_OK ) +#else + IF( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1252,7 +1276,11 @@ ivas_error ivas_jbm_dec_tc_fx( ELSE IF( EQ_16( st_ivas->nCPE, 1 ) ) { +#ifndef FIX_826_PRECISION_LOST_AND_COMPL IF( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0], &q_output ) ) != IVAS_ERR_OK ) +#else + IF( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) +#endif { return error; } diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 5546d3f4c1f3b7a5295fc8c47fb4853b6c96a611..f750f3c9929057907b7f326a7bbc456ddfabf980 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -363,8 +363,11 @@ ivas_error ivas_mct_dec_fx( set32_fx( &output_fx[0][0], 0, L_FRAME48k ); set32_fx( &output_fx[1][0], 0, L_FRAME48k ); - +#ifndef FIX_826_PRECISION_LOST_AND_COMPL IF( NE_32( ( error = ivas_cpe_dec_fx( st_ivas, cpe_id, &output_fx[0], output_frame, 0, &q_output ) ), IVAS_ERR_OK ) ) +#else + IF( NE_32( ( error = ivas_cpe_dec_fx( st_ivas, cpe_id, &output_fx[0], output_frame, 0 ) ), IVAS_ERR_OK ) ) +#endif { return error; } diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index ba197492c257d77ec79c58ad6ce8edb19cabd442..1542469a438d974e0aaa5f2707e4b607753d9898 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -322,7 +322,11 @@ typedef struct stereo_dft_dec_data_struct Word16 Q_nrg_subr; Word16 prev_Q_stefi_sig; +#ifdef FIX_826_PRECISION_LOST_AND_COMPL + Word16 q_td_gain[STEREO_DFT_CORE_HIST_MAX]; +#else Word32 q_td_gain[STEREO_DFT_CORE_HIST_MAX]; +#endif Word16 q_hb_stefi_sig_fx; #endif diff --git a/lib_dec/ivas_stereo_dft_dec_fx.c b/lib_dec/ivas_stereo_dft_dec_fx.c index 6e428de2f10163b9062f42fd4528d673bcba517f..d981db15ef5d29ddc620e14ef3af4a40ba25a0e9 100644 --- a/lib_dec/ivas_stereo_dft_dec_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_fx.c @@ -209,8 +209,11 @@ void stereo_dft_dec_reset_fx( set32_fx( hStereoDft->hb_stefi_sig_fx, 0, L_FRAME48k + NS2SA( 48000, STEREO_DFT_TD_STEFI_DELAY_NS ) ); set32_fx( hStereoDft->hb_nrg_fx, 0, STEREO_DFT_CORE_HIST_MAX ); set32_fx( hStereoDft->td_gain_fx, 0, STEREO_DFT_CORE_HIST_MAX ); +#ifdef FIX_826_PRECISION_LOST_AND_COMPL + set16_fx( hStereoDft->q_td_gain, 0, STEREO_DFT_CORE_HIST_MAX ); +#else set32_fx( hStereoDft->q_td_gain, 0, STEREO_DFT_CORE_HIST_MAX ); - +#endif hStereoDft->q_dft = 0; move16(); @@ -675,7 +678,11 @@ void stereo_dft_dec_update_fx( Copy32( hStereoDft->hb_stefi_sig_fx + output_frame, hStereoDft->hb_stefi_sig_fx, hStereoDft->hb_stefi_delay ); Copy32( hStereoDft->hb_nrg_fx, hStereoDft->hb_nrg_fx + 1, STEREO_DFT_CORE_HIST_MAX - 1 ); Copy32( hStereoDft->td_gain_fx, hStereoDft->td_gain_fx + 1, STEREO_DFT_CORE_HIST_MAX - 1 ); +#ifdef FIX_826_PRECISION_LOST_AND_COMPL + Copy( hStereoDft->q_td_gain, hStereoDft->q_td_gain + 1, STEREO_DFT_CORE_HIST_MAX - 1 ); +#else Copy32( hStereoDft->q_td_gain, hStereoDft->q_td_gain + 1, STEREO_DFT_CORE_HIST_MAX - 1 ); +#endif IF( sba_dirac_stereo_flag ) { diff --git a/lib_dec/ivas_stereo_icbwe_dec.c b/lib_dec/ivas_stereo_icbwe_dec.c index 95d43ad4816d120ba38d701f8ccdd8e2df75ecee..d5acccc7a47daf615b92c266d4f8da55523ad0f0 100644 --- a/lib_dec/ivas_stereo_icbwe_dec.c +++ b/lib_dec/ivas_stereo_icbwe_dec.c @@ -554,9 +554,9 @@ static Word16 FindScale( 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 */ + Word32 *synthRef_fx, /* i/o: Reference channel HB synthesis at output Fs Q11 */ + Word32 *synth_fx, /* o : Non reference channel HB synthesis at output Fs Q11 */ + const Word16 *fb_synth_ref_fx, /* i : ref. high-band synthesis 16-20 kHz Q11 */ 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 */ @@ -578,7 +578,11 @@ void stereo_icBWE_dec_fx( Word16 temp1_fx, temp2_fx; Word16 icbweM2Ref_fx, ratio_L_fx; Word16 gsMapping_fx; +#ifndef FIX_826_PRECISION_LOST_AND_COMPL Word32 hb_nrg_fx, hb_nrg2_fx; +#else + Word32 hb_nrg_fx; +#endif Word16 Q_syn_shb; Word16 shift_prev_pow, synthRef_shift; Word32 L_tmp; @@ -626,7 +630,9 @@ void stereo_icBWE_dec_fx( { hb_nrg_fx = 0; move32(); +#ifndef FIX_826_PRECISION_LOST_AND_COMPL hb_nrg2_fx = 0; +#endif move32(); maximum_abs_32_fx( synthRef_fx, output_frame, &maxVal ); synthRef_shift = norm_l( maxVal ); @@ -635,17 +641,47 @@ void stereo_icBWE_dec_fx( synthRef_shift = 31; move16(); } +#ifndef FIX_826_PRECISION_LOST_AND_COMPL /* Not needed Q11 is already enough */ synthRef_shift = sub( synthRef_shift, shr( add( find_guarded_bits_fx( output_frame ), 1 ), 1 ) ); +#else + synthRef_shift = sub( synthRef_shift, shr( add( find_guarded_bits_fx( shr( output_frame, 1 ) ), 1 ), 1 ) ); +#endif test(); - IF( st->core == ACELP_CORE || st->last_core == ACELP_CORE ) + IF( EQ_16( st->core, ACELP_CORE ) || EQ_16( st->last_core, ACELP_CORE ) ) { - FOR( i = 0; i < output_frame / 2; i++ ) +#ifdef FIX_826_PRECISION_LOST_AND_COMPL + Word64 W_tmp = 0; + move64(); + tmp = shl_sat( 1, synthRef_shift ); +#endif + FOR( i = 0; i < shr( output_frame, 1 ); i++ ) { // needed to be adjusted for q +#ifndef FIX_826_PRECISION_LOST_AND_COMPL 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 +#else + L_tmp = Mpy_32_16_1( synthRef_fx[i], tmp ); + W_tmp = W_mac_32_32( W_tmp, L_tmp, L_tmp ); +#endif + } +#ifdef FIX_826_PRECISION_LOST_AND_COMPL + hb_nrg_fx = W_round48_L( W_tmp ); + hCPE->hStereoDft->hb_nrg_subr_fx[0] = hb_nrg_fx; + move32(); + hStereoDft->q_hb_nrg_subr = sub( shl( add( *Q_syn, synthRef_shift ), 1 ), 45 ); + move16(); + W_tmp = 0; + move64(); + FOR( ; i < output_frame; i++ ) + { + L_tmp = Mpy_32_16_1( synthRef_fx[i], tmp ); + W_tmp = W_mac_32_32( W_tmp, L_tmp, L_tmp ); } + hCPE->hStereoDft->hb_nrg_subr_fx[1] = W_round48_L( W_tmp ); // 2*(Qx + SynthRef_shift) - 45 + hb_nrg_fx = L_add( hCPE->hStereoDft->hb_nrg_subr_fx[0], hCPE->hStereoDft->hb_nrg_subr_fx[1] ); +#else hCPE->hStereoDft->hb_nrg_subr_fx[0] = hb_nrg2_fx; move32(); hStereoDft->q_hb_nrg_subr = sub( add( *Q_syn, synthRef_shift ), 31 ); @@ -662,10 +698,13 @@ void stereo_icBWE_dec_fx( 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 ); +#endif - Copy32( synthRef_fx, hCPE->hStereoDft->hb_stefi_sig_fx + hCPE->hStereoDft->hb_stefi_delay, output_frame ); + Copy32( synthRef_fx, hCPE->hStereoDft->hb_stefi_sig_fx + hCPE->hStereoDft->hb_stefi_delay, output_frame ); +#ifndef FIX_826_PRECISION_LOST_AND_COMPL Scale_sig32( hCPE->hStereoDft->hb_stefi_sig_fx + hCPE->hStereoDft->hb_stefi_delay, output_frame, -5 ); +#endif } ELSE { @@ -681,7 +720,11 @@ void stereo_icBWE_dec_fx( 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(); +#ifndef FIX_826_PRECISION_LOST_AND_COMPL hCPE->hStereoDft->q_hb_nrg_subr = sub( shl( ( *Q_syn + synthRef_shift ), 1 ), 40 ); +#else + hCPE->hStereoDft->q_hb_nrg_subr = sub( shl( ( *Q_syn + synthRef_shift ), 1 ), 45 + 9 ); +#endif hCPE->hStereoDft->hb_nrg_fx[0] = hb_nrg_fx; // 2 * (Qx + SynthRef_shift) - 31 move32(); hCPE->hStereoDft->td_gain_fx[0] = 0; @@ -759,6 +802,7 @@ void stereo_icBWE_dec_fx( move16(); FOR( i = 0; i < winLen_fx; i++ ) { +#ifndef FIX_826_PRECISION_LOST_AND_COMPL 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 @@ -773,6 +817,20 @@ void stereo_icBWE_dec_fx( { alpha_fx = add( alpha_fx, winSlope_fx ); } +#else + /*synthRef[i] *= ( alpha * ( icbweM2Ref ) + ( 1.0f - alpha ) * ( hStereoICBWE->icbweM2Ref_prev ) );*/ + temp1_fx = sub( 32767, alpha_fx ); + L_tmp = L_mult( alpha_fx, icbweM2Ref_fx ); // Q15 + Q14 + 1 + L_tmp = L_mac( L_tmp, temp1_fx, hStereoICBWE->icbweM2Ref_prev_fx ); // Q15 + Q14 +1 ; + synthRef_fx[i] = L_shl( Mpy_32_32( synthRef_fx[i], L_tmp ), 1 ); + move32(); + /*synth[i] *= ( alpha * ( gsMapping ) + ( 1.0f - alpha ) * ( prevgsMapping ) );*/ + L_tmp = L_mult( alpha_fx, gsMapping_fx ); + L_tmp = L_mac( L_tmp, temp1_fx, prevgsMapping_fx ); + synth_fx[i] = L_shl( Mpy_32_32( synth_fx[i], L_tmp ), 1 ); + move32(); + alpha_fx = add_sat( alpha_fx, winSlope_fx ); +#endif } FOR( ; i < NS2SA( st->output_Fs, FRAME_SIZE_NS ); i++ ) { @@ -1326,7 +1384,7 @@ void stereo_icBWE_dec_fx( #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 + 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 @@ -1675,15 +1733,22 @@ void stereo_icBWE_decproc_fx( 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 */ + const Word16 output_frame /* i : frame length */ +#ifndef FIX_826_PRECISION_LOST_AND_COMPL + , + Word16 q_output /* i : Q-fac of output */ +#endif ) { 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 )]; +#if defined FIX_826_PRECISION_LOST_AND_COMPL + Word16 winSlope_fx = 0, alpha_fx; +#else Word32 winSlope_fx = 0, alpha_fx; +#endif move32(); const Word16 *win_dft_fx; Word32 extl_brate, output_Fs; @@ -1754,7 +1819,11 @@ void stereo_icBWE_decproc_fx( /* stereo to mono downmix */ FOR( i = 0; i < output_frame; i++ ) { +#ifdef FIX_826_PRECISION_LOST_AND_COMPL + outputHB[0][i] = W_extract_h( W_mac_32_16( W_mult_32_16( outputHB[0][i], 16384 ), outputHB[1][i], 16384 ) ); +#else outputHB[0][i] = L_shr( ( outputHB[0][i] + outputHB[1][i] ), 1 ); +#endif move32(); } v_add_32( output[0], outputHB[0], output[0], output_frame ); @@ -1809,6 +1878,20 @@ void stereo_icBWE_decproc_fx( { SWITCH( memOffset ) { +#if defined FIX_826_PRECISION_LOST_AND_COMPL + case 15: + winSlope_fx = 2185; + move32(); + BREAK; + case 30: + winSlope_fx = 1092; + move32(); + BREAK; + case 45: + winSlope_fx = 728; + move32(); + BREAK; +#else case 15: winSlope_fx = 71582792; move32(); @@ -1821,6 +1904,7 @@ void stereo_icBWE_decproc_fx( winSlope_fx = 23860930; move32(); BREAK; +#endif } // memOffset for 16K 32K 48K are 15 30 45 respectively.camera } @@ -1829,11 +1913,20 @@ void stereo_icBWE_decproc_fx( winSlope_fx = 0; move32(); } +#if defined FIX_826_PRECISION_LOST_AND_COMPL + alpha_fx = 0; + move16(); +#endif FOR( i = 0; i < memOffset; i++ ) { +#if defined FIX_826_PRECISION_LOST_AND_COMPL + alpha_fx = add_sat( alpha_fx, winSlope_fx ); + outputHB[refChanIndx_bwe][i] = W_round48_L( W_mult_32_16( outputHB[refChanIndx_bwe][i] /* Q11 + Q15 + 1 - 16 = Q11)*/, winSlope_fx ) ); // +#else 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 ); // +#endif move32(); } } @@ -1860,6 +1953,24 @@ void stereo_icBWE_decproc_fx( assert( icbweOLASize > 0 ); SWITCH( icbweOLASize ) { +#if defined FIX_826_PRECISION_LOST_AND_COMPL + case 60: + winSlope_fx = 546; + move16(); + BREAK; + case 40: + winSlope_fx = 819; + move16(); + BREAK; + case 20: + winSlope_fx = 1638; + move16(); + BREAK; + default: + fprintf( stderr, "icbweOLASize of size %d not implemented \n", icbweOLASize ); + assert( 0 ); + BREAK; +#else case 60: winSlope_fx = 17895698; move32(); @@ -1872,16 +1983,25 @@ void stereo_icBWE_decproc_fx( winSlope_fx = 53687092; move32(); BREAK; +#endif } alpha_fx = winSlope_fx; // Q30 move32(); FOR( ; i < add( decoderDelay, icbweOLASize ); i++ ) { +#if defined FIX_826_PRECISION_LOST_AND_COMPL + temp0_fx[i] = W_round48_L( W_mult_32_16( temp0_fx[i], alpha_fx ) ); // Q11 + move32(); + temp1_fx[i] = W_round48_L( W_mult_32_16( temp1_fx[i], alpha_fx ) ); + move32(); + alpha_fx = add_sat( alpha_fx, winSlope_fx ); +#else 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 ); +#endif } } ELSE @@ -1892,6 +2012,20 @@ void stereo_icBWE_decproc_fx( { SWITCH( memOffset ) { +#if defined FIX_826_PRECISION_LOST_AND_COMPL + case 15: + winSlope_fx = 2185; + move16(); + BREAK; + case 30: + winSlope_fx = 1092; + move16(); + BREAK; + case 45: + winSlope_fx = 728; + move16(); + BREAK; +#else case 15: winSlope_fx = 71582792; move32(); @@ -1904,6 +2038,7 @@ void stereo_icBWE_decproc_fx( winSlope_fx = 23860930; // Q30 move32(); BREAK; +#endif } // memOffset for 16K 32K 48K are 15 30 45 respectively.camera } @@ -1912,14 +2047,27 @@ void stereo_icBWE_decproc_fx( winSlope_fx = 0; move32(); } +#if defined FIX_826_PRECISION_LOST_AND_COMPL + Word16 Incr = 0; + Word16 Decr = MAX_16; +#endif + move16(); + move16(); FOR( i = 0; i < memOffset; i++ ) { +#ifndef FIX_826_PRECISION_LOST_AND_COMPL 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 ) ); +#else + Incr = add_sat( Incr, winSlope_fx ); + Decr = sub( Decr, winSlope_fx ); + temp0_fx[i] = W_round48_L( W_mac_32_16( W_mult_32_16( hStereoICBWE->memOutHB_fx[refChanIndx_bwe][i], Incr ), hStereoICBWE->memOutHB_fx[hStereoICBWE->prev_refChanIndx_bwe][i], Decr ) ); + temp1_fx[i] = W_round48_L( W_mac_32_16( W_mult_32_16( hStereoICBWE->memOutHB_fx[hStereoICBWE->prev_refChanIndx_bwe][i], Incr ), hStereoICBWE->memOutHB_fx[refChanIndx_bwe][i], Decr ) ); +#endif move32(); } } @@ -1932,14 +2080,25 @@ void stereo_icBWE_decproc_fx( IF( EQ_16( hCPE->nchan_out, 1 ) ) { +#ifdef FIX_826_PRECISION_LOST_AND_COMPL + Word64 W_tmp; +#endif /* stereo to mono downmix */ FOR( i = 0; i < output_frame; i++ ) { +#ifndef FIX_826_PRECISION_LOST_AND_COMPL 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] ); +#else + W_tmp = W_mult_32_16( output[0][i], 32767 ); + W_tmp = W_mac_32_16( W_tmp, temp0_fx[i], 16384 ); + output[0][i] = W_round48_L( W_mac_32_16( W_tmp, temp1_fx[i], 16384 ) ); + move32(); + +#endif move32(); } } @@ -1960,26 +2119,53 @@ void stereo_icBWE_decproc_fx( move16(); /* Preparing buffers in anticipation of an ACELP to TCX switch */ + +#ifndef FIX_826_PRECISION_LOST_AND_COMPL j = 0; move16(); +#else + j = sub( dftOvlLen, 1 ); +#endif FOR( i = 0; i < memOffset; i++ ) { +#ifndef FIX_826_PRECISION_LOST_AND_COMPL 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 = add( j, 1 ); +#else + Word16 tmp_mul = i_mult( STEREO_DFT32MS_STEP, 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 = sub( j, 1 ); +#endif } +#ifndef FIX_826_PRECISION_LOST_AND_COMPL FOR( i = 0; j < dftOvlLen; i++ ) +#else + FOR( i = 0; i < dftOvlLen; i++ ) +#endif { +#ifndef FIX_826_PRECISION_LOST_AND_COMPL 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 = add( j, 1 ); +#else + Word16 tmp_mul = i_mult( STEREO_DFT32MS_STEP, 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 = sub( j, 1 ); +#endif } } @@ -2034,8 +2220,12 @@ void stereo_icBWE_decproc_fx( 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 ) ) { +#ifdef FIX_826_PRECISION_LOST_AND_COMPL + Word32 win_in_fx, win_out_fx, tmp_fx; + Word64 W_tmp, W_tmp1; +#else Word32 win_in_fx, win_out_fx, tmp_fx, gain0_fx, gain1_fx; - +#endif win_dft_fx = hCPE->hStereoDft->win32ms_fx; dftOvlLen = hCPE->hStereoDft->dft32ms_ovl; move16(); @@ -2044,6 +2234,31 @@ void stereo_icBWE_decproc_fx( FOR( i = 0; i < dftOvlLen; i++ ) { +#ifdef FIX_826_PRECISION_LOST_AND_COMPL + j = i_mult( STEREO_DFT32MS_STEP, i ); + win_in_fx = L_mult( win_dft_fx[j], win_dft_fx[j] ); /* Q31 */ + win_out_fx = L_sub( ONE_IN_Q31, win_in_fx ); /* Q31 */ + /* hCPE->hStereoDft->q_hb_stefi_sig_fx is always 31 here */ + /* tmp = ( win_in * hCPE->hStereoDft->td_gain[0] + win_out * hCPE->hStereoDft->td_gain[1] ) * hCPE->hStereoDft->hb_stefi_sig[i]; */ + + W_tmp = W_mult_32_32( hCPE->hStereoDft->td_gain_fx[0], win_in_fx ); + if ( hCPE->hStereoDft->q_td_gain[0] != 0 ) + { + W_tmp = W_shl( W_tmp, sub( 31, hCPE->hStereoDft->q_td_gain[0] ) ); + } + W_tmp1 = W_mult_32_32( hCPE->hStereoDft->td_gain_fx[1], win_out_fx ); + if ( hCPE->hStereoDft->q_td_gain[1] != 0 ) + { + W_tmp1 = W_shl( W_tmp1, sub( 31, hCPE->hStereoDft->q_td_gain[1] ) ); + } + tmp_fx = W_extract_h( W_add_nosat( W_tmp, W_tmp1 ) ); + tmp_fx = W_extract_h( W_mult_32_32( tmp_fx, hCPE->hStereoDft->hb_stefi_sig_fx[i] ) ); + + output[0][i] = L_add_sat( output[0][i], tmp_fx ); + move32(); + output[1][i] = L_sub_sat( output[1][i], tmp_fx ); + move32(); +#else 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 */ @@ -2063,13 +2278,18 @@ void stereo_icBWE_decproc_fx( move32(); output[1][i] = L_sub_sat( output[1][i], tmp_fx ); move32(); +#endif } FOR( i = dftOvlLen; i < output_frame; i++ ) { +#ifdef FIX_826_PRECISION_LOST_AND_COMPL + tmp_fx = W_extract_h( W_mult_32_32( hCPE->hStereoDft->td_gain_fx[0], hCPE->hStereoDft->hb_stefi_sig_fx[i] ) ); /* Q11 --> Q11 */ +#else #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 #endif output[0][i] = L_add_sat( output[0][i], tmp_fx ); move32();