diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj
index 3d447fe2196fb9e35f76e8f03b205a6174e55cfc..b3a84779158e9b9ded863e4244d939ace788c2bf 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 cc75944150d8853254cef72ce7bb1881cc39508e..c4e148b89e13b3cf7bff069fd7cad39d85c6892f 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 6a119b365552212f9ae48f4a3e4c760f9d226dac..0000000000000000000000000000000000000000
--- 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 f88927ee50f3d5ee6c7d6a412805ee7e9fe9151e..09bc652be8b7cfbb370f18938ca0ac32632bcb56 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 b45cb5d9c77b2379a1d38cc544eb9ba5a8d42d53..0000000000000000000000000000000000000000
--- 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 3681568f28f46665132a75fefe5aa2ec05ac5bca..3aabbdaa58cbcdda0a7c83d962eb9297c8a8608f 100644
--- a/lib_dec/ari_dec_fx.c
+++ b/lib_dec/ari_dec_fx.c
@@ -551,3 +551,291 @@ 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 93bd8877cf6f23910bb7436b7bb6528b7f0e54ef..0000000000000000000000000000000000000000
--- 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 4a18f64f9af7a503a0e66756353605e7e5d03b07..e5a1220e046e3f3a1c672267585dc01c694634ca 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,207 @@ 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 478a814744be7f47d9ae8df548e54b14d10d289c..0000000000000000000000000000000000000000
--- 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 c11e30c93af6770d9f053cd177f56482d43484d1..75cabf160042c12159d477ea02f447c97ef37456 100644
--- a/lib_dec/bass_psfilter_fx.c
+++ b/lib_dec/bass_psfilter_fx.c
@@ -4,11 +4,12 @@
#include
#include
-#include "options.h" /* Compilation switches */
-#include "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 "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 "basop_util.h"
/*---------------------------------------------------------------------*
@@ -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 37c397bbf8c4ba8044d86fd7d321d3f04956186e..0000000000000000000000000000000000000000
--- 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 671dbfd2ca520671ad8ab10abb004f32f8b055f2..8fefa3bb20964acf31e8bae508a124706225c146 100644
--- a/lib_dec/core_dec_init_fx.c
+++ b/lib_dec/core_dec_init_fx.c
@@ -2191,3 +2191,28 @@ 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 aa04a70cb683917ced3a224958d9fba3447b8f1d..0000000000000000000000000000000000000000
--- 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 d654b3af4e101256656bdb87382d74766f4afca6..52c3e3073ae1895ed155d5ce7aee597dc8f2c98d 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;
+}
diff --git a/lib_dec/dec_prm.c b/lib_dec/dec_prm.c
deleted file mode 100644
index 7b4567f7ad8bb192b6f6fa17cb60378fb9ea499e..0000000000000000000000000000000000000000
--- 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 73edd3b3b3c98d0a0018f9e206153a54254a3ec3..3d277807d2fed95764ba8e3c4992662fd26eac4b 100644
--- a/lib_dec/dec_prm_fx.c
+++ b/lib_dec/dec_prm_fx.c
@@ -1742,3 +1742,272 @@ 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 aca84d9d9cb01237ba9c9d644a876986d3d6335e..0000000000000000000000000000000000000000
--- 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 a0556437dbdba05954c2ae8cef80c71761abf197..e71157a1e8ccaba942b7c77054a21a3bd7163856 100644
--- a/lib_dec/dec_tcx_fx.c
+++ b/lib_dec/dec_tcx_fx.c
@@ -4856,3 +4856,449 @@ 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 dd3adb2470ab33c3b0d5da3f21bad0e8c9cb366b..0000000000000000000000000000000000000000
--- 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 8a902448fa47e351d93bf6e396415d7370343a56..70c4760aee16ce3b925899f7fbac5d69b5c25f21 100644
--- a/lib_dec/fd_cng_dec_fx.c
+++ b/lib_dec/fd_cng_dec_fx.c
@@ -20,10 +20,18 @@
#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
+#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 2b80913050f8377570fb2b62377a6b71cdbb3d5a..0000000000000000000000000000000000000000
--- 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 a9677411300ed661f55a50255bf17d0d7b3cde10..caa164df9414325db1f74fb63bd19ce5c4179d74 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 459dcc4d4da1dfa37657d24fee0af4979963ad82..5a948bdfa0b7a23f23536a69a0699e54e17920d8 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 0d9ee27107cedfdf97ef477e77d8c0882d2917ca..0000000000000000000000000000000000000000
--- 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 6b80108a81b97b38ca26bbf389e38af6a4e5da4d..0000000000000000000000000000000000000000
--- 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 9552bbf2fa11c6ef5c282bdc6548a5185aa606b1..d15a9782166e77f80a9dd1e16c116197dd6d323f 100644
--- a/lib_dec/swb_bwe_dec_fx.c
+++ b/lib_dec/swb_bwe_dec_fx.c
@@ -1266,3 +1266,371 @@ 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 80dfad505c3822d91ca395323cbeb6a8b7e00e8e..0000000000000000000000000000000000000000
--- 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 28ac016711566fe8063b8cbd586dd718ab271df4..a37ebf9d9cc4ef2aa10fd94cb2775898bf3b2955 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 6a74d3b8731bba95b0058ef635784abee6ed6311..0000000000000000000000000000000000000000
--- 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 a4aa23e7fbf69a6ca9283e8be81993209c0c8edb..3cf5f51f306df2b66800c6a79d37440a573e33e9 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],