From bb55862d3bbd4d106b2f10e9ff6deb35595b32f1 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 4 Mar 2025 20:41:36 +0530 Subject: [PATCH 1/2] Duplicate lib_dec files cleanup --- Workspace_msvc/lib_dec.vcxproj | 14 - Workspace_msvc/lib_dec.vcxproj.filters | 42 - lib_dec/FEC_HQ_core.c | 136 -- lib_dec/FEC_HQ_core_fx.c | 92 + lib_dec/ari_dec.c | 338 ---- lib_dec/ari_dec_fx.c | 289 +++ lib_dec/arith_coder_dec.c | 250 --- lib_dec/arith_coder_dec_fx.c | 208 ++ lib_dec/bass_psfilter.c | 317 --- lib_dec/bass_psfilter_fx.c | 244 +++ lib_dec/core_dec_init.c | 84 - lib_dec/core_dec_init_fx.c | 26 + lib_dec/core_switching_dec.c | 1076 ---------- lib_dec/core_switching_dec_fx.c | 1009 ++++++++++ lib_dec/dec_prm.c | 328 ---- lib_dec/dec_prm_fx.c | 270 +++ lib_dec/dec_tcx.c | 508 ----- lib_dec/dec_tcx_fx.c | 447 +++++ lib_dec/fd_cng_dec.c | 1393 ------------- lib_dec/fd_cng_dec_fx.c | 1280 ++++++++++++ lib_dec/init_dec.c | 76 - lib_dec/init_dec_fx.c | 15 + lib_dec/ivas_mc_param_dec.c | 33 + lib_dec/ivas_mc_param_dec_fx.c | 34 - lib_dec/swb_bwe_dec.c | 681 ------- lib_dec/swb_bwe_dec_fx.c | 369 ++++ lib_dec/swb_tbe_dec.c | 2478 ------------------------ lib_dec/swb_tbe_dec_fx.c | 2034 ++++++++++++++++++- lib_dec/tonalMDCTconcealment.c | 436 ----- lib_dec/tonalMDCTconcealment_fx.c | 391 ++++ 30 files changed, 6701 insertions(+), 8197 deletions(-) delete mode 100644 lib_dec/FEC_HQ_core.c delete mode 100644 lib_dec/ari_dec.c delete mode 100644 lib_dec/arith_coder_dec.c delete mode 100644 lib_dec/bass_psfilter.c delete mode 100644 lib_dec/core_dec_init.c delete mode 100644 lib_dec/core_switching_dec.c delete mode 100644 lib_dec/dec_prm.c delete mode 100644 lib_dec/dec_tcx.c delete mode 100644 lib_dec/fd_cng_dec.c delete mode 100644 lib_dec/init_dec.c delete mode 100644 lib_dec/ivas_mc_param_dec_fx.c delete mode 100644 lib_dec/swb_bwe_dec.c delete mode 100644 lib_dec/swb_tbe_dec.c delete mode 100644 lib_dec/tonalMDCTconcealment.c diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index 3d447fe21..b3a847791 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -145,22 +145,17 @@ - - - false - - @@ -176,9 +171,7 @@ - - @@ -191,12 +184,10 @@ - - @@ -216,7 +207,6 @@ - @@ -246,7 +236,6 @@ - @@ -310,18 +299,15 @@ - - - diff --git a/Workspace_msvc/lib_dec.vcxproj.filters b/Workspace_msvc/lib_dec.vcxproj.filters index cc7594415..c4e148b89 100644 --- a/Workspace_msvc/lib_dec.vcxproj.filters +++ b/Workspace_msvc/lib_dec.vcxproj.filters @@ -8,9 +8,6 @@ decoder_evs_c - - decoder_evs_c - decoder_evs_c @@ -137,9 +134,6 @@ decoder_ivas_c - - decoder_ivas_c - decoder_ivas_c @@ -275,36 +269,24 @@ decoder_all_c - - decoder_all_c - decoder_all_c decoder_all_c - - decoder_all_c - decoder_all_c decoder_all_c - - decoder_all_c - decoder_all_c decoder_all_c - - decoder_all_c - decoder_all_c @@ -320,15 +302,9 @@ decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c @@ -365,9 +341,6 @@ decoder_all_c - - decoder_all_c - decoder_all_c @@ -380,9 +353,6 @@ decoder_all_c - - decoder_all_c - decoder_all_c @@ -437,9 +407,6 @@ decoder_all_c - - decoder_all_c - decoder_all_c @@ -515,15 +482,9 @@ decoder_all_c - - decoder_all_c - decoder_all_c - - decoder_all_c - decoder_all_c @@ -542,9 +503,6 @@ decoder_all_c - - decoder_all_c - decoder_all_c diff --git a/lib_dec/FEC_HQ_core.c b/lib_dec/FEC_HQ_core.c deleted file mode 100644 index 6a119b365..000000000 --- a/lib_dec/FEC_HQ_core.c +++ /dev/null @@ -1,136 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_dec.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" - - -void save_synthesis_hq_fec_fx( - Decoder_State *st, /* i/o: decoder state structure */ - const Word32 output_fx[], /* i : decoded synthesis */ - const Word16 output_frame, /* i : decoded synthesis */ - CPE_DEC_HANDLE hCPE /* i : CPE decoder structure */ -) -{ - Word16 post_hq_delay; - - SWITCH( st->element_mode ) - { - case EVS_MONO: - post_hq_delay = NS2SA_FX2( st->output_Fs, POST_HQ_DELAY_NS ); - BREAK; - case IVAS_SCE: - post_hq_delay = NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ); - BREAK; - case IVAS_CPE_DFT: - test(); - IF( EQ_16( hCPE->nchan_out, 1 ) && hCPE->hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF ) - { - post_hq_delay = NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ); - } - ELSE - { - post_hq_delay = 0; - move16(); - } - BREAK; - default: - post_hq_delay = 0; - move16(); - BREAK; - } - - test(); - test(); - test(); - test(); - test(); - IF( ( EQ_16( st->codec_mode, MODE1 ) && st->hTcxDec != NULL ) && ( ( ( st->core == ACELP_CORE ) && !( EQ_16( st->bfi, 1 ) && EQ_16( st->con_tcx, 1 ) ) ) || EQ_16( st->core, HQ_CORE ) ) ) - { - Copy( st->hTcxDec->synth_history_fx + output_frame, st->hTcxDec->synth_history_fx, add( sub( output_frame, post_hq_delay ), NS2SA_FX2( st->output_Fs, PH_ECU_MEM_NS ) ) ); - FOR( Word16 i = 0; i < output_frame; i++ ) - { - st->hTcxDec->old_synthFB_fx[( ( i + output_frame ) - post_hq_delay )] = extract_h( L_shl_sat( output_fx[i], 16 ) ); // Q16 - move16(); - } - - IF( st->element_mode == EVS_MONO ) - { - /* reset the remaining buffer, which is read in TCX concealment the necessary samples to fill - this buffer are not available for all cases, the impact on the output is limited */ - - set16_fx( st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), post_hq_delay ), 0, post_hq_delay ); - IF( GE_16( output_frame, L_FRAME16k ) ) - { - Copy( st->prev_synth_buffer_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); - } - ELSE - { - Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); - } - - IF( st->core != ACELP_CORE ) - { - IF( GE_16( output_frame, L_FRAME16k ) ) - { - Copy( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ); - Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); - } - ELSE - { - Copy( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ); - Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); - } - } - } - ELSE - { - IF( st->core != ACELP_CORE ) - { - Copy( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), post_hq_delay ), post_hq_delay ); - Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); - } - } - } - return; -} diff --git a/lib_dec/FEC_HQ_core_fx.c b/lib_dec/FEC_HQ_core_fx.c index f88927ee5..09bc652be 100644 --- a/lib_dec/FEC_HQ_core_fx.c +++ b/lib_dec/FEC_HQ_core_fx.c @@ -1961,6 +1961,98 @@ static void Next_good_after_burst_erasures_fx( return; } + +void save_synthesis_hq_fec_fx( + Decoder_State *st, /* i/o: decoder state structure */ + const Word32 output_fx[], /* i : decoded synthesis */ + const Word16 output_frame, /* i : decoded synthesis */ + CPE_DEC_HANDLE hCPE /* i : CPE decoder structure */ +) +{ + Word16 post_hq_delay; + + SWITCH( st->element_mode ) + { + case EVS_MONO: + post_hq_delay = NS2SA_FX2( st->output_Fs, POST_HQ_DELAY_NS ); + BREAK; + case IVAS_SCE: + post_hq_delay = NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ); + BREAK; + case IVAS_CPE_DFT: + test(); + IF( EQ_16( hCPE->nchan_out, 1 ) && hCPE->hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF ) + { + post_hq_delay = NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ); + } + ELSE + { + post_hq_delay = 0; + move16(); + } + BREAK; + default: + post_hq_delay = 0; + move16(); + BREAK; + } + + test(); + test(); + test(); + test(); + test(); + IF( ( EQ_16( st->codec_mode, MODE1 ) && st->hTcxDec != NULL ) && ( ( ( st->core == ACELP_CORE ) && !( EQ_16( st->bfi, 1 ) && EQ_16( st->con_tcx, 1 ) ) ) || EQ_16( st->core, HQ_CORE ) ) ) + { + Copy( st->hTcxDec->synth_history_fx + output_frame, st->hTcxDec->synth_history_fx, add( sub( output_frame, post_hq_delay ), NS2SA_FX2( st->output_Fs, PH_ECU_MEM_NS ) ) ); + FOR( Word16 i = 0; i < output_frame; i++ ) + { + st->hTcxDec->old_synthFB_fx[( ( i + output_frame ) - post_hq_delay )] = extract_h( L_shl_sat( output_fx[i], 16 ) ); // Q16 + move16(); + } + + IF( st->element_mode == EVS_MONO ) + { + /* reset the remaining buffer, which is read in TCX concealment the necessary samples to fill + this buffer are not available for all cases, the impact on the output is limited */ + + set16_fx( st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), post_hq_delay ), 0, post_hq_delay ); + IF( GE_16( output_frame, L_FRAME16k ) ) + { + Copy( st->prev_synth_buffer_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); + } + ELSE + { + Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); + } + + IF( st->core != ACELP_CORE ) + { + IF( GE_16( output_frame, L_FRAME16k ) ) + { + Copy( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ); + Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); + } + ELSE + { + Copy( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS ) ), NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ) ); + Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); + } + } + } + ELSE + { + IF( st->core != ACELP_CORE ) + { + Copy( st->delay_buf_out_fx, st->hTcxDec->old_synthFB_fx + sub( shl( output_frame, 1 ), post_hq_delay ), post_hq_delay ); + Copy( st->hHQ_core->old_out_fx + NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), st->hTcxDec->old_synthFB_fx + shl( output_frame, 1 ), NS2SA_FX2( st->output_Fs, PH_ECU_LOOKAHEAD_NS ) ); + } + } + } + return; +} + + #ifdef ADD_IVAS_HQ_CODE_FEC /*-------------------------------------------------------------------------- * save_synthesis_hq_fec() diff --git a/lib_dec/ari_dec.c b/lib_dec/ari_dec.c deleted file mode 100644 index b45cb5d9c..000000000 --- a/lib_dec/ari_dec.c +++ /dev/null @@ -1,338 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "prot_fx.h" -#include "stat_com.h" -#include "basop_util.h" -#include "wmc_auto.h" - - -/*--------------------------------------------------------------- - * Ari decode 14 bits routines - -------------------------------------------------------------*/ - -/*--------------------------------------------------------------- - * ari_start_decoding_14bits_ivas() - * - * Start ArCo decoding - *-------------------------------------------------------------*/ - - -Word16 ari_start_decoding_14bits_prm_ivas_fx( - const Word16 *ptr, - Word16 bp, - Tastat *s ) -{ - Word32 val; - Word16 i; - const Word16 *p; - - val = 0; - move32(); - p = ptr + bp; - - FOR( i = 0; i < cbitsnew; i++ ) - { - val = L_or( L_shl( val, 1 ), *( p + i ) ); - } - s->low = 0; - move32(); - s->high = ari_q4new; - move32(); - s->value = val; - move32(); - - return add( bp, i ); -} - - -Word16 ari_decode_14bits_pow_ivas( - Word16 *ptr, - Word16 bp, - Word16 bits, - Word16 *res, - Tastat *s, - UWord16 base ) -{ - UWord16 symbol; - Word32 low, high; - UWord32 range, value, cum; - Word16 pows[12]; /* "base" to the power of 2, 4, 8,... 2^12 */ - Word16 lowlim, highlim, testval; - Word16 k; - - highlim = 0; - low = s->low; - high = L_add( s->high, 1 ); - value = s->value; - lowlim = 0; - symbol = 0; - move16(); - move32(); - move32(); - move16(); - move16(); - - range = (UWord32) W_sub( high, low ); - move32(); - - /* the value read from bitstream */ - assert( value >= (UWord32) low ); - cum = (UWord32) W_add( W_shl( ( W_sub( value, low ) ), stat_bitsnew ), ( 1 << stat_bitsnew ) - 1 ); - move32(); - - /* search for the interval where "cum" fits */ - IF( GT_64( W_mult0_32_32( L_shr( base, 1 ), range ), cum ) ) /* below pow-1 */ - { - pows[0] = testval = base; - move16(); - move16(); - /* increase exponent until it is smaller than "cum" */ - FOR( k = 1; k < 12; k++ ) - { - highlim = testval; - move16(); - pows[k] = mult_r( pows[k - 1], pows[k - 1] ); - move16(); - testval = mult_r( pows[k], base ); - IF( LE_64( W_mult0_32_32( shr( testval, 1 ), range ), cum ) ) /* found! big range is [lowlim,testval], (now narrow it down) */ - { - lowlim = testval; - move16(); - k = sub( k, 1 ); - symbol = (UWord16) L_shl( 1, k ); - BREAK; - } - } - assert( k < 12 ); /* maximum 2^10-1*/ - /* narrow the range down */ - FOR( k--; k > 0; k-- ) - { - testval = mult_r( highlim, pows[k] ); - IF( LE_64( W_mult0_32_32( shr( testval, 1 ), range ), cum ) ) - { - lowlim = testval; - move16(); - symbol = (UWord16) L_sub( symbol, L_shl( 1, sub( k, 1 ) ) ); - } - ELSE - { - highlim = testval; - move16(); - } - } - highlim = shr( highlim, 1 ); - lowlim = shr( lowlim, 1 ); - } - ELSE /* trivial case, above pow-1, that is, first symbol */ - { - symbol = 0; - lowlim = extract_l( L_shr( base, 1 ) ); - highlim = 16384; - move16(); - move16(); - } - - - high = L_add( low, mul_sbc_14bits( range, highlim ) ); - - low = L_add( low, mul_sbc_14bits( range, lowlim ) ); - - /*ptr init for ptr*/ - FOR( ; bp < bits; ) - { - IF( GT_32( high, ari_q2new ) ) - { - IF( GE_32( low, ari_q2new ) ) - { - value = (UWord32) W_sub( value, ari_q2new ); - low = L_sub( low, ari_q2new ); - high = L_sub( high, ari_q2new ); - } - ELSE - { - test(); - IF( GE_32( low, ari_q1new ) && LE_32( high, ari_q3new ) ) - { - value = (UWord32) W_sub( value, ari_q1new ); - low = L_sub( low, ari_q1new ); - high = L_sub( high, ari_q1new ); - } - ELSE - { - BREAK; - } - } - } - low = L_add( low, low ); - high = L_add( high, high ); - - assert( abs( ptr[bp] ) <= 1 && "AC expects reading binary values!!!" ); - - value = (UWord32) ( W_shl( value, 1 ) | ptr[bp++] ); - } - - test(); - test(); - test(); - IF( !( NE_16( bp, bits ) || !( EQ_32( s->low, low ) && ( EQ_32( s->high, high ) ) && ( EQ_64( s->value, value ) ) ) ) ) - { - /* This should not happen except of bit errors. */ - s->high = s->low = 0; - move32(); - move32(); - *res = 0; - move16(); - return -1; - } - - s->low = low; - s->high = L_sub( high, 1 ); - s->value = value; - move32(); - move32(); - move32(); - - *res = symbol; - move16(); - return bp; -} - -Word16 ari_decode_14bits_sign_ivas( - Word16 *ptr, - Word16 bp, - Word16 bits, - Word16 *res, - Tastat *s ) -{ - Word16 symbol; - Word32 low, high; - UWord32 range, value, cum; - - low = s->low; - high = L_add( s->high, 1 ); - value = s->value; - move32(); - move32(); - - range = (UWord32) W_sub( high, low ); - - IF( LT_16( bp, bits ) ) - { - assert( value >= (UWord32) low ); - cum = (UWord32) W_add( W_shl( ( W_sub( value, low ) ), stat_bitsnew ), ( 1 << stat_bitsnew ) - 1 ); - IF( GT_64( W_shl( range, 13 ), cum ) ) - { - symbol = 2; - move16(); - high = L_add( low, W_extract_l( W_shr( range, 1 ) ) ); - } - ELSE - { - symbol = 1; - move16(); - low = L_add( low, W_extract_l( W_shr( range, 1 ) ) ); - } - - /*ptr init for ptr*/ - FOR( ; bp < bits; ) - { - IF( GT_32( high, ari_q2new ) ) - { - IF( GE_32( low, ari_q2new ) ) - { - value = (UWord32) W_sub( value, ari_q2new ); - low = L_sub( low, ari_q2new ); - high = L_sub( high, ari_q2new ); - } - ELSE - { - test(); - IF( GE_32( low, ari_q1new ) && LE_32( high, ari_q3new ) ) - { - value = (UWord32) W_sub( value, ari_q1new ); - low = L_sub( low, ari_q1new ); - high = L_sub( high, ari_q1new ); - } - ELSE - { - BREAK; - } - } - } - low = L_add( low, low ); - high = L_add( high, high ); - - assert( abs( ptr[bp] ) <= 1 && "AC expects reading binary values!!!" ); - - value = (UWord32) ( W_shl( value, 1 ) | ptr[bp++] ); - } - } - ELSE - { - cum = (UWord32) W_sub( value, low ); - range = (UWord32) W_shr( range, 1 ); - IF( GT_64( range, cum ) ) - { - symbol = 2; - move16(); - high = L_add( low, range ); - } - ELSE - { - symbol = 1; - move16(); - low = L_add( low, range ); - } - } - - s->low = low; - s->high = L_sub( high, 1 ); - s->value = value; - move32(); - move32(); - move32(); - - *res = symbol; - move16(); - - return bp; -} diff --git a/lib_dec/ari_dec_fx.c b/lib_dec/ari_dec_fx.c index 3681568f2..524f9d121 100644 --- a/lib_dec/ari_dec_fx.c +++ b/lib_dec/ari_dec_fx.c @@ -551,3 +551,292 @@ Word16 ari_decode_14bits_sign_fx( Word16 *ptr, Word16 bp, Word16 bits, Word16 *r { return ari_decode_14bits_notbl_fx( ptr, bp, bits, res, s, 0, ari_lookup_sign_fx ); } + +/*--------------------------------------------------------------- + * ari_start_decoding_14bits_ivas() + * + * Start ArCo decoding + *-------------------------------------------------------------*/ + + +Word16 ari_start_decoding_14bits_prm_ivas_fx( + const Word16 *ptr, + Word16 bp, + Tastat *s ) +{ + Word32 val; + Word16 i; + const Word16 *p; + + val = 0; + move32(); + p = ptr + bp; + + FOR( i = 0; i < cbitsnew; i++ ) + { + val = L_or( L_shl( val, 1 ), *( p + i ) ); + } + s->low = 0; + move32(); + s->high = ari_q4new; + move32(); + s->value = val; + move32(); + + return add( bp, i ); +} + + +Word16 ari_decode_14bits_pow_ivas( + Word16 *ptr, + Word16 bp, + Word16 bits, + Word16 *res, + Tastat *s, + UWord16 base ) +{ + UWord16 symbol; + Word32 low, high; + UWord32 range, value, cum; + Word16 pows[12]; /* "base" to the power of 2, 4, 8,... 2^12 */ + Word16 lowlim, highlim, testval; + Word16 k; + + highlim = 0; + low = s->low; + high = L_add( s->high, 1 ); + value = s->value; + lowlim = 0; + symbol = 0; + move16(); + move32(); + move32(); + move16(); + move16(); + + range = (UWord32) W_sub( high, low ); + move32(); + + /* the value read from bitstream */ + assert( value >= (UWord32) low ); + cum = (UWord32) W_add( W_shl( ( W_sub( value, low ) ), stat_bitsnew ), ( 1 << stat_bitsnew ) - 1 ); + move32(); + + /* search for the interval where "cum" fits */ + IF( GT_64( W_mult0_32_32( L_shr( base, 1 ), range ), cum ) ) /* below pow-1 */ + { + pows[0] = testval = base; + move16(); + move16(); + /* increase exponent until it is smaller than "cum" */ + FOR( k = 1; k < 12; k++ ) + { + highlim = testval; + move16(); + pows[k] = mult_r( pows[k - 1], pows[k - 1] ); + move16(); + testval = mult_r( pows[k], base ); + IF( LE_64( W_mult0_32_32( shr( testval, 1 ), range ), cum ) ) /* found! big range is [lowlim,testval], (now narrow it down) */ + { + lowlim = testval; + move16(); + k = sub( k, 1 ); + symbol = (UWord16) L_shl( 1, k ); + BREAK; + } + } + assert( k < 12 ); /* maximum 2^10-1*/ + /* narrow the range down */ + FOR( k--; k > 0; k-- ) + { + testval = mult_r( highlim, pows[k] ); + IF( LE_64( W_mult0_32_32( shr( testval, 1 ), range ), cum ) ) + { + lowlim = testval; + move16(); + symbol = (UWord16) L_sub( symbol, L_shl( 1, sub( k, 1 ) ) ); + } + ELSE + { + highlim = testval; + move16(); + } + } + highlim = shr( highlim, 1 ); + lowlim = shr( lowlim, 1 ); + } + ELSE /* trivial case, above pow-1, that is, first symbol */ + { + symbol = 0; + lowlim = extract_l( L_shr( base, 1 ) ); + highlim = 16384; + move16(); + move16(); + } + + + high = L_add( low, mul_sbc_14bits( range, highlim ) ); + + low = L_add( low, mul_sbc_14bits( range, lowlim ) ); + + /*ptr init for ptr*/ + FOR( ; bp < bits; ) + { + IF( GT_32( high, ari_q2new ) ) + { + IF( GE_32( low, ari_q2new ) ) + { + value = (UWord32) W_sub( value, ari_q2new ); + low = L_sub( low, ari_q2new ); + high = L_sub( high, ari_q2new ); + } + ELSE + { + test(); + IF( GE_32( low, ari_q1new ) && LE_32( high, ari_q3new ) ) + { + value = (UWord32) W_sub( value, ari_q1new ); + low = L_sub( low, ari_q1new ); + high = L_sub( high, ari_q1new ); + } + ELSE + { + BREAK; + } + } + } + low = L_add( low, low ); + high = L_add( high, high ); + + assert( abs( ptr[bp] ) <= 1 && "AC expects reading binary values!!!" ); + + value = (UWord32) ( W_shl( value, 1 ) | ptr[bp++] ); + } + + test(); + test(); + test(); + IF( !( NE_16( bp, bits ) || !( EQ_32( s->low, low ) && ( EQ_32( s->high, high ) ) && ( EQ_64( s->value, value ) ) ) ) ) + { + /* This should not happen except of bit errors. */ + s->high = s->low = 0; + move32(); + move32(); + *res = 0; + move16(); + return -1; + } + + s->low = low; + s->high = L_sub( high, 1 ); + s->value = value; + move32(); + move32(); + move32(); + + *res = symbol; + move16(); + return bp; +} + +Word16 ari_decode_14bits_sign_ivas( + Word16 *ptr, + Word16 bp, + Word16 bits, + Word16 *res, + Tastat *s ) +{ + Word16 symbol; + Word32 low, high; + UWord32 range, value, cum; + + low = s->low; + high = L_add( s->high, 1 ); + value = s->value; + move32(); + move32(); + + range = (UWord32) W_sub( high, low ); + + IF( LT_16( bp, bits ) ) + { + assert( value >= (UWord32) low ); + cum = (UWord32) W_add( W_shl( ( W_sub( value, low ) ), stat_bitsnew ), ( 1 << stat_bitsnew ) - 1 ); + IF( GT_64( W_shl( range, 13 ), cum ) ) + { + symbol = 2; + move16(); + high = L_add( low, W_extract_l( W_shr( range, 1 ) ) ); + } + ELSE + { + symbol = 1; + move16(); + low = L_add( low, W_extract_l( W_shr( range, 1 ) ) ); + } + + /*ptr init for ptr*/ + FOR( ; bp < bits; ) + { + IF( GT_32( high, ari_q2new ) ) + { + IF( GE_32( low, ari_q2new ) ) + { + value = (UWord32) W_sub( value, ari_q2new ); + low = L_sub( low, ari_q2new ); + high = L_sub( high, ari_q2new ); + } + ELSE + { + test(); + IF( GE_32( low, ari_q1new ) && LE_32( high, ari_q3new ) ) + { + value = (UWord32) W_sub( value, ari_q1new ); + low = L_sub( low, ari_q1new ); + high = L_sub( high, ari_q1new ); + } + ELSE + { + BREAK; + } + } + } + low = L_add( low, low ); + high = L_add( high, high ); + + assert( abs( ptr[bp] ) <= 1 && "AC expects reading binary values!!!" ); + + value = (UWord32) ( W_shl( value, 1 ) | ptr[bp++] ); + } + } + ELSE + { + cum = (UWord32) W_sub( value, low ); + range = (UWord32) W_shr( range, 1 ); + IF( GT_64( range, cum ) ) + { + symbol = 2; + move16(); + high = L_add( low, range ); + } + ELSE + { + symbol = 1; + move16(); + low = L_add( low, range ); + } + } + + s->low = low; + s->high = L_sub( high, 1 ); + s->value = value; + move32(); + move32(); + move32(); + + *res = symbol; + move16(); + + return bp; +} + diff --git a/lib_dec/arith_coder_dec.c b/lib_dec/arith_coder_dec.c deleted file mode 100644 index 93bd8877c..000000000 --- a/lib_dec/arith_coder_dec.c +++ /dev/null @@ -1,250 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "basop_util.h" -#include "basop_proto_func.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*-------------------------------------------------------* - * tcx_arith_decode() - * - * - *-------------------------------------------------------*/ - -/*! r: number of bits consumed */ - -static Word16 tcx_arith_decode_ivas_fx( - const Word16 L_frame, /* i : number of spectral lines */ - const Word16 envelope[], /* i : scaled envelope (Q15-envelope_e) */ - Word16 envelope_e, /* i : scaled envelope exponent (Q0) */ - const Word16 target_bits, /* i : target bit budget */ - Word16 prm[], /* i : bitstream parameters */ - Word32 q_spectrum[], /* o : scalar quantized spectrum (Q31-q_spectrum_e) */ - Word16 *q_spectrum_e /* o : spectrum exponent */ -) -{ - Word16 bp, k, q; - Word16 s; - Tastat as; - UWord16 exp_k; - Word16 tmp; - - bp = ari_start_decoding_14bits_prm_ivas_fx( prm, 0, &as ); - - tmp = sub( envelope_e, 1 ); - - FOR( k = 0; k < L_frame; k++ ) - { - IF( EQ_16( envelope[k], 0 ) ) /* safety check in case of bit errors */ - { - set32_fx( q_spectrum, 0, L_frame ); - return -1; - } - ELSE - { - exp_k = expfp_evs_fx( negate( envelope[k] ), tmp ); - } - - /* decode line magnitude */ - bp = ari_decode_14bits_pow_ivas( prm, bp, target_bits, &q, &as, exp_k ); - - IF( q ) - { - /* line is non-zero, decode sign */ - bp = ari_decode_14bits_sign_ivas( prm, bp, target_bits, &s, &as ); - q_spectrum[k] = L_mult( q, sub( 3, shl( s, 1 ) ) ); - move32(); - q_spectrum[k] = L_shl( q_spectrum[k], 30 - SPEC_EXP_DEC ); // Q(31-20) - move32(); - } - ELSE - { - /* line is zero, no sign needed */ - q_spectrum[k] = 0; - move32(); - } - - IF( LE_32( as.high, as.low ) ) - { - if ( LT_16( bp, target_bits ) ) /* safety check in case of bit errors */ - { - bp = -1; - move16(); - } - BREAK; /* no bits left, so exit loop */ - } - } - *q_spectrum_e = SPEC_EXP_DEC; - move16(); - - set32_fx( q_spectrum + k, 0, sub( L_frame, k ) ); - - return bp; -} - -/*-------------------------------------------------------* - * tcx_arith_decode_envelope() - * - * - *-------------------------------------------------------*/ - -void tcx_arith_decode_envelope_ivas_fx( - Decoder_State *st, /* i/o: coder state */ - Word32 q_spectrum[], /* o : quantised MDCT coefficients Q(31-q_spectrum_e) */ - Word16 *q_spectrum_e, /* o : MDCT exponent */ - const Word16 L_frame, /* i : frame or MDCT length */ - Word16 L_spec, /* i : length w/o BW limitation */ - const Word16 A_ind[], /* i : quantised LPC coefficients */ - const Word16 target_bits, /* i : number of available bits */ - Word16 prm[], /* i : bitstream parameters */ - const Word16 use_hm, /* i : use HM in current frame? */ - const Word16 prm_hm[], /* i : HM parameter area */ - Word16 tcxltp_pitch, /* i : TCX LTP pitch in FD, -1 if n/a*/ - Word16 *arith_bits, /* o : bits used for ari. coding */ - Word16 *signaling_bits, /* o : bits used for signaling */ - const Word16 low_complexity /* i : low-complexity flag */ -) -{ - Word32 env[N_MAX_ARI]; /* unscaled envelope (Q16) */ - Word16 *envelope; /* scaled envelope (Q15-e) */ - Word16 envelope_e; - Word16 L_spec_core; - TCX_CONFIG_HANDLE hTcxCfg; - TCX_DEC_HANDLE hTcxDec; - Word16 gamma_w, gamma_uw; - Word16 hm_bits; - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( GT_16( L_spec, N_MAX_ARI ) || ( ( st->element_mode == EVS_MONO ) && GT_16( target_bits, ( ACELP_13k20 / FRAMES_PER_SEC ) ) ) || - ( EQ_16( st->element_mode, IVAS_SCE ) && ( GT_16( st->bits_frame_nominal, ( LPC_SHAPED_ARI_MAX_RATE / FRAMES_PER_SEC ) ) ) ) || - ( GT_16( st->element_mode, IVAS_SCE ) && ( GT_16( st->bits_frame_nominal, ( LPC_SHAPED_ARI_MAX_RATE_CPE / FRAMES_PER_SEC ) ) ) ) || - ( target_bits <= 0 ) ) - { - /* this could happen in case of bit errors */ - st->BER_detect = 1; - move16(); - L_spec = N_MAX_ARI; - move16(); - *signaling_bits = 0; - move16(); - *arith_bits = 0; - move16(); - set32_fx( q_spectrum, 0, L_frame ); - - return; - } - - hTcxCfg = st->hTcxCfg; - hTcxDec = st->hTcxDec; - *signaling_bits = 0; - move16(); - - assert( hTcxDec->enableTcxLpc ); - gamma_w = MAX16B; - move16(); - gamma_uw = st->inv_gamma; - move16(); - -#define WMC_TOOL_SKIP - tcx_arith_render_envelope_ivas_fx( A_ind, L_frame, L_spec, hTcxCfg->preemph_fac, gamma_w, gamma_uw, env ); -#undef WMC_TOOL_SKIP - - IF( use_hm != 0 ) - { - IF( prm_hm[0] != 0 ) - { - tcx_hm_decode( L_spec, env, target_bits, st->coder_type, prm_hm, tcxltp_pitch, &hm_bits ); - - IF( hm_bits < 0 ) - { - st->BER_detect = 1; - move16(); - *signaling_bits = 0; - move16(); - *arith_bits = 0; - move16(); - set32_fx( q_spectrum, 0, L_frame ); - - return; - } - } - ELSE - { - hm_bits = 1; - move16(); - } - *signaling_bits = add( *signaling_bits, hm_bits ); - move16(); - } - - L_spec_core = L_spec; - move16(); - IF( st->igf ) - { - L_spec_core = s_min( L_spec_core, st->hIGFDec->infoIGFStartLine ); - } - - envelope = (Word16 *) env; - tcx_arith_scale_envelope( L_spec, L_spec_core, env, target_bits, low_complexity, envelope, &envelope_e ); - - *arith_bits = tcx_arith_decode_ivas_fx( L_spec, envelope, envelope_e, target_bits, prm, q_spectrum, q_spectrum_e ); - move16(); - - /* safety check in case of bit errors */ - IF( *arith_bits < 0 ) - { - st->BER_detect = 1; - move16(); - set32_fx( q_spectrum, 0, L_frame ); - } - - set32_fx( q_spectrum + L_spec, 0, sub( L_frame, L_spec ) ); - - return; -} diff --git a/lib_dec/arith_coder_dec_fx.c b/lib_dec/arith_coder_dec_fx.c index 4a18f64f9..6df1eb268 100644 --- a/lib_dec/arith_coder_dec_fx.c +++ b/lib_dec/arith_coder_dec_fx.c @@ -8,6 +8,9 @@ #include "cnst.h" #include "rom_com.h" #include "prot_fx.h" +#include "basop_util.h" +#include "basop_proto_func.h" +#include "prot.h" /* Returns: number of bits consumed */ static Word16 tcx_arith_decode_fx( @@ -213,3 +216,208 @@ void tcx_arith_decode_envelope_fx( set32_fx( q_spectrum + L_spec, 0, sub( L_frame, L_spec ) ); } + +/*-------------------------------------------------------* + * tcx_arith_decode() + * + * + *-------------------------------------------------------*/ + +/*! r: number of bits consumed */ + +static Word16 tcx_arith_decode_ivas_fx( + const Word16 L_frame, /* i : number of spectral lines */ + const Word16 envelope[], /* i : scaled envelope (Q15-envelope_e) */ + Word16 envelope_e, /* i : scaled envelope exponent (Q0) */ + const Word16 target_bits, /* i : target bit budget */ + Word16 prm[], /* i : bitstream parameters */ + Word32 q_spectrum[], /* o : scalar quantized spectrum (Q31-q_spectrum_e) */ + Word16 *q_spectrum_e /* o : spectrum exponent */ +) +{ + Word16 bp, k, q; + Word16 s; + Tastat as; + UWord16 exp_k; + Word16 tmp; + + bp = ari_start_decoding_14bits_prm_ivas_fx( prm, 0, &as ); + + tmp = sub( envelope_e, 1 ); + + FOR( k = 0; k < L_frame; k++ ) + { + IF( EQ_16( envelope[k], 0 ) ) /* safety check in case of bit errors */ + { + set32_fx( q_spectrum, 0, L_frame ); + return -1; + } + ELSE + { + exp_k = expfp_evs_fx( negate( envelope[k] ), tmp ); + } + + /* decode line magnitude */ + bp = ari_decode_14bits_pow_ivas( prm, bp, target_bits, &q, &as, exp_k ); + + IF( q ) + { + /* line is non-zero, decode sign */ + bp = ari_decode_14bits_sign_ivas( prm, bp, target_bits, &s, &as ); + q_spectrum[k] = L_mult( q, sub( 3, shl( s, 1 ) ) ); + move32(); + q_spectrum[k] = L_shl( q_spectrum[k], 30 - SPEC_EXP_DEC ); // Q(31-20) + move32(); + } + ELSE + { + /* line is zero, no sign needed */ + q_spectrum[k] = 0; + move32(); + } + + IF( LE_32( as.high, as.low ) ) + { + if ( LT_16( bp, target_bits ) ) /* safety check in case of bit errors */ + { + bp = -1; + move16(); + } + BREAK; /* no bits left, so exit loop */ + } + } + *q_spectrum_e = SPEC_EXP_DEC; + move16(); + + set32_fx( q_spectrum + k, 0, sub( L_frame, k ) ); + + return bp; +} + +/*-------------------------------------------------------* + * tcx_arith_decode_envelope() + * + * + *-------------------------------------------------------*/ + +void tcx_arith_decode_envelope_ivas_fx( + Decoder_State *st, /* i/o: coder state */ + Word32 q_spectrum[], /* o : quantised MDCT coefficients Q(31-q_spectrum_e) */ + Word16 *q_spectrum_e, /* o : MDCT exponent */ + const Word16 L_frame, /* i : frame or MDCT length */ + Word16 L_spec, /* i : length w/o BW limitation */ + const Word16 A_ind[], /* i : quantised LPC coefficients */ + const Word16 target_bits, /* i : number of available bits */ + Word16 prm[], /* i : bitstream parameters */ + const Word16 use_hm, /* i : use HM in current frame? */ + const Word16 prm_hm[], /* i : HM parameter area */ + Word16 tcxltp_pitch, /* i : TCX LTP pitch in FD, -1 if n/a*/ + Word16 *arith_bits, /* o : bits used for ari. coding */ + Word16 *signaling_bits, /* o : bits used for signaling */ + const Word16 low_complexity /* i : low-complexity flag */ +) +{ + Word32 env[N_MAX_ARI]; /* unscaled envelope (Q16) */ + Word16 *envelope; /* scaled envelope (Q15-e) */ + Word16 envelope_e; + Word16 L_spec_core; + TCX_CONFIG_HANDLE hTcxCfg; + TCX_DEC_HANDLE hTcxDec; + Word16 gamma_w, gamma_uw; + Word16 hm_bits; + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( GT_16( L_spec, N_MAX_ARI ) || ( ( st->element_mode == EVS_MONO ) && GT_16( target_bits, ( ACELP_13k20 / FRAMES_PER_SEC ) ) ) || + ( EQ_16( st->element_mode, IVAS_SCE ) && ( GT_16( st->bits_frame_nominal, ( LPC_SHAPED_ARI_MAX_RATE / FRAMES_PER_SEC ) ) ) ) || + ( GT_16( st->element_mode, IVAS_SCE ) && ( GT_16( st->bits_frame_nominal, ( LPC_SHAPED_ARI_MAX_RATE_CPE / FRAMES_PER_SEC ) ) ) ) || + ( target_bits <= 0 ) ) + { + /* this could happen in case of bit errors */ + st->BER_detect = 1; + move16(); + L_spec = N_MAX_ARI; + move16(); + *signaling_bits = 0; + move16(); + *arith_bits = 0; + move16(); + set32_fx( q_spectrum, 0, L_frame ); + + return; + } + + hTcxCfg = st->hTcxCfg; + hTcxDec = st->hTcxDec; + *signaling_bits = 0; + move16(); + + assert( hTcxDec->enableTcxLpc ); + gamma_w = MAX16B; + move16(); + gamma_uw = st->inv_gamma; + move16(); + +#define WMC_TOOL_SKIP + tcx_arith_render_envelope_ivas_fx( A_ind, L_frame, L_spec, hTcxCfg->preemph_fac, gamma_w, gamma_uw, env ); +#undef WMC_TOOL_SKIP + + IF( use_hm != 0 ) + { + IF( prm_hm[0] != 0 ) + { + tcx_hm_decode( L_spec, env, target_bits, st->coder_type, prm_hm, tcxltp_pitch, &hm_bits ); + + IF( hm_bits < 0 ) + { + st->BER_detect = 1; + move16(); + *signaling_bits = 0; + move16(); + *arith_bits = 0; + move16(); + set32_fx( q_spectrum, 0, L_frame ); + + return; + } + } + ELSE + { + hm_bits = 1; + move16(); + } + *signaling_bits = add( *signaling_bits, hm_bits ); + move16(); + } + + L_spec_core = L_spec; + move16(); + IF( st->igf ) + { + L_spec_core = s_min( L_spec_core, st->hIGFDec->infoIGFStartLine ); + } + + envelope = (Word16 *) env; + tcx_arith_scale_envelope( L_spec, L_spec_core, env, target_bits, low_complexity, envelope, &envelope_e ); + + *arith_bits = tcx_arith_decode_ivas_fx( L_spec, envelope, envelope_e, target_bits, prm, q_spectrum, q_spectrum_e ); + move16(); + + /* safety check in case of bit errors */ + IF( *arith_bits < 0 ) + { + st->BER_detect = 1; + move16(); + set32_fx( q_spectrum, 0, L_frame ); + } + + set32_fx( q_spectrum + L_spec, 0, sub( L_frame, L_spec ) ); + + return; +} + diff --git a/lib_dec/bass_psfilter.c b/lib_dec/bass_psfilter.c deleted file mode 100644 index 478a81474..000000000 --- a/lib_dec/bass_psfilter.c +++ /dev/null @@ -1,317 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "prot.h" -#include "prot_fx.h" -#include "ivas_prot.h" -#include "cnst.h" -#include "stat_dec.h" -#include "rom_com.h" -#include -#include "wmc_auto.h" -#include "ivas_prot_fx.h" - -/*---------------------------------------------------------------------* - * Local constants - *---------------------------------------------------------------------*/ - - -#define NBPSF_L_EXTRA 120 -#define BPF_STOP_STOPBAND_16 16 -#define K_PC_DEC_FX -1170 /* -0.0357f in Q15 */ -#define K_PC_DEC_FX32 -76665166 /* -0.0357f in Q31 */ -#define C_PC_DEC_FX 6583 /*in Q8*/ - -/*---------------------------------------------------------------------* - * Local function prototypes - *---------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------* - * bass_psfilter() - * - * Perform low-frequency postfiltering - *---------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------* - * Pit_track() - * - * Perform pitch tracking and test pitch/2 to avoid continuous pitch doubling - *---------------------------------------------------------------------*/ - -/*! r: Pitch */ - - -/*---------------------------------------------------------------------* - * addBassPostFilter() - * - * Add BPF component in cldfb domain - *---------------------------------------------------------------------*/ - - -void addBassPostFilter_ivas_fx( - const Word32 *harm_timeIn_fx, // Qx - const Word16 samplesToProcess, - Word32 **rAnalysis_fx, // Qx - 5 - Word32 **iAnalysis_fx, // Qx - 5 - HANDLE_CLDFB_FILTER_BANK cldfb ) -{ - Word32 *tmp_R_fx[CLDFB_NO_COL_MAX]; - Word32 *tmp_I_fx[CLDFB_NO_COL_MAX]; - Word32 cldfbBufferReal_fx[CLDFB_NO_COL_MAX][20]; - Word32 cldfbBufferImag_fx[CLDFB_NO_COL_MAX][20]; - Word16 i, b; - Word16 maxBand; - const Word32 *weights_fx; - Word16 nCol = cldfb->no_col; - move16(); - Word16 nColToProcess = nCol; - move16(); - Word16 nChan = cldfb->no_channels; - move16(); - IF( GT_16( samplesToProcess, -1 ) ) - { - nColToProcess = idiv1616( sub( add( samplesToProcess, cldfb->no_channels ), 1 ), cldfb->no_channels ); - move16(); - } - - assert( nCol == 16 ); - - weights_fx = bpf_weights_16_ivas_fx_32; - - IF( GT_16( nChan, BPF_STOP_STOPBAND_16 ) ) - { - maxBand = BPF_STOP_STOPBAND_16; - move16(); - } - ELSE - { - maxBand = nChan; - move16(); - } - - FOR( i = 0; i < nColToProcess; i++ ) - { - tmp_R_fx[i] = cldfbBufferReal_fx[i]; - tmp_I_fx[i] = cldfbBufferImag_fx[i]; - } - - cldfbAnalysis_ivas_fx( harm_timeIn_fx, tmp_R_fx, tmp_I_fx, samplesToProcess, cldfb ); - - /* now do the subtraction */ - FOR( i = 0; i < nColToProcess; i++ ) - { - /* loop over low frequency bands */ - FOR( b = 0; b < maxBand; b++ ) - { - rAnalysis_fx[i][b] = Msub_32_32( rAnalysis_fx[i][b], tmp_R_fx[i][b], weights_fx[b] ); // Qx - 6 - move32(); - iAnalysis_fx[i][b] = Msub_32_32( iAnalysis_fx[i][b], tmp_I_fx[i][b], weights_fx[b] ); // Qx - 6 - move32(); - } - } - - return; -} - - -/*---------------------------------------------------------------------* - * res_bpf_adapt_ivas_fx() - * - * Analyze BPF output and decide if it should be applied on DFT stereo - * residual signal - *---------------------------------------------------------------------*/ - -/*! r: Decision to enable or disable BPF on DFT stereo residual */ -Word16 res_bpf_adapt_ivas_fx( - STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo decoder handle */ - const Word32 *bpf_error_signal_8k, /* i : BPF modification signal */ - Word32 res_buf[STEREO_DFT_N_8k], /* i : residual buffer Q12 */ - Word16 q_res ) -{ - Word32 error_nrg; - Word32 tmp; - Word32 res_hb_nrg; - Word16 bpf_error_ratio; - Word16 res_bpf_flag; - Word16 i; - Word16 i_start; - Word16 i_end; - Word16 bw_inv; - Word64 W_tmp; - - IF( EQ_16( hStereoDft->res_cod_band_max, 6 ) ) - { - i_start = 39; - move16(); - i_end = 64; - move16(); - bw_inv = 1311; - move16(); /* 1/(64 - 39) in Q15 */ - } - ELSE - { - i_start = 28; - move16(); - i_end = 40; - move16(); - bw_inv = 2720; - move16(); /* 1/(40 - 28) in Q15*/ - } - - /* Measure energy of high frequency band in MDCT domain */ - res_hb_nrg = L_deposit_l( 0 ); - W_tmp = W_deposit32_l( 0 ); - FOR( i = i_start; i < i_end; i++ ) - { - W_tmp = W_add_nosat( W_tmp, W_mult0_32_32( res_buf[i], res_buf[i] ) ); - } - - res_hb_nrg = W_extract_l( W_shr( W_tmp, shl( q_res, 1 ) ) ); // Q0 - res_hb_nrg = Mpy_32_16_1( res_hb_nrg, bw_inv ); // Q0 - res_hb_nrg = L_add( Mpy_32_16_1( res_hb_nrg, STEREO_DFT_BPF_ADAPT_ALPHA_FX ), Mpy_32_16_1( hStereoDft->res_hb_nrg_mem_fx, sub( MAX_16, STEREO_DFT_BPF_ADAPT_ALPHA_FX ) ) ); - hStereoDft->res_hb_nrg_mem_fx = res_hb_nrg; - move32(); - - /* Measure energy of discontinuities at subframe boundaries */ - error_nrg = 0; - move32(); - FOR( i = 0; i < L_FRAME8k; i += STEREO_DFT_L_SUBFR_8k ) - { - tmp = L_sub( bpf_error_signal_8k[i], hStereoDft->bpf_error_signal_last_fx ); - error_nrg = Madd_32_32( error_nrg, tmp, tmp ); - hStereoDft->bpf_error_signal_last_fx = bpf_error_signal_8k[( i + ( STEREO_DFT_L_SUBFR_8k - 1 ) )]; - move32(); - } - error_nrg = L_shl( error_nrg, 1 ); // Q0 - error_nrg = Mpy_32_16_1( error_nrg, 6553 /* 0.2f in Q15 */ ); /* Division by 5 for average value */ - /* Form decision variable and apply limit */ - IF( LT_32( ( L_shr( error_nrg, 1 ) ), res_hb_nrg ) ) - { - Word16 temp; - bpf_error_ratio = BASOP_Util_Divide3232_Scale( error_nrg, res_hb_nrg, &temp ); - bpf_error_ratio = shl( bpf_error_ratio, sub( 13, sub( 15, temp ) ) ); - } - ELSE - { - bpf_error_ratio = ONE_IN_Q14; // Q13 - move16(); - } - bpf_error_ratio = add( mult( STEREO_DFT_BPF_ADAPT_BETA_FX, bpf_error_ratio ), mult( ( MAX_16 - STEREO_DFT_BPF_ADAPT_BETA_FX ), hStereoDft->bpf_error_ratio_mem_fx ) ); - hStereoDft->bpf_error_ratio_mem_fx = bpf_error_ratio; - move16(); - - res_bpf_flag = (Word16) LT_16( bpf_error_ratio, ONE_IN_Q13 ); - move16(); - - return res_bpf_flag; -} - -void bpf_pitch_coherence_ivas_fx( - Decoder_State *st, /* i/o: decoder state structure */ - const Word32 pitch_buf[] /* i : pitch for every subfr [0,1,2,3] Q20 */ -) -{ - Word16 nb_subfr; - Word32 pc, pcn1, pcn2, pcn3; - Word32 scaled_inv_L_frame; // Q8 + Q23 - - SWITCH( st->L_frame ) - { - case 80: - scaled_inv_L_frame = 26843545; // 1/80 in Q31 - move32(); - BREAK; - case 160: - scaled_inv_L_frame = 13421773; // 1/160 in Q31 - move32(); - BREAK; - case 256: - scaled_inv_L_frame = 8388608; // 1/256 in Q31 - move32(); - BREAK; - case 320: - scaled_inv_L_frame = 6710886; // 1/320 in Q31 - move32(); - BREAK; - case 512: - scaled_inv_L_frame = 4194304; // 1/512 in Q31 - move32(); - BREAK; - case 640: - scaled_inv_L_frame = 3355443; // 1/640 in Q31 - move32(); - BREAK; - case 960: - scaled_inv_L_frame = 2236962; // 1/80 in Q31 - move32(); - BREAK; - default: - scaled_inv_L_frame = 0; - move32(); - } - - nb_subfr = shr( st->L_frame, 6 ); - test(); - IF( GT_16( st->clas_dec, UNVOICED_CLAS ) && ( st->element_mode != EVS_MONO ) ) - { - pc = L_abs( L_sub( L_add( st->old_pitch_buf_fx[nb_subfr + 3], st->old_pitch_buf_fx[nb_subfr + 2] ), L_add( st->old_pitch_buf_fx[nb_subfr], st->old_pitch_buf_fx[nb_subfr + 1] ) ) ); - pc = Mpy_32_32( pc, scaled_inv_L_frame ); - pcn1 = L_add( Mpy_32_32( pc, K_PC_DEC_FX32 ), C_PC_DEC_FX ); - pcn1 = L_max( L_min( pcn1, 4096 ), 0 ); // 4096 = 1 in Q12 - - pc = L_abs( L_sub( L_add( pitch_buf[nb_subfr - 1], pitch_buf[nb_subfr - 2] ), L_add( pitch_buf[1], pitch_buf[0] ) ) ); - pc = Mpy_32_32( pc, scaled_inv_L_frame ); - pcn2 = L_add( Mpy_32_32( pc, K_PC_DEC_FX32 ), C_PC_DEC_FX ); - pcn2 = L_max( L_min( pcn2, 4096 ), 0 ); // 4096 = 1 in Q12 - - pc = L_abs( L_sub( L_add( st->old_pitch_buf_fx[nb_subfr + 3], st->old_pitch_buf_fx[nb_subfr + 2] ), L_add( pitch_buf[1], pitch_buf[0] ) ) ); - pc = Mpy_32_32( pc, scaled_inv_L_frame ); - pcn3 = L_add( Mpy_32_32( pc, K_PC_DEC_FX32 ), C_PC_DEC_FX ); - pcn3 = L_max( L_min( pcn3, 4096 ), 0 ); // 4096 = 1 in Q12 - - IF( LT_32( L_add( pcn1, L_add( pcn2, pcn3 ) ), 10240 /*2.5f in Q12*/ ) ) - { - st->hBPF->psf_att_fx = 13107; //.4 in Q15 - move16(); /*Q15*/ - set16_fx( &st->hBPF->Track_on_hist[L_TRACK_HIST - nb_subfr], 1, nb_subfr ); - } - } - - return; -} diff --git a/lib_dec/bass_psfilter_fx.c b/lib_dec/bass_psfilter_fx.c index c11e30c93..7d2be2c52 100644 --- a/lib_dec/bass_psfilter_fx.c +++ b/lib_dec/bass_psfilter_fx.c @@ -6,6 +6,7 @@ #include #include "options.h" /* Compilation switches */ #include "prot_fx.h" /* Function prototypes */ +#include "ivas_prot_fx.h" /* Function prototypes */ #include "cnst.h" /* Common constants */ #include "rom_com.h" /* Static table prototypes */ #include "rom_dec.h" /* Static table prototypes */ @@ -17,6 +18,9 @@ #define NBPSF_L_EXTRA 120 #define BPF_STOP_STOPBAND_16 16 +#define K_PC_DEC_FX -1170 /* -0.0357f in Q15 */ +#define K_PC_DEC_FX32 -76665166 /* -0.0357f in Q31 */ +#define C_PC_DEC_FX 6583 /*in Q8*/ /*---------------------------------------------------------------------* * Local function prototypes @@ -889,6 +893,246 @@ void addBassPostFilter_fx( return; } +/*---------------------------------------------------------------------* + * addBassPostFilter() + * + * Add BPF component in cldfb domain + *---------------------------------------------------------------------*/ + + +void addBassPostFilter_ivas_fx( + const Word32 *harm_timeIn_fx, // Qx + const Word16 samplesToProcess, + Word32 **rAnalysis_fx, // Qx - 5 + Word32 **iAnalysis_fx, // Qx - 5 + HANDLE_CLDFB_FILTER_BANK cldfb ) +{ + Word32 *tmp_R_fx[CLDFB_NO_COL_MAX]; + Word32 *tmp_I_fx[CLDFB_NO_COL_MAX]; + Word32 cldfbBufferReal_fx[CLDFB_NO_COL_MAX][20]; + Word32 cldfbBufferImag_fx[CLDFB_NO_COL_MAX][20]; + Word16 i, b; + Word16 maxBand; + const Word32 *weights_fx; + Word16 nCol = cldfb->no_col; + move16(); + Word16 nColToProcess = nCol; + move16(); + Word16 nChan = cldfb->no_channels; + move16(); + IF( GT_16( samplesToProcess, -1 ) ) + { + nColToProcess = idiv1616( sub( add( samplesToProcess, cldfb->no_channels ), 1 ), cldfb->no_channels ); + move16(); + } + + assert( nCol == 16 ); + + weights_fx = bpf_weights_16_ivas_fx_32; + + IF( GT_16( nChan, BPF_STOP_STOPBAND_16 ) ) + { + maxBand = BPF_STOP_STOPBAND_16; + move16(); + } + ELSE + { + maxBand = nChan; + move16(); + } + + FOR( i = 0; i < nColToProcess; i++ ) + { + tmp_R_fx[i] = cldfbBufferReal_fx[i]; + tmp_I_fx[i] = cldfbBufferImag_fx[i]; + } + + cldfbAnalysis_ivas_fx( harm_timeIn_fx, tmp_R_fx, tmp_I_fx, samplesToProcess, cldfb ); + + /* now do the subtraction */ + FOR( i = 0; i < nColToProcess; i++ ) + { + /* loop over low frequency bands */ + FOR( b = 0; b < maxBand; b++ ) + { + rAnalysis_fx[i][b] = Msub_32_32( rAnalysis_fx[i][b], tmp_R_fx[i][b], weights_fx[b] ); // Qx - 6 + move32(); + iAnalysis_fx[i][b] = Msub_32_32( iAnalysis_fx[i][b], tmp_I_fx[i][b], weights_fx[b] ); // Qx - 6 + move32(); + } + } + + return; +} + + +/*---------------------------------------------------------------------* + * res_bpf_adapt_ivas_fx() + * + * Analyze BPF output and decide if it should be applied on DFT stereo + * residual signal + *---------------------------------------------------------------------*/ + +/*! r: Decision to enable or disable BPF on DFT stereo residual */ +Word16 res_bpf_adapt_ivas_fx( + STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo decoder handle */ + const Word32 *bpf_error_signal_8k, /* i : BPF modification signal */ + Word32 res_buf[STEREO_DFT_N_8k], /* i : residual buffer Q12 */ + Word16 q_res ) +{ + Word32 error_nrg; + Word32 tmp; + Word32 res_hb_nrg; + Word16 bpf_error_ratio; + Word16 res_bpf_flag; + Word16 i; + Word16 i_start; + Word16 i_end; + Word16 bw_inv; + Word64 W_tmp; + + IF( EQ_16( hStereoDft->res_cod_band_max, 6 ) ) + { + i_start = 39; + move16(); + i_end = 64; + move16(); + bw_inv = 1311; + move16(); /* 1/(64 - 39) in Q15 */ + } + ELSE + { + i_start = 28; + move16(); + i_end = 40; + move16(); + bw_inv = 2720; + move16(); /* 1/(40 - 28) in Q15*/ + } + + /* Measure energy of high frequency band in MDCT domain */ + res_hb_nrg = L_deposit_l( 0 ); + W_tmp = W_deposit32_l( 0 ); + FOR( i = i_start; i < i_end; i++ ) + { + W_tmp = W_add_nosat( W_tmp, W_mult0_32_32( res_buf[i], res_buf[i] ) ); + } + + res_hb_nrg = W_extract_l( W_shr( W_tmp, shl( q_res, 1 ) ) ); // Q0 + res_hb_nrg = Mpy_32_16_1( res_hb_nrg, bw_inv ); // Q0 + res_hb_nrg = L_add( Mpy_32_16_1( res_hb_nrg, STEREO_DFT_BPF_ADAPT_ALPHA_FX ), Mpy_32_16_1( hStereoDft->res_hb_nrg_mem_fx, sub( MAX_16, STEREO_DFT_BPF_ADAPT_ALPHA_FX ) ) ); + hStereoDft->res_hb_nrg_mem_fx = res_hb_nrg; + move32(); + + /* Measure energy of discontinuities at subframe boundaries */ + error_nrg = 0; + move32(); + FOR( i = 0; i < L_FRAME8k; i += STEREO_DFT_L_SUBFR_8k ) + { + tmp = L_sub( bpf_error_signal_8k[i], hStereoDft->bpf_error_signal_last_fx ); + error_nrg = Madd_32_32( error_nrg, tmp, tmp ); + hStereoDft->bpf_error_signal_last_fx = bpf_error_signal_8k[( i + ( STEREO_DFT_L_SUBFR_8k - 1 ) )]; + move32(); + } + error_nrg = L_shl( error_nrg, 1 ); // Q0 + error_nrg = Mpy_32_16_1( error_nrg, 6553 /* 0.2f in Q15 */ ); /* Division by 5 for average value */ + /* Form decision variable and apply limit */ + IF( LT_32( ( L_shr( error_nrg, 1 ) ), res_hb_nrg ) ) + { + Word16 temp; + bpf_error_ratio = BASOP_Util_Divide3232_Scale( error_nrg, res_hb_nrg, &temp ); + bpf_error_ratio = shl( bpf_error_ratio, sub( 13, sub( 15, temp ) ) ); + } + ELSE + { + bpf_error_ratio = ONE_IN_Q14; // Q13 + move16(); + } + bpf_error_ratio = add( mult( STEREO_DFT_BPF_ADAPT_BETA_FX, bpf_error_ratio ), mult( ( MAX_16 - STEREO_DFT_BPF_ADAPT_BETA_FX ), hStereoDft->bpf_error_ratio_mem_fx ) ); + hStereoDft->bpf_error_ratio_mem_fx = bpf_error_ratio; + move16(); + + res_bpf_flag = (Word16) LT_16( bpf_error_ratio, ONE_IN_Q13 ); + move16(); + + return res_bpf_flag; +} + +void bpf_pitch_coherence_ivas_fx( + Decoder_State *st, /* i/o: decoder state structure */ + const Word32 pitch_buf[] /* i : pitch for every subfr [0,1,2,3] Q20 */ +) +{ + Word16 nb_subfr; + Word32 pc, pcn1, pcn2, pcn3; + Word32 scaled_inv_L_frame; // Q8 + Q23 + + SWITCH( st->L_frame ) + { + case 80: + scaled_inv_L_frame = 26843545; // 1/80 in Q31 + move32(); + BREAK; + case 160: + scaled_inv_L_frame = 13421773; // 1/160 in Q31 + move32(); + BREAK; + case 256: + scaled_inv_L_frame = 8388608; // 1/256 in Q31 + move32(); + BREAK; + case 320: + scaled_inv_L_frame = 6710886; // 1/320 in Q31 + move32(); + BREAK; + case 512: + scaled_inv_L_frame = 4194304; // 1/512 in Q31 + move32(); + BREAK; + case 640: + scaled_inv_L_frame = 3355443; // 1/640 in Q31 + move32(); + BREAK; + case 960: + scaled_inv_L_frame = 2236962; // 1/80 in Q31 + move32(); + BREAK; + default: + scaled_inv_L_frame = 0; + move32(); + } + + nb_subfr = shr( st->L_frame, 6 ); + test(); + IF( GT_16( st->clas_dec, UNVOICED_CLAS ) && ( st->element_mode != EVS_MONO ) ) + { + pc = L_abs( L_sub( L_add( st->old_pitch_buf_fx[nb_subfr + 3], st->old_pitch_buf_fx[nb_subfr + 2] ), L_add( st->old_pitch_buf_fx[nb_subfr], st->old_pitch_buf_fx[nb_subfr + 1] ) ) ); + pc = Mpy_32_32( pc, scaled_inv_L_frame ); + pcn1 = L_add( Mpy_32_32( pc, K_PC_DEC_FX32 ), C_PC_DEC_FX ); + pcn1 = L_max( L_min( pcn1, 4096 ), 0 ); // 4096 = 1 in Q12 + + pc = L_abs( L_sub( L_add( pitch_buf[nb_subfr - 1], pitch_buf[nb_subfr - 2] ), L_add( pitch_buf[1], pitch_buf[0] ) ) ); + pc = Mpy_32_32( pc, scaled_inv_L_frame ); + pcn2 = L_add( Mpy_32_32( pc, K_PC_DEC_FX32 ), C_PC_DEC_FX ); + pcn2 = L_max( L_min( pcn2, 4096 ), 0 ); // 4096 = 1 in Q12 + + pc = L_abs( L_sub( L_add( st->old_pitch_buf_fx[nb_subfr + 3], st->old_pitch_buf_fx[nb_subfr + 2] ), L_add( pitch_buf[1], pitch_buf[0] ) ) ); + pc = Mpy_32_32( pc, scaled_inv_L_frame ); + pcn3 = L_add( Mpy_32_32( pc, K_PC_DEC_FX32 ), C_PC_DEC_FX ); + pcn3 = L_max( L_min( pcn3, 4096 ), 0 ); // 4096 = 1 in Q12 + + IF( LT_32( L_add( pcn1, L_add( pcn2, pcn3 ) ), 10240 /*2.5f in Q12*/ ) ) + { + st->hBPF->psf_att_fx = 13107; //.4 in Q15 + move16(); /*Q15*/ + set16_fx( &st->hBPF->Track_on_hist[L_TRACK_HIST - nb_subfr], 1, nb_subfr ); + } + } + + return; +} + + #ifdef ADD_BPF_ADAPT /*---------------------------------------------------------------------* * res_bpf_adapt() diff --git a/lib_dec/core_dec_init.c b/lib_dec/core_dec_init.c deleted file mode 100644 index 37c397bbf..000000000 --- a/lib_dec/core_dec_init.c +++ /dev/null @@ -1,84 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "stat_com.h" -#include "cnst.h" -#include "prot.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include "prot_fx.h" -/*-----------------------------------------------------------------------* - * open_decoder_LPD() - * - * Initialization of state variables - *-----------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------* - * tcxltp_dec_init() - * - * Initialization TCX-LTP handle - *-----------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------* - * reset_tcx_overl_buf() - * - * Reset TCX core overlap buffers - *-----------------------------------------------------------------------*/ - -void reset_tcx_overl_buf_fx( - TCX_DEC_HANDLE hTcxDec /* i/o: TCX decoder handle */ -) -{ - set16_fx( hTcxDec->old_syn_Overl, 0, L_FRAME32k / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ - hTcxDec->Q_old_syn_Overl = 0; - move16(); - set16_fx( hTcxDec->syn_Overl_TDAC, 0, L_FRAME32k / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ - hTcxDec->Q_syn_Overl_TDAC = 0; - move16(); - set16_fx( hTcxDec->syn_Overl, 0, L_FRAME32k / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ - hTcxDec->Q_syn_Overl = 0; - move16(); - set16_fx( hTcxDec->syn_Overl_TDACFB, 0, L_FRAME_MAX / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ - hTcxDec->Q_syn_Overl_TDACFB = 0; - move16(); - return; -} - -/*-----------------------------------------------------------------------* - * acelp_plc_mdct_transition() - * - * Prepare MDCT OLA memories in TCX/HQ after ACELP PLC - *-----------------------------------------------------------------------*/ diff --git a/lib_dec/core_dec_init_fx.c b/lib_dec/core_dec_init_fx.c index 671dbfd2c..f649772b2 100644 --- a/lib_dec/core_dec_init_fx.c +++ b/lib_dec/core_dec_init_fx.c @@ -2191,3 +2191,29 @@ void open_decoder_LPD_ivas_fx( return; } + +/*-----------------------------------------------------------------------* + * reset_tcx_overl_buf() + * + * Reset TCX core overlap buffers + *-----------------------------------------------------------------------*/ + +void reset_tcx_overl_buf_fx( + TCX_DEC_HANDLE hTcxDec /* i/o: TCX decoder handle */ +) +{ + set16_fx( hTcxDec->old_syn_Overl, 0, L_FRAME32k / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ + hTcxDec->Q_old_syn_Overl = 0; + move16(); + set16_fx( hTcxDec->syn_Overl_TDAC, 0, L_FRAME32k / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ + hTcxDec->Q_syn_Overl_TDAC = 0; + move16(); + set16_fx( hTcxDec->syn_Overl, 0, L_FRAME32k / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ + hTcxDec->Q_syn_Overl = 0; + move16(); + set16_fx( hTcxDec->syn_Overl_TDACFB, 0, L_FRAME_MAX / 2 ); /*HQ-CORE(bfi)->TCX don't need it*/ + hTcxDec->Q_syn_Overl_TDACFB = 0; + move16(); + return; +} + diff --git a/lib_dec/core_switching_dec.c b/lib_dec/core_switching_dec.c deleted file mode 100644 index aa04a70cb..000000000 --- a/lib_dec/core_switching_dec.c +++ /dev/null @@ -1,1076 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "prot_fx.h" -#include "ivas_cnst.h" -#include "wmc_auto.h" - -#include "ivas_prot_fx.h" -#include "debug.h" -/*---------------------------------------------------------------------* - * Local prototypes - *---------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------* - * core_switching_pre_dec() - * - * Preprocessing/preparation for ACELP/HQ core switching - *---------------------------------------------------------------------*/ -ivas_error core_switching_pre_dec_ivas_fx( - Decoder_State *st, /* i/o: decoder state structure */ - const Word16 output_frame, /* i : frame length */ - const Word32 last_core_brate_st0, /* i : channel 0 last core bitrate */ - const Word16 nchan_out, /* i : number of output channels */ - const Word16 last_element_mode, /* i : last_element_mode */ - const Word32 last_element_brate, /* i : last element bitrate */ - Word16 Q_old_synthFB, - Word16 *Q_olapBufferSynth, - Word16 *Q_olapBufferSynth2 ) -{ - Word32 tmp_fx; /*Q-12*/ - Word16 i, oldLenClasBuff, newLenClasBuff; - ivas_error error; - Word16 exp = 25; - move16(); - error = IVAS_ERR_OK; - move32(); - - /* Codec mode switching */ - test(); - test(); - test(); - IF( EQ_16( st->last_codec_mode, MODE2 ) || ( ( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) && ( st->element_mode > EVS_MONO ) ) ) - { - st->mem_deemph_fx = st->syn[M]; - move16(); - set16_fx( st->agc_mem_fx, 0, 2 ); - Scale_sig( &( st->mem_deemph_fx ), 1, st->Q_syn ); /* Brings mem_deemph to Qsyn */ - - Copy_Scale_sig( st->mem_syn2_fx, st->mem_syn1_fx, M, sub( -1, st->Q_syn ) ); /*Q-1*/ - - st->bpf_off = 1; - move16(); - IF( st->hPFstat != NULL ) - { - Scale_sig( st->hPFstat->mem_pf_in, L_SUBFR, st->Q_syn ); /* Post_filter mem ,Q_syn*/ - Scale_sig( st->hPFstat->mem_res2, DECMEM_RES2, st->Q_syn ); /* NB post_filter mem , Q_syn*/ - Scale_sig( st->hPFstat->mem_stp, L_SUBFR, st->Q_syn ); /* Post_filter mem ,Q_syn*/ - set16_fx( st->hBPF->pst_old_syn_fx, 0, NBPSF_PIT_MAX ); /* BPF mem*/ - } - IF( st->hBPF != NULL ) - { - st->hBPF->pst_lp_ener_fx = round_fx( L_shl( Mpy_32_16_1( st->lp_error_ener, 0x6054 ), 2 + 8 ) ); /* convert from 15Q16, log2 -> 7Q8 10*log10 */ - st->hBPF->pst_mem_deemp_err_fx = 0; - move16(); - move16(); - } - st->psf_lp_noise_fx = round_fx( L_shl( st->lp_noise, 1 ) ); // Q(23+1-16)->Q8 - move16(); - - /* reset old HB synthesis buffer */ - IF( EQ_16( st->last_L_frame, L_FRAME ) ) - { - st->old_bwe_delay = NS2SA_FX2( st->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_12k8_NS ); - } - ELSE - { - st->old_bwe_delay = NS2SA_FX2( st->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_16k_NS ); - } - move16(); - set16_fx( st->hb_prev_synth_buffer_fx, 0, NS2SA( 48000, DELAY_BWE_TOTAL_NS ) ); - - test(); - IF( st->hBWE_TD != NULL && ( st->last_core != ACELP_CORE ) ) - { -#ifdef MSAN_FIX - st->hBWE_TD->prev_hb_synth_fx_exp = 31; - move16(); -#endif // MSAN_FIX - /* reset BWE memories */ - set16_fx( st->hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); - st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; - move32(); - } - - /* reset upd_cnt */ - st->upd_cnt = MAX_UPD_CNT; - move16(); - - st->igf = 0; - move16(); - - test(); - IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) - { - hf_synth_reset_fx( st->hBWE_zero ); -#ifdef MSAN_FIX - set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); -#endif - } - - IF( st->hBWE_FD != NULL ) - { - set16_fx( st->hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); - } - - IF( st->hHQ_core != NULL ) - { - set32_fx( st->hHQ_core->prev_env_fx, 0, SFM_N_WB ); - set32_fx( st->hHQ_core->prev_normq_fx, 0, SFM_N_WB ); - - set32_fx( st->hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); - set16_fx( st->hHQ_core->last_env_fx, 0, BANDS_MAX ); - - st->hHQ_core->last_max_pos_pulse = 0; - move16(); - - IF( GT_32( st->output_Fs, 16000 ) ) - { - set32_fx( st->hHQ_core->prev_coeff_out_fx, 0, L_HQ_WB_BWE ); - } - - /* pre-echo */ - st->hHQ_core->pastpre = 0; - move16(); - } - - /* reset the GSC pre echo energy threshold in case of switching */ - if ( st->hGSCDec != NULL ) - { - st->hGSCDec->Last_frame_ener_fx = MAX_32; - move32(); - } - - test(); - IF( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) - { - IF( st->element_mode == EVS_MONO ) - { - st->last_core = HQ_CORE; - move16(); - - Copy32( st->hTcxDec->FBTCXdelayBuf_32, st->prev_synth_buffer32_fx, NS2SA_FX2( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); - // Copy_Scale_sig_32_16( st->hTcxDec->FBTCXdelayBuf_32, st->prev_synth_buffer_fx, NS2SA( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), -11 ); //Q11 -> Q0 - } - - IF( st->hHQ_core != NULL ) - { - set32_fx( st->hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); - set16_fx( st->hHQ_core->last_env_fx, 0, BANDS_MAX ); - st->hHQ_core->last_max_pos_pulse = 0; - move16(); - - set16_fx( st->hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); - st->hHQ_core->prev_frm_hfe2 = 0; - st->hHQ_core->prev_stab_hfe2 = 0; - move16(); - move16(); - } - } - - IF( st->prev_bfi != 0 ) - { - Word16 delay_comp; - - /*switch off Hq Voicing as it was not updated in MODE2*/ - IF( st->hHQ_core != NULL ) - { - st->hHQ_core->oldHqVoicing = 0; - st->hHQ_core->HqVoicing = 0; - move16(); - move16(); - } - - delay_comp = NS2SA_FX2( st->output_Fs, DELAY_CLDFB_NS ); - /*TODO To be tested:control not entering the block*/ - test(); - test(); - IF( !st->last_con_tcx && ( st->last_core_bfi == ACELP_CORE ) && EQ_16( st->core, HQ_CORE ) ) - { - /*TODO None of the test dtreams are entering this block,hence enabled assert(0)*/ - assert( 0 ); - Word32 *realBuffer_fx[CLDFB_NO_COL_MAX_SWITCH], *imagBuffer_fx[CLDFB_NO_COL_MAX_SWITCH]; - Word32 realBufferTmp_fx[CLDFB_NO_COL_MAX_SWITCH][CLDFB_NO_CHANNELS_MAX], imagBufferTmp_fx[CLDFB_NO_COL_MAX_SWITCH][CLDFB_NO_CHANNELS_MAX]; - Word32 syn_Overl_fx[320]; - Word32 fer_samples_fx[960]; - Copy_Scale_sig_16_32_DEPREC( st->hTcxDec->syn_Overl, syn_Overl_fx, 320, 15 ); - Copy_Scale_sig_16_32_DEPREC( st->hHQ_core->fer_samples_fx, fer_samples_fx, 960, 15 ); - - - FOR( i = 0; i < CLDFB_NO_COL_MAX_SWITCH; i++ ) - { - set32_fx( realBufferTmp_fx[i], 0, CLDFB_NO_CHANNELS_MAX ); - set32_fx( imagBufferTmp_fx[i], 0, CLDFB_NO_CHANNELS_MAX ); - realBuffer_fx[i] = realBufferTmp_fx[i]; - imagBuffer_fx[i] = imagBufferTmp_fx[i]; - } - - /* CLDFB analysis of the synthesis at internal sampling rate */ - IF( NE_32( ( error = cldfb_save_memory_ivas_fx( st->cldfbAna ) ), IVAS_ERR_OK ) ) - { - return error; - } - - cldfbAnalysis_ivas_fx( syn_Overl_fx, realBuffer_fx, imagBuffer_fx, delay_comp, st->cldfbAna ); - cldfb_restore_memory_ivas_fx( st->cldfbAna ); /*Assuming Q10*/ - - /* CLDFB synthesis of the combined signal */ - IF( NE_32( ( error = cldfb_save_memory_ivas_fx( st->cldfbSyn ) ), IVAS_ERR_OK ) ) - { - return error; - } - - cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, fer_samples_fx, delay_comp, st->cldfbSyn ); - cldfb_restore_memory_ivas_fx( st->cldfbSyn ); - Copy_Scale_sig_32_16( syn_Overl_fx, st->hTcxDec->syn_Overl, 320, 15 ); - Copy_Scale_sig_32_16( fer_samples_fx, st->hHQ_core->fer_samples_fx, 960, 9 ); - } - - test(); - test(); - IF( !st->last_con_tcx && ( st->last_core_bfi == ACELP_CORE ) && EQ_16( st->core, HQ_CORE ) ) - { - lerp( st->hTcxDec->syn_Overl, st->hHQ_core->fer_samples_fx + delay_comp, shr( output_frame, 1 ), shr( st->last_L_frame, 1 ) ); - /*Set to zero the remaining part*/ - set16_fx( st->hHQ_core->fer_samples_fx + delay_comp + output_frame / 2, 0, sub( shr( output_frame, 1 ), delay_comp ) ); - } - } - - st->use_acelp_preq = 0; - st->reset_mem_AR = 0; - move16(); - move16(); - } - - /*FEC*/ - IF( LE_16( st->L_frame, L_FRAME16k ) ) - { - test(); - IF( LE_16( st->last_L_frame, L_FRAME16k ) && NE_16( st->core, HQ_CORE ) ) - { - IF( NE_16( st->L_frame, st->last_L_frame ) ) - { - IF( GT_16( st->L_frame, st->last_L_frame ) ) - { - oldLenClasBuff = mult_r( L_SYN_MEM_CLAS_ESTIM, div_s( st->last_L_frame, st->L_frame ) ); - newLenClasBuff = L_SYN_MEM_CLAS_ESTIM; - move16(); - } - ELSE - { - oldLenClasBuff = L_SYN_MEM_CLAS_ESTIM; - move16(); - newLenClasBuff = mult_r( L_SYN_MEM_CLAS_ESTIM, div_s( st->L_frame, st->last_L_frame ) ); - } - lerp( &st->mem_syn_clas_estim_fx[L_SYN_MEM_CLAS_ESTIM - oldLenClasBuff], &st->mem_syn_clas_estim_fx[L_SYN_MEM_CLAS_ESTIM - newLenClasBuff], newLenClasBuff, oldLenClasBuff ); - } - } - ELSE - { - set16_fx( st->mem_syn_clas_estim_fx, 0, L_SYN_MEM_CLAS_ESTIM ); - } - } - - /* Here we only handle cases where last_ppp and last_nelp not updated when coming from CodecB or other cores - within ACELP_CORE if switching from another bitarate to vbr, last_ppp and last_nelp is always updated in the previous frame */ - test(); - test(); - IF( ( st->core == ACELP_CORE ) && ( ( st->last_core != ACELP_CORE ) || EQ_16( st->last_codec_mode, MODE2 ) ) ) - { - st->last_ppp_mode_dec = 0; - st->last_nelp_mode_dec = 0; - move16(); - move16(); - } - - /* Handle state reset of stat_noise_uv_mod memory */ - test(); - test(); - test(); - IF( ( st->core == ACELP_CORE ) && ( ( st->last_core != ACELP_CORE ) || EQ_16( st->last_codec_mode, MODE2 ) || LE_32( st->last_total_brate, PPP_NELP_2k80 ) ) ) - { - st->act_count = 3; - st->uv_count = 0; - move16(); - move16(); - } - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( ( ( st->core == ACELP_CORE ) || EQ_16( st->core, AMR_WB_CORE ) ) && EQ_16( st->last_core, HQ_CORE ) ) || ( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_16( last_element_mode, IVAS_CPE_DFT ) ) ) && EQ_16( nchan_out, 2 ) && - NE_32( st->core_brate, SID_2k40 ) && ( st->core_brate != FRAME_NO_DATA ) && ( ( last_core_brate_st0 == FRAME_NO_DATA ) || EQ_32( last_core_brate_st0, SID_2k40 ) ) ) ) - { - test(); - if ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) - { - st->hPFstat->reset = 1; - move16(); - } - - IF( EQ_16( st->L_frame, L_FRAME16k ) ) - { - Copy( TRWB2_Ave_fx, st->lsf_old_fx, M ); /* init of LSP */ - Copy( TRWB2_Ave_fx, st->lsfoldbfi1_fx, M ); - Copy( TRWB2_Ave_fx, st->lsfoldbfi0_fx, M ); - Copy( TRWB2_Ave_fx, st->lsf_adaptive_mean_fx, M ); - lsf2lsp_fx( st->lsf_old_fx, st->lsp_old_fx, M, INT_FS_16k ); - } - ELSE - { - Copy( TRWB_Ave_fx, st->lsf_old_fx, M ); /* init of LSP */ - Copy( TRWB_Ave_fx, st->lsfoldbfi1_fx, M ); - Copy( TRWB_Ave_fx, st->lsfoldbfi0_fx, M ); - Copy( TRWB_Ave_fx, st->lsf_adaptive_mean_fx, M ); - lsf2lsp_fx( st->lsf_old_fx, st->lsp_old_fx, M, INT_FS_12k8 ); - } - - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && EQ_16( nchan_out, 2 ) && GT_32( st->core_brate, SID_2k40 ) && ( ( last_core_brate_st0 == FRAME_NO_DATA ) || EQ_32( last_core_brate_st0, SID_2k40 ) ) && st->hTcxDec != NULL ) - { - /* Last frame was Stereo CNG and the synthesis memory is outdated -- reset */ - set16_fx( st->hTcxDec->old_syn_Overl, 0, L_FRAME32k / 2 ); - set16_fx( st->hFdCngDec->hFdCngCom->olapBufferAna_fx, 0, FFTLEN ); - set16_fx( st->agc_mem_fx, 0, 2 ); - } - st->mem_deemph_fx = 0; - move16(); - IF( !st->last_con_tcx ) - { - set16_fx( st->mem_syn2_fx, 0, M ); - } - set16_fx( st->mem_syn1_fx, 0, M ); - if ( st->hBWE_TD != NULL ) - { - st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; - move32(); - } - - /* Reset ACELP parameters */ - set16_fx( st->mem_MA_fx, 0, M ); - - IF( EQ_32( st->sr_core, INT_FS_16k ) ) - { - Copy( GEWB2_Ave_fx, st->mem_AR_fx, M ); - } - ELSE - { - Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); - } - - st->tilt_code_fx = 0; - st->gc_threshold_fx = 0; - st->dm_fx.prev_gain_code = 0; - st->dm_fx.prev_state = 0; - move16(); - move32(); - move32(); - move16(); - set16_fx( st->dm_fx.prev_gain_pit, 0, 6 ); - - st->last_coder_type = GENERIC; - move16(); - - fer_energy_fx( output_frame, UNVOICED_CLAS, st->previoussynth_fx_32, 0, -1, &st->enr_old_fx, 1 ); /*Q-0*/ - st->lp_gainp_fx = 0; - move16(); - st->lp_gainc_fx = extract_h( Sqrt32( st->lp_ener_fx, &exp ) ); /*Q=15-exp*/ - move16(); - st->lp_gainc_fx = shr( st->lp_gainc_fx, sub( 12, exp ) ); /*Q3*/ - move16(); - - st->last_voice_factor_fx = 0; - st->Last_GSC_noisy_speech_flag = 0; - move16(); - move16(); - - /* reset CLDFB memories */ - cldfb_reset_memory_fx( st->cldfbAna ); - cldfb_reset_memory_fx( st->cldfbBPF ); - cldfb_reset_memory_fx( st->cldfbSyn ); - - /* reset TBE memories */ - test(); - test(); - IF( !st->last_con_tcx && !( ( EQ_16( st->last_core, HQ_CORE ) ) && ( st->element_mode > EVS_MONO ) ) ) - { - set16_fx( st->old_exc_fx, 0, L_EXC_MEM_DEC ); - } - ELSE IF( LT_16( st->L_frame, L_FRAME16k ) ) - { - /* resample from 16kHz to 12.8kHZ */ - synth_mem_updt2( st->L_frame, L_FRAME16k, st->old_exc_fx, st->mem_syn_r, st->mem_syn2_fx, NULL, DEC ); - } - - IF( st->hBWE_TD != NULL ) - { - set16_fx( st->hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); - } - - test(); - IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) - { - hf_synth_reset_fx( st->hBWE_zero ); -#ifdef MSAN_FIX - set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); -#endif - } - - IF( st->hBWE_FD != NULL ) - { - set16_fx( st->hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); - } - } - - test(); - test(); - test(); - IF( ( ( st->core == ACELP_CORE ) || EQ_16( st->core, AMR_WB_CORE ) ) && ( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) ) - { - IF( st->hBWE_TD != NULL ) - { - st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; - move32(); - set16_fx( st->hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); - } - - st->tilt_code_fx = 0; - st->gc_threshold_fx = 0; - st->dm_fx.prev_gain_code = 0; - st->dm_fx.prev_state = 0; - move16(); - move32(); - move32(); - move16(); - set16_fx( st->dm_fx.prev_gain_pit, 0, 6 ); - st->last_coder_type = GENERIC; - move16(); - fer_energy_fx( output_frame, UNVOICED_CLAS, st->previoussynth_fx_32, 0, -1, &st->enr_old_fx, 1 ); /*Q-0*/ - - st->lp_gainp_fx = 0; - move16(); - st->lp_gainc_fx = extract_h( Sqrt32( st->lp_ener_fx, &exp ) ); /*Q=15-exp*/ - move16(); - st->lp_gainc_fx = shr( st->lp_gainc_fx, sub( 12, exp ) ); /*Q3*/ - move16(); - - st->last_voice_factor_fx = 0; - st->Last_GSC_noisy_speech_flag = 0; - move16(); - move16(); - - test(); - IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) - { - hf_synth_reset_fx( st->hBWE_zero ); -#ifdef MSAN_FIX - set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); -#endif - } - - IF( st->hBWE_FD != NULL ) - { - set16_fx( st->hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); - } - - test(); - test(); - test(); - IF( EQ_16( nchan_out, 1 ) && EQ_16( st->element_mode, IVAS_CPE_DFT ) && LE_32( st->element_brate, IVAS_24k4 ) && GT_32( last_element_brate, IVAS_24k4 ) ) - { - /* update cldbf state with previous frame TCX synthesis when going from a bitrate with residual coding to a bitrate without it */ - Word16 offset; - offset = sub( st->cldfbAna->p_filter_length, st->cldfbAna->no_channels ); - Word32 *old_synthFB_fx; - IF( ( old_synthFB_fx = (Word32 *) malloc( st->hTcxDec->old_synth_lenFB * sizeof( Word32 ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for old_synth_lenFB (32 bit) \n" ) ); - } -#ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( st->hTcxDec->old_synthFB_fx, old_synthFB_fx, st->hTcxDec->old_synth_lenFB, sub( Q10, Q_old_synthFB ) ); // Q10 -#else - Copy_Scale_sig_16_32_DEPREC( st->hTcxDec->old_synthFB_fx, old_synthFB_fx, st->hTcxDec->old_synth_lenFB, sub( Q10, Q_old_synthFB ) ); // Q10 -#endif - Copy32( old_synthFB_fx + st->hTcxDec->old_synth_lenFB - offset, st->cldfbAna->cldfb_state_fx, offset ); - st->cldfbAna->Q_cldfb_state = Q10; - move16(); - IF( old_synthFB_fx ) - free( old_synthFB_fx ); - } - } - - test(); - test(); - test(); - test(); - IF( EQ_16( st->core, HQ_CORE ) && ( ( st->last_core == ACELP_CORE ) || EQ_16( st->last_core, AMR_WB_CORE ) || ( ( ( st->element_mode != EVS_MONO ) ) && ( NE_16( st->last_core, HQ_CORE ) ) ) ) ) - { - set32_fx( st->hHQ_core->prev_env_fx, 0, SFM_N_WB ); - set32_fx( st->hHQ_core->prev_normq_fx, 0, SFM_N_WB ); - - set32_fx( st->hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); - set16_fx( st->hHQ_core->last_env_fx, 0, BANDS_MAX ); - st->hHQ_core->last_max_pos_pulse = 0; - move16(); - - set16_fx( st->hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); - st->hHQ_core->prev_frm_hfe2 = 0; - st->hHQ_core->prev_stab_hfe2 = 0; - move16(); - move16(); - IF( GT_32( st->output_Fs, 16000 ) ) - { - set32_fx( st->hHQ_core->prev_coeff_out_fx, 0, L_HQ_WB_BWE ); - } - - IF( st->element_mode != EVS_MONO ) - { - /* Estimate mem_env_delta to reinit env_stab */ - tmp_fx = L_max( 0, L_add( ENV_STAB_EST1_FX, L_add( Mult_32_16( st->stab_fac_smooth_lt_fx, ENV_STAB_EST2_FX ), Mult_32_16( st->log_energy_diff_lt_fx, ENV_STAB_EST3_FX ) ) ) ); /*Q12*/ - - st->hHQ_core->mem_env_delta = extract_l( L_min( MAX16B, tmp_fx ) ); /* Convert to Q12 and handle saturation */ - move16(); - test(); - IF( NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) - { - set16_fx( st->hHQ_core->old_out_fx, 0, output_frame ); - set32_fx( st->hHQ_core->old_outLB_fx, 0, L_FRAME16k ); - set16_fx( st->hHQ_core->old_out_LB_fx, 0, L_FRAME16k ); - } - - st->hHQ_core->no_att_hangover = 0; - move16(); - st->hHQ_core->energy_lt_fx = 2457600; /*300.0f Q13*/ - move32(); - set16_fx( st->hHQ_core->old_is_transient, 0, 3 ); - set16_fx( st->hHQ_core->prev_noise_level_fx, 0, 2 ); - st->hHQ_core->prev_R = 0; - move16(); - set16_fx( st->hHQ_core->mem_norm + 1, 39, SFM_N_ENV_STAB - 1 ); - st->hHQ_core->prev_hqswb_clas = HQ_NORMAL; - st->hHQ_core->prev_ni_ratio_fx = 16384; /*Q15*/ - move16(); - move16(); - set16_fx( st->hHQ_core->prev_En_sb_fx, 0, NB_SWB_SUBBANDS ); - } - ELSE - { - set16_fx( st->hHQ_core->old_out_fx, 0, output_frame ); - set32_fx( st->hHQ_core->old_outLB_fx, 0, L_FRAME16k ); - } - } - - /* handle switching cases where preecho_sb was not called in the last frame (memory not up to date) */ - IF( st->hHQ_core != NULL ) - { - st->hHQ_core->pastpre = sub( st->hHQ_core->pastpre, 1 ); - move16(); - IF( st->hHQ_core->pastpre < 0 ) - { - reset_preecho_dec_fx( st->hHQ_core ); - } - } - test(); - IF( st->core_brate == FRAME_NO_DATA ) - { - st->VAD = 0; - st->m_frame_type = ZERO_FRAME; - } - ELSE IF( EQ_32( st->core_brate, SID_2k40 ) || EQ_32( st->core_brate, SID_1k75 ) ) - { - st->VAD = 0; - st->m_frame_type = SID_FRAME; - } - ELSE - { - st->VAD = 1; - st->m_frame_type = ACTIVE_FRAME; - } - - move16(); - move16(); - /*switch on CNA on active frames*/ - IF( ( st->element_mode == EVS_MONO ) ) /* for IVAS modes, st->flag_cna is set earlier */ - { - test(); - test(); - test(); - test(); - test(); - test(); - IF( st->VAD && ( ( NE_16( st->core, AMR_WB_CORE ) && LE_32( st->total_brate, CNA_MAX_BRATE ) ) || ( EQ_16( st->core, AMR_WB_CORE ) && LE_32( st->total_brate, ACELP_8k85 ) ) ) ) - { - st->flag_cna = 1; - move16(); - } - ELSE IF( st->VAD || ( EQ_16( st->cng_type, FD_CNG ) && EQ_16( st->L_frame, L_FRAME16k ) ) ) - { - st->flag_cna = 0; - move16(); - } - } - - if ( EQ_16( st->core, AMR_WB_CORE ) ) - { - st->cng_type = LP_CNG; - move16(); - } - - /* Reconfigure CNG */ - test(); - test(); - test(); - test(); - IF( st->hFdCngDec && ( NE_16( st->last_L_frame, st->L_frame ) || NE_16( st->hFdCngDec->hFdCngCom->frameSize, st->L_frame ) || ( st->ini_frame == 0 ) || NE_16( st->bwidth, st->last_bwidth ) ) ) - { - /* || st->last_core == AMR_WB_CORE || st->last_codec_mode == MODE2)){*/ - IF( NE_16( st->core, AMR_WB_CORE ) ) - { - test(); - IF( EQ_16( st->rf_flag, 1 ) && EQ_32( st->total_brate, ACELP_13k20 ) ) - { - configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, ACELP_9k60, st->L_frame, st->last_L_frame, st->element_mode ); - } - ELSE - { - configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, st->total_brate, st->L_frame, st->last_L_frame, st->element_mode ); - } - } - ELSE - { - configureFdCngDec_ivas_fx( st->hFdCngDec, WB, ACELP_8k00, st->L_frame, st->last_L_frame, st->element_mode ); - - if ( st->VAD ) - { - st->hFdCngDec->hFdCngCom->CngBitrate = st->total_brate; - move32(); - } - } - test(); - test(); - IF( NE_16( st->last_L_frame, st->L_frame ) && LE_16( st->L_frame, L_FRAME16k ) && LE_16( st->last_L_frame, L_FRAME16k ) ) - { - test(); - IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) - { - lerp( st->hFdCngDec->hFdCngCom->olapBufferAna_fx + st->last_L_frame, st->hFdCngDec->hFdCngCom->olapBufferAna_fx + st->L_frame, st->L_frame, st->last_L_frame ); - } - - L_lerp_fx( st->hFdCngDec->hFdCngCom->olapBufferSynth2_fx, st->hFdCngDec->hFdCngCom->olapBufferSynth2_fx, shl( st->L_frame, 1 ), shl( st->last_L_frame, 1 ), Q_olapBufferSynth2 ); - - test(); - IF( LE_32( st->total_brate, SID_2k40 ) && LE_32( st->last_total_brate, SID_2k40 ) ) - { - L_lerp_fx( st->hFdCngDec->hFdCngCom->olapBufferSynth_fx, st->hFdCngDec->hFdCngCom->olapBufferSynth_fx, shl( st->L_frame, 1 ), shl( st->last_L_frame, 1 ), Q_olapBufferSynth ); - - IF( EQ_16( st->L_frame, L_FRAME ) ) - { - FOR( i = 0; i < ( st->L_frame * 2 ); i++ ) - { - st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i] = Mult_32_16( st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i], (Word16) 20480 /* 0.6250f in Q15 */ ); - move32(); - } - } - ELSE - { - FOR( i = 0; i < ( st->L_frame * 2 ); i++ ) - { - st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i] = Mult_32_16( L_shl( st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i], 1 ), (Word16) 26214 /* 1.6f in Q14 */ ); - move32(); - } - } - } - } - } - - return error; -} -/*---------------------------------------------------------------------* - * core_switching_hq_prepare_dec() - * - * Preprocessing in the first HQ frame after ACELP frame - * Modify bit allocation for HQ core by removing ACELP subframe budget - *---------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------* - * bandwidth_switching_detect() - * - * Classification for band-width switching - *---------------------------------------------------------------------*/ - -void bandwidth_switching_detect_ivas_fx( - Decoder_State *st_fx /* i/o: encoder state structure */ -) -{ - test(); - test(); - IF( ( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) && EQ_16( st_fx->idchan, 1 ) ) || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) - { - /* there is no BWE in TD stereo secondary channel and in MDCT stereo, IGF is part of the core decoding -> no BW switching -> reset BWS counters */ - st_fx->prev_bws_cnt = 0; - st_fx->bws_cnt = 0; - st_fx->bws_cnt1 = 0; - move16(); - move16(); - move16(); - - return; - } - /* update band-width switching counter */ - test(); - test(); - test(); - test(); - IF( GE_16( st_fx->bws_cnt1, N_NS2W_FRAMES ) ) - { - st_fx->bws_cnt1 = 0; - move16(); - } - ELSE IF( GT_32( st_fx->total_brate, ACELP_9k60 ) && LT_32( st_fx->last_core_brate, ACELP_9k60 ) && EQ_16( st_fx->bwidth, SWB ) && EQ_16( st_fx->last_bwidth, WB ) && ( st_fx->last_low_rate_mode == 0 ) ) - { - st_fx->bws_cnt1 = add( st_fx->bws_cnt1, 1 ); - move16(); - } - ELSE IF( st_fx->bws_cnt1 > 0 ) - { - IF( LT_16( st_fx->bwidth, st_fx->last_bwidth ) ) - { - st_fx->bws_cnt = sub( shl( sub( N_NS2W_FRAMES, st_fx->bws_cnt1 ), 1 ), 1 ); - move16(); - } - ELSE - { - st_fx->bws_cnt = 0; - move16(); - } - - IF( LT_16( st_fx->bwidth, st_fx->last_bwidth ) ) - { - st_fx->bws_cnt1 = 0; - move16(); - } - ELSE - { - IF( EQ_16( st_fx->bwidth, SWB ) ) - { - st_fx->bws_cnt1 = add( st_fx->bws_cnt1, 1 ); - move16(); - } - ELSE - { - st_fx->bws_cnt1 = 0; - move16(); - } - } - } - - /* update band-width switching counter */ - test(); - test(); - test(); - IF( GE_16( st_fx->bws_cnt, N_WS2N_FRAMES ) ) - { - st_fx->bws_cnt = 0; - move16(); - } - ELSE IF( LT_32( st_fx->total_brate, ACELP_9k60 ) && GT_32( st_fx->last_core_brate, ACELP_9k60 ) && LT_16( st_fx->bwidth, st_fx->last_bwidth ) && EQ_16( st_fx->bwidth, WB ) ) - { - st_fx->bws_cnt = add( st_fx->bws_cnt, 1 ); - move16(); - } - ELSE IF( st_fx->bws_cnt > 0 ) - { - IF( GT_16( st_fx->bwidth, st_fx->last_bwidth ) ) - { - st_fx->bws_cnt1 = shr( sub( N_WS2N_FRAMES, st_fx->bws_cnt ), 1 ); - move16(); - } - ELSE - { - st_fx->bws_cnt1 = 0; - move16(); - } - - IF( GT_16( st_fx->bwidth, st_fx->last_bwidth ) ) - { - st_fx->bws_cnt = 0; - move16(); - } - ELSE - { - IF( EQ_16( st_fx->bwidth, WB ) ) - { - st_fx->bws_cnt = add( st_fx->bws_cnt, 1 ); - move16(); - } - ELSE - { - st_fx->bws_cnt = 0; - move16(); - } - } - } - - return; -} - - -/*---------------------------------------------------------------------* - * bw_switching_pre_proc() - * - * Band-width switching pre-processing - *---------------------------------------------------------------------*/ -void ivas_bw_switching_pre_proc_fx( - Decoder_State *st, /* i/o: decoder state structure */ - const Word32 last_element_brate, /* i : last element bitrate */ - const Word16 nchan_out /* i : number of output channels */, - Word32 *old_syn_12k8_16k_fx, - Word16 Q, - Word16 Q_audio ) -{ - Word16 i; - Word32 syn_dct_fx[L_FRAME]; - - - Flag Overflow = 0; - move32(); - - IF( st->element_mode > EVS_MONO ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( st->core == ACELP_CORE ) && !( EQ_16( st->bfi, 1 ) && EQ_16( st->con_tcx, 1 ) ) && st->hBWE_FD != NULL && !( LE_32( st->core_brate, SID_2k40 ) && EQ_16( st->element_mode, IVAS_CPE_DFT ) && EQ_16( nchan_out, 2 ) ) && !( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_16( nchan_out, 1 ) && EQ_16( st->idchan, 1 ) && LE_32( last_element_brate, IVAS_SID_5k2 ) ) ) - { - /* Calculate tilt of the ACELP core synthesis - needed in SWB BWE decoding */ - Word16 old_syn_12k8_16k_tmp_16fx[L_FRAME16k]; - Copy_Scale_sig_32_16( old_syn_12k8_16k_fx, old_syn_12k8_16k_tmp_16fx, st->L_frame, sub( -1, Q ) ); - st->tilt_wb_fx = round_fx_sat( L_shl_sat( calc_tilt_bwe_fx( old_syn_12k8_16k_tmp_16fx, -1, st->L_frame ), sub( Q, 8 ) ) ); // Q24+(Q-8) - 16 - move16(); - } - - return; - } - - - test(); - test(); - IF( ( st->core == ACELP_CORE ) && !( EQ_16( st->bfi, 1 ) && EQ_16( st->con_tcx, 1 ) ) ) - { - /*----------------------------------------------------------------------* - * Calculate tilt of the ACELP core synthesis - *----------------------------------------------------------------------*/ - - st->tilt_wb_fx = ivas_calc_tilt_bwe_fx( old_syn_12k8_16k_fx, Q, st->L_frame ); - move16(); - /*-------------------------------------------------------------------------------* - * Calculate frequency energy of 0~3.2kHz and 3.2~6.4kHz the ACELP core synthesis - *-------------------------------------------------------------------------------*/ - edct_fx( old_syn_12k8_16k_fx, syn_dct_fx, L_FRAME, &Q ); - Word64 W_tmp = 0; - move64(); - Word32 tmp; - Word16 shift; - FOR( i = 0; i < L_FRAME / 2; i++ ) - { - W_tmp = W_add( W_tmp, W_shr( W_mult0_32_32( syn_dct_fx[i], syn_dct_fx[i] ), Q ) ); - } - shift = W_norm( W_tmp ); - W_tmp = W_shl( W_tmp, shift ); - tmp = W_extract_h( W_tmp ); - tmp = L_shr( tmp, 8 ); - - tmp = getSqrtWord32( tmp ); - st->enerLL_fx = tmp; - move32(); - st->enerLL_fx_Q = shr( sub( add( Q, shift ), 32 ), 1 ); - move16(); - W_tmp = 0; - move64(); - FOR( ; i < L_FRAME; i++ ) - { - W_tmp = W_add( W_tmp, W_shr( W_mult0_32_32( syn_dct_fx[i], syn_dct_fx[i] ), Q ) ); - } - shift = W_norm( W_tmp ); - W_tmp = W_shl( W_tmp, shift ); - tmp = W_extract_h( W_tmp ); // Q = Q + shift - 32 - tmp = L_shr( tmp, 7 ); // divide by 128 - tmp = getSqrtWord32( tmp ); - st->enerLH_fx = tmp; - move32(); - st->enerLH_fx_Q = shr( sub( add( Q, shift ), 32 ), 1 ); - move16(); - } - ELSE - { - IF( st->hHQ_core->old_is_transient[0] ) - { - Word32 tmp, L_tmp = 0; - move32(); - FOR( i = 0; i < 32; i++ ) - { - L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); - } - tmp = L_shr( L_tmp, 5 ); // divide by 32 - tmp = getSqrtWord32( tmp ); - st->enerLL_fx = tmp; - move32(); - st->enerLL_fx_Q = Q_audio; - move16(); - - L_tmp = 0; - move32(); - FOR( ; i < 64; i++ ) - { - L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); - } - - tmp = L_shr( L_tmp, 5 ); // divide by 32 - tmp = getSqrtWord32( tmp ); - st->enerLH_fx = tmp; - move32(); - st->enerLH_fx_Q = Q_audio; - move16(); - } - ELSE - { - Word32 tmp, L_tmp = 0; - move32(); - FOR( i = 0; i < L_FRAME / 2; i++ ) - { - L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); - } - tmp = L_shr( L_tmp, 5 ); // divide by 32 - tmp = getSqrtWord32( tmp ); - st->enerLL_fx = tmp; - move32(); - st->enerLL_fx_Q = Q_audio; - move16(); - - L_tmp = 0; - move32(); - FOR( ; i < L_FRAME; i++ ) - { - L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); - } - tmp = L_shr( L_tmp, 5 ); // divide by 32 - tmp = getSqrtWord32( tmp ); - st->enerLL_fx = tmp; - move32(); - st->enerLL_fx_Q = Q_audio; - move16(); - } - } - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( EQ_16( st->last_bwidth, 0 ) && LE_16( st->extl, SWB_CNG ) ) - { - - st->prev_ener_shb_fx = 0; - move16(); - IF( st->hBWE_FD != NULL ) - { - set16_fx( st->prev_SWB_fenv_fx, 0, SWB_FENV ); - } - } - ELSE IF( ( ( ( st->core == ACELP_CORE ) && ( EQ_16( st->last_core, HQ_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) || EQ_16( st->last_core, TCX_20_CORE ) ) ) || ( EQ_16( st->core, st->last_core ) && NE_16( st->extl, st->last_extl ) ) ) && GE_16( st->last_bwidth, SWB ) ) - { - st->attenu_fx = 3277; // 0.1f in Q15 - move16(); - } - - test(); - test(); - test(); - test(); - test(); - if ( EQ_16( st->last_core, HQ_CORE ) || ( ( st->last_core == ACELP_CORE ) && !( EQ_16( st->last_extl, WB_TBE ) || EQ_16( st->last_extl, SWB_TBE ) || EQ_16( st->last_extl, FB_TBE ) ) && GT_32( st->core_brate, ACELP_8k00 ) ) ) - { - st->prev_fractive = 0; - move16(); - } - - return; -} -/*---------------------------------------------------------------------* - * core_switch_lb_upsamp() - * - * Resample HQ/TCX-LB to the output sampling rate (8/16/32/48 kHz) - *---------------------------------------------------------------------*/ - - -/*---------------------------------------------------------------------* - * smoothTransitionDtxToTcx() - * - * apply smoothing to the transition part for inactive to active transitions in DTX - *---------------------------------------------------------------------*/ - -#define TRANSITION_SMOOTHING_LEN_16k 15 -#define TRANSITION_SMOOTHING_LEN_32k 31 -#define TRANSITION_SMOOTHING_LEN_48k 47 diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index d654b3af4..caef9485b 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -2435,3 +2435,1012 @@ static void smoothTransitionDtxToTcx_fx( return; } + + +/*---------------------------------------------------------------------* + * core_switching_pre_dec() + * + * Preprocessing/preparation for ACELP/HQ core switching + *---------------------------------------------------------------------*/ +ivas_error core_switching_pre_dec_ivas_fx( + Decoder_State *st, /* i/o: decoder state structure */ + const Word16 output_frame, /* i : frame length */ + const Word32 last_core_brate_st0, /* i : channel 0 last core bitrate */ + const Word16 nchan_out, /* i : number of output channels */ + const Word16 last_element_mode, /* i : last_element_mode */ + const Word32 last_element_brate, /* i : last element bitrate */ + Word16 Q_old_synthFB, + Word16 *Q_olapBufferSynth, + Word16 *Q_olapBufferSynth2 ) +{ + Word32 tmp_fx; /*Q-12*/ + Word16 i, oldLenClasBuff, newLenClasBuff; + ivas_error error; + Word16 exp = 25; + move16(); + error = IVAS_ERR_OK; + move32(); + + /* Codec mode switching */ + test(); + test(); + test(); + IF( EQ_16( st->last_codec_mode, MODE2 ) || ( ( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) && ( st->element_mode > EVS_MONO ) ) ) + { + st->mem_deemph_fx = st->syn[M]; + move16(); + set16_fx( st->agc_mem_fx, 0, 2 ); + Scale_sig( &( st->mem_deemph_fx ), 1, st->Q_syn ); /* Brings mem_deemph to Qsyn */ + + Copy_Scale_sig( st->mem_syn2_fx, st->mem_syn1_fx, M, sub( -1, st->Q_syn ) ); /*Q-1*/ + + st->bpf_off = 1; + move16(); + IF( st->hPFstat != NULL ) + { + Scale_sig( st->hPFstat->mem_pf_in, L_SUBFR, st->Q_syn ); /* Post_filter mem ,Q_syn*/ + Scale_sig( st->hPFstat->mem_res2, DECMEM_RES2, st->Q_syn ); /* NB post_filter mem , Q_syn*/ + Scale_sig( st->hPFstat->mem_stp, L_SUBFR, st->Q_syn ); /* Post_filter mem ,Q_syn*/ + set16_fx( st->hBPF->pst_old_syn_fx, 0, NBPSF_PIT_MAX ); /* BPF mem*/ + } + IF( st->hBPF != NULL ) + { + st->hBPF->pst_lp_ener_fx = round_fx( L_shl( Mpy_32_16_1( st->lp_error_ener, 0x6054 ), 2 + 8 ) ); /* convert from 15Q16, log2 -> 7Q8 10*log10 */ + st->hBPF->pst_mem_deemp_err_fx = 0; + move16(); + move16(); + } + st->psf_lp_noise_fx = round_fx( L_shl( st->lp_noise, 1 ) ); // Q(23+1-16)->Q8 + move16(); + + /* reset old HB synthesis buffer */ + IF( EQ_16( st->last_L_frame, L_FRAME ) ) + { + st->old_bwe_delay = NS2SA( st->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_12k8_NS ); + } + ELSE + { + st->old_bwe_delay = NS2SA( st->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_16k_NS ); + } + move16(); + set16_fx( st->hb_prev_synth_buffer_fx, 0, NS2SA( 48000, DELAY_BWE_TOTAL_NS ) ); + + test(); + IF( st->hBWE_TD != NULL && ( st->last_core != ACELP_CORE ) ) + { +#ifdef MSAN_FIX + st->hBWE_TD->prev_hb_synth_fx_exp = 31; + move16(); +#endif // MSAN_FIX + /* reset BWE memories */ + set16_fx( st->hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); + st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + move32(); + } + + /* reset upd_cnt */ + st->upd_cnt = MAX_UPD_CNT; + move16(); + + st->igf = 0; + move16(); + + test(); + IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) + { + hf_synth_reset_fx( st->hBWE_zero ); +#ifdef MSAN_FIX + set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); +#endif + } + + IF( st->hBWE_FD != NULL ) + { + set16_fx( st->hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); + } + + IF( st->hHQ_core != NULL ) + { + set32_fx( st->hHQ_core->prev_env_fx, 0, SFM_N_WB ); + set32_fx( st->hHQ_core->prev_normq_fx, 0, SFM_N_WB ); + + set32_fx( st->hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); + set16_fx( st->hHQ_core->last_env_fx, 0, BANDS_MAX ); + + st->hHQ_core->last_max_pos_pulse = 0; + move16(); + + IF( GT_32( st->output_Fs, 16000 ) ) + { + set32_fx( st->hHQ_core->prev_coeff_out_fx, 0, L_HQ_WB_BWE ); + } + + /* pre-echo */ + st->hHQ_core->pastpre = 0; + move16(); + } + + /* reset the GSC pre echo energy threshold in case of switching */ + if ( st->hGSCDec != NULL ) + { + st->hGSCDec->Last_frame_ener_fx = MAX_32; + move32(); + } + + test(); + IF( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) + { + IF( st->element_mode == EVS_MONO ) + { + st->last_core = HQ_CORE; + move16(); + + Copy32( st->hTcxDec->FBTCXdelayBuf_32, st->prev_synth_buffer32_fx, NS2SA( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); + // Copy_Scale_sig_32_16( st->hTcxDec->FBTCXdelayBuf_32, st->prev_synth_buffer_fx, NS2SA( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), -11 ); //Q11 -> Q0 + } + + IF( st->hHQ_core != NULL ) + { + set32_fx( st->hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); + set16_fx( st->hHQ_core->last_env_fx, 0, BANDS_MAX ); + st->hHQ_core->last_max_pos_pulse = 0; + move16(); + + set16_fx( st->hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); + st->hHQ_core->prev_frm_hfe2 = 0; + st->hHQ_core->prev_stab_hfe2 = 0; + move16(); + move16(); + } + } + + IF( st->prev_bfi != 0 ) + { + Word16 delay_comp; + + /*switch off Hq Voicing as it was not updated in MODE2*/ + IF( st->hHQ_core != NULL ) + { + st->hHQ_core->oldHqVoicing = 0; + st->hHQ_core->HqVoicing = 0; + move16(); + move16(); + } + + delay_comp = NS2SA( st->output_Fs, DELAY_CLDFB_NS ); + /*TODO To be tested:control not entering the block*/ + test(); + test(); + IF( !st->last_con_tcx && ( st->last_core_bfi == ACELP_CORE ) && EQ_16( st->core, HQ_CORE ) ) + { + /*TODO None of the test dtreams are entering this block,hence enabled assert(0)*/ + assert( 0 ); + Word32 *realBuffer_fx[CLDFB_NO_COL_MAX_SWITCH], *imagBuffer_fx[CLDFB_NO_COL_MAX_SWITCH]; + Word32 realBufferTmp_fx[CLDFB_NO_COL_MAX_SWITCH][CLDFB_NO_CHANNELS_MAX], imagBufferTmp_fx[CLDFB_NO_COL_MAX_SWITCH][CLDFB_NO_CHANNELS_MAX]; + Word32 syn_Overl_fx[320]; + Word32 fer_samples_fx[960]; + Copy_Scale_sig_16_32_DEPREC( st->hTcxDec->syn_Overl, syn_Overl_fx, 320, 15 ); + Copy_Scale_sig_16_32_DEPREC( st->hHQ_core->fer_samples_fx, fer_samples_fx, 960, 15 ); + + + FOR( i = 0; i < CLDFB_NO_COL_MAX_SWITCH; i++ ) + { + set32_fx( realBufferTmp_fx[i], 0, CLDFB_NO_CHANNELS_MAX ); + set32_fx( imagBufferTmp_fx[i], 0, CLDFB_NO_CHANNELS_MAX ); + realBuffer_fx[i] = realBufferTmp_fx[i]; + imagBuffer_fx[i] = imagBufferTmp_fx[i]; + } + + /* CLDFB analysis of the synthesis at internal sampling rate */ + IF( NE_32( ( error = cldfb_save_memory_ivas_fx( st->cldfbAna ) ), IVAS_ERR_OK ) ) + { + return error; + } + + cldfbAnalysis_ivas_fx( syn_Overl_fx, realBuffer_fx, imagBuffer_fx, delay_comp, st->cldfbAna ); + cldfb_restore_memory_ivas_fx( st->cldfbAna ); /*Assuming Q10*/ + + /* CLDFB synthesis of the combined signal */ + IF( NE_32( ( error = cldfb_save_memory_ivas_fx( st->cldfbSyn ) ), IVAS_ERR_OK ) ) + { + return error; + } + + cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, fer_samples_fx, delay_comp, st->cldfbSyn ); + cldfb_restore_memory_ivas_fx( st->cldfbSyn ); + Copy_Scale_sig_32_16( syn_Overl_fx, st->hTcxDec->syn_Overl, 320, 15 ); + Copy_Scale_sig_32_16( fer_samples_fx, st->hHQ_core->fer_samples_fx, 960, 9 ); + } + + test(); + test(); + IF( !st->last_con_tcx && ( st->last_core_bfi == ACELP_CORE ) && EQ_16( st->core, HQ_CORE ) ) + { + lerp( st->hTcxDec->syn_Overl, st->hHQ_core->fer_samples_fx + delay_comp, shr( output_frame, 1 ), shr( st->last_L_frame, 1 ) ); + /*Set to zero the remaining part*/ + set16_fx( st->hHQ_core->fer_samples_fx + delay_comp + output_frame / 2, 0, sub( shr( output_frame, 1 ), delay_comp ) ); + } + } + + st->use_acelp_preq = 0; + st->reset_mem_AR = 0; + move16(); + move16(); + } + + /*FEC*/ + IF( LE_16( st->L_frame, L_FRAME16k ) ) + { + test(); + IF( LE_16( st->last_L_frame, L_FRAME16k ) && NE_16( st->core, HQ_CORE ) ) + { + IF( NE_16( st->L_frame, st->last_L_frame ) ) + { + IF( GT_16( st->L_frame, st->last_L_frame ) ) + { + oldLenClasBuff = mult_r( L_SYN_MEM_CLAS_ESTIM, div_s( st->last_L_frame, st->L_frame ) ); + newLenClasBuff = L_SYN_MEM_CLAS_ESTIM; + move16(); + } + ELSE + { + oldLenClasBuff = L_SYN_MEM_CLAS_ESTIM; + move16(); + newLenClasBuff = mult_r( L_SYN_MEM_CLAS_ESTIM, div_s( st->L_frame, st->last_L_frame ) ); + } + lerp( &st->mem_syn_clas_estim_fx[L_SYN_MEM_CLAS_ESTIM - oldLenClasBuff], &st->mem_syn_clas_estim_fx[L_SYN_MEM_CLAS_ESTIM - newLenClasBuff], newLenClasBuff, oldLenClasBuff ); + } + } + ELSE + { + set16_fx( st->mem_syn_clas_estim_fx, 0, L_SYN_MEM_CLAS_ESTIM ); + } + } + + /* Here we only handle cases where last_ppp and last_nelp not updated when coming from CodecB or other cores + within ACELP_CORE if switching from another bitarate to vbr, last_ppp and last_nelp is always updated in the previous frame */ + test(); + test(); + IF( ( st->core == ACELP_CORE ) && ( ( st->last_core != ACELP_CORE ) || EQ_16( st->last_codec_mode, MODE2 ) ) ) + { + st->last_ppp_mode_dec = 0; + st->last_nelp_mode_dec = 0; + move16(); + move16(); + } + + /* Handle state reset of stat_noise_uv_mod memory */ + test(); + test(); + test(); + IF( ( st->core == ACELP_CORE ) && ( ( st->last_core != ACELP_CORE ) || EQ_16( st->last_codec_mode, MODE2 ) || LE_32( st->last_total_brate, PPP_NELP_2k80 ) ) ) + { + st->act_count = 3; + st->uv_count = 0; + move16(); + move16(); + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( ( ( st->core == ACELP_CORE ) || EQ_16( st->core, AMR_WB_CORE ) ) && EQ_16( st->last_core, HQ_CORE ) ) || ( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_16( last_element_mode, IVAS_CPE_DFT ) ) ) && EQ_16( nchan_out, 2 ) && + NE_32( st->core_brate, SID_2k40 ) && ( st->core_brate != FRAME_NO_DATA ) && ( ( last_core_brate_st0 == FRAME_NO_DATA ) || EQ_32( last_core_brate_st0, SID_2k40 ) ) ) ) + { + test(); + if ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + st->hPFstat->reset = 1; + move16(); + } + + IF( EQ_16( st->L_frame, L_FRAME16k ) ) + { + Copy( TRWB2_Ave_fx, st->lsf_old_fx, M ); /* init of LSP */ + Copy( TRWB2_Ave_fx, st->lsfoldbfi1_fx, M ); + Copy( TRWB2_Ave_fx, st->lsfoldbfi0_fx, M ); + Copy( TRWB2_Ave_fx, st->lsf_adaptive_mean_fx, M ); + lsf2lsp_fx( st->lsf_old_fx, st->lsp_old_fx, M, INT_FS_16k ); + } + ELSE + { + Copy( TRWB_Ave_fx, st->lsf_old_fx, M ); /* init of LSP */ + Copy( TRWB_Ave_fx, st->lsfoldbfi1_fx, M ); + Copy( TRWB_Ave_fx, st->lsfoldbfi0_fx, M ); + Copy( TRWB_Ave_fx, st->lsf_adaptive_mean_fx, M ); + lsf2lsp_fx( st->lsf_old_fx, st->lsp_old_fx, M, INT_FS_12k8 ); + } + + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) && EQ_16( nchan_out, 2 ) && GT_32( st->core_brate, SID_2k40 ) && ( ( last_core_brate_st0 == FRAME_NO_DATA ) || EQ_32( last_core_brate_st0, SID_2k40 ) ) && st->hTcxDec != NULL ) + { + /* Last frame was Stereo CNG and the synthesis memory is outdated -- reset */ + set16_fx( st->hTcxDec->old_syn_Overl, 0, L_FRAME32k / 2 ); + set16_fx( st->hFdCngDec->hFdCngCom->olapBufferAna_fx, 0, FFTLEN ); + set16_fx( st->agc_mem_fx, 0, 2 ); + } + st->mem_deemph_fx = 0; + move16(); + IF( !st->last_con_tcx ) + { + set16_fx( st->mem_syn2_fx, 0, M ); + } + set16_fx( st->mem_syn1_fx, 0, M ); + if ( st->hBWE_TD != NULL ) + { + st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + move32(); + } + + /* Reset ACELP parameters */ + set16_fx( st->mem_MA_fx, 0, M ); + + IF( EQ_32( st->sr_core, INT_FS_16k ) ) + { + Copy( GEWB2_Ave_fx, st->mem_AR_fx, M ); + } + ELSE + { + Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); + } + + st->tilt_code_fx = 0; + st->gc_threshold_fx = 0; + st->dm_fx.prev_gain_code = 0; + st->dm_fx.prev_state = 0; + move16(); + move32(); + move32(); + move16(); + set16_fx( st->dm_fx.prev_gain_pit, 0, 6 ); + + st->last_coder_type = GENERIC; + move16(); + + fer_energy_fx( output_frame, UNVOICED_CLAS, st->previoussynth_fx_32, 0, -1, &st->enr_old_fx, 1 ); /*Q-0*/ + st->lp_gainp_fx = 0; + move16(); + st->lp_gainc_fx = extract_h( Sqrt32( st->lp_ener_fx, &exp ) ); /*Q=15-exp*/ + move16(); + st->lp_gainc_fx = shr( st->lp_gainc_fx, sub( 12, exp ) ); /*Q3*/ + move16(); + + st->last_voice_factor_fx = 0; + st->Last_GSC_noisy_speech_flag = 0; + move16(); + move16(); + + /* reset CLDFB memories */ + cldfb_reset_memory_fx( st->cldfbAna ); + cldfb_reset_memory_fx( st->cldfbBPF ); + cldfb_reset_memory_fx( st->cldfbSyn ); + + /* reset TBE memories */ + test(); + test(); + IF( !st->last_con_tcx && !( ( EQ_16( st->last_core, HQ_CORE ) ) && ( st->element_mode > EVS_MONO ) ) ) + { + set16_fx( st->old_exc_fx, 0, L_EXC_MEM_DEC ); + } + ELSE IF( LT_16( st->L_frame, L_FRAME16k ) ) + { + /* resample from 16kHz to 12.8kHZ */ + synth_mem_updt2( st->L_frame, L_FRAME16k, st->old_exc_fx, st->mem_syn_r, st->mem_syn2_fx, NULL, DEC ); + } + + IF( st->hBWE_TD != NULL ) + { + set16_fx( st->hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); + } + + test(); + IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) + { + hf_synth_reset_fx( st->hBWE_zero ); +#ifdef MSAN_FIX + set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); +#endif + } + + IF( st->hBWE_FD != NULL ) + { + set16_fx( st->hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); + } + } + + test(); + test(); + test(); + IF( ( ( st->core == ACELP_CORE ) || EQ_16( st->core, AMR_WB_CORE ) ) && ( EQ_16( st->last_core, TCX_20_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) ) ) + { + IF( st->hBWE_TD != NULL ) + { + st->hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + move32(); + set16_fx( st->hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); + } + + st->tilt_code_fx = 0; + st->gc_threshold_fx = 0; + st->dm_fx.prev_gain_code = 0; + st->dm_fx.prev_state = 0; + move16(); + move32(); + move32(); + move16(); + set16_fx( st->dm_fx.prev_gain_pit, 0, 6 ); + st->last_coder_type = GENERIC; + move16(); + fer_energy_fx( output_frame, UNVOICED_CLAS, st->previoussynth_fx_32, 0, -1, &st->enr_old_fx, 1 ); /*Q-0*/ + + st->lp_gainp_fx = 0; + move16(); + st->lp_gainc_fx = extract_h( Sqrt32( st->lp_ener_fx, &exp ) ); /*Q=15-exp*/ + move16(); + st->lp_gainc_fx = shr( st->lp_gainc_fx, sub( 12, exp ) ); /*Q3*/ + move16(); + + st->last_voice_factor_fx = 0; + st->Last_GSC_noisy_speech_flag = 0; + move16(); + move16(); + + test(); + IF( GT_32( st->output_Fs, 16000 ) && st->hBWE_zero != NULL ) + { + hf_synth_reset_fx( st->hBWE_zero ); +#ifdef MSAN_FIX + set16_fx( st->hBWE_zero->mem_hp400_fx, 0, 6 ); +#endif + } + + IF( st->hBWE_FD != NULL ) + { + set16_fx( st->hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); + } + + test(); + test(); + test(); + IF( EQ_16( nchan_out, 1 ) && EQ_16( st->element_mode, IVAS_CPE_DFT ) && LE_32( st->element_brate, IVAS_24k4 ) && GT_32( last_element_brate, IVAS_24k4 ) ) + { + /* update cldbf state with previous frame TCX synthesis when going from a bitrate with residual coding to a bitrate without it */ + Word16 offset; + offset = sub( st->cldfbAna->p_filter_length, st->cldfbAna->no_channels ); + Word32 *old_synthFB_fx; + IF( ( old_synthFB_fx = (Word32 *) malloc( st->hTcxDec->old_synth_lenFB * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for old_synth_lenFB (32 bit) \n" ) ); + } +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( st->hTcxDec->old_synthFB_fx, old_synthFB_fx, st->hTcxDec->old_synth_lenFB, sub( Q10, Q_old_synthFB ) ); // Q10 +#else + Copy_Scale_sig_16_32_DEPREC( st->hTcxDec->old_synthFB_fx, old_synthFB_fx, st->hTcxDec->old_synth_lenFB, sub( Q10, Q_old_synthFB ) ); // Q10 +#endif + Copy32( old_synthFB_fx + st->hTcxDec->old_synth_lenFB - offset, st->cldfbAna->cldfb_state_fx, offset ); + st->cldfbAna->Q_cldfb_state = Q10; + move16(); + IF( old_synthFB_fx ) + free( old_synthFB_fx ); + } + } + + test(); + test(); + test(); + test(); + IF( EQ_16( st->core, HQ_CORE ) && ( ( st->last_core == ACELP_CORE ) || EQ_16( st->last_core, AMR_WB_CORE ) || ( ( ( st->element_mode != EVS_MONO ) ) && ( NE_16( st->last_core, HQ_CORE ) ) ) ) ) + { + set32_fx( st->hHQ_core->prev_env_fx, 0, SFM_N_WB ); + set32_fx( st->hHQ_core->prev_normq_fx, 0, SFM_N_WB ); + + set32_fx( st->hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); + set16_fx( st->hHQ_core->last_env_fx, 0, BANDS_MAX ); + st->hHQ_core->last_max_pos_pulse = 0; + move16(); + + set16_fx( st->hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); + st->hHQ_core->prev_frm_hfe2 = 0; + st->hHQ_core->prev_stab_hfe2 = 0; + move16(); + move16(); + IF( GT_32( st->output_Fs, 16000 ) ) + { + set32_fx( st->hHQ_core->prev_coeff_out_fx, 0, L_HQ_WB_BWE ); + } + + IF( st->element_mode != EVS_MONO ) + { + /* Estimate mem_env_delta to reinit env_stab */ + tmp_fx = L_max( 0, L_add( ENV_STAB_EST1_FX, L_add( Mult_32_16( st->stab_fac_smooth_lt_fx, ENV_STAB_EST2_FX ), Mult_32_16( st->log_energy_diff_lt_fx, ENV_STAB_EST3_FX ) ) ) ); /*Q12*/ + + st->hHQ_core->mem_env_delta = extract_l( L_min( MAX16B, tmp_fx ) ); /* Convert to Q12 and handle saturation */ + move16(); + test(); + IF( NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) + { + set16_fx( st->hHQ_core->old_out_fx, 0, output_frame ); + set32_fx( st->hHQ_core->old_outLB_fx, 0, L_FRAME16k ); + set16_fx( st->hHQ_core->old_out_LB_fx, 0, L_FRAME16k ); + } + + st->hHQ_core->no_att_hangover = 0; + move16(); + st->hHQ_core->energy_lt_fx = 2457600; /*300.0f Q13*/ + move32(); + set16_fx( st->hHQ_core->old_is_transient, 0, 3 ); + set16_fx( st->hHQ_core->prev_noise_level_fx, 0, 2 ); + st->hHQ_core->prev_R = 0; + move16(); + set16_fx( st->hHQ_core->mem_norm + 1, 39, SFM_N_ENV_STAB - 1 ); + st->hHQ_core->prev_hqswb_clas = HQ_NORMAL; + st->hHQ_core->prev_ni_ratio_fx = 16384; /*Q15*/ + move16(); + move16(); + set16_fx( st->hHQ_core->prev_En_sb_fx, 0, NB_SWB_SUBBANDS ); + } + ELSE + { + set16_fx( st->hHQ_core->old_out_fx, 0, output_frame ); + set32_fx( st->hHQ_core->old_outLB_fx, 0, L_FRAME16k ); + } + } + + /* handle switching cases where preecho_sb was not called in the last frame (memory not up to date) */ + IF( st->hHQ_core != NULL ) + { + st->hHQ_core->pastpre = sub( st->hHQ_core->pastpre, 1 ); + move16(); + IF( st->hHQ_core->pastpre < 0 ) + { + reset_preecho_dec_fx( st->hHQ_core ); + } + } + test(); + IF( st->core_brate == FRAME_NO_DATA ) + { + st->VAD = 0; + st->m_frame_type = ZERO_FRAME; + } + ELSE IF( EQ_32( st->core_brate, SID_2k40 ) || EQ_32( st->core_brate, SID_1k75 ) ) + { + st->VAD = 0; + st->m_frame_type = SID_FRAME; + } + ELSE + { + st->VAD = 1; + st->m_frame_type = ACTIVE_FRAME; + } + + move16(); + move16(); + /*switch on CNA on active frames*/ + IF( ( st->element_mode == EVS_MONO ) ) /* for IVAS modes, st->flag_cna is set earlier */ + { + test(); + test(); + test(); + test(); + test(); + test(); + IF( st->VAD && ( ( NE_16( st->core, AMR_WB_CORE ) && LE_32( st->total_brate, CNA_MAX_BRATE ) ) || ( EQ_16( st->core, AMR_WB_CORE ) && LE_32( st->total_brate, ACELP_8k85 ) ) ) ) + { + st->flag_cna = 1; + move16(); + } + ELSE IF( st->VAD || ( EQ_16( st->cng_type, FD_CNG ) && EQ_16( st->L_frame, L_FRAME16k ) ) ) + { + st->flag_cna = 0; + move16(); + } + } + + if ( EQ_16( st->core, AMR_WB_CORE ) ) + { + st->cng_type = LP_CNG; + move16(); + } + + /* Reconfigure CNG */ + test(); + test(); + test(); + test(); + IF( st->hFdCngDec && ( NE_16( st->last_L_frame, st->L_frame ) || NE_16( st->hFdCngDec->hFdCngCom->frameSize, st->L_frame ) || ( st->ini_frame == 0 ) || NE_16( st->bwidth, st->last_bwidth ) ) ) + { + /* || st->last_core == AMR_WB_CORE || st->last_codec_mode == MODE2)){*/ + IF( NE_16( st->core, AMR_WB_CORE ) ) + { + test(); + IF( EQ_16( st->rf_flag, 1 ) && EQ_32( st->total_brate, ACELP_13k20 ) ) + { + configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, ACELP_9k60, st->L_frame, st->last_L_frame, st->element_mode ); + } + ELSE + { + configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, st->total_brate, st->L_frame, st->last_L_frame, st->element_mode ); + } + } + ELSE + { + configureFdCngDec_ivas_fx( st->hFdCngDec, WB, ACELP_8k00, st->L_frame, st->last_L_frame, st->element_mode ); + + if ( st->VAD ) + { + st->hFdCngDec->hFdCngCom->CngBitrate = st->total_brate; + move32(); + } + } + test(); + test(); + IF( NE_16( st->last_L_frame, st->L_frame ) && LE_16( st->L_frame, L_FRAME16k ) && LE_16( st->last_L_frame, L_FRAME16k ) ) + { + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) ) + { + lerp( st->hFdCngDec->hFdCngCom->olapBufferAna_fx + st->last_L_frame, st->hFdCngDec->hFdCngCom->olapBufferAna_fx + st->L_frame, st->L_frame, st->last_L_frame ); + } + + L_lerp_fx( st->hFdCngDec->hFdCngCom->olapBufferSynth2_fx, st->hFdCngDec->hFdCngCom->olapBufferSynth2_fx, shl( st->L_frame, 1 ), shl( st->last_L_frame, 1 ), Q_olapBufferSynth2 ); + + test(); + IF( LE_32( st->total_brate, SID_2k40 ) && LE_32( st->last_total_brate, SID_2k40 ) ) + { + L_lerp_fx( st->hFdCngDec->hFdCngCom->olapBufferSynth_fx, st->hFdCngDec->hFdCngCom->olapBufferSynth_fx, shl( st->L_frame, 1 ), shl( st->last_L_frame, 1 ), Q_olapBufferSynth ); + + IF( EQ_16( st->L_frame, L_FRAME ) ) + { + FOR( i = 0; i < ( st->L_frame * 2 ); i++ ) + { + st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i] = Mult_32_16( st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i], (Word16) 20480 /* 0.6250f in Q15 */ ); + move32(); + } + } + ELSE + { + FOR( i = 0; i < ( st->L_frame * 2 ); i++ ) + { + st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i] = Mult_32_16( L_shl( st->hFdCngDec->hFdCngCom->olapBufferSynth_fx[i], 1 ), (Word16) 26214 /* 1.6f in Q14 */ ); + move32(); + } + } + } + } + } + + return error; +} +/*---------------------------------------------------------------------* + * core_switching_hq_prepare_dec() + * + * Preprocessing in the first HQ frame after ACELP frame + * Modify bit allocation for HQ core by removing ACELP subframe budget + *---------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------* + * bandwidth_switching_detect() + * + * Classification for band-width switching + *---------------------------------------------------------------------*/ + +void bandwidth_switching_detect_ivas_fx( + Decoder_State *st_fx /* i/o: encoder state structure */ +) +{ + test(); + test(); + IF( ( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) && EQ_16( st_fx->idchan, 1 ) ) || EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) + { + /* there is no BWE in TD stereo secondary channel and in MDCT stereo, IGF is part of the core decoding -> no BW switching -> reset BWS counters */ + st_fx->prev_bws_cnt = 0; + st_fx->bws_cnt = 0; + st_fx->bws_cnt1 = 0; + move16(); + move16(); + move16(); + + return; + } + /* update band-width switching counter */ + test(); + test(); + test(); + test(); + IF( GE_16( st_fx->bws_cnt1, N_NS2W_FRAMES ) ) + { + st_fx->bws_cnt1 = 0; + move16(); + } + ELSE IF( GT_32( st_fx->total_brate, ACELP_9k60 ) && LT_32( st_fx->last_core_brate, ACELP_9k60 ) && EQ_16( st_fx->bwidth, SWB ) && EQ_16( st_fx->last_bwidth, WB ) && ( st_fx->last_low_rate_mode == 0 ) ) + { + st_fx->bws_cnt1 = add( st_fx->bws_cnt1, 1 ); + move16(); + } + ELSE IF( st_fx->bws_cnt1 > 0 ) + { + IF( LT_16( st_fx->bwidth, st_fx->last_bwidth ) ) + { + st_fx->bws_cnt = sub( shl( sub( N_NS2W_FRAMES, st_fx->bws_cnt1 ), 1 ), 1 ); + move16(); + } + ELSE + { + st_fx->bws_cnt = 0; + move16(); + } + + IF( LT_16( st_fx->bwidth, st_fx->last_bwidth ) ) + { + st_fx->bws_cnt1 = 0; + move16(); + } + ELSE + { + IF( EQ_16( st_fx->bwidth, SWB ) ) + { + st_fx->bws_cnt1 = add( st_fx->bws_cnt1, 1 ); + move16(); + } + ELSE + { + st_fx->bws_cnt1 = 0; + move16(); + } + } + } + + /* update band-width switching counter */ + test(); + test(); + test(); + IF( GE_16( st_fx->bws_cnt, N_WS2N_FRAMES ) ) + { + st_fx->bws_cnt = 0; + move16(); + } + ELSE IF( LT_32( st_fx->total_brate, ACELP_9k60 ) && GT_32( st_fx->last_core_brate, ACELP_9k60 ) && LT_16( st_fx->bwidth, st_fx->last_bwidth ) && EQ_16( st_fx->bwidth, WB ) ) + { + st_fx->bws_cnt = add( st_fx->bws_cnt, 1 ); + move16(); + } + ELSE IF( st_fx->bws_cnt > 0 ) + { + IF( GT_16( st_fx->bwidth, st_fx->last_bwidth ) ) + { + st_fx->bws_cnt1 = shr( sub( N_WS2N_FRAMES, st_fx->bws_cnt ), 1 ); + move16(); + } + ELSE + { + st_fx->bws_cnt1 = 0; + move16(); + } + + IF( GT_16( st_fx->bwidth, st_fx->last_bwidth ) ) + { + st_fx->bws_cnt = 0; + move16(); + } + ELSE + { + IF( EQ_16( st_fx->bwidth, WB ) ) + { + st_fx->bws_cnt = add( st_fx->bws_cnt, 1 ); + move16(); + } + ELSE + { + st_fx->bws_cnt = 0; + move16(); + } + } + } + + return; +} + + +/*---------------------------------------------------------------------* + * bw_switching_pre_proc() + * + * Band-width switching pre-processing + *---------------------------------------------------------------------*/ +void ivas_bw_switching_pre_proc_fx( + Decoder_State *st, /* i/o: decoder state structure */ + const Word32 last_element_brate, /* i : last element bitrate */ + const Word16 nchan_out /* i : number of output channels */, + Word32 *old_syn_12k8_16k_fx, + Word16 Q, + Word16 Q_audio ) +{ + Word16 i; + Word32 syn_dct_fx[L_FRAME]; + + + Flag Overflow = 0; + move32(); + + IF( st->element_mode > EVS_MONO ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( st->core == ACELP_CORE ) && !( EQ_16( st->bfi, 1 ) && EQ_16( st->con_tcx, 1 ) ) && st->hBWE_FD != NULL && !( LE_32( st->core_brate, SID_2k40 ) && EQ_16( st->element_mode, IVAS_CPE_DFT ) && EQ_16( nchan_out, 2 ) ) && !( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_16( nchan_out, 1 ) && EQ_16( st->idchan, 1 ) && LE_32( last_element_brate, IVAS_SID_5k2 ) ) ) + { + /* Calculate tilt of the ACELP core synthesis - needed in SWB BWE decoding */ + Word16 old_syn_12k8_16k_tmp_16fx[L_FRAME16k]; + Copy_Scale_sig_32_16( old_syn_12k8_16k_fx, old_syn_12k8_16k_tmp_16fx, st->L_frame, sub( -1, Q ) ); + st->tilt_wb_fx = round_fx_sat( L_shl_sat( calc_tilt_bwe_fx( old_syn_12k8_16k_tmp_16fx, -1, st->L_frame ), sub( Q, 8 ) ) ); // Q24+(Q-8) - 16 + move16(); + } + + return; + } + + + test(); + test(); + IF( ( st->core == ACELP_CORE ) && !( EQ_16( st->bfi, 1 ) && EQ_16( st->con_tcx, 1 ) ) ) + { + /*----------------------------------------------------------------------* + * Calculate tilt of the ACELP core synthesis + *----------------------------------------------------------------------*/ + + st->tilt_wb_fx = ivas_calc_tilt_bwe_fx( old_syn_12k8_16k_fx, Q, st->L_frame ); + move16(); + /*-------------------------------------------------------------------------------* + * Calculate frequency energy of 0~3.2kHz and 3.2~6.4kHz the ACELP core synthesis + *-------------------------------------------------------------------------------*/ + edct_fx( old_syn_12k8_16k_fx, syn_dct_fx, L_FRAME, &Q ); + Word64 W_tmp = 0; + move64(); + Word32 tmp; + Word16 shift; + FOR( i = 0; i < L_FRAME / 2; i++ ) + { + W_tmp = W_add( W_tmp, W_shr( W_mult0_32_32( syn_dct_fx[i], syn_dct_fx[i] ), Q ) ); + } + shift = W_norm( W_tmp ); + W_tmp = W_shl( W_tmp, shift ); + tmp = W_extract_h( W_tmp ); + tmp = L_shr( tmp, 8 ); + + tmp = getSqrtWord32( tmp ); + st->enerLL_fx = tmp; + move32(); + st->enerLL_fx_Q = shr( sub( add( Q, shift ), 32 ), 1 ); + move16(); + W_tmp = 0; + move64(); + FOR( ; i < L_FRAME; i++ ) + { + W_tmp = W_add( W_tmp, W_shr( W_mult0_32_32( syn_dct_fx[i], syn_dct_fx[i] ), Q ) ); + } + shift = W_norm( W_tmp ); + W_tmp = W_shl( W_tmp, shift ); + tmp = W_extract_h( W_tmp ); // Q = Q + shift - 32 + tmp = L_shr( tmp, 7 ); // divide by 128 + tmp = getSqrtWord32( tmp ); + st->enerLH_fx = tmp; + move32(); + st->enerLH_fx_Q = shr( sub( add( Q, shift ), 32 ), 1 ); + move16(); + } + ELSE + { + IF( st->hHQ_core->old_is_transient[0] ) + { + Word32 tmp, L_tmp = 0; + move32(); + FOR( i = 0; i < 32; i++ ) + { + L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); + } + tmp = L_shr( L_tmp, 5 ); // divide by 32 + tmp = getSqrtWord32( tmp ); + st->enerLL_fx = tmp; + move32(); + st->enerLL_fx_Q = Q_audio; + move16(); + + L_tmp = 0; + move32(); + FOR( ; i < 64; i++ ) + { + L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); + } + + tmp = L_shr( L_tmp, 5 ); // divide by 32 + tmp = getSqrtWord32( tmp ); + st->enerLH_fx = tmp; + move32(); + st->enerLH_fx_Q = Q_audio; + move16(); + } + ELSE + { + Word32 tmp, L_tmp = 0; + move32(); + FOR( i = 0; i < L_FRAME / 2; i++ ) + { + L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); + } + tmp = L_shr( L_tmp, 5 ); // divide by 32 + tmp = getSqrtWord32( tmp ); + st->enerLL_fx = tmp; + move32(); + st->enerLL_fx_Q = Q_audio; + move16(); + + L_tmp = 0; + move32(); + FOR( ; i < L_FRAME; i++ ) + { + L_tmp = L_mac0_o( L_tmp, st->t_audio_q_fx[i], st->t_audio_q_fx[i], &Overflow ); + } + tmp = L_shr( L_tmp, 5 ); // divide by 32 + tmp = getSqrtWord32( tmp ); + st->enerLL_fx = tmp; + move32(); + st->enerLL_fx_Q = Q_audio; + move16(); + } + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( EQ_16( st->last_bwidth, 0 ) && LE_16( st->extl, SWB_CNG ) ) + { + + st->prev_ener_shb_fx = 0; + move16(); + IF( st->hBWE_FD != NULL ) + { + set16_fx( st->prev_SWB_fenv_fx, 0, SWB_FENV ); + } + } + ELSE IF( ( ( ( st->core == ACELP_CORE ) && ( EQ_16( st->last_core, HQ_CORE ) || EQ_16( st->last_core, TCX_10_CORE ) || EQ_16( st->last_core, TCX_20_CORE ) ) ) || ( EQ_16( st->core, st->last_core ) && NE_16( st->extl, st->last_extl ) ) ) && GE_16( st->last_bwidth, SWB ) ) + { + st->attenu_fx = 3277; // 0.1f in Q15 + move16(); + } + + test(); + test(); + test(); + test(); + test(); + if ( EQ_16( st->last_core, HQ_CORE ) || ( ( st->last_core == ACELP_CORE ) && !( EQ_16( st->last_extl, WB_TBE ) || EQ_16( st->last_extl, SWB_TBE ) || EQ_16( st->last_extl, FB_TBE ) ) && GT_32( st->core_brate, ACELP_8k00 ) ) ) + { + st->prev_fractive = 0; + move16(); + } + + return; +} \ No newline at end of file diff --git a/lib_dec/dec_prm.c b/lib_dec/dec_prm.c deleted file mode 100644 index 7b4567f7a..000000000 --- a/lib_dec/dec_prm.c +++ /dev/null @@ -1,328 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include "cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*-------------------------------------------------------------------* - * getTCXMode_ivas() - * - * get TCX mode - *--------------------------------------------------------------------*/ -void getTCXMode_ivas_fx( - Decoder_State *st, /* i/o: decoder memory state */ - Decoder_State *st0, /* i : bitstream */ - const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -) -{ - UWord16 ind; - - IF( st->tcxonly ) - { - /* get core */ - ind = get_next_indice_fx( st0, 1 ); /* Store decoder memory of last_core */ - st->core = add( ind, TCX_20_CORE ); - move16(); - /* get class */ - ind = get_next_indice_fx( st0, 2 ); - - st->clas_dec = ONSET; - move16(); - IF( ind == 0 ) - { - st->clas_dec = UNVOICED_CLAS; - move16(); - } - ELSE IF( EQ_16( ind, 1 ) ) - { - IF( GE_16( st->last_good, VOICED_TRANSITION ) ) - { - st->clas_dec = VOICED_TRANSITION; - move16(); - } - ELSE - { - st->clas_dec = UNVOICED_TRANSITION; - move16(); - } - } - ELSE IF( EQ_16( ind, 2 ) ) - { - st->clas_dec = VOICED_CLAS; - move16(); - } - - st->coder_type = INACTIVE; - move16(); - test(); - IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && !MCT_flag ) - { - st->VAD = get_next_indice_fx( st0, 1 ); - move16(); - } - ELSE - { - st->VAD = 0; - move16(); - } - } - ELSE - { - IF( EQ_16( st->mdct_sw, MODE1 ) ) - { - /* 2 bits instead of 3 as TCX is already signaled */ - st->core = TCX_20_CORE; - move16(); - st->hTcxCfg->coder_type = get_next_indice_fx( st0, 2 ); - move16(); - st->coder_type = st->hTcxCfg->coder_type; - move16(); - } - ELSE - { - IF( EQ_16( st->mdct_sw_enable, MODE2 ) ) - { - IF( get_next_indice_1_fx( st0 ) ) - { - ind = get_next_indice_fx( st0, 3 ); - assert( !( ind & 4 ) || !"HQ_CORE encountered in dec_prm_ivas" ); - st->core = TCX_20_CORE; - move16(); - st->hTcxCfg->coder_type = ind; - move16(); - st->coder_type = st->hTcxCfg->coder_type; - move16(); - } - ELSE /* ACELP */ - { - st->core = ACELP_CORE; - move16(); - st->coder_type = get_next_indice_fx( st0, 2 ); - move16(); - } - } - ELSE - { - IF( EQ_16( st->rf_flag, 1 ) ) - { - IF( !st->use_partial_copy ) - { - ind = get_next_indice_fx( st0, 1 ); - IF( ind == 0 ) - { - st->core = ACELP_CORE; - move16(); - } - ELSE - { - st->core = TCX_20_CORE; - move16(); - st->hTcxCfg->coder_type = st->coder_type; - move16(); - } - } - } - ELSE - { - ind = get_next_indice_fx( st, 3 ); - IF( LT_16( ind, ACELP_MODE_MAX ) ) - { - st->core = ACELP_CORE; - move16(); - st->coder_type = ind; - move16(); - } - ELSE - { - st->core = TCX_20_CORE; - move16(); - st->hTcxCfg->coder_type = sub( ind, ACELP_MODE_MAX ); - move16(); - st->coder_type = st->hTcxCfg->coder_type; - move16(); - } - } - } - } - - IF( EQ_16( st->element_mode, EVS_MONO ) ) - { - test(); - IF( st->igf && EQ_16( st->core, ACELP_CORE ) ) - { - st->bits_frame_core = sub( st->bits_frame_core, get_tbe_bits_fx( st->total_brate, st->bwidth, st->rf_flag ) ); - move16(); - } - - IF( st->rf_flag ) - { - st->bits_frame_core = sub( st->bits_frame_core, add( st->rf_target_bits, 1 ) ); /* +1 as flag-bit not considered in rf_target_bits */ - move16(); - } - } - - /* Inactive frame detection on non-DTX mode */ - IF( EQ_16( st->coder_type, INACTIVE ) ) - { - st->VAD = 0; - move16(); - } - ELSE - { - st->VAD = 1; - move16(); - } - } - - /*Core extended mode mapping for correct PLC classification*/ - st->core_ext_mode = st->coder_type; - move16(); - if ( EQ_16( st->coder_type, INACTIVE ) ) - { - st->core_ext_mode = UNVOICED; - move16(); - } - - return; -} - -/*-------------------------------------------------------------------* - * getTCXWindowing_ivas() - * - * get TCX transform type for each subframe - *--------------------------------------------------------------------*/ -void getTCXWindowing_ivas_fx( - const Word16 core, /* i : current core */ - const Word16 last_core, /* i : last frame core */ - const Word16 element_mode, /* i : element mode */ - TCX_CONFIG_HANDLE hTcxCfg, /* i/o: TCX configuration handle */ - Decoder_State *st0 /* i : bitstream */ -) -{ - Word16 overlap_code; - - /* Set the last overlap mode based on the previous and current frame type and coded overlap mode */ - test(); - test(); - test(); - IF( EQ_16( last_core, ACELP_CORE ) || EQ_16( last_core, AMR_WB_CORE ) ) - { - hTcxCfg->tcx_last_overlap_mode = TRANSITION_OVERLAP; - move16(); - } - ELSE IF( EQ_16( core, TCX_10_CORE ) && EQ_16( hTcxCfg->tcx_curr_overlap_mode, ALDO_WINDOW ) ) - { - hTcxCfg->tcx_last_overlap_mode = FULL_OVERLAP; - move16(); - } - ELSE IF( NE_16( core, TCX_10_CORE ) && EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) - { - hTcxCfg->tcx_last_overlap_mode = ALDO_WINDOW; - move16(); - } - ELSE - { - hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode; - move16(); - } - - /* Set the current overlap mode based on the current frame type and coded overlap mode */ - hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; - move16(); - - IF( NE_16( core, ACELP_CORE ) ) - { - overlap_code = 0; - move16(); - IF( get_next_indice_fx( st0, 1 ) ) - { - overlap_code = add( 2, get_next_indice_fx( st0, 1 ) ); - } - - assert( MIN_OVERLAP == 2 && HALF_OVERLAP == 3 ); - hTcxCfg->tcx_curr_overlap_mode = overlap_code; - move16(); - /*TCX10 : always symmetric windows*/ - test(); - test(); - test(); - IF( EQ_16( core, TCX_20_CORE ) && ( overlap_code == 0 ) && NE_16( last_core, ACELP_CORE ) && NE_16( last_core, AMR_WB_CORE ) ) - { - hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; - move16(); - } - } - - test(); - IF( NE_16( element_mode, EVS_MONO ) && EQ_16( core, TCX_10_CORE ) ) - { - /* also read last overlap */ - overlap_code = 0; - move16(); - - IF( get_next_indice_fx( st0, 1 ) ) - { - overlap_code = add( 2, get_next_indice_fx( st0, 1 ) ); - } - - hTcxCfg->tcx_last_overlap_mode = overlap_code; - move16(); - } - - return; -} - -/*-------------------------------------------------------------------* - * getLPCparam_ivas() - * - * get LPC parameters - *--------------------------------------------------------------------*/ - - -/*-----------------------------------------------------------------* - * Function dec_prm_ivas() * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * - * - * SQ is used for TCX modes - * - * decode parameters according to selected mode * - *-----------------------------------------------------------------*/ diff --git a/lib_dec/dec_prm_fx.c b/lib_dec/dec_prm_fx.c index 73edd3b3b..77fd7d421 100644 --- a/lib_dec/dec_prm_fx.c +++ b/lib_dec/dec_prm_fx.c @@ -1742,3 +1742,273 @@ void dec_prm_fx( return; } + + +/*-------------------------------------------------------------------* + * getTCXMode_ivas() + * + * get TCX mode + *--------------------------------------------------------------------*/ +void getTCXMode_ivas_fx( + Decoder_State *st, /* i/o: decoder memory state */ + Decoder_State *st0, /* i : bitstream */ + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ +) +{ + UWord16 ind; + + IF( st->tcxonly ) + { + /* get core */ + ind = get_next_indice_fx( st0, 1 ); /* Store decoder memory of last_core */ + st->core = add( ind, TCX_20_CORE ); + move16(); + /* get class */ + ind = get_next_indice_fx( st0, 2 ); + + st->clas_dec = ONSET; + move16(); + IF( ind == 0 ) + { + st->clas_dec = UNVOICED_CLAS; + move16(); + } + ELSE IF( EQ_16( ind, 1 ) ) + { + IF( GE_16( st->last_good, VOICED_TRANSITION ) ) + { + st->clas_dec = VOICED_TRANSITION; + move16(); + } + ELSE + { + st->clas_dec = UNVOICED_TRANSITION; + move16(); + } + } + ELSE IF( EQ_16( ind, 2 ) ) + { + st->clas_dec = VOICED_CLAS; + move16(); + } + + st->coder_type = INACTIVE; + move16(); + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && !MCT_flag ) + { + st->VAD = get_next_indice_fx( st0, 1 ); + move16(); + } + ELSE + { + st->VAD = 0; + move16(); + } + } + ELSE + { + IF( EQ_16( st->mdct_sw, MODE1 ) ) + { + /* 2 bits instead of 3 as TCX is already signaled */ + st->core = TCX_20_CORE; + move16(); + st->hTcxCfg->coder_type = get_next_indice_fx( st0, 2 ); + move16(); + st->coder_type = st->hTcxCfg->coder_type; + move16(); + } + ELSE + { + IF( EQ_16( st->mdct_sw_enable, MODE2 ) ) + { + IF( get_next_indice_1_fx( st0 ) ) + { + ind = get_next_indice_fx( st0, 3 ); + assert( !( ind & 4 ) || !"HQ_CORE encountered in dec_prm_ivas" ); + st->core = TCX_20_CORE; + move16(); + st->hTcxCfg->coder_type = ind; + move16(); + st->coder_type = st->hTcxCfg->coder_type; + move16(); + } + ELSE /* ACELP */ + { + st->core = ACELP_CORE; + move16(); + st->coder_type = get_next_indice_fx( st0, 2 ); + move16(); + } + } + ELSE + { + IF( EQ_16( st->rf_flag, 1 ) ) + { + IF( !st->use_partial_copy ) + { + ind = get_next_indice_fx( st0, 1 ); + IF( ind == 0 ) + { + st->core = ACELP_CORE; + move16(); + } + ELSE + { + st->core = TCX_20_CORE; + move16(); + st->hTcxCfg->coder_type = st->coder_type; + move16(); + } + } + } + ELSE + { + ind = get_next_indice_fx( st, 3 ); + IF( LT_16( ind, ACELP_MODE_MAX ) ) + { + st->core = ACELP_CORE; + move16(); + st->coder_type = ind; + move16(); + } + ELSE + { + st->core = TCX_20_CORE; + move16(); + st->hTcxCfg->coder_type = sub( ind, ACELP_MODE_MAX ); + move16(); + st->coder_type = st->hTcxCfg->coder_type; + move16(); + } + } + } + } + + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + test(); + IF( st->igf && EQ_16( st->core, ACELP_CORE ) ) + { + st->bits_frame_core = sub( st->bits_frame_core, get_tbe_bits_fx( st->total_brate, st->bwidth, st->rf_flag ) ); + move16(); + } + + IF( st->rf_flag ) + { + st->bits_frame_core = sub( st->bits_frame_core, add( st->rf_target_bits, 1 ) ); /* +1 as flag-bit not considered in rf_target_bits */ + move16(); + } + } + + /* Inactive frame detection on non-DTX mode */ + IF( EQ_16( st->coder_type, INACTIVE ) ) + { + st->VAD = 0; + move16(); + } + ELSE + { + st->VAD = 1; + move16(); + } + } + + /*Core extended mode mapping for correct PLC classification*/ + st->core_ext_mode = st->coder_type; + move16(); + if ( EQ_16( st->coder_type, INACTIVE ) ) + { + st->core_ext_mode = UNVOICED; + move16(); + } + + return; +} + +/*-------------------------------------------------------------------* + * getTCXWindowing_ivas() + * + * get TCX transform type for each subframe + *--------------------------------------------------------------------*/ +void getTCXWindowing_ivas_fx( + const Word16 core, /* i : current core */ + const Word16 last_core, /* i : last frame core */ + const Word16 element_mode, /* i : element mode */ + TCX_CONFIG_HANDLE hTcxCfg, /* i/o: TCX configuration handle */ + Decoder_State *st0 /* i : bitstream */ +) +{ + Word16 overlap_code; + + /* Set the last overlap mode based on the previous and current frame type and coded overlap mode */ + test(); + test(); + test(); + IF( EQ_16( last_core, ACELP_CORE ) || EQ_16( last_core, AMR_WB_CORE ) ) + { + hTcxCfg->tcx_last_overlap_mode = TRANSITION_OVERLAP; + move16(); + } + ELSE IF( EQ_16( core, TCX_10_CORE ) && EQ_16( hTcxCfg->tcx_curr_overlap_mode, ALDO_WINDOW ) ) + { + hTcxCfg->tcx_last_overlap_mode = FULL_OVERLAP; + move16(); + } + ELSE IF( NE_16( core, TCX_10_CORE ) && EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) + { + hTcxCfg->tcx_last_overlap_mode = ALDO_WINDOW; + move16(); + } + ELSE + { + hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode; + move16(); + } + + /* Set the current overlap mode based on the current frame type and coded overlap mode */ + hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; + move16(); + + IF( NE_16( core, ACELP_CORE ) ) + { + overlap_code = 0; + move16(); + IF( get_next_indice_fx( st0, 1 ) ) + { + overlap_code = add( 2, get_next_indice_fx( st0, 1 ) ); + } + + assert( MIN_OVERLAP == 2 && HALF_OVERLAP == 3 ); + hTcxCfg->tcx_curr_overlap_mode = overlap_code; + move16(); + /*TCX10 : always symmetric windows*/ + test(); + test(); + test(); + IF( EQ_16( core, TCX_20_CORE ) && ( overlap_code == 0 ) && NE_16( last_core, ACELP_CORE ) && NE_16( last_core, AMR_WB_CORE ) ) + { + hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; + move16(); + } + } + + test(); + IF( NE_16( element_mode, EVS_MONO ) && EQ_16( core, TCX_10_CORE ) ) + { + /* also read last overlap */ + overlap_code = 0; + move16(); + + IF( get_next_indice_fx( st0, 1 ) ) + { + overlap_code = add( 2, get_next_indice_fx( st0, 1 ) ); + } + + hTcxCfg->tcx_last_overlap_mode = overlap_code; + move16(); + } + + return; +} + diff --git a/lib_dec/dec_tcx.c b/lib_dec/dec_tcx.c deleted file mode 100644 index aca84d9d9..000000000 --- a/lib_dec/dec_tcx.c +++ /dev/null @@ -1,508 +0,0 @@ - -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "prot.h" -#include "ivas_prot.h" -#include "prot_fx.h" -#include -#include "options.h" -#include -#include "stat_com.h" -#include "cnst.h" -#include "wmc_auto.h" -#include "ivas_rom_com.h" -#include "ivas_prot_fx.h" -#include "debug.h" - -/*-------------------------------------------------------------------* - * decoder_tcx_post() - * - * - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * decoder_tcx_tns() - * - * TCX: TNS application - *-------------------------------------------------------------------*/ - -void decoder_tcx_tns_fx( - Decoder_State *st, /* i/o: coder memory state */ - const Word16 L_frame_glob, /* i : frame length */ - const Word16 L_spec, - const Word16 L_frame, - const Word16 L_frameTCX, - Word32 x_fx[N_MAX], // Qx - const Word16 fUseTns, /* i : flag that is set if TNS data is present */ - STnsData *tnsData, - const Word16 bfi, /* i : Bad frame indicator */ - const Word16 frame_cnt, /* i : frame counter in the super frame */ - const Word16 whitenedDomain, - Word16 *length ) -{ - Word16 index, isTCX5, L, tmp; - TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg; - - index = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */ - move16(); - - isTCX5 = 0; - move16(); - L = L_frameTCX; - move16(); - tmp = L; - move16(); - - test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) ) - { - test(); - test(); - IF( NE_16( frame_cnt, 0 ) && EQ_16( bfi, 0 ) && NE_16( st->last_core, ACELP_CORE ) ) - { - /* fix sub-window overlap */ - hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode; - move16(); - } - - test(); - test(); - test(); - IF( ( NE_16( hTcxCfg->fIsTNSAllowed, 0 ) && NE_16( fUseTns, 0 ) && NE_16( bfi, 1 ) ) || GT_16( L_spec, L_frameTCX ) ) - { - L = L_spec; - move16(); - tmp = L; - move16(); - } - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( EQ_16( bfi, 0 ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) || - ( EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) && EQ_16( frame_cnt, 0 ) && EQ_16( index, 0 ) ) ) ) || - ( NE_16( bfi, 0 ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) && - NE_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) ) ) - { - isTCX5 = 1; - move16(); - - tcx5SpectrumDeinterleaving_fx( shr( L, 1 ), x_fx ); - } - } - - /*-----------------------------------------------------------* - * Temporal Noise Shaping Synthesis * - *-----------------------------------------------------------*/ - - - test(); - test(); - test(); - IF( NE_16( hTcxCfg->fIsTNSAllowed, 0 ) && NE_16( fUseTns, 0 ) && NE_16( bfi, 1 ) && EQ_16( tnsData->tnsOnWhitenedSpectra, whitenedDomain ) ) - { - /* Apply TNS to get the reconstructed signal */ - SetTnsConfig( hTcxCfg, L_frame_glob == st->L_frame, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) ); - - test(); - test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) && NE_16( isTCX5, 0 ) ) - { - tcx5TnsGrouping_fx( shr( L, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx ); - } - - ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, tnsData, x_fx, 0 ); - - test(); - test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) && NE_16( isTCX5, 0 ) ) - { - test(); - IF( EQ_16( st->element_mode, EVS_MONO ) || LT_16( L_spec, L_frameTCX ) ) /* todo: this is temporary to maintain EVS BE, this is a bug and should be fixed also for EVS (see issue 13) */ - { - tcx5TnsUngrouping_fx( shr( L_frameTCX, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx, DEC ); - tmp = L_frameTCX; - move16(); - } - ELSE - { - tcx5TnsUngrouping_fx( shr( L, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx, DEC ); - } - } - } - test(); - IF( NE_16( whitenedDomain, 0 ) && NE_16( isTCX5, 0 ) ) - { - tcx5SpectrumInterleaving_fx( shr( L, 1 ), x_fx ); - } - - /* restore index */ - test(); - test(); - test(); - test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) && NE_16( frame_cnt, 0 ) && EQ_16( bfi, 0 ) && NE_16( st->last_core, ACELP_CORE ) ) - { - /* restore sub-window overlap */ - hTcxCfg->tcx_last_overlap_mode = index; - move16(); - } - - if ( length != NULL ) - { - *length = tmp; - move16(); - } - - return; -} - - -void decoder_tcx_imdct_fx( - Decoder_State *st, /* i/o: coder memory state */ - const Word16 L_frame_glob, /* i : frame length */ - const Word16 L_frameTCX_glob, - const Word16 L_spec, - const Word16 tcx_offset, - const Word16 tcx_offsetFB, - const Word16 L_frame, - const Word16 L_frameTCX, - const Word16 left_rect, - Word32 x_fx[N_MAX], // Q(11) - Word16 q_x, - Word16 xn_buf_fx[], // Q(-2) - Word16 q_win, - const UWord16 kernelType, /* i : TCX transform kernel type */ - const Word16 fUseTns, /* i : flag that is set if TNS data is present */ - Word16 synth_fx[], // Q(-2) /* i/o: synth[-M..L_frame] */ - Word16 synthFB_fx[], // Q(-2) - const Word16 bfi, /* i : Bad frame indicator */ - const Word16 frame_cnt, /* i : frame counter in the super frame */ - const Word16 sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ -) -{ - Word16 j, L, overlap, curr_order, startLine, endLine, isTCX5; - Word16 overlapFB; - Word32 x_tmp_fx[L_FRAME_PLUS]; - Word32 xn_bufFB_fx[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX] = { 0 }; - Word16 xn_bufFB_fx_16[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; - Word16 acelp_zir_fx[L_FRAME_MAX / 2]; - Word32 x_itf_fx[N_MAX_TCX - IGF_START_MN]; - Word16 index, proc = 0; - TCX_LTP_DEC_HANDLE hTcxLtpDec = st->hTcxLtpDec; - TCX_DEC_HANDLE hTcxDec = st->hTcxDec; - TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg; - Word16 predictionGain_fx; - Word16 A_itf_fx[ITF_MAX_FILTER_ORDER + 1]; // q_a_itf - Word16 q_a_itf = 15; - Word16 x_e = sub( 31, q_x ); - move16(); - Word16 shift_q = sub( q_x, q_win ); - - /*-----------------------------------------------------------------* - * Initializations - *-----------------------------------------------------------------*/ - - /* Init lengths */ - overlap = hTcxCfg->tcx_mdct_window_length; - move16(); - overlapFB = hTcxCfg->tcx_mdct_window_lengthFB; - move16(); - - index = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */ - move16(); - test(); - test(); - test(); - test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && ( st->tcxonly != 0 ) && ( frame_cnt != 0 ) && ( bfi == 0 ) && ( st->last_core != ACELP_CORE ) ) - { - /* fix sub-window overlap */ - hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode; - move16(); - } - - IF( st->igf != 0 ) - { - proc = st->hIGFDec->flatteningTrigger; - move16(); - - test(); - IF( proc && fUseTns != 0 ) - { - proc = 0; - move16(); - } - - IF( proc ) - { - - startLine = st->hIGFDec->infoIGFStartLine; - move16(); - endLine = st->hIGFDec->infoIGFStopLine; - move16(); - curr_order = 0; - move16(); - predictionGain_fx = 0; - move16(); - L = L_frameTCX; - move16(); - isTCX5 = 0; - move16(); - - /* interleave again for ITF */ - test(); - IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly ) - { - test(); - test(); - test(); - IF( ( hTcxCfg->fIsTNSAllowed && ( fUseTns != 0 ) && NE_16( bfi, 1 ) ) || GT_16( L_spec, L_frameTCX ) ) - { - L = L_spec; - move16(); - } - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( ( bfi == 0 ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) || - ( ( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( frame_cnt == 0 ) && ( index == 0 ) ) ) ) || - ( ( bfi != 0 ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) && - ( hTcxCfg->tcx_curr_overlap_mode != FULL_OVERLAP ) ) ) ) - { - isTCX5 = 1; - move16(); - - tcx5SpectrumInterleaving_fx( shr( L, 1 ), x_fx ); - } - } - - FOR( j = startLine; j < endLine; j++ ) - { - IF( EQ_16( st->hIGFDec->flag_sparse[j - IGF_START_MN], 2 ) ) - { - x_itf_fx[j - IGF_START_MN] = x_fx[j]; // q_x - move32(); - x_fx[j] = st->hIGFDec->virtualSpec_fx[j - IGF_START_MN]; - move32(); - } - } - - ITF_Detect_fx( x_fx + IGF_START_MN, startLine, endLine, 8 /*maxOrder*/, A_itf_fx, &q_a_itf, &predictionGain_fx, &curr_order, shl( x_e, 1 ) ); - - ITF_Apply_fx( x_fx, startLine, endLine, A_itf_fx, q_a_itf, curr_order ); - - FOR( j = startLine; j < endLine; j++ ) - { - IF( EQ_16( st->hIGFDec->flag_sparse[j - IGF_START_MN], 2 ) ) - { - x_fx[j] = x_itf_fx[j - IGF_START_MN]; // q_x - move32(); - } - } - - /* deinterleave */ - IF( NE_16( isTCX5, 0 ) ) - { - tcx5SpectrumDeinterleaving_fx( shr( L, 1 ), x_fx ); - } - } - } - - /*-----------------------------------------------------------* - * Prepare OLA buffer after waveadjustment. * - * Compute inverse MDCT of x[]. * - *-----------------------------------------------------------*/ - - - IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - Word16 copy_len = s_min( L_FRAME48k, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); - set32_fx( x_tmp_fx, 0, L_FRAME_PLUS ); - Copy32( x_fx, x_tmp_fx, copy_len ); // q_x - Copy32( x_fx, xn_bufFB_fx, copy_len ); // q_x - } - ELSE IF( ( st->element_mode == EVS_MONO ) ) - { - Copy32( x_fx, xn_bufFB_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x - } - ELSE - { - Word16 copy_len = s_max( L_spec, s_max( L_frame, L_frameTCX ) ); - Copy32( x_fx, x_tmp_fx, copy_len ); // q_x - Copy32( x_fx, xn_bufFB_fx, copy_len ); // q_x - } - - IF( ( st->igf != 0 ) ) - { - set32_fx( xn_bufFB_fx + st->hIGFDec->infoIGFStartLine, 0, L_frameTCX - st->hIGFDec->infoIGFStartLine ); - } - - test(); - IF( NE_16( st->element_mode, IVAS_CPE_DFT ) && !sba_dirac_stereo_flag ) - { - - IMDCT_ivas_fx( xn_bufFB_fx, q_x, hTcxDec->syn_Overl, hTcxDec->syn_Overl_TDAC, xn_buf_fx, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, - hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, - kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, 0, st, 0, acelp_zir_fx, q_win ); - } - - /* Generate additional comfort noise to mask potential coding artefacts */ - test(); - test(); - test(); - IF( ( st->flag_cna != 0 ) && NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) && ( st->cna_dirac_flag == 0 ) ) - { - generate_masking_noise_mdct_ivas_fx( x_fx, &x_e, st->hFdCngDec->hFdCngCom ); - FOR( Word16 ind = 0; ind < L_frame; ind++ ) - { - x_fx[ind] = L_shr( x_fx[ind], sub( 31, add( x_e, q_x ) ) ); // q_x - } - } - - test(); - IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || ( sba_dirac_stereo_flag != 0 ) ) - { - Copy32( x_fx, xn_bufFB_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x - - IMDCT_ivas_fx( xn_bufFB_fx, q_x, hTcxDec->syn_Overl, hTcxDec->syn_Overl_TDAC, xn_buf_fx, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, - kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, 0, st, 0, acelp_zir_fx, q_win ); - } - - FOR( Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++ ) - { - xn_bufFB_fx_16[ind] = extract_l( L_shr( xn_bufFB_fx[ind], shift_q ) ); // q_x - move16(); - } - - Word16 ratio_e; - Word16 ratio = BASOP_Util_Divide1616_Scale( L_frameTCX_glob, L_frame_glob, &ratio_e ); // Q = 15-ratio_e. * FSCALE_DENOM is (1 << 9) - ratio = shr( ratio, sub( 6, ratio_e ) ); - - IF( st->element_mode != EVS_MONO ) - { - IMDCT_ivas_fx( x_tmp_fx, q_x, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_bufFB_fx_16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, - hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, - kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, ratio, acelp_zir_fx, q_win ); - } - ELSE - { - - IMDCT_ivas_fx( x_fx, q_x, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_bufFB_fx_16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, - kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, ratio, acelp_zir_fx, q_win ); - } - FOR( Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++ ) - { - xn_bufFB_fx[ind] = L_shl( L_deposit_l( xn_bufFB_fx_16[ind] ), shift_q ); // Q_x - } - - IF( ( bfi == 0 ) ) - { - Word16 res_m, res_e = 0; - move16(); - st->second_last_tns_active = st->last_tns_active; - move16(); - st->last_tns_active = hTcxCfg->fIsTNSAllowed & fUseTns; - move16(); - hTcxDec->tcxltp_third_last_pitch = hTcxDec->tcxltp_second_last_pitch; - move32(); - hTcxDec->tcxltp_second_last_pitch = st->old_fpitch; - move32(); - res_m = BASOP_Util_Divide1616_Scale( hTcxLtpDec->tcxltp_pitch_fr, st->pit_res_max, &res_e ); - st->old_fpitch = L_add( L_shl( hTcxLtpDec->tcxltp_pitch_int, 16 ), L_shl( res_m, add( res_e, 1 ) ) ); - - IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) - { - // Using sat as a single instruction shifts and extracts - st->old_fpitch = W_shl_sat_l( W_mult0_32_32( st->old_fpitch, L_frame_glob ), -8 ); // Divide by 256 ==> SHR by 8 - move32(); - } - - IF( GT_16( st->element_mode, EVS_MONO ) ) - { - res_m = BASOP_Util_Divide1616_Scale( L_frameTCX_glob, L_frame_glob, &res_e ); - st->old_fpitchFB = L_shl( Mpy_32_16_1( st->old_fpitch, res_m ), res_e ); - move32(); - } - ELSE - { - res_m = BASOP_Util_Divide1616_Scale( L_frameTCX, L_frame, &res_e ); - st->old_fpitchFB = L_shl( Mpy_32_16_1( st->old_fpitch, res_m ), res_e ); - move32(); - } - } - - /* Update old_syn_overl */ - IF( hTcxCfg->last_aldo == 0 ) - { - Copy( xn_buf_fx + L_frame, hTcxDec->syn_Overl, overlap ); // Q(-2) - FOR( Word16 ind = 0; ind < overlapFB; ind++ ) - { - hTcxDec->syn_OverlFB[ind] = extract_l( L_shr( xn_bufFB_fx[( ind + L_frameTCX )], shift_q ) ); // q_x - } - } - - /* Output */ - Copy( xn_buf_fx + sub( shr( overlap, 1 ), tcx_offset ), synth_fx, L_frame_glob ); // Q(-2) - FOR( Word16 ind = 0; ind < L_frameTCX_glob; ind++ ) - { - synthFB_fx[ind] = extract_l( L_shr( xn_bufFB_fx[( ind + ( ( overlapFB >> 1 ) - tcx_offsetFB ) )], shift_q ) ); // q_x - } - - - return; -} - -/*-------------------------------------------------------------------* - * init_tcx_info() - * - * Initialize lengths for TCX processing, update IGF subframe info - *-------------------------------------------------------------------*/ diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index a0556437d..4d97367ef 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -4856,3 +4856,450 @@ void decoder_tcx_noiseshaping_igf_fx( return; } + + +/*-------------------------------------------------------------------* + * decoder_tcx_tns() + * + * TCX: TNS application + *-------------------------------------------------------------------*/ + +void decoder_tcx_tns_fx( + Decoder_State *st, /* i/o: coder memory state */ + const Word16 L_frame_glob, /* i : frame length */ + const Word16 L_spec, + const Word16 L_frame, + const Word16 L_frameTCX, + Word32 x_fx[N_MAX], // Qx + const Word16 fUseTns, /* i : flag that is set if TNS data is present */ + STnsData *tnsData, + const Word16 bfi, /* i : Bad frame indicator */ + const Word16 frame_cnt, /* i : frame counter in the super frame */ + const Word16 whitenedDomain, + Word16 *length ) +{ + Word16 index, isTCX5, L, tmp; + TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg; + + index = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */ + move16(); + + isTCX5 = 0; + move16(); + L = L_frameTCX; + move16(); + tmp = L; + move16(); + + test(); + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) ) + { + test(); + test(); + IF( NE_16( frame_cnt, 0 ) && EQ_16( bfi, 0 ) && NE_16( st->last_core, ACELP_CORE ) ) + { + /* fix sub-window overlap */ + hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode; + move16(); + } + + test(); + test(); + test(); + IF( ( NE_16( hTcxCfg->fIsTNSAllowed, 0 ) && NE_16( fUseTns, 0 ) && NE_16( bfi, 1 ) ) || GT_16( L_spec, L_frameTCX ) ) + { + L = L_spec; + move16(); + tmp = L; + move16(); + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( EQ_16( bfi, 0 ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) || + ( EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) && EQ_16( frame_cnt, 0 ) && EQ_16( index, 0 ) ) ) ) || + ( NE_16( bfi, 0 ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) && + NE_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) ) ) + { + isTCX5 = 1; + move16(); + + tcx5SpectrumDeinterleaving_fx( shr( L, 1 ), x_fx ); + } + } + + /*-----------------------------------------------------------* + * Temporal Noise Shaping Synthesis * + *-----------------------------------------------------------*/ + + + test(); + test(); + test(); + IF( NE_16( hTcxCfg->fIsTNSAllowed, 0 ) && NE_16( fUseTns, 0 ) && NE_16( bfi, 1 ) && EQ_16( tnsData->tnsOnWhitenedSpectra, whitenedDomain ) ) + { + /* Apply TNS to get the reconstructed signal */ + SetTnsConfig( hTcxCfg, L_frame_glob == st->L_frame, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) ); + + test(); + test(); + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) && NE_16( isTCX5, 0 ) ) + { + tcx5TnsGrouping_fx( shr( L, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx ); + } + + ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, tnsData, x_fx, 0 ); + + test(); + test(); + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) && NE_16( isTCX5, 0 ) ) + { + test(); + IF( EQ_16( st->element_mode, EVS_MONO ) || LT_16( L_spec, L_frameTCX ) ) /* todo: this is temporary to maintain EVS BE, this is a bug and should be fixed also for EVS (see issue 13) */ + { + tcx5TnsUngrouping_fx( shr( L_frameTCX, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx, DEC ); + tmp = L_frameTCX; + move16(); + } + ELSE + { + tcx5TnsUngrouping_fx( shr( L, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx, DEC ); + } + } + } + test(); + IF( NE_16( whitenedDomain, 0 ) && NE_16( isTCX5, 0 ) ) + { + tcx5SpectrumInterleaving_fx( shr( L, 1 ), x_fx ); + } + + /* restore index */ + test(); + test(); + test(); + test(); + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) && NE_16( frame_cnt, 0 ) && EQ_16( bfi, 0 ) && NE_16( st->last_core, ACELP_CORE ) ) + { + /* restore sub-window overlap */ + hTcxCfg->tcx_last_overlap_mode = index; + move16(); + } + + if ( length != NULL ) + { + *length = tmp; + move16(); + } + + return; +} + + +void decoder_tcx_imdct_fx( + Decoder_State *st, /* i/o: coder memory state */ + const Word16 L_frame_glob, /* i : frame length */ + const Word16 L_frameTCX_glob, + const Word16 L_spec, + const Word16 tcx_offset, + const Word16 tcx_offsetFB, + const Word16 L_frame, + const Word16 L_frameTCX, + const Word16 left_rect, + Word32 x_fx[N_MAX], // Q(11) + Word16 q_x, + Word16 xn_buf_fx[], // Q(-2) + Word16 q_win, + const UWord16 kernelType, /* i : TCX transform kernel type */ + const Word16 fUseTns, /* i : flag that is set if TNS data is present */ + Word16 synth_fx[], // Q(-2) /* i/o: synth[-M..L_frame] */ + Word16 synthFB_fx[], // Q(-2) + const Word16 bfi, /* i : Bad frame indicator */ + const Word16 frame_cnt, /* i : frame counter in the super frame */ + const Word16 sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ +) +{ + Word16 j, L, overlap, curr_order, startLine, endLine, isTCX5; + Word16 overlapFB; + Word32 x_tmp_fx[L_FRAME_PLUS]; + Word32 xn_bufFB_fx[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX] = { 0 }; + Word16 xn_bufFB_fx_16[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; + Word16 acelp_zir_fx[L_FRAME_MAX / 2]; + Word32 x_itf_fx[N_MAX_TCX - IGF_START_MN]; + Word16 index, proc = 0; + TCX_LTP_DEC_HANDLE hTcxLtpDec = st->hTcxLtpDec; + TCX_DEC_HANDLE hTcxDec = st->hTcxDec; + TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg; + Word16 predictionGain_fx; + Word16 A_itf_fx[ITF_MAX_FILTER_ORDER + 1]; // q_a_itf + Word16 q_a_itf = 15; + Word16 x_e = sub( 31, q_x ); + move16(); + Word16 shift_q = sub( q_x, q_win ); + + /*-----------------------------------------------------------------* + * Initializations + *-----------------------------------------------------------------*/ + + /* Init lengths */ + overlap = hTcxCfg->tcx_mdct_window_length; + move16(); + overlapFB = hTcxCfg->tcx_mdct_window_lengthFB; + move16(); + + index = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */ + move16(); + test(); + test(); + test(); + test(); + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && ( st->tcxonly != 0 ) && ( frame_cnt != 0 ) && ( bfi == 0 ) && ( st->last_core != ACELP_CORE ) ) + { + /* fix sub-window overlap */ + hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode; + move16(); + } + + IF( st->igf != 0 ) + { + proc = st->hIGFDec->flatteningTrigger; + move16(); + + test(); + IF( proc && fUseTns != 0 ) + { + proc = 0; + move16(); + } + + IF( proc ) + { + + startLine = st->hIGFDec->infoIGFStartLine; + move16(); + endLine = st->hIGFDec->infoIGFStopLine; + move16(); + curr_order = 0; + move16(); + predictionGain_fx = 0; + move16(); + L = L_frameTCX; + move16(); + isTCX5 = 0; + move16(); + + /* interleave again for ITF */ + test(); + IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly ) + { + test(); + test(); + test(); + IF( ( hTcxCfg->fIsTNSAllowed && ( fUseTns != 0 ) && NE_16( bfi, 1 ) ) || GT_16( L_spec, L_frameTCX ) ) + { + L = L_spec; + move16(); + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( ( bfi == 0 ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) || + ( ( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( frame_cnt == 0 ) && ( index == 0 ) ) ) ) || + ( ( bfi != 0 ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) && + ( hTcxCfg->tcx_curr_overlap_mode != FULL_OVERLAP ) ) ) ) + { + isTCX5 = 1; + move16(); + + tcx5SpectrumInterleaving_fx( shr( L, 1 ), x_fx ); + } + } + + FOR( j = startLine; j < endLine; j++ ) + { + IF( EQ_16( st->hIGFDec->flag_sparse[j - IGF_START_MN], 2 ) ) + { + x_itf_fx[j - IGF_START_MN] = x_fx[j]; // q_x + move32(); + x_fx[j] = st->hIGFDec->virtualSpec_fx[j - IGF_START_MN]; + move32(); + } + } + + ITF_Detect_fx( x_fx + IGF_START_MN, startLine, endLine, 8 /*maxOrder*/, A_itf_fx, &q_a_itf, &predictionGain_fx, &curr_order, shl( x_e, 1 ) ); + + ITF_Apply_fx( x_fx, startLine, endLine, A_itf_fx, q_a_itf, curr_order ); + + FOR( j = startLine; j < endLine; j++ ) + { + IF( EQ_16( st->hIGFDec->flag_sparse[j - IGF_START_MN], 2 ) ) + { + x_fx[j] = x_itf_fx[j - IGF_START_MN]; // q_x + move32(); + } + } + + /* deinterleave */ + IF( NE_16( isTCX5, 0 ) ) + { + tcx5SpectrumDeinterleaving_fx( shr( L, 1 ), x_fx ); + } + } + } + + /*-----------------------------------------------------------* + * Prepare OLA buffer after waveadjustment. * + * Compute inverse MDCT of x[]. * + *-----------------------------------------------------------*/ + + + IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + Word16 copy_len = s_min( L_FRAME48k, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); + set32_fx( x_tmp_fx, 0, L_FRAME_PLUS ); + Copy32( x_fx, x_tmp_fx, copy_len ); // q_x + Copy32( x_fx, xn_bufFB_fx, copy_len ); // q_x + } + ELSE IF( ( st->element_mode == EVS_MONO ) ) + { + Copy32( x_fx, xn_bufFB_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x + } + ELSE + { + Word16 copy_len = s_max( L_spec, s_max( L_frame, L_frameTCX ) ); + Copy32( x_fx, x_tmp_fx, copy_len ); // q_x + Copy32( x_fx, xn_bufFB_fx, copy_len ); // q_x + } + + IF( ( st->igf != 0 ) ) + { + set32_fx( xn_bufFB_fx + st->hIGFDec->infoIGFStartLine, 0, L_frameTCX - st->hIGFDec->infoIGFStartLine ); + } + + test(); + IF( NE_16( st->element_mode, IVAS_CPE_DFT ) && !sba_dirac_stereo_flag ) + { + + IMDCT_ivas_fx( xn_bufFB_fx, q_x, hTcxDec->syn_Overl, hTcxDec->syn_Overl_TDAC, xn_buf_fx, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, + hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, + kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, 0, st, 0, acelp_zir_fx, q_win ); + } + + /* Generate additional comfort noise to mask potential coding artefacts */ + test(); + test(); + test(); + IF( ( st->flag_cna != 0 ) && NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) && ( st->cna_dirac_flag == 0 ) ) + { + generate_masking_noise_mdct_ivas_fx( x_fx, &x_e, st->hFdCngDec->hFdCngCom ); + FOR( Word16 ind = 0; ind < L_frame; ind++ ) + { + x_fx[ind] = L_shr( x_fx[ind], sub( 31, add( x_e, q_x ) ) ); // q_x + } + } + + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || ( sba_dirac_stereo_flag != 0 ) ) + { + Copy32( x_fx, xn_bufFB_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x + + IMDCT_ivas_fx( xn_bufFB_fx, q_x, hTcxDec->syn_Overl, hTcxDec->syn_Overl_TDAC, xn_buf_fx, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index, + kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, 0, st, 0, acelp_zir_fx, q_win ); + } + + FOR( Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++ ) + { + xn_bufFB_fx_16[ind] = extract_l( L_shr( xn_bufFB_fx[ind], shift_q ) ); // q_x + move16(); + } + + Word16 ratio_e; + Word16 ratio = BASOP_Util_Divide1616_Scale( L_frameTCX_glob, L_frame_glob, &ratio_e ); // Q = 15-ratio_e. * FSCALE_DENOM is (1 << 9) + ratio = shr( ratio, sub( 6, ratio_e ) ); + + IF( st->element_mode != EVS_MONO ) + { + IMDCT_ivas_fx( x_tmp_fx, q_x, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_bufFB_fx_16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, + hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, + kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, ratio, acelp_zir_fx, q_win ); + } + ELSE + { + + IMDCT_ivas_fx( x_fx, q_x, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_bufFB_fx_16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index, + kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, 1, st, ratio, acelp_zir_fx, q_win ); + } + FOR( Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++ ) + { + xn_bufFB_fx[ind] = L_shl( L_deposit_l( xn_bufFB_fx_16[ind] ), shift_q ); // Q_x + } + + IF( ( bfi == 0 ) ) + { + Word16 res_m, res_e = 0; + move16(); + st->second_last_tns_active = st->last_tns_active; + move16(); + st->last_tns_active = hTcxCfg->fIsTNSAllowed & fUseTns; + move16(); + hTcxDec->tcxltp_third_last_pitch = hTcxDec->tcxltp_second_last_pitch; + move32(); + hTcxDec->tcxltp_second_last_pitch = st->old_fpitch; + move32(); + res_m = BASOP_Util_Divide1616_Scale( hTcxLtpDec->tcxltp_pitch_fr, st->pit_res_max, &res_e ); + st->old_fpitch = L_add( L_shl( hTcxLtpDec->tcxltp_pitch_int, 16 ), L_shl( res_m, add( res_e, 1 ) ) ); + + IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + // Using sat as a single instruction shifts and extracts + st->old_fpitch = W_shl_sat_l( W_mult0_32_32( st->old_fpitch, L_frame_glob ), -8 ); // Divide by 256 ==> SHR by 8 + move32(); + } + + IF( GT_16( st->element_mode, EVS_MONO ) ) + { + res_m = BASOP_Util_Divide1616_Scale( L_frameTCX_glob, L_frame_glob, &res_e ); + st->old_fpitchFB = L_shl( Mpy_32_16_1( st->old_fpitch, res_m ), res_e ); + move32(); + } + ELSE + { + res_m = BASOP_Util_Divide1616_Scale( L_frameTCX, L_frame, &res_e ); + st->old_fpitchFB = L_shl( Mpy_32_16_1( st->old_fpitch, res_m ), res_e ); + move32(); + } + } + + /* Update old_syn_overl */ + IF( hTcxCfg->last_aldo == 0 ) + { + Copy( xn_buf_fx + L_frame, hTcxDec->syn_Overl, overlap ); // Q(-2) + FOR( Word16 ind = 0; ind < overlapFB; ind++ ) + { + hTcxDec->syn_OverlFB[ind] = extract_l( L_shr( xn_bufFB_fx[( ind + L_frameTCX )], shift_q ) ); // q_x + } + } + + /* Output */ + Copy( xn_buf_fx + sub( shr( overlap, 1 ), tcx_offset ), synth_fx, L_frame_glob ); // Q(-2) + FOR( Word16 ind = 0; ind < L_frameTCX_glob; ind++ ) + { + synthFB_fx[ind] = extract_l( L_shr( xn_bufFB_fx[( ind + ( ( overlapFB >> 1 ) - tcx_offsetFB ) )], shift_q ) ); // q_x + } + + + return; +} + diff --git a/lib_dec/fd_cng_dec.c b/lib_dec/fd_cng_dec.c deleted file mode 100644 index dd3adb247..000000000 --- a/lib_dec/fd_cng_dec.c +++ /dev/null @@ -1,1393 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "ivas_prot.h" -#include "rom_com.h" -#include "wmc_auto.h" -#include "ivas_prot.h" -#include "ivas_rom_dec.h" -#include "ivas_rom_com_fx.h" -#include "prot_fx.h" -#include "ivas_prot_fx.h" -#include "basop_util.h" -#include "rom_basop_util.h" - -/*------------------------------------------------------------------- - * Local constants - *-------------------------------------------------------------------*/ - -#define DELTA_MASKING_NOISE_Q15 0 -#define CNA_ACT_DN_LARGE_PARTITION 50 /* index of the first larger partition */ -#define FIRST_CNA_NOISE_UPD_FRAMES 5 /* minimum number of CN initialization frames */ -#define LOG_10_BASE_2 1783446566 /* Q29 */ -#define GAIN_Q_OFFSET_IVAS_FX 45 -#define LOG_10_BASE_2_BY_10_Q31 713378606 -#define TWO_BY_THREE_Q31 1431655765 -#define ONE_BY_FRAMES_PER_SEC_Q15 656 -#define NB_LAST_BAND_SCALE_Q31 1717986918 -#define SWB_13k2_LAST_BAND_SCALE_Q31 1717986918 - -/*------------------------------------------------------------------- - * Local fucntions declarations - *-------------------------------------------------------------------*/ - -/*------------------------------------------------------------------- - * createFdCngDec() - * - * Create an instance of type FD_CNG - *-------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------- - * initFdCngDec() - * - * Initialize an instance of type FD_CNG - *-------------------------------------------------------------------*/ -void configureFdCngDec_ivas_fx( - HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: Contains the variables related to the FD-based CNG process */ - const Word16 bwidth, /*Q0*/ - const Word32 total_brate, /*Q0*/ - const Word16 L_frame, /*Q0*/ - const Word16 last_L_frame, /*Q0*/ - const Word16 element_mode /*Q0*/ ) -{ - Word16 j, stopBandFR; - HANDLE_FD_CNG_COM hsCom = hFdCngDec->hFdCngCom; - - hsCom->CngBandwidth = bwidth; /*Q0*/ - move16(); - if ( EQ_16( hsCom->CngBandwidth, FB ) ) - { - hsCom->CngBandwidth = SWB; - move16(); - } - test(); - IF( NE_32( total_brate, FRAME_NO_DATA ) && NE_32( total_brate, SID_2k40 ) ) - { - hsCom->CngBitrate = total_brate; /*Q0*/ - move32(); - } - ELSE IF( EQ_32( hsCom->CngBitrate, -1 ) ) - { - /* set minimum active CBR bitrate IF CngBitrate is uninitialized */ - IF( element_mode > EVS_MONO ) - { - hsCom->CngBitrate = IVAS_13k2; - move32(); - } - ELSE - { - hsCom->CngBitrate = ACELP_7k20; - move32(); - } - } - - /* FD-CNG config for MDCT-Stereo is always the same (since for > 48 kbps only) */ - /* This may need adjustment in the future IF 2TC DTX for some mode uses MDCT-Stereo DTX for lower bitrates too */ - if ( EQ_16( element_mode, IVAS_CPE_MDCT ) ) - { - hsCom->CngBitrate = IVAS_48k; - move32(); - } - hsCom->numSlots = 16; - move32(); - - /* NB configuration */ - IF( EQ_16( bwidth, NB ) ) - { - hsCom->FdCngSetup = FdCngSetup_nb; - hsCom->numCoreBands = 16; - move16(); - hsCom->regularStopBand = 16; - move16(); - } - - /* WB configuration */ - ELSE IF( EQ_16( bwidth, WB ) ) - { - /* FFT 6.4kHz, no CLDFB */ - test(); - test(); - IF( LE_32( hsCom->CngBitrate, ACELP_8k00 ) && EQ_16( L_frame, L_FRAME ) ) - { - hsCom->FdCngSetup = FdCngSetup_wb1; - hsCom->numCoreBands = 16; - move16(); - hsCom->regularStopBand = 16; - move16(); - } - /* FFT 6.4kHz, CLDFB 8.0kHz */ - ELSE IF( LE_32( hsCom->CngBitrate, ACELP_13k20 ) || EQ_16( L_frame, L_FRAME ) ) - { - hsCom->FdCngSetup = FdCngSetup_wb2; - hsCom->numCoreBands = 16; - move16(); - hsCom->regularStopBand = 20; - move16(); - IF( EQ_16( L_frame, L_FRAME16k ) ) - { - hsCom->FdCngSetup = FdCngSetup_wb2; - hsCom->numCoreBands = 20; - move16(); - hsCom->regularStopBand = 20; - move16(); - hsCom->FdCngSetup.fftlen = 640; - move16(); - hsCom->FdCngSetup.stopFFTbin = 256; - move16(); - } - } - /* FFT 8.0kHz, no CLDFB */ - ELSE - { - hsCom->FdCngSetup = FdCngSetup_wb3; - hsCom->numCoreBands = 20; - move16(); - hsCom->regularStopBand = 20; - move16(); - } - } - - /* SWB/FB configuration */ - ELSE - { - /* FFT 6.4kHz, CLDFB 14kHz */ - IF( EQ_16( L_frame, L_FRAME ) ) - { - hsCom->FdCngSetup = FdCngSetup_swb1; - hsCom->numCoreBands = 16; - move16(); - hsCom->regularStopBand = 35; - move16(); - } - /* FFT 8.0kHz, CLDFB 16kHz */ - ELSE - { - hsCom->FdCngSetup = FdCngSetup_swb2; - hsCom->numCoreBands = 20; - move16(); - hsCom->regularStopBand = 40; - move16(); - test(); - if ( EQ_16( last_L_frame, L_FRAME ) && EQ_16( element_mode, IVAS_CPE_DFT ) ) - { - hsCom->regularStopBand = 35; - move16(); - } - } - } - - - hsCom->fftlen = hsCom->FdCngSetup.fftlen; - move16(); - hsCom->stopFFTbin = hsCom->FdCngSetup.stopFFTbin; - move16(); - - /* Configure the SID quantizer and the Comfort Noise Generator */ - - hsCom->startBand = 2; - move16(); - hsCom->stopBand = add( hsCom->FdCngSetup.sidPartitions[( hsCom->FdCngSetup.numPartitions - 1 )], 1 ); /*Q0*/ - initPartitions( hsCom->FdCngSetup.sidPartitions, hsCom->FdCngSetup.numPartitions, hsCom->startBand, hsCom->stopBand, hsCom->part, &hsCom->npart, hsCom->midband, hsCom->psize, hsCom->psize_norm, &hsCom->psize_norm_exp, hsCom->psize_inv, 0 ); - - IF( EQ_16( hsCom->stopFFTbin, 160 ) ) - { - hsCom->nFFTpart = 17; - move16(); - } - ELSE IF( EQ_16( hsCom->stopFFTbin, 256 ) ) - { - hsCom->nFFTpart = 20; - move16(); - } - ELSE - { - hsCom->nFFTpart = 21; - move16(); - } - hsCom->nCLDFBpart = sub( hsCom->npart, hsCom->nFFTpart ); /*Q0*/ - move16(); - FOR( j = 0; j < hsCom->nCLDFBpart; j++ ) - { - hsCom->CLDFBpart[j] = sub( hsCom->part[( j + hsCom->nFFTpart )], sub( hsCom->stopFFTbin, hsCom->startBand ) ); /*Q0*/ - move16(); - hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[( j + hsCom->nFFTpart )]; - move16(); - } - - stopBandFR = 40; //(Word16)floor(1000.f /*Hz*/ / 25.f /*Hz/Bin*/); - move16(); - if ( GT_16( stopBandFR, hsCom->stopFFTbin ) ) - { - stopBandFR = hsCom->stopFFTbin; /*Q0*/ - move16(); - } - - initPartitions( hsCom->FdCngSetup.shapingPartitions, hsCom->FdCngSetup.numShapingPartitions, hsCom->startBand, hsCom->stopFFTbin, hFdCngDec->part_shaping, &hFdCngDec->npart_shaping, hFdCngDec->midband_shaping, hFdCngDec->psize_shaping, hFdCngDec->psize_shaping_norm, &hFdCngDec->psize_shaping_norm_exp, hFdCngDec->psize_inv_shaping, stopBandFR ); - - hFdCngDec->nFFTpart_shaping = hFdCngDec->npart_shaping; /*Q0*/ - move16(); - - BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) ); - BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) ); - - SWITCH( hsCom->fftlen ) - { - case 512: - hsCom->olapWinAna_fx = olapWinAna512_fx; /*Q30*/ - hsCom->fftSineTab_fx = NULL; - hsCom->olapWinSyn_fx = olapWinSyn256_fx; /*Q15*/ - hsCom->fftlenShift = 8; - move16(); - hsCom->fftlenFac = 32767 /*1.0 Q15*/; - move16(); - BREAK; - case 640: - hsCom->olapWinAna_fx = olapWinAna640_fx; /*Q30*/ - hsCom->fftSineTab_fx = fftSineTab640_fx; /*Q15*/ - hsCom->olapWinSyn_fx = olapWinSyn320_fx; /*Q15*/ - hsCom->fftlenShift = 9; - move16(); - hsCom->fftlenFac = 20480 /*0.625 Q15*/; - move16(); - BREAK; - default: - assert( !"Unsupported FFT length for FD-based CNG" ); - BREAK; - } - BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) ); - BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) ); - hsCom->frameSize = shr( hsCom->fftlen, 1 ); - - return; -} - -/*------------------------------------------------------------------- - * deleteFdCngDec() - * - * Delete the instance of type FD_CNG - *-------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------- - * ApplyFdCng() - * - * Apply the CLDFB-based CNG at the decoder - *-------------------------------------------------------------------*/ - -/*------------------------------------------------------------------- - * FdCng_decodeSID() - * - * Decode the FD-CNG bitstream - *-------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------- - * FdCng_decodeSID_ivas_fx() - * - * Decode the FD-CNG bitstream - *-------------------------------------------------------------------*/ - -void FdCng_decodeSID_ivas_fx( - Decoder_State *st /* i/o: decoder state structure */ -) -{ - Word16 N; - Word32 *sidNoiseEst; - Word32 gain; - Word16 i, index; - Word32 v[32]; - Word16 indices[32]; - HANDLE_FD_CNG_COM hFdCngCom; - Word32 *invTrfMatrix_fx; - Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; - Word16 tmp16; - - IF( st->element_mode == EVS_MONO ) - { - tmp16 = GAIN_Q_OFFSET_EVS_FX_Q0; - move16(); - } - ELSE - { - tmp16 = GAIN_Q_OFFSET_IVAS_FX_Q0; - move16(); - } - - const Word16 gain_q_offset = tmp16; /* Q0 */ - move16(); - - invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /*Q31*/ - - hFdCngCom = ( st->hFdCngDec )->hFdCngCom; - - sidNoiseEst = hFdCngCom->sidNoiseEst; /*Q16*/ - - N = hFdCngCom->npart; /*Q0*/ - move16(); - gain = 0; - move32(); - hFdCngCom->sid_frame_counter = add( hFdCngCom->sid_frame_counter, 1 ); - move16(); - - /* Read bitstream */ - FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) - { - indices[i] = get_next_indice_fx( st, bits_37bits[i] ); /*Q0*/ - move16(); - } - - index = get_next_indice_fx( st, 7 ); - - /* MSVQ decoder */ - - IF( st->element_mode != EVS_MONO ) - { - create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); - msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, v, NULL, 7 ); - } - ELSE - { /* Legacy EVS_MONO MSVQ tables */ - msvq_dec_fx( cdk_37bits, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v, NULL, 7 ); - } - - - /* Decode gain */ - // gain = ((float)index - gain_q_offset) / 1.5f; - gain = L_mult0( sub( index, gain_q_offset ), 21845 ); // Q15 - - /* Apply gain and undo log */ - Word16 res_exp[NPART]; - Word16 max_res_exp = 0; - move16(); - FOR( i = 0; i < N; i++ ) - { - sidNoiseEst[i] = BASOP_util_Pow2( Mpy_32_32( L_add( v[i], gain ), LOG_10_BASE_2_BY_10_Q31 ), Q16, &res_exp[i] ); /*Q31 - res_exp[i]*/ - move32(); - if ( LT_16( max_res_exp, res_exp[i] ) ) - { - max_res_exp = res_exp[i]; - move16(); - } - } - - FOR( i = 0; i < N; i++ ) - { - sidNoiseEst[i] = L_shr( sidNoiseEst[i], sub( max_res_exp, res_exp[i] ) ); /*Q31 - max_res_exp*/ - move32(); - } - - hFdCngCom->sidNoiseEstExp = max_res_exp; - move16(); - - /* NB last band energy compensation */ - - IF( hFdCngCom->CngBandwidth == NB ) - { - sidNoiseEst[( N - 1 )] = Mpy_32_16_1( sidNoiseEst[( N - 1 )], NB_LAST_BAND_SCALE ); /*Q31 - max_res_exp*/ - move32(); - } - - test(); - IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) - { - sidNoiseEst[( N - 1 )] = Mpy_32_16_1( sidNoiseEst[( N - 1 )], SWB_13k2_LAST_BAND_SCALE ); /*Q31 - max_res_exp*/ - move32(); - } - - scalebands( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 ); - hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; - move16(); - - lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, st->preemph_fac ); - - return; -} - -/*------------------------------------------------------------------- - * noisy_speech_detection() - * - * - *-------------------------------------------------------------------*/ - -/*------------------------------------------------------------------- - * generate_comfort_noise_dec() - * - * Generate the comfort noise based on the target noise level - *-------------------------------------------------------------------*/ - -/*------------------------------------------------------------------- - * generate_masking_noise() - * - * Generate additional comfort noise (kind of noise filling) - *-------------------------------------------------------------------*/ - -/*------------------------------------------------------------------- - * generate_masking_noise_ivas_fx() - * - * Generate additional comfort noise (kind of noise filling) - *-------------------------------------------------------------------*/ - -void generate_masking_noise_ivas_fx( - Word32 *timeDomainBuffer, /* i/o: time-domain signal Q31 - *exp_out*/ - Word16 *exp_out, /* o : time-domain signal exp */ - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - const Word16 length, /* i : frame size Q0*/ - const Word16 core, /* i : core Q0*/ - const Word16 return_noise, /* i : noise is returned instead of added Q0*/ - const Word16 secondary, /* i : flag to indicate secondary noise generation Q0*/ - const Word16 element_mode, /* i : element mode Q0*/ - STEREO_CNG_DEC_HANDLE hStereoCng, /* i : stereo CNG handle */ - const Word16 nchan_out /* i : number of output channels Q0*/ -) -{ - Word32 *cngNoiseLevel_fx = hFdCngCom->cngNoiseLevel; - Word32 *ptr_level_fx = cngNoiseLevel_fx; - Word32 *fftBuffer_fx = hFdCngCom->fftBuffer; - Word16 i; - Word32 maskingNoise_fx[L_FRAME16k]; - Word32 *ptr_r_fx; - Word32 *ptr_i_fx; - Word16 startBand; - Word16 *seed = &( hFdCngCom->seed ); - Word32 scale_fx; - Word16 shift; - scale_fx = 0x40000000; // 1.0 in Q30 - move32(); - startBand = hFdCngCom->startBand; /*Q0*/ - move16(); - shift = getScaleFactor32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN ); - if ( LT_16( sub( hFdCngCom->cngNoiseLevelExp, shift ), 4 ) ) - { - shift = sub( hFdCngCom->cngNoiseLevelExp, 4 ); /*Q0*/ - } - scale_sig32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, shift ); /*hFdCngCom->cngNoiseLevelExp*/ - hFdCngCom->cngNoiseLevelExp = sub( hFdCngCom->cngNoiseLevelExp, shift ); - move16(); - - /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ - *exp_out = Q15; - move16(); - IF( GT_16( hFdCngCom->likelihood_noisy_speech, DELTA_MASKING_NOISE_Q15 ) ) - { - IF( NE_16( core, AMR_WB_CORE ) ) - { - /* Compute additional CN level */ - FOR( i = 0; i < SIZE_SCALE_TABLE_CN; i++ ) - { - test(); - test(); - if ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_only[i].bwmode ) && - GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateFrom ) && - LT_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateTo ) ) - { - BREAK; - } - } - - scale_fx = L_deposit_h( scaleTable_cn_only[i].scale_ivas ); /* Q30 */ - } - ELSE - { - /* Compute additional CN level */ - FOR( i = 0; i < SIZE_SCALE_TABLE_CN_AMRWB; i++ ) - { - if ( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only_amrwbio[i][0] ) ) - { - BREAK; - } - } - - IF( LT_16( i, SIZE_SCALE_TABLE_CN_AMRWB ) ) - { - scale_fx = L_deposit_h( scaleTable_cn_only_amrwbio[i][1] ); /* Q30 */ - } - ELSE - { - scale_fx = 0; - move32(); - } - } - - /* Exclude clean speech */ - scale_fx = Mpy_32_16_1( scale_fx, hFdCngCom->likelihood_noisy_speech ); // Q30 - - /* Generate Gaussian random noise in real and imaginary parts of the FFT bins - Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */ - IF( startBand == 0 ) - { - rand_gauss_fx( &fftBuffer_fx[0], seed, *exp_out ); // Q15 - ptr_r_fx = fftBuffer_fx + 2; /*Q31 - hFdCngCom->fftBuffer_exp*/ - Word16 exp1; - exp1 = add( hFdCngCom->cngNoiseLevelExp, 1 ); - Word32 mpy1; - mpy1 = Sqrt32( Mpy_32_32( scale_fx, *ptr_level_fx ), &exp1 ); /*Q31 - exp1*/ - mpy1 = L_shl( mpy1, exp1 ); // Q31 - fftBuffer_fx[0] = Mpy_32_32( fftBuffer_fx[0], mpy1 ); /* DC component in FFT */ // Q = Q15 - ptr_level_fx++; - } - ELSE - { - fftBuffer_fx[0] = 0; - move32(); - set32_fx( fftBuffer_fx + 2, 0, shl( sub( startBand, 1 ), 1 ) ); - ptr_r_fx = fftBuffer_fx + shl( startBand, 1 ); /*Q31 - hFdCngCom->fftBuffer_exp*/ - } - ptr_i_fx = ptr_r_fx + 1; - FOR( ; ptr_level_fx < cngNoiseLevel_fx + hFdCngCom->stopFFTbin - startBand; ptr_level_fx++ ) - { - /* Real part in FFT bins */ - rand_gauss_fx( ptr_r_fx, seed, *exp_out ); // Q15 - Word16 exp2; - exp2 = add( hFdCngCom->cngNoiseLevelExp, 1 ); - Word32 mpy2; - mpy2 = Sqrt32( L_shr( Mpy_32_32( scale_fx, *ptr_level_fx ), 1 ), &exp2 ); /*Q31 - exp2*/ - ( *ptr_r_fx ) = L_shl( Mpy_32_32( *ptr_r_fx, mpy2 ), exp2 ); // Q = Q15 - move32(); - ptr_r_fx += 2; - - /* Imaginary part in FFT bins */ - rand_gauss_fx( ptr_i_fx, seed, *exp_out ); // Q15 - ( *ptr_i_fx ) = L_shl( Mpy_32_32( *ptr_i_fx, mpy2 ), exp2 ); // Q = Q15 - ptr_i_fx += 2; - } - - /* Remaining FFT bins are set to zero */ - set32_fx( fftBuffer_fx + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) ); - /* Nyquist frequency is discarded */ - fftBuffer_fx[1] = 0; - move32(); - } - ELSE - { - /* very low level case - update random seeds and reset FFT buffer; don't fully skip SynthesisSTFT_flt(), because of the buffer updates done there... */ - generate_masking_noise_update_seed_fx( hFdCngCom ); - - set32_fx( fftBuffer_fx, 0, hFdCngCom->fftlen ); - } - - /* Perform STFT synthesis */ - IF( secondary ) - { - SynthesisSTFT_fx( fftBuffer_fx, maskingNoise_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->olapWinSyn_fx, 0, hFdCngCom, element_mode, nchan_out ); - } - ELSE - { - SynthesisSTFT_fx( fftBuffer_fx, maskingNoise_fx, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, 0, hFdCngCom, element_mode, nchan_out ); - } - *exp_out = sub( *exp_out, Q9 ); - move16(); - - /* Add some comfort noise on top of decoded signal */ - IF( return_noise ) - { - Copy32( maskingNoise_fx, timeDomainBuffer, s_min( hFdCngCom->frameSize, length ) ); /*Q31 - *exp_out*/ - } - ELSE - { - v_add_fixed( maskingNoise_fx, timeDomainBuffer, timeDomainBuffer, s_min( hFdCngCom->frameSize, length ), 0 ); /*Q31 - *exp_out*/ - } - - return; -} - -/*------------------------------------------------------------------- - * generate_masking_noise_update_seed() - * - * Update seed for scenarios where generate_masking_noise() is - * not called based on signal statistics - *-------------------------------------------------------------------*/ - - -/*------------------------------------------------------------------- - * generate_stereo_masking_noise_fx() - * - * Generate additional comfort noise (kind of noise filling) - *-------------------------------------------------------------------*/ - -void generate_stereo_masking_noise_fx( - Word16 *syn, /* i/o: time-domain signal Q_syn*/ - Word16 Q_syn, - Decoder_State *st, /* i/o: decoder state structure */ - STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i : TD stereo structure */ - const Word16 flag_sec_CNA, /* i : CNA flag for secondary channel Q0*/ - const Word16 fadeOut, /* i : only fade out of previous state Q0*/ - STEREO_CNG_DEC_HANDLE hStereoCng, /* i : Stereo CNG handle */ - const Word16 nchan_out /* i : number of output channels Q0*/ -) -{ - HANDLE_FD_CNG_COM hFdCngCom; - Word32 gamma_fx, scale_fx /*, SP_ratio_fx needs to be integrated*/; - Word32 Np_fx[L_FRAME16k]; - Word32 Ns_fx[L_FRAME16k]; - Word32 N1_fx[L_FRAME16k]; - Word32 N2_fx[L_FRAME16k]; - Word16 N1_fx_exp, N2_fx_exp; - Word16 i; - - IF( st->idchan == 0 ) - { - hFdCngCom = st->hFdCngDec->hFdCngCom; -#ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, Ns_fx, shr( hFdCngCom->frameSize, 1 ), sub( Q6, st->Q_syn ) ); /*Q6*/ -#else - Copy_Scale_sig_16_32_DEPREC( hStereoCng->olapBufferSynth22_fx, Ns_fx, shr( hFdCngCom->frameSize, 1 ), sub( Q6, st->Q_syn ) ); /*Q6*/ -#endif - Copy32( hFdCngCom->olapBufferSynth2_fx, Np_fx, shr( hFdCngCom->frameSize, 1 ) ); /*st->Q_syn*/ - - set32_fx( &Np_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) ); - set32_fx( &Ns_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) ); - - IF( !fadeOut ) - { -#ifdef FIX_ISSUE_1237 - Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->fftlen, sub( Q15, st->Q_syn ) ); /*Q15*/ -#else - Copy_Scale_sig_16_32_DEPREC( hStereoCng->olapBufferSynth22_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->fftlen, sub( Q15, st->Q_syn ) ); /*Q15*/ -#endif - generate_masking_noise_ivas_fx( N1_fx, &N1_fx_exp, hFdCngCom, hFdCngCom->frameSize, 0, 1, 0, st->element_mode, hStereoCng, nchan_out ); // N1_fx Q6 - /* Generate masking noise for secondary channel */ - IF( flag_sec_CNA ) - { - generate_masking_noise_ivas_fx( N2_fx, &N2_fx_exp, hFdCngCom, hFdCngCom->frameSize, 0, 1, 1, st->element_mode, hStereoCng, nchan_out ); // N2_fx Q6 - gamma_fx = L_shr( Mpy_32_32( hStereoCng->c_PS_LT_fx, hStereoCng->c_PS_LT_fx ), 1 ); /*Q30*/ - scale_fx = ONE_IN_Q30; - move32(); - IF( LT_32( gamma_fx, 966367642 /* 0.9 in Q30 */ ) ) - { - Word16 exp_gamma; - exp_gamma = 0; - move16(); - Word16 divisor1; - divisor1 = Inv16( (Word16) L_shr( L_sub( ONE_IN_Q30, gamma_fx ), Q15 ), &exp_gamma ); // Q15-exp_gamma - gamma_fx = L_shl( Mpy_32_16_1( gamma_fx, divisor1 ), exp_gamma ); // Q30 - Word16 exp_gamma1, exp_gamma2, exp_gamma3; - exp_gamma1 = Q1; - exp_gamma2 = Q1; - exp_gamma3 = Q1; - move16(); - move16(); - move16(); - gamma_fx = Sqrt32( L_add( gamma_fx, ONE_IN_Q30 ), &exp_gamma1 ); /*Q31 - exp_gamma1*/ - Word32 temp; - temp = Sqrt32( gamma_fx, &exp_gamma2 ); // Q31-exp_gamma1 - gamma_fx = L_sub( gamma_fx, L_shl( temp, sub( exp_gamma2, exp_gamma1 ) ) ); // Q31-exp_gamma1 - gamma_fx = L_shl( gamma_fx, sub( exp_gamma1, Q1 ) ); // Q30 - Word32 divisor2; - divisor2 = Sqrt32( L_add( ONE_IN_Q30, L_shl( Mpy_32_32( gamma_fx, gamma_fx ), Q1 ) ), &exp_gamma3 ); // Q31 - exp_gamma3 - scale_fx = L_shl( divide3232( ONE_IN_Q30, divisor2 ), add( Q15, exp_gamma3 ) ); // Q30 - } - ELSE - { - gamma_fx = 0; - move16(); - } - - FOR( i = 0; i < 2 * hFdCngCom->frameSize / 4; i++ ) - { - Np_fx[i] = L_add( Np_fx[i], - Mpy_32_32( scale_fx, L_shl( L_add( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ) ); // Q6 - move32(); - Word32 add2; - add2 = Mpy_32_32( scale_fx, L_shl( L_sub( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6 - if ( hStereoCng->c_PS_LT_fx < 0 ) - { - add2 = L_negate( add2 ); /*Q6*/ - } - Ns_fx[i] = L_add( Ns_fx[i], add2 ); /*Q6*/ - move32(); - } - FOR( ; i < hFdCngCom->frameSize; i++ ) - { - Np_fx[i] = Mpy_32_32( scale_fx, L_shl( L_add( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6 - move32(); - Ns_fx[i] = Mpy_32_32( scale_fx, L_shl( L_sub( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6 - move32(); - IF( hStereoCng->c_PS_LT_fx < 0 ) - { - Ns_fx[i] = L_negate( Ns_fx[i] ); - move32(); - } - } - /* Below code to be converted */ - Word32 scale_fx_tmp = Mpy_32_32( scale_fx, L_shl( shr( hFdCngCom->fftlen, 1 ), Q22 ) ); // Q21 - FOR( i = 0; i < shr( hFdCngCom->frameSize, 1 ); i++ ) - { - hFdCngCom->olapBufferSynth2[i] = (Word16) L_shr( Mpy_32_32( scale_fx_tmp, - L_add( L_shr( hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )], Q15 ), - Mpy_32_16_1( gamma_fx, hStereoCng->olapBufferSynth22_fx[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ) ) ), - Q14 ); // Q_olap - move16(); - hStereoCng->olapBufferSynth22_fx[i] = (Word16) L_shr( Mpy_32_32( scale_fx_tmp, - L_sub( L_shr( hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )], Q15 ), - Mpy_32_16_1( gamma_fx, hStereoCng->olapBufferSynth22_fx[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ) ) ), - Q14 ); // Q_olap - move16(); - } - } - ELSE - { - FOR( i = 0; i < shr( hFdCngCom->frameSize, 1 ); i++ ) - { - Np_fx[i] = L_add( Np_fx[i], N1_fx[i] ); // Q6 - move32(); - } - Copy32( &N1_fx[( hFdCngCom->frameSize / 2 )], &Np_fx[( hFdCngCom->frameSize / 2 )], shr( hFdCngCom->frameSize, 1 ) ); /*Q6*/ - scale_fx = L_shl( shr( hFdCngCom->fftlen, 1 ), Q22 ); // Q21 - FOR( i = 0; i < hFdCngCom->frameSize; i++ ) - { - hFdCngCom->olapBufferSynth2[i] = (Word16) L_shr( Mpy_32_16_1( scale_fx, hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ), Q6 ); // Q_olap - move16(); - } - } - - Copy_Scale_sig_32_16( hStereoCng->olapBufferSynth22_32fx, hStereoCng->olapBufferSynth22_fx, hFdCngCom->fftlen, sub( st->Q_syn, 15 ) ); /*st->Q_syn*/ - } - ELSE - { - set16_fx( hFdCngCom->olapBufferSynth2, 0, shr( hFdCngCom->frameSize, 1 ) ); - set16_fx( hStereoCng->olapBufferSynth22_fx, 0, shr( hFdCngCom->frameSize, 1 ) ); - } - IF( flag_sec_CNA ) - { - Copy_Scale_sig_32_16( Ns_fx, hStereoCng->maskingNoiseS_fx, hFdCngCom->frameSize, 0 ); // Q6 - hStereoCng->enableSecCNA = 1; - move16(); - } - ELSE - { - set16_fx( hStereoCng->olapBufferSynth22_fx, 0, hFdCngCom->frameSize ); - } - - /* add masking noise */ - FOR( i = 0; i < hFdCngCom->frameSize; i++ ) - { - syn[i] = add( syn[i], (Word16) L_shr( Np_fx[i], sub( Q16 + Q6, Q_syn ) ) ); // Q_syn - move16(); - } - } - ELSE IF( hStereoCng->enableSecCNA ) - { - Word16 SP_ratio_fx; - SP_ratio_fx = extract_h( hStereoTD->SP_ratio_LT_fx ); /* Use long-term SP ratio based on L/R synthesis Q15*/ - Word16 prevSP_ratio_fx; - prevSP_ratio_fx = hStereoTD->prevSP_ratio_fx; /* Use long-term SP ratio based on L/R synthesis Q15*/ - move16(); - /* scale and add masking noise */ - FOR( i = 0; i < shr( *hStereoCng->frameSize, 2 ); i++ ) - { - Word16 s; - Word16 scale_fx_tmp; - scale_fx_tmp = BASOP_Util_Divide3216_Scale( L_add( L_mult0( prevSP_ratio_fx, sub( shr( *hStereoCng->frameSize, 2 ), i ) ), L_mult0( SP_ratio_fx, i ) ), shr( *hStereoCng->frameSize, 2 ), &s ); // Q15 - scale_fx_tmp = shl( scale_fx_tmp, s ); - syn[i] = add( syn[i], mult( scale_fx_tmp, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/ - move16(); - } - FOR( ; i < *hStereoCng->frameSize / 2; i++ ) - { - syn[i] = add( syn[i], mult( SP_ratio_fx, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/ - move16(); - } - FOR( ; i < *hStereoCng->frameSize; i++ ) - { - syn[i] = add( syn[i], mult( SP_ratio_fx, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/ - move16(); - } - hStereoTD->prevSP_ratio_fx = extract_h( hStereoTD->SP_ratio_LT_fx ); /*Q15*/ - move16(); - } - - return; -} -void generate_masking_noise_lb_dirac_fx( - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - Word32 *tdBuffer, /* i/o: time-domain signal, if NULL no LB-CNA Q11*/ - const Word16 nCldfbTs, /* i : number of CLDFB slots that will be rendered Q0*/ - const Word16 cna_flag /* i : CNA flag for LB and HB Q0*/ -) -{ - Word16 i; - Word32 *cngNoiseLevel = hFdCngCom->cngNoiseLevel; /*hFdCngCom->cngNoiseLevelExp*/ - Word32 *fftBuffer = hFdCngCom->fftBuffer; /*hFdCngCom->fftBuffer_exp*/ - Word32 *ptr_r; - Word32 *ptr_i; - Word32 *ptr_level; - Word16 *seed = &( hFdCngCom->seed ); - Word32 scale; - Word16 n_samples_out, n_samples_start, n_samples_out_loop; - - push_wmops( "fd_cng_dirac" ); - - /* Init */ - scale = 0; - move32(); - n_samples_out = i_mult( shr( hFdCngCom->frameSize, 4 ), nCldfbTs ); - n_samples_start = 0; - move16(); - Word16 exp_out = Q11; - move16(); - /*LB CLDFB - CNA from STFT*/ - IF( cna_flag ) - { - /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ - IF( GT_16( hFdCngCom->likelihood_noisy_speech, DELTA_MASKING_NOISE_Q15 ) ) - { - /* Compute additional CN level */ - FOR( i = 0; i < 15; i++ ) - { - test(); - test(); - if ( ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_dirac[i].bwmode ) ) && - GE_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateFrom ) && - LT_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateTo ) ) - { - BREAK; - } - } - - scale = L_deposit_h( scaleTable_cn_dirac[i].scale_ivas ); /* Q30 */ - scale = Mpy_32_16_1( scale, hFdCngCom->likelihood_noisy_speech ); /* Q30 */ - } - } - - /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/ - test(); - IF( cna_flag && tdBuffer != NULL ) - { - WHILE( n_samples_out > 0 ) - { - n_samples_out_loop = s_min( hFdCngCom->frameSize, n_samples_out ); - IF( scale != 0 ) - { - /*Generate LF comfort noise only at first slot, for the whole frame*/ - ptr_level = cngNoiseLevel; /*hFdCngCom->cngNoiseLevelExp*/ - - /* Generate Gaussian random noise in real and imaginary parts of the FFT bins - Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */ - IF( EQ_16( hFdCngCom->startBand, 0 ) ) - { - rand_gauss_fx( &fftBuffer[0], seed, exp_out ); - ptr_r = fftBuffer + 2; /*hFdCngCom->fftBuffer_exp*/ - - Word16 exp2 = sub( 31, hFdCngCom->cngNoiseLevelExp ); - Word32 sqr = Sqrt32( L_shr( Mpy_32_32( scale, *ptr_level ), 1 ), &exp2 ); /* DC component in FFT Q31 - exp2*/ - sqr = L_shl( sqr, exp2 ); /*Q31*/ - fftBuffer[0] = Mpy_32_32( fftBuffer[0], sqr ); /* DC component in FFT Q31 - hFdCngCom->fftBuffer_exp*/ - move32(); - ptr_level++; - } - ELSE - { - fftBuffer[0] = 0; - move32(); - set32_fx( fftBuffer + 2, 0, shl( sub( hFdCngCom->startBand, 1 ), 1 ) ); - ptr_r = fftBuffer + shl( hFdCngCom->startBand, 1 ); /*hFdCngCom->fftBuffer_exp*/ - } - ptr_i = ptr_r + 1; /*hFdCngCom->fftBuffer_exp*/ - - FOR( ; ptr_level < cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); ptr_level++ ) - { - rand_gauss_fx( ptr_r, seed, exp_out ); - Word16 exp2 = hFdCngCom->cngNoiseLevelExp; - Word32 mpy2 = Sqrt32( Mpy_32_32( scale, *ptr_level ), &exp2 ); /*Q31 - exp2*/ - ( *ptr_r ) = L_shl( Mpy_32_32( *ptr_r, mpy2 ), exp2 ); /*Q31 - hFdCngCom->fftBuffer_exp*/ - move32(); - ptr_r += 2; - - /* Imaginary part in FFT bins */ - rand_gauss_fx( ptr_i, seed, exp_out ); - ( *ptr_i ) = L_shl( Mpy_32_32( *ptr_i, mpy2 ), exp2 ); /*Q31 - hFdCngCom->fftBuffer_exp*/ - move32(); - ptr_i += 2; - } - /* Remaining FFT bins are set to zero */ - set32_fx( fftBuffer + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) ); - /* Nyquist frequency is discarded */ - fftBuffer[1] = 0; - move32(); - - /* Perform STFT synthesis */ - SynthesisSTFT_dirac_fx( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, n_samples_out_loop, hFdCngCom ); - scale_sig32( tdBuffer + n_samples_start, n_samples_out_loop, Q9 ); // Q2 -> Q11 - } - - ELSE - { - /* very low level case - update random seeds */ - generate_masking_noise_update_seed_fx( hFdCngCom ); - - set32_fx( fftBuffer, 0, hFdCngCom->fftlen ); - /* Perform STFT synthesis */ - SynthesisSTFT_dirac_fx( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, n_samples_out_loop, hFdCngCom ); - } - hFdCngCom->fftBuffer_exp = 31 - 11; - move16(); - n_samples_out = sub( n_samples_out, hFdCngCom->frameSize ); - n_samples_start = add( n_samples_start, hFdCngCom->frameSize ); - } - } - - pop_wmops(); - - return; -} -void generate_masking_noise_dirac_ivas_fx( - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */ - Word32 *tdBuffer_fx, /* i/o: time-domain signal, if NULL no LB-CNA q_input*/ - Word32 *Cldfb_RealBuffer_fx, /* o : CLDFD real buffer q_cldfb*/ - Word32 *Cldfb_ImagBuffer_fx, /* o : CLDFD imaginary buffer q_cldfb*/ - const Word16 slot_index, /* i : CLDFB slot index Q0*/ - const Word16 cna_flag, /* i : CNA flag for LB and HB Q0*/ - const Word16 fd_cng_flag, /* i : FD-CNG flag for HB Q0*/ - Word16 q_input, - Word16 *q_cldfb ) -{ - Word16 i; - Word32 *ptr_level_fx; - Word16 *seed = &( hFdCngCom->seed ); - Word32 scale_fx; - Word16 q_scale, q_shift, q_ptr_level; - - push_wmops( "fd_cng_dirac" ); - - /* Init */ - scale_fx = 0; - move32(); - - /* Resample CLDFB memories if necessary*/ - IF( NE_16( i_mult( h_cldfb->no_channels, h_cldfb->no_col ), hFdCngCom->frameSize ) ) - { - resampleCldfb_ivas_fx( h_cldfb, hFdCngCom->frameSize * FRAMES_PER_SEC ); - } - - set32_fx( Cldfb_RealBuffer_fx, 0, CLDFB_NO_CHANNELS_MAX ); - set32_fx( Cldfb_ImagBuffer_fx, 0, CLDFB_NO_CHANNELS_MAX ); - - /*LB CLDFB - CNA from STFT*/ - IF( cna_flag != 0 ) - { - /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ - IF( hFdCngCom->likelihood_noisy_speech > 0 ) - { - /* Compute additional CN level */ - FOR( i = 0; i < 15; i++ ) - { - test(); - test(); - if ( ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_dirac[i].bwmode ) ) && - ( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateFrom ) ) && - ( LT_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateTo ) ) ) - { - BREAK; - } - } - - scale_fx = L_shr( L_deposit_h( scaleTable_cn_dirac[i].scale_ivas ), Q3 ); /* Q27 */ - scale_fx = Mpy_32_16_1( scale_fx, hFdCngCom->likelihood_noisy_speech ); - } - } - /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/ - IF( cna_flag && tdBuffer_fx != NULL ) - { - *q_cldfb = q_input; - move16(); - IF( scale_fx != 0 ) - { - /* LF CLDFB*/ - cldfbAnalysis_ts_fx_fixed_q( &( tdBuffer_fx[( hFdCngCom->numCoreBands * slot_index )] ), Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hFdCngCom->numCoreBands, h_cldfb, q_cldfb ); - } - ELSE - { - /* LB ana CLDFB*/ - cldfbAnalysis_ts_fx_fixed_q( &( tdBuffer_fx[( hFdCngCom->numCoreBands * slot_index )] ), Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hFdCngCom->numCoreBands, h_cldfb, q_cldfb ); - } - } - - /*HF CLDFB - CNA and/or FD-CNG*/ - if ( fd_cng_flag ) - { - scale_fx = L_add( scale_fx, ONE_IN_Q27 ); // 1 in Q27 - } - IF( scale_fx != 0 ) - { - q_scale = 27; - move16(); - q_shift = norm_l( scale_fx ); - scale_fx = L_shl( scale_fx, q_shift ); /*q_scale+q_shift*/ - q_scale = add( q_scale, q_shift ); - scale_fx = Mpy_32_32( scale_fx, Mpy_32_16_1( L_mult( h_cldfb->scale, h_cldfb->scale ), CLDFB_SCALING ) ); // Q = q_scale + 2 * Q8 - 34 - q_scale = sub( add( q_scale, 2 * Q8 ), 31 ); - ptr_level_fx = hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q31 - hFdCngCom->cngNoiseLevelExp*/ - q_ptr_level = sub( 31, hFdCngCom->cngNoiseLevelExp ); - - FOR( i = hFdCngCom->numCoreBands; i < hFdCngCom->regularStopBand; i++ ) - { - Word32 num; - Word16 exp, q_num; - q_shift = norm_l( scale_fx ); - scale_fx = L_shl( scale_fx, q_shift ); /*q_scale+q_shift*/ - q_scale = add( q_scale, q_shift ); - num = Mpy_32_32( scale_fx, *ptr_level_fx ); /*q_num*/ - q_num = sub( add( q_scale, q_ptr_level ), 31 ); - exp = sub( 31, q_num ); - num = Sqrt32( num, &exp ); /*Q31 - exp*/ - /* Real part in CLDFB band */ - rand_gauss_fx( &Cldfb_RealBuffer_fx[i], seed, *q_cldfb ); - Cldfb_RealBuffer_fx[i] = L_shl( Mpy_32_32( Cldfb_RealBuffer_fx[i], num ), exp ); - move32(); - /* Imaginary part in CLDFB band */ - rand_gauss_fx( &Cldfb_ImagBuffer_fx[i], seed, *q_cldfb ); - Cldfb_ImagBuffer_fx[i] = L_shl( Mpy_32_32( Cldfb_ImagBuffer_fx[i], num ), exp ); - move32(); - - ptr_level_fx++; - } - } - - pop_wmops(); - - return; -} - - -/*------------------------------------------------------------------- - * FdCngDecodeMDCTStereoSID() - * - * Decode FD-Cng parameters for CNG in MDCT-Stereo mode from the bitstream - * - *-------------------------------------------------------------------*/ - -void FdCngDecodeMDCTStereoSID_fx( - CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */ -) -{ - DEC_CORE_HANDLE sts[CPE_CHANNELS]; - HANDLE_FD_CNG_COM hFdCngCom; - Word32 *ms_ptr_fx[CPE_CHANNELS]; - Word32 *lr_ptr_fx[CPE_CHANNELS]; - Word32 logNoiseEst_fx[CPE_CHANNELS][NPART]; - Word32 gain_fx[CPE_CHANNELS]; - Word16 indices[FD_CNG_stages_37bits]; - Word16 N, i, ch, p, stages; - Word16 is_out_ms; - Word32 *invTrfMatrix_fx; - Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; - Word16 shift, exp_diff, max_exp_idx; - Word16 exp_arr[NPART]; - Word32 tmp32, tmp32_arr[NPART]; - - invTrfMatrix_fx = (Word32 *) tmpRAM_fx; - create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); // Q31 - - is_out_ms = 0; - move16(); - if ( hCPE->hCoreCoder[0]->cng_sba_flag ) - { - is_out_ms = 1; - move16(); - } - - N = 0; /* to avoid compilation warning */ - move16(); - - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - sts[ch] = hCPE->hCoreCoder[ch]; - ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; /*Q20*/ - lr_ptr_fx[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; /*Q18*/ - } - - /* decode noise shapes and gains */ - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - sts[ch] = hCPE->hCoreCoder[ch]; - hFdCngCom = ( sts[ch]->hFdCngDec )->hFdCngCom; - N = hFdCngCom->npart; - move16(); - hFdCngCom->sid_frame_counter = add( hFdCngCom->sid_frame_counter, 1 ); /*Q0*/ - move16(); - - IF( ch ) - { - stages = FD_CNG_JOINT_stages_25bits; - move16(); - } - ELSE - { - stages = FD_CNG_stages_37bits; - move16(); - } - - /* read bitstream */ - FOR( i = 0; i < stages; i++ ) - { - indices[i] = get_next_indice_fx( sts[ch], bits_37bits[i] ); /*Q0*/ - move16(); - } - { - gain_fx[ch] = Mpy_32_32( L_shl( L_sub( get_next_indice_fx( sts[ch], 7 ), GAIN_Q_OFFSET_IVAS_FX ), Q20 ), TWO_BY_THREE_Q31 /* 2/3 in Q31 */ ); // Q20 - move32(); - } - - /* MSVQ decoder */ - shift = find_guarded_bits_fx( N ); - msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, stages, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, ms_ptr_fx[ch], NULL, 7 ); // Q20 - shift - - Scale_sig32( ms_ptr_fx[ch], N, shift ); // Q20 - } - - dtx_read_padding_bits_fx( sts[1], mult( sub( IVAS_SID_5k2, 4400 ), ONE_BY_FRAMES_PER_SEC_Q15 ) ); - - IF( sts[0]->hFdCngDec->hFdCngCom->no_side_flag ) - { - set32_fx( ms_ptr_fx[1], 0, NPART ); - } - - IF( EQ_16( is_out_ms, 0 ) ) - { - inverseMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 ); - } - - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - max_exp_idx = 0; - move16(); - hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom; - FOR( p = 0; p < N; p++ ) - { - tmp32 = L_add( ms_ptr_fx[ch][p], gain_fx[ch] ); // Q20 - tmp32_arr[p] = BASOP_util_Pow2( Mpy_32_32( tmp32, LOG_10_BASE_2_BY_10_Q31 ), Q11, &exp_arr[p] ); /*Q31 - exp_arr[p]*/ - move32(); - if ( LT_16( exp_arr[max_exp_idx], exp_arr[p] ) ) - { - max_exp_idx = p; /*Q0*/ - move16(); - } - } - - // Bringing in same exponent - FOR( p = 0; p < N; p++ ) - { - lr_ptr_fx[ch][p] = L_shl( tmp32_arr[p], sub( exp_arr[p], exp_arr[max_exp_idx] ) ); /*Q31 - exp_arr[max_exp_idx]*/ - move32(); - } - - hFdCngCom->sidNoiseEstExp = exp_arr[max_exp_idx]; - move16(); - - scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 ); - - hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; - move16(); - - lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac ); - } - - test(); - IF( EQ_16( hCPE->nchan_out, 1 ) && LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) ) - { - /* create proper M noise shape in channel zero after gains have been applied */ - exp_diff = sub( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp ); - move16(); - FOR( p = 0; p < N; p++ ) - { - IF( GT_16( exp_diff, 0 ) ) - { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], add( exp_diff, 1 ) ) ); /*Q18*/ - move32(); - } - ELSE - { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], sub( 1, exp_diff ) ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ) ); /*Q18*/ - move32(); - } - } - IF( LT_16( exp_diff, 0 ) ) - { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = add( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, negate( exp_diff ) ); - move16(); - } - } - - return; -} - - -/*------------------------------------------------------------------- - * FdCngDecodeDiracMDCTStereoSID_fx() - * - * Decode FD-CNG parameters for CNG in 2TC DirAC mode from the bitstream - *-------------------------------------------------------------------*/ - -void FdCngDecodeDiracMDCTStereoSID_fx( - CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */ -) -{ - DEC_CORE_HANDLE sts[CPE_CHANNELS]; - HANDLE_FD_CNG_COM hFdCngCom; - Word32 *ms_ptr_fx[CPE_CHANNELS]; - Word32 *lr_ptr_fx[CPE_CHANNELS]; - Word32 logNoiseEst_fx[CPE_CHANNELS][NPART]; - Word32 gain_fx[CPE_CHANNELS]; - Word16 indices[FD_CNG_stages_37bits]; - Word16 N, i, ch, p; - Word32 *invTrfMatrix_fx; - Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; - Word16 shift, exp_diff, max_exp_idx; - Word16 exp_arr[NPART]; - Word32 tmp32, tmp32_arr[NPART]; - - invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */ - create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); // Q31 - - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - sts[ch] = hCPE->hCoreCoder[ch]; - ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; /*Q20*/ - lr_ptr_fx[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; /*Q20*/ - ( sts[ch]->hFdCngDec )->hFdCngCom->sid_frame_counter++; /*Q18*/ - } - - /* decode noise shapes and gains */ - hFdCngCom = ( sts[0]->hFdCngDec )->hFdCngCom; - N = hFdCngCom->npart; /*Q0*/ - move16(); - - /* read bitstream */ - FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) - { - indices[i] = get_next_indice_fx( sts[0], bits_37bits[i] ); /*Q0*/ - move16(); - } - gain_fx[0] = Mpy_32_32( L_shl( L_sub( get_next_indice_fx( sts[0], 7 ), GAIN_Q_OFFSET_IVAS_FX ), Q20 ), TWO_BY_THREE_Q31 /* 2/3 in Q31 */ ); // Q20 - move32(); - - gain_fx[1] = gain_fx[0]; /*Q20*/ - move32(); - - /* MSVQ decoder */ - shift = find_guarded_bits_fx( N ); - msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, ms_ptr_fx[0], NULL, 7 ); // Q20 - shift - - Scale_sig32( ms_ptr_fx[0], N, shift ); // Q20 - - Copy32( ms_ptr_fx[0], ms_ptr_fx[1], N ); /*Q20*/ - - FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) - { - max_exp_idx = 0; - move16(); - hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom; - - FOR( p = 0; p < N; p++ ) - { - tmp32 = L_add( ms_ptr_fx[ch][p], gain_fx[ch] ); // Q20 - tmp32_arr[p] = BASOP_util_Pow2( Mpy_32_32( tmp32, LOG_10_BASE_2_BY_10_Q31 ), Q11, &exp_arr[p] ); /*Q31 - exp_arr[p]*/ - move32(); - if ( LT_16( exp_arr[max_exp_idx], exp_arr[p] ) ) - { - max_exp_idx = p; /*Q0*/ - move16(); - } - } - - // Bringing in same exponent - FOR( p = 0; p < N; p++ ) - { - lr_ptr_fx[ch][p] = L_shl( tmp32_arr[p], sub( exp_arr[p], exp_arr[max_exp_idx] ) ); /*Q20*/ - move32(); - } - - hFdCngCom->sidNoiseEstExp = exp_arr[max_exp_idx]; /*Q0*/ - move16(); - - /* NB last band energy compensation */ - test(); - IF( hFdCngCom->CngBandwidth == NB ) - { - lr_ptr_fx[ch][( N - 1 )] = Mpy_32_32( lr_ptr_fx[ch][( N - 1 )], NB_LAST_BAND_SCALE_Q31 ); /*Q20*/ - move32(); - } - ELSE IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) - { - lr_ptr_fx[ch][( N - 1 )] = Mpy_32_32( lr_ptr_fx[ch][( N - 1 )], SWB_13k2_LAST_BAND_SCALE_Q31 ); /*Q20*/ - move32(); - } - - scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 ); - - hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; - move16(); - - lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac ); - } - sts[0]->hFdCngDec->hFdCngCom->coherence_fx = 0; - move16(); - sts[1]->hFdCngDec->hFdCngCom->coherence_fx = 0; - move16(); - - IF( EQ_16( hCPE->nchan_out, 1 ) ) - { - /* create proper M noise shape in channel zero after gains have been applied */ - exp_diff = sub( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp ); - FOR( p = 0; p < N; p++ ) - { - IF( exp_diff > 0 ) - { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], add( exp_diff, 1 ) ) ); /*Q18*/ - move32(); - } - ELSE - { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], sub( 1, exp_diff ) ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ) ); /*Q18*/ - move32(); - } - } - IF( exp_diff < 0 ) - { - sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = add( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, negate( exp_diff ) ); - move16(); - } - } - - return; -} diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index 8a902448f..f788144fa 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -24,6 +24,14 @@ #define ST_PERIODOG_FACT_Q15 29491 /* 0.9 in Q15, short-term filter factor for periodogram */ #define CNA_ACT_DN_FACT_Q15 22938 /* 0.7 in Q15, downward updating factor for CNA during active frames */ #define FIRST_CNA_NOISE_UPD_FRAMES 5 /* minimum number of CN initialization frames */ +#define DELTA_MASKING_NOISE_Q15 0 +#define LOG_10_BASE_2 1783446566 /* Q29 */ +#define GAIN_Q_OFFSET_IVAS_FX 45 +#define LOG_10_BASE_2_BY_10_Q31 713378606 +#define TWO_BY_THREE_Q31 1431655765 +#define ONE_BY_FRAMES_PER_SEC_Q15 656 +#define NB_LAST_BAND_SCALE_Q31 1717986918 +#define SWB_13k2_LAST_BAND_SCALE_Q31 1717986918 /******************************** * External tables * @@ -5025,6 +5033,1278 @@ void generate_masking_noise_mdct_ivas_fx( return; } + +/*------------------------------------------------------------------- + * initFdCngDec() + * + * Initialize an instance of type FD_CNG + *-------------------------------------------------------------------*/ +void configureFdCngDec_ivas_fx( + HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: Contains the variables related to the FD-based CNG process */ + const Word16 bwidth, /*Q0*/ + const Word32 total_brate, /*Q0*/ + const Word16 L_frame, /*Q0*/ + const Word16 last_L_frame, /*Q0*/ + const Word16 element_mode /*Q0*/ ) +{ + Word16 j, stopBandFR; + HANDLE_FD_CNG_COM hsCom = hFdCngDec->hFdCngCom; + + hsCom->CngBandwidth = bwidth; /*Q0*/ + move16(); + if ( EQ_16( hsCom->CngBandwidth, FB ) ) + { + hsCom->CngBandwidth = SWB; + move16(); + } + test(); + IF( NE_32( total_brate, FRAME_NO_DATA ) && NE_32( total_brate, SID_2k40 ) ) + { + hsCom->CngBitrate = total_brate; /*Q0*/ + move32(); + } + ELSE IF( EQ_32( hsCom->CngBitrate, -1 ) ) + { + /* set minimum active CBR bitrate IF CngBitrate is uninitialized */ + IF( element_mode > EVS_MONO ) + { + hsCom->CngBitrate = IVAS_13k2; + move32(); + } + ELSE + { + hsCom->CngBitrate = ACELP_7k20; + move32(); + } + } + + /* FD-CNG config for MDCT-Stereo is always the same (since for > 48 kbps only) */ + /* This may need adjustment in the future IF 2TC DTX for some mode uses MDCT-Stereo DTX for lower bitrates too */ + if ( EQ_16( element_mode, IVAS_CPE_MDCT ) ) + { + hsCom->CngBitrate = IVAS_48k; + move32(); + } + hsCom->numSlots = 16; + move32(); + + /* NB configuration */ + IF( EQ_16( bwidth, NB ) ) + { + hsCom->FdCngSetup = FdCngSetup_nb; + hsCom->numCoreBands = 16; + move16(); + hsCom->regularStopBand = 16; + move16(); + } + + /* WB configuration */ + ELSE IF( EQ_16( bwidth, WB ) ) + { + /* FFT 6.4kHz, no CLDFB */ + test(); + test(); + IF( LE_32( hsCom->CngBitrate, ACELP_8k00 ) && EQ_16( L_frame, L_FRAME ) ) + { + hsCom->FdCngSetup = FdCngSetup_wb1; + hsCom->numCoreBands = 16; + move16(); + hsCom->regularStopBand = 16; + move16(); + } + /* FFT 6.4kHz, CLDFB 8.0kHz */ + ELSE IF( LE_32( hsCom->CngBitrate, ACELP_13k20 ) || EQ_16( L_frame, L_FRAME ) ) + { + hsCom->FdCngSetup = FdCngSetup_wb2; + hsCom->numCoreBands = 16; + move16(); + hsCom->regularStopBand = 20; + move16(); + IF( EQ_16( L_frame, L_FRAME16k ) ) + { + hsCom->FdCngSetup = FdCngSetup_wb2; + hsCom->numCoreBands = 20; + move16(); + hsCom->regularStopBand = 20; + move16(); + hsCom->FdCngSetup.fftlen = 640; + move16(); + hsCom->FdCngSetup.stopFFTbin = 256; + move16(); + } + } + /* FFT 8.0kHz, no CLDFB */ + ELSE + { + hsCom->FdCngSetup = FdCngSetup_wb3; + hsCom->numCoreBands = 20; + move16(); + hsCom->regularStopBand = 20; + move16(); + } + } + + /* SWB/FB configuration */ + ELSE + { + /* FFT 6.4kHz, CLDFB 14kHz */ + IF( EQ_16( L_frame, L_FRAME ) ) + { + hsCom->FdCngSetup = FdCngSetup_swb1; + hsCom->numCoreBands = 16; + move16(); + hsCom->regularStopBand = 35; + move16(); + } + /* FFT 8.0kHz, CLDFB 16kHz */ + ELSE + { + hsCom->FdCngSetup = FdCngSetup_swb2; + hsCom->numCoreBands = 20; + move16(); + hsCom->regularStopBand = 40; + move16(); + test(); + if ( EQ_16( last_L_frame, L_FRAME ) && EQ_16( element_mode, IVAS_CPE_DFT ) ) + { + hsCom->regularStopBand = 35; + move16(); + } + } + } + + + hsCom->fftlen = hsCom->FdCngSetup.fftlen; + move16(); + hsCom->stopFFTbin = hsCom->FdCngSetup.stopFFTbin; + move16(); + + /* Configure the SID quantizer and the Comfort Noise Generator */ + + hsCom->startBand = 2; + move16(); + hsCom->stopBand = add( hsCom->FdCngSetup.sidPartitions[( hsCom->FdCngSetup.numPartitions - 1 )], 1 ); /*Q0*/ + initPartitions( hsCom->FdCngSetup.sidPartitions, hsCom->FdCngSetup.numPartitions, hsCom->startBand, hsCom->stopBand, hsCom->part, &hsCom->npart, hsCom->midband, hsCom->psize, hsCom->psize_norm, &hsCom->psize_norm_exp, hsCom->psize_inv, 0 ); + + IF( EQ_16( hsCom->stopFFTbin, 160 ) ) + { + hsCom->nFFTpart = 17; + move16(); + } + ELSE IF( EQ_16( hsCom->stopFFTbin, 256 ) ) + { + hsCom->nFFTpart = 20; + move16(); + } + ELSE + { + hsCom->nFFTpart = 21; + move16(); + } + hsCom->nCLDFBpart = sub( hsCom->npart, hsCom->nFFTpart ); /*Q0*/ + move16(); + FOR( j = 0; j < hsCom->nCLDFBpart; j++ ) + { + hsCom->CLDFBpart[j] = sub( hsCom->part[( j + hsCom->nFFTpart )], sub( hsCom->stopFFTbin, hsCom->startBand ) ); /*Q0*/ + move16(); + hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[( j + hsCom->nFFTpart )]; + move16(); + } + + stopBandFR = 40; //(Word16)floor(1000.f /*Hz*/ / 25.f /*Hz/Bin*/); + move16(); + if ( GT_16( stopBandFR, hsCom->stopFFTbin ) ) + { + stopBandFR = hsCom->stopFFTbin; /*Q0*/ + move16(); + } + + initPartitions( hsCom->FdCngSetup.shapingPartitions, hsCom->FdCngSetup.numShapingPartitions, hsCom->startBand, hsCom->stopFFTbin, hFdCngDec->part_shaping, &hFdCngDec->npart_shaping, hFdCngDec->midband_shaping, hFdCngDec->psize_shaping, hFdCngDec->psize_shaping_norm, &hFdCngDec->psize_shaping_norm_exp, hFdCngDec->psize_inv_shaping, stopBandFR ); + + hFdCngDec->nFFTpart_shaping = hFdCngDec->npart_shaping; /*Q0*/ + move16(); + + BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) ); + BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) ); + + SWITCH( hsCom->fftlen ) + { + case 512: + hsCom->olapWinAna_fx = olapWinAna512_fx; /*Q30*/ + hsCom->fftSineTab_fx = NULL; + hsCom->olapWinSyn_fx = olapWinSyn256_fx; /*Q15*/ + hsCom->fftlenShift = 8; + move16(); + hsCom->fftlenFac = 32767 /*1.0 Q15*/; + move16(); + BREAK; + case 640: + hsCom->olapWinAna_fx = olapWinAna640_fx; /*Q30*/ + hsCom->fftSineTab_fx = fftSineTab640_fx; /*Q15*/ + hsCom->olapWinSyn_fx = olapWinSyn320_fx; /*Q15*/ + hsCom->fftlenShift = 9; + move16(); + hsCom->fftlenFac = 20480 /*0.625 Q15*/; + move16(); + BREAK; + default: + assert( !"Unsupported FFT length for FD-based CNG" ); + BREAK; + } + BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) ); + BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) ); + hsCom->frameSize = shr( hsCom->fftlen, 1 ); + + return; +} + +/*------------------------------------------------------------------- + * FdCng_decodeSID_ivas_fx() + * + * Decode the FD-CNG bitstream + *-------------------------------------------------------------------*/ + +void FdCng_decodeSID_ivas_fx( + Decoder_State *st /* i/o: decoder state structure */ +) +{ + Word16 N; + Word32 *sidNoiseEst; + Word32 gain; + Word16 i, index; + Word32 v[32]; + Word16 indices[32]; + HANDLE_FD_CNG_COM hFdCngCom; + Word32 *invTrfMatrix_fx; + Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; + Word16 tmp16; + + IF( st->element_mode == EVS_MONO ) + { + tmp16 = GAIN_Q_OFFSET_EVS_FX_Q0; + move16(); + } + ELSE + { + tmp16 = GAIN_Q_OFFSET_IVAS_FX_Q0; + move16(); + } + + const Word16 gain_q_offset = tmp16; /* Q0 */ + move16(); + + invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /*Q31*/ + + hFdCngCom = ( st->hFdCngDec )->hFdCngCom; + + sidNoiseEst = hFdCngCom->sidNoiseEst; /*Q16*/ + + N = hFdCngCom->npart; /*Q0*/ + move16(); + gain = 0; + move32(); + hFdCngCom->sid_frame_counter = add( hFdCngCom->sid_frame_counter, 1 ); + move16(); + + /* Read bitstream */ + FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) + { + indices[i] = get_next_indice_fx( st, bits_37bits[i] ); /*Q0*/ + move16(); + } + + index = get_next_indice_fx( st, 7 ); + + /* MSVQ decoder */ + + IF( st->element_mode != EVS_MONO ) + { + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); + msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, v, NULL, 7 ); + } + ELSE + { /* Legacy EVS_MONO MSVQ tables */ + msvq_dec_fx( cdk_37bits, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v, NULL, 7 ); + } + + + /* Decode gain */ + // gain = ((float)index - gain_q_offset) / 1.5f; + gain = L_mult0( sub( index, gain_q_offset ), 21845 ); // Q15 + + /* Apply gain and undo log */ + Word16 res_exp[NPART]; + Word16 max_res_exp = 0; + move16(); + FOR( i = 0; i < N; i++ ) + { + sidNoiseEst[i] = BASOP_util_Pow2( Mpy_32_32( L_add( v[i], gain ), LOG_10_BASE_2_BY_10_Q31 ), Q16, &res_exp[i] ); /*Q31 - res_exp[i]*/ + move32(); + if ( LT_16( max_res_exp, res_exp[i] ) ) + { + max_res_exp = res_exp[i]; + move16(); + } + } + + FOR( i = 0; i < N; i++ ) + { + sidNoiseEst[i] = L_shr( sidNoiseEst[i], sub( max_res_exp, res_exp[i] ) ); /*Q31 - max_res_exp*/ + move32(); + } + + hFdCngCom->sidNoiseEstExp = max_res_exp; + move16(); + + /* NB last band energy compensation */ + + IF( hFdCngCom->CngBandwidth == NB ) + { + sidNoiseEst[( N - 1 )] = Mpy_32_16_1( sidNoiseEst[( N - 1 )], NB_LAST_BAND_SCALE ); /*Q31 - max_res_exp*/ + move32(); + } + + test(); + IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) + { + sidNoiseEst[( N - 1 )] = Mpy_32_16_1( sidNoiseEst[( N - 1 )], SWB_13k2_LAST_BAND_SCALE ); /*Q31 - max_res_exp*/ + move32(); + } + + scalebands( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 ); + hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; + move16(); + + lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, st->preemph_fac ); + + return; +} + +/*------------------------------------------------------------------- + * generate_masking_noise_ivas_fx() + * + * Generate additional comfort noise (kind of noise filling) + *-------------------------------------------------------------------*/ + +void generate_masking_noise_ivas_fx( + Word32 *timeDomainBuffer, /* i/o: time-domain signal Q31 - *exp_out*/ + Word16 *exp_out, /* o : time-domain signal exp */ + HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ + const Word16 length, /* i : frame size Q0*/ + const Word16 core, /* i : core Q0*/ + const Word16 return_noise, /* i : noise is returned instead of added Q0*/ + const Word16 secondary, /* i : flag to indicate secondary noise generation Q0*/ + const Word16 element_mode, /* i : element mode Q0*/ + STEREO_CNG_DEC_HANDLE hStereoCng, /* i : stereo CNG handle */ + const Word16 nchan_out /* i : number of output channels Q0*/ +) +{ + Word32 *cngNoiseLevel_fx = hFdCngCom->cngNoiseLevel; + Word32 *ptr_level_fx = cngNoiseLevel_fx; + Word32 *fftBuffer_fx = hFdCngCom->fftBuffer; + Word16 i; + Word32 maskingNoise_fx[L_FRAME16k]; + Word32 *ptr_r_fx; + Word32 *ptr_i_fx; + Word16 startBand; + Word16 *seed = &( hFdCngCom->seed ); + Word32 scale_fx; + Word16 shift; + scale_fx = 0x40000000; // 1.0 in Q30 + move32(); + startBand = hFdCngCom->startBand; /*Q0*/ + move16(); + shift = getScaleFactor32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN ); + if ( LT_16( sub( hFdCngCom->cngNoiseLevelExp, shift ), 4 ) ) + { + shift = sub( hFdCngCom->cngNoiseLevelExp, 4 ); /*Q0*/ + } + scale_sig32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, shift ); /*hFdCngCom->cngNoiseLevelExp*/ + hFdCngCom->cngNoiseLevelExp = sub( hFdCngCom->cngNoiseLevelExp, shift ); + move16(); + + /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ + *exp_out = Q15; + move16(); + IF( GT_16( hFdCngCom->likelihood_noisy_speech, DELTA_MASKING_NOISE_Q15 ) ) + { + IF( NE_16( core, AMR_WB_CORE ) ) + { + /* Compute additional CN level */ + FOR( i = 0; i < SIZE_SCALE_TABLE_CN; i++ ) + { + test(); + test(); + if ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_only[i].bwmode ) && + GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateFrom ) && + LT_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateTo ) ) + { + BREAK; + } + } + + scale_fx = L_deposit_h( scaleTable_cn_only[i].scale_ivas ); /* Q30 */ + } + ELSE + { + /* Compute additional CN level */ + FOR( i = 0; i < SIZE_SCALE_TABLE_CN_AMRWB; i++ ) + { + if ( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only_amrwbio[i][0] ) ) + { + BREAK; + } + } + + IF( LT_16( i, SIZE_SCALE_TABLE_CN_AMRWB ) ) + { + scale_fx = L_deposit_h( scaleTable_cn_only_amrwbio[i][1] ); /* Q30 */ + } + ELSE + { + scale_fx = 0; + move32(); + } + } + + /* Exclude clean speech */ + scale_fx = Mpy_32_16_1( scale_fx, hFdCngCom->likelihood_noisy_speech ); // Q30 + + /* Generate Gaussian random noise in real and imaginary parts of the FFT bins + Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */ + IF( startBand == 0 ) + { + rand_gauss_fx( &fftBuffer_fx[0], seed, *exp_out ); // Q15 + ptr_r_fx = fftBuffer_fx + 2; /*Q31 - hFdCngCom->fftBuffer_exp*/ + Word16 exp1; + exp1 = add( hFdCngCom->cngNoiseLevelExp, 1 ); + Word32 mpy1; + mpy1 = Sqrt32( Mpy_32_32( scale_fx, *ptr_level_fx ), &exp1 ); /*Q31 - exp1*/ + mpy1 = L_shl( mpy1, exp1 ); // Q31 + fftBuffer_fx[0] = Mpy_32_32( fftBuffer_fx[0], mpy1 ); /* DC component in FFT */ // Q = Q15 + ptr_level_fx++; + } + ELSE + { + fftBuffer_fx[0] = 0; + move32(); + set32_fx( fftBuffer_fx + 2, 0, shl( sub( startBand, 1 ), 1 ) ); + ptr_r_fx = fftBuffer_fx + shl( startBand, 1 ); /*Q31 - hFdCngCom->fftBuffer_exp*/ + } + ptr_i_fx = ptr_r_fx + 1; + FOR( ; ptr_level_fx < cngNoiseLevel_fx + hFdCngCom->stopFFTbin - startBand; ptr_level_fx++ ) + { + /* Real part in FFT bins */ + rand_gauss_fx( ptr_r_fx, seed, *exp_out ); // Q15 + Word16 exp2; + exp2 = add( hFdCngCom->cngNoiseLevelExp, 1 ); + Word32 mpy2; + mpy2 = Sqrt32( L_shr( Mpy_32_32( scale_fx, *ptr_level_fx ), 1 ), &exp2 ); /*Q31 - exp2*/ + ( *ptr_r_fx ) = L_shl( Mpy_32_32( *ptr_r_fx, mpy2 ), exp2 ); // Q = Q15 + move32(); + ptr_r_fx += 2; + + /* Imaginary part in FFT bins */ + rand_gauss_fx( ptr_i_fx, seed, *exp_out ); // Q15 + ( *ptr_i_fx ) = L_shl( Mpy_32_32( *ptr_i_fx, mpy2 ), exp2 ); // Q = Q15 + ptr_i_fx += 2; + } + + /* Remaining FFT bins are set to zero */ + set32_fx( fftBuffer_fx + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) ); + /* Nyquist frequency is discarded */ + fftBuffer_fx[1] = 0; + move32(); + } + ELSE + { + /* very low level case - update random seeds and reset FFT buffer; don't fully skip SynthesisSTFT_flt(), because of the buffer updates done there... */ + generate_masking_noise_update_seed_fx( hFdCngCom ); + + set32_fx( fftBuffer_fx, 0, hFdCngCom->fftlen ); + } + + /* Perform STFT synthesis */ + IF( secondary ) + { + SynthesisSTFT_fx( fftBuffer_fx, maskingNoise_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->olapWinSyn_fx, 0, hFdCngCom, element_mode, nchan_out ); + } + ELSE + { + SynthesisSTFT_fx( fftBuffer_fx, maskingNoise_fx, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, 0, hFdCngCom, element_mode, nchan_out ); + } + *exp_out = sub( *exp_out, Q9 ); + move16(); + + /* Add some comfort noise on top of decoded signal */ + IF( return_noise ) + { + Copy32( maskingNoise_fx, timeDomainBuffer, s_min( hFdCngCom->frameSize, length ) ); /*Q31 - *exp_out*/ + } + ELSE + { + v_add_fixed( maskingNoise_fx, timeDomainBuffer, timeDomainBuffer, s_min( hFdCngCom->frameSize, length ), 0 ); /*Q31 - *exp_out*/ + } + + return; +} + +/*------------------------------------------------------------------- + * generate_stereo_masking_noise_fx() + * + * Generate additional comfort noise (kind of noise filling) + *-------------------------------------------------------------------*/ + +void generate_stereo_masking_noise_fx( + Word16 *syn, /* i/o: time-domain signal Q_syn*/ + Word16 Q_syn, + Decoder_State *st, /* i/o: decoder state structure */ + STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i : TD stereo structure */ + const Word16 flag_sec_CNA, /* i : CNA flag for secondary channel Q0*/ + const Word16 fadeOut, /* i : only fade out of previous state Q0*/ + STEREO_CNG_DEC_HANDLE hStereoCng, /* i : Stereo CNG handle */ + const Word16 nchan_out /* i : number of output channels Q0*/ +) +{ + HANDLE_FD_CNG_COM hFdCngCom; + Word32 gamma_fx, scale_fx /*, SP_ratio_fx needs to be integrated*/; + Word32 Np_fx[L_FRAME16k]; + Word32 Ns_fx[L_FRAME16k]; + Word32 N1_fx[L_FRAME16k]; + Word32 N2_fx[L_FRAME16k]; + Word16 N1_fx_exp, N2_fx_exp; + Word16 i; + + IF( st->idchan == 0 ) + { + hFdCngCom = st->hFdCngDec->hFdCngCom; +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, Ns_fx, shr( hFdCngCom->frameSize, 1 ), sub( Q6, st->Q_syn ) ); /*Q6*/ +#else + Copy_Scale_sig_16_32_DEPREC( hStereoCng->olapBufferSynth22_fx, Ns_fx, shr( hFdCngCom->frameSize, 1 ), sub( Q6, st->Q_syn ) ); /*Q6*/ +#endif + Copy32( hFdCngCom->olapBufferSynth2_fx, Np_fx, shr( hFdCngCom->frameSize, 1 ) ); /*st->Q_syn*/ + + set32_fx( &Np_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) ); + set32_fx( &Ns_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) ); + + IF( !fadeOut ) + { +#ifdef FIX_ISSUE_1237 + Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->fftlen, sub( Q15, st->Q_syn ) ); /*Q15*/ +#else + Copy_Scale_sig_16_32_DEPREC( hStereoCng->olapBufferSynth22_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->fftlen, sub( Q15, st->Q_syn ) ); /*Q15*/ +#endif + generate_masking_noise_ivas_fx( N1_fx, &N1_fx_exp, hFdCngCom, hFdCngCom->frameSize, 0, 1, 0, st->element_mode, hStereoCng, nchan_out ); // N1_fx Q6 + /* Generate masking noise for secondary channel */ + IF( flag_sec_CNA ) + { + generate_masking_noise_ivas_fx( N2_fx, &N2_fx_exp, hFdCngCom, hFdCngCom->frameSize, 0, 1, 1, st->element_mode, hStereoCng, nchan_out ); // N2_fx Q6 + gamma_fx = L_shr( Mpy_32_32( hStereoCng->c_PS_LT_fx, hStereoCng->c_PS_LT_fx ), 1 ); /*Q30*/ + scale_fx = ONE_IN_Q30; + move32(); + IF( LT_32( gamma_fx, 966367642 /* 0.9 in Q30 */ ) ) + { + Word16 exp_gamma; + exp_gamma = 0; + move16(); + Word16 divisor1; + divisor1 = Inv16( (Word16) L_shr( L_sub( ONE_IN_Q30, gamma_fx ), Q15 ), &exp_gamma ); // Q15-exp_gamma + gamma_fx = L_shl( Mpy_32_16_1( gamma_fx, divisor1 ), exp_gamma ); // Q30 + Word16 exp_gamma1, exp_gamma2, exp_gamma3; + exp_gamma1 = Q1; + exp_gamma2 = Q1; + exp_gamma3 = Q1; + move16(); + move16(); + move16(); + gamma_fx = Sqrt32( L_add( gamma_fx, ONE_IN_Q30 ), &exp_gamma1 ); /*Q31 - exp_gamma1*/ + Word32 temp; + temp = Sqrt32( gamma_fx, &exp_gamma2 ); // Q31-exp_gamma1 + gamma_fx = L_sub( gamma_fx, L_shl( temp, sub( exp_gamma2, exp_gamma1 ) ) ); // Q31-exp_gamma1 + gamma_fx = L_shl( gamma_fx, sub( exp_gamma1, Q1 ) ); // Q30 + Word32 divisor2; + divisor2 = Sqrt32( L_add( ONE_IN_Q30, L_shl( Mpy_32_32( gamma_fx, gamma_fx ), Q1 ) ), &exp_gamma3 ); // Q31 - exp_gamma3 + scale_fx = L_shl( divide3232( ONE_IN_Q30, divisor2 ), add( Q15, exp_gamma3 ) ); // Q30 + } + ELSE + { + gamma_fx = 0; + move16(); + } + + FOR( i = 0; i < 2 * hFdCngCom->frameSize / 4; i++ ) + { + Np_fx[i] = L_add( Np_fx[i], + Mpy_32_32( scale_fx, L_shl( L_add( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ) ); // Q6 + move32(); + Word32 add2; + add2 = Mpy_32_32( scale_fx, L_shl( L_sub( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6 + if ( hStereoCng->c_PS_LT_fx < 0 ) + { + add2 = L_negate( add2 ); /*Q6*/ + } + Ns_fx[i] = L_add( Ns_fx[i], add2 ); /*Q6*/ + move32(); + } + FOR( ; i < hFdCngCom->frameSize; i++ ) + { + Np_fx[i] = Mpy_32_32( scale_fx, L_shl( L_add( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6 + move32(); + Ns_fx[i] = Mpy_32_32( scale_fx, L_shl( L_sub( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6 + move32(); + IF( hStereoCng->c_PS_LT_fx < 0 ) + { + Ns_fx[i] = L_negate( Ns_fx[i] ); + move32(); + } + } + /* Below code to be converted */ + Word32 scale_fx_tmp = Mpy_32_32( scale_fx, L_shl( shr( hFdCngCom->fftlen, 1 ), Q22 ) ); // Q21 + FOR( i = 0; i < shr( hFdCngCom->frameSize, 1 ); i++ ) + { + hFdCngCom->olapBufferSynth2[i] = (Word16) L_shr( Mpy_32_32( scale_fx_tmp, + L_add( L_shr( hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )], Q15 ), + Mpy_32_16_1( gamma_fx, hStereoCng->olapBufferSynth22_fx[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ) ) ), + Q14 ); // Q_olap + move16(); + hStereoCng->olapBufferSynth22_fx[i] = (Word16) L_shr( Mpy_32_32( scale_fx_tmp, + L_sub( L_shr( hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )], Q15 ), + Mpy_32_16_1( gamma_fx, hStereoCng->olapBufferSynth22_fx[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ) ) ), + Q14 ); // Q_olap + move16(); + } + } + ELSE + { + FOR( i = 0; i < shr( hFdCngCom->frameSize, 1 ); i++ ) + { + Np_fx[i] = L_add( Np_fx[i], N1_fx[i] ); // Q6 + move32(); + } + Copy32( &N1_fx[( hFdCngCom->frameSize / 2 )], &Np_fx[( hFdCngCom->frameSize / 2 )], shr( hFdCngCom->frameSize, 1 ) ); /*Q6*/ + scale_fx = L_shl( shr( hFdCngCom->fftlen, 1 ), Q22 ); // Q21 + FOR( i = 0; i < hFdCngCom->frameSize; i++ ) + { + hFdCngCom->olapBufferSynth2[i] = (Word16) L_shr( Mpy_32_16_1( scale_fx, hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ), Q6 ); // Q_olap + move16(); + } + } + + Copy_Scale_sig_32_16( hStereoCng->olapBufferSynth22_32fx, hStereoCng->olapBufferSynth22_fx, hFdCngCom->fftlen, sub( st->Q_syn, 15 ) ); /*st->Q_syn*/ + } + ELSE + { + set16_fx( hFdCngCom->olapBufferSynth2, 0, shr( hFdCngCom->frameSize, 1 ) ); + set16_fx( hStereoCng->olapBufferSynth22_fx, 0, shr( hFdCngCom->frameSize, 1 ) ); + } + IF( flag_sec_CNA ) + { + Copy_Scale_sig_32_16( Ns_fx, hStereoCng->maskingNoiseS_fx, hFdCngCom->frameSize, 0 ); // Q6 + hStereoCng->enableSecCNA = 1; + move16(); + } + ELSE + { + set16_fx( hStereoCng->olapBufferSynth22_fx, 0, hFdCngCom->frameSize ); + } + + /* add masking noise */ + FOR( i = 0; i < hFdCngCom->frameSize; i++ ) + { + syn[i] = add( syn[i], (Word16) L_shr( Np_fx[i], sub( Q16 + Q6, Q_syn ) ) ); // Q_syn + move16(); + } + } + ELSE IF( hStereoCng->enableSecCNA ) + { + Word16 SP_ratio_fx; + SP_ratio_fx = extract_h( hStereoTD->SP_ratio_LT_fx ); /* Use long-term SP ratio based on L/R synthesis Q15*/ + Word16 prevSP_ratio_fx; + prevSP_ratio_fx = hStereoTD->prevSP_ratio_fx; /* Use long-term SP ratio based on L/R synthesis Q15*/ + move16(); + /* scale and add masking noise */ + FOR( i = 0; i < shr( *hStereoCng->frameSize, 2 ); i++ ) + { + Word16 s; + Word16 scale_fx_tmp; + scale_fx_tmp = BASOP_Util_Divide3216_Scale( L_add( L_mult0( prevSP_ratio_fx, sub( shr( *hStereoCng->frameSize, 2 ), i ) ), L_mult0( SP_ratio_fx, i ) ), shr( *hStereoCng->frameSize, 2 ), &s ); // Q15 + scale_fx_tmp = shl( scale_fx_tmp, s ); + syn[i] = add( syn[i], mult( scale_fx_tmp, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/ + move16(); + } + FOR( ; i < *hStereoCng->frameSize / 2; i++ ) + { + syn[i] = add( syn[i], mult( SP_ratio_fx, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/ + move16(); + } + FOR( ; i < *hStereoCng->frameSize; i++ ) + { + syn[i] = add( syn[i], mult( SP_ratio_fx, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/ + move16(); + } + hStereoTD->prevSP_ratio_fx = extract_h( hStereoTD->SP_ratio_LT_fx ); /*Q15*/ + move16(); + } + + return; +} +void generate_masking_noise_lb_dirac_fx( + HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ + Word32 *tdBuffer, /* i/o: time-domain signal, if NULL no LB-CNA Q11*/ + const Word16 nCldfbTs, /* i : number of CLDFB slots that will be rendered Q0*/ + const Word16 cna_flag /* i : CNA flag for LB and HB Q0*/ +) +{ + Word16 i; + Word32 *cngNoiseLevel = hFdCngCom->cngNoiseLevel; /*hFdCngCom->cngNoiseLevelExp*/ + Word32 *fftBuffer = hFdCngCom->fftBuffer; /*hFdCngCom->fftBuffer_exp*/ + Word32 *ptr_r; + Word32 *ptr_i; + Word32 *ptr_level; + Word16 *seed = &( hFdCngCom->seed ); + Word32 scale; + Word16 n_samples_out, n_samples_start, n_samples_out_loop; + + push_wmops( "fd_cng_dirac" ); + + /* Init */ + scale = 0; + move32(); + n_samples_out = i_mult( shr( hFdCngCom->frameSize, 4 ), nCldfbTs ); + n_samples_start = 0; + move16(); + Word16 exp_out = Q11; + move16(); + /*LB CLDFB - CNA from STFT*/ + IF( cna_flag ) + { + /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ + IF( GT_16( hFdCngCom->likelihood_noisy_speech, DELTA_MASKING_NOISE_Q15 ) ) + { + /* Compute additional CN level */ + FOR( i = 0; i < 15; i++ ) + { + test(); + test(); + if ( ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_dirac[i].bwmode ) ) && + GE_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateFrom ) && + LT_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateTo ) ) + { + BREAK; + } + } + + scale = L_deposit_h( scaleTable_cn_dirac[i].scale_ivas ); /* Q30 */ + scale = Mpy_32_16_1( scale, hFdCngCom->likelihood_noisy_speech ); /* Q30 */ + } + } + + /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/ + test(); + IF( cna_flag && tdBuffer != NULL ) + { + WHILE( n_samples_out > 0 ) + { + n_samples_out_loop = s_min( hFdCngCom->frameSize, n_samples_out ); + IF( scale != 0 ) + { + /*Generate LF comfort noise only at first slot, for the whole frame*/ + ptr_level = cngNoiseLevel; /*hFdCngCom->cngNoiseLevelExp*/ + + /* Generate Gaussian random noise in real and imaginary parts of the FFT bins + Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */ + IF( EQ_16( hFdCngCom->startBand, 0 ) ) + { + rand_gauss_fx( &fftBuffer[0], seed, exp_out ); + ptr_r = fftBuffer + 2; /*hFdCngCom->fftBuffer_exp*/ + + Word16 exp2 = sub( 31, hFdCngCom->cngNoiseLevelExp ); + Word32 sqr = Sqrt32( L_shr( Mpy_32_32( scale, *ptr_level ), 1 ), &exp2 ); /* DC component in FFT Q31 - exp2*/ + sqr = L_shl( sqr, exp2 ); /*Q31*/ + fftBuffer[0] = Mpy_32_32( fftBuffer[0], sqr ); /* DC component in FFT Q31 - hFdCngCom->fftBuffer_exp*/ + move32(); + ptr_level++; + } + ELSE + { + fftBuffer[0] = 0; + move32(); + set32_fx( fftBuffer + 2, 0, shl( sub( hFdCngCom->startBand, 1 ), 1 ) ); + ptr_r = fftBuffer + shl( hFdCngCom->startBand, 1 ); /*hFdCngCom->fftBuffer_exp*/ + } + ptr_i = ptr_r + 1; /*hFdCngCom->fftBuffer_exp*/ + + FOR( ; ptr_level < cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); ptr_level++ ) + { + rand_gauss_fx( ptr_r, seed, exp_out ); + Word16 exp2 = hFdCngCom->cngNoiseLevelExp; + Word32 mpy2 = Sqrt32( Mpy_32_32( scale, *ptr_level ), &exp2 ); /*Q31 - exp2*/ + ( *ptr_r ) = L_shl( Mpy_32_32( *ptr_r, mpy2 ), exp2 ); /*Q31 - hFdCngCom->fftBuffer_exp*/ + move32(); + ptr_r += 2; + + /* Imaginary part in FFT bins */ + rand_gauss_fx( ptr_i, seed, exp_out ); + ( *ptr_i ) = L_shl( Mpy_32_32( *ptr_i, mpy2 ), exp2 ); /*Q31 - hFdCngCom->fftBuffer_exp*/ + move32(); + ptr_i += 2; + } + /* Remaining FFT bins are set to zero */ + set32_fx( fftBuffer + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) ); + /* Nyquist frequency is discarded */ + fftBuffer[1] = 0; + move32(); + + /* Perform STFT synthesis */ + SynthesisSTFT_dirac_fx( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, n_samples_out_loop, hFdCngCom ); + scale_sig32( tdBuffer + n_samples_start, n_samples_out_loop, Q9 ); // Q2 -> Q11 + } + + ELSE + { + /* very low level case - update random seeds */ + generate_masking_noise_update_seed_fx( hFdCngCom ); + + set32_fx( fftBuffer, 0, hFdCngCom->fftlen ); + /* Perform STFT synthesis */ + SynthesisSTFT_dirac_fx( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, n_samples_out_loop, hFdCngCom ); + } + hFdCngCom->fftBuffer_exp = 31 - 11; + move16(); + n_samples_out = sub( n_samples_out, hFdCngCom->frameSize ); + n_samples_start = add( n_samples_start, hFdCngCom->frameSize ); + } + } + + pop_wmops(); + + return; +} +void generate_masking_noise_dirac_ivas_fx( + HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ + HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */ + Word32 *tdBuffer_fx, /* i/o: time-domain signal, if NULL no LB-CNA q_input*/ + Word32 *Cldfb_RealBuffer_fx, /* o : CLDFD real buffer q_cldfb*/ + Word32 *Cldfb_ImagBuffer_fx, /* o : CLDFD imaginary buffer q_cldfb*/ + const Word16 slot_index, /* i : CLDFB slot index Q0*/ + const Word16 cna_flag, /* i : CNA flag for LB and HB Q0*/ + const Word16 fd_cng_flag, /* i : FD-CNG flag for HB Q0*/ + Word16 q_input, + Word16 *q_cldfb ) +{ + Word16 i; + Word32 *ptr_level_fx; + Word16 *seed = &( hFdCngCom->seed ); + Word32 scale_fx; + Word16 q_scale, q_shift, q_ptr_level; + + push_wmops( "fd_cng_dirac" ); + + /* Init */ + scale_fx = 0; + move32(); + + /* Resample CLDFB memories if necessary*/ + IF( NE_16( i_mult( h_cldfb->no_channels, h_cldfb->no_col ), hFdCngCom->frameSize ) ) + { + resampleCldfb_ivas_fx( h_cldfb, hFdCngCom->frameSize * FRAMES_PER_SEC ); + } + + set32_fx( Cldfb_RealBuffer_fx, 0, CLDFB_NO_CHANNELS_MAX ); + set32_fx( Cldfb_ImagBuffer_fx, 0, CLDFB_NO_CHANNELS_MAX ); + + /*LB CLDFB - CNA from STFT*/ + IF( cna_flag != 0 ) + { + /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ + IF( hFdCngCom->likelihood_noisy_speech > 0 ) + { + /* Compute additional CN level */ + FOR( i = 0; i < 15; i++ ) + { + test(); + test(); + if ( ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_dirac[i].bwmode ) ) && + ( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateFrom ) ) && + ( LT_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateTo ) ) ) + { + BREAK; + } + } + + scale_fx = L_shr( L_deposit_h( scaleTable_cn_dirac[i].scale_ivas ), Q3 ); /* Q27 */ + scale_fx = Mpy_32_16_1( scale_fx, hFdCngCom->likelihood_noisy_speech ); + } + } + /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/ + IF( cna_flag && tdBuffer_fx != NULL ) + { + *q_cldfb = q_input; + move16(); + IF( scale_fx != 0 ) + { + /* LF CLDFB*/ + cldfbAnalysis_ts_fx_fixed_q( &( tdBuffer_fx[( hFdCngCom->numCoreBands * slot_index )] ), Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hFdCngCom->numCoreBands, h_cldfb, q_cldfb ); + } + ELSE + { + /* LB ana CLDFB*/ + cldfbAnalysis_ts_fx_fixed_q( &( tdBuffer_fx[( hFdCngCom->numCoreBands * slot_index )] ), Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hFdCngCom->numCoreBands, h_cldfb, q_cldfb ); + } + } + + /*HF CLDFB - CNA and/or FD-CNG*/ + if ( fd_cng_flag ) + { + scale_fx = L_add( scale_fx, ONE_IN_Q27 ); // 1 in Q27 + } + IF( scale_fx != 0 ) + { + q_scale = 27; + move16(); + q_shift = norm_l( scale_fx ); + scale_fx = L_shl( scale_fx, q_shift ); /*q_scale+q_shift*/ + q_scale = add( q_scale, q_shift ); + scale_fx = Mpy_32_32( scale_fx, Mpy_32_16_1( L_mult( h_cldfb->scale, h_cldfb->scale ), CLDFB_SCALING ) ); // Q = q_scale + 2 * Q8 - 34 + q_scale = sub( add( q_scale, 2 * Q8 ), 31 ); + ptr_level_fx = hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q31 - hFdCngCom->cngNoiseLevelExp*/ + q_ptr_level = sub( 31, hFdCngCom->cngNoiseLevelExp ); + + FOR( i = hFdCngCom->numCoreBands; i < hFdCngCom->regularStopBand; i++ ) + { + Word32 num; + Word16 exp, q_num; + q_shift = norm_l( scale_fx ); + scale_fx = L_shl( scale_fx, q_shift ); /*q_scale+q_shift*/ + q_scale = add( q_scale, q_shift ); + num = Mpy_32_32( scale_fx, *ptr_level_fx ); /*q_num*/ + q_num = sub( add( q_scale, q_ptr_level ), 31 ); + exp = sub( 31, q_num ); + num = Sqrt32( num, &exp ); /*Q31 - exp*/ + /* Real part in CLDFB band */ + rand_gauss_fx( &Cldfb_RealBuffer_fx[i], seed, *q_cldfb ); + Cldfb_RealBuffer_fx[i] = L_shl( Mpy_32_32( Cldfb_RealBuffer_fx[i], num ), exp ); + move32(); + /* Imaginary part in CLDFB band */ + rand_gauss_fx( &Cldfb_ImagBuffer_fx[i], seed, *q_cldfb ); + Cldfb_ImagBuffer_fx[i] = L_shl( Mpy_32_32( Cldfb_ImagBuffer_fx[i], num ), exp ); + move32(); + + ptr_level_fx++; + } + } + + pop_wmops(); + + return; +} + + +/*------------------------------------------------------------------- + * FdCngDecodeMDCTStereoSID() + * + * Decode FD-Cng parameters for CNG in MDCT-Stereo mode from the bitstream + * + *-------------------------------------------------------------------*/ + +void FdCngDecodeMDCTStereoSID_fx( + CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */ +) +{ + DEC_CORE_HANDLE sts[CPE_CHANNELS]; + HANDLE_FD_CNG_COM hFdCngCom; + Word32 *ms_ptr_fx[CPE_CHANNELS]; + Word32 *lr_ptr_fx[CPE_CHANNELS]; + Word32 logNoiseEst_fx[CPE_CHANNELS][NPART]; + Word32 gain_fx[CPE_CHANNELS]; + Word16 indices[FD_CNG_stages_37bits]; + Word16 N, i, ch, p, stages; + Word16 is_out_ms; + Word32 *invTrfMatrix_fx; + Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; + Word16 shift, exp_diff, max_exp_idx; + Word16 exp_arr[NPART]; + Word32 tmp32, tmp32_arr[NPART]; + + invTrfMatrix_fx = (Word32 *) tmpRAM_fx; + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); // Q31 + + is_out_ms = 0; + move16(); + if ( hCPE->hCoreCoder[0]->cng_sba_flag ) + { + is_out_ms = 1; + move16(); + } + + N = 0; /* to avoid compilation warning */ + move16(); + + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + sts[ch] = hCPE->hCoreCoder[ch]; + ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; /*Q20*/ + lr_ptr_fx[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; /*Q18*/ + } + + /* decode noise shapes and gains */ + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + sts[ch] = hCPE->hCoreCoder[ch]; + hFdCngCom = ( sts[ch]->hFdCngDec )->hFdCngCom; + N = hFdCngCom->npart; + move16(); + hFdCngCom->sid_frame_counter = add( hFdCngCom->sid_frame_counter, 1 ); /*Q0*/ + move16(); + + IF( ch ) + { + stages = FD_CNG_JOINT_stages_25bits; + move16(); + } + ELSE + { + stages = FD_CNG_stages_37bits; + move16(); + } + + /* read bitstream */ + FOR( i = 0; i < stages; i++ ) + { + indices[i] = get_next_indice_fx( sts[ch], bits_37bits[i] ); /*Q0*/ + move16(); + } + { + gain_fx[ch] = Mpy_32_32( L_shl( L_sub( get_next_indice_fx( sts[ch], 7 ), GAIN_Q_OFFSET_IVAS_FX ), Q20 ), TWO_BY_THREE_Q31 /* 2/3 in Q31 */ ); // Q20 + move32(); + } + + /* MSVQ decoder */ + shift = find_guarded_bits_fx( N ); + msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, stages, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, ms_ptr_fx[ch], NULL, 7 ); // Q20 - shift + + Scale_sig32( ms_ptr_fx[ch], N, shift ); // Q20 + } + + dtx_read_padding_bits_fx( sts[1], mult( sub( IVAS_SID_5k2, 4400 ), ONE_BY_FRAMES_PER_SEC_Q15 ) ); + + IF( sts[0]->hFdCngDec->hFdCngCom->no_side_flag ) + { + set32_fx( ms_ptr_fx[1], 0, NPART ); + } + + IF( EQ_16( is_out_ms, 0 ) ) + { + inverseMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 ); + } + + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + max_exp_idx = 0; + move16(); + hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom; + FOR( p = 0; p < N; p++ ) + { + tmp32 = L_add( ms_ptr_fx[ch][p], gain_fx[ch] ); // Q20 + tmp32_arr[p] = BASOP_util_Pow2( Mpy_32_32( tmp32, LOG_10_BASE_2_BY_10_Q31 ), Q11, &exp_arr[p] ); /*Q31 - exp_arr[p]*/ + move32(); + if ( LT_16( exp_arr[max_exp_idx], exp_arr[p] ) ) + { + max_exp_idx = p; /*Q0*/ + move16(); + } + } + + // Bringing in same exponent + FOR( p = 0; p < N; p++ ) + { + lr_ptr_fx[ch][p] = L_shl( tmp32_arr[p], sub( exp_arr[p], exp_arr[max_exp_idx] ) ); /*Q31 - exp_arr[max_exp_idx]*/ + move32(); + } + + hFdCngCom->sidNoiseEstExp = exp_arr[max_exp_idx]; + move16(); + + scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 ); + + hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; + move16(); + + lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac ); + } + + test(); + IF( EQ_16( hCPE->nchan_out, 1 ) && LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) ) + { + /* create proper M noise shape in channel zero after gains have been applied */ + exp_diff = sub( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp ); + move16(); + FOR( p = 0; p < N; p++ ) + { + IF( GT_16( exp_diff, 0 ) ) + { + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], add( exp_diff, 1 ) ) ); /*Q18*/ + move32(); + } + ELSE + { + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], sub( 1, exp_diff ) ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ) ); /*Q18*/ + move32(); + } + } + IF( LT_16( exp_diff, 0 ) ) + { + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = add( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, negate( exp_diff ) ); + move16(); + } + } + + return; +} + + +/*------------------------------------------------------------------- + * FdCngDecodeDiracMDCTStereoSID_fx() + * + * Decode FD-CNG parameters for CNG in 2TC DirAC mode from the bitstream + *-------------------------------------------------------------------*/ + +void FdCngDecodeDiracMDCTStereoSID_fx( + CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */ +) +{ + DEC_CORE_HANDLE sts[CPE_CHANNELS]; + HANDLE_FD_CNG_COM hFdCngCom; + Word32 *ms_ptr_fx[CPE_CHANNELS]; + Word32 *lr_ptr_fx[CPE_CHANNELS]; + Word32 logNoiseEst_fx[CPE_CHANNELS][NPART]; + Word32 gain_fx[CPE_CHANNELS]; + Word16 indices[FD_CNG_stages_37bits]; + Word16 N, i, ch, p; + Word32 *invTrfMatrix_fx; + Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; + Word16 shift, exp_diff, max_exp_idx; + Word16 exp_arr[NPART]; + Word32 tmp32, tmp32_arr[NPART]; + + invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */ + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); // Q31 + + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + sts[ch] = hCPE->hCoreCoder[ch]; + ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; /*Q20*/ + lr_ptr_fx[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; /*Q20*/ + ( sts[ch]->hFdCngDec )->hFdCngCom->sid_frame_counter++; /*Q18*/ + } + + /* decode noise shapes and gains */ + hFdCngCom = ( sts[0]->hFdCngDec )->hFdCngCom; + N = hFdCngCom->npart; /*Q0*/ + move16(); + + /* read bitstream */ + FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) + { + indices[i] = get_next_indice_fx( sts[0], bits_37bits[i] ); /*Q0*/ + move16(); + } + gain_fx[0] = Mpy_32_32( L_shl( L_sub( get_next_indice_fx( sts[0], 7 ), GAIN_Q_OFFSET_IVAS_FX ), Q20 ), TWO_BY_THREE_Q31 /* 2/3 in Q31 */ ); // Q20 + move32(); + + gain_fx[1] = gain_fx[0]; /*Q20*/ + move32(); + + /* MSVQ decoder */ + shift = find_guarded_bits_fx( N ); + msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, ms_ptr_fx[0], NULL, 7 ); // Q20 - shift + + Scale_sig32( ms_ptr_fx[0], N, shift ); // Q20 + + Copy32( ms_ptr_fx[0], ms_ptr_fx[1], N ); /*Q20*/ + + FOR( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + max_exp_idx = 0; + move16(); + hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom; + + FOR( p = 0; p < N; p++ ) + { + tmp32 = L_add( ms_ptr_fx[ch][p], gain_fx[ch] ); // Q20 + tmp32_arr[p] = BASOP_util_Pow2( Mpy_32_32( tmp32, LOG_10_BASE_2_BY_10_Q31 ), Q11, &exp_arr[p] ); /*Q31 - exp_arr[p]*/ + move32(); + if ( LT_16( exp_arr[max_exp_idx], exp_arr[p] ) ) + { + max_exp_idx = p; /*Q0*/ + move16(); + } + } + + // Bringing in same exponent + FOR( p = 0; p < N; p++ ) + { + lr_ptr_fx[ch][p] = L_shl( tmp32_arr[p], sub( exp_arr[p], exp_arr[max_exp_idx] ) ); /*Q20*/ + move32(); + } + + hFdCngCom->sidNoiseEstExp = exp_arr[max_exp_idx]; /*Q0*/ + move16(); + + /* NB last band energy compensation */ + test(); + IF( hFdCngCom->CngBandwidth == NB ) + { + lr_ptr_fx[ch][( N - 1 )] = Mpy_32_32( lr_ptr_fx[ch][( N - 1 )], NB_LAST_BAND_SCALE_Q31 ); /*Q20*/ + move32(); + } + ELSE IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) + { + lr_ptr_fx[ch][( N - 1 )] = Mpy_32_32( lr_ptr_fx[ch][( N - 1 )], SWB_13k2_LAST_BAND_SCALE_Q31 ); /*Q20*/ + move32(); + } + + scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 ); + + hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; + move16(); + + lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac ); + } + sts[0]->hFdCngDec->hFdCngCom->coherence_fx = 0; + move16(); + sts[1]->hFdCngDec->hFdCngCom->coherence_fx = 0; + move16(); + + IF( EQ_16( hCPE->nchan_out, 1 ) ) + { + /* create proper M noise shape in channel zero after gains have been applied */ + exp_diff = sub( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp ); + FOR( p = 0; p < N; p++ ) + { + IF( exp_diff > 0 ) + { + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], add( exp_diff, 1 ) ) ); /*Q18*/ + move32(); + } + ELSE + { + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], sub( 1, exp_diff ) ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ) ); /*Q18*/ + move32(); + } + } + IF( exp_diff < 0 ) + { + sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = add( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, negate( exp_diff ) ); + move16(); + } + } + + return; +} + + #ifdef IVAS_CODE_CNG /*------------------------------------------------------------------- diff --git a/lib_dec/init_dec.c b/lib_dec/init_dec.c deleted file mode 100644 index 2b8091305..000000000 --- a/lib_dec/init_dec.c +++ /dev/null @@ -1,76 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include "cnst.h" -#include "ivas_cnst.h" -#include "rom_com.h" -#include "prot.h" -#include "wmc_auto.h" -#include "prot_fx.h" - -/*----------------------------------------------------------------------* - * init_decoder() - * - * Initialization of static variables for the decoder - *----------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------* - * reset_preecho_dec() - * - * Initialization of static variables for pre-echo - *----------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------* - * destroy_cldfb_decoder_flt() - * - * Free memory which was allocated in init_decoder() - *----------------------------------------------------------------------*/ -void destroy_cldfb_decoder_ivas_fx( - Decoder_State *st /* o : Decoder static variables structure */ -) -{ - /* CLDFB BPF & resampling tools */ - deleteCldfb_ivas_fx( &st->cldfbAna ); /* delete analysis at max. sampling rate 48kHz */ - deleteCldfb_ivas_fx( &st->cldfbBPF ); /* delete analysis BPF at max. internal sampling rate 16kHz */ - deleteCldfb_ivas_fx( &st->cldfbSyn ); /* delete synthesis at output sampling rate */ - deleteCldfb_ivas_fx( &st->cldfbSynHB ); - - deleteFdCngDec_fx( &st->hFdCngDec ); - - return; -} diff --git a/lib_dec/init_dec_fx.c b/lib_dec/init_dec_fx.c index a96774113..caa164df9 100644 --- a/lib_dec/init_dec_fx.c +++ b/lib_dec/init_dec_fx.c @@ -1822,3 +1822,18 @@ void destroy_cldfb_decoder_fx( return; } + +void destroy_cldfb_decoder_ivas_fx( + Decoder_State *st /* o : Decoder static variables structure */ +) +{ + /* CLDFB BPF & resampling tools */ + deleteCldfb_ivas_fx( &st->cldfbAna ); /* delete analysis at max. sampling rate 48kHz */ + deleteCldfb_ivas_fx( &st->cldfbBPF ); /* delete analysis BPF at max. internal sampling rate 16kHz */ + deleteCldfb_ivas_fx( &st->cldfbSyn ); /* delete synthesis at output sampling rate */ + deleteCldfb_ivas_fx( &st->cldfbSynHB ); + + deleteFdCngDec_fx( &st->hFdCngDec ); + + return; +} diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 459dcc4d4..5a948bdfa 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -3787,3 +3787,36 @@ static void ivas_param_mc_bs_decode_parameter_values_fx( return; } + +Word16 param_mc_get_num_cldfb_syntheses_ivas_fx( + Decoder_Struct *st_ivas /* i : Parametric MC handle */ +) +{ + Word16 num_cldfb_syntheses; + + num_cldfb_syntheses = 0; + move16(); + + /* sanity check*/ + IF( st_ivas->hParamMC == NULL ) + { + assert( 0 && "ParamMC handle does not exist!\n" ); + } + + test(); + IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) + { + num_cldfb_syntheses = 2; + move16(); + } + ELSE IF( EQ_16( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) + { + num_cldfb_syntheses = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); + } + ELSE IF( EQ_16( st_ivas->renderer_type, RENDERER_MC_PARAMMC ) ) + { + num_cldfb_syntheses = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); + } + + return num_cldfb_syntheses; +} diff --git a/lib_dec/ivas_mc_param_dec_fx.c b/lib_dec/ivas_mc_param_dec_fx.c deleted file mode 100644 index 0d9ee2710..000000000 --- a/lib_dec/ivas_mc_param_dec_fx.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "ivas_prot_fx.h" - -Word16 param_mc_get_num_cldfb_syntheses_ivas_fx( - Decoder_Struct *st_ivas /* i : Parametric MC handle */ -) -{ - Word16 num_cldfb_syntheses; - - num_cldfb_syntheses = 0; - move16(); - - /* sanity check*/ - IF( st_ivas->hParamMC == NULL ) - { - assert( 0 && "ParamMC handle does not exist!\n" ); - } - - test(); - IF( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) - { - num_cldfb_syntheses = 2; - move16(); - } - ELSE IF( EQ_16( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) - { - num_cldfb_syntheses = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ); - } - ELSE IF( EQ_16( st_ivas->renderer_type, RENDERER_MC_PARAMMC ) ) - { - num_cldfb_syntheses = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); - } - - return num_cldfb_syntheses; -} diff --git a/lib_dec/swb_bwe_dec.c b/lib_dec/swb_bwe_dec.c deleted file mode 100644 index 6b80108a8..000000000 --- a/lib_dec/swb_bwe_dec.c +++ /dev/null @@ -1,681 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "prot_fx.h" -#include "rom_com.h" -#include "basop_util.h" -#include "basop_proto_func.h" -#include "wmc_auto.h" - - -static Word16 para_pred_bws_fx( - Decoder_State *st_fx, /* i/o: decoder state structure */ - Word16 *signal_wb_fx, /* i : wideband frequency signal Q_syn */ - Word16 *SWB_fenv_fx, /* o : frequency-domain BWE envelope Q1 */ - Word16 Q_syn ) -{ - Word16 i, j, k; - Word16 mode; - Word16 tmp, tmp_den, tmp_num; - Word32 L_tmp, L_tmp_max; - Word16 exp; - Word16 *input_hi_fx; - Word32 *mea; - Word16 peak_fx, mag_fx; - Word32 mean_fx[7], peak_32_fx; - Word32 avrg1_fx, avrg2_fx, min_fx; - Word16 att_fx; - Word16 coder_type = st_fx->coder_type; - move16(); - - mode = NORMAL; - move16(); - - k = 0; - move16(); - input_hi_fx = &signal_wb_fx[SHARP_WIDTH]; /*Q_syn*/ - FOR( i = 0; i < 7; i++ ) - { - peak_fx = 0; - move16(); - mean_fx[i] = 0; - move16(); - FOR( j = 0; j < SHARP_WIDTH; j++ ) - { - mag_fx = abs_s( *input_hi_fx ); /*Q_syn*/ - peak_fx = s_max( peak_fx, mag_fx ); /*Q_syn*/ - mean_fx[i] = L_add( mean_fx[i], L_deposit_l( mag_fx ) ); /*Q_syn*/ - move32(); - input_hi_fx++; - } - - IF( LT_16( Q_syn, 11 ) ) - { - tmp = 1; - move16(); - } - ELSE - { - tmp = 0; - move16(); - if ( GT_16( shr( peak_fx, 3 ), shl( 1, Q_syn ) ) ) - { - tmp = 1; - move16(); - } - } - IF( tmp > 0 ) - { - L_tmp = L_msu0( Mult_32_16( L_shl( mean_fx[i], 10 ) /*Q_syn + 10*/, 18432 /*4.5f Q12*/ ), peak_fx /*Q_syn*/, 4544 /*35.5 (SHARP_WIDTH + 3.5f)Q7*/ ); - if ( L_tmp < 0 ) - { - k = add( k, 1 ); - } - } - } - - avrg1_fx = L_deposit_l( 0 ); - avrg2_fx = L_deposit_l( 0 ); - FOR( i = 1; i < 4; i++ ) - { - avrg1_fx = L_add( avrg1_fx, mean_fx[i] ); /*Q_syn*/ - avrg2_fx = L_add( avrg2_fx, mean_fx[i + 3] ); /*Q_syn*/ - } - avrg1_fx = Mult_32_16( avrg1_fx, 10923 /* 1/3 -> Q15 -> 10923 */ ); /*Q_syn + Q15 - 15*/ - avrg2_fx = Mult_32_16( avrg2_fx, 10923 /* 1/3 -> Q15 -> 10923 */ ); /*Q_syn + Q15 - 15*/ - - min_fx = L_add( 2147483647, 0 ); /*2^31 */ - peak_32_fx = L_deposit_l( 0 ); - FOR( i = 4; i < 7; i++ ) - { - IF( GT_32( mean_fx[i], L_shl( avrg2_fx, 1 ) ) ) - { - exp = norm_l( mean_fx[i] ); - IF( LT_16( exp, 16 ) ) - { - tmp_den = extract_l( L_shr( mean_fx[i], sub( 16, exp ) ) ); /*Qsyn - 16 + exp */ - tmp_num = extract_l( L_shr( avrg2_fx, sub( 15, exp ) ) ); /*Qsyn - 16 + exp */ - } - ELSE - { - tmp_den = extract_l( mean_fx[i] ); - tmp_num = extract_l( L_shl( avrg2_fx, 1 ) ); - } - - tmp_den = div_s( 1, tmp_den ); - - tmp = i_mult( tmp_num, tmp_den ); /*Q15 */ - - mean_fx[i] = Mult_32_16( mean_fx[i], tmp ); /*Q_syn + Q15 - 15*/ - move32(); - } - min_fx = L_min( min_fx, mean_fx[i] ); - peak_32_fx = L_max( peak_32_fx, mean_fx[i] ); - } - - IF( GT_16( st_fx->tilt_wb_fx, 16384 /*8 in Q11*/ ) ) - { - IF( GT_16( st_fx->tilt_wb_fx, 30720 /*15.0f in Q11*/ ) ) - { - min_fx = peak_32_fx; - move32(); - } - ELSE - { - tmp = extract_l( L_shr( L_mult0( st_fx->tilt_wb_fx, 17476 ), 14 ) ); /*Q15 */ - min_fx = Mult_32_16( peak_32_fx, tmp ); - } - } - - test(); - IF( peak_32_fx == 0 || min_fx == 0 ) - { - set16_fx( SWB_fenv_fx, 0, SWB_FENV ); - } - ELSE - { - exp = norm_l( peak_32_fx ); - IF( LT_16( exp, 16 ) ) - { - tmp_den = extract_l( L_shr( peak_32_fx, sub( 16, exp ) ) ); /*Qsyn - 16 + exp */ - tmp = div_s( 16384, tmp_den ); /*Q15+14 - (Qsyn - 16 + exp) */ - tmp_num = extract_l( L_shr( min_fx, sub( 16, exp ) ) ); /*Qsyn - 16 + exp */ - tmp = extract_l( L_shr( L_mult0( tmp_num, tmp ), 14 ) ); /*Q15 */ - } - ELSE - { - tmp_den = extract_l( peak_32_fx ); /*Qsyn */ - exp = norm_s( tmp_den ); - tmp = div_s( shl( 1, sub( 14, exp ) ), tmp_den ); /*Q 29-exp - Qsyn */ - tmp_num = extract_l( min_fx ); /*Qsyn */ - tmp = extract_l( L_shr( L_mult0( tmp_num, tmp ), sub( 14, exp ) ) ); /*Q15 */ - } - - j = 0; - move16(); - mea = &mean_fx[4]; - L_tmp_max = L_shl( 32767, add( Q_syn, 5 ) ); - FOR( i = 0; i < SWB_FENV; i++ ) - { - if ( EQ_16( j, 5 ) ) - { - mea++; - j = 0; - move16(); - } - j = add( j, 1 ); - L_tmp = L_min( Mult_32_16( *mea, tmp ), L_tmp_max ); - SWB_fenv_fx[i] = extract_l( L_shr( L_tmp, add( Q_syn, 5 ) ) ); - move16(); - } - } - - j = 0; - move16(); - FOR( i = SWB_FENV / 2; i < SWB_FENV; i++ ) - { - tmp = sub( 32767, i_mult( j, 2341 ) ); - SWB_fenv_fx[i] = mult_r( SWB_fenv_fx[i], tmp ); - move16(); - j = add( j, 1 ); - } - - IF( GT_32( avrg1_fx, L_shl( avrg2_fx, 3 ) ) ) - { - FOR( i = 0; i < SWB_FENV; i++ ) - { - SWB_fenv_fx[i] = shr( SWB_fenv_fx[i], 1 ); - move16(); - } - } - - test(); - test(); - test(); - test(); - test(); - IF( NE_16( st_fx->last_core, HQ_CORE ) && EQ_16( st_fx->last_codec_mode, MODE1 ) && - ( GT_32( st_fx->enerLH_fx, L_shr( st_fx->prev_enerLH_fx, 1 ) ) && LT_32( L_shr( st_fx->enerLH_fx, 1 ), st_fx->prev_enerLH_fx ) ) && - ( GT_32( st_fx->enerLL_fx, L_shr( st_fx->prev_enerLL_fx, 1 ) ) && LT_32( L_shr( st_fx->enerLL_fx, 1 ), st_fx->prev_enerLL_fx ) ) ) - { - FOR( i = 0; i < SWB_FENV; i++ ) - { - test(); - IF( NE_16( st_fx->prev_coder_type, coder_type ) && GT_16( mult_r( SWB_fenv_fx[i], 16384 /*1/2.0f in Q15*/ ), st_fx->prev_SWB_fenv_fx[i] ) ) - { - SWB_fenv_fx[i] = round_fx( L_mac( L_mult( SWB_fenv_fx[i], 3277 /*0.1f in Q15*/ ), st_fx->prev_SWB_fenv_fx[i], 29491 /*0.9f in Q15*/ ) ); - move16(); - } - ELSE - { - SWB_fenv_fx[i] = round_fx( L_mac( L_mult( SWB_fenv_fx[i], st_fx->attenu_fx ), st_fx->prev_SWB_fenv_fx[i], sub( 32767 /*1.0f in Q15*/, st_fx->attenu_fx ) ) ); - move16(); - } - } - - IF( LT_16( st_fx->attenu_fx, 29491 /*0.9f in Q15*/ ) ) - { - st_fx->attenu_fx = add( st_fx->attenu_fx, 1638 /*0.05f in Q15*/ ); - move16(); - } - } - ELSE - { - test(); - test(); - test(); - test(); - IF( NE_32( st_fx->core_brate, st_fx->last_core_brate ) || ( GT_32( st_fx->enerLH_fx, L_shr( st_fx->prev_enerLH_fx, 1 ) ) && LT_32( L_shr( st_fx->enerLH_fx, 1 ), st_fx->prev_enerLH_fx ) ) || - ( GT_32( st_fx->enerLL_fx, L_shr( st_fx->prev_enerLL_fx, 1 ) ) && LT_32( L_shr( st_fx->enerLL_fx, 1 ), st_fx->prev_enerLL_fx ) ) ) - { - FOR( i = 0; i < SWB_FENV; i++ ) - { - if ( GT_16( mult_r( SWB_fenv_fx[i], 16384 /*0.5f in Q15*/ ), st_fx->prev_SWB_fenv_fx[i] ) ) - { - SWB_fenv_fx[i] = st_fx->prev_SWB_fenv_fx[i]; - move16(); - } - } - } - - FOR( i = 0; i < SWB_FENV; i++ ) - { - SWB_fenv_fx[i] = round_fx( L_mac( L_mult( SWB_fenv_fx[i], 29491 /*0.9f in Q15*/ ), st_fx->prev_SWB_fenv_fx[i], 3277 /*0.1f in Q15*/ ) ); - move16(); - } - st_fx->attenu_fx = 3277; /*Q15*/ - move16(); - } - - if ( GT_16( k, 3 ) ) - { - mode = HARMONIC; - move16(); - } - - - att_fx = i_mult( sub( N_WS2N_FRAMES, st_fx->bws_cnt ), 819 ); /*15 */ - IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) - { - FOR( i = 0; i < 4; i++ ) - { - SWB_fenv_fx[i] = mult_r( SWB_fenv_fx[i], att_fx ); - move16(); /*Q1 */ - } - } - - FOR( i = 4; i < SWB_FENV; i++ ) - { - SWB_fenv_fx[i] = mult_r( SWB_fenv_fx[i], att_fx ); - move16(); /*Q1 */ - } - - return mode; -} - - -/*-------------------------------------------------------------------* - * WB_BWE_gain_deq() - * - * Decoding of WB parameters - *-------------------------------------------------------------------*/ - - -Word16 swb_bwe_dec_fx32( - Decoder_State *st_fx, /* i/o: decoder state structure */ - Word32 output_fx[], /* i : synthesis @internal Fs : Q11 */ - Word32 *synth_fx, /* i : ACELP core synthesis/final synthesis : Q11 */ - Word32 *hb_synth_fx, /* o : SHB synthesis/final synthesis : Q_syn_hb */ - Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - Word16 output_frame /* i : frame length */ -) -{ - Word16 L; - Word16 mode; - Word16 idxGain; - Word16 i, j, l_subfr; - Word16 fb_band_begin; - Word16 frica_flag = 0; - move16(); - Word16 ener_adjust_quan_fx; - Word16 fb_ener_adjust_fx = 0; - move16(); - Word16 scl, new_input_fx_exp, ysynth_frame_size; - Word16 Q_syn, Q_syn_hb, tmp, tmp2, q_tmp, Qsynth_fx16; - - Word16 ysynth_fx[L_FRAME48k]; - Word16 SWB_fenv_fx[SWB_FENV]; - Word16 SWB_tenv_fx[SWB_TENV]; - Word16 synth_fx16[L_FRAME48k]; - Word16 hb_synth_fx16[L_FRAME48k]; - - Word32 L_tmp; - Word32 yerror_fx[L_FRAME48k]; - Word32 ysynth_fx32[L_FRAME48k]; - Word32 SWB_tenv_tmp_fx[SWB_TENV]; - Word32 wtda_synth_fx[2 * L_FRAME48k]; - - FD_BWE_DEC_HANDLE hBWE_FD; - hBWE_FD = st_fx->hBWE_FD; - - /*---------------------------------------------------------------------* - * SWB BWE decoding - *---------------------------------------------------------------------*/ - test(); - IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && !use_cldfb_for_dft ) - { - /* todo - wtda() does not support L_FRAME length; thus temporarily resample the signal */ - /* todo - delay output[] by 1.25ms ? */ - L_lerp_fx_q11( output_fx, ysynth_fx32, L_FRAME16k, st_fx->L_frame ); - - /* windowing of the ACELP core synthesis */ - wtda_fx32( ysynth_fx32, wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx32, ALDO_WINDOW, ALDO_WINDOW, /*st_fx->L_frame*/ L_FRAME16k ); - - /* DCT of the ACELP core synthesis */ - new_input_fx_exp = 11; - move16(); - direct_transform_fx( wtda_synth_fx, ysynth_fx32, 0, /*st_fx->L_frame*/ L_FRAME16k, &new_input_fx_exp, st_fx->element_mode ); - ysynth_frame_size = L_FRAME16k; - move16(); - } - ELSE - { - /* windowing of the ACELP core synthesis */ - wtda_fx32( synth_fx, wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx32, ALDO_WINDOW, ALDO_WINDOW, output_frame ); - - /* DCT of the ACELP core synthesis */ - new_input_fx_exp = 11; - move16(); - direct_transform_fx( wtda_synth_fx, ysynth_fx32, 0, output_frame, &new_input_fx_exp, st_fx->element_mode ); - ysynth_frame_size = output_frame; - move16(); - } - - /* Convert to 16 Bits (Calc Shift Required to Stay within MAX_Q_NEW_INPUT) */ - scl = sub( 16 + 11, new_input_fx_exp ); - /* Possible to Upscale? */ - IF( scl > 0 ) - { - /* Yes */ - /* Calc Room to Upscale */ - Q_syn = sub( Find_Max_Norm32( ysynth_fx32, ysynth_frame_size ), 3 ); - /* Stay within MAX_Q_NEW_INPUT */ - scl = s_min( Q_syn, scl ); - } - /*Don't upscale if already in 15 bits*/ - IF( GT_16( scl, 15 ) ) - { - FOR( i = 0; i < ysynth_frame_size; i++ ) - { - ysynth_fx[i] = extract_l( ysynth_fx32[i] ); - move16(); - } - Q_syn = new_input_fx_exp; - move16(); - } - ELSE - { - Copy_Scale_sig32_16( ysynth_fx32, ysynth_fx, ysynth_frame_size, scl ); - Q_syn = add( sub( new_input_fx_exp, 16 ), scl ); - } - - IF( !st_fx->bfi ) - { - IF( st_fx->bws_cnt > 0 ) - { - /* estimate parameters */ - mode = para_pred_bws_fx( st_fx, ysynth_fx, SWB_fenv_fx, Q_syn ); - } - ELSE - { - /* de-quantization */ - mode = swb_bwe_gain_deq_fx( st_fx, ACELP_CORE, SWB_tenv_fx, SWB_fenv_fx, 0, -1 ); - } - - L = SWB_FENV; - move16(); - if ( EQ_16( mode, TRANSIENT ) ) - { - L = SWB_FENV_TRANS; - move16(); - } - - L_tmp = 0; - move32(); - FOR( i = 0; i < L; i++ ) - { - L_tmp = L_add( L_tmp, L_deposit_l( SWB_fenv_fx[i] ) ); - } - q_tmp = norm_s( L ); - tmp = div_s( shl( 1, sub( 14, q_tmp ) ), L ); /*Q(29-q_tmp) */ - L_tmp = Mpy_32_16_1( L_tmp, tmp ); /*Q(1+29-q_tmp+1-16)->Q(15-q_tmp) */ - st_fx->prev_ener_shb_fx = round_fx( L_shl( L_tmp, add( q_tmp, 2 ) ) ); /*Q1 */ - move16(); - } - ELSE - { - /* SHB FEC */ - - IF( NE_16( hBWE_FD->prev_mode, TRANSIENT ) ) - { - mode = hBWE_FD->prev_mode; - move16(); - } - ELSE - { - mode = NORMAL; - move16(); - } - - Copy( st_fx->prev_SWB_fenv_fx, SWB_fenv_fx, SWB_FENV ); - } - - /* reconstruction of MDCT spectrum of the error signal */ - set32_fx( yerror_fx, 0, output_frame ); - - IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) - { - SWB_BWE_decoding_fx( ysynth_fx, SWB_fenv_fx, yerror_fx, L_FRAME32k - 80, mode, &frica_flag, &hBWE_FD->prev_Energy_fx, st_fx->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, st_fx->tilt_wb_fx, &hBWE_FD->Seed, 80, &hBWE_FD->prev_weight_fx, st_fx->extl, Q_syn, st_fx->last_extl ); - } - ELSE - { - SWB_BWE_decoding_fx( ysynth_fx, SWB_fenv_fx, yerror_fx, L_FRAME32k - 80, mode, &frica_flag, &hBWE_FD->prev_Energy_fx, st_fx->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, st_fx->tilt_wb_fx, &hBWE_FD->Seed, 6, &hBWE_FD->prev_weight_fx, st_fx->extl, Q_syn, st_fx->last_extl ); - } - - test(); - IF( EQ_16( hBWE_FD->prev_frica_flag, 1 ) && frica_flag == 0 ) - { - FOR( i = 0; i < L_SUBFR; i++ ) - { - tmp = sub( 32767, extract_l( L_mult0( i, 512 ) ) ); /*Q15 */ - hBWE_FD->mem_imdct_fx[i] = mult_r( hBWE_FD->mem_imdct_fx[i], tmp ); - move16(); - } - - FOR( ; i < output_frame; i++ ) - { - hBWE_FD->mem_imdct_fx[i] = 0; - move16(); - } - } - - /* decode information */ - IF( EQ_16( st_fx->extl, FB_BWE ) ) - { - IF( !st_fx->bfi ) - { - idxGain = (Word16) get_next_indice_fx( st_fx, NUM_BITS_FB_FRAMEGAIN ); - fb_ener_adjust_fx = usdequant_fx( idxGain, FB_GAIN_QLOW_FX, FB_GAIN_QDELTA_FX ); /*Q15 */ - } - ELSE IF( st_fx->bfi ) - { - fb_ener_adjust_fx = st_fx->prev_fb_ener_adjust_fx; - move16(); - } - - st_fx->prev_fb_ener_adjust_fx = fb_ener_adjust_fx; - move16(); - IF( EQ_16( mode, TRANSIENT ) ) - { - ener_adjust_quan_fx = shr( fb_ener_adjust_fx, 2 ); - } - ELSE - { - IF( SWB_fenv_fx[7] != 0 ) - { - tmp = div_s( 1, SWB_fenv_fx[7] ); - ener_adjust_quan_fx = s_min( shr( i_mult_sat( SWB_fenv_fx[13], tmp ), 2 ), 32767 ); - } - ELSE - { - ener_adjust_quan_fx = 0; - move16(); - } - } - - fb_band_begin = FB_BAND_BEGIN; - move16(); - if ( EQ_16( st_fx->L_frame, L_FRAME ) ) - { - fb_band_begin = FB_BAND_BEGIN_12k8; - move16(); - } - - j = 0; - move16(); - FOR( i = fb_band_begin; i < add( fb_band_begin, DE_OFFSET1 ); i++ ) - { - tmp = sub( 32767, i_mult( j, 1024 ) ); - tmp = mult_r( tmp, ener_adjust_quan_fx ); /*Q13*/ - - tmp2 = i_mult( j, 256 ); /*Q13*/ - tmp2 = mult_r( tmp2, fb_ener_adjust_fx ); /*Q13*/ - - tmp = add( tmp, tmp2 ); /*Q13*/ - yerror_fx[i] = L_shl( Mpy_32_16_1( yerror_fx[i - FB_BAND_WIDTH], tmp ), 2 ); /*15+Q_syn */ - move32(); - j = add( j, 1 ); - } - FOR( ; i < FB_BAND_END; i++ ) - { - yerror_fx[i] = Mpy_32_16_1( yerror_fx[i - FB_BAND_WIDTH], fb_ener_adjust_fx ); /*15+Q_syn */ - move32(); - } - } - - /* iDCT of the error signal */ - Q_syn_hb = add( Q_syn, 15 ); - Inverse_Transform( yerror_fx, &Q_syn_hb, wtda_synth_fx, 0, output_frame, -1, st_fx->element_mode ); - - /* inverse windowing of the error signal */ - window_ola_fx( wtda_synth_fx, hb_synth_fx16, &Q_syn_hb, hBWE_FD->mem_imdct_fx, &hBWE_FD->mem_imdct_exp_fx, output_frame, ALDO_WINDOW, ALDO_WINDOW, 0, 0, 0 ); - l_subfr = mult( output_frame, 8192 ); - - test(); - IF( EQ_16( mode, TRANSIENT ) ) - { - FOR( i = 0; i < SWB_TENV; i++ ) - { - SWB_tenv_tmp_fx[i] = L_mult0( SWB_tenv_fx[i] /*Q0*/, 26214 /*0.8f Q15*/ ); // Q15 - move32(); - } - - /* time envelope shaping when the current frame is TRANSIENT frame */ - time_envelop_shaping_ivas_fx( hb_synth_fx16, SWB_tenv_tmp_fx, output_frame, &Q_syn_hb ); - - Q_syn_hb = sub( Q_syn_hb, 3 ); - - hBWE_FD->prev_td_energy_fx = SWB_tenv_fx[3]; - move16(); - } - ELSE IF( EQ_16( frica_flag, 1 ) && hBWE_FD->prev_frica_flag == 0 ) - { - Qsynth_fx16 = Find_Max_Norm32( synth_fx, output_frame ); - Qsynth_fx16 = sub( Qsynth_fx16, shr( add( sub( 15, norm_s( l_subfr ) ), 1 ), 1 ) ); - Copy_Scale_sig32_16( synth_fx, synth_fx16, output_frame, Qsynth_fx16 ); - Qsynth_fx16 = add( 11 - 16, Qsynth_fx16 ); - - /* IVAS_fmToDo: synth[] is @internal_Fs!!! */ - time_reduce_pre_echo_fx( synth_fx16, hb_synth_fx16, hBWE_FD->prev_td_energy_fx, l_subfr, Qsynth_fx16, Q_syn_hb ); - } - ELSE - { - tmp = i_mult2( 3, l_subfr ); - L_tmp = L_deposit_l( 0 ); - - FOR( i = 0; i < l_subfr; i++ ) - { - L_tmp = L_mac0_sat( L_tmp, hb_synth_fx16[add( tmp, i )], hb_synth_fx16[add( tmp, i )] ); /*(2*Q_syn_hb) */ - } - - L_tmp = Mult_32_16( L_tmp, div_s( 1, l_subfr ) ); /*(2*Q_syn_hb) */ - hBWE_FD->prev_td_energy_fx = 0; - move16(); - - IF( L_tmp != 0 ) - { - q_tmp = norm_l( L_tmp ); - tmp = extract_h( L_shl( L_tmp, q_tmp ) ); - q_tmp = sub( q_tmp, sub( 30, shl( Q_syn_hb, 1 ) ) ); - - tmp = div_s( 16384, tmp ); - L_tmp = L_deposit_h( tmp ); - L_tmp = Isqrt_lc( L_tmp, &q_tmp ); /*Q(31-exp) */ - hBWE_FD->prev_td_energy_fx = round_fx( L_shl( L_tmp, sub( q_tmp, 15 ) ) ); /*Q0 */ - move16(); - } - } - - test(); - IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && !use_cldfb_for_dft ) - { - Qsynth_fx16 = add( 16 - 11, Q_syn_hb ); - Copy_Scale_sig32_16( synth_fx, synth_fx16, output_frame, Qsynth_fx16 ); - - /* add HB synth from hf_synth() */ - v_add_16( hb_synth_fx16, synth_fx16, hb_synth_fx16, output_frame ); - } - - hBWE_FD->prev_mode = mode; - move16(); - hBWE_FD->prev_frica_flag = frica_flag; - move16(); - - FOR( i = 0; i < output_frame; i++ ) - { - hb_synth_fx[i] = L_deposit_l( hb_synth_fx16[i] ); // Q_syn_hb - move32(); - } - - return Q_syn_hb; -} - - -void fd_bwe_dec_init_fx( - FD_BWE_DEC_HANDLE hBWE_FD /* i/o: FD BWE data handle */ -) -{ - set16_fx( hBWE_FD->L_old_wtda_swb_fx, 0, L_FRAME48k ); - set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); - hBWE_FD->prev_mode = NORMAL; - move16(); - hBWE_FD->prev_Energy_fx = 0; - move16(); - hBWE_FD->prev_L_swb_norm = 8; - move16(); - hBWE_FD->Seed = 21211; - move16(); - hBWE_FD->prev_frica_flag = 0; - move16(); - set16_fx( hBWE_FD->mem_imdct_fx, 0, L_FRAME48k ); - hBWE_FD->prev_td_energy_fx = 0; - move16(); - hBWE_FD->prev_weight_fx = 0; - move16(); - hBWE_FD->prev_flag = 0; - move16(); - hBWE_FD->prev_Energy_wb_fx = 0; - move32(); - hBWE_FD->mem_deemph_old_syn_fx = 0; - move16(); - - return; -} diff --git a/lib_dec/swb_bwe_dec_fx.c b/lib_dec/swb_bwe_dec_fx.c index 9552bbf2f..23c4c3e8a 100644 --- a/lib_dec/swb_bwe_dec_fx.c +++ b/lib_dec/swb_bwe_dec_fx.c @@ -1266,3 +1266,372 @@ void fd_bwe_dec_init( return; } + +/*-------------------------------------------------------------------* + * WB_BWE_gain_deq() + * + * Decoding of WB parameters + *-------------------------------------------------------------------*/ + + +Word16 swb_bwe_dec_fx32( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word32 output_fx[], /* i : synthesis @internal Fs : Q11 */ + Word32 *synth_fx, /* i : ACELP core synthesis/final synthesis : Q11 */ + Word32 *hb_synth_fx, /* o : SHB synthesis/final synthesis : Q_syn_hb */ + Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ + Word16 output_frame /* i : frame length */ +) +{ + Word16 L; + Word16 mode; + Word16 idxGain; + Word16 i, j, l_subfr; + Word16 fb_band_begin; + Word16 frica_flag = 0; + move16(); + Word16 ener_adjust_quan_fx; + Word16 fb_ener_adjust_fx = 0; + move16(); + Word16 scl, new_input_fx_exp, ysynth_frame_size; + Word16 Q_syn, Q_syn_hb, tmp, tmp2, q_tmp, Qsynth_fx16; + + Word16 ysynth_fx[L_FRAME48k]; + Word16 SWB_fenv_fx[SWB_FENV]; + Word16 SWB_tenv_fx[SWB_TENV]; + Word16 synth_fx16[L_FRAME48k]; + Word16 hb_synth_fx16[L_FRAME48k]; + + Word32 L_tmp; + Word32 yerror_fx[L_FRAME48k]; + Word32 ysynth_fx32[L_FRAME48k]; + Word32 SWB_tenv_tmp_fx[SWB_TENV]; + Word32 wtda_synth_fx[2 * L_FRAME48k]; + + FD_BWE_DEC_HANDLE hBWE_FD; + hBWE_FD = st_fx->hBWE_FD; + + /*---------------------------------------------------------------------* + * SWB BWE decoding + *---------------------------------------------------------------------*/ + test(); + IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && !use_cldfb_for_dft ) + { + /* todo - wtda() does not support L_FRAME length; thus temporarily resample the signal */ + /* todo - delay output[] by 1.25ms ? */ + L_lerp_fx_q11( output_fx, ysynth_fx32, L_FRAME16k, st_fx->L_frame ); + + /* windowing of the ACELP core synthesis */ + wtda_fx32( ysynth_fx32, wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx32, ALDO_WINDOW, ALDO_WINDOW, /*st_fx->L_frame*/ L_FRAME16k ); + + /* DCT of the ACELP core synthesis */ + new_input_fx_exp = 11; + move16(); + direct_transform_fx( wtda_synth_fx, ysynth_fx32, 0, /*st_fx->L_frame*/ L_FRAME16k, &new_input_fx_exp, st_fx->element_mode ); + ysynth_frame_size = L_FRAME16k; + move16(); + } + ELSE + { + /* windowing of the ACELP core synthesis */ + wtda_fx32( synth_fx, wtda_synth_fx, hBWE_FD->L_old_wtda_swb_fx32, ALDO_WINDOW, ALDO_WINDOW, output_frame ); + + /* DCT of the ACELP core synthesis */ + new_input_fx_exp = 11; + move16(); + direct_transform_fx( wtda_synth_fx, ysynth_fx32, 0, output_frame, &new_input_fx_exp, st_fx->element_mode ); + ysynth_frame_size = output_frame; + move16(); + } + + /* Convert to 16 Bits (Calc Shift Required to Stay within MAX_Q_NEW_INPUT) */ + scl = sub( 16 + 11, new_input_fx_exp ); + /* Possible to Upscale? */ + IF( scl > 0 ) + { + /* Yes */ + /* Calc Room to Upscale */ + Q_syn = sub( Find_Max_Norm32( ysynth_fx32, ysynth_frame_size ), 3 ); + /* Stay within MAX_Q_NEW_INPUT */ + scl = s_min( Q_syn, scl ); + } + /*Don't upscale if already in 15 bits*/ + IF( GT_16( scl, 15 ) ) + { + FOR( i = 0; i < ysynth_frame_size; i++ ) + { + ysynth_fx[i] = extract_l( ysynth_fx32[i] ); + move16(); + } + Q_syn = new_input_fx_exp; + move16(); + } + ELSE + { + Copy_Scale_sig32_16( ysynth_fx32, ysynth_fx, ysynth_frame_size, scl ); + Q_syn = add( sub( new_input_fx_exp, 16 ), scl ); + } + + IF( !st_fx->bfi ) + { + IF( st_fx->bws_cnt > 0 ) + { + /* estimate parameters */ + mode = para_pred_bws_fx( st_fx, ysynth_fx, SWB_fenv_fx, Q_syn ); + } + ELSE + { + /* de-quantization */ + mode = swb_bwe_gain_deq_fx( st_fx, ACELP_CORE, SWB_tenv_fx, SWB_fenv_fx, 0, -1 ); + } + + L = SWB_FENV; + move16(); + if ( EQ_16( mode, TRANSIENT ) ) + { + L = SWB_FENV_TRANS; + move16(); + } + + L_tmp = 0; + move32(); + FOR( i = 0; i < L; i++ ) + { + L_tmp = L_add( L_tmp, L_deposit_l( SWB_fenv_fx[i] ) ); + } + q_tmp = norm_s( L ); + tmp = div_s( shl( 1, sub( 14, q_tmp ) ), L ); /*Q(29-q_tmp) */ + L_tmp = Mpy_32_16_1( L_tmp, tmp ); /*Q(1+29-q_tmp+1-16)->Q(15-q_tmp) */ + st_fx->prev_ener_shb_fx = round_fx( L_shl( L_tmp, add( q_tmp, 2 ) ) ); /*Q1 */ + move16(); + } + ELSE + { + /* SHB FEC */ + + IF( NE_16( hBWE_FD->prev_mode, TRANSIENT ) ) + { + mode = hBWE_FD->prev_mode; + move16(); + } + ELSE + { + mode = NORMAL; + move16(); + } + + Copy( st_fx->prev_SWB_fenv_fx, SWB_fenv_fx, SWB_FENV ); + } + + /* reconstruction of MDCT spectrum of the error signal */ + set32_fx( yerror_fx, 0, output_frame ); + + IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) + { + SWB_BWE_decoding_fx( ysynth_fx, SWB_fenv_fx, yerror_fx, L_FRAME32k - 80, mode, &frica_flag, &hBWE_FD->prev_Energy_fx, st_fx->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, st_fx->tilt_wb_fx, &hBWE_FD->Seed, 80, &hBWE_FD->prev_weight_fx, st_fx->extl, Q_syn, st_fx->last_extl ); + } + ELSE + { + SWB_BWE_decoding_fx( ysynth_fx, SWB_fenv_fx, yerror_fx, L_FRAME32k - 80, mode, &frica_flag, &hBWE_FD->prev_Energy_fx, st_fx->prev_SWB_fenv_fx, &hBWE_FD->prev_L_swb_norm, st_fx->tilt_wb_fx, &hBWE_FD->Seed, 6, &hBWE_FD->prev_weight_fx, st_fx->extl, Q_syn, st_fx->last_extl ); + } + + test(); + IF( EQ_16( hBWE_FD->prev_frica_flag, 1 ) && frica_flag == 0 ) + { + FOR( i = 0; i < L_SUBFR; i++ ) + { + tmp = sub( 32767, extract_l( L_mult0( i, 512 ) ) ); /*Q15 */ + hBWE_FD->mem_imdct_fx[i] = mult_r( hBWE_FD->mem_imdct_fx[i], tmp ); + move16(); + } + + FOR( ; i < output_frame; i++ ) + { + hBWE_FD->mem_imdct_fx[i] = 0; + move16(); + } + } + + /* decode information */ + IF( EQ_16( st_fx->extl, FB_BWE ) ) + { + IF( !st_fx->bfi ) + { + idxGain = (Word16) get_next_indice_fx( st_fx, NUM_BITS_FB_FRAMEGAIN ); + fb_ener_adjust_fx = usdequant_fx( idxGain, FB_GAIN_QLOW_FX, FB_GAIN_QDELTA_FX ); /*Q15 */ + } + ELSE IF( st_fx->bfi ) + { + fb_ener_adjust_fx = st_fx->prev_fb_ener_adjust_fx; + move16(); + } + + st_fx->prev_fb_ener_adjust_fx = fb_ener_adjust_fx; + move16(); + IF( EQ_16( mode, TRANSIENT ) ) + { + ener_adjust_quan_fx = shr( fb_ener_adjust_fx, 2 ); + } + ELSE + { + IF( SWB_fenv_fx[7] != 0 ) + { + tmp = div_s( 1, SWB_fenv_fx[7] ); + ener_adjust_quan_fx = s_min( shr( i_mult_sat( SWB_fenv_fx[13], tmp ), 2 ), 32767 ); + } + ELSE + { + ener_adjust_quan_fx = 0; + move16(); + } + } + + fb_band_begin = FB_BAND_BEGIN; + move16(); + if ( EQ_16( st_fx->L_frame, L_FRAME ) ) + { + fb_band_begin = FB_BAND_BEGIN_12k8; + move16(); + } + + j = 0; + move16(); + FOR( i = fb_band_begin; i < add( fb_band_begin, DE_OFFSET1 ); i++ ) + { + tmp = sub( 32767, i_mult( j, 1024 ) ); + tmp = mult_r( tmp, ener_adjust_quan_fx ); /*Q13*/ + + tmp2 = i_mult( j, 256 ); /*Q13*/ + tmp2 = mult_r( tmp2, fb_ener_adjust_fx ); /*Q13*/ + + tmp = add( tmp, tmp2 ); /*Q13*/ + yerror_fx[i] = L_shl( Mpy_32_16_1( yerror_fx[i - FB_BAND_WIDTH], tmp ), 2 ); /*15+Q_syn */ + move32(); + j = add( j, 1 ); + } + FOR( ; i < FB_BAND_END; i++ ) + { + yerror_fx[i] = Mpy_32_16_1( yerror_fx[i - FB_BAND_WIDTH], fb_ener_adjust_fx ); /*15+Q_syn */ + move32(); + } + } + + /* iDCT of the error signal */ + Q_syn_hb = add( Q_syn, 15 ); + Inverse_Transform( yerror_fx, &Q_syn_hb, wtda_synth_fx, 0, output_frame, -1, st_fx->element_mode ); + + /* inverse windowing of the error signal */ + window_ola_fx( wtda_synth_fx, hb_synth_fx16, &Q_syn_hb, hBWE_FD->mem_imdct_fx, &hBWE_FD->mem_imdct_exp_fx, output_frame, ALDO_WINDOW, ALDO_WINDOW, 0, 0, 0 ); + l_subfr = mult( output_frame, 8192 ); + + test(); + IF( EQ_16( mode, TRANSIENT ) ) + { + FOR( i = 0; i < SWB_TENV; i++ ) + { + SWB_tenv_tmp_fx[i] = L_mult0( SWB_tenv_fx[i] /*Q0*/, 26214 /*0.8f Q15*/ ); // Q15 + move32(); + } + + /* time envelope shaping when the current frame is TRANSIENT frame */ + time_envelop_shaping_ivas_fx( hb_synth_fx16, SWB_tenv_tmp_fx, output_frame, &Q_syn_hb ); + + Q_syn_hb = sub( Q_syn_hb, 3 ); + + hBWE_FD->prev_td_energy_fx = SWB_tenv_fx[3]; + move16(); + } + ELSE IF( EQ_16( frica_flag, 1 ) && hBWE_FD->prev_frica_flag == 0 ) + { + Qsynth_fx16 = Find_Max_Norm32( synth_fx, output_frame ); + Qsynth_fx16 = sub( Qsynth_fx16, shr( add( sub( 15, norm_s( l_subfr ) ), 1 ), 1 ) ); + Copy_Scale_sig32_16( synth_fx, synth_fx16, output_frame, Qsynth_fx16 ); + Qsynth_fx16 = add( 11 - 16, Qsynth_fx16 ); + + /* IVAS_fmToDo: synth[] is @internal_Fs!!! */ + time_reduce_pre_echo_fx( synth_fx16, hb_synth_fx16, hBWE_FD->prev_td_energy_fx, l_subfr, Qsynth_fx16, Q_syn_hb ); + } + ELSE + { + tmp = i_mult2( 3, l_subfr ); + L_tmp = L_deposit_l( 0 ); + + FOR( i = 0; i < l_subfr; i++ ) + { + L_tmp = L_mac0_sat( L_tmp, hb_synth_fx16[add( tmp, i )], hb_synth_fx16[add( tmp, i )] ); /*(2*Q_syn_hb) */ + } + + L_tmp = Mult_32_16( L_tmp, div_s( 1, l_subfr ) ); /*(2*Q_syn_hb) */ + hBWE_FD->prev_td_energy_fx = 0; + move16(); + + IF( L_tmp != 0 ) + { + q_tmp = norm_l( L_tmp ); + tmp = extract_h( L_shl( L_tmp, q_tmp ) ); + q_tmp = sub( q_tmp, sub( 30, shl( Q_syn_hb, 1 ) ) ); + + tmp = div_s( 16384, tmp ); + L_tmp = L_deposit_h( tmp ); + L_tmp = Isqrt_lc( L_tmp, &q_tmp ); /*Q(31-exp) */ + hBWE_FD->prev_td_energy_fx = round_fx( L_shl( L_tmp, sub( q_tmp, 15 ) ) ); /*Q0 */ + move16(); + } + } + + test(); + IF( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) && !use_cldfb_for_dft ) + { + Qsynth_fx16 = add( 16 - 11, Q_syn_hb ); + Copy_Scale_sig32_16( synth_fx, synth_fx16, output_frame, Qsynth_fx16 ); + + /* add HB synth from hf_synth() */ + v_add_16( hb_synth_fx16, synth_fx16, hb_synth_fx16, output_frame ); + } + + hBWE_FD->prev_mode = mode; + move16(); + hBWE_FD->prev_frica_flag = frica_flag; + move16(); + + FOR( i = 0; i < output_frame; i++ ) + { + hb_synth_fx[i] = L_deposit_l( hb_synth_fx16[i] ); // Q_syn_hb + move32(); + } + + return Q_syn_hb; +} + + +void fd_bwe_dec_init_fx( + FD_BWE_DEC_HANDLE hBWE_FD /* i/o: FD BWE data handle */ +) +{ + set16_fx( hBWE_FD->L_old_wtda_swb_fx, 0, L_FRAME48k ); + set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA_FX2( 16000, DELAY_FD_BWE_ENC_NS ) ); + hBWE_FD->prev_mode = NORMAL; + move16(); + hBWE_FD->prev_Energy_fx = 0; + move16(); + hBWE_FD->prev_L_swb_norm = 8; + move16(); + hBWE_FD->Seed = 21211; + move16(); + hBWE_FD->prev_frica_flag = 0; + move16(); + set16_fx( hBWE_FD->mem_imdct_fx, 0, L_FRAME48k ); + hBWE_FD->prev_td_energy_fx = 0; + move16(); + hBWE_FD->prev_weight_fx = 0; + move16(); + hBWE_FD->prev_flag = 0; + move16(); + hBWE_FD->prev_Energy_wb_fx = 0; + move32(); + hBWE_FD->mem_deemph_old_syn_fx = 0; + move16(); + + return; +} + diff --git a/lib_dec/swb_tbe_dec.c b/lib_dec/swb_tbe_dec.c deleted file mode 100644 index 80dfad505..000000000 --- a/lib_dec/swb_tbe_dec.c +++ /dev/null @@ -1,2478 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#include -#include "options.h" -#include -#include "cnst.h" -#include "prot.h" -#include "prot_fx.h" -#include "rom_com.h" -#include "rom_dec.h" -#include "wmc_auto.h" -#include "ivas_prot.h" -#include "ivas_prot_fx.h" - -/*-----------------------------------------------------------------* - * Local function prototypes - *-----------------------------------------------------------------*/ - - -void find_max_mem_dec_m3( - Decoder_State *st, - Word16 *n_mem3 ); - -/*-------------------------------------------------------------------* - * ResetSHBbuffer_Dec() - * - * - *-------------------------------------------------------------------*/ - -static void calc_tilt_bwe_fx_loc( - const Word32 *sp_fx, /* i : input signal : Q11 */ - Word32 *tilt_fx, /* o : signal tilt : tilt_fx_q */ - Word16 *tilt_fx_q, /* o : signal tilt */ - const Word16 N /* i : signal length : Q0 */ -) -{ - Word16 i; - Word64 r0_fx, r1_fx; - - r0_fx = EPSILON_FX_SMALL; - move64(); - FOR( i = 0; i < N; i++ ) - { - r0_fx = W_add( r0_fx, W_shr( W_mult_32_32( sp_fx[i], sp_fx[i] ), 1 ) ); /*Q11*2 - 1*/ - } - r1_fx = W_deposit32_l( abs( L_sub( sp_fx[1], sp_fx[0] ) ) ); /*Q11*/ - FOR( i = 2; i < N; i++ ) - { - IF( W_mult_32_32( L_sub( sp_fx[i], sp_fx[i - 1] ) /*Q11*/, L_sub( sp_fx[i - 1], sp_fx[i - 2] ) /*Q11*/ ) /*Q11 * 2 - 1*/ < 0 ) - { - r1_fx = W_add( r1_fx, W_deposit32_l( abs( L_sub( sp_fx[i], sp_fx[i - 1] ) ) ) ); /*Q11*/ - } - } - Word16 headroom_left_r0 = W_norm( r0_fx ); - Word16 headroom_left_r1 = W_norm( r1_fx ); - Word16 r0_q = 0, r1_q = 0; - move16(); - move16(); - IF( LT_16( headroom_left_r0, 32 ) ) - { - r0_fx = W_shr( r0_fx, sub( 32, headroom_left_r0 ) ); - r0_q = sub( 31, sub( ( 2 * OUTPUT_Q ), sub( 32, headroom_left_r0 ) ) ); - } - ELSE - { - r0_q = 31 - ( 2 * OUTPUT_Q ); - move16(); - } - - IF( LT_16( headroom_left_r1, 32 ) ) - { - r1_fx = W_shr( r1_fx, sub( 32, headroom_left_r1 ) ); - r1_q = sub( OUTPUT_Q, sub( 32, headroom_left_r1 ) ); - } - ELSE - { - r1_q = OUTPUT_Q; - move16(); - } - Word32 temp_r0_inv = ISqrt32( W_extract_l( r0_fx ), &r0_q ); - Word32 res = Mpy_32_32( W_extract_l( r1_fx ), temp_r0_inv ); - // Word16 res_q = r1_q + ( r0_q < 0 ? ( 31 + ( -1 * r0_q ) ) : r0_q ) - 31; - Word16 res_q; - IF( r0_q < 0 ) - { - res_q = add( r1_q, sub( add( 31, -r0_q ), 31 ) ); - } - ELSE - { - res_q = add( r1_q, sub( r0_q, 31 ) ); - } - Word16 norm_res = norm_l( res ); - IF( norm_res > 0 ) - { - *tilt_fx = L_shl_sat( res, norm_res ); - move32(); - *tilt_fx_q = add( res_q, norm_res ); - move16(); - } - ELSE - { - *tilt_fx = res; - move32(); - *tilt_fx_q = res_q; - move16(); - } - return; -} - -/*-------------------------------------------------------------------* - * swb_tbe_dec() - * - * SWB TBE decoder, 6 - 14 kHz (or 7.5 - 15.5 kHz) band decoding module - *-------------------------------------------------------------------*/ -static void rescale_genSHB_mem_dec( - Decoder_State *st_fx, - Word16 sf /*Q0*/ -) -{ - Word16 i; - TD_BWE_DEC_HANDLE hBWE_TD; - hBWE_TD = st_fx->hBWE_TD; - - FOR( i = 0; i < NL_BUFF_OFFSET; i++ ) - { - hBWE_TD->old_bwe_exc_extended_fx[i] = shl( hBWE_TD->old_bwe_exc_extended_fx[i], sf ); - move16(); - } - - FOR( i = 0; i < 7; i++ ) - { - hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i] = shl( hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i], sf ); - move16(); - } - - /* -- Apply memory scaling for 13.2 and 16.4k bps using sf ----*/ - IF( LT_32( st_fx->total_brate, ACELP_24k40 ) ) - { - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - hBWE_TD->state_lpc_syn_fx[i] = shl_sat( hBWE_TD->state_lpc_syn_fx[i], sf ); - move16(); - } - - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - hBWE_TD->state_syn_shbexc_fx[i] = shl_sat( hBWE_TD->state_syn_shbexc_fx[i], sf ); - move16(); - } - } - - hBWE_TD->mem_csfilt_fx[0] = L_shl( hBWE_TD->mem_csfilt_fx[0], sf ); - move32(); - - hBWE_TD->tbe_demph_fx = shl_r( hBWE_TD->tbe_demph_fx, sf ); - move16(); - hBWE_TD->tbe_premph_fx = shl_r( hBWE_TD->tbe_premph_fx, sf ); - move16(); -} - -static void gradientGainShape( - Decoder_State *st_fx, - Word16 *GainShape_fx, /*Q15*/ - Word32 *GainFrame_fx /* Q18 */ ) -{ - Word16 i, j, tmp; - Word16 GainShapeTemp[NUM_SHB_SUBFR / 4]; - Word16 GainGrad0[3]; - Word16 GainGrad1[3]; - Word16 GainGradFEC[4]; - TD_BWE_DEC_HANDLE hBWE_TD; - hBWE_TD = st_fx->hBWE_TD; - - - /* the previous frame gainshape gradient and the gainshape gradient pattern for the current frame */ - FOR( j = 0; j < 3; j++ ) - { - GainGrad0[j] = sub( shr( st_fx->GainShape_Delay[j + 1], 1 ), shr( st_fx->GainShape_Delay[j], 1 ) ); - move16(); /* Q14 */ - GainGrad1[j] = sub( shr( st_fx->GainShape_Delay[j + 5], 1 ), shr( st_fx->GainShape_Delay[j + 4], 1 ) ); - move16(); /* Q14 */ - GainGradFEC[j + 1] = add( mult_r( GainGrad0[j], 13107 /*0.4f in Q15*/ ), mult_r( GainGrad1[j], 19660 /*0.6f in Q15*/ ) ); - move16(); /* Q14 */ - } - - /* gradient for the first gainshape */ - test(); - test(); - test(); - IF( ( ( GT_16( shr( GainGrad1[2], 1 ), GainGrad1[1] ) ) && ( GT_16( shr( GainGrad1[1], 1 ), GainGrad1[0] ) ) ) || - ( ( LT_16( shr( GainGrad1[2], 1 ), GainGrad1[1] ) ) && ( LT_16( shr( GainGrad1[1], 1 ), GainGrad1[0] ) ) ) ) - { - GainGradFEC[0] = add( mult_r( GainGrad1[1], 3277 /*0.1f in Q15*/ ), mult_r( GainGrad1[2], 29490 /*0.9f in Q15*/ ) ); - move16(); /* Q14 */ - } - ELSE - { - GainGradFEC[0] = add( mult_r( GainGrad1[0], 6553 /*0.2f in Q15*/ ), mult_r( GainGrad1[1], 9830 /*0.3f in Q15*/ ) ); - move16(); - GainGradFEC[0] = add( GainGradFEC[0], mult_r( GainGrad1[2], 16384 /*0.5f in Q15*/ ) ); - move16(); /* Q14 */ - } - - /* get the first gainshape template */ - test(); - test(); - IF( ( EQ_16( st_fx->prev_coder_type, UNVOICED ) || ( st_fx->last_good == UNVOICED_CLAS ) ) && ( GainGradFEC[0] > 0 ) ) - { - GainShapeTemp[0] = add( shr( st_fx->GainShape_Delay[7], 1 ), GainGradFEC[0] ); - move16(); - } - ELSE IF( GainGradFEC[0] > 0 ) - { - GainShapeTemp[0] = add( shr( st_fx->GainShape_Delay[7], 1 ), mult_r( GainGradFEC[0], 16384 /*0.5f in Q15*/ ) ); - move16(); /* Q14 */ - } - ELSE - { - GainShapeTemp[0] = shr( st_fx->GainShape_Delay[7], 1 ); - move16(); /* Q14 */ - } - - /*Get the second the third and the fourth gainshape template*/ - - tmp = shr( GainGrad1[2], 3 ); /* GainGrad1[2]/8 */ - tmp = mult_r( tmp, 26214 ); /* 0.8 in Q15 tmp*(8/10) */ - - test(); - IF( ( GT_16( tmp, GainGrad1[1] ) ) && ( GainGrad1[1] > 0 ) ) - { - FOR( i = 1; i < NUM_SHB_SUBFR / 4; i++ ) - { - GainShapeTemp[i] = add( GainShapeTemp[i - 1], mult_r( GainGradFEC[i], 26214 /*0.8f in Q15*/ ) ); - move16(); /* GainShapeTemp[i-1] + 0.8* GainShapeTemp[i] */ - GainShapeTemp[i] = s_max( GainShapeTemp[i], 328 /*0.01f Q15*/ ); - move16(); - } - } - ELSE - { - test(); - IF( ( GT_16( tmp, GainGrad1[1] ) ) && ( GainGrad1[1] < 0 ) ) - { - FOR( i = 1; i < NUM_SHB_SUBFR / 4; i++ ) - { - GainShapeTemp[i] = add( GainShapeTemp[i - 1], mult_r( GainGradFEC[i], 6553 /*0.2f in Q15*/ ) ); - move16(); /* GainShapeTemp[i-1] + 0.8* GainShapeTemp[i] */ - GainShapeTemp[i] = s_max( GainShapeTemp[i], 328 /*0.01f Q15*/ ); - move16(); /* Q14 */ - } - } - ELSE - { - FOR( i = 1; i < NUM_SHB_SUBFR / 4; i++ ) - { - GainShapeTemp[i] = add( GainShapeTemp[i - 1], GainGradFEC[i] ); - move16(); - GainShapeTemp[i] = s_max( GainShapeTemp[i], 328 /*0.01f Q15*/ ); - move16(); - } - } - } - - /* Get the gainshape and gain frame for the current frame*/ - test(); - test(); - test(); - IF( ( EQ_16( st_fx->prev_coder_type, UNVOICED ) || ( st_fx->last_good == UNVOICED_CLAS ) ) && EQ_16( st_fx->nbLostCmpt, 1 ) ) - { - FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) - { - FOR( j = 0; j < 4; j++ ) - { - tmp = mult_r( GainShapeTemp[i], 19660 /*0.6f Q15*/ ); /* GainShapeTemp[i]*0.6 */ - - IF( GT_16( 8192, tmp ) ) - { - GainShape_fx[i * 4 + j] = shl( tmp, 2 ); /*Q15*/ - move16(); /* (GainShapeTemp[i]*0.6)>>1 */ - } - ELSE - { - GainShape_fx[i * 4 + j] = 32767; /*Q15*/ - move16(); /* Clipping here to avoid the a huge change of the code due to gain shape change */ - } - } - } - hBWE_TD->GainAttn_fx = mult_r( hBWE_TD->GainAttn_fx, 31129 ); - move16(); - } - ELSE IF( EQ_16( st_fx->prev_coder_type, UNVOICED ) || ( st_fx->last_good == UNVOICED_CLAS ) ) - { - FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) - { - FOR( j = 0; j < 4; j++ ) - { - IF( LT_16( GainShapeTemp[i], 16384 ) ) - { - GainShape_fx[i * 4 + j] = shl( GainShapeTemp[i], 1 ); /*Q15*/ - move16(); - } - ELSE - { - GainShape_fx[i * 4 + j] = 32767; // 1.0f in Q15 - move16(); - } - } - } - hBWE_TD->GainAttn_fx = mult_r( hBWE_TD->GainAttn_fx, 31129 /*0.95f in Q15*/ ); /*Q15*/ - move16(); - } - ELSE IF( GT_16( st_fx->nbLostCmpt, 1 ) ) - { - FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) - { - FOR( j = 0; j < 4; j++ ) - { - GainShape_fx[i * 4 + j] = GainShapeTemp[i]; /*Q15*/ - move16(); - } - } - hBWE_TD->GainAttn_fx = mult_r( hBWE_TD->GainAttn_fx, 16384 /*0.5f in Q15*/ ); /*Q15*/ - move16(); - } - ELSE - { - FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) - { - FOR( j = 0; j < 4; j++ ) - { - IF( LT_16( GainShapeTemp[i], 16384 ) ) - { - GainShape_fx[i * 4 + j] = shl( GainShapeTemp[i], 1 ); /*Q15*/ - move16(); - } - ELSE - { - GainShape_fx[i * 4 + j] = 32767; /*Q15*/ - move16(); - } - } - } - hBWE_TD->GainAttn_fx = mult_r( hBWE_TD->GainAttn_fx, 27852 /*0.85f in Q15*/ ); /*Q15*/ - move16(); - } - - *GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, hBWE_TD->GainAttn_fx ); /* Q18 */ - move32(); -} - -static void find_max_mem_dec( - Decoder_State *st_fx, - Word16 *n_mem, - Word16 *n_mem2, - Word16 *n_mem3 ) -{ - Word16 i; - Word16 n_mem_32; - Word16 max = 0; - move16(); - Word32 Lmax = 0; - move32(); - Word16 tempQ15, max2 = 0; - move16(); - Word16 max3; - Word32 tempQ32, Lmax3; - TD_BWE_DEC_HANDLE hBWE_TD; - hBWE_TD = st_fx->hBWE_TD; - - /* old BWE exc max */ - FOR( i = 0; i < NL_BUFF_OFFSET; i++ ) - { - tempQ15 = abs_s( hBWE_TD->old_bwe_exc_extended_fx[i] ); - max = s_max( max, tempQ15 ); - } - - /* decimate all-pass steep memory */ - FOR( i = 0; i < 7; i++ ) - { - tempQ15 = abs_s( hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i] ); - max = s_max( max, tempQ15 ); - } - - /* -- keep norm of state_lpc_syn_fx, state_syn_shbexc_fx, - and mem_stp_swb_fx separately for 24.4 and 32kbps ----*/ - /* findMaxMem2() inside tbe com */ - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - tempQ15 = abs_s( hBWE_TD->state_lpc_syn_fx[i] ); - max2 = s_max( max2, tempQ15 ); - } - - /* findMaxMem2() inside tbe com */ - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - tempQ15 = abs_s( hBWE_TD->state_syn_shbexc_fx[i] ); - max2 = s_max( max2, tempQ15 ); - } - - /* findMaxMem2() inside tbe com */ - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - tempQ15 = abs_s( hBWE_TD->mem_stp_swb_fx[i] ); - max2 = s_max( max2, tempQ15 ); - } - - /* for total_brate > 16.4kbps, use n_mem2; else account for the max2 for n_mem calculation */ - *n_mem2 = norm_s( max2 ); - move16(); - if ( max2 == 0 ) - { - *n_mem2 = 15; - move16(); - } - - if ( LT_32( st_fx->total_brate, ACELP_24k40 ) ) - { - max = s_max( max, max2 ); - } - - /* de-emph and pre-emph memory */ - tempQ15 = abs_s( hBWE_TD->tbe_demph_fx ); - max = s_max( max, tempQ15 ); - - tempQ15 = abs_s( hBWE_TD->tbe_premph_fx ); - max = s_max( max, tempQ15 ); - - IF( EQ_16( st_fx->extl, FB_TBE ) ) - { - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - tempQ15 = abs_s( hBWE_TD->fb_state_lpc_syn_fx[i] ); - max = s_max( max, tempQ15 ); - } - /* FB de-emph memory */ - tempQ15 = abs_s( hBWE_TD->fb_tbe_demph_fx ); - max = s_max( max, tempQ15 ); - } - /* estimate the norm for 16-bit memories */ - *n_mem = norm_s( max ); - move16(); - if ( max == 0 ) - { - *n_mem = 15; - move16(); - } - - /* estimate the norm for 32-bit memories */ - Lmax = L_abs( hBWE_TD->mem_csfilt_fx[0] ); /* only element [0] is used in env. shaping */ - - n_mem_32 = norm_l( Lmax ); - if ( Lmax == 0 ) - { - n_mem_32 = 31; - move16(); - } - - tempQ15 = sub( s_min( *n_mem, n_mem_32 ), 1 ); - *n_mem = s_max( tempQ15, 0 ); - move16(); - - /* --------------------------------------------------------------*/ - /* Find headroom for synthesis stage associated with these memories: - 1. st_fx->syn_overlap_fx - 2. st_fx->genSHBsynth_state_lsyn_filt_shb_local - 3. st_fx->genSHBsynth_Hilbert_Mem_fx (32-bit) */ - max3 = 0; - move16(); - /* find max in prev overlapSyn */ - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - tempQ15 = abs_s( hBWE_TD->syn_overlap_fx[i] ); - max3 = s_max( max3, tempQ15 ); - } - /* find max in prev genSHBsynth_state_lsyn_filt_shb_local_fx */ - FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ ) - { - tempQ15 = abs_s( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i] ); - max3 = s_max( max3, tempQ15 ); - } - /* find max in prev int_3_over_2_tbemem_dec_fx */ - IF( EQ_32( st_fx->output_Fs, 48000 ) ) - { - FOR( i = 0; i < INTERP_3_2_MEM_LEN; i++ ) - { - tempQ15 = abs_s( hBWE_TD->int_3_over_2_tbemem_dec_fx[i] ); - max3 = s_max( max3, tempQ15 ); - } - } - IF( EQ_32( st_fx->output_Fs, 16000 ) ) - { - FOR( i = 0; i < ( 2 * ALLPASSSECTIONS_STEEP + 1 ); i++ ) - { - tempQ15 = abs_s( hBWE_TD->mem_resamp_HB_32k_fx[i] ); - max3 = s_max( max3, tempQ15 ); - } - } - /* estimate the norm for 16-bit memories */ - *n_mem3 = norm_s( max3 ); - move16(); - if ( max3 == 0 ) - { - *n_mem3 = 15; - move16(); - } - - Lmax3 = 0; - move32(); - IF( EQ_16( st_fx->L_frame, L_FRAME ) ) - { - /* find max in prev genSHBsynth_Hilbert_Mem_fx */ - FOR( i = 0; i < HILBERT_MEM_SIZE; i++ ) - { - tempQ32 = L_abs( hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i] ); - Lmax3 = L_max( Lmax3, tempQ32 ); - } - } - - /* estimate the norm for 32-bit memories */ - n_mem_32 = norm_l( Lmax3 ); - if ( Lmax3 == 0 ) - { - n_mem_32 = 31; - move16(); - } - - tempQ15 = sub( s_min( *n_mem3, n_mem_32 ), 2 ); /* very important leave at least 2 bit head room - because of the Hilber transform and Q14 coeffs */ - *n_mem3 = s_max( tempQ15, 0 ); - move16(); - /* --------------------------------------------------------------*/ -} - -void find_max_mem_dec_m3( - Decoder_State *st, - Word16 *n_mem3 ) -{ - Word16 i; - // Word16 n_mem_32; - Word16 tempQ15; - Word16 max3; - // Word32 tempQ32, Lmax3; - TD_BWE_DEC_HANDLE hBWE_TD; - hBWE_TD = st->hBWE_TD; - - /* --------------------------------------------------------------*/ - /* Find headroom for synthesis stage associated with these memories: - 1. st->syn_overlap_fx*/ - max3 = 0; - move16(); - /* find max in prev overlapSyn */ - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - tempQ15 = abs_s( hBWE_TD->syn_overlap_fx[i] ); - max3 = s_max( max3, tempQ15 ); - } - /* find max in prev genSHBsynth_state_lsyn_filt_shb_local_fx */ - - /* estimate the norm for 16-bit memories */ - *n_mem3 = norm_s( max3 ); - move16(); - if ( max3 == 0 ) - { - *n_mem3 = 15; - move16(); - } -} - -/*-------------------------------------------------------------------* - * ivas_swb_tbe_dec_fx() - * - * SWB TBE decoder, 6 - 14 kHz (or 7.5 - 15.5 kHz) band decoding module - *-------------------------------------------------------------------*/ -void ivas_swb_tbe_dec_fx( - Decoder_State *st, /* i/o: decoder state structure */ - STEREO_ICBWE_DEC_HANDLE hStereoICBWE, /* i/o: IC-BWE state structure */ - const Word32 *bwe_exc_extended_fx, /* i : bandwidth extended excitation : Q_exc */ - Word16 Q_exc, - const Word16 voice_factors_fx[], /* i : voicing factors : Q15 */ - const Word32 old_syn_12k8_16k_fx[], /* i : low band synthesis : old_syn_fx */ - Word16 *White_exc16k_fx, /* o : shaped white excitation for the FB TBE : Q_white_exc*/ - Word32 *synth_fx, /* o : SHB synthesis/final synthesis : Qx */ - Word16 *pitch_buf_fx, /* i : Q6 */ - Word16 *Q_white_exc ) -{ - Word16 i, j, cnt, n; - Word16 stemp; - TD_BWE_DEC_HANDLE hBWE_TD; - Word32 shaped_shb_excitation_fx_32[L_FRAME16k + L_SHB_LAHEAD]; - Word16 bwe_exc_extended_16[L_FRAME32k + NL_BUFF_OFFSET]; - Word16 shaped_shb_excitation_fx[L_FRAME16k + L_SHB_LAHEAD]; - Word16 lsf_shb_fx[LPC_SHB_ORDER], lpc_shb_fx[LPC_SHB_ORDER + 1], GainShape_fx[NUM_SHB_SUBFR]; // Q12,Q12,Q15 - Word32 GainFrame_fx; // Q18 - Word32 error_fx[L_FRAME32k]; - Word16 ener_fx; - Word32 L_ener; - Word16 is_fractive; - Word32 prev_pow_fx, curr_pow_fx, Lscale; - Word16 scale_fx; - Word16 max_val, temp_fx, shaped_shb_excitation_frac[L_FRAME16k + L_SHB_LAHEAD]; - Word32 curr_frame_pow_fx; - Word16 curr_frame_pow_exp; - Word32 L_prev_ener_shb; - Word16 vf_modified_fx[NB_SUBFR16k]; - Word16 f_fx, inc_fx; - Word32 GainFrame_prevfrm_fx; - Word32 tilt_swb_fec_32_fx; - Word16 tilt_swb_fec_fx_q; - Word16 tilt_swb_fec_fx; - Word32 prev_ener_ratio_fx = 0; /* initialize just to avoid compiler warning */ - Word16 lsp_shb_1_fx[LPC_SHB_ORDER], lsp_shb_2_fx[LPC_SHB_ORDER], lsp_temp_fx[LPC_SHB_ORDER]; - Word16 lpc_shb_sf_fx[4 * ( LPC_SHB_ORDER + 1 )]; - const Word16 *ptr_lsp_interp_coef_fx; - Word32 shb_ener_sf_32; - Word16 shb_res_gshape_fx[NB_SUBFR16k]; - Word16 mixFactors_fx; - Word16 vind; - Word16 shb_res_dummy_fx[L_FRAME16k]; - Word16 shaped_shb_excitationTemp_fx[L_FRAME16k]; - Word32 ener_tmp_fx[NUM_SHB_SUBGAINS]; - Word16 GainShape_tmp_fx[NUM_SHB_SUBGAINS]; - Word16 pitch_fx; - Word16 l_subframe; - Word16 formant_fac_fx; - Word16 synth_scale_fx; - Word16 lsf_diff_fx[LPC_SHB_ORDER], w_fx[LPC_SHB_ORDER]; - Word16 refl_fx[M]; - Word16 tilt_para_fx; - Word16 *nlExc16k_fx, *mixExc16k_fx; - Word16 MSFlag; - Word16 feedback_fx; - Word16 GainShape_tilt_fx; - - // scaling - Word16 exp, tmp; - Word16 tmp1, tmp2; - Word16 mean_vf; - Word32 Lmax, L_tmp; - Word16 frac; - Word32 L_tmp1, L_tmp2; - Word16 Q_bwe_exc; - Word16 Q_bwe_exc_fb; - Word16 Q_shb; - Word16 n_mem, n_mem2, n_mem3, Qx, sc; - Word16 expa, expb; - Word16 fraca, fracb; - Word16 exp_ener, inv_ener; - - hBWE_TD = st->hBWE_TD; - - /* initializations */ - GainFrame_fx = 0; - move32(); - mixFactors_fx = 0; - move16(); - shb_ener_sf_32 = 0; - move32(); - set16_fx( shaped_shb_excitationTemp_fx, 0, L_FRAME16k ); - if ( st->hTdCngDec != NULL ) - { - st->hTdCngDec->shb_dtx_count = 0; - move16(); - } - is_fractive = 0; - move16(); - - IF( hStereoICBWE != NULL ) - { - nlExc16k_fx = hStereoICBWE->nlExc16k_fx; - mixExc16k_fx = hStereoICBWE->mixExc16k_fx; - MSFlag = hStereoICBWE->MSFlag; - move16(); - } - ELSE - { - nlExc16k_fx = NULL; - mixExc16k_fx = NULL; - MSFlag = 0; - move16(); - } - - /* find tilt */ - calc_tilt_bwe_fx_loc( old_syn_12k8_16k_fx, &tilt_swb_fec_32_fx, &tilt_swb_fec_fx_q, L_FRAME ); - tilt_swb_fec_fx = round_fx_sat( L_shl_sat( tilt_swb_fec_32_fx, sub( 11 + 16, tilt_swb_fec_fx_q ) ) ); - test(); - if ( st->bfi && st->clas_dec != UNVOICED_CLAS ) - { - tilt_swb_fec_fx = hBWE_TD->tilt_swb_fec_fx; - move16(); - } - - /* WB/SWB bandwidth switching */ - test(); - test(); - IF( ( GT_16( st->tilt_wb_fx, 10240 /*5 in Q11*/ ) && ( EQ_16( st->clas_dec, UNVOICED_CLAS ) ) ) || GT_16( st->tilt_wb_fx, 20480 /*10 in Q11*/ ) ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( ( st->prev_fractive == 0 ) && - ( LT_32( st->prev_enerLH_fx, L_shl( st->enerLH_fx, 1 ) ) && GT_32( st->prev_enerLH_fx, L_shr( st->enerLH_fx, 1 ) ) && LT_32( st->prev_enerLL_fx, L_shl( st->enerLL_fx, 1 ) ) && GT_32( st->prev_enerLL_fx, L_shr( st->enerLL_fx, 1 ) ) ) ) || - ( EQ_16( st->prev_fractive, 1 ) && - GT_32( L_shr( st->prev_enerLH_fx, 2 ), Mult_32_16( st->enerLH_fx, 24576 ) ) ) /* 24576 in Q13*/ - || ( GT_32( L_shr( st->enerLL_fx, 1 ), Mult_32_16( st->enerLH_fx, 24576 ) ) && /*24576 = 1.5 in Q14*/ - LT_16( st->tilt_wb_fx, 20480 ) ) /* 20480 = 10 in Q11*/ - ) - { - is_fractive = 0; - } - ELSE - { - is_fractive = 1; - } - move16(); - } - - /* WB/SWB bandwidth switching */ - IF( st->bws_cnt > 0 ) - { - f_fx = 1489; /*1.0f / 22.0f in Q15*/ - move16(); - inc_fx = 1489; /*1.0f / 22.0f in Q15*/ - move16(); - - IF( EQ_16( is_fractive, 1 ) ) - { - Copy( lsf_tab_fx, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER ); - } - ELSE - { - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - hBWE_TD->lsp_prevfrm_fx[i] = f_fx; /*Q15*/ - move16(); - f_fx = add( f_fx, inc_fx ); /*Q15*/ - } - } - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) && !( ( L_sub( L_shr( st->prev_enerLH_fx, 1 ), st->enerLH_fx ) < 0 ) && L_sub( st->prev_enerLH_fx, ( L_shr( st->enerLH_fx, 1 ) > 0 ) ) ) ) || st->last_core != ACELP_CORE || ( ( st->last_core == ACELP_CORE ) && GT_32( abs( L_sub( st->last_core_brate, st->core_brate ) ), 3600 ) ) || EQ_16( s_xor( is_fractive, st->prev_fractive ), 1 ) ) - { - set16_fx( GainShape_fx, 11587, NUM_SHB_SUBFR ); /*0.3536f in Q15*/ - } - ELSE - { - if ( GT_16( hBWE_TD->prev_GainShape_fx, 11587 ) ) /*0.3536f in Q15*/ - { - hBWE_TD->prev_GainShape_fx = 11587; /*0.3536f in Q15*/ - move16(); - } - set16_fx( GainShape_fx, hBWE_TD->prev_GainShape_fx, NUM_SHB_SUBFR ); - } - - Copy( hBWE_TD->lsp_prevfrm_fx, lsf_shb_fx, LPC_SHB_ORDER ); - set16_fx( shb_res_gshape_fx, 3277 /*0.2f Q14*/, NB_SUBFR16k ); /* Q14 */ - } - ELSE - { - test(); - IF( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) ) - { - f_fx = 1489; /*Q15*/ - move16(); - inc_fx = 1489; /*Q15*/ - move16(); - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - hBWE_TD->lsp_prevfrm_fx[i] = f_fx; /*Q15*/ - move16(); - f_fx = add( f_fx, inc_fx ); - } - } - - IF( !st->bfi ) - { - IF( st->use_partial_copy ) - { - IF( NE_16( st->last_extl, SWB_TBE ) ) - { - hBWE_TD->GainFrame_prevfrm_fx = 0; - move32(); - f_fx = 1489 /*0.045454f Q15*/; - move16(); - inc_fx = 1489 /*0.045454f Q15*/; - move16(); - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - hBWE_TD->lsp_prevfrm_fx[i] = f_fx; /*Q15*/ - move16(); - f_fx = add( f_fx, inc_fx ); /*Q15*/ - } - } - Copy( hBWE_TD->lsp_prevfrm_fx, lsf_shb_fx, LPC_SHB_ORDER ); - set16_fx( GainShape_fx, RECIP_ROOT_EIGHT_FX, NUM_SHB_SUBFR ); - - IF( EQ_16( st->rf_frame_type, RF_NELP ) ) - { - /* Frame gain */ - - GainFrame_fx = L_mac( SHB_GAIN_QLOW_FX, st->rf_indx_tbeGainFr, SHB_GAIN_QDELTA_FX ); - L_tmp = Mult_32_16( GainFrame_fx, 27213 ); /*Q16*/ /* 3.321928 in Q13 */ - - frac = L_Extract_lc( L_tmp, &exp ); - L_tmp = Pow2( 30, frac ); - GainFrame_fx = L_shl( L_tmp, sub( exp, 12 ) ); /*Q18*/ - - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( st->core == ACELP_CORE ) && ( st->last_core == ACELP_CORE ) && !st->prev_use_partial_copy && EQ_16( st->prev_coder_type, UNVOICED ) && NE_32( GainFrame_fx, hBWE_TD->GainFrame_prevfrm_fx ) && NE_16( st->next_coder_type, GENERIC ) && EQ_16( st->last_extl, SWB_TBE ) ) - { - GainFrame_fx = L_add( Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 26214 /*0.8f in Q15*/ ), Mult_32_16( GainFrame_fx, 6553 /*0.2f in Q15*/ ) ); - } - } - ELSE - { - temp_fx = 0; - move16(); - /* Frame gain */ - SWITCH( st->rf_indx_tbeGainFr ) - { - case 0: - GainFrame_fx = 131072; /* 0.5f in Q18 */ - move32(); - if ( LE_32( hBWE_TD->GainFrame_prevfrm_fx, 327680l /*1.25 Q18*/ ) ) - { - temp_fx = 26214 /*0.8 Q15*/; - move16(); - } - BREAK; - case 1: - GainFrame_fx = 524288; /* 2.0f in Q18 */ - move32(); - test(); - if ( GT_32( hBWE_TD->GainFrame_prevfrm_fx, 327680l /*1.25 Q18*/ ) && LE_32( hBWE_TD->GainFrame_prevfrm_fx, 786432l /*3 Q18*/ ) ) - { - temp_fx = 26214 /*0.8 Q15*/; - move16(); - } - BREAK; - case 2: - GainFrame_fx = 1048576; /* 4.0f in Q18 */ - move32(); - test(); - if ( GT_32( hBWE_TD->GainFrame_prevfrm_fx, 786432l /*3 Q18*/ ) && LE_32( hBWE_TD->GainFrame_prevfrm_fx, 1572864l /*6 Q18*/ ) ) - { - temp_fx = 26214 /*0.8 Q15*/; - move16(); - } - BREAK; - case 3: - GainFrame_fx = 2097152; /* 8.0f in Q18 */ - move32(); - test(); - if ( GT_32( hBWE_TD->GainFrame_prevfrm_fx, 1572864l /*6 Q18*/ ) && LE_32( hBWE_TD->GainFrame_prevfrm_fx, 4194304l /*16Q18*/ ) ) - { - temp_fx = 26214 /*0.8 Q15*/; - move16(); - } - BREAK; - default: - fprintf( stderr, "RF SWB-TBE gain bits not supported." ); - } - - IF( EQ_16( st->last_extl, SWB_TBE ) ) - { - GainFrame_fx = L_add( Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, temp_fx ), Mult_32_16( GainFrame_fx, sub( 32767, temp_fx ) ) ); - /*Q18*/ - } - - IF( ( st->core == ACELP_CORE ) && ( st->last_core == ACELP_CORE ) ) - { - if ( !st->prev_use_partial_copy && EQ_16( st->last_coder_type, VOICED ) && EQ_16( st->rf_frame_type, RF_GENPRED ) && GT_32( GainFrame_fx, 2097152 /*8.0f in Q18*/ ) && LT_32( GainFrame_fx, 3059606 /*11.67f in Q18*/ ) ) - { - GainFrame_fx = Mult_32_16( GainFrame_fx, 9830 /*0.3f in Q15*/ ); // Q18 - } - } - } - } - ELSE - { - /* de-quantization */ - ivas_dequantizeSHBparams_fx_9_1( st, st->extl, st->extl_brate, lsf_shb_fx, GainShape_fx, &GainFrame_fx, &stemp, - &shb_ener_sf_32, shb_res_gshape_fx, &mixFactors_fx, &MSFlag ); - if ( hStereoICBWE != NULL ) - { - hStereoICBWE->MSFlag = MSFlag; - move16(); - } - } - } - ELSE - { - Copy( hBWE_TD->lsp_prevfrm_fx, lsf_shb_fx, LPC_SHB_ORDER ); - test(); - IF( EQ_16( st->codec_mode, MODE1 ) && ( st->element_mode == EVS_MONO ) ) - { - gradientGainShape( st, GainShape_fx, &GainFrame_fx ); - } - ELSE - { - FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) - { - FOR( j = 0; j < 4; j++ ) - { - GainShape_fx[i * 4 + j] = mult_r( st->cummulative_damping, st->GainShape_Delay[4 + i] ); - move16(); - } - } - IF( GT_16( tilt_swb_fec_fx, ( 8 << 11 ) ) ) /* tilt_swb_fec_fx in Q11 */ - { - IF( EQ_16( st->nbLostCmpt, 1 ) ) - { - GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 19661 /*0.6f Q15*/ ); - } - ELSE IF( EQ_16( st->nbLostCmpt, 2 ) ) - { - GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 11469 /*0.35f Q15*/ ); - } - ELSE - { - GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 6554 /*0.2f Q15*/ ); - } - GainFrame_fx = Mult_32_16( GainFrame_fx, st->cummulative_damping ); - } - ELSE - { - GainFrame_fx = hBWE_TD->GainFrame_prevfrm_fx; - move32(); /* gain locking */ - } - } - - IF( GE_32( st->extl_brate, SWB_TBE_2k8 ) ) - { - test(); - IF( EQ_16( st->codec_mode, MODE1 ) && ( st->element_mode == EVS_MONO ) ) - { - L_tmp = L_mult( extract_l( hBWE_TD->prev2_shb_ener_sf_fx ), extract_l( hBWE_TD->prev3_shb_ener_sf_fx ) ); /*Q1*/ - tmp = round_fx( root_a_fx( L_tmp, 1, &exp ) ); /* Q = 15-exp */ - tmp1 = extract_l( hBWE_TD->prev1_shb_ener_sf_fx ); /*Q0*/ - i = sub( norm_s( tmp1 ), 1 ); - tmp1 = shl( tmp1, i ); /* Qi */ - IF( tmp == 0 ) - { - tmp = 32767 /*1.0f Q15*/; - move16(); /*Q15*/ - } - ELSE - { - scale_fx = div_s( tmp1, tmp ); /* Q15 - Q(15-exp) + Qi = Qexp+i */ - scale_fx = s_max( scale_fx, 0 ); - tmp = shl_sat( scale_fx, sub( sub( 15, exp ), i ) ); /*Q15*/ - } - scale_fx = mult_r( hBWE_TD->prev_res_shb_gshape_fx, tmp ); /* Q14 */ - test(); - IF( GT_32( L_shr( hBWE_TD->prev2_shb_ener_sf_fx, 1 ), hBWE_TD->prev1_shb_ener_sf_fx ) || - GT_32( L_shr( hBWE_TD->prev3_shb_ener_sf_fx, 1 ), hBWE_TD->prev2_shb_ener_sf_fx ) ) - { - shb_ener_sf_32 = Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, scale_fx ); - - if ( GT_16( st->nbLostCmpt, 1 ) ) - { - shb_ener_sf_32 = L_shr( shb_ener_sf_32, 1 ); - } - } - ELSE - { - L_tmp = L_mult( scale_fx, scale_fx ); /* Q29 */ - shb_ener_sf_32 = L_shl( Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, round_fx( L_tmp ) ), 2 ); - } - } - ELSE - { - test(); - IF( GT_32( L_shr( hBWE_TD->prev2_shb_ener_sf_fx, 1 ), hBWE_TD->prev1_shb_ener_sf_fx ) || - GT_32( L_shr( hBWE_TD->prev3_shb_ener_sf_fx, 1 ), hBWE_TD->prev2_shb_ener_sf_fx ) ) - { - shb_ener_sf_32 = L_shr( Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, st->cummulative_damping ), 1 ); - } - ELSE - { - shb_ener_sf_32 = Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, st->cummulative_damping ); - } - } - } - - shb_ener_sf_32 = L_max( shb_ener_sf_32, 1l /*1.0f Q0*/ ); - mixFactors_fx = hBWE_TD->prev_mixFactors_fx; - move16(); - - IF( EQ_16( st->codec_mode, MODE1 ) ) - { - set16_fx( shb_res_gshape_fx, 3277 /*0.2f Q14*/, 5 ); /* Q14 */ - } - ELSE - { - set16_fx( shb_res_gshape_fx, 16384 /*1.0f Q14*/, 5 ); /* Q14 */ - } - } - } - - /* get the gainshape delay */ - Copy( &st->GainShape_Delay[4], &st->GainShape_Delay[0], NUM_SHB_SUBFR / 4 ); - FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) - { - st->GainShape_Delay[i + 4] = GainShape_fx[i * 4]; /*Q15*/ - move16(); - } - - L_tmp = L_mult( voice_factors_fx[0], 8192 ); - L_tmp = L_mac( L_tmp, voice_factors_fx[1], 8192 ); - L_tmp = L_mac( L_tmp, voice_factors_fx[2], 8192 ); - mean_vf = mac_r( L_tmp, voice_factors_fx[3], 8192 ); - - Copy( voice_factors_fx, vf_modified_fx, NB_SUBFR16k ); - - test(); - IF( EQ_16( st->coder_type, VOICED ) || GT_16( mean_vf, 13107 /*0.4f Q15*/ ) ) - { - FOR( i = 1; i < NB_SUBFR; i++ ) - { - L_tmp = L_mult( voice_factors_fx[i], 26214 /*0.8f Q15*/ ); - vf_modified_fx[i] = mac_r( L_tmp, voice_factors_fx[i - 1], 6554 /*0.2f Q15*/ ); - move16(); - } - - IF( st->L_frame != L_FRAME ) - { - L_tmp = L_mult( voice_factors_fx[4], 26214 /*0.8f Q15*/ ); - vf_modified_fx[4] = mac_r( L_tmp, voice_factors_fx[3], 6554 /*0.2f Q15*/ ); - move16(); - } - } - - test(); - IF( st->use_partial_copy && st->nelp_mode_dec ) - { - set16_fx( vf_modified_fx, 0, NB_SUBFR16k ); - } - - /* SHB LSF from current frame; and convert to LSP for interpolation */ - E_LPC_lsf_lsp_conversion( lsf_shb_fx, lsp_shb_2_fx, LPC_SHB_ORDER ); - - test(); - IF( EQ_16( st->last_extl, SWB_TBE ) || EQ_16( st->last_extl, FB_TBE ) ) - { - /* SHB LSP values from prev. frame for interpolation */ - Copy( hBWE_TD->swb_lsp_prev_interp_fx, lsp_shb_1_fx, LPC_SHB_ORDER ); - } - ELSE - { - /* Use current frame's LSPs; in effect no interpolation */ - Copy( lsp_shb_2_fx, lsp_shb_1_fx, LPC_SHB_ORDER ); - } - - test(); - test(); - test(); - IF( ( st->bws_cnt == 0 ) && ( st->bws_cnt1 == 0 ) && ( st->prev_use_partial_copy == 0 ) && ( st->use_partial_copy == 0 ) ) - { - lsf_diff_fx[0] = 16384; - move16(); /*Q15*/ - lsf_diff_fx[LPC_SHB_ORDER - 1] = 16384; - move16(); /*Q15*/ - FOR( i = 1; i < LPC_SHB_ORDER - 1; i++ ) - { - lsf_diff_fx[i] = sub( lsf_shb_fx[i], lsf_shb_fx[i - 1] ); - move16(); - } - - a2rc_fx( hBWE_TD->cur_sub_Aq_fx + 1, refl_fx, M ); - tmp = add( 16384, shr( refl_fx[0], 1 ) ); /*Q14*/ - tmp1 = mult( 27425, tmp ); - tmp1 = mult( tmp1, tmp ); /*Q10*/ - tmp2 = shr( mult( 31715, tmp ), 2 ); /*Q10*/ - tilt_para_fx = add( sub( tmp1, tmp2 ), 1335 ); /*Q10*/ - - test(); - IF( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) ) - { - FOR( i = 1; i < LPC_SHB_ORDER - 1; i++ ) - { - hBWE_TD->prev_lsf_diff_fx[i - 1] = shr( lsf_diff_fx[i], 1 ); - move16(); - } - } - - IF( LE_32( st->extl_brate, FB_TBE_1k8 ) ) - { - test(); - test(); - test(); - test(); - test(); - IF( !( GT_16( hBWE_TD->prev_tilt_para_fx, 5120 ) && ( EQ_16( st->coder_type, TRANSITION ) || LT_16( tilt_para_fx, 1024 ) ) ) && - !( ( ( LT_16( hBWE_TD->prev_tilt_para_fx, 3072 ) && GE_16( st->prev_coder_type, VOICED ) ) ) && GT_16( tilt_para_fx, 5120 ) ) ) - { - FOR( i = 1; i < LPC_SHB_ORDER - 1; i++ ) - { - IF( LT_16( lsf_diff_fx[i], hBWE_TD->prev_lsf_diff_fx[i - 1] ) ) - { - tmp = mult( 26214, lsf_diff_fx[i] ); - - test(); - IF( ( hBWE_TD->prev_lsf_diff_fx[i - 1] <= 0 ) || ( tmp < 0 ) ) /* safety check in case of bit errors */ - { - st->BER_detect = 1; - move16(); - tmp = 0; - move16(); - } - ELSE - { - tmp = div_s( tmp, hBWE_TD->prev_lsf_diff_fx[i - 1] ); - } - - tmp = s_max( tmp, 16384 ); - w_fx[i] = s_min( tmp, 32767 ); - move16(); - } - ELSE - { - tmp = mult( 26214, hBWE_TD->prev_lsf_diff_fx[i - 1] ); - - test(); - IF( ( lsf_diff_fx[i] <= 0 ) || ( tmp < 0 ) ) /* safety check in case of bit errors */ - { - st->BER_detect = 1; - move16(); - tmp = 0; - move16(); - } - ELSE - { - tmp = div_s( tmp, lsf_diff_fx[i] ); - } - - tmp = s_max( tmp, 16384 ); - w_fx[i] = s_min( tmp, 32767 ); - move16(); - } - } - w_fx[0] = w_fx[1]; - move16(); - w_fx[LPC_SHB_ORDER - 1] = w_fx[LPC_SHB_ORDER - 2]; - move16(); - - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - tmp1 = mult( lsp_shb_1_fx[i], sub( 32767, w_fx[i] ) ); - tmp2 = mult( lsp_shb_2_fx[i], w_fx[i] ); - lsp_temp_fx[i] = add( tmp1, tmp2 ); - move16(); - } - } - ELSE - { - Copy( lsp_shb_2_fx, lsp_temp_fx, LPC_SHB_ORDER ); - } - - /* convert from lsp to lsf */ - lsp2lsf_fx( lsp_temp_fx, lsf_shb_fx, LPC_SHB_ORDER, 1 ); - } - - Copy( lsf_diff_fx + 1, hBWE_TD->prev_lsf_diff_fx, LPC_SHB_ORDER - 2 ); - hBWE_TD->prev_tilt_para_fx = tilt_para_fx; - move16(); - } - ELSE - { - Copy( lsp_shb_2_fx, lsp_temp_fx, LPC_SHB_ORDER ); - } - - IF( GE_32( st->extl_brate, SWB_TBE_2k8 ) ) - { - /* SHB LSP interpolation */ - ptr_lsp_interp_coef_fx = interpol_frac_shb; /*Q15*/ - FOR( j = 0; j < 4; j++ ) - { - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - L_tmp = L_mult( lsp_shb_1_fx[i], ( *ptr_lsp_interp_coef_fx ) ); - lsp_temp_fx[i] = mac_r( L_tmp, lsp_shb_2_fx[i], ( *( ptr_lsp_interp_coef_fx + 1 ) ) ); - move16(); - } - ptr_lsp_interp_coef_fx += 2; - - tmp = i_mult( j, ( LPC_SHB_ORDER + 1 ) ); - /* convert LSPs to LP coefficients */ - E_LPC_f_lsp_a_conversion( lsp_temp_fx, lpc_shb_sf_fx + tmp, LPC_SHB_ORDER ); -#ifndef FIX_1100_REMOVE_LPC_RESCALING - /* Bring the LPCs to Q12 */ - Copy_Scale_sig( lpc_shb_sf_fx + tmp, lpc_shb_sf_fx + tmp, LPC_SHB_ORDER + 1, sub( norm_s( lpc_shb_sf_fx[tmp] ), 2 ) ); - lpc_shb_sf_fx[i_mult( j, ( LPC_SHB_ORDER + 1 ) )] = ONE_IN_Q12; // recheck this - move16(); -#endif - } - } - - /* Save the SWB LSP values from current frame for interpolation */ - Copy( lsp_shb_2_fx, hBWE_TD->swb_lsp_prev_interp_fx, LPC_SHB_ORDER ); - - /* save the shb_ener and mixFactor values */ - hBWE_TD->prev3_shb_ener_sf_fx = hBWE_TD->prev2_shb_ener_sf_fx; - move32(); - hBWE_TD->prev2_shb_ener_sf_fx = hBWE_TD->prev1_shb_ener_sf_fx; - move32(); - hBWE_TD->prev1_shb_ener_sf_fx = shb_ener_sf_32; - move32(); - hBWE_TD->prev_res_shb_gshape_fx = shb_res_gshape_fx[4]; - move16(); - hBWE_TD->prev_mixFactors_fx = mixFactors_fx; - move16(); - - /* SWB CNG/DTX - update memories */ - IF( st->hTdCngDec != NULL ) - { - Copy( st->hTdCngDec->lsp_shb_prev_fx, st->hTdCngDec->lsp_shb_prev_prev_fx, LPC_SHB_ORDER ); - Copy( lsf_shb_fx, st->hTdCngDec->lsp_shb_prev_fx, LPC_SHB_ORDER ); - } - - /* convert LSPs back into LP coeffs */ - E_LPC_f_lsp_a_conversion( lsp_temp_fx, lpc_shb_fx, LPC_SHB_ORDER ); - Copy_Scale_sig( lpc_shb_fx, lpc_shb_fx, LPC_SHB_ORDER + 1, sub( norm_s( lpc_shb_fx[0] ), 2 ) ); /* Q12 */ - lpc_shb_fx[0] = ONE_IN_Q12; - move16(); - - test(); - IF( EQ_32( st->extl_brate, SWB_TBE_1k10 ) || EQ_32( st->extl_brate, SWB_TBE_1k75 ) ) - { - Word32 vind_temp = Mpy_32_32( L_shl( L_add( L_deposit_l( mixFactors_fx ), 1 ), 15 ), ( ( ( 1 << NUM_BITS_SHB_VF ) - 1 ) << 16 ) ); // check addition of 1 - vind = extract_l( L_shr( vind_temp, 15 ) ); /* 3 for mpy by 8.0f, -15 to bring it to Q0 */ /*mixFactors*7*/ - /* i: mixFactors_fx in Q15 */ - /* o: vind in Q0 */ - } - ELSE - { - vind = shl( mixFactors_fx, 3 - 15 ); /* 3 for mpy by 8.0f, -15 to bring it to Q0 */ /*mixFactors*8*/ - /* i: mixFactors_fx in Q15 */ - /* o: vind in Q0 */ - } - - /* Determine formant PF strength */ - formant_fac_fx = swb_formant_fac_fx( lpc_shb_fx[1], &hBWE_TD->tilt_mem_fx ); - /* i:lpc_shb_fx Q12, o:formant_fac_fx Q15 */ - IF( GT_32( st->total_brate, ACELP_32k ) ) - { - FOR( j = 0; j < 4; j++ ) - { - Copy( lpc_shb_fx, &lpc_shb_sf_fx[i_mult( j, ( LPC_SHB_ORDER + 1 ) )], LPC_SHB_ORDER + 1 ); - } - } - - /* From low band excitation, generate highband excitation */ - - /* -------- start of memory rescaling -------- */ - /* ----- calculate optimum Q_bwe_exc and rescale memories accordingly ----- */ - Lmax = 0; - move32(); - FOR( cnt = 0; cnt < L_FRAME32k; cnt++ ) - { - Lmax = L_max( Lmax, L_abs( bwe_exc_extended_fx[cnt] ) ); - } - Q_bwe_exc = norm_l( Lmax ); - if ( Lmax == 0 ) - { - Q_bwe_exc = 31; - move16(); - } - Q_bwe_exc = add( Q_bwe_exc, add( Q_exc, Q_exc ) ); - find_max_mem_dec( st, &n_mem, &n_mem2, &n_mem3 ); /* for >=24.4, use n_mem2 lpc_syn, shb_20sample, and mem_stp_swb_fx memory */ - - tmp = add( st->prev_Q_bwe_exc, n_mem ); - if ( GT_16( Q_bwe_exc, tmp ) ) - { - Q_bwe_exc = tmp; - move16(); - } - - /* rescale the memories if Q_bwe_exc is different from previous frame */ - sc = sub( Q_bwe_exc, st->prev_Q_bwe_exc ); - IF( sc != 0 ) - { - rescale_genSHB_mem_dec( st, sc ); - } - - /* rescale the bwe_exc_extended and bring it to 16-bit single precision with dynamic norm */ - sc = sub( Q_bwe_exc, add( Q_exc, Q_exc ) ); - - FOR( cnt = 0; cnt < L_FRAME32k; cnt++ ) - { - bwe_exc_extended_16[cnt] = round_fx_sat( L_shl_sat( bwe_exc_extended_fx[cnt], sc ) ); - move16(); - } - - /* state_syn_shbexc_fx is kept at (st_fx->prev_Q_bwe_syn) for 24.4/32kbps or is kept at Q_bwe_exc for 13.2/16.4kbps */ - - /* save the previous Q factor (32-bit) of the buffer */ - st->prev_Q_bwe_exc = Q_bwe_exc; - move16(); - - Q_bwe_exc = sub( Q_bwe_exc, 16 ); /* Q_bwe_exc reflecting the single precision dynamic norm-ed buffers from here */ - - /* -------- end of rescaling memories -------- */ - - Q_bwe_exc_fb = st->prev_Q_bwe_exc_fb; - move16(); - - Q_shb = 0; - move16(); - - Copy( hBWE_TD->state_syn_shbexc_fx, shaped_shb_excitation_fx, L_SHB_LAHEAD ); - GenShapedSHBExcitation_ivas_dec_fx( shaped_shb_excitation_fx + L_SHB_LAHEAD, lpc_shb_fx, White_exc16k_fx, - hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, - st->coder_type, bwe_exc_extended_16, hBWE_TD->bwe_seed, vf_modified_fx, st->extl, - &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), lpc_shb_sf_fx, shb_ener_sf_32, - shb_res_gshape_fx, shb_res_dummy_fx, &vind, formant_fac_fx, hBWE_TD->fb_state_lpc_syn_fx, - &( hBWE_TD->fb_tbe_demph_fx ), &Q_bwe_exc, &Q_bwe_exc_fb, Q_shb, n_mem2, st->prev_Q_bwe_syn, st->total_brate, st->prev_bfi, - st->element_mode, st->flag_ACELP16k, nlExc16k_fx, mixExc16k_fx, st->extl_brate, MSFlag, - NULL, &( hBWE_TD->prev_pow_exc16kWhtnd_fx32 ), &( hBWE_TD->prev_mix_factor_fx ), NULL, NULL ); - - *Q_white_exc = Q_bwe_exc_fb; - move16(); - IF( EQ_16( st->extl, FB_TBE ) ) - { - st->prev_Q_bwe_exc_fb = Q_bwe_exc_fb; - move16(); - } - ELSE - { - /*Indirectly a memory reset of FB memories for next frame such that rescaling of memories would lead to 0 due to such high prev. Q value. - 51 because of 31 + 20(shift of Q_bwe_exc_fb before de-emphasis)*/ - st->prev_Q_bwe_exc_fb = 51; - move16(); - } - - /* rescale the TBE post proc memory */ - FOR( i = 0; i < LPC_SHB_ORDER; i++ ) - { - hBWE_TD->mem_stp_swb_fx[i] = shl_sat( hBWE_TD->mem_stp_swb_fx[i], sub( Q_bwe_exc, st->prev_Q_bwe_syn ) ); - move16(); - } - /* fill-in missing SHB excitation */ - test(); - test(); - IF( ( EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) ) && LE_32( st->last_core_brate, SID_2k40 ) ) - { - Copy( shaped_shb_excitation_fx + L_SHB_LAHEAD, shaped_shb_excitation_fx, L_SHB_LAHEAD ); - } - - IF( hStereoICBWE != NULL ) - { - Copy( shaped_shb_excitation_fx + L_SHB_LAHEAD, hStereoICBWE->shbSynthRef_fx, L_FRAME16k ); - } - - test(); - IF( NE_32( st->extl_brate, SWB_TBE_1k10 ) && NE_32( st->extl_brate, SWB_TBE_1k75 ) ) - { - FOR( i = 0; i < L_FRAME16k; i += L_SUBFR16k ) - { - /* TD BWE post-processing */ - PostShortTerm_ivas_dec_fx( &shaped_shb_excitation_fx[L_SHB_LAHEAD + i], lpc_shb_fx, &shaped_shb_excitationTemp_fx[i], hBWE_TD->mem_stp_swb_fx, - hBWE_TD->ptr_mem_stp_swb_fx, &( hBWE_TD->gain_prec_swb_fx ), hBWE_TD->mem_zero_swb_fx, formant_fac_fx ); - } - - Copy( shaped_shb_excitationTemp_fx, &shaped_shb_excitation_fx[L_SHB_LAHEAD], L_FRAME16k ); /* Q_bwe_exc */ - - tmp = sub( shl( Q_bwe_exc, 1 ), 31 + 16 ); - prev_pow_fx = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /* 2*(Q_bwe_exc) */ - curr_pow_fx = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /* 2*(Q_bwe_exc) */ - FOR( i = 0; i < L_SHB_LAHEAD + 10; i++ ) - { - prev_pow_fx = L_mac0_sat( prev_pow_fx, shaped_shb_excitation_fx[i], shaped_shb_excitation_fx[i] ); /*2*Q_bwe_exc*/ - curr_pow_fx = L_mac0_sat( curr_pow_fx, shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10], shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10] ); /* 2*Q_bwe_exc */ - } - - if ( GT_16( voice_factors_fx[0], 24576 /*0.75f Q15*/ ) ) - { - curr_pow_fx = L_shr( curr_pow_fx, 2 ); /* Q(2*Q_bwe_exc) */ - } - - Lscale = root_a_over_b_fx( curr_pow_fx, - shl( Q_bwe_exc, 1 ), - prev_pow_fx, - shl( Q_bwe_exc, 1 ), - &exp ); - - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q_bwe_exc + (31-exp) - 15 */ - shaped_shb_excitation_fx[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc */ - move16(); - } - IF( exp < 0 ) - { - Lscale = L_shl( Lscale, exp ); - exp = 0; - move16(); - } - FOR( ; i < L_SHB_LAHEAD + 10; i++ ) - { - temp_fx = i_mult_sat( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ - L_tmp1 = Mult_32_16( L_shl_sat( 1, sub( 31, exp ) ), temp_fx ); /* Q31-exp */ - temp_fx = sub( 32767 /*1.0f Q15*/, temp_fx ); - Lscale = L_add( Mult_32_16( Lscale, temp_fx ), L_tmp1 ); - L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q_bwe_exc + (31-exp) - 15 */ - shaped_shb_excitation_fx[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc */ - move16(); - } - } - ELSE - { - /* reset the PF memories if the PF is not running */ - set16_fx( hBWE_TD->mem_stp_swb_fx, 0, LPC_SHB_ORDER ); - hBWE_TD->gain_prec_swb_fx = ONE_IN_Q14; - move16(); - set16_fx( hBWE_TD->mem_zero_swb_fx, 0, LPC_SHB_ORDER ); - } - - /* Update SHB excitation */ - Copy( shaped_shb_excitation_fx + L_FRAME16k, hBWE_TD->state_syn_shbexc_fx, L_SHB_LAHEAD ); /* Q_bwe_exc */ - l_subframe = L_FRAME16k / NUM_SHB_SUBGAINS; - move16(); - L_ener = EPSILON_FX_SMALL; - move32(); - - FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - L_tmp = 0; - move32(); - ener_tmp_fx[i] = EPSILON_FX_SMALL; - move32(); - - Word64 tmp64 = 0; - move64(); - FOR( j = 0; j < l_subframe; j++ ) - { - tmp64 = W_mac0_16_16( tmp64, shaped_shb_excitation_fx[add( i_mult( i, l_subframe ), j )], shaped_shb_excitation_fx[add( i_mult( i, l_subframe ), j )] ); /* 2*Q_bwe_exc */ - } - L_tmp = W_sat_l( tmp64 ); - - L_tmp = Mult_32_16( L_tmp, 410 /*0.0125 Q15*/ ); /* 2*Q_bwe_exc: ener_tmp_fx in (2*Q_bwe_exc) */ - IF( L_tmp != 0 ) - { - exp = norm_l( L_tmp ); - tmp = extract_h( L_shl( L_tmp, exp ) ); - exp = sub( exp, sub( 30, i_mult( 2, Q_bwe_exc ) ) ); - - tmp = div_s( 16384, tmp ); - L_tmp = L_deposit_h( tmp ); - L_tmp = Isqrt_lc( L_tmp, &exp ); - ener_tmp_fx[i] = L_shl_sat( L_tmp, sub( add( exp, shl( Q_bwe_exc, 1 ) ), 31 ) ); /*2 * Q_bwe_exc: Q31 -exp +exp +2 * Q_bwe_exc -31 */ - move32(); - L_ener = L_add_sat( L_ener, L_shr( ener_tmp_fx[i], 2 ) ); /* 2*Q_bwe_exc */ - } - } - ener_fx = s_max( 1, round_fx_sat( L_shl_sat( L_ener, sub( 18, shl( Q_bwe_exc, 1 ) ) ) ) ); /* Q2: 2*Q_bwe_exc+18-2*Q_bwe_exc-16 */ - /* WB/SWB bandwidth switching */ - IF( st->bws_cnt > 0 ) - { - IF( is_fractive == 0 ) - { - IF( GT_16( st->tilt_wb_fx, 2048 ) ) /*assuming st->tilt_wb_fx in Q11*/ - { - st->tilt_wb_fx = 2048; - move16(); - } - ELSE IF( LT_16( st->tilt_wb_fx, 1024 ) ) - { - st->tilt_wb_fx = 1024; - move16(); - } - test(); - if ( EQ_16( st->prev_fractive, 1 ) && GT_16( st->tilt_wb_fx, 1024 ) ) - { - st->tilt_wb_fx = 1024; - move16(); - } - } - ELSE - { - IF( GT_16( st->tilt_wb_fx, 8192 ) ) - { - IF( st->prev_fractive == 0 ) - { - st->tilt_wb_fx = 8192; - move16(); - } - ELSE - { - st->tilt_wb_fx = 16384; - move16(); - } - } - ELSE - { - st->tilt_wb_fx = shl( st->tilt_wb_fx, 2 ); - move16(); - } - } - - IF( ener_fx != 0 ) - { - L_tmp = L_shl( L_mult0( ener_fx, st->tilt_wb_fx ), sub( st->Q_syn2, 13 ) ); /* 2+11 +st->Q_syn2 -13 = st->Q_syn2*/ - exp_ener = norm_s( ener_fx ); - tmp = shl( ener_fx, exp_ener ); /*Q(2+exp)*/ - inv_ener = shr( div_s( 16384, tmp ), 1 ); /*Q(15+14-2-exp-1) = 26 - exp*/ - - test(); - IF( GT_32( L_tmp, st->enerLH_fx ) ) /*st->Q_syn2*/ - { - st->tilt_wb_fx = extract_h( L_shr_sat( Mult_32_16( st->enerLH_fx, inv_ener ), sub( sub( st->Q_syn2, exp_ener ), 16 ) ) ); /*Q11*/ - move16(); - /*st->Q_syn2 -1 + 26- exp_ener -15 -(st->Q_syn2 -exp_ener -16 ) -16 +1 -1 = (11) *0.5*/ - } - ELSE IF( LT_32( L_tmp, Mult_32_16( st->enerLH_fx, 1638 ) ) && EQ_16( is_fractive, 1 ) ) - { - st->tilt_wb_fx = extract_h( L_shr_sat( Mult_32_16( st->enerLH_fx, inv_ener ), sub( sub( st->Q_syn2, exp_ener ), 15 ) ) ); /*Q11*/ - move16(); - /*st->Q_syn2 -1 + 26- exp_ener -15 -(st->Q_syn2 -exp_ener -15 ) -16 = (11) 0.25*/ - } - L_tmp = L_mult0( st->prev_ener_shb_fx, inv_ener ); /*Q(1+15+14-3-exp_ener) = 27 -exp_ener*/ - GainFrame_prevfrm_fx = L_shr( L_tmp, sub( 9, exp_ener ) ); /*27 -exp_ener -(9-exp_ener )= Q18*/ - } - ELSE - { - GainFrame_prevfrm_fx = 0; - move32(); - } - - IF( EQ_16( is_fractive, 1 ) ) - { - GainFrame_fx = L_shl( L_deposit_l( st->tilt_wb_fx ), 10 ); - } - ELSE - { - GainFrame_fx = L_shl( L_deposit_l( st->tilt_wb_fx ), 8 ); - } - - test(); - IF( EQ_16( ( is_fractive & st->prev_fractive ), 1 ) && GT_32( GainFrame_fx, GainFrame_prevfrm_fx ) ) - { - GainFrame_fx = L_add( Mult_32_16( GainFrame_prevfrm_fx, 26214 ), Mult_32_16( GainFrame_fx, 6554 ) ); /* 18 +15 -15 = 18*/ - } - ELSE - { - test(); - test(); - test(); - test(); - IF( ( LT_32( L_shr( st->prev_enerLH_fx, 1 ), st->enerLH_fx ) && GT_32( st->prev_enerLH_fx, L_shr( st->enerLH_fx, 1 ) ) ) && ( LT_32( L_shr( st->prev_enerLL_fx, 1 ), st->enerLL_fx ) && GT_32( st->prev_enerLL_fx, L_shr( st->enerLL_fx, 1 ) ) ) && ( s_xor( is_fractive, st->prev_fractive ) == 0 ) ) - { - GainFrame_fx = L_add( L_shr( GainFrame_fx, 1 ), L_shr( GainFrame_prevfrm_fx, 1 ) ); - } - ELSE - { - test(); - IF( ( is_fractive == 0 ) && EQ_16( st->prev_fractive, 1 ) ) - { - L_tmp1 = L_shl( Mult_32_16( GainFrame_fx, 3277 ), 13 ); /* 31 */ - L_tmp = L_sub( 2147483647, L_tmp1 ); /* 31 */ - GainFrame_fx = L_add( Mult_32_32( GainFrame_fx, L_tmp ), Mult_32_32( GainFrame_prevfrm_fx, L_tmp1 ) ); /* 18 */ - } - ELSE - { - GainFrame_fx = L_add( L_shr( GainFrame_fx, 1 ), L_shr( L_min( GainFrame_prevfrm_fx, GainFrame_fx ), 1 ) ); /* 18 */ - } - } - } - - GainFrame_fx = Mult_32_16( GainFrame_fx, i_mult( sub( N_WS2N_FRAMES, st->bws_cnt ), 819 ) ); /*Q18*/ - } - ELSE - { - IF( st->bws_cnt1 > 0 ) - { - GainFrame_fx = Mult_32_16( GainFrame_fx, i_mult( st->bws_cnt1, 819 ) ); /*Q18*/ - } - IF( GE_16( st->nbLostCmpt, 1 ) ) - { - ener_fx = s_max( 1, ener_fx ); - exp_ener = norm_s( ener_fx ); - tmp = shl( ener_fx, exp_ener ); /*Q(2+exp)*/ - inv_ener = div_s( 16384, tmp ); /*Q(15+14-2-exp)*/ - prev_ener_ratio_fx = L_shr( L_mult0( st->prev_ener_shb_fx, inv_ener ), add( sub( 9, exp_ener ), 1 ) ); /*Q: 1+27-exp-9+exp-1 = 18 */ - } - - IF( EQ_16( st->nbLostCmpt, 1 ) ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( st->clas_dec != UNVOICED_CLAS ) && NE_16( st->clas_dec, UNVOICED_TRANSITION ) && LT_16( hBWE_TD->tilt_swb_fec_fx, 16384 ) && - ( ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) && LT_32( L_shr( st->enerLL_fx, 1 ), st->prev_enerLL_fx ) ) || ( GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) && LT_32( L_shr( st->enerLH_fx, 1 ), st->prev_enerLH_fx ) ) ) ) - { - IF( GT_32( L_shr( prev_ener_ratio_fx, 2 ), GainFrame_fx ) ) /*18*/ - { - GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 13107 ), Mult_32_16( GainFrame_fx, 19661 ) ); /*18*/ - } - ELSE IF( GT_32( L_shr( prev_ener_ratio_fx, 1 ), GainFrame_fx ) ) - { - GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 26214 ), Mult_32_16( GainFrame_fx, 6554 ) ); - } - ELSE - { - GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 6554 ), Mult_32_16( GainFrame_fx, 26214 ) ); - } - - test(); - IF( GT_16( tilt_swb_fec_fx, hBWE_TD->tilt_swb_fec_fx ) && ( hBWE_TD->tilt_swb_fec_fx > 0 ) ) - { - exp = norm_s( hBWE_TD->tilt_swb_fec_fx ); - tmp = shl( hBWE_TD->tilt_swb_fec_fx, exp ); /*Q(11+exp)*/ - tmp = div_s( 16384, tmp ); /*Q(15+14-11-exp)*/ - tmp = extract_h( L_shl( L_mult0( tmp, st->tilt_wb_fx ), sub( exp, 1 ) ) ); /*18 -exp +11 + exp -1 -16 =12; */ - GainFrame_fx = L_shl( Mult_32_16( GainFrame_fx, s_min( tmp, 20480 ) ), 3 ); /*Q18 = 18 +12 -15 +3 */ - } - } - ELSE IF( ( ( st->clas_dec != UNVOICED_CLAS ) || GT_16( hBWE_TD->tilt_swb_fec_fx, 4096 ) ) && GT_32( L_shr( prev_ener_ratio_fx, 2 ), GainFrame_fx ) && - ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) || GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) ) ) - { - GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 6554 ), Mult_32_16( GainFrame_fx, 26214 ) ); - } - } - ELSE IF( GT_16( st->nbLostCmpt, 1 ) ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( GT_32( L_shr( prev_ener_ratio_fx, 2 ), GainFrame_fx ) && ( ( EQ_16( st->codec_mode, MODE1 ) && GT_32( st->enerLL_fx, st->prev_enerLL_fx ) && GT_32( st->enerLH_fx, st->prev_enerLH_fx ) ) || EQ_16( st->codec_mode, MODE2 ) ) ) - { - test(); - IF( GT_16( tilt_swb_fec_fx, 20480 /*10.0f in Q11*/ ) && GT_16( hBWE_TD->tilt_swb_fec_fx, 20480 /*10.0f in Q11*/ ) ) - { - GainFrame_fx = L_min( L_add( Mult_32_16( prev_ener_ratio_fx, 26214 /*0.8f in Q15*/ ), Mult_32_16( GainFrame_fx, 6554 /*0.2f in Q15*/ ) ), L_shl( Mult_32_16( GainFrame_fx, 16384 /*4.0f in Q12*/ ), 3 ) ); /*Q18*/ - } - ELSE - { - GainFrame_fx = L_min( L_add( Mult_32_16( prev_ener_ratio_fx, 16384 ), Mult_32_16( GainFrame_fx, 16384 ) ), L_shl( Mult_32_16( GainFrame_fx, 16384 ), 3 ) ); /*Q18*/ - } - } - ELSE IF( GT_32( prev_ener_ratio_fx, GainFrame_fx ) && ( ( EQ_16( st->codec_mode, MODE1 ) && GT_32( st->enerLL_fx, st->prev_enerLL_fx ) && GT_32( st->enerLH_fx, st->prev_enerLH_fx ) ) || EQ_16( st->codec_mode, MODE2 ) ) ) - { - test(); - IF( GT_16( tilt_swb_fec_fx, 20480 ) && GT_16( hBWE_TD->tilt_swb_fec_fx, 20480 ) ) - { - GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 16384 /*0.5f in Q15*/ ), Mult_32_16( GainFrame_fx, 16384 /*0.5f in Q15*/ ) ); /* Q18 */ - } - ELSE - { - GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 6554 /*0.2f in Q15*/ ), Mult_32_16( GainFrame_fx, 26214 /*0.8f in Q15*/ ) ); /* Q18 */ - } - } - } - } - - st->prev_fractive = is_fractive; - move16(); - - /* Adjust the subframe and frame gain of the synthesized shb signal */ - /* Scale the shaped excitation */ - IF( EQ_16( st->L_frame, L_FRAME ) ) - { - L_tmp = L_mult( pitch_buf_fx[0], 8192 ); - FOR( i = 1; i < NB_SUBFR; i++ ) - { - L_tmp = L_mac( L_tmp, pitch_buf_fx[i], 8192 ); /* pitch_buf in Q6 x 0.25 in Q15 */ - } - pitch_fx = round_fx( L_tmp ); /* Q6 */ - } - ELSE - { - L_tmp = L_mult( pitch_buf_fx[0], 6554 ); - FOR( i = 1; i < NB_SUBFR16k; i++ ) - { - L_tmp = L_mac( L_tmp, pitch_buf_fx[i], 6554 ); /* pitch_buf in Q6 x 0.2 in Q15 */ - } - pitch_fx = round_fx( L_tmp ); /* Q6 */ - } - - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( ( ( GE_32( st->extl_brate, SWB_TBE_2k8 ) && EQ_16( st->prev_coder_type, st->coder_type ) && NE_16( st->coder_type, UNVOICED ) ) || ( LT_32( st->extl_brate, SWB_TBE_2k8 ) && ( EQ_16( st->prev_coder_type, st->coder_type ) || ( EQ_16( st->prev_coder_type, VOICED ) && EQ_16( st->coder_type, GENERIC ) ) || ( EQ_16( st->prev_coder_type, GENERIC ) && EQ_16( st->coder_type, VOICED ) ) ) ) ) && GT_16( pitch_fx, 4480 /*70 in Q6*/ ) && LT_16( st->extl, FB_TBE ) && NE_32( st->extl_brate, SWB_TBE_1k10 ) && NE_32( st->extl_brate, SWB_TBE_1k75 ) ) - { - FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - GainShape_tmp_fx[i] = GainShape_fx[i * 4]; /* Q15 */ - move16(); - } - - FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - L_tmp1 = Mult_32_16( ener_tmp_fx[i], GainShape_tmp_fx[i] ); /* (2*Q_bwe_exc) */ - L_tmp2 = Mult_32_16( hBWE_TD->prev_ener_fx, hBWE_TD->prev_GainShape_fx ); /* (2*st->prev_ener_fx_Q) */ - tmp = sub( shl( Q_bwe_exc, 1 ), shl( st->prev_ener_fx_Q, 1 ) ); - L_tmp2 = L_shl_sat( L_tmp2, tmp ); /* new Q = (2*Q_bwe_exc) */ - IF( GT_32( L_tmp1, L_tmp2 ) ) - { - L_tmp = L_tmp2; - move32(); - if ( L_tmp2 < 0 ) - { - L_tmp = L_negate( L_tmp2 ); - } - - expb = norm_l( L_tmp ); - fracb = round_fx_sat( L_shl_sat( L_tmp, expb ) ); - expb = sub( 30, expb ); /* - (2*Q_bwe_exc_ext); */ - - expa = norm_l( ener_tmp_fx[i] ); - fraca = extract_h( L_shl( ener_tmp_fx[i], expa ) ); - expa = sub( 30, expa ); - - scale_fx = shr( sub( fraca, fracb ), 15 ); - fracb = shl( fracb, scale_fx ); - expb = sub( expb, scale_fx ); - - tmp = div_s( fracb, fraca ); - exp = sub( sub( expb, expa ), 1 ); - tmp = shl( tmp, exp ); - GainShape_tmp_fx[i] = add( tmp, shr( GainShape_tmp_fx[i], 1 ) ); /* Q15 */ - move16(); - } - - hBWE_TD->prev_ener_fx = ener_tmp_fx[i]; - move32(); - hBWE_TD->prev_GainShape_fx = GainShape_tmp_fx[i]; - move16(); - st->prev_ener_fx_Q = Q_bwe_exc; - move16(); - } - - FOR( i = 0; i < NUM_SHB_SUBFR; i++ ) - { - Word16 idx = 0; - move16(); - IF( i != 0 ) - { - idx = idiv1616( i_mult( i, NUM_SHB_SUBGAINS ), NUM_SHB_SUBFR ); - } - GainShape_fx[i] = GainShape_tmp_fx[idx]; - move16(); - } - } - ELSE - { - st->prev_ener_fx_Q = Q_bwe_exc; - move16(); - } - st->prev_Q_bwe_syn = Q_bwe_exc; - move16(); - - - /* Gain shape smoothing after quantization */ - test(); - IF( EQ_32( st->extl_brate, SWB_TBE_1k10 ) || EQ_32( st->extl_brate, SWB_TBE_1k75 ) ) - { - FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - GainShape_tmp_fx[i] = GainShape_fx[i * NUM_SHB_SUBGAINS]; - move16(); - } - - lls_interp_n_fx( GainShape_tmp_fx, NUM_SHB_SUBGAINS, &GainShape_tilt_fx, &temp_fx, 1 ); - - test(); - IF( GE_16( vind, 6 ) && LT_16( abs_s( GainShape_tilt_fx ), 3932 ) ) - { - feedback_fx = 9830; - move16(); - FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) - { - GainShape_fx[i] = add_sat( mult( sub( 32767, feedback_fx ), GainShape_fx[i * NUM_SHB_SUBGAINS] ), mult( feedback_fx, GainShape_tmp_fx[i] ) ); - move16(); - } - - FOR( i = NUM_SHB_SUBFR - 1; i > 0; i-- ) - { - Word16 idx = 0; - move16(); - IF( i != 0 ) - { - idx = idiv1616( i_mult( i, NUM_SHB_SUBGAINS ), NUM_SHB_SUBFR ); - } - GainShape_fx[i] = GainShape_fx[idx]; - move16(); - } - } - } - - /* fil-in missing memory */ - test(); - test(); - IF( ( EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) ) && LE_32( st->last_core_brate, SID_2k40 ) ) - { - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - Word16 intermediate = mult( shaped_shb_excitation_fx[i], subwin_shb_fx[L_SHB_LAHEAD - i] ); - Word32 intermediate_32 = Mpy_32_16_1( Mpy_32_16_1( GainFrame_fx, window_shb_fx[L_SHB_LAHEAD - 1 - i] ), intermediate ); - hBWE_TD->syn_overlap_fx[i] = round_fx( L_shl_sat( intermediate_32, sub( 16, ( add( Q_bwe_exc, 18 - 15 ) ) ) ) ); - move16(); - } - } - - Word16 n_mem3_new = 0; - move16(); - find_max_mem_dec_m3( st, &n_mem3_new ); - - ScaleShapedSHB_fx( SHB_OVERLAP_LEN, - shaped_shb_excitation_fx, /* i/o: Q_bwe_exc */ - hBWE_TD->syn_overlap_fx, - GainShape_fx, /* Q15 */ - GainFrame_fx, /* Q18 */ - window_shb_fx, - subwin_shb_fx, - &Q_bwe_exc, &Qx, n_mem3_new, st->prev_Q_bwe_syn2 ); - - IF( hStereoICBWE != NULL ) - { - Copy_Scale_sig_16_32_DEPREC( lpc_shb_fx, hStereoICBWE->lpSHBRef_fx, LPC_SHB_ORDER + 1, 0 ); - Copy( GainShape_fx, hStereoICBWE->gshapeRef_fx, NUM_SHB_SUBFR ); - hStereoICBWE->gFrameRef_fx = GainFrame_fx; - move32(); - - Copy( shaped_shb_excitation_fx, hStereoICBWE->shbSynthRef_fx, L_FRAME16k ); - } - - max_val = 0; - move16(); - FOR( i = 0; i < L_FRAME16k; i++ ) - { - max_val = s_max( max_val, abs_s( shaped_shb_excitation_fx[i] ) ); /* Q0 */ - } - IF( max_val == 0 ) - { - curr_frame_pow_fx = 0; - move32(); - n = 0; - move16(); - } - ELSE - { - n = norm_s( max_val ); - max_val = 0; - move16(); - FOR( i = 0; i < L_FRAME16k; i++ ) - { - shaped_shb_excitation_frac[i] = shl_sat( shaped_shb_excitation_fx[i], n ); /*Q_bwe_exc+n*/ - move16(); - } - - curr_frame_pow_fx = 0; - move32(); - FOR( i = 0; i < L_FRAME16k; i++ ) - { - L_tmp = L_mult0( shaped_shb_excitation_frac[i], shaped_shb_excitation_frac[i] ); /*2*(Q_bwe_exc+n)*/ - curr_frame_pow_fx = L_add( curr_frame_pow_fx, L_shr( L_tmp, 9 ) ); /*2*(Q_bwe_exc+n)-9*/ - } - } - curr_frame_pow_exp = sub( shl( add( Q_bwe_exc, n ), 1 ), 9 ); - tmp = sub( st->prev_frame_pow_exp, curr_frame_pow_exp ); - IF( tmp > 0 ) /* shifting prev */ - { - IF( GT_16( tmp, 32 ) ) - { - st->prev_frame_pow_exp = add( curr_frame_pow_exp, 32 ); - move16(); - tmp = 32; - move16(); - } - hBWE_TD->prev_swb_bwe_frame_pow_fx = L_shr( hBWE_TD->prev_swb_bwe_frame_pow_fx, tmp ); - move32(); - st->prev_frame_pow_exp = curr_frame_pow_exp; - move16(); - } - ELSE /* shifting curr */ - { - IF( LT_16( tmp, -32 ) ) - { - curr_frame_pow_exp = sub( st->prev_frame_pow_exp, 32 ); - tmp = -32; - move16(); - } - curr_frame_pow_fx = L_shr( curr_frame_pow_fx, -tmp ); - curr_frame_pow_exp = st->prev_frame_pow_exp; - move16(); - } - test(); - test(); - IF( !st->bfi && ( st->prev_bfi || st->prev_use_partial_copy ) ) - { - test(); - test(); - IF( ( GT_32( L_shr( curr_frame_pow_fx, 1 ), hBWE_TD->prev_swb_bwe_frame_pow_fx ) ) && - ( GT_32( hBWE_TD->prev_swb_bwe_frame_pow_fx, L_tmp ) ) && EQ_16( st->prev_coder_type, UNVOICED ) ) - { - L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); - scale_fx = round_fx( L_shl( L_tmp, exp ) ); /*Q15*/ - - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - temp_fx = round_fx( L_shl( L_tmp, exp ) ); /*Q15*/ - } - ELSE - { - scale_fx = temp_fx = 32767; - move16(); /*Q15*/ - move16(); /*Q15*/ - } - - FOR( j = 0; j < 8; j++ ) - { - GainShape_fx[2 * j] = mult_r( GainShape_fx[2 * j], scale_fx ); - move16(); - GainShape_fx[2 * j + 1] = mult_r( GainShape_fx[2 * j + 1], scale_fx ); - move16(); - FOR( i = 0; i < L_FRAME16k / 8; i++ ) - { - shaped_shb_excitation_fx[add( i, j * ( L_FRAME16k / 8 ) )] = mult_r( shaped_shb_excitation_fx[add( i, j * ( L_FRAME16k / 8 ) )], scale_fx ); - move16(); - } - - IF( temp_fx > 0 ) - { - /* scale_fx <= temp_fx, due to scale_fx = sqrt( st->prev_swb_bwe_frame_pow_fx/curr_frame_pow_fx ), temp_fx = sqrt( scale_fx, 1.f/8.f ) - and curr_frame_pow_fx > st->prev_swb_bwe_frame_pow_fx -> scale_fx <= 1.0, sqrt(scale_fx, 1.f/8.f) >= scale_fx */ - IF( LT_16( scale_fx, temp_fx ) ) - { - scale_fx = div_s( scale_fx, temp_fx ); - } - ELSE - { - scale_fx = 32767; - move16(); - } - } - ELSE - { - scale_fx = 0; - move16(); - } - } - } - - /* adjust the FEC frame energy */ - IF( st->bfi ) - { - scale_fx = temp_fx = 4096; - move16(); /*Q12*/ - move16(); - IF( EQ_16( st->nbLostCmpt, 1 ) ) - { - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - IF( GT_32( curr_frame_pow_fx, hBWE_TD->prev_swb_bwe_frame_pow_fx ) && - NE_16( st->prev_coder_type, UNVOICED ) && - ( st->last_good != UNVOICED_CLAS ) ) - { - L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); /*31 - exp*/ - scale_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - temp_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ - } - ELSE IF( LT_32( curr_frame_pow_fx, L_shr( hBWE_TD->prev_swb_bwe_frame_pow_fx, 1 ) ) && EQ_16( st->nbLostCmpt, 1 ) && - ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) || GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) ) && - ( EQ_16( st->prev_coder_type, UNVOICED ) || ( st->last_good == UNVOICED_CLAS ) || GT_16( hBWE_TD->tilt_swb_fec_fx, 10240 ) ) ) - { - L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); - scale_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - temp_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ - } - } - ELSE IF( GT_16( st->nbLostCmpt, 1 ) ) - { - test(); - test(); - test(); - test(); - test(); - IF( GT_32( curr_frame_pow_fx, hBWE_TD->prev_swb_bwe_frame_pow_fx ) ) - { - L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); - scale_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - temp_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ - } - ELSE IF( LT_32( curr_frame_pow_fx, L_shr( hBWE_TD->prev_swb_bwe_frame_pow_fx, 1 ) ) && - ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) || GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) ) && - ( EQ_16( st->prev_coder_type, UNVOICED ) || ( st->last_good == UNVOICED_CLAS ) || GT_16( hBWE_TD->tilt_swb_fec_fx, 10240 ) ) ) - { - L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); - L_tmp = L_min( L_tmp, L_shl_sat( 2, sub( 31, exp ) ) ); /*31 - exp*/ - scale_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); - temp_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ - } - } - - FOR( j = 0; j < 8; j++ ) - { - GainShape_fx[2 * j] = shl_sat( mult_r( GainShape_fx[2 * j], scale_fx ), 3 ); - move16(); /* 15 +12 +3-15 =15*/ - GainShape_fx[add( 2 * j, 1 )] = shl_sat( mult_r( GainShape_fx[add( 2 * j, 1 )], scale_fx ), 3 ); - move16(); - FOR( i = 0; i < 40; i++ ) - { - shaped_shb_excitation_fx[i + j * L_FRAME16k / 8] = shl( mult_r( shaped_shb_excitation_fx[i + j * L_FRAME16k / 8], scale_fx ), 3 ); - move16(); /* Q_bwe_exc +12+3 -15 =Q_bwe_exc*/ - } - - IF( temp_fx > 0 ) - { - IF( LT_16( scale_fx, temp_fx ) ) - { - scale_fx = shr( div_s( scale_fx, temp_fx ), 3 ); - } - ELSE - { - tmp1 = sub( norm_s( scale_fx ), 1 ); - tmp2 = norm_s( temp_fx ); - scale_fx = div_s( shl( scale_fx, tmp1 ), shl( temp_fx, tmp2 ) ); - scale_fx = shr( scale_fx, add( sub( tmp1, tmp2 ), 3 ) ); - } - } - ELSE - { - scale_fx = 0; - move16(); - } - } - } - - hBWE_TD->prev_swb_bwe_frame_pow_fx = curr_frame_pow_fx; - move32(); - st->prev_frame_pow_exp = curr_frame_pow_exp; - move16(); - - Word64 prev_ener_shb64 = 0; - move64(); - FOR( i = 0; i < L_FRAME16k; i++ ) - { - prev_ener_shb64 = W_mac0_16_16( prev_ener_shb64, shaped_shb_excitation_fx[i], shaped_shb_excitation_fx[i] ); /* Q0 */ - } - L_prev_ener_shb = W_sat_l( prev_ener_shb64 ); - - L_prev_ener_shb = Mult_32_16( L_prev_ener_shb, 26214 ); /* 2*Q_bwe_exc_mod+8; 26214=(1/L_FRAME16k) in Q23 */ - st->prev_ener_shb_fx = 0; - move16(); - IF( L_prev_ener_shb != 0 ) - { - exp = norm_l( L_prev_ener_shb ); - tmp = extract_h( L_shl( L_prev_ener_shb, exp ) ); - exp = sub( exp, sub( 30, ( add( i_mult( 2, Q_bwe_exc ), 8 ) ) ) ); - - tmp = div_s( 16384, tmp ); - L_tmp = L_deposit_h( tmp ); - L_tmp = Isqrt_lc( L_tmp, &exp ); - st->prev_ener_shb_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /* Q1 */ - move16(); - } - - IF( st->hBWE_FD != NULL ) - { - L_tmp = Mult_32_16( curr_frame_pow_fx, 26214 ); /* curr_frame_pow_exp+8; 26214=(1/L_FRAME16k) in Q23 */ - tmp = 0; - move16(); - IF( L_tmp != 0 ) - { - exp = norm_l( L_tmp ); - tmp = extract_h( L_shl( L_tmp, exp ) ); - exp = sub( exp, sub( 30, add( curr_frame_pow_exp, 8 ) ) ); - - tmp = div_s( 16384, tmp ); - L_tmp = L_deposit_h( tmp ); - L_tmp = Isqrt_lc( L_tmp, &exp ); - tmp = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /* Q1 */ - } - set16_fx( st->prev_SWB_fenv_fx, tmp, SWB_FENV ); /* Q1 */ - } - - FOR( i = 0; i < L_FRAME16k; i++ ) - { - shaped_shb_excitation_fx_32[i] = L_shl( shaped_shb_excitation_fx[i], sub( Q11, Q_bwe_exc ) ); - move32(); - } - - /* generate 32kHz SHB synthesis from 12.8(16)kHz signal */ - GenSHBSynth_fx_32( shaped_shb_excitation_fx_32, error_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->L_frame, &( hBWE_TD->syn_dm_phase ) ); - 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, 2 * ALLPASSSECTIONS_STEEP, -( Q11 - Q_bwe_exc ) ); - Copy32( error_fx + L_FRAME32k - L_SHB_TRANSITION_LENGTH, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH ); - - /* resample SHB synthesis (if needed) and scale down */ - synth_scale_fx = 32767; - move16(); /* 1.0 in Q15 */ - if ( EQ_16( st->codec_mode, MODE1 ) ) - { - synth_scale_fx = 29491; - move16(); /* 0.9 in Q15 */ - } - - IF( EQ_32( st->output_Fs, 48000 ) ) - { - IF( EQ_16( st->extl, FB_TBE ) ) - { - tmp = norm_l( GainFrame_fx ); - if ( GainFrame_fx == 0 ) - { - tmp = 31; - move16(); - } - L_tmp = L_shl( GainFrame_fx, tmp ); /* 18 + tmp */ - - tmp1 = 0; - move16(); - FOR( i = 0; i < L_FRAME16k; i++ ) - { - Word16 idx = 0; - move16(); - IF( i != 0 ) - { - idx = idiv1616( i_mult( NUM_SHB_SUBFR, i ), L_FRAME16k ); - } - L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ - White_exc16k_fx[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k_fx[i] ) ); /* 18 + tmp +*Q_white_exc -15 -16 */ - move16(); - tmp1 = s_max( tmp1, abs_s( White_exc16k_fx[i] ) ); - } - - *Q_white_exc = sub( add( *Q_white_exc, tmp ), 13 ); /* *Q_white_exc + 18 + tmp -15 -16 */ - move16(); - tmp = norm_s( tmp1 ); - if ( tmp1 == 0 ) - { - tmp = 15; - move16(); - } - - FOR( i = 0; i < L_FRAME16k; i++ ) - { - White_exc16k_fx[i] = shl( White_exc16k_fx[i], sub( tmp, 1 ) ); - move16(); - } - *Q_white_exc = sub( add( *Q_white_exc, tmp ), 1 ); - move16(); - } - - IF( NE_16( synth_scale_fx, 32767 ) ) /* 1.0 in Q15 */ - { - FOR( i = 0; i < L_FRAME32k; i++ ) - { - error_fx[i] = Mpy_32_16_1( error_fx[i], synth_scale_fx ); - move32(); - } - } - interpolate_3_over_2_allpass_32( error_fx, L_FRAME32k, synth_fx, hBWE_TD->int_3_over_2_tbemem_dec_fx_32 ); - } - ELSE IF( EQ_32( st->output_Fs, 32000 ) ) - { - IF( NE_16( synth_scale_fx, 32767 ) ) /* 1.0 in Q15 */ - { - FOR( i = 0; i < L_FRAME32k; i++ ) - { - synth_fx[i] = Mpy_32_16_1( error_fx[i], synth_scale_fx ); - move32(); /*Qx*/ - } - } - ELSE - { - Copy32( error_fx, synth_fx, L_FRAME32k ); - } - } - ELSE IF( EQ_32( st->output_Fs, 16000 ) ) - { - IF( NE_16( synth_scale_fx, 32767 ) ) /* 1.0 in Q15 */ - { - FOR( i = 0; i < L_FRAME32k; i++ ) - { - error_fx[i] = Mpy_32_16_1( error_fx[i], synth_scale_fx ); - move32(); - } - } - - Decimate_allpass_steep_fx32( error_fx, hBWE_TD->mem_resamp_HB_32k_fx_32, L_FRAME32k, synth_fx ); - } - - - /* Update previous frame parameters for FEC */ - Copy( lsf_shb_fx, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER ); - IF( EQ_16( st->codec_mode, MODE1 ) ) - { - hBWE_TD->GainFrame_prevfrm_fx = GainFrame_fx; - move32(); /*Q18*/ - hBWE_TD->tilt_swb_fec_fx = tilt_swb_fec_fx; - move16(); - - if ( !st->bfi ) - { - hBWE_TD->GainAttn_fx = 32767; /*1.0f in Q15*/ - move16(); - } - } - ELSE - { - IF( !st->bfi ) - { - hBWE_TD->GainFrame_prevfrm_fx = GainFrame_fx; - move32(); /*Q18*/ - hBWE_TD->tilt_swb_fec_fx = tilt_swb_fec_fx; - move16(); - hBWE_TD->GainAttn_fx = 32767; /*1.0f in Q15*/ - move16(); - } - } - - hBWE_TD->prev_ener_fx = ener_tmp_fx[NUM_SHB_SUBGAINS - 1]; - move32(); - hBWE_TD->prev_GainShape_fx = GainShape_fx[NUM_SHB_SUBFR - 1]; - move16(); - st->prev_Q_bwe_syn2 = Q_bwe_exc; - move16(); - st->prev_Qx = Q_bwe_exc; - move16(); - - return; -} -/*-------------------------------------------------------------------* - * Dequant_lower_LSF() - * - * Dequantized the lower LSFs - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * Map_higher_LSF() - * - * Map the higher LSFs from the lower LSFs - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * Map_higher_LSF() - * - * Map the higher LSFs from the lower LSFs - *-------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------* - * dequantizeSHBparams() - * - * Dequantize super highband spectral envolope, temporal gains and frame gain - *-------------------------------------------------------------------*/ - - -void GenTransition_fixed( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ - const Word32 output_Fs, /* i : output sampling rate : Q0 */ - const Word16 element_mode, /* i : element mode : Q0 */ - const Word16 L_frame, /* i : ACELP frame length : Q0 */ - const Word16 rf_flag, /* i : RF flag : Q0 */ - const Word32 total_brate, /* i : total bitrate : Q0 */ - const Word16 prev_Qx ) -{ - Word16 i, length; - - Word32 syn_overlap_32k_fx[2 * SHB_OVERLAP_LEN]; - - /* set targeted length of transition signal */ - length = i_mult( 2, NS2SA_FX2( output_Fs, DELAY_BWE_TOTAL_NS ) ); - - /* upsample overlap snippet */ - Interpolate_allpass_steep_32( hBWE_TD->syn_overlap_fx_32, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, SHB_OVERLAP_LEN, syn_overlap_32k_fx ); - - /* perFORm spectral flip and downmix with overlap snippet to match HB synth */ - test(); - test(); - test(); - test(); - IF( ( ( element_mode == EVS_MONO ) && ( rf_flag || EQ_32( total_brate, ACELP_9k60 ) ) ) || ( ( element_mode > EVS_MONO ) && EQ_16( L_frame, L_FRAME ) ) ) - { - flip_and_downmix_generic_fx_32( syn_overlap_32k_fx, syn_overlap_32k_fx, 2 * SHB_OVERLAP_LEN, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx + HILBERT_ORDER1, hBWE_TD->genSHBsynth_Hilbert_Mem_fx + ( HILBERT_ORDER1 + 2 * HILBERT_ORDER2 ), &( hBWE_TD->syn_dm_phase ) ); - } - ELSE - { - FOR( i = 0; i < 2 * SHB_OVERLAP_LEN; i++ ) - { - IF( i % 2 == 0 ) - { - syn_overlap_32k_fx[i] = L_negate( syn_overlap_32k_fx[i] ); - } - ELSE - { - syn_overlap_32k_fx[i] = syn_overlap_32k_fx[i]; - } - move32(); - } - } - - /* cross fade of overlap snippet and mirrored HB synth from previous frame */ - FOR( i = 0; i < 2 * L_SHB_LAHEAD; i++ ) - { - outputHB_fx[i] = L_add_sat( Mpy_32_16_1( hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i], window_shb_32k_fx[i] ), Mpy_32_16_1( syn_overlap_32k_fx[i], window_shb_32k_fx[2 * L_SHB_LAHEAD - 1 - i] ) ); - move32(); - } - - /* fill transition signal with mirrored HB synth from previous frame to fully fill delay alignment buffer gap */ - FOR( ; i < length; i++ ) - { - outputHB_fx[i] = L_shl( hBWE_TD->old_tbe_synth_fx[L_SHB_TRANSITION_LENGTH - 1 - i], sub( Q11, prev_Qx ) ); - move32(); - } - - IF( EQ_32( output_Fs, 48000 ) ) - { - interpolate_3_over_2_allpass_32( outputHB_fx, length, outputHB_fx, hBWE_TD->int_3_over_2_tbemem_dec_fx_32 ); - } - ELSE IF( EQ_32( output_Fs, 16000 ) ) - { - Decimate_allpass_steep_fx32( outputHB_fx, hBWE_TD->mem_resamp_HB_32k_fx_32, L_FRAME32k, outputHB_fx ); - } - - return; -} -void GenTransition_WB_fixed( - TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ - Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ - const Word32 output_Fs /* i : output sampling rate */ -) -{ - Word16 i, length; - Word32 speech_buf_16k1_fx[SHB_OVERLAP_LEN], speech_buf_16k2_fx[2 * SHB_OVERLAP_LEN]; - Word32 upsampled_synth_fx[L_FRAME48k]; - - /* set targeted length of transition signal */ - length = i_mult( 2, NS2SA_FX2( output_Fs, DELAY_BWE_TOTAL_NS ) ); - - /* upsample overlap snippet */ - Interpolate_allpass_steep_32( hBWE_TD->syn_overlap_fx_32, hBWE_TD->state_lsyn_filt_shb_fx_32, SHB_OVERLAP_LEN / 2, speech_buf_16k1_fx ); - Interpolate_allpass_steep_32( speech_buf_16k1_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, SHB_OVERLAP_LEN, speech_buf_16k2_fx ); - - /* perform spectral flip and downmix with overlap snippet to match HB synth */ - FOR( i = 0; i < SHB_OVERLAP_LEN; i++ ) - { - IF( i % 2 == 0 ) - { - speech_buf_16k2_fx[i] = L_negate( speech_buf_16k2_fx[i] ); - move32(); - } - ELSE - { - speech_buf_16k2_fx[i] = speech_buf_16k2_fx[i]; - move32(); - } - } - - /* cross fade of overlap snippet and mirrored HB synth from previous frame */ - FOR( i = 0; i < L_SHB_LAHEAD; i++ ) - { - outputHB_fx[i] = L_add( Mpy_32_16_1( hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i], window_shb_fx[i] ), Mpy_32_16_1( speech_buf_16k2_fx[i], window_shb_fx[L_SHB_LAHEAD - 1 - i] ) ); - move32(); - outputHB_fx[i] = Mpy_32_16_1( outputHB_fx[i], 21299 ); - move32(); - } - - /* fill transition signal with mirrored HB synth from previous frame to fully fill delay alignment buffer gap */ - FOR( ; i < length; i++ ) - { - outputHB_fx[i] = hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i]; - move32(); - outputHB_fx[i] = Mpy_32_16_1( outputHB_fx[i], 21299 ); - move32(); - } - - /* upsampling if necessary */ - IF( EQ_32( output_Fs, 32000 ) ) - { - Interpolate_allpass_steep_32( outputHB_fx, hBWE_TD->mem_resamp_HB_fx_32, L_FRAME16k, upsampled_synth_fx ); - Copy32( upsampled_synth_fx, outputHB_fx, L_FRAME32k ); - } - ELSE IF( EQ_32( output_Fs, 48000 ) ) - { - interpolate_3_over_1_allpass_32( outputHB_fx, L_FRAME16k, upsampled_synth_fx, hBWE_TD->mem_resamp_HB_fx_32 ); - Copy32( upsampled_synth_fx, outputHB_fx, L_FRAME48k ); - } - - return; -} - -/*-------------------------------------------------------------------* - * td_bwe_dec_init() - * - * Initialize TD BWE state structure at the decoder - *-------------------------------------------------------------------*/ diff --git a/lib_dec/swb_tbe_dec_fx.c b/lib_dec/swb_tbe_dec_fx.c index 28ac01671..a37ebf9d9 100644 --- a/lib_dec/swb_tbe_dec_fx.c +++ b/lib_dec/swb_tbe_dec_fx.c @@ -7,6 +7,7 @@ #include "options.h" #include "rom_com.h" #include "prot_fx.h" +#include "prot.h" #include "rom_dec.h" #include "stl.h" @@ -31,6 +32,11 @@ Word16 dotp_loc( const Word16 n /* i : vector length */ ); +void find_max_mem_dec_m3( + Decoder_State *st, + Word16 *n_mem3 ); + + /* gain shape concealment code */ static void gradientGainShape( Decoder_State *st_fx, Word16 *GainShape, Word32 *GainFrame ); @@ -3695,12 +3701,12 @@ static void gradientGainShape( IF( GT_16( 8192, tmp ) ) { - GainShape[add( i * 4, j )] = shl( tmp, 2 ); + GainShape[i * 4 + j] = shl( tmp, 2 ); move16(); /* (GainShapeTemp[i]*0.6)>>1 */ } ELSE { - GainShape[add( i * 4, j )] = 32767; + GainShape[i * 4 + j] = 32767; move16(); /* Clipping here to avoid the a huge change of the code due to gain shape change */ } } @@ -3716,12 +3722,12 @@ static void gradientGainShape( { IF( LT_16( GainShapeTemp[i], 16384 ) ) { - GainShape[add( i * 4, j )] = shl( GainShapeTemp[i], 1 ); + GainShape[i * 4 + j] = shl( GainShapeTemp[i], 1 ); move16(); } ELSE { - GainShape[add( i * 4, j )] = 32767; + GainShape[i * 4 + j] = 32767; move16(); } } @@ -3750,12 +3756,12 @@ static void gradientGainShape( { IF( LT_16( GainShapeTemp[i], 16384 ) ) { - GainShape[add( i * 4, j )] = shl( GainShapeTemp[i], 1 ); + GainShape[i * 4 + j] = shl( GainShapeTemp[i], 1 ); move16(); } ELSE { - GainShape[add( i * 4, j )] = 32767; + GainShape[i * 4 + j] = 32767; move16(); } } @@ -5300,3 +5306,2019 @@ void td_bwe_dec_init_fx( return; } + +/*-------------------------------------------------------------------* + * ResetSHBbuffer_Dec() + * + * + *-------------------------------------------------------------------*/ + +static void calc_tilt_bwe_fx_loc( + const Word32 *sp_fx, /* i : input signal : Q11 */ + Word32 *tilt_fx, /* o : signal tilt : tilt_fx_q */ + Word16 *tilt_fx_q, /* o : signal tilt */ + const Word16 N /* i : signal length : Q0 */ +) +{ + Word16 i; + Word64 r0_fx, r1_fx; + + r0_fx = EPSILON_FX_SMALL; + move64(); + FOR( i = 0; i < N; i++ ) + { + r0_fx = W_add( r0_fx, W_shr( W_mult_32_32( sp_fx[i], sp_fx[i] ), 1 ) ); /*Q11*2 - 1*/ + } + r1_fx = W_deposit32_l( abs( L_sub( sp_fx[1], sp_fx[0] ) ) ); /*Q11*/ + FOR( i = 2; i < N; i++ ) + { + IF( W_mult_32_32( L_sub( sp_fx[i], sp_fx[i - 1] ) /*Q11*/, L_sub( sp_fx[i - 1], sp_fx[i - 2] ) /*Q11*/ ) /*Q11 * 2 - 1*/ < 0 ) + { + r1_fx = W_add( r1_fx, W_deposit32_l( abs( L_sub( sp_fx[i], sp_fx[i - 1] ) ) ) ); /*Q11*/ + } + } + Word16 headroom_left_r0 = W_norm( r0_fx ); + Word16 headroom_left_r1 = W_norm( r1_fx ); + Word16 r0_q = 0, r1_q = 0; + move16(); + move16(); + IF( LT_16( headroom_left_r0, 32 ) ) + { + r0_fx = W_shr( r0_fx, sub( 32, headroom_left_r0 ) ); + r0_q = sub( 31, sub( ( 2 * OUTPUT_Q ), sub( 32, headroom_left_r0 ) ) ); + } + ELSE + { + r0_q = 31 - ( 2 * OUTPUT_Q ); + move16(); + } + + IF( LT_16( headroom_left_r1, 32 ) ) + { + r1_fx = W_shr( r1_fx, sub( 32, headroom_left_r1 ) ); + r1_q = sub( OUTPUT_Q, sub( 32, headroom_left_r1 ) ); + } + ELSE + { + r1_q = OUTPUT_Q; + move16(); + } + Word32 temp_r0_inv = ISqrt32( W_extract_l( r0_fx ), &r0_q ); + Word32 res = Mpy_32_32( W_extract_l( r1_fx ), temp_r0_inv ); + // Word16 res_q = r1_q + ( r0_q < 0 ? ( 31 + ( -1 * r0_q ) ) : r0_q ) - 31; + Word16 res_q; + IF( r0_q < 0 ) + { + res_q = add( r1_q, sub( add( 31, -r0_q ), 31 ) ); + } + ELSE + { + res_q = add( r1_q, sub( r0_q, 31 ) ); + } + Word16 norm_res = norm_l( res ); + IF( norm_res > 0 ) + { + *tilt_fx = L_shl_sat( res, norm_res ); + move32(); + *tilt_fx_q = add( res_q, norm_res ); + move16(); + } + ELSE + { + *tilt_fx = res; + move32(); + *tilt_fx_q = res_q; + move16(); + } + return; +} + +/*-------------------------------------------------------------------* + * swb_tbe_dec() + * + * SWB TBE decoder, 6 - 14 kHz (or 7.5 - 15.5 kHz) band decoding module + *-------------------------------------------------------------------*/ +static void rescale_genSHB_mem_dec_ivas( + Decoder_State *st_fx, + Word16 sf /*Q0*/ +) +{ + Word16 i; + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st_fx->hBWE_TD; + + FOR( i = 0; i < NL_BUFF_OFFSET; i++ ) + { + hBWE_TD->old_bwe_exc_extended_fx[i] = shl( hBWE_TD->old_bwe_exc_extended_fx[i], sf ); + move16(); + } + + FOR( i = 0; i < 7; i++ ) + { + hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i] = shl( hBWE_TD->mem_genSHBexc_filt_down_shb_fx[i], sf ); + move16(); + } + + /* -- Apply memory scaling for 13.2 and 16.4k bps using sf ----*/ + IF( LT_32( st_fx->total_brate, ACELP_24k40 ) ) + { + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + hBWE_TD->state_lpc_syn_fx[i] = shl_sat( hBWE_TD->state_lpc_syn_fx[i], sf ); + move16(); + } + + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + hBWE_TD->state_syn_shbexc_fx[i] = shl_sat( hBWE_TD->state_syn_shbexc_fx[i], sf ); + move16(); + } + } + + hBWE_TD->mem_csfilt_fx[0] = L_shl( hBWE_TD->mem_csfilt_fx[0], sf ); + move32(); + + hBWE_TD->tbe_demph_fx = shl_r( hBWE_TD->tbe_demph_fx, sf ); + move16(); + hBWE_TD->tbe_premph_fx = shl_r( hBWE_TD->tbe_premph_fx, sf ); + move16(); +} + +void find_max_mem_dec_m3( + Decoder_State *st, + Word16 *n_mem3 ) +{ + Word16 i; + // Word16 n_mem_32; + Word16 tempQ15; + Word16 max3; + // Word32 tempQ32, Lmax3; + TD_BWE_DEC_HANDLE hBWE_TD; + hBWE_TD = st->hBWE_TD; + + /* --------------------------------------------------------------*/ + /* Find headroom for synthesis stage associated with these memories: + 1. st->syn_overlap_fx*/ + max3 = 0; + move16(); + /* find max in prev overlapSyn */ + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + tempQ15 = abs_s( hBWE_TD->syn_overlap_fx[i] ); + max3 = s_max( max3, tempQ15 ); + } + /* find max in prev genSHBsynth_state_lsyn_filt_shb_local_fx */ + + /* estimate the norm for 16-bit memories */ + *n_mem3 = norm_s( max3 ); + move16(); + if ( max3 == 0 ) + { + *n_mem3 = 15; + move16(); + } +} + +/*-------------------------------------------------------------------* + * ivas_swb_tbe_dec_fx() + * + * SWB TBE decoder, 6 - 14 kHz (or 7.5 - 15.5 kHz) band decoding module + *-------------------------------------------------------------------*/ +void ivas_swb_tbe_dec_fx( + Decoder_State *st, /* i/o: decoder state structure */ + STEREO_ICBWE_DEC_HANDLE hStereoICBWE, /* i/o: IC-BWE state structure */ + const Word32 *bwe_exc_extended_fx, /* i : bandwidth extended excitation : Q_exc */ + Word16 Q_exc, + const Word16 voice_factors_fx[], /* i : voicing factors : Q15 */ + const Word32 old_syn_12k8_16k_fx[], /* i : low band synthesis : old_syn_fx */ + Word16 *White_exc16k_fx, /* o : shaped white excitation for the FB TBE : Q_white_exc*/ + Word32 *synth_fx, /* o : SHB synthesis/final synthesis : Qx */ + Word16 *pitch_buf_fx, /* i : Q6 */ + Word16 *Q_white_exc ) +{ + Word16 i, j, cnt, n; + Word16 stemp; + TD_BWE_DEC_HANDLE hBWE_TD; + Word32 shaped_shb_excitation_fx_32[L_FRAME16k + L_SHB_LAHEAD]; + Word16 bwe_exc_extended_16[L_FRAME32k + NL_BUFF_OFFSET]; + Word16 shaped_shb_excitation_fx[L_FRAME16k + L_SHB_LAHEAD]; + Word16 lsf_shb_fx[LPC_SHB_ORDER], lpc_shb_fx[LPC_SHB_ORDER + 1], GainShape_fx[NUM_SHB_SUBFR]; // Q12,Q12,Q15 + Word32 GainFrame_fx; // Q18 + Word32 error_fx[L_FRAME32k]; + Word16 ener_fx; + Word32 L_ener; + Word16 is_fractive; + Word32 prev_pow_fx, curr_pow_fx, Lscale; + Word16 scale_fx; + Word16 max_val, temp_fx, shaped_shb_excitation_frac[L_FRAME16k + L_SHB_LAHEAD]; + Word32 curr_frame_pow_fx; + Word16 curr_frame_pow_exp; + Word32 L_prev_ener_shb; + Word16 vf_modified_fx[NB_SUBFR16k]; + Word16 f_fx, inc_fx; + Word32 GainFrame_prevfrm_fx; + Word32 tilt_swb_fec_32_fx; + Word16 tilt_swb_fec_fx_q; + Word16 tilt_swb_fec_fx; + Word32 prev_ener_ratio_fx = 0; /* initialize just to avoid compiler warning */ + Word16 lsp_shb_1_fx[LPC_SHB_ORDER], lsp_shb_2_fx[LPC_SHB_ORDER], lsp_temp_fx[LPC_SHB_ORDER]; + Word16 lpc_shb_sf_fx[4 * ( LPC_SHB_ORDER + 1 )]; + const Word16 *ptr_lsp_interp_coef_fx; + Word32 shb_ener_sf_32; + Word16 shb_res_gshape_fx[NB_SUBFR16k]; + Word16 mixFactors_fx; + Word16 vind; + Word16 shb_res_dummy_fx[L_FRAME16k]; + Word16 shaped_shb_excitationTemp_fx[L_FRAME16k]; + Word32 ener_tmp_fx[NUM_SHB_SUBGAINS]; + Word16 GainShape_tmp_fx[NUM_SHB_SUBGAINS]; + Word16 pitch_fx; + Word16 l_subframe; + Word16 formant_fac_fx; + Word16 synth_scale_fx; + Word16 lsf_diff_fx[LPC_SHB_ORDER], w_fx[LPC_SHB_ORDER]; + Word16 refl_fx[M]; + Word16 tilt_para_fx; + Word16 *nlExc16k_fx, *mixExc16k_fx; + Word16 MSFlag; + Word16 feedback_fx; + Word16 GainShape_tilt_fx; + + // scaling + Word16 exp, tmp; + Word16 tmp1, tmp2; + Word16 mean_vf; + Word32 Lmax, L_tmp; + Word16 frac; + Word32 L_tmp1, L_tmp2; + Word16 Q_bwe_exc; + Word16 Q_bwe_exc_fb; + Word16 Q_shb; + Word16 n_mem, n_mem2, n_mem3, Qx, sc; + Word16 expa, expb; + Word16 fraca, fracb; + Word16 exp_ener, inv_ener; + + hBWE_TD = st->hBWE_TD; + + /* initializations */ + GainFrame_fx = 0; + move32(); + mixFactors_fx = 0; + move16(); + shb_ener_sf_32 = 0; + move32(); + set16_fx( shaped_shb_excitationTemp_fx, 0, L_FRAME16k ); + if ( st->hTdCngDec != NULL ) + { + st->hTdCngDec->shb_dtx_count = 0; + move16(); + } + is_fractive = 0; + move16(); + + IF( hStereoICBWE != NULL ) + { + nlExc16k_fx = hStereoICBWE->nlExc16k_fx; + mixExc16k_fx = hStereoICBWE->mixExc16k_fx; + MSFlag = hStereoICBWE->MSFlag; + move16(); + } + ELSE + { + nlExc16k_fx = NULL; + mixExc16k_fx = NULL; + MSFlag = 0; + move16(); + } + + /* find tilt */ + calc_tilt_bwe_fx_loc( old_syn_12k8_16k_fx, &tilt_swb_fec_32_fx, &tilt_swb_fec_fx_q, L_FRAME ); + tilt_swb_fec_fx = round_fx_sat( L_shl_sat( tilt_swb_fec_32_fx, sub( 11 + 16, tilt_swb_fec_fx_q ) ) ); + test(); + if ( st->bfi && st->clas_dec != UNVOICED_CLAS ) + { + tilt_swb_fec_fx = hBWE_TD->tilt_swb_fec_fx; + move16(); + } + + /* WB/SWB bandwidth switching */ + test(); + test(); + IF( ( GT_16( st->tilt_wb_fx, 10240 /*5 in Q11*/ ) && ( EQ_16( st->clas_dec, UNVOICED_CLAS ) ) ) || GT_16( st->tilt_wb_fx, 20480 /*10 in Q11*/ ) ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( ( st->prev_fractive == 0 ) && + ( LT_32( st->prev_enerLH_fx, L_shl( st->enerLH_fx, 1 ) ) && GT_32( st->prev_enerLH_fx, L_shr( st->enerLH_fx, 1 ) ) && LT_32( st->prev_enerLL_fx, L_shl( st->enerLL_fx, 1 ) ) && GT_32( st->prev_enerLL_fx, L_shr( st->enerLL_fx, 1 ) ) ) ) || + ( EQ_16( st->prev_fractive, 1 ) && + GT_32( L_shr( st->prev_enerLH_fx, 2 ), Mult_32_16( st->enerLH_fx, 24576 ) ) ) /* 24576 in Q13*/ + || ( GT_32( L_shr( st->enerLL_fx, 1 ), Mult_32_16( st->enerLH_fx, 24576 ) ) && /*24576 = 1.5 in Q14*/ + LT_16( st->tilt_wb_fx, 20480 ) ) /* 20480 = 10 in Q11*/ + ) + { + is_fractive = 0; + } + ELSE + { + is_fractive = 1; + } + move16(); + } + + /* WB/SWB bandwidth switching */ + IF( st->bws_cnt > 0 ) + { + f_fx = 1489; /*1.0f / 22.0f in Q15*/ + move16(); + inc_fx = 1489; /*1.0f / 22.0f in Q15*/ + move16(); + + IF( EQ_16( is_fractive, 1 ) ) + { + Copy( lsf_tab_fx, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER ); + } + ELSE + { + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + hBWE_TD->lsp_prevfrm_fx[i] = f_fx; /*Q15*/ + move16(); + f_fx = add( f_fx, inc_fx ); /*Q15*/ + } + } + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) && !( ( L_sub( L_shr( st->prev_enerLH_fx, 1 ), st->enerLH_fx ) < 0 ) && L_sub( st->prev_enerLH_fx, ( L_shr( st->enerLH_fx, 1 ) > 0 ) ) ) ) || st->last_core != ACELP_CORE || ( ( st->last_core == ACELP_CORE ) && GT_32( abs( L_sub( st->last_core_brate, st->core_brate ) ), 3600 ) ) || EQ_16( s_xor( is_fractive, st->prev_fractive ), 1 ) ) + { + set16_fx( GainShape_fx, 11587, NUM_SHB_SUBFR ); /*0.3536f in Q15*/ + } + ELSE + { + if ( GT_16( hBWE_TD->prev_GainShape_fx, 11587 ) ) /*0.3536f in Q15*/ + { + hBWE_TD->prev_GainShape_fx = 11587; /*0.3536f in Q15*/ + move16(); + } + set16_fx( GainShape_fx, hBWE_TD->prev_GainShape_fx, NUM_SHB_SUBFR ); + } + + Copy( hBWE_TD->lsp_prevfrm_fx, lsf_shb_fx, LPC_SHB_ORDER ); + set16_fx( shb_res_gshape_fx, 3277 /*0.2f Q14*/, NB_SUBFR16k ); /* Q14 */ + } + ELSE + { + test(); + IF( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) ) + { + f_fx = 1489; /*Q15*/ + move16(); + inc_fx = 1489; /*Q15*/ + move16(); + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + hBWE_TD->lsp_prevfrm_fx[i] = f_fx; /*Q15*/ + move16(); + f_fx = add( f_fx, inc_fx ); + } + } + + IF( !st->bfi ) + { + IF( st->use_partial_copy ) + { + IF( NE_16( st->last_extl, SWB_TBE ) ) + { + hBWE_TD->GainFrame_prevfrm_fx = 0; + move32(); + f_fx = 1489 /*0.045454f Q15*/; + move16(); + inc_fx = 1489 /*0.045454f Q15*/; + move16(); + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + hBWE_TD->lsp_prevfrm_fx[i] = f_fx; /*Q15*/ + move16(); + f_fx = add( f_fx, inc_fx ); /*Q15*/ + } + } + Copy( hBWE_TD->lsp_prevfrm_fx, lsf_shb_fx, LPC_SHB_ORDER ); + set16_fx( GainShape_fx, RECIP_ROOT_EIGHT_FX, NUM_SHB_SUBFR ); + + IF( EQ_16( st->rf_frame_type, RF_NELP ) ) + { + /* Frame gain */ + + GainFrame_fx = L_mac( SHB_GAIN_QLOW_FX, st->rf_indx_tbeGainFr, SHB_GAIN_QDELTA_FX ); + L_tmp = Mult_32_16( GainFrame_fx, 27213 ); /*Q16*/ /* 3.321928 in Q13 */ + + frac = L_Extract_lc( L_tmp, &exp ); + L_tmp = Pow2( 30, frac ); + GainFrame_fx = L_shl( L_tmp, sub( exp, 12 ) ); /*Q18*/ + + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( st->core == ACELP_CORE ) && ( st->last_core == ACELP_CORE ) && !st->prev_use_partial_copy && EQ_16( st->prev_coder_type, UNVOICED ) && NE_32( GainFrame_fx, hBWE_TD->GainFrame_prevfrm_fx ) && NE_16( st->next_coder_type, GENERIC ) && EQ_16( st->last_extl, SWB_TBE ) ) + { + GainFrame_fx = L_add( Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 26214 /*0.8f in Q15*/ ), Mult_32_16( GainFrame_fx, 6553 /*0.2f in Q15*/ ) ); + } + } + ELSE + { + temp_fx = 0; + move16(); + /* Frame gain */ + SWITCH( st->rf_indx_tbeGainFr ) + { + case 0: + GainFrame_fx = 131072; /* 0.5f in Q18 */ + move32(); + if ( LE_32( hBWE_TD->GainFrame_prevfrm_fx, 327680l /*1.25 Q18*/ ) ) + { + temp_fx = 26214 /*0.8 Q15*/; + move16(); + } + BREAK; + case 1: + GainFrame_fx = 524288; /* 2.0f in Q18 */ + move32(); + test(); + if ( GT_32( hBWE_TD->GainFrame_prevfrm_fx, 327680l /*1.25 Q18*/ ) && LE_32( hBWE_TD->GainFrame_prevfrm_fx, 786432l /*3 Q18*/ ) ) + { + temp_fx = 26214 /*0.8 Q15*/; + move16(); + } + BREAK; + case 2: + GainFrame_fx = 1048576; /* 4.0f in Q18 */ + move32(); + test(); + if ( GT_32( hBWE_TD->GainFrame_prevfrm_fx, 786432l /*3 Q18*/ ) && LE_32( hBWE_TD->GainFrame_prevfrm_fx, 1572864l /*6 Q18*/ ) ) + { + temp_fx = 26214 /*0.8 Q15*/; + move16(); + } + BREAK; + case 3: + GainFrame_fx = 2097152; /* 8.0f in Q18 */ + move32(); + test(); + if ( GT_32( hBWE_TD->GainFrame_prevfrm_fx, 1572864l /*6 Q18*/ ) && LE_32( hBWE_TD->GainFrame_prevfrm_fx, 4194304l /*16Q18*/ ) ) + { + temp_fx = 26214 /*0.8 Q15*/; + move16(); + } + BREAK; + default: + fprintf( stderr, "RF SWB-TBE gain bits not supported." ); + } + + IF( EQ_16( st->last_extl, SWB_TBE ) ) + { + GainFrame_fx = L_add( Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, temp_fx ), Mult_32_16( GainFrame_fx, sub( 32767, temp_fx ) ) ); + /*Q18*/ + } + + IF( ( st->core == ACELP_CORE ) && ( st->last_core == ACELP_CORE ) ) + { + if ( !st->prev_use_partial_copy && EQ_16( st->last_coder_type, VOICED ) && EQ_16( st->rf_frame_type, RF_GENPRED ) && GT_32( GainFrame_fx, 2097152 /*8.0f in Q18*/ ) && LT_32( GainFrame_fx, 3059606 /*11.67f in Q18*/ ) ) + { + GainFrame_fx = Mult_32_16( GainFrame_fx, 9830 /*0.3f in Q15*/ ); // Q18 + } + } + } + } + ELSE + { + /* de-quantization */ + ivas_dequantizeSHBparams_fx_9_1( st, st->extl, st->extl_brate, lsf_shb_fx, GainShape_fx, &GainFrame_fx, &stemp, + &shb_ener_sf_32, shb_res_gshape_fx, &mixFactors_fx, &MSFlag ); + if ( hStereoICBWE != NULL ) + { + hStereoICBWE->MSFlag = MSFlag; + move16(); + } + } + } + ELSE + { + Copy( hBWE_TD->lsp_prevfrm_fx, lsf_shb_fx, LPC_SHB_ORDER ); + test(); + IF( EQ_16( st->codec_mode, MODE1 ) && ( st->element_mode == EVS_MONO ) ) + { + gradientGainShape( st, GainShape_fx, &GainFrame_fx ); + } + ELSE + { + FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) + { + FOR( j = 0; j < 4; j++ ) + { + GainShape_fx[i * 4 + j] = mult_r( st->cummulative_damping, st->GainShape_Delay[4 + i] ); + move16(); + } + } + IF( GT_16( tilt_swb_fec_fx, ( 8 << 11 ) ) ) /* tilt_swb_fec_fx in Q11 */ + { + IF( EQ_16( st->nbLostCmpt, 1 ) ) + { + GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 19661 /*0.6f Q15*/ ); + } + ELSE IF( EQ_16( st->nbLostCmpt, 2 ) ) + { + GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 11469 /*0.35f Q15*/ ); + } + ELSE + { + GainFrame_fx = Mult_32_16( hBWE_TD->GainFrame_prevfrm_fx, 6554 /*0.2f Q15*/ ); + } + GainFrame_fx = Mult_32_16( GainFrame_fx, st->cummulative_damping ); + } + ELSE + { + GainFrame_fx = hBWE_TD->GainFrame_prevfrm_fx; + move32(); /* gain locking */ + } + } + + IF( GE_32( st->extl_brate, SWB_TBE_2k8 ) ) + { + test(); + IF( EQ_16( st->codec_mode, MODE1 ) && ( st->element_mode == EVS_MONO ) ) + { + L_tmp = L_mult( extract_l( hBWE_TD->prev2_shb_ener_sf_fx ), extract_l( hBWE_TD->prev3_shb_ener_sf_fx ) ); /*Q1*/ + tmp = round_fx( root_a_fx( L_tmp, 1, &exp ) ); /* Q = 15-exp */ + tmp1 = extract_l( hBWE_TD->prev1_shb_ener_sf_fx ); /*Q0*/ + i = sub( norm_s( tmp1 ), 1 ); + tmp1 = shl( tmp1, i ); /* Qi */ + IF( tmp == 0 ) + { + tmp = 32767 /*1.0f Q15*/; + move16(); /*Q15*/ + } + ELSE + { + scale_fx = div_s( tmp1, tmp ); /* Q15 - Q(15-exp) + Qi = Qexp+i */ + scale_fx = s_max( scale_fx, 0 ); + tmp = shl_sat( scale_fx, sub( sub( 15, exp ), i ) ); /*Q15*/ + } + scale_fx = mult_r( hBWE_TD->prev_res_shb_gshape_fx, tmp ); /* Q14 */ + test(); + IF( GT_32( L_shr( hBWE_TD->prev2_shb_ener_sf_fx, 1 ), hBWE_TD->prev1_shb_ener_sf_fx ) || + GT_32( L_shr( hBWE_TD->prev3_shb_ener_sf_fx, 1 ), hBWE_TD->prev2_shb_ener_sf_fx ) ) + { + shb_ener_sf_32 = Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, scale_fx ); + + if ( GT_16( st->nbLostCmpt, 1 ) ) + { + shb_ener_sf_32 = L_shr( shb_ener_sf_32, 1 ); + } + } + ELSE + { + L_tmp = L_mult( scale_fx, scale_fx ); /* Q29 */ + shb_ener_sf_32 = L_shl( Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, round_fx( L_tmp ) ), 2 ); + } + } + ELSE + { + test(); + IF( GT_32( L_shr( hBWE_TD->prev2_shb_ener_sf_fx, 1 ), hBWE_TD->prev1_shb_ener_sf_fx ) || + GT_32( L_shr( hBWE_TD->prev3_shb_ener_sf_fx, 1 ), hBWE_TD->prev2_shb_ener_sf_fx ) ) + { + shb_ener_sf_32 = L_shr( Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, st->cummulative_damping ), 1 ); + } + ELSE + { + shb_ener_sf_32 = Mult_32_16( hBWE_TD->prev1_shb_ener_sf_fx, st->cummulative_damping ); + } + } + } + + shb_ener_sf_32 = L_max( shb_ener_sf_32, 1l /*1.0f Q0*/ ); + mixFactors_fx = hBWE_TD->prev_mixFactors_fx; + move16(); + + IF( EQ_16( st->codec_mode, MODE1 ) ) + { + set16_fx( shb_res_gshape_fx, 3277 /*0.2f Q14*/, 5 ); /* Q14 */ + } + ELSE + { + set16_fx( shb_res_gshape_fx, 16384 /*1.0f Q14*/, 5 ); /* Q14 */ + } + } + } + + /* get the gainshape delay */ + Copy( &st->GainShape_Delay[4], &st->GainShape_Delay[0], NUM_SHB_SUBFR / 4 ); + FOR( i = 0; i < NUM_SHB_SUBFR / 4; i++ ) + { + st->GainShape_Delay[i + 4] = GainShape_fx[i * 4]; /*Q15*/ + move16(); + } + + L_tmp = L_mult( voice_factors_fx[0], 8192 ); + L_tmp = L_mac( L_tmp, voice_factors_fx[1], 8192 ); + L_tmp = L_mac( L_tmp, voice_factors_fx[2], 8192 ); + mean_vf = mac_r( L_tmp, voice_factors_fx[3], 8192 ); + + Copy( voice_factors_fx, vf_modified_fx, NB_SUBFR16k ); + + test(); + IF( EQ_16( st->coder_type, VOICED ) || GT_16( mean_vf, 13107 /*0.4f Q15*/ ) ) + { + FOR( i = 1; i < NB_SUBFR; i++ ) + { + L_tmp = L_mult( voice_factors_fx[i], 26214 /*0.8f Q15*/ ); + vf_modified_fx[i] = mac_r( L_tmp, voice_factors_fx[i - 1], 6554 /*0.2f Q15*/ ); + move16(); + } + + IF( st->L_frame != L_FRAME ) + { + L_tmp = L_mult( voice_factors_fx[4], 26214 /*0.8f Q15*/ ); + vf_modified_fx[4] = mac_r( L_tmp, voice_factors_fx[3], 6554 /*0.2f Q15*/ ); + move16(); + } + } + + test(); + IF( st->use_partial_copy && st->nelp_mode_dec ) + { + set16_fx( vf_modified_fx, 0, NB_SUBFR16k ); + } + + /* SHB LSF from current frame; and convert to LSP for interpolation */ + E_LPC_lsf_lsp_conversion( lsf_shb_fx, lsp_shb_2_fx, LPC_SHB_ORDER ); + + test(); + IF( EQ_16( st->last_extl, SWB_TBE ) || EQ_16( st->last_extl, FB_TBE ) ) + { + /* SHB LSP values from prev. frame for interpolation */ + Copy( hBWE_TD->swb_lsp_prev_interp_fx, lsp_shb_1_fx, LPC_SHB_ORDER ); + } + ELSE + { + /* Use current frame's LSPs; in effect no interpolation */ + Copy( lsp_shb_2_fx, lsp_shb_1_fx, LPC_SHB_ORDER ); + } + + test(); + test(); + test(); + IF( ( st->bws_cnt == 0 ) && ( st->bws_cnt1 == 0 ) && ( st->prev_use_partial_copy == 0 ) && ( st->use_partial_copy == 0 ) ) + { + lsf_diff_fx[0] = 16384; + move16(); /*Q15*/ + lsf_diff_fx[LPC_SHB_ORDER - 1] = 16384; + move16(); /*Q15*/ + FOR( i = 1; i < LPC_SHB_ORDER - 1; i++ ) + { + lsf_diff_fx[i] = sub( lsf_shb_fx[i], lsf_shb_fx[i - 1] ); + move16(); + } + + a2rc_fx( hBWE_TD->cur_sub_Aq_fx + 1, refl_fx, M ); + tmp = add( 16384, shr( refl_fx[0], 1 ) ); /*Q14*/ + tmp1 = mult( 27425, tmp ); + tmp1 = mult( tmp1, tmp ); /*Q10*/ + tmp2 = shr( mult( 31715, tmp ), 2 ); /*Q10*/ + tilt_para_fx = add( sub( tmp1, tmp2 ), 1335 ); /*Q10*/ + + test(); + IF( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) ) + { + FOR( i = 1; i < LPC_SHB_ORDER - 1; i++ ) + { + hBWE_TD->prev_lsf_diff_fx[i - 1] = shr( lsf_diff_fx[i], 1 ); + move16(); + } + } + + IF( LE_32( st->extl_brate, FB_TBE_1k8 ) ) + { + test(); + test(); + test(); + test(); + test(); + IF( !( GT_16( hBWE_TD->prev_tilt_para_fx, 5120 ) && ( EQ_16( st->coder_type, TRANSITION ) || LT_16( tilt_para_fx, 1024 ) ) ) && + !( ( ( LT_16( hBWE_TD->prev_tilt_para_fx, 3072 ) && GE_16( st->prev_coder_type, VOICED ) ) ) && GT_16( tilt_para_fx, 5120 ) ) ) + { + FOR( i = 1; i < LPC_SHB_ORDER - 1; i++ ) + { + IF( LT_16( lsf_diff_fx[i], hBWE_TD->prev_lsf_diff_fx[i - 1] ) ) + { + tmp = mult( 26214, lsf_diff_fx[i] ); + + test(); + IF( ( hBWE_TD->prev_lsf_diff_fx[i - 1] <= 0 ) || ( tmp < 0 ) ) /* safety check in case of bit errors */ + { + st->BER_detect = 1; + move16(); + tmp = 0; + move16(); + } + ELSE + { + tmp = div_s( tmp, hBWE_TD->prev_lsf_diff_fx[i - 1] ); + } + + tmp = s_max( tmp, 16384 ); + w_fx[i] = s_min( tmp, 32767 ); + move16(); + } + ELSE + { + tmp = mult( 26214, hBWE_TD->prev_lsf_diff_fx[i - 1] ); + + test(); + IF( ( lsf_diff_fx[i] <= 0 ) || ( tmp < 0 ) ) /* safety check in case of bit errors */ + { + st->BER_detect = 1; + move16(); + tmp = 0; + move16(); + } + ELSE + { + tmp = div_s( tmp, lsf_diff_fx[i] ); + } + + tmp = s_max( tmp, 16384 ); + w_fx[i] = s_min( tmp, 32767 ); + move16(); + } + } + w_fx[0] = w_fx[1]; + move16(); + w_fx[LPC_SHB_ORDER - 1] = w_fx[LPC_SHB_ORDER - 2]; + move16(); + + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + tmp1 = mult( lsp_shb_1_fx[i], sub( 32767, w_fx[i] ) ); + tmp2 = mult( lsp_shb_2_fx[i], w_fx[i] ); + lsp_temp_fx[i] = add( tmp1, tmp2 ); + move16(); + } + } + ELSE + { + Copy( lsp_shb_2_fx, lsp_temp_fx, LPC_SHB_ORDER ); + } + + /* convert from lsp to lsf */ + lsp2lsf_fx( lsp_temp_fx, lsf_shb_fx, LPC_SHB_ORDER, 1 ); + } + + Copy( lsf_diff_fx + 1, hBWE_TD->prev_lsf_diff_fx, LPC_SHB_ORDER - 2 ); + hBWE_TD->prev_tilt_para_fx = tilt_para_fx; + move16(); + } + ELSE + { + Copy( lsp_shb_2_fx, lsp_temp_fx, LPC_SHB_ORDER ); + } + + IF( GE_32( st->extl_brate, SWB_TBE_2k8 ) ) + { + /* SHB LSP interpolation */ + ptr_lsp_interp_coef_fx = interpol_frac_shb; /*Q15*/ + FOR( j = 0; j < 4; j++ ) + { + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + L_tmp = L_mult( lsp_shb_1_fx[i], ( *ptr_lsp_interp_coef_fx ) ); + lsp_temp_fx[i] = mac_r( L_tmp, lsp_shb_2_fx[i], ( *( ptr_lsp_interp_coef_fx + 1 ) ) ); + move16(); + } + ptr_lsp_interp_coef_fx += 2; + + tmp = i_mult( j, ( LPC_SHB_ORDER + 1 ) ); + /* convert LSPs to LP coefficients */ + E_LPC_f_lsp_a_conversion( lsp_temp_fx, lpc_shb_sf_fx + tmp, LPC_SHB_ORDER ); +#ifndef FIX_1100_REMOVE_LPC_RESCALING + /* Bring the LPCs to Q12 */ + Copy_Scale_sig( lpc_shb_sf_fx + tmp, lpc_shb_sf_fx + tmp, LPC_SHB_ORDER + 1, sub( norm_s( lpc_shb_sf_fx[tmp] ), 2 ) ); + lpc_shb_sf_fx[i_mult( j, ( LPC_SHB_ORDER + 1 ) )] = ONE_IN_Q12; // recheck this + move16(); +#endif + } + } + + /* Save the SWB LSP values from current frame for interpolation */ + Copy( lsp_shb_2_fx, hBWE_TD->swb_lsp_prev_interp_fx, LPC_SHB_ORDER ); + + /* save the shb_ener and mixFactor values */ + hBWE_TD->prev3_shb_ener_sf_fx = hBWE_TD->prev2_shb_ener_sf_fx; + move32(); + hBWE_TD->prev2_shb_ener_sf_fx = hBWE_TD->prev1_shb_ener_sf_fx; + move32(); + hBWE_TD->prev1_shb_ener_sf_fx = shb_ener_sf_32; + move32(); + hBWE_TD->prev_res_shb_gshape_fx = shb_res_gshape_fx[4]; + move16(); + hBWE_TD->prev_mixFactors_fx = mixFactors_fx; + move16(); + + /* SWB CNG/DTX - update memories */ + IF( st->hTdCngDec != NULL ) + { + Copy( st->hTdCngDec->lsp_shb_prev_fx, st->hTdCngDec->lsp_shb_prev_prev_fx, LPC_SHB_ORDER ); + Copy( lsf_shb_fx, st->hTdCngDec->lsp_shb_prev_fx, LPC_SHB_ORDER ); + } + + /* convert LSPs back into LP coeffs */ + E_LPC_f_lsp_a_conversion( lsp_temp_fx, lpc_shb_fx, LPC_SHB_ORDER ); + Copy_Scale_sig( lpc_shb_fx, lpc_shb_fx, LPC_SHB_ORDER + 1, sub( norm_s( lpc_shb_fx[0] ), 2 ) ); /* Q12 */ + lpc_shb_fx[0] = ONE_IN_Q12; + move16(); + + test(); + IF( EQ_32( st->extl_brate, SWB_TBE_1k10 ) || EQ_32( st->extl_brate, SWB_TBE_1k75 ) ) + { + Word32 vind_temp = Mpy_32_32( L_shl( L_add( L_deposit_l( mixFactors_fx ), 1 ), 15 ), ( ( ( 1 << NUM_BITS_SHB_VF ) - 1 ) << 16 ) ); // check addition of 1 + vind = extract_l( L_shr( vind_temp, 15 ) ); /* 3 for mpy by 8.0f, -15 to bring it to Q0 */ /*mixFactors*7*/ + /* i: mixFactors_fx in Q15 */ + /* o: vind in Q0 */ + } + ELSE + { + vind = shl( mixFactors_fx, 3 - 15 ); /* 3 for mpy by 8.0f, -15 to bring it to Q0 */ /*mixFactors*8*/ + /* i: mixFactors_fx in Q15 */ + /* o: vind in Q0 */ + } + + /* Determine formant PF strength */ + formant_fac_fx = swb_formant_fac_fx( lpc_shb_fx[1], &hBWE_TD->tilt_mem_fx ); + /* i:lpc_shb_fx Q12, o:formant_fac_fx Q15 */ + IF( GT_32( st->total_brate, ACELP_32k ) ) + { + FOR( j = 0; j < 4; j++ ) + { + Copy( lpc_shb_fx, &lpc_shb_sf_fx[i_mult( j, ( LPC_SHB_ORDER + 1 ) )], LPC_SHB_ORDER + 1 ); + } + } + + /* From low band excitation, generate highband excitation */ + + /* -------- start of memory rescaling -------- */ + /* ----- calculate optimum Q_bwe_exc and rescale memories accordingly ----- */ + Lmax = 0; + move32(); + FOR( cnt = 0; cnt < L_FRAME32k; cnt++ ) + { + Lmax = L_max( Lmax, L_abs( bwe_exc_extended_fx[cnt] ) ); + } + Q_bwe_exc = norm_l( Lmax ); + if ( Lmax == 0 ) + { + Q_bwe_exc = 31; + move16(); + } + Q_bwe_exc = add( Q_bwe_exc, add( Q_exc, Q_exc ) ); + find_max_mem_dec( st, &n_mem, &n_mem2, &n_mem3 ); /* for >=24.4, use n_mem2 lpc_syn, shb_20sample, and mem_stp_swb_fx memory */ + + tmp = add( st->prev_Q_bwe_exc, n_mem ); + if ( GT_16( Q_bwe_exc, tmp ) ) + { + Q_bwe_exc = tmp; + move16(); + } + + /* rescale the memories if Q_bwe_exc is different from previous frame */ + sc = sub( Q_bwe_exc, st->prev_Q_bwe_exc ); + IF( sc != 0 ) + { + rescale_genSHB_mem_dec_ivas( st, sc ); + } + + /* rescale the bwe_exc_extended and bring it to 16-bit single precision with dynamic norm */ + sc = sub( Q_bwe_exc, add( Q_exc, Q_exc ) ); + + FOR( cnt = 0; cnt < L_FRAME32k; cnt++ ) + { + bwe_exc_extended_16[cnt] = round_fx_sat( L_shl_sat( bwe_exc_extended_fx[cnt], sc ) ); + move16(); + } + + /* state_syn_shbexc_fx is kept at (st_fx->prev_Q_bwe_syn) for 24.4/32kbps or is kept at Q_bwe_exc for 13.2/16.4kbps */ + + /* save the previous Q factor (32-bit) of the buffer */ + st->prev_Q_bwe_exc = Q_bwe_exc; + move16(); + + Q_bwe_exc = sub( Q_bwe_exc, 16 ); /* Q_bwe_exc reflecting the single precision dynamic norm-ed buffers from here */ + + /* -------- end of rescaling memories -------- */ + + Q_bwe_exc_fb = st->prev_Q_bwe_exc_fb; + move16(); + + Q_shb = 0; + move16(); + + Copy( hBWE_TD->state_syn_shbexc_fx, shaped_shb_excitation_fx, L_SHB_LAHEAD ); + GenShapedSHBExcitation_ivas_dec_fx( shaped_shb_excitation_fx + L_SHB_LAHEAD, lpc_shb_fx, White_exc16k_fx, + hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, + st->coder_type, bwe_exc_extended_16, hBWE_TD->bwe_seed, vf_modified_fx, st->extl, + &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), lpc_shb_sf_fx, shb_ener_sf_32, + shb_res_gshape_fx, shb_res_dummy_fx, &vind, formant_fac_fx, hBWE_TD->fb_state_lpc_syn_fx, + &( hBWE_TD->fb_tbe_demph_fx ), &Q_bwe_exc, &Q_bwe_exc_fb, Q_shb, n_mem2, st->prev_Q_bwe_syn, st->total_brate, st->prev_bfi, + st->element_mode, st->flag_ACELP16k, nlExc16k_fx, mixExc16k_fx, st->extl_brate, MSFlag, + NULL, &( hBWE_TD->prev_pow_exc16kWhtnd_fx32 ), &( hBWE_TD->prev_mix_factor_fx ), NULL, NULL ); + + *Q_white_exc = Q_bwe_exc_fb; + move16(); + IF( EQ_16( st->extl, FB_TBE ) ) + { + st->prev_Q_bwe_exc_fb = Q_bwe_exc_fb; + move16(); + } + ELSE + { + /*Indirectly a memory reset of FB memories for next frame such that rescaling of memories would lead to 0 due to such high prev. Q value. + 51 because of 31 + 20(shift of Q_bwe_exc_fb before de-emphasis)*/ + st->prev_Q_bwe_exc_fb = 51; + move16(); + } + + /* rescale the TBE post proc memory */ + FOR( i = 0; i < LPC_SHB_ORDER; i++ ) + { + hBWE_TD->mem_stp_swb_fx[i] = shl_sat( hBWE_TD->mem_stp_swb_fx[i], sub( Q_bwe_exc, st->prev_Q_bwe_syn ) ); + move16(); + } + /* fill-in missing SHB excitation */ + test(); + test(); + IF( ( EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) ) && LE_32( st->last_core_brate, SID_2k40 ) ) + { + Copy( shaped_shb_excitation_fx + L_SHB_LAHEAD, shaped_shb_excitation_fx, L_SHB_LAHEAD ); + } + + IF( hStereoICBWE != NULL ) + { + Copy( shaped_shb_excitation_fx + L_SHB_LAHEAD, hStereoICBWE->shbSynthRef_fx, L_FRAME16k ); + } + + test(); + IF( NE_32( st->extl_brate, SWB_TBE_1k10 ) && NE_32( st->extl_brate, SWB_TBE_1k75 ) ) + { + FOR( i = 0; i < L_FRAME16k; i += L_SUBFR16k ) + { + /* TD BWE post-processing */ + PostShortTerm_ivas_dec_fx( &shaped_shb_excitation_fx[L_SHB_LAHEAD + i], lpc_shb_fx, &shaped_shb_excitationTemp_fx[i], hBWE_TD->mem_stp_swb_fx, + hBWE_TD->ptr_mem_stp_swb_fx, &( hBWE_TD->gain_prec_swb_fx ), hBWE_TD->mem_zero_swb_fx, formant_fac_fx ); + } + + Copy( shaped_shb_excitationTemp_fx, &shaped_shb_excitation_fx[L_SHB_LAHEAD], L_FRAME16k ); /* Q_bwe_exc */ + + tmp = sub( shl( Q_bwe_exc, 1 ), 31 + 16 ); + prev_pow_fx = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /* 2*(Q_bwe_exc) */ + curr_pow_fx = L_shl_sat( 1407374848l /*0.00001f Q47*/, tmp ); /* 2*(Q_bwe_exc) */ + FOR( i = 0; i < L_SHB_LAHEAD + 10; i++ ) + { + prev_pow_fx = L_mac0_sat( prev_pow_fx, shaped_shb_excitation_fx[i], shaped_shb_excitation_fx[i] ); /*2*Q_bwe_exc*/ + curr_pow_fx = L_mac0_sat( curr_pow_fx, shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10], shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10] ); /* 2*Q_bwe_exc */ + } + + if ( GT_16( voice_factors_fx[0], 24576 /*0.75f Q15*/ ) ) + { + curr_pow_fx = L_shr( curr_pow_fx, 2 ); /* Q(2*Q_bwe_exc) */ + } + + Lscale = root_a_over_b_fx( curr_pow_fx, + shl( Q_bwe_exc, 1 ), + prev_pow_fx, + shl( Q_bwe_exc, 1 ), + &exp ); + + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q_bwe_exc + (31-exp) - 15 */ + shaped_shb_excitation_fx[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc */ + move16(); + } + IF( exp < 0 ) + { + Lscale = L_shl( Lscale, exp ); + exp = 0; + move16(); + } + FOR( ; i < L_SHB_LAHEAD + 10; i++ ) + { + temp_fx = i_mult_sat( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ + L_tmp1 = Mult_32_16( L_shl_sat( 1, sub( 31, exp ) ), temp_fx ); /* Q31-exp */ + temp_fx = sub( 32767 /*1.0f Q15*/, temp_fx ); + Lscale = L_add( Mult_32_16( Lscale, temp_fx ), L_tmp1 ); + L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q_bwe_exc + (31-exp) - 15 */ + shaped_shb_excitation_fx[i] = round_fx_sat( L_shl_sat( L_tmp, exp ) ); /* Q_bwe_exc */ + move16(); + } + } + ELSE + { + /* reset the PF memories if the PF is not running */ + set16_fx( hBWE_TD->mem_stp_swb_fx, 0, LPC_SHB_ORDER ); + hBWE_TD->gain_prec_swb_fx = ONE_IN_Q14; + move16(); + set16_fx( hBWE_TD->mem_zero_swb_fx, 0, LPC_SHB_ORDER ); + } + + /* Update SHB excitation */ + Copy( shaped_shb_excitation_fx + L_FRAME16k, hBWE_TD->state_syn_shbexc_fx, L_SHB_LAHEAD ); /* Q_bwe_exc */ + l_subframe = L_FRAME16k / NUM_SHB_SUBGAINS; + move16(); + L_ener = EPSILON_FX_SMALL; + move32(); + + FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + L_tmp = 0; + move32(); + ener_tmp_fx[i] = EPSILON_FX_SMALL; + move32(); + + Word64 tmp64 = 0; + move64(); + FOR( j = 0; j < l_subframe; j++ ) + { + tmp64 = W_mac0_16_16( tmp64, shaped_shb_excitation_fx[add( i_mult( i, l_subframe ), j )], shaped_shb_excitation_fx[add( i_mult( i, l_subframe ), j )] ); /* 2*Q_bwe_exc */ + } + L_tmp = W_sat_l( tmp64 ); + + L_tmp = Mult_32_16( L_tmp, 410 /*0.0125 Q15*/ ); /* 2*Q_bwe_exc: ener_tmp_fx in (2*Q_bwe_exc) */ + IF( L_tmp != 0 ) + { + exp = norm_l( L_tmp ); + tmp = extract_h( L_shl( L_tmp, exp ) ); + exp = sub( exp, sub( 30, i_mult( 2, Q_bwe_exc ) ) ); + + tmp = div_s( 16384, tmp ); + L_tmp = L_deposit_h( tmp ); + L_tmp = Isqrt_lc( L_tmp, &exp ); + ener_tmp_fx[i] = L_shl_sat( L_tmp, sub( add( exp, shl( Q_bwe_exc, 1 ) ), 31 ) ); /*2 * Q_bwe_exc: Q31 -exp +exp +2 * Q_bwe_exc -31 */ + move32(); + L_ener = L_add_sat( L_ener, L_shr( ener_tmp_fx[i], 2 ) ); /* 2*Q_bwe_exc */ + } + } + ener_fx = s_max( 1, round_fx_sat( L_shl_sat( L_ener, sub( 18, shl( Q_bwe_exc, 1 ) ) ) ) ); /* Q2: 2*Q_bwe_exc+18-2*Q_bwe_exc-16 */ + /* WB/SWB bandwidth switching */ + IF( st->bws_cnt > 0 ) + { + IF( is_fractive == 0 ) + { + IF( GT_16( st->tilt_wb_fx, 2048 ) ) /*assuming st->tilt_wb_fx in Q11*/ + { + st->tilt_wb_fx = 2048; + move16(); + } + ELSE IF( LT_16( st->tilt_wb_fx, 1024 ) ) + { + st->tilt_wb_fx = 1024; + move16(); + } + test(); + if ( EQ_16( st->prev_fractive, 1 ) && GT_16( st->tilt_wb_fx, 1024 ) ) + { + st->tilt_wb_fx = 1024; + move16(); + } + } + ELSE + { + IF( GT_16( st->tilt_wb_fx, 8192 ) ) + { + IF( st->prev_fractive == 0 ) + { + st->tilt_wb_fx = 8192; + move16(); + } + ELSE + { + st->tilt_wb_fx = 16384; + move16(); + } + } + ELSE + { + st->tilt_wb_fx = shl( st->tilt_wb_fx, 2 ); + move16(); + } + } + + IF( ener_fx != 0 ) + { + L_tmp = L_shl( L_mult0( ener_fx, st->tilt_wb_fx ), sub( st->Q_syn2, 13 ) ); /* 2+11 +st->Q_syn2 -13 = st->Q_syn2*/ + exp_ener = norm_s( ener_fx ); + tmp = shl( ener_fx, exp_ener ); /*Q(2+exp)*/ + inv_ener = shr( div_s( 16384, tmp ), 1 ); /*Q(15+14-2-exp-1) = 26 - exp*/ + + test(); + IF( GT_32( L_tmp, st->enerLH_fx ) ) /*st->Q_syn2*/ + { + st->tilt_wb_fx = extract_h( L_shr_sat( Mult_32_16( st->enerLH_fx, inv_ener ), sub( sub( st->Q_syn2, exp_ener ), 16 ) ) ); /*Q11*/ + move16(); + /*st->Q_syn2 -1 + 26- exp_ener -15 -(st->Q_syn2 -exp_ener -16 ) -16 +1 -1 = (11) *0.5*/ + } + ELSE IF( LT_32( L_tmp, Mult_32_16( st->enerLH_fx, 1638 ) ) && EQ_16( is_fractive, 1 ) ) + { + st->tilt_wb_fx = extract_h( L_shr_sat( Mult_32_16( st->enerLH_fx, inv_ener ), sub( sub( st->Q_syn2, exp_ener ), 15 ) ) ); /*Q11*/ + move16(); + /*st->Q_syn2 -1 + 26- exp_ener -15 -(st->Q_syn2 -exp_ener -15 ) -16 = (11) 0.25*/ + } + L_tmp = L_mult0( st->prev_ener_shb_fx, inv_ener ); /*Q(1+15+14-3-exp_ener) = 27 -exp_ener*/ + GainFrame_prevfrm_fx = L_shr( L_tmp, sub( 9, exp_ener ) ); /*27 -exp_ener -(9-exp_ener )= Q18*/ + } + ELSE + { + GainFrame_prevfrm_fx = 0; + move32(); + } + + IF( EQ_16( is_fractive, 1 ) ) + { + GainFrame_fx = L_shl( L_deposit_l( st->tilt_wb_fx ), 10 ); + } + ELSE + { + GainFrame_fx = L_shl( L_deposit_l( st->tilt_wb_fx ), 8 ); + } + + test(); + IF( EQ_16( ( is_fractive & st->prev_fractive ), 1 ) && GT_32( GainFrame_fx, GainFrame_prevfrm_fx ) ) + { + GainFrame_fx = L_add( Mult_32_16( GainFrame_prevfrm_fx, 26214 ), Mult_32_16( GainFrame_fx, 6554 ) ); /* 18 +15 -15 = 18*/ + } + ELSE + { + test(); + test(); + test(); + test(); + IF( ( LT_32( L_shr( st->prev_enerLH_fx, 1 ), st->enerLH_fx ) && GT_32( st->prev_enerLH_fx, L_shr( st->enerLH_fx, 1 ) ) ) && ( LT_32( L_shr( st->prev_enerLL_fx, 1 ), st->enerLL_fx ) && GT_32( st->prev_enerLL_fx, L_shr( st->enerLL_fx, 1 ) ) ) && ( s_xor( is_fractive, st->prev_fractive ) == 0 ) ) + { + GainFrame_fx = L_add( L_shr( GainFrame_fx, 1 ), L_shr( GainFrame_prevfrm_fx, 1 ) ); + } + ELSE + { + test(); + IF( ( is_fractive == 0 ) && EQ_16( st->prev_fractive, 1 ) ) + { + L_tmp1 = L_shl( Mult_32_16( GainFrame_fx, 3277 ), 13 ); /* 31 */ + L_tmp = L_sub( 2147483647, L_tmp1 ); /* 31 */ + GainFrame_fx = L_add( Mult_32_32( GainFrame_fx, L_tmp ), Mult_32_32( GainFrame_prevfrm_fx, L_tmp1 ) ); /* 18 */ + } + ELSE + { + GainFrame_fx = L_add( L_shr( GainFrame_fx, 1 ), L_shr( L_min( GainFrame_prevfrm_fx, GainFrame_fx ), 1 ) ); /* 18 */ + } + } + } + + GainFrame_fx = Mult_32_16( GainFrame_fx, i_mult( sub( N_WS2N_FRAMES, st->bws_cnt ), 819 ) ); /*Q18*/ + } + ELSE + { + IF( st->bws_cnt1 > 0 ) + { + GainFrame_fx = Mult_32_16( GainFrame_fx, i_mult( st->bws_cnt1, 819 ) ); /*Q18*/ + } + IF( GE_16( st->nbLostCmpt, 1 ) ) + { + ener_fx = s_max( 1, ener_fx ); + exp_ener = norm_s( ener_fx ); + tmp = shl( ener_fx, exp_ener ); /*Q(2+exp)*/ + inv_ener = div_s( 16384, tmp ); /*Q(15+14-2-exp)*/ + prev_ener_ratio_fx = L_shr( L_mult0( st->prev_ener_shb_fx, inv_ener ), add( sub( 9, exp_ener ), 1 ) ); /*Q: 1+27-exp-9+exp-1 = 18 */ + } + + IF( EQ_16( st->nbLostCmpt, 1 ) ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( st->clas_dec != UNVOICED_CLAS ) && NE_16( st->clas_dec, UNVOICED_TRANSITION ) && LT_16( hBWE_TD->tilt_swb_fec_fx, 16384 ) && + ( ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) && LT_32( L_shr( st->enerLL_fx, 1 ), st->prev_enerLL_fx ) ) || ( GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) && LT_32( L_shr( st->enerLH_fx, 1 ), st->prev_enerLH_fx ) ) ) ) + { + IF( GT_32( L_shr( prev_ener_ratio_fx, 2 ), GainFrame_fx ) ) /*18*/ + { + GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 13107 ), Mult_32_16( GainFrame_fx, 19661 ) ); /*18*/ + } + ELSE IF( GT_32( L_shr( prev_ener_ratio_fx, 1 ), GainFrame_fx ) ) + { + GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 26214 ), Mult_32_16( GainFrame_fx, 6554 ) ); + } + ELSE + { + GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 6554 ), Mult_32_16( GainFrame_fx, 26214 ) ); + } + + test(); + IF( GT_16( tilt_swb_fec_fx, hBWE_TD->tilt_swb_fec_fx ) && ( hBWE_TD->tilt_swb_fec_fx > 0 ) ) + { + exp = norm_s( hBWE_TD->tilt_swb_fec_fx ); + tmp = shl( hBWE_TD->tilt_swb_fec_fx, exp ); /*Q(11+exp)*/ + tmp = div_s( 16384, tmp ); /*Q(15+14-11-exp)*/ + tmp = extract_h( L_shl( L_mult0( tmp, st->tilt_wb_fx ), sub( exp, 1 ) ) ); /*18 -exp +11 + exp -1 -16 =12; */ + GainFrame_fx = L_shl( Mult_32_16( GainFrame_fx, s_min( tmp, 20480 ) ), 3 ); /*Q18 = 18 +12 -15 +3 */ + } + } + ELSE IF( ( ( st->clas_dec != UNVOICED_CLAS ) || GT_16( hBWE_TD->tilt_swb_fec_fx, 4096 ) ) && GT_32( L_shr( prev_ener_ratio_fx, 2 ), GainFrame_fx ) && + ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) || GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) ) ) + { + GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 6554 ), Mult_32_16( GainFrame_fx, 26214 ) ); + } + } + ELSE IF( GT_16( st->nbLostCmpt, 1 ) ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( GT_32( L_shr( prev_ener_ratio_fx, 2 ), GainFrame_fx ) && ( ( EQ_16( st->codec_mode, MODE1 ) && GT_32( st->enerLL_fx, st->prev_enerLL_fx ) && GT_32( st->enerLH_fx, st->prev_enerLH_fx ) ) || EQ_16( st->codec_mode, MODE2 ) ) ) + { + test(); + IF( GT_16( tilt_swb_fec_fx, 20480 /*10.0f in Q11*/ ) && GT_16( hBWE_TD->tilt_swb_fec_fx, 20480 /*10.0f in Q11*/ ) ) + { + GainFrame_fx = L_min( L_add( Mult_32_16( prev_ener_ratio_fx, 26214 /*0.8f in Q15*/ ), Mult_32_16( GainFrame_fx, 6554 /*0.2f in Q15*/ ) ), L_shl( Mult_32_16( GainFrame_fx, 16384 /*4.0f in Q12*/ ), 3 ) ); /*Q18*/ + } + ELSE + { + GainFrame_fx = L_min( L_add( Mult_32_16( prev_ener_ratio_fx, 16384 ), Mult_32_16( GainFrame_fx, 16384 ) ), L_shl( Mult_32_16( GainFrame_fx, 16384 ), 3 ) ); /*Q18*/ + } + } + ELSE IF( GT_32( prev_ener_ratio_fx, GainFrame_fx ) && ( ( EQ_16( st->codec_mode, MODE1 ) && GT_32( st->enerLL_fx, st->prev_enerLL_fx ) && GT_32( st->enerLH_fx, st->prev_enerLH_fx ) ) || EQ_16( st->codec_mode, MODE2 ) ) ) + { + test(); + IF( GT_16( tilt_swb_fec_fx, 20480 ) && GT_16( hBWE_TD->tilt_swb_fec_fx, 20480 ) ) + { + GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 16384 /*0.5f in Q15*/ ), Mult_32_16( GainFrame_fx, 16384 /*0.5f in Q15*/ ) ); /* Q18 */ + } + ELSE + { + GainFrame_fx = L_add( Mult_32_16( prev_ener_ratio_fx, 6554 /*0.2f in Q15*/ ), Mult_32_16( GainFrame_fx, 26214 /*0.8f in Q15*/ ) ); /* Q18 */ + } + } + } + } + + st->prev_fractive = is_fractive; + move16(); + + /* Adjust the subframe and frame gain of the synthesized shb signal */ + /* Scale the shaped excitation */ + IF( EQ_16( st->L_frame, L_FRAME ) ) + { + L_tmp = L_mult( pitch_buf_fx[0], 8192 ); + FOR( i = 1; i < NB_SUBFR; i++ ) + { + L_tmp = L_mac( L_tmp, pitch_buf_fx[i], 8192 ); /* pitch_buf in Q6 x 0.25 in Q15 */ + } + pitch_fx = round_fx( L_tmp ); /* Q6 */ + } + ELSE + { + L_tmp = L_mult( pitch_buf_fx[0], 6554 ); + FOR( i = 1; i < NB_SUBFR16k; i++ ) + { + L_tmp = L_mac( L_tmp, pitch_buf_fx[i], 6554 ); /* pitch_buf in Q6 x 0.2 in Q15 */ + } + pitch_fx = round_fx( L_tmp ); /* Q6 */ + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( ( GE_32( st->extl_brate, SWB_TBE_2k8 ) && EQ_16( st->prev_coder_type, st->coder_type ) && NE_16( st->coder_type, UNVOICED ) ) || ( LT_32( st->extl_brate, SWB_TBE_2k8 ) && ( EQ_16( st->prev_coder_type, st->coder_type ) || ( EQ_16( st->prev_coder_type, VOICED ) && EQ_16( st->coder_type, GENERIC ) ) || ( EQ_16( st->prev_coder_type, GENERIC ) && EQ_16( st->coder_type, VOICED ) ) ) ) ) && GT_16( pitch_fx, 4480 /*70 in Q6*/ ) && LT_16( st->extl, FB_TBE ) && NE_32( st->extl_brate, SWB_TBE_1k10 ) && NE_32( st->extl_brate, SWB_TBE_1k75 ) ) + { + FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + GainShape_tmp_fx[i] = GainShape_fx[i * 4]; /* Q15 */ + move16(); + } + + FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + L_tmp1 = Mult_32_16( ener_tmp_fx[i], GainShape_tmp_fx[i] ); /* (2*Q_bwe_exc) */ + L_tmp2 = Mult_32_16( hBWE_TD->prev_ener_fx, hBWE_TD->prev_GainShape_fx ); /* (2*st->prev_ener_fx_Q) */ + tmp = sub( shl( Q_bwe_exc, 1 ), shl( st->prev_ener_fx_Q, 1 ) ); + L_tmp2 = L_shl_sat( L_tmp2, tmp ); /* new Q = (2*Q_bwe_exc) */ + IF( GT_32( L_tmp1, L_tmp2 ) ) + { + L_tmp = L_tmp2; + move32(); + if ( L_tmp2 < 0 ) + { + L_tmp = L_negate( L_tmp2 ); + } + + expb = norm_l( L_tmp ); + fracb = round_fx_sat( L_shl_sat( L_tmp, expb ) ); + expb = sub( 30, expb ); /* - (2*Q_bwe_exc_ext); */ + + expa = norm_l( ener_tmp_fx[i] ); + fraca = extract_h( L_shl( ener_tmp_fx[i], expa ) ); + expa = sub( 30, expa ); + + scale_fx = shr( sub( fraca, fracb ), 15 ); + fracb = shl( fracb, scale_fx ); + expb = sub( expb, scale_fx ); + + tmp = div_s( fracb, fraca ); + exp = sub( sub( expb, expa ), 1 ); + tmp = shl( tmp, exp ); + GainShape_tmp_fx[i] = add( tmp, shr( GainShape_tmp_fx[i], 1 ) ); /* Q15 */ + move16(); + } + + hBWE_TD->prev_ener_fx = ener_tmp_fx[i]; + move32(); + hBWE_TD->prev_GainShape_fx = GainShape_tmp_fx[i]; + move16(); + st->prev_ener_fx_Q = Q_bwe_exc; + move16(); + } + + FOR( i = 0; i < NUM_SHB_SUBFR; i++ ) + { + Word16 idx = 0; + move16(); + IF( i != 0 ) + { + idx = idiv1616( i_mult( i, NUM_SHB_SUBGAINS ), NUM_SHB_SUBFR ); + } + GainShape_fx[i] = GainShape_tmp_fx[idx]; + move16(); + } + } + ELSE + { + st->prev_ener_fx_Q = Q_bwe_exc; + move16(); + } + st->prev_Q_bwe_syn = Q_bwe_exc; + move16(); + + + /* Gain shape smoothing after quantization */ + test(); + IF( EQ_32( st->extl_brate, SWB_TBE_1k10 ) || EQ_32( st->extl_brate, SWB_TBE_1k75 ) ) + { + FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + GainShape_tmp_fx[i] = GainShape_fx[i * NUM_SHB_SUBGAINS]; + move16(); + } + + lls_interp_n_fx( GainShape_tmp_fx, NUM_SHB_SUBGAINS, &GainShape_tilt_fx, &temp_fx, 1 ); + + test(); + IF( GE_16( vind, 6 ) && LT_16( abs_s( GainShape_tilt_fx ), 3932 ) ) + { + feedback_fx = 9830; + move16(); + FOR( i = 0; i < NUM_SHB_SUBGAINS; i++ ) + { + GainShape_fx[i] = add_sat( mult( sub( 32767, feedback_fx ), GainShape_fx[i * NUM_SHB_SUBGAINS] ), mult( feedback_fx, GainShape_tmp_fx[i] ) ); + move16(); + } + + FOR( i = NUM_SHB_SUBFR - 1; i > 0; i-- ) + { + Word16 idx = 0; + move16(); + IF( i != 0 ) + { + idx = idiv1616( i_mult( i, NUM_SHB_SUBGAINS ), NUM_SHB_SUBFR ); + } + GainShape_fx[i] = GainShape_fx[idx]; + move16(); + } + } + } + + /* fil-in missing memory */ + test(); + test(); + IF( ( EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) ) && LE_32( st->last_core_brate, SID_2k40 ) ) + { + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + Word16 intermediate = mult( shaped_shb_excitation_fx[i], subwin_shb_fx[L_SHB_LAHEAD - i] ); + Word32 intermediate_32 = Mpy_32_16_1( Mpy_32_16_1( GainFrame_fx, window_shb_fx[L_SHB_LAHEAD - 1 - i] ), intermediate ); + hBWE_TD->syn_overlap_fx[i] = round_fx( L_shl_sat( intermediate_32, sub( 16, ( add( Q_bwe_exc, 18 - 15 ) ) ) ) ); + move16(); + } + } + + Word16 n_mem3_new = 0; + move16(); + find_max_mem_dec_m3( st, &n_mem3_new ); + + ScaleShapedSHB_fx( SHB_OVERLAP_LEN, + shaped_shb_excitation_fx, /* i/o: Q_bwe_exc */ + hBWE_TD->syn_overlap_fx, + GainShape_fx, /* Q15 */ + GainFrame_fx, /* Q18 */ + window_shb_fx, + subwin_shb_fx, + &Q_bwe_exc, &Qx, n_mem3_new, st->prev_Q_bwe_syn2 ); + + IF( hStereoICBWE != NULL ) + { + Copy_Scale_sig_16_32_DEPREC( lpc_shb_fx, hStereoICBWE->lpSHBRef_fx, LPC_SHB_ORDER + 1, 0 ); + Copy( GainShape_fx, hStereoICBWE->gshapeRef_fx, NUM_SHB_SUBFR ); + hStereoICBWE->gFrameRef_fx = GainFrame_fx; + move32(); + + Copy( shaped_shb_excitation_fx, hStereoICBWE->shbSynthRef_fx, L_FRAME16k ); + } + + max_val = 0; + move16(); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + max_val = s_max( max_val, abs_s( shaped_shb_excitation_fx[i] ) ); /* Q0 */ + } + IF( max_val == 0 ) + { + curr_frame_pow_fx = 0; + move32(); + n = 0; + move16(); + } + ELSE + { + n = norm_s( max_val ); + max_val = 0; + move16(); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + shaped_shb_excitation_frac[i] = shl_sat( shaped_shb_excitation_fx[i], n ); /*Q_bwe_exc+n*/ + move16(); + } + + curr_frame_pow_fx = 0; + move32(); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + L_tmp = L_mult0( shaped_shb_excitation_frac[i], shaped_shb_excitation_frac[i] ); /*2*(Q_bwe_exc+n)*/ + curr_frame_pow_fx = L_add( curr_frame_pow_fx, L_shr( L_tmp, 9 ) ); /*2*(Q_bwe_exc+n)-9*/ + } + } + curr_frame_pow_exp = sub( shl( add( Q_bwe_exc, n ), 1 ), 9 ); + tmp = sub( st->prev_frame_pow_exp, curr_frame_pow_exp ); + IF( tmp > 0 ) /* shifting prev */ + { + IF( GT_16( tmp, 32 ) ) + { + st->prev_frame_pow_exp = add( curr_frame_pow_exp, 32 ); + move16(); + tmp = 32; + move16(); + } + hBWE_TD->prev_swb_bwe_frame_pow_fx = L_shr( hBWE_TD->prev_swb_bwe_frame_pow_fx, tmp ); + move32(); + st->prev_frame_pow_exp = curr_frame_pow_exp; + move16(); + } + ELSE /* shifting curr */ + { + IF( LT_16( tmp, -32 ) ) + { + curr_frame_pow_exp = sub( st->prev_frame_pow_exp, 32 ); + tmp = -32; + move16(); + } + curr_frame_pow_fx = L_shr( curr_frame_pow_fx, -tmp ); + curr_frame_pow_exp = st->prev_frame_pow_exp; + move16(); + } + test(); + test(); + IF( !st->bfi && ( st->prev_bfi || st->prev_use_partial_copy ) ) + { + test(); + test(); + IF( ( GT_32( L_shr( curr_frame_pow_fx, 1 ), hBWE_TD->prev_swb_bwe_frame_pow_fx ) ) && + ( GT_32( hBWE_TD->prev_swb_bwe_frame_pow_fx, L_tmp ) ) && EQ_16( st->prev_coder_type, UNVOICED ) ) + { + L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); + scale_fx = round_fx( L_shl( L_tmp, exp ) ); /*Q15*/ + + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + temp_fx = round_fx( L_shl( L_tmp, exp ) ); /*Q15*/ + } + ELSE + { + scale_fx = temp_fx = 32767; + move16(); /*Q15*/ + move16(); /*Q15*/ + } + + FOR( j = 0; j < 8; j++ ) + { + GainShape_fx[2 * j] = mult_r( GainShape_fx[2 * j], scale_fx ); + move16(); + GainShape_fx[2 * j + 1] = mult_r( GainShape_fx[2 * j + 1], scale_fx ); + move16(); + FOR( i = 0; i < L_FRAME16k / 8; i++ ) + { + shaped_shb_excitation_fx[add( i, j * ( L_FRAME16k / 8 ) )] = mult_r( shaped_shb_excitation_fx[add( i, j * ( L_FRAME16k / 8 ) )], scale_fx ); + move16(); + } + + IF( temp_fx > 0 ) + { + /* scale_fx <= temp_fx, due to scale_fx = sqrt( st->prev_swb_bwe_frame_pow_fx/curr_frame_pow_fx ), temp_fx = sqrt( scale_fx, 1.f/8.f ) + and curr_frame_pow_fx > st->prev_swb_bwe_frame_pow_fx -> scale_fx <= 1.0, sqrt(scale_fx, 1.f/8.f) >= scale_fx */ + IF( LT_16( scale_fx, temp_fx ) ) + { + scale_fx = div_s( scale_fx, temp_fx ); + } + ELSE + { + scale_fx = 32767; + move16(); + } + } + ELSE + { + scale_fx = 0; + move16(); + } + } + } + + /* adjust the FEC frame energy */ + IF( st->bfi ) + { + scale_fx = temp_fx = 4096; + move16(); /*Q12*/ + move16(); + IF( EQ_16( st->nbLostCmpt, 1 ) ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( GT_32( curr_frame_pow_fx, hBWE_TD->prev_swb_bwe_frame_pow_fx ) && + NE_16( st->prev_coder_type, UNVOICED ) && + ( st->last_good != UNVOICED_CLAS ) ) + { + L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); /*31 - exp*/ + scale_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + temp_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + } + ELSE IF( LT_32( curr_frame_pow_fx, L_shr( hBWE_TD->prev_swb_bwe_frame_pow_fx, 1 ) ) && EQ_16( st->nbLostCmpt, 1 ) && + ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) || GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) ) && + ( EQ_16( st->prev_coder_type, UNVOICED ) || ( st->last_good == UNVOICED_CLAS ) || GT_16( hBWE_TD->tilt_swb_fec_fx, 10240 ) ) ) + { + L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); + scale_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + temp_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + } + } + ELSE IF( GT_16( st->nbLostCmpt, 1 ) ) + { + test(); + test(); + test(); + test(); + test(); + IF( GT_32( curr_frame_pow_fx, hBWE_TD->prev_swb_bwe_frame_pow_fx ) ) + { + L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); + scale_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + temp_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + } + ELSE IF( LT_32( curr_frame_pow_fx, L_shr( hBWE_TD->prev_swb_bwe_frame_pow_fx, 1 ) ) && + ( GT_32( st->enerLL_fx, L_shr( st->prev_enerLL_fx, 1 ) ) || GT_32( st->enerLH_fx, L_shr( st->prev_enerLH_fx, 1 ) ) ) && + ( EQ_16( st->prev_coder_type, UNVOICED ) || ( st->last_good == UNVOICED_CLAS ) || GT_16( hBWE_TD->tilt_swb_fec_fx, 10240 ) ) ) + { + L_tmp = root_a_over_b_fx( hBWE_TD->prev_swb_bwe_frame_pow_fx, curr_frame_pow_exp, curr_frame_pow_fx, curr_frame_pow_exp, &exp ); + L_tmp = L_min( L_tmp, L_shl_sat( 2, sub( 31, exp ) ) ); /*31 - exp*/ + scale_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + L_tmp = root_a_fx( L_tmp, sub( 31, exp ), &exp ); + temp_fx = round_fx( L_shl( L_tmp, sub( exp, 3 ) ) ); /*Q12*/ + } + } + + FOR( j = 0; j < 8; j++ ) + { + GainShape_fx[2 * j] = shl_sat( mult_r( GainShape_fx[2 * j], scale_fx ), 3 ); + move16(); /* 15 +12 +3-15 =15*/ + GainShape_fx[add( 2 * j, 1 )] = shl_sat( mult_r( GainShape_fx[add( 2 * j, 1 )], scale_fx ), 3 ); + move16(); + FOR( i = 0; i < 40; i++ ) + { + shaped_shb_excitation_fx[i + j * L_FRAME16k / 8] = shl( mult_r( shaped_shb_excitation_fx[i + j * L_FRAME16k / 8], scale_fx ), 3 ); + move16(); /* Q_bwe_exc +12+3 -15 =Q_bwe_exc*/ + } + + IF( temp_fx > 0 ) + { + IF( LT_16( scale_fx, temp_fx ) ) + { + scale_fx = shr( div_s( scale_fx, temp_fx ), 3 ); + } + ELSE + { + tmp1 = sub( norm_s( scale_fx ), 1 ); + tmp2 = norm_s( temp_fx ); + scale_fx = div_s( shl( scale_fx, tmp1 ), shl( temp_fx, tmp2 ) ); + scale_fx = shr( scale_fx, add( sub( tmp1, tmp2 ), 3 ) ); + } + } + ELSE + { + scale_fx = 0; + move16(); + } + } + } + + hBWE_TD->prev_swb_bwe_frame_pow_fx = curr_frame_pow_fx; + move32(); + st->prev_frame_pow_exp = curr_frame_pow_exp; + move16(); + + Word64 prev_ener_shb64 = 0; + move64(); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + prev_ener_shb64 = W_mac0_16_16( prev_ener_shb64, shaped_shb_excitation_fx[i], shaped_shb_excitation_fx[i] ); /* Q0 */ + } + L_prev_ener_shb = W_sat_l( prev_ener_shb64 ); + + L_prev_ener_shb = Mult_32_16( L_prev_ener_shb, 26214 ); /* 2*Q_bwe_exc_mod+8; 26214=(1/L_FRAME16k) in Q23 */ + st->prev_ener_shb_fx = 0; + move16(); + IF( L_prev_ener_shb != 0 ) + { + exp = norm_l( L_prev_ener_shb ); + tmp = extract_h( L_shl( L_prev_ener_shb, exp ) ); + exp = sub( exp, sub( 30, ( add( i_mult( 2, Q_bwe_exc ), 8 ) ) ) ); + + tmp = div_s( 16384, tmp ); + L_tmp = L_deposit_h( tmp ); + L_tmp = Isqrt_lc( L_tmp, &exp ); + st->prev_ener_shb_fx = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /* Q1 */ + move16(); + } + + IF( st->hBWE_FD != NULL ) + { + L_tmp = Mult_32_16( curr_frame_pow_fx, 26214 ); /* curr_frame_pow_exp+8; 26214=(1/L_FRAME16k) in Q23 */ + tmp = 0; + move16(); + IF( L_tmp != 0 ) + { + exp = norm_l( L_tmp ); + tmp = extract_h( L_shl( L_tmp, exp ) ); + exp = sub( exp, sub( 30, add( curr_frame_pow_exp, 8 ) ) ); + + tmp = div_s( 16384, tmp ); + L_tmp = L_deposit_h( tmp ); + L_tmp = Isqrt_lc( L_tmp, &exp ); + tmp = round_fx_sat( L_shl_sat( L_tmp, sub( exp, 14 ) ) ); /* Q1 */ + } + set16_fx( st->prev_SWB_fenv_fx, tmp, SWB_FENV ); /* Q1 */ + } + + FOR( i = 0; i < L_FRAME16k; i++ ) + { + shaped_shb_excitation_fx_32[i] = L_shl( shaped_shb_excitation_fx[i], sub( Q11, Q_bwe_exc ) ); + move32(); + } + + /* generate 32kHz SHB synthesis from 12.8(16)kHz signal */ + GenSHBSynth_fx_32( shaped_shb_excitation_fx_32, error_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, st->L_frame, &( hBWE_TD->syn_dm_phase ) ); + 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, 2 * ALLPASSSECTIONS_STEEP, -( Q11 - Q_bwe_exc ) ); + Copy32( error_fx + L_FRAME32k - L_SHB_TRANSITION_LENGTH, hBWE_TD->old_tbe_synth_fx_32, L_SHB_TRANSITION_LENGTH ); + + /* resample SHB synthesis (if needed) and scale down */ + synth_scale_fx = 32767; + move16(); /* 1.0 in Q15 */ + if ( EQ_16( st->codec_mode, MODE1 ) ) + { + synth_scale_fx = 29491; + move16(); /* 0.9 in Q15 */ + } + + IF( EQ_32( st->output_Fs, 48000 ) ) + { + IF( EQ_16( st->extl, FB_TBE ) ) + { + tmp = norm_l( GainFrame_fx ); + if ( GainFrame_fx == 0 ) + { + tmp = 31; + move16(); + } + L_tmp = L_shl( GainFrame_fx, tmp ); /* 18 + tmp */ + + tmp1 = 0; + move16(); + FOR( i = 0; i < L_FRAME16k; i++ ) + { + Word16 idx = 0; + move16(); + IF( i != 0 ) + { + idx = idiv1616( i_mult( NUM_SHB_SUBFR, i ), L_FRAME16k ); + } + L_tmp1 = Mult_32_16( L_tmp, GainShape_fx[idx] ); /* Q : 18 + tmp +15 -15*/ + White_exc16k_fx[i] = round_fx( Mult_32_16( L_tmp1, White_exc16k_fx[i] ) ); /* 18 + tmp +*Q_white_exc -15 -16 */ + move16(); + tmp1 = s_max( tmp1, abs_s( White_exc16k_fx[i] ) ); + } + + *Q_white_exc = sub( add( *Q_white_exc, tmp ), 13 ); /* *Q_white_exc + 18 + tmp -15 -16 */ + move16(); + tmp = norm_s( tmp1 ); + if ( tmp1 == 0 ) + { + tmp = 15; + move16(); + } + + FOR( i = 0; i < L_FRAME16k; i++ ) + { + White_exc16k_fx[i] = shl( White_exc16k_fx[i], sub( tmp, 1 ) ); + move16(); + } + *Q_white_exc = sub( add( *Q_white_exc, tmp ), 1 ); + move16(); + } + + IF( NE_16( synth_scale_fx, 32767 ) ) /* 1.0 in Q15 */ + { + FOR( i = 0; i < L_FRAME32k; i++ ) + { + error_fx[i] = Mpy_32_16_1( error_fx[i], synth_scale_fx ); + move32(); + } + } + interpolate_3_over_2_allpass_32( error_fx, L_FRAME32k, synth_fx, hBWE_TD->int_3_over_2_tbemem_dec_fx_32 ); + } + ELSE IF( EQ_32( st->output_Fs, 32000 ) ) + { + IF( NE_16( synth_scale_fx, 32767 ) ) /* 1.0 in Q15 */ + { + FOR( i = 0; i < L_FRAME32k; i++ ) + { + synth_fx[i] = Mpy_32_16_1( error_fx[i], synth_scale_fx ); + move32(); /*Qx*/ + } + } + ELSE + { + Copy32( error_fx, synth_fx, L_FRAME32k ); + } + } + ELSE IF( EQ_32( st->output_Fs, 16000 ) ) + { + IF( NE_16( synth_scale_fx, 32767 ) ) /* 1.0 in Q15 */ + { + FOR( i = 0; i < L_FRAME32k; i++ ) + { + error_fx[i] = Mpy_32_16_1( error_fx[i], synth_scale_fx ); + move32(); + } + } + + Decimate_allpass_steep_fx32( error_fx, hBWE_TD->mem_resamp_HB_32k_fx_32, L_FRAME32k, synth_fx ); + } + + + /* Update previous frame parameters for FEC */ + Copy( lsf_shb_fx, hBWE_TD->lsp_prevfrm_fx, LPC_SHB_ORDER ); + IF( EQ_16( st->codec_mode, MODE1 ) ) + { + hBWE_TD->GainFrame_prevfrm_fx = GainFrame_fx; + move32(); /*Q18*/ + hBWE_TD->tilt_swb_fec_fx = tilt_swb_fec_fx; + move16(); + + if ( !st->bfi ) + { + hBWE_TD->GainAttn_fx = 32767; /*1.0f in Q15*/ + move16(); + } + } + ELSE + { + IF( !st->bfi ) + { + hBWE_TD->GainFrame_prevfrm_fx = GainFrame_fx; + move32(); /*Q18*/ + hBWE_TD->tilt_swb_fec_fx = tilt_swb_fec_fx; + move16(); + hBWE_TD->GainAttn_fx = 32767; /*1.0f in Q15*/ + move16(); + } + } + + hBWE_TD->prev_ener_fx = ener_tmp_fx[NUM_SHB_SUBGAINS - 1]; + move32(); + hBWE_TD->prev_GainShape_fx = GainShape_fx[NUM_SHB_SUBFR - 1]; + move16(); + st->prev_Q_bwe_syn2 = Q_bwe_exc; + move16(); + st->prev_Qx = Q_bwe_exc; + move16(); + + return; +} + +void GenTransition_fixed( + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ + const Word32 output_Fs, /* i : output sampling rate : Q0 */ + const Word16 element_mode, /* i : element mode : Q0 */ + const Word16 L_frame, /* i : ACELP frame length : Q0 */ + const Word16 rf_flag, /* i : RF flag : Q0 */ + const Word32 total_brate, /* i : total bitrate : Q0 */ + const Word16 prev_Qx ) +{ + Word16 i, length; + + Word32 syn_overlap_32k_fx[2 * SHB_OVERLAP_LEN]; + + /* set targeted length of transition signal */ + length = i_mult( 2, NS2SA_FX2( output_Fs, DELAY_BWE_TOTAL_NS ) ); + + /* upsample overlap snippet */ + Interpolate_allpass_steep_32( hBWE_TD->syn_overlap_fx_32, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx_32, SHB_OVERLAP_LEN, syn_overlap_32k_fx ); + + /* perFORm spectral flip and downmix with overlap snippet to match HB synth */ + test(); + test(); + test(); + test(); + IF( ( ( element_mode == EVS_MONO ) && ( rf_flag || EQ_32( total_brate, ACELP_9k60 ) ) ) || ( ( element_mode > EVS_MONO ) && EQ_16( L_frame, L_FRAME ) ) ) + { + flip_and_downmix_generic_fx_32( syn_overlap_32k_fx, syn_overlap_32k_fx, 2 * SHB_OVERLAP_LEN, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx + HILBERT_ORDER1, hBWE_TD->genSHBsynth_Hilbert_Mem_fx + ( HILBERT_ORDER1 + 2 * HILBERT_ORDER2 ), &( hBWE_TD->syn_dm_phase ) ); + } + ELSE + { + FOR( i = 0; i < 2 * SHB_OVERLAP_LEN; i++ ) + { + IF( i % 2 == 0 ) + { + syn_overlap_32k_fx[i] = L_negate( syn_overlap_32k_fx[i] ); + } + ELSE + { + syn_overlap_32k_fx[i] = syn_overlap_32k_fx[i]; + } + move32(); + } + } + + /* cross fade of overlap snippet and mirrored HB synth from previous frame */ + FOR( i = 0; i < 2 * L_SHB_LAHEAD; i++ ) + { + outputHB_fx[i] = L_add_sat( Mpy_32_16_1( hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i], window_shb_32k_fx[i] ), Mpy_32_16_1( syn_overlap_32k_fx[i], window_shb_32k_fx[2 * L_SHB_LAHEAD - 1 - i] ) ); + move32(); + } + + /* fill transition signal with mirrored HB synth from previous frame to fully fill delay alignment buffer gap */ + FOR( ; i < length; i++ ) + { + outputHB_fx[i] = L_shl( hBWE_TD->old_tbe_synth_fx[L_SHB_TRANSITION_LENGTH - 1 - i], sub( Q11, prev_Qx ) ); + move32(); + } + + IF( EQ_32( output_Fs, 48000 ) ) + { + interpolate_3_over_2_allpass_32( outputHB_fx, length, outputHB_fx, hBWE_TD->int_3_over_2_tbemem_dec_fx_32 ); + } + ELSE IF( EQ_32( output_Fs, 16000 ) ) + { + Decimate_allpass_steep_fx32( outputHB_fx, hBWE_TD->mem_resamp_HB_32k_fx_32, L_FRAME32k, outputHB_fx ); + } + + return; +} +void GenTransition_WB_fixed( + TD_BWE_DEC_HANDLE hBWE_TD, /* i/o: TD BWE data handle */ + Word32 *outputHB_fx, /* o : synthesized HB transitions signal : Q11 */ + const Word32 output_Fs /* i : output sampling rate */ +) +{ + Word16 i, length; + Word32 speech_buf_16k1_fx[SHB_OVERLAP_LEN], speech_buf_16k2_fx[2 * SHB_OVERLAP_LEN]; + Word32 upsampled_synth_fx[L_FRAME48k]; + + /* set targeted length of transition signal */ + length = i_mult( 2, NS2SA_FX2( output_Fs, DELAY_BWE_TOTAL_NS ) ); + + /* upsample overlap snippet */ + Interpolate_allpass_steep_32( hBWE_TD->syn_overlap_fx_32, hBWE_TD->state_lsyn_filt_shb_fx_32, SHB_OVERLAP_LEN / 2, speech_buf_16k1_fx ); + Interpolate_allpass_steep_32( speech_buf_16k1_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx_32, SHB_OVERLAP_LEN, speech_buf_16k2_fx ); + + /* perform spectral flip and downmix with overlap snippet to match HB synth */ + FOR( i = 0; i < SHB_OVERLAP_LEN; i++ ) + { + IF( i % 2 == 0 ) + { + speech_buf_16k2_fx[i] = L_negate( speech_buf_16k2_fx[i] ); + move32(); + } + ELSE + { + speech_buf_16k2_fx[i] = speech_buf_16k2_fx[i]; + move32(); + } + } + + /* cross fade of overlap snippet and mirrored HB synth from previous frame */ + FOR( i = 0; i < L_SHB_LAHEAD; i++ ) + { + outputHB_fx[i] = L_add( Mpy_32_16_1( hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i], window_shb_fx[i] ), Mpy_32_16_1( speech_buf_16k2_fx[i], window_shb_fx[L_SHB_LAHEAD - 1 - i] ) ); + move32(); + outputHB_fx[i] = Mpy_32_16_1( outputHB_fx[i], 21299 ); + move32(); + } + + /* fill transition signal with mirrored HB synth from previous frame to fully fill delay alignment buffer gap */ + FOR( ; i < length; i++ ) + { + outputHB_fx[i] = hBWE_TD->old_tbe_synth_fx_32[L_SHB_TRANSITION_LENGTH - 1 - i]; + move32(); + outputHB_fx[i] = Mpy_32_16_1( outputHB_fx[i], 21299 ); + move32(); + } + + /* upsampling if necessary */ + IF( EQ_32( output_Fs, 32000 ) ) + { + Interpolate_allpass_steep_32( outputHB_fx, hBWE_TD->mem_resamp_HB_fx_32, L_FRAME16k, upsampled_synth_fx ); + Copy32( upsampled_synth_fx, outputHB_fx, L_FRAME32k ); + } + ELSE IF( EQ_32( output_Fs, 48000 ) ) + { + interpolate_3_over_1_allpass_32( outputHB_fx, L_FRAME16k, upsampled_synth_fx, hBWE_TD->mem_resamp_HB_fx_32 ); + Copy32( upsampled_synth_fx, outputHB_fx, L_FRAME48k ); + } + + return; +} diff --git a/lib_dec/tonalMDCTconcealment.c b/lib_dec/tonalMDCTconcealment.c deleted file mode 100644 index 6a74d3b87..000000000 --- a/lib_dec/tonalMDCTconcealment.c +++ /dev/null @@ -1,436 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2025 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. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#define _USE_MATH_DEFINES - -#include -#include -#include "options.h" -#include -#include "prot.h" -#include "ivas_prot.h" -#include "wmc_auto.h" -#include "ivas_prot_fx.h" -#include "prot_fx.h" - - -/*******************************************************/ -/*-------------- public functions -------------------- */ -/*******************************************************/ - -void TonalMdctConceal_create_concealment_noise_ivas_fx( - Word32 concealment_noise[L_FRAME48k], // Q31-concealment_noise_exp - Word16 *concealment_noise_exp, - CPE_DEC_HANDLE hCPE, - const Word16 L_frameTCX, // Q0 - const Word16 L_frame, // Q0 - const Word16 idchan, // Q0 - const Word16 subframe_idx, // Q0 - const Word16 core, // Q0 - const Word16 crossfade_gain, // Q15 - const TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode ) -{ - STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct; - TonalMDCTConcealPtr hTonalMDCTConc; - Decoder_State *st; - HANDLE_FD_CNG_COM hFdCngCom; - Word16 *rnd_c, *rnd; - Word16 crossOverFreq, i, save_rnd_c, max_noise_line; - Word16 c, c_inv, inc; - Word32 noise_shape_buffer[L_FRAME48k]; - Word16 noise_shape_buffer_e[L_FRAME48k]; - Word16 start_idx, stop_idx, noise_shape_buffer_common_exp = MIN16B_FLT_FX, last_scf_e, temp_e; - move16(); - Word32 *cngNoiseLevelPtr; - Word32 last_scf; - - Word16 c_e, c_inv_e; - - push_wmops( "create_conc_noise" ); - - hStereoMdct = hCPE->hStereoMdct; - st = hCPE->hCoreCoder[idchan]; - hTonalMDCTConc = st->hTonalMDCTConc; - hFdCngCom = st->hFdCngDec->hFdCngCom; - rnd = &hStereoMdct->noise_seeds_channels[idchan]; - rnd_c = &hStereoMdct->noise_seed_common; - - /* determine start bin for IGF */ - IF( st->igf == 0 ) - { - IF( st->narrowBand == 0 ) - { - /* minimum needed for output with sampling rates lower then the - nominal sampling rate */ - crossOverFreq = s_min( L_frameTCX, L_frame ); - } - ELSE - { - crossOverFreq = L_frameTCX; - move16(); - } - } - ELSE - { - crossOverFreq = s_min( st->hIGFDec->infoIGFStartLine, L_frameTCX ); - } - - /* for tonal mdct concealment with tonal components above the crossover frequency, conditionally raise the frequency index until which noise is generated */ - max_noise_line = crossOverFreq; - move16(); - IF( st->tonal_mdct_plc_active ) - { - max_noise_line = s_max( max_noise_line, extract_l( L_add( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1], 1 ) ) ); - } - - /* first lost frame is handled separately */ - IF( !hTonalMDCTConc->lastBlockData.blockIsConcealed ) - { - *rnd = add( 1977, idchan ); // Q0 - move16(); - /* will be set twice when looping over two channels, but does not matter */ - *rnd_c = 1979; // Q0 - move16(); - } - - IF( GT_16( crossfade_gain, 32734 ) ) - /* Due to precision loss */ /* 0.999 in Q15*/ - { - /* In first frame, noise is weighted with zero anyway, we only need the random numbers for the sign scrambling */ - FOR( i = 0; i < max_noise_line; i++ ) - { - *rnd = own_random( rnd ); - move16(); - concealment_noise[i] = *rnd; // Q31-concealment_noise_exp - move32(); - } - *concealment_noise_exp = 31; - move16(); - pop_wmops(); - - return; - } - - save_rnd_c = *rnd_c; // Q0 - move16(); - - c_e = 1; - move16(); - c_inv_e = 1; - move16(); - - c = Sqrt16( hStereoMdct->lastCoh_fx, &c_e ); // Q1 = 15 - c_e - c_inv = Sqrt16( sub( ONE_IN_Q14, hStereoMdct->lastCoh_fx ), &c_inv_e ); // Q2 = 15 - c_inv_e - - IF( NE_16( c_e, c_inv_e ) ) - { - IF( LT_16( c_e, c_inv_e ) ) - { - c = shr( c, sub( c_inv_e, c_e ) ); // Q0 - c_e = c_inv_e; - move16(); - } - ELSE - { - c_inv = shr( c_inv, sub( c_e, c_inv_e ) ); // Q0 - } - } - - /* pre-compute the noise shape for later weighting of the noise spectra */ - cngNoiseLevelPtr = &hFdCngCom->cngNoiseLevel[0]; - last_scf_e = hFdCngCom->cngNoiseLevelExp; - move16(); - - IF( GT_16( st->core, TCX_20_CORE ) ) - { - inc = 2; - } - ELSE - { - inc = 1; - } - move16(); - start_idx = idiv1616( hFdCngCom->startBand, inc ); - stop_idx = idiv1616( hFdCngCom->stopFFTbin, inc ); - - FOR( i = 0; i < start_idx; i++ ) - { - noise_shape_buffer[i] = 0; - move32(); - noise_shape_buffer_e[i] = 0; - move16(); - } - FOR( ; i < stop_idx; ( i++, cngNoiseLevelPtr += inc ) ) - { - noise_shape_buffer_e[i] = hFdCngCom->cngNoiseLevelExp; - move16(); - noise_shape_buffer[i] = Sqrt32( *( cngNoiseLevelPtr ), &noise_shape_buffer_e[i] ); // Q31-noise_shape_buffer_e[i] - move32(); - noise_shape_buffer_common_exp = s_max( noise_shape_buffer_e[i], noise_shape_buffer_common_exp ); - } - - FOR( i = 0; i < stop_idx; i++ ) - { - IF( NE_16( noise_shape_buffer_common_exp, noise_shape_buffer_e[i] ) ) - { - - noise_shape_buffer[i] = L_shr( noise_shape_buffer[i], sub( noise_shape_buffer_common_exp, noise_shape_buffer_e[i] ) ); // Q31- (noise_shape_buffer_common_exp-noise_shape_buffer_e[i]) - move32(); - } - } - - last_scf = Sqrt32( *( cngNoiseLevelPtr - inc ), &last_scf_e ); // Q31-last_scf_e - - IF( LT_16( noise_shape_buffer_common_exp, last_scf_e ) ) - { - Scale_sig32( noise_shape_buffer, stop_idx, sub( noise_shape_buffer_common_exp, last_scf_e ) ); // Q31- (noise_shape_buffer_common_exp-last_scf_e) - - noise_shape_buffer_common_exp = last_scf_e; - move16(); - } - ELSE - { - last_scf = L_shl( last_scf, sub( last_scf_e, noise_shape_buffer_common_exp ) ); // Q31-(last_scf_e-noise_shape_buffer_common_exp) - } - - FOR( ; i < max_noise_line; i++ ) - { - noise_shape_buffer[i] = last_scf; // Q31 - noise_shape_buffer_common_exp - move32(); - } - - /* fill the noise vector */ - hTonalMDCTConc->curr_noise_nrg = MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG_Q31; // Q31 - move32(); - hTonalMDCTConc->curr_noise_nrg_exp = 0; - move16(); - *concealment_noise_exp = add( 16, add( noise_shape_buffer_common_exp, c_e ) ); - move16(); - temp_e = hTonalMDCTConc->curr_noise_nrg_exp; - move16(); - - test(); - test(); - test(); - test(); - IF( EQ_16( noise_gen_mode, EQUAL_CORES ) || ( ( EQ_16( noise_gen_mode, TCX20_IN_0_TCX10_IN_1 ) && EQ_16( idchan, 0 ) ) || ( EQ_16( noise_gen_mode, TCX10_IN_0_TCX20_IN_1 ) && EQ_16( idchan, 1 ) ) ) ) - { - /* current channel is TCX20 -> generate noise for "full-length" spectrum */ - - FOR( i = 0; i < max_noise_line; i++ ) - { - *rnd = own_random( rnd ); // Q0 - *rnd_c = own_random( rnd_c ); - - move16(); - move16(); - - concealment_noise[i] = Mpy_32_32( L_add( L_shr( L_mult( c_inv, *rnd ), 1 ), L_shr( L_mult( c, *rnd_c ), 1 ) ), noise_shape_buffer[i] ); // Q31 - *concealment_noise_exp - move32(); - IF( concealment_noise[i] != 0 ) - { - hTonalMDCTConc->curr_noise_nrg = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->curr_noise_nrg, hTonalMDCTConc->curr_noise_nrg_exp, Mpy_32_32( concealment_noise[i], concealment_noise[i] ), shl( *concealment_noise_exp, 1 ), &temp_e ); // Q31-temp_e - } - hTonalMDCTConc->curr_noise_nrg_exp = temp_e; - move16(); - } - } - ELSE /* ( ( noise_gen_mode == TCX10_IN_0_TCX20_IN_1 && idchan == 0 ) || ( noise_gen_mode == TCX20_IN_0_TCX10_IN_1 && idchan == 1 ) ) */ - { - /* current channel is TCX10 and the other is TCX20 -> generate noise for "half-length" spectrum, but "increment" mid seed twice, to have the same seed in mid as the other (TCX20) channel for next frame */ - FOR( i = 0; i < max_noise_line; i++ ) - { - *rnd = own_random( rnd ); // Q0 - *rnd_c = own_random( rnd_c ); // Q0 - move16(); - move16(); - - concealment_noise[i] = Mpy_32_32( L_add( L_shr( L_mult( c_inv, *rnd ), 1 ), L_shr( L_mult( c, *rnd_c ), 1 ) ), noise_shape_buffer[i] ); - move32(); - IF( concealment_noise[i] != 0 ) - { - hTonalMDCTConc->curr_noise_nrg = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->curr_noise_nrg, hTonalMDCTConc->curr_noise_nrg_exp, Mpy_32_32( concealment_noise[i], concealment_noise[i] ), shl( *concealment_noise_exp, 1 ), &temp_e ); // Q31-temp_e - } - hTonalMDCTConc->curr_noise_nrg_exp = temp_e; - move16(); - - *rnd_c = own_random( rnd_c ); - move16(); - } - } - - IF( st->tonal_mdct_plc_active ) - { - FOR( i = crossOverFreq; i < s_max( crossOverFreq, hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ); ++i ) - { - concealment_noise[i] = 0; - move32(); - } - } - - /* restore common seed - - after finishing the first channel - - after a first subframe if the current channel is TCX10 */ - - test(); - test(); - test(); - test(); - test(); - IF( ( EQ_16( idchan, 0 ) && ( EQ_16( core, TCX_20 ) || ( EQ_16( core, TCX_10 ) && EQ_16( subframe_idx, 1 ) ) ) ) || ( EQ_16( core, TCX_10 ) && EQ_16( subframe_idx, 0 ) ) ) - { - *rnd_c = save_rnd_c; - move16(); - } - - st->seed_tcx_plc = *rnd; - move16(); - - pop_wmops(); - - return; -} - - -void TonalMdctConceal_whiten_noise_shape_ivas_fx( - Decoder_State *st, - const Word16 L_frame, - const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE whitening_mode ) -{ - Word16 inc, start_idx, stop_idx, i; - Word32 *noiseLevelPtr, *scfs_bg, *scfs_for_shaping; - Word16 noiseLevelPtr_exp; - HANDLE_FD_CNG_COM hFdCngCom; - Word32 whitenend_noise_shape[L_FRAME16k]; - Word16 q_wns; - Word32 scfs_int[FDNS_NPTS]; - const PsychoacousticParameters *psychParams; - - push_wmops( "apply_sns_on_noise_shape" ); - - scfs_bg = &st->hTonalMDCTConc->scaleFactorsBackground_fx[0]; - psychParams = st->hTonalMDCTConc->psychParams; - hFdCngCom = st->hFdCngDec->hFdCngCom; - -#ifdef MSAN_FIX - set32_fx( whitenend_noise_shape, 0, L_FRAME16k ); -#endif - - IF( EQ_32( whitening_mode, ON_FIRST_LOST_FRAME ) ) - { - IF( GT_16( st->core, TCX_20_CORE ) ) - { - inc = 2; - move16(); - } - ELSE - { - inc = 1; - move16(); - } - } - ELSE - { - IF( GT_16( st->last_core, TCX_20_CORE ) ) - { - inc = 2; - move16(); - } - ELSE - { - inc = 1; - move16(); - } - } - start_idx = shr( hFdCngCom->startBand, sub( inc, 1 ) ); - stop_idx = shr( L_frame, sub( inc, 1 ) ); - noiseLevelPtr = hFdCngCom->cngNoiseLevel; - noiseLevelPtr_exp = hFdCngCom->cngNoiseLevelExp; - move16(); - - FOR( Word16 j = start_idx; j < stop_idx; j++ ) - { - whitenend_noise_shape[j] = L_shr( *noiseLevelPtr, 3 ); - move32(); - noiseLevelPtr += inc; - } - - IF( EQ_32( whitening_mode, ON_FIRST_LOST_FRAME ) ) - { - Word32 scf[SNS_NPTS]; - - sns_compute_scf_fx( whitenend_noise_shape, psychParams, L_frame, scf, sub( sub( 31, noiseLevelPtr_exp ), 3 ) ); - - sns_interpolate_scalefactors_fx( scfs_int, scf, ENC ); - sns_interpolate_scalefactors_fx( scfs_bg, scf, DEC ); - - scfs_for_shaping = &scfs_int[0]; // Q16 - } - ELSE /* whitening_mode == ON_FIRST_GOOD_FRAME */ - { - scfs_for_shaping = &scfs_bg[0]; // Q16 - } - - IF( sum32_sat( scfs_for_shaping, FDNS_NPTS ) > 0 ) - { - q_wns = sub( sub( 31, noiseLevelPtr_exp ), 3 ); - sns_shape_spectrum_fx( whitenend_noise_shape, &q_wns, psychParams, scfs_for_shaping, Q16, L_frame, NULL ); - - IF( GT_16( add( q_wns, 1 ), sub( 31, hFdCngCom->cngNoiseLevelExp ) ) ) - { - FOR( i = 0; i < sub( stop_idx, start_idx ); i++ ) - { - hFdCngCom->cngNoiseLevel[i] = L_shr( whitenend_noise_shape[start_idx + i], sub( add( q_wns, hFdCngCom->cngNoiseLevelExp ), 30 ) ); //(q_wns + 1) - move32(); - } - } - ELSE - { - Copy32( whitenend_noise_shape + start_idx, hFdCngCom->cngNoiseLevel, sub( stop_idx, start_idx ) ); - - scale_sig32( hFdCngCom->cngNoiseLevel + sub( stop_idx, start_idx ), sub( FFTCLDFBLEN, sub( stop_idx, start_idx ) ), sub( add( q_wns, hFdCngCom->cngNoiseLevelExp ), 30 ) ); - - hFdCngCom->cngNoiseLevelExp = sub( Q30, q_wns ); // Exponent = 31 - (q_wns + 1) - move16(); - } - } - ELSE - { - set32_fx( hFdCngCom->cngNoiseLevel, 0, sub( stop_idx, start_idx ) ); - } - - pop_wmops(); -} diff --git a/lib_dec/tonalMDCTconcealment_fx.c b/lib_dec/tonalMDCTconcealment_fx.c index a4aa23e7f..3cf5f51f3 100644 --- a/lib_dec/tonalMDCTconcealment_fx.c +++ b/lib_dec/tonalMDCTconcealment_fx.c @@ -3200,6 +3200,397 @@ static void CalcPowerSpec( powerSpec[nSamples - 1] = L_shr( powerSpec[nSamples - 2], 1 ); move32(); } + + +/*******************************************************/ +/*-------------- public functions -------------------- */ +/*******************************************************/ + +void TonalMdctConceal_create_concealment_noise_ivas_fx( + Word32 concealment_noise[L_FRAME48k], // Q31-concealment_noise_exp + Word16 *concealment_noise_exp, + CPE_DEC_HANDLE hCPE, + const Word16 L_frameTCX, // Q0 + const Word16 L_frame, // Q0 + const Word16 idchan, // Q0 + const Word16 subframe_idx, // Q0 + const Word16 core, // Q0 + const Word16 crossfade_gain, // Q15 + const TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode ) +{ + STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct; + TonalMDCTConcealPtr hTonalMDCTConc; + Decoder_State *st; + HANDLE_FD_CNG_COM hFdCngCom; + Word16 *rnd_c, *rnd; + Word16 crossOverFreq, i, save_rnd_c, max_noise_line; + Word16 c, c_inv, inc; + Word32 noise_shape_buffer[L_FRAME48k]; + Word16 noise_shape_buffer_e[L_FRAME48k]; + Word16 start_idx, stop_idx, noise_shape_buffer_common_exp = MIN16B_FLT_FX, last_scf_e, temp_e; + move16(); + Word32 *cngNoiseLevelPtr; + Word32 last_scf; + + Word16 c_e, c_inv_e; + + push_wmops( "create_conc_noise" ); + + hStereoMdct = hCPE->hStereoMdct; + st = hCPE->hCoreCoder[idchan]; + hTonalMDCTConc = st->hTonalMDCTConc; + hFdCngCom = st->hFdCngDec->hFdCngCom; + rnd = &hStereoMdct->noise_seeds_channels[idchan]; + rnd_c = &hStereoMdct->noise_seed_common; + + /* determine start bin for IGF */ + IF( st->igf == 0 ) + { + IF( st->narrowBand == 0 ) + { + /* minimum needed for output with sampling rates lower then the + nominal sampling rate */ + crossOverFreq = s_min( L_frameTCX, L_frame ); + } + ELSE + { + crossOverFreq = L_frameTCX; + move16(); + } + } + ELSE + { + crossOverFreq = s_min( st->hIGFDec->infoIGFStartLine, L_frameTCX ); + } + + /* for tonal mdct concealment with tonal components above the crossover frequency, conditionally raise the frequency index until which noise is generated */ + max_noise_line = crossOverFreq; + move16(); + IF( st->tonal_mdct_plc_active ) + { + max_noise_line = s_max( max_noise_line, extract_l( L_add( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1], 1 ) ) ); + } + + /* first lost frame is handled separately */ + IF( !hTonalMDCTConc->lastBlockData.blockIsConcealed ) + { + *rnd = add( 1977, idchan ); // Q0 + move16(); + /* will be set twice when looping over two channels, but does not matter */ + *rnd_c = 1979; // Q0 + move16(); + } + + IF( GT_16( crossfade_gain, 32734 ) ) + /* Due to precision loss */ /* 0.999 in Q15*/ + { + /* In first frame, noise is weighted with zero anyway, we only need the random numbers for the sign scrambling */ + FOR( i = 0; i < max_noise_line; i++ ) + { + *rnd = own_random( rnd ); + move16(); + concealment_noise[i] = *rnd; // Q31-concealment_noise_exp + move32(); + } + *concealment_noise_exp = 31; + move16(); + pop_wmops(); + + return; + } + + save_rnd_c = *rnd_c; // Q0 + move16(); + + c_e = 1; + move16(); + c_inv_e = 1; + move16(); + + c = Sqrt16( hStereoMdct->lastCoh_fx, &c_e ); // Q1 = 15 - c_e + c_inv = Sqrt16( sub( ONE_IN_Q14, hStereoMdct->lastCoh_fx ), &c_inv_e ); // Q2 = 15 - c_inv_e + + IF( NE_16( c_e, c_inv_e ) ) + { + IF( LT_16( c_e, c_inv_e ) ) + { + c = shr( c, sub( c_inv_e, c_e ) ); // Q0 + c_e = c_inv_e; + move16(); + } + ELSE + { + c_inv = shr( c_inv, sub( c_e, c_inv_e ) ); // Q0 + } + } + + /* pre-compute the noise shape for later weighting of the noise spectra */ + cngNoiseLevelPtr = &hFdCngCom->cngNoiseLevel[0]; + last_scf_e = hFdCngCom->cngNoiseLevelExp; + move16(); + + IF( GT_16( st->core, TCX_20_CORE ) ) + { + inc = 2; + } + ELSE + { + inc = 1; + } + move16(); + start_idx = idiv1616( hFdCngCom->startBand, inc ); + stop_idx = idiv1616( hFdCngCom->stopFFTbin, inc ); + + FOR( i = 0; i < start_idx; i++ ) + { + noise_shape_buffer[i] = 0; + move32(); + noise_shape_buffer_e[i] = 0; + move16(); + } + FOR( ; i < stop_idx; ( i++, cngNoiseLevelPtr += inc ) ) + { + noise_shape_buffer_e[i] = hFdCngCom->cngNoiseLevelExp; + move16(); + noise_shape_buffer[i] = Sqrt32( *( cngNoiseLevelPtr ), &noise_shape_buffer_e[i] ); // Q31-noise_shape_buffer_e[i] + move32(); + noise_shape_buffer_common_exp = s_max( noise_shape_buffer_e[i], noise_shape_buffer_common_exp ); + } + + FOR( i = 0; i < stop_idx; i++ ) + { + IF( NE_16( noise_shape_buffer_common_exp, noise_shape_buffer_e[i] ) ) + { + + noise_shape_buffer[i] = L_shr( noise_shape_buffer[i], sub( noise_shape_buffer_common_exp, noise_shape_buffer_e[i] ) ); // Q31- (noise_shape_buffer_common_exp-noise_shape_buffer_e[i]) + move32(); + } + } + + last_scf = Sqrt32( *( cngNoiseLevelPtr - inc ), &last_scf_e ); // Q31-last_scf_e + + IF( LT_16( noise_shape_buffer_common_exp, last_scf_e ) ) + { + Scale_sig32( noise_shape_buffer, stop_idx, sub( noise_shape_buffer_common_exp, last_scf_e ) ); // Q31- (noise_shape_buffer_common_exp-last_scf_e) + + noise_shape_buffer_common_exp = last_scf_e; + move16(); + } + ELSE + { + last_scf = L_shl( last_scf, sub( last_scf_e, noise_shape_buffer_common_exp ) ); // Q31-(last_scf_e-noise_shape_buffer_common_exp) + } + + FOR( ; i < max_noise_line; i++ ) + { + noise_shape_buffer[i] = last_scf; // Q31 - noise_shape_buffer_common_exp + move32(); + } + + /* fill the noise vector */ + hTonalMDCTConc->curr_noise_nrg = MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG_Q31; // Q31 + move32(); + hTonalMDCTConc->curr_noise_nrg_exp = 0; + move16(); + *concealment_noise_exp = add( 16, add( noise_shape_buffer_common_exp, c_e ) ); + move16(); + temp_e = hTonalMDCTConc->curr_noise_nrg_exp; + move16(); + + test(); + test(); + test(); + test(); + IF( EQ_16( noise_gen_mode, EQUAL_CORES ) || ( ( EQ_16( noise_gen_mode, TCX20_IN_0_TCX10_IN_1 ) && EQ_16( idchan, 0 ) ) || ( EQ_16( noise_gen_mode, TCX10_IN_0_TCX20_IN_1 ) && EQ_16( idchan, 1 ) ) ) ) + { + /* current channel is TCX20 -> generate noise for "full-length" spectrum */ + + FOR( i = 0; i < max_noise_line; i++ ) + { + *rnd = own_random( rnd ); // Q0 + *rnd_c = own_random( rnd_c ); + + move16(); + move16(); + + concealment_noise[i] = Mpy_32_32( L_add( L_shr( L_mult( c_inv, *rnd ), 1 ), L_shr( L_mult( c, *rnd_c ), 1 ) ), noise_shape_buffer[i] ); // Q31 - *concealment_noise_exp + move32(); + IF( concealment_noise[i] != 0 ) + { + hTonalMDCTConc->curr_noise_nrg = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->curr_noise_nrg, hTonalMDCTConc->curr_noise_nrg_exp, Mpy_32_32( concealment_noise[i], concealment_noise[i] ), shl( *concealment_noise_exp, 1 ), &temp_e ); // Q31-temp_e + } + hTonalMDCTConc->curr_noise_nrg_exp = temp_e; + move16(); + } + } + ELSE /* ( ( noise_gen_mode == TCX10_IN_0_TCX20_IN_1 && idchan == 0 ) || ( noise_gen_mode == TCX20_IN_0_TCX10_IN_1 && idchan == 1 ) ) */ + { + /* current channel is TCX10 and the other is TCX20 -> generate noise for "half-length" spectrum, but "increment" mid seed twice, to have the same seed in mid as the other (TCX20) channel for next frame */ + FOR( i = 0; i < max_noise_line; i++ ) + { + *rnd = own_random( rnd ); // Q0 + *rnd_c = own_random( rnd_c ); // Q0 + move16(); + move16(); + + concealment_noise[i] = Mpy_32_32( L_add( L_shr( L_mult( c_inv, *rnd ), 1 ), L_shr( L_mult( c, *rnd_c ), 1 ) ), noise_shape_buffer[i] ); + move32(); + IF( concealment_noise[i] != 0 ) + { + hTonalMDCTConc->curr_noise_nrg = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->curr_noise_nrg, hTonalMDCTConc->curr_noise_nrg_exp, Mpy_32_32( concealment_noise[i], concealment_noise[i] ), shl( *concealment_noise_exp, 1 ), &temp_e ); // Q31-temp_e + } + hTonalMDCTConc->curr_noise_nrg_exp = temp_e; + move16(); + + *rnd_c = own_random( rnd_c ); + move16(); + } + } + + IF( st->tonal_mdct_plc_active ) + { + FOR( i = crossOverFreq; i < s_max( crossOverFreq, hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ); ++i ) + { + concealment_noise[i] = 0; + move32(); + } + } + + /* restore common seed + - after finishing the first channel + - after a first subframe if the current channel is TCX10 */ + + test(); + test(); + test(); + test(); + test(); + IF( ( EQ_16( idchan, 0 ) && ( EQ_16( core, TCX_20 ) || ( EQ_16( core, TCX_10 ) && EQ_16( subframe_idx, 1 ) ) ) ) || ( EQ_16( core, TCX_10 ) && EQ_16( subframe_idx, 0 ) ) ) + { + *rnd_c = save_rnd_c; + move16(); + } + + st->seed_tcx_plc = *rnd; + move16(); + + pop_wmops(); + + return; +} + + +void TonalMdctConceal_whiten_noise_shape_ivas_fx( + Decoder_State *st, + const Word16 L_frame, + const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE whitening_mode ) +{ + Word16 inc, start_idx, stop_idx, i; + Word32 *noiseLevelPtr, *scfs_bg, *scfs_for_shaping; + Word16 noiseLevelPtr_exp; + HANDLE_FD_CNG_COM hFdCngCom; + Word32 whitenend_noise_shape[L_FRAME16k]; + Word16 q_wns; + Word32 scfs_int[FDNS_NPTS]; + const PsychoacousticParameters *psychParams; + + push_wmops( "apply_sns_on_noise_shape" ); + + scfs_bg = &st->hTonalMDCTConc->scaleFactorsBackground_fx[0]; + psychParams = st->hTonalMDCTConc->psychParams; + hFdCngCom = st->hFdCngDec->hFdCngCom; + +#ifdef MSAN_FIX + set32_fx( whitenend_noise_shape, 0, L_FRAME16k ); +#endif + + IF( EQ_32( whitening_mode, ON_FIRST_LOST_FRAME ) ) + { + IF( GT_16( st->core, TCX_20_CORE ) ) + { + inc = 2; + move16(); + } + ELSE + { + inc = 1; + move16(); + } + } + ELSE + { + IF( GT_16( st->last_core, TCX_20_CORE ) ) + { + inc = 2; + move16(); + } + ELSE + { + inc = 1; + move16(); + } + } + start_idx = shr( hFdCngCom->startBand, sub( inc, 1 ) ); + stop_idx = shr( L_frame, sub( inc, 1 ) ); + noiseLevelPtr = hFdCngCom->cngNoiseLevel; + noiseLevelPtr_exp = hFdCngCom->cngNoiseLevelExp; + move16(); + + FOR( Word16 j = start_idx; j < stop_idx; j++ ) + { + whitenend_noise_shape[j] = L_shr( *noiseLevelPtr, 3 ); + move32(); + noiseLevelPtr += inc; + } + + IF( EQ_32( whitening_mode, ON_FIRST_LOST_FRAME ) ) + { + Word32 scf[SNS_NPTS]; + + sns_compute_scf_fx( whitenend_noise_shape, psychParams, L_frame, scf, sub( sub( 31, noiseLevelPtr_exp ), 3 ) ); + + sns_interpolate_scalefactors_fx( scfs_int, scf, ENC ); + sns_interpolate_scalefactors_fx( scfs_bg, scf, DEC ); + + scfs_for_shaping = &scfs_int[0]; // Q16 + } + ELSE /* whitening_mode == ON_FIRST_GOOD_FRAME */ + { + scfs_for_shaping = &scfs_bg[0]; // Q16 + } + + IF( sum32_sat( scfs_for_shaping, FDNS_NPTS ) > 0 ) + { + q_wns = sub( sub( 31, noiseLevelPtr_exp ), 3 ); + sns_shape_spectrum_fx( whitenend_noise_shape, &q_wns, psychParams, scfs_for_shaping, Q16, L_frame, NULL ); + + IF( GT_16( add( q_wns, 1 ), sub( 31, hFdCngCom->cngNoiseLevelExp ) ) ) + { + FOR( i = 0; i < sub( stop_idx, start_idx ); i++ ) + { + hFdCngCom->cngNoiseLevel[i] = L_shr( whitenend_noise_shape[start_idx + i], sub( add( q_wns, hFdCngCom->cngNoiseLevelExp ), 30 ) ); //(q_wns + 1) + move32(); + } + } + ELSE + { + Copy32( whitenend_noise_shape + start_idx, hFdCngCom->cngNoiseLevel, sub( stop_idx, start_idx ) ); + + scale_sig32( hFdCngCom->cngNoiseLevel + sub( stop_idx, start_idx ), sub( FFTCLDFBLEN, sub( stop_idx, start_idx ) ), sub( add( q_wns, hFdCngCom->cngNoiseLevelExp ), 30 ) ); + + hFdCngCom->cngNoiseLevelExp = sub( Q30, q_wns ); // Exponent = 31 - (q_wns + 1) + move16(); + } + } + ELSE + { + set32_fx( hFdCngCom->cngNoiseLevel, 0, sub( stop_idx, start_idx ) ); + } + + pop_wmops(); +} + + #ifdef IVAS_CODE_CNG_FIX185_PLC_FADEOUT void TonalMdctConceal_create_concealment_noise( float concealment_noise[L_FRAME48k], -- GitLab From 5424115f277ce702a36ade2f97f07029b2c543a6 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 4 Mar 2025 20:44:33 +0530 Subject: [PATCH 2/2] Clang formatting --- lib_dec/ari_dec_fx.c | 1 - lib_dec/arith_coder_dec_fx.c | 1 - lib_dec/bass_psfilter_fx.c | 10 +++++----- lib_dec/core_dec_init_fx.c | 1 - lib_dec/core_switching_dec_fx.c | 2 +- lib_dec/dec_prm_fx.c | 1 - lib_dec/dec_tcx_fx.c | 1 - lib_dec/fd_cng_dec_fx.c | 8 ++++---- lib_dec/swb_bwe_dec_fx.c | 1 - 9 files changed, 10 insertions(+), 16 deletions(-) diff --git a/lib_dec/ari_dec_fx.c b/lib_dec/ari_dec_fx.c index 524f9d121..3aabbdaa5 100644 --- a/lib_dec/ari_dec_fx.c +++ b/lib_dec/ari_dec_fx.c @@ -839,4 +839,3 @@ Word16 ari_decode_14bits_sign_ivas( return bp; } - diff --git a/lib_dec/arith_coder_dec_fx.c b/lib_dec/arith_coder_dec_fx.c index 6df1eb268..e5a1220e0 100644 --- a/lib_dec/arith_coder_dec_fx.c +++ b/lib_dec/arith_coder_dec_fx.c @@ -420,4 +420,3 @@ void tcx_arith_decode_envelope_ivas_fx( return; } - diff --git a/lib_dec/bass_psfilter_fx.c b/lib_dec/bass_psfilter_fx.c index 7d2be2c52..75cabf160 100644 --- a/lib_dec/bass_psfilter_fx.c +++ b/lib_dec/bass_psfilter_fx.c @@ -4,12 +4,12 @@ #include #include -#include "options.h" /* Compilation switches */ -#include "prot_fx.h" /* Function prototypes */ +#include "options.h" /* Compilation switches */ +#include "prot_fx.h" /* Function prototypes */ #include "ivas_prot_fx.h" /* Function prototypes */ -#include "cnst.h" /* Common constants */ -#include "rom_com.h" /* Static table prototypes */ -#include "rom_dec.h" /* Static table prototypes */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Static table prototypes */ +#include "rom_dec.h" /* Static table prototypes */ #include "basop_util.h" /*---------------------------------------------------------------------* diff --git a/lib_dec/core_dec_init_fx.c b/lib_dec/core_dec_init_fx.c index f649772b2..8fefa3bb2 100644 --- a/lib_dec/core_dec_init_fx.c +++ b/lib_dec/core_dec_init_fx.c @@ -2216,4 +2216,3 @@ void reset_tcx_overl_buf_fx( move16(); return; } - diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index caef9485b..52c3e3073 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -3443,4 +3443,4 @@ void ivas_bw_switching_pre_proc_fx( } return; -} \ No newline at end of file +} diff --git a/lib_dec/dec_prm_fx.c b/lib_dec/dec_prm_fx.c index 77fd7d421..3d277807d 100644 --- a/lib_dec/dec_prm_fx.c +++ b/lib_dec/dec_prm_fx.c @@ -2011,4 +2011,3 @@ void getTCXWindowing_ivas_fx( return; } - diff --git a/lib_dec/dec_tcx_fx.c b/lib_dec/dec_tcx_fx.c index 4d97367ef..e71157a1e 100644 --- a/lib_dec/dec_tcx_fx.c +++ b/lib_dec/dec_tcx_fx.c @@ -5302,4 +5302,3 @@ void decoder_tcx_imdct_fx( return; } - diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index f788144fa..70c4760ae 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -20,10 +20,10 @@ #endif -#define CNA_ACT_DN_LARGE_PARTITION 50 /* index of the first larger partition */ -#define ST_PERIODOG_FACT_Q15 29491 /* 0.9 in Q15, short-term filter factor for periodogram */ -#define CNA_ACT_DN_FACT_Q15 22938 /* 0.7 in Q15, downward updating factor for CNA during active frames */ -#define FIRST_CNA_NOISE_UPD_FRAMES 5 /* minimum number of CN initialization frames */ +#define CNA_ACT_DN_LARGE_PARTITION 50 /* index of the first larger partition */ +#define ST_PERIODOG_FACT_Q15 29491 /* 0.9 in Q15, short-term filter factor for periodogram */ +#define CNA_ACT_DN_FACT_Q15 22938 /* 0.7 in Q15, downward updating factor for CNA during active frames */ +#define FIRST_CNA_NOISE_UPD_FRAMES 5 /* minimum number of CN initialization frames */ #define DELTA_MASKING_NOISE_Q15 0 #define LOG_10_BASE_2 1783446566 /* Q29 */ #define GAIN_Q_OFFSET_IVAS_FX 45 diff --git a/lib_dec/swb_bwe_dec_fx.c b/lib_dec/swb_bwe_dec_fx.c index 23c4c3e8a..d15a97821 100644 --- a/lib_dec/swb_bwe_dec_fx.c +++ b/lib_dec/swb_bwe_dec_fx.c @@ -1634,4 +1634,3 @@ void fd_bwe_dec_init_fx( return; } - -- GitLab