diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj
index 7a2aa8a7f66bcdd6ec2164f382b709a8b43cc925..91401ee2eee0f92a849121f0e223522948614061 100644
--- a/Workspace_msvc/lib_com.vcxproj
+++ b/Workspace_msvc/lib_com.vcxproj
@@ -136,14 +136,14 @@
-
-
+
+
-
+
-
-
-
+
+
+
@@ -153,21 +153,19 @@
-
-
-
-
+
+
+
+
-
-
-
-
+
+
@@ -175,7 +173,6 @@
-
@@ -183,20 +180,18 @@
-
-
-
+
-
-
-
+
+
+
@@ -207,7 +202,7 @@
-
+
@@ -235,8 +230,8 @@
-
-
+
+
@@ -248,9 +243,7 @@
-
-
@@ -258,7 +251,6 @@
-
@@ -283,9 +275,9 @@
-
+
-
+
@@ -297,7 +289,6 @@
-
diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters
index 89b47a3fcf9b04744c7ba3e9fd1cfec159c27ca9..3b781aa40a612fac63d7840abe2371ba83d72a7b 100644
--- a/Workspace_msvc/lib_com.vcxproj.filters
+++ b/Workspace_msvc/lib_com.vcxproj.filters
@@ -115,9 +115,6 @@
common_all_c
-
- common_all_c
-
common_all_c
@@ -133,9 +130,6 @@
common_all_c
-
- common_all_c
-
common_all_c
@@ -301,21 +295,9 @@
common_all_c
-
- common_all_c
-
common_all_c
-
- common_all_c
-
-
- common_all_c
-
-
- common_all_c
-
common_all_c
@@ -325,30 +307,6 @@
common_all_c
-
- common_all_c
-
-
- common_all_c
-
-
- common_all_c
-
-
- common_all_c
-
-
- common_all_c
-
-
- common_all_c
-
-
- common_all_c
-
-
- common_all_c
-
common_all_c
@@ -361,33 +319,12 @@
common_all_c
-
- common_all_c
-
common_all_c
common_all_c
-
- common_all_c
-
-
- common_all_c
-
-
- common_all_c
-
-
- common_all_c
-
-
- common_all_c
-
-
- common_all_c
-
common_ivas_c
@@ -403,45 +340,21 @@
common_ivas_c
-
- common_all_c
-
-
- common_all_c
-
common_all_c
-
- common_all_c
-
-
- common_all_c
-
common_all_c
-
- common_all_c
-
common_all_c
common_all_c
-
- common_all_c
-
-
- common_all_c
-
common_all_c
-
- common_all_c
-
common_all_c
@@ -481,9 +394,6 @@
common_ivas_c
-
- common_ivas_c
-
common_ivas_c
@@ -535,6 +445,69 @@
common_ivas_c
+
+ common_all_c
+
+
+ common_all_c
+
+
+ common_all_c
+
+
+ common_all_c
+
+
+ common_all_c
+
+
+ common_all_c
+
+
+ common_all_c
+
+
+ common_all_c
+
+
+ common_all_c
+
+
+ common_all_c
+
+
+ common_all_c
+
+
+ common_all_c
+
+
+ common_all_c
+
+
+ common_all_c
+
+
+ common_all_c
+
+
+ common_all_c
+
+
+ common_ivas_c
+
+
+ common_all_c
+
+
+ common_all_c
+
+
+ common_all_c
+
+
+ common_all_c
+
diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj
index 12f77b3461b2cd30cd3cf9645c8e423c797c86d4..1ae8c4d9313f4bb22ebde33891db01a72ddcdf78 100644
--- a/Workspace_msvc/lib_dec.vcxproj
+++ b/Workspace_msvc/lib_dec.vcxproj
@@ -144,7 +144,7 @@
-
+
@@ -215,7 +215,6 @@
-
@@ -245,7 +244,7 @@
-
+
@@ -254,8 +253,7 @@
-
-
+
@@ -270,13 +268,13 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -293,7 +291,7 @@
-
+
diff --git a/Workspace_msvc/lib_dec.vcxproj.filters b/Workspace_msvc/lib_dec.vcxproj.filters
index 25079058ca86d0ba17ed45fb351d4ddfa144612a..170eada9ad30e017f4f3652be5ee6f08f2080937 100644
--- a/Workspace_msvc/lib_dec.vcxproj.filters
+++ b/Workspace_msvc/lib_dec.vcxproj.filters
@@ -74,12 +74,6 @@
decoder_ivas_c
-
- decoder_ivas_c
-
-
- decoder_ivas_c
-
decoder_ivas_c
@@ -89,9 +83,6 @@
decoder_ivas_c
-
- decoder_ivas_c
-
decoder_ivas_c
@@ -101,12 +92,6 @@
decoder_ivas_c
-
- decoder_ivas_c
-
-
- decoder_ivas_c
-
decoder_ivas_c
@@ -122,9 +107,6 @@
decoder_all_c
-
- decoder_all_c
-
decoder_all_c
@@ -263,27 +245,6 @@
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
@@ -323,9 +284,6 @@
decoder_all_c
-
- decoder_all_c
-
decoder_all_c
@@ -515,18 +473,45 @@
decoder_all_c
+
+ decoder_all_c
+
+
+ decoder_ivas_c
+
+
+ decoder_all_c
+
+
+ decoder_ivas_c
+
+
+ decoder_ivas_c
+
+
+ decoder_all_c
+
+
+ decoder_all_c
+
+
+ decoder_all_c
+
+
+ decoder_all_c
+
+
+ decoder_all_c
+
+
+ decoder_all_c
+
+
+ decoder_all_c
+
-
- decoder_h
-
-
- decoder_h
-
-
- decoder_h
-
decoder_h
@@ -554,6 +539,15 @@
decoder_h
+
+ decoder_h
+
+
+ decoder_h
+
+
+ decoder_h
+
diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj
index 86dcef90541be79286704dffc2160960a9846d2c..af16efedf05580910fc85d674935bdf647c43421 100644
--- a/Workspace_msvc/lib_enc.vcxproj
+++ b/Workspace_msvc/lib_enc.vcxproj
@@ -239,7 +239,7 @@
-
+
@@ -274,11 +274,10 @@
-
+
-
@@ -318,7 +317,7 @@
-
+
diff --git a/Workspace_msvc/lib_enc.vcxproj.filters b/Workspace_msvc/lib_enc.vcxproj.filters
index 8990971637ef90b8f3a11fbd672278a29d3f89da..e8f429f4914dace1f3d9efa63afe65a713d5bf25 100644
--- a/Workspace_msvc/lib_enc.vcxproj.filters
+++ b/Workspace_msvc/lib_enc.vcxproj.filters
@@ -1,7 +1,6 @@
-
encoder_evs_c
@@ -152,9 +151,6 @@
encoder_all_c
-
- encoder_all_c
-
encoder_all_c
@@ -287,9 +283,6 @@
encoder_all_c
-
- encoder_all_c
-
encoder_all_c
@@ -347,9 +340,6 @@
encoder_all_c
-
- encoder_all_c
-
encoder_all_c
@@ -602,6 +592,13 @@
encoder_ivas_c
+
+ encoder_all_c
+
+
+
+ encoder_all_c
+
diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj
index e47858ae380f169b2bf53e720d1c3abf23c29224..0a00f9331a9fe92ff4a71bfea4a4798059aa2b9b 100644
--- a/Workspace_msvc/lib_rend.vcxproj
+++ b/Workspace_msvc/lib_rend.vcxproj
@@ -142,7 +142,6 @@
-
@@ -159,7 +158,7 @@
-
+
@@ -176,7 +175,7 @@
-
+
diff --git a/Workspace_msvc/lib_rend.vcxproj.filters b/Workspace_msvc/lib_rend.vcxproj.filters
index 5c4a4901111136b5ce1c1406701ffe10e156b86b..820a5c044354c8b35ceabc1855256052b4915b24 100644
--- a/Workspace_msvc/lib_rend.vcxproj.filters
+++ b/Workspace_msvc/lib_rend.vcxproj.filters
@@ -1,13 +1,6 @@
-
-
- rend_c
-
-
- rend_c
-
rend_c
@@ -122,6 +115,10 @@
rend_c
+
+ rend_c
+
+
diff --git a/lib_com/cldfb_evs.c b/lib_com/cldfb_evs_fx.c
similarity index 100%
rename from lib_com/cldfb_evs.c
rename to lib_com/cldfb_evs_fx.c
diff --git a/lib_com/cldfb.c b/lib_com/cldfb_fx.c
similarity index 100%
rename from lib_com/cldfb.c
rename to lib_com/cldfb_fx.c
diff --git a/lib_com/codec_tcx_common.c b/lib_com/codec_tcx_common_fx.c
similarity index 100%
rename from lib_com/codec_tcx_common.c
rename to lib_com/codec_tcx_common_fx.c
diff --git a/lib_com/core_com_config.c b/lib_com/core_com_config_fx.c
similarity index 100%
rename from lib_com/core_com_config.c
rename to lib_com/core_com_config_fx.c
diff --git a/lib_com/deemph.c b/lib_com/deemph_fx.c
similarity index 100%
rename from lib_com/deemph.c
rename to lib_com/deemph_fx.c
diff --git a/lib_com/delay_comp.c b/lib_com/delay_comp_fx.c
similarity index 100%
rename from lib_com/delay_comp.c
rename to lib_com/delay_comp_fx.c
diff --git a/lib_com/enr_1_az.c b/lib_com/enr_1_az_fx.c
similarity index 100%
rename from lib_com/enr_1_az.c
rename to lib_com/enr_1_az_fx.c
diff --git a/lib_com/env_adj.c b/lib_com/env_adj_fx.c
similarity index 100%
rename from lib_com/env_adj.c
rename to lib_com/env_adj_fx.c
diff --git a/lib_com/env_stab.c b/lib_com/env_stab_fx.c
similarity index 100%
rename from lib_com/env_stab.c
rename to lib_com/env_stab_fx.c
diff --git a/lib_com/env_stab_trans.c b/lib_com/env_stab_trans_fx.c
similarity index 100%
rename from lib_com/env_stab_trans.c
rename to lib_com/env_stab_trans_fx.c
diff --git a/lib_com/fft.c b/lib_com/fft.c
deleted file mode 100644
index e262f3909f179ea67b91c160866b1f62cd2b411a..0000000000000000000000000000000000000000
--- a/lib_com/fft.c
+++ /dev/null
@@ -1,366 +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 "cnst.h"
-#include "prot_fx.h"
-#include "rom_com.h"
-#include "wmc_auto.h"
-
-#ifdef _MSC_VER
-#pragma warning( disable : 4310 )
-#endif
-
-/*-----------------------------------------------------------------*
- * Low-complexity implementation of FFT
- *-----------------------------------------------------------------*/
-
-#define WMC_TOOL_SKIP
-
-#define SHC( x ) ( (Word16) x )
-#define FFTC( x ) WORD322WORD16( (Word32) x )
-
-#define C81_FX ( FFTC( 0x5a82799a ) ) /* FL2WORD32( 7.071067811865475e-1) */
-#define C82_FX ( FFTC( 0xa57d8666 ) ) /* FL2WORD32(-7.071067811865475e-1) */
-
-#define cplxMpy4_8_0( re, im, a, b, c, d ) \
- re = L_shr( L_sub( Mpy_32_16_1( a, c ), Mpy_32_16_1( b, d ) ), 1 ); \
- im = L_shr( L_add( Mpy_32_16_1( a, d ), Mpy_32_16_1( b, c ) ), 1 );
-
-#define cplxMpy4_8_1( re, im, a, b ) \
- re = L_shr( a, 1 ); \
- im = L_shr( b, 1 );
-
-
-/**
- * \brief Twiddle factors are unscaled
- */
-/*-----------------------------------------------------------------*
- * BASOP_fft8()
- *
- * Function performs a complex 8-point FFT
- * The FFT is performed inplace. The result of the FFT
- * is scaled by SCALEFACTOR8 bits.
- *
- * WOPS with 32x16 bit multiplications: 108 cycles
- *-----------------------------------------------------------------*/
-
-static void BASOP_fft8(
- Word32 *re,
- Word32 *im,
- Word16 s )
-{
- Word32 x00, x01, x02, x03, x04, x05, x06, x07;
- Word32 x08, x09, x10, x11, x12, x13, x14, x15;
- Word32 t00, t01, t02, t03, t04, t05, t06, t07;
- Word32 t08, t09, t10, t11, t12, t13, t14, t15;
- Word32 s00, s01, s02, s03, s04, s05, s06, s07;
- Word32 s08, s09, s10, s11, s12, s13, s14, s15;
-
-
- /* Pre-additions */
-
- x00 = L_shr( re[s * 0], SCALEFACTOR8 );
- x01 = L_shr( im[s * 0], SCALEFACTOR8 );
- x02 = L_shr( re[s * 1], SCALEFACTOR8 );
- x03 = L_shr( im[s * 1], SCALEFACTOR8 );
- x04 = L_shr( re[s * 2], SCALEFACTOR8 );
- x05 = L_shr( im[s * 2], SCALEFACTOR8 );
- x06 = L_shr( re[s * 3], SCALEFACTOR8 );
- x07 = L_shr( im[s * 3], SCALEFACTOR8 );
- x08 = L_shr( re[s * 4], SCALEFACTOR8 );
- x09 = L_shr( im[s * 4], SCALEFACTOR8 );
- x10 = L_shr( re[s * 5], SCALEFACTOR8 );
- x11 = L_shr( im[s * 5], SCALEFACTOR8 );
- x12 = L_shr( re[s * 6], SCALEFACTOR8 );
- x13 = L_shr( im[s * 6], SCALEFACTOR8 );
- x14 = L_shr( re[s * 7], SCALEFACTOR8 );
- x15 = L_shr( im[s * 7], SCALEFACTOR8 );
-
- t00 = L_add( x00, x08 );
- t02 = L_sub( x00, x08 );
- t01 = L_add( x01, x09 );
- t03 = L_sub( x01, x09 );
- t04 = L_add( x02, x10 );
- t06 = L_sub( x02, x10 );
- t05 = L_add( x03, x11 );
- t07 = L_sub( x03, x11 );
- t08 = L_add( x04, x12 );
- t10 = L_sub( x04, x12 );
- t09 = L_add( x05, x13 );
- t11 = L_sub( x05, x13 );
- t12 = L_add( x06, x14 );
- t14 = L_sub( x06, x14 );
- t13 = L_add( x07, x15 );
- t15 = L_sub( x07, x15 );
-
- /* Pre-additions and core multiplications */
-
- s00 = L_add( t00, t08 );
- s04 = L_sub( t00, t08 );
- s01 = L_add( t01, t09 );
- s05 = L_sub( t01, t09 );
- s08 = L_sub( t02, t11 );
- s10 = L_add( t02, t11 );
- s09 = L_add( t03, t10 );
- s11 = L_sub( t03, t10 );
- s02 = L_add( t04, t12 );
- s07 = L_sub( t04, t12 );
- s03 = L_add( t05, t13 );
- s06 = L_sub( t13, t05 );
-
- t01 = L_add( t06, t14 );
- t02 = L_sub( t06, t14 );
- t00 = L_add( t07, t15 );
- t03 = L_sub( t07, t15 );
-
- s12 = Mpy_32_16_1( L_add( t00, t02 ), C81_FX );
- s14 = Mpy_32_16_1( L_sub( t00, t02 ), C81_FX );
- s13 = Mpy_32_16_1( L_sub( t03, t01 ), C81_FX );
- s15 = Mpy_32_16_1( L_add( t01, t03 ), C82_FX );
-
- /* Post-additions */
-
- re[s * 0] = L_add( s00, s02 );
- move32();
- re[s * 4] = L_sub( s00, s02 );
- move32();
- im[s * 0] = L_add( s01, s03 );
- move32();
- im[s * 4] = L_sub( s01, s03 );
- move32();
- re[s * 2] = L_sub( s04, s06 );
- move32();
- re[s * 6] = L_add( s04, s06 );
- move32();
- im[s * 2] = L_sub( s05, s07 );
- move32();
- im[s * 6] = L_add( s05, s07 );
- move32();
- re[i_mult( s, 3 )] = L_add( s08, s14 );
- move32();
- re[i_mult( s, 7 )] = L_sub( s08, s14 );
- move32();
- im[i_mult( s, 3 )] = L_add( s09, s15 );
- move32();
- im[i_mult( s, 7 )] = L_sub( s09, s15 );
- move32();
- re[s * 1] = L_add( s10, s12 );
- move32();
- re[i_mult( s, 5 )] = L_sub( s10, s12 );
- move32();
- im[s * 1] = L_add( s11, s13 );
- move32();
- im[i_mult( s, 5 )] = L_sub( s11, s13 );
- move32();
-
- return;
-}
-
-
-/*-----------------------------------------------------------------*
- * fftN2()
- *
- * Combined FFT
- *-----------------------------------------------------------------*/
-
-static void BASOP_fftN2(
- Word32 *re, /* i/o: real part */
- Word32 *im, /* i/o: imag part */
- const Word16 *W, /* i : rotation factor */
- Word16 dim1, /* i : length of fft1 */
- Word16 dim2, /* i : length of fft2 */
- Word16 sx, /* i : stride real and imag part */
- Word16 sc, /* i : stride phase rotation coefficients */
- Word32 *x, /* tmp: 32-bit workbuffer */
- Word16 Woff /* i : offset for addressing the rotation vector table */
-)
-{
- Word16 i, j;
- Word32 x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10, x11, x12, x13, x14, x15;
- Word32 t00, t01, t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t12, t13, t14, t15;
- Word32 s00, s01, s02, s03, s04, s05, s06, s07, s08, s09, s10, s11, s12, s13, s14, s15;
-
- FOR( i = 0; i < dim2; i++ )
- {
- FOR( j = 0; j < dim1; j++ )
- {
- x[2 * i * dim1 + 2 * j] = re[sx * i + sx * j * dim2];
- move32();
- x[2 * i * dim1 + 2 * j + 1] = im[sx * i + sx * j * dim2];
- move32();
- }
- }
-
- /* dim1 == 8 */
- FOR( i = 0; i < dim2; i++ )
- {
- BASOP_fft8( &x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2 );
- }
-
- /* dim2 == 8 */
- FOR( i = 0; i < dim1; i++ )
- {
- cplxMpy4_8_1( x00, x01, x[2 * i + 2 * 0 * dim1], x[2 * i + 2 * 0 * dim1 + 1] );
-
- IF( i == 0 )
- {
- cplxMpy4_8_1( x02, x03, x[add( shl( i, 1 ), i_mult( 2 * 1, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 1, dim1 ) ), 1 )] );
- cplxMpy4_8_1( x04, x05, x[add( shl( i, 1 ), i_mult( 2 * 2, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 2, dim1 ) ), 1 )] );
- cplxMpy4_8_1( x06, x07, x[add( shl( i, 1 ), i_mult( 2 * 3, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 3, dim1 ) ), 1 )] );
- cplxMpy4_8_1( x08, x09, x[add( shl( i, 1 ), i_mult( 2 * 4, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 4, dim1 ) ), 1 )] );
- cplxMpy4_8_1( x10, x11, x[add( shl( i, 1 ), i_mult( 2 * 5, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 5, dim1 ) ), 1 )] );
- cplxMpy4_8_1( x12, x13, x[add( shl( i, 1 ), i_mult( 2 * 6, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 6, dim1 ) ), 1 )] );
- cplxMpy4_8_1( x14, x15, x[add( shl( i, 1 ), i_mult( 2 * 7, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 7, dim1 ) ), 1 )] );
- }
- ELSE
- {
- cplxMpy4_8_0( x02, x03, x[add( shl( i, 1 ), i_mult( 2 * 1, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 1, dim1 ) ), 1 )], W[sub( add( i_mult( sc, i ), i_mult( sc, i_mult( 1, dim1 ) ) ), Woff )], W[sub( add( add( i_mult( sc, i ), i_mult( sc, i_mult( 1, dim1 ) ) ), 1 ), Woff )] );
- cplxMpy4_8_0( x04, x05, x[add( shl( i, 1 ), i_mult( 2 * 2, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 2, dim1 ) ), 1 )], W[sub( add( i_mult( sc, i ), i_mult( sc, i_mult( 2, dim1 ) ) ), Woff )], W[sub( add( add( i_mult( sc, i ), i_mult( sc, i_mult( 2, dim1 ) ) ), 1 ), Woff )] );
- cplxMpy4_8_0( x06, x07, x[add( shl( i, 1 ), i_mult( 2 * 3, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 3, dim1 ) ), 1 )], W[sub( add( i_mult( sc, i ), i_mult( sc, i_mult( 3, dim1 ) ) ), Woff )], W[sub( add( add( i_mult( sc, i ), i_mult( sc, i_mult( 3, dim1 ) ) ), 1 ), Woff )] );
- cplxMpy4_8_0( x08, x09, x[add( shl( i, 1 ), i_mult( 2 * 4, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 4, dim1 ) ), 1 )], W[sub( add( i_mult( sc, i ), i_mult( sc, i_mult( 4, dim1 ) ) ), Woff )], W[sub( add( add( i_mult( sc, i ), i_mult( sc, i_mult( 4, dim1 ) ) ), 1 ), Woff )] );
- cplxMpy4_8_0( x10, x11, x[add( shl( i, 1 ), i_mult( 2 * 5, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 5, dim1 ) ), 1 )], W[sub( add( i_mult( sc, i ), i_mult( sc, i_mult( 5, dim1 ) ) ), Woff )], W[sub( add( add( i_mult( sc, i ), i_mult( sc, i_mult( 5, dim1 ) ) ), 1 ), Woff )] );
- cplxMpy4_8_0( x12, x13, x[add( shl( i, 1 ), i_mult( 2 * 6, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 6, dim1 ) ), 1 )], W[sub( add( i_mult( sc, i ), i_mult( sc, i_mult( 6, dim1 ) ) ), Woff )], W[sub( add( add( i_mult( sc, i ), i_mult( sc, i_mult( 6, dim1 ) ) ), 1 ), Woff )] );
- cplxMpy4_8_0( x14, x15, x[add( shl( i, 1 ), i_mult( 2 * 7, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 7, dim1 ) ), 1 )], W[sub( add( i_mult( sc, i ), i_mult( sc, i_mult( 7, dim1 ) ) ), Woff )], W[sub( add( add( i_mult( sc, i ), i_mult( sc, i_mult( 7, dim1 ) ) ), 1 ), Woff )] );
- }
- t00 = L_shr( L_add( x00, x08 ), SCALEFACTORN2 - 1 );
- t02 = L_shr( L_sub( x00, x08 ), SCALEFACTORN2 - 1 );
- t01 = L_shr( L_add( x01, x09 ), SCALEFACTORN2 - 1 );
- t03 = L_shr( L_sub( x01, x09 ), SCALEFACTORN2 - 1 );
- t04 = L_shr( L_add( x02, x10 ), SCALEFACTORN2 - 1 );
- t06 = L_sub( x02, x10 );
- t05 = L_shr( L_add( x03, x11 ), SCALEFACTORN2 - 1 );
- t07 = L_sub( x03, x11 );
- t08 = L_shr( L_add( x04, x12 ), SCALEFACTORN2 - 1 );
- t10 = L_shr( L_sub( x04, x12 ), SCALEFACTORN2 - 1 );
- t09 = L_shr( L_add( x05, x13 ), SCALEFACTORN2 - 1 );
- t11 = L_shr( L_sub( x05, x13 ), SCALEFACTORN2 - 1 );
- t12 = L_shr( L_add( x06, x14 ), SCALEFACTORN2 - 1 );
- t14 = L_sub( x06, x14 );
- t13 = L_shr( L_add( x07, x15 ), SCALEFACTORN2 - 1 );
- t15 = L_sub( x07, x15 );
-
- s00 = L_add( t00, t08 );
- s04 = L_sub( t00, t08 );
- s01 = L_add( t01, t09 );
- s05 = L_sub( t01, t09 );
- s08 = L_sub( t02, t11 );
- s10 = L_add( t02, t11 );
- s09 = L_add( t03, t10 );
- s11 = L_sub( t03, t10 );
- s02 = L_add( t04, t12 );
- s07 = L_sub( t04, t12 );
- s03 = L_add( t05, t13 );
- s06 = L_sub( t13, t05 );
-
- t01 = L_shr( L_add( t06, t14 ), SCALEFACTORN2 - 1 );
- t02 = L_shr( L_sub( t06, t14 ), SCALEFACTORN2 - 1 );
- t00 = L_shr( L_add( t07, t15 ), SCALEFACTORN2 - 1 );
- t03 = L_shr( L_sub( t07, t15 ), SCALEFACTORN2 - 1 );
-
- s12 = Mpy_32_16_1( L_add( t00, t02 ), C81_FX );
- s14 = Mpy_32_16_1( L_sub( t00, t02 ), C81_FX );
- s13 = Mpy_32_16_1( L_sub( t03, t01 ), C81_FX );
- s15 = Mpy_32_16_1( L_add( t01, t03 ), C82_FX );
-
- re[add( i_mult( sx, i ), i_mult( sx, i_mult( 0, dim1 ) ) )] = L_add( s00, s02 );
- move32();
- im[add( i_mult( sx, i ), i_mult( sx, i_mult( 0, dim1 ) ) )] = L_add( s01, s03 );
- move32();
- re[add( i_mult( sx, i ), i_mult( sx, i_mult( 1, dim1 ) ) )] = L_add( s10, s12 );
- move32();
- im[add( i_mult( sx, i ), i_mult( sx, i_mult( 1, dim1 ) ) )] = L_add( s11, s13 );
- move32();
- re[add( i_mult( sx, i ), i_mult( sx, i_mult( 2, dim1 ) ) )] = L_sub( s04, s06 );
- move32();
- im[add( i_mult( sx, i ), i_mult( sx, i_mult( 2, dim1 ) ) )] = L_sub( s05, s07 );
- move32();
- re[add( i_mult( sx, i ), i_mult( sx, i_mult( 3, dim1 ) ) )] = L_add( s08, s14 );
- move32();
- im[add( i_mult( sx, i ), i_mult( sx, i_mult( 3, dim1 ) ) )] = L_add( s09, s15 );
- move32();
- re[add( i_mult( sx, i ), i_mult( sx, i_mult( 4, dim1 ) ) )] = L_sub( s00, s02 );
- move32();
- im[add( i_mult( sx, i ), i_mult( sx, i_mult( 4, dim1 ) ) )] = L_sub( s01, s03 );
- move32();
- re[add( i_mult( sx, i ), i_mult( sx, i_mult( 5, dim1 ) ) )] = L_sub( s10, s12 );
- move32();
- im[add( i_mult( sx, i ), i_mult( sx, i_mult( 5, dim1 ) ) )] = L_sub( s11, s13 );
- move32();
- re[add( i_mult( sx, i ), i_mult( sx, i_mult( 6, dim1 ) ) )] = L_add( s04, s06 );
- move32();
- im[add( i_mult( sx, i ), i_mult( sx, i_mult( 6, dim1 ) ) )] = L_add( s05, s07 );
- move32();
- re[add( i_mult( sx, i ), i_mult( sx, i_mult( 7, dim1 ) ) )] = L_sub( s08, s14 );
- move32();
- im[add( i_mult( sx, i ), i_mult( sx, i_mult( 7, dim1 ) ) )] = L_sub( s09, s15 );
- move32();
- }
-
- return;
-}
-
-
-/*-----------------------------------------------------------------*
- * BASOP_cfft_ivas()
- *
- * Complex valued FFT
- *-----------------------------------------------------------------*/
-
-void BASOP_cfft_ivas(
- Word32 *re, /* i/o: real part */
- Word32 *im, /* i/o: imag part */
- Word16 s, /* i : stride real and imag part */
- Word16 *scale /* i : scalefactor */
-)
-{
- Word32 x[2 * 64];
-
- /* FFT for len = FDNS_NPTS */
- BASOP_fftN2( re, im, RotVector_256, 8, 8, s, 8, x, 64 );
- s = add( *scale, SCALEFACTOR64 );
-
- *scale = s;
- move16();
-
- return;
-}
-
-
-#undef WMC_TOOL_SKIP
diff --git a/lib_com/fft_fx.c b/lib_com/fft_fx.c
index 5ee5098797c3b57caf6c91e826bcc76dd1fdf850..40c9780148ac85d1a202be1a623309ed24095c1b 100644
--- a/lib_com/fft_fx.c
+++ b/lib_com/fft_fx.c
@@ -44,9 +44,7 @@
#include "options.h"
#include
#include "cnst.h"
-// #include "prot_fx.h"
#include "prot_fx.h"
-//#include "cnst_fx.h"
#include "rom_com.h"
#include "rom_com_fx.h"
#include "wmc_auto.h"
@@ -7555,3 +7553,317 @@ void rfft_fx(
return;
}
+
+
+#define WMC_TOOL_SKIP
+
+#define SHC( x ) ( (Word16) x )
+#define FFTC( x ) WORD322WORD16( (Word32) x )
+
+#define C81_FX ( FFTC( 0x5a82799a ) ) /* FL2WORD32( 7.071067811865475e-1) */
+#define C82_FX ( FFTC( 0xa57d8666 ) ) /* FL2WORD32(-7.071067811865475e-1) */
+
+#define cplxMpy4_8_0( re, im, a, b, c, d ) \
+ re = L_shr( L_sub( Mpy_32_16_1( a, c ), Mpy_32_16_1( b, d ) ), 1 ); \
+ im = L_shr( L_add( Mpy_32_16_1( a, d ), Mpy_32_16_1( b, c ) ), 1 );
+
+#define cplxMpy4_8_1( re, im, a, b ) \
+ re = L_shr( a, 1 ); \
+ im = L_shr( b, 1 );
+
+
+/**
+ * \brief Twiddle factors are unscaled
+ */
+/*-----------------------------------------------------------------*
+ * BASOP_fft8()
+ *
+ * Function performs a complex 8-point FFT
+ * The FFT is performed inplace. The result of the FFT
+ * is scaled by SCALEFACTOR8 bits.
+ *
+ * WOPS with 32x16 bit multiplications: 108 cycles
+ *-----------------------------------------------------------------*/
+
+static void BASOP_fft8(
+ Word32 *re,
+ Word32 *im,
+ Word16 s )
+{
+ Word32 x00, x01, x02, x03, x04, x05, x06, x07;
+ Word32 x08, x09, x10, x11, x12, x13, x14, x15;
+ Word32 t00, t01, t02, t03, t04, t05, t06, t07;
+ Word32 t08, t09, t10, t11, t12, t13, t14, t15;
+ Word32 s00, s01, s02, s03, s04, s05, s06, s07;
+ Word32 s08, s09, s10, s11, s12, s13, s14, s15;
+
+
+ /* Pre-additions */
+
+ x00 = L_shr( re[s * 0], SCALEFACTOR8 );
+ x01 = L_shr( im[s * 0], SCALEFACTOR8 );
+ x02 = L_shr( re[s * 1], SCALEFACTOR8 );
+ x03 = L_shr( im[s * 1], SCALEFACTOR8 );
+ x04 = L_shr( re[s * 2], SCALEFACTOR8 );
+ x05 = L_shr( im[s * 2], SCALEFACTOR8 );
+ x06 = L_shr( re[s * 3], SCALEFACTOR8 );
+ x07 = L_shr( im[s * 3], SCALEFACTOR8 );
+ x08 = L_shr( re[s * 4], SCALEFACTOR8 );
+ x09 = L_shr( im[s * 4], SCALEFACTOR8 );
+ x10 = L_shr( re[s * 5], SCALEFACTOR8 );
+ x11 = L_shr( im[s * 5], SCALEFACTOR8 );
+ x12 = L_shr( re[s * 6], SCALEFACTOR8 );
+ x13 = L_shr( im[s * 6], SCALEFACTOR8 );
+ x14 = L_shr( re[s * 7], SCALEFACTOR8 );
+ x15 = L_shr( im[s * 7], SCALEFACTOR8 );
+
+ t00 = L_add( x00, x08 );
+ t02 = L_sub( x00, x08 );
+ t01 = L_add( x01, x09 );
+ t03 = L_sub( x01, x09 );
+ t04 = L_add( x02, x10 );
+ t06 = L_sub( x02, x10 );
+ t05 = L_add( x03, x11 );
+ t07 = L_sub( x03, x11 );
+ t08 = L_add( x04, x12 );
+ t10 = L_sub( x04, x12 );
+ t09 = L_add( x05, x13 );
+ t11 = L_sub( x05, x13 );
+ t12 = L_add( x06, x14 );
+ t14 = L_sub( x06, x14 );
+ t13 = L_add( x07, x15 );
+ t15 = L_sub( x07, x15 );
+
+ /* Pre-additions and core multiplications */
+
+ s00 = L_add( t00, t08 );
+ s04 = L_sub( t00, t08 );
+ s01 = L_add( t01, t09 );
+ s05 = L_sub( t01, t09 );
+ s08 = L_sub( t02, t11 );
+ s10 = L_add( t02, t11 );
+ s09 = L_add( t03, t10 );
+ s11 = L_sub( t03, t10 );
+ s02 = L_add( t04, t12 );
+ s07 = L_sub( t04, t12 );
+ s03 = L_add( t05, t13 );
+ s06 = L_sub( t13, t05 );
+
+ t01 = L_add( t06, t14 );
+ t02 = L_sub( t06, t14 );
+ t00 = L_add( t07, t15 );
+ t03 = L_sub( t07, t15 );
+
+ s12 = Mpy_32_16_1( L_add( t00, t02 ), C81_FX );
+ s14 = Mpy_32_16_1( L_sub( t00, t02 ), C81_FX );
+ s13 = Mpy_32_16_1( L_sub( t03, t01 ), C81_FX );
+ s15 = Mpy_32_16_1( L_add( t01, t03 ), C82_FX );
+
+ /* Post-additions */
+
+ re[s * 0] = L_add( s00, s02 );
+ move32();
+ re[s * 4] = L_sub( s00, s02 );
+ move32();
+ im[s * 0] = L_add( s01, s03 );
+ move32();
+ im[s * 4] = L_sub( s01, s03 );
+ move32();
+ re[s * 2] = L_sub( s04, s06 );
+ move32();
+ re[s * 6] = L_add( s04, s06 );
+ move32();
+ im[s * 2] = L_sub( s05, s07 );
+ move32();
+ im[s * 6] = L_add( s05, s07 );
+ move32();
+ re[i_mult( s, 3 )] = L_add( s08, s14 );
+ move32();
+ re[i_mult( s, 7 )] = L_sub( s08, s14 );
+ move32();
+ im[i_mult( s, 3 )] = L_add( s09, s15 );
+ move32();
+ im[i_mult( s, 7 )] = L_sub( s09, s15 );
+ move32();
+ re[s * 1] = L_add( s10, s12 );
+ move32();
+ re[i_mult( s, 5 )] = L_sub( s10, s12 );
+ move32();
+ im[s * 1] = L_add( s11, s13 );
+ move32();
+ im[i_mult( s, 5 )] = L_sub( s11, s13 );
+ move32();
+
+ return;
+}
+
+
+/*-----------------------------------------------------------------*
+ * fftN2()
+ *
+ * Combined FFT
+ *-----------------------------------------------------------------*/
+
+static void BASOP_fftN2(
+ Word32 *re, /* i/o: real part */
+ Word32 *im, /* i/o: imag part */
+ const Word16 *W, /* i : rotation factor */
+ Word16 dim1, /* i : length of fft1 */
+ Word16 dim2, /* i : length of fft2 */
+ Word16 sx, /* i : stride real and imag part */
+ Word16 sc, /* i : stride phase rotation coefficients */
+ Word32 *x, /* tmp: 32-bit workbuffer */
+ Word16 Woff /* i : offset for addressing the rotation vector table */
+)
+{
+ Word16 i, j;
+ Word32 x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10, x11, x12, x13, x14, x15;
+ Word32 t00, t01, t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t12, t13, t14, t15;
+ Word32 s00, s01, s02, s03, s04, s05, s06, s07, s08, s09, s10, s11, s12, s13, s14, s15;
+
+ FOR( i = 0; i < dim2; i++ )
+ {
+ FOR( j = 0; j < dim1; j++ )
+ {
+ x[2 * i * dim1 + 2 * j] = re[sx * i + sx * j * dim2];
+ move32();
+ x[2 * i * dim1 + 2 * j + 1] = im[sx * i + sx * j * dim2];
+ move32();
+ }
+ }
+
+ /* dim1 == 8 */
+ FOR( i = 0; i < dim2; i++ )
+ {
+ BASOP_fft8( &x[i * 2 * dim1], &x[i * 2 * dim1 + 1], 2 );
+ }
+
+ /* dim2 == 8 */
+ FOR( i = 0; i < dim1; i++ )
+ {
+ cplxMpy4_8_1( x00, x01, x[2 * i + 2 * 0 * dim1], x[2 * i + 2 * 0 * dim1 + 1] );
+
+ IF( i == 0 )
+ {
+ cplxMpy4_8_1( x02, x03, x[add( shl( i, 1 ), i_mult( 2 * 1, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 1, dim1 ) ), 1 )] );
+ cplxMpy4_8_1( x04, x05, x[add( shl( i, 1 ), i_mult( 2 * 2, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 2, dim1 ) ), 1 )] );
+ cplxMpy4_8_1( x06, x07, x[add( shl( i, 1 ), i_mult( 2 * 3, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 3, dim1 ) ), 1 )] );
+ cplxMpy4_8_1( x08, x09, x[add( shl( i, 1 ), i_mult( 2 * 4, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 4, dim1 ) ), 1 )] );
+ cplxMpy4_8_1( x10, x11, x[add( shl( i, 1 ), i_mult( 2 * 5, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 5, dim1 ) ), 1 )] );
+ cplxMpy4_8_1( x12, x13, x[add( shl( i, 1 ), i_mult( 2 * 6, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 6, dim1 ) ), 1 )] );
+ cplxMpy4_8_1( x14, x15, x[add( shl( i, 1 ), i_mult( 2 * 7, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 7, dim1 ) ), 1 )] );
+ }
+ ELSE
+ {
+ cplxMpy4_8_0( x02, x03, x[add( shl( i, 1 ), i_mult( 2 * 1, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 1, dim1 ) ), 1 )], W[sub( add( i_mult( sc, i ), i_mult( sc, i_mult( 1, dim1 ) ) ), Woff )], W[sub( add( add( i_mult( sc, i ), i_mult( sc, i_mult( 1, dim1 ) ) ), 1 ), Woff )] );
+ cplxMpy4_8_0( x04, x05, x[add( shl( i, 1 ), i_mult( 2 * 2, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 2, dim1 ) ), 1 )], W[sub( add( i_mult( sc, i ), i_mult( sc, i_mult( 2, dim1 ) ) ), Woff )], W[sub( add( add( i_mult( sc, i ), i_mult( sc, i_mult( 2, dim1 ) ) ), 1 ), Woff )] );
+ cplxMpy4_8_0( x06, x07, x[add( shl( i, 1 ), i_mult( 2 * 3, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 3, dim1 ) ), 1 )], W[sub( add( i_mult( sc, i ), i_mult( sc, i_mult( 3, dim1 ) ) ), Woff )], W[sub( add( add( i_mult( sc, i ), i_mult( sc, i_mult( 3, dim1 ) ) ), 1 ), Woff )] );
+ cplxMpy4_8_0( x08, x09, x[add( shl( i, 1 ), i_mult( 2 * 4, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 4, dim1 ) ), 1 )], W[sub( add( i_mult( sc, i ), i_mult( sc, i_mult( 4, dim1 ) ) ), Woff )], W[sub( add( add( i_mult( sc, i ), i_mult( sc, i_mult( 4, dim1 ) ) ), 1 ), Woff )] );
+ cplxMpy4_8_0( x10, x11, x[add( shl( i, 1 ), i_mult( 2 * 5, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 5, dim1 ) ), 1 )], W[sub( add( i_mult( sc, i ), i_mult( sc, i_mult( 5, dim1 ) ) ), Woff )], W[sub( add( add( i_mult( sc, i ), i_mult( sc, i_mult( 5, dim1 ) ) ), 1 ), Woff )] );
+ cplxMpy4_8_0( x12, x13, x[add( shl( i, 1 ), i_mult( 2 * 6, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 6, dim1 ) ), 1 )], W[sub( add( i_mult( sc, i ), i_mult( sc, i_mult( 6, dim1 ) ) ), Woff )], W[sub( add( add( i_mult( sc, i ), i_mult( sc, i_mult( 6, dim1 ) ) ), 1 ), Woff )] );
+ cplxMpy4_8_0( x14, x15, x[add( shl( i, 1 ), i_mult( 2 * 7, dim1 ) )], x[add( add( shl( i, 1 ), i_mult( 2 * 7, dim1 ) ), 1 )], W[sub( add( i_mult( sc, i ), i_mult( sc, i_mult( 7, dim1 ) ) ), Woff )], W[sub( add( add( i_mult( sc, i ), i_mult( sc, i_mult( 7, dim1 ) ) ), 1 ), Woff )] );
+ }
+ t00 = L_shr( L_add( x00, x08 ), SCALEFACTORN2 - 1 );
+ t02 = L_shr( L_sub( x00, x08 ), SCALEFACTORN2 - 1 );
+ t01 = L_shr( L_add( x01, x09 ), SCALEFACTORN2 - 1 );
+ t03 = L_shr( L_sub( x01, x09 ), SCALEFACTORN2 - 1 );
+ t04 = L_shr( L_add( x02, x10 ), SCALEFACTORN2 - 1 );
+ t06 = L_sub( x02, x10 );
+ t05 = L_shr( L_add( x03, x11 ), SCALEFACTORN2 - 1 );
+ t07 = L_sub( x03, x11 );
+ t08 = L_shr( L_add( x04, x12 ), SCALEFACTORN2 - 1 );
+ t10 = L_shr( L_sub( x04, x12 ), SCALEFACTORN2 - 1 );
+ t09 = L_shr( L_add( x05, x13 ), SCALEFACTORN2 - 1 );
+ t11 = L_shr( L_sub( x05, x13 ), SCALEFACTORN2 - 1 );
+ t12 = L_shr( L_add( x06, x14 ), SCALEFACTORN2 - 1 );
+ t14 = L_sub( x06, x14 );
+ t13 = L_shr( L_add( x07, x15 ), SCALEFACTORN2 - 1 );
+ t15 = L_sub( x07, x15 );
+
+ s00 = L_add( t00, t08 );
+ s04 = L_sub( t00, t08 );
+ s01 = L_add( t01, t09 );
+ s05 = L_sub( t01, t09 );
+ s08 = L_sub( t02, t11 );
+ s10 = L_add( t02, t11 );
+ s09 = L_add( t03, t10 );
+ s11 = L_sub( t03, t10 );
+ s02 = L_add( t04, t12 );
+ s07 = L_sub( t04, t12 );
+ s03 = L_add( t05, t13 );
+ s06 = L_sub( t13, t05 );
+
+ t01 = L_shr( L_add( t06, t14 ), SCALEFACTORN2 - 1 );
+ t02 = L_shr( L_sub( t06, t14 ), SCALEFACTORN2 - 1 );
+ t00 = L_shr( L_add( t07, t15 ), SCALEFACTORN2 - 1 );
+ t03 = L_shr( L_sub( t07, t15 ), SCALEFACTORN2 - 1 );
+
+ s12 = Mpy_32_16_1( L_add( t00, t02 ), C81_FX );
+ s14 = Mpy_32_16_1( L_sub( t00, t02 ), C81_FX );
+ s13 = Mpy_32_16_1( L_sub( t03, t01 ), C81_FX );
+ s15 = Mpy_32_16_1( L_add( t01, t03 ), C82_FX );
+
+ re[add( i_mult( sx, i ), i_mult( sx, i_mult( 0, dim1 ) ) )] = L_add( s00, s02 );
+ move32();
+ im[add( i_mult( sx, i ), i_mult( sx, i_mult( 0, dim1 ) ) )] = L_add( s01, s03 );
+ move32();
+ re[add( i_mult( sx, i ), i_mult( sx, i_mult( 1, dim1 ) ) )] = L_add( s10, s12 );
+ move32();
+ im[add( i_mult( sx, i ), i_mult( sx, i_mult( 1, dim1 ) ) )] = L_add( s11, s13 );
+ move32();
+ re[add( i_mult( sx, i ), i_mult( sx, i_mult( 2, dim1 ) ) )] = L_sub( s04, s06 );
+ move32();
+ im[add( i_mult( sx, i ), i_mult( sx, i_mult( 2, dim1 ) ) )] = L_sub( s05, s07 );
+ move32();
+ re[add( i_mult( sx, i ), i_mult( sx, i_mult( 3, dim1 ) ) )] = L_add( s08, s14 );
+ move32();
+ im[add( i_mult( sx, i ), i_mult( sx, i_mult( 3, dim1 ) ) )] = L_add( s09, s15 );
+ move32();
+ re[add( i_mult( sx, i ), i_mult( sx, i_mult( 4, dim1 ) ) )] = L_sub( s00, s02 );
+ move32();
+ im[add( i_mult( sx, i ), i_mult( sx, i_mult( 4, dim1 ) ) )] = L_sub( s01, s03 );
+ move32();
+ re[add( i_mult( sx, i ), i_mult( sx, i_mult( 5, dim1 ) ) )] = L_sub( s10, s12 );
+ move32();
+ im[add( i_mult( sx, i ), i_mult( sx, i_mult( 5, dim1 ) ) )] = L_sub( s11, s13 );
+ move32();
+ re[add( i_mult( sx, i ), i_mult( sx, i_mult( 6, dim1 ) ) )] = L_add( s04, s06 );
+ move32();
+ im[add( i_mult( sx, i ), i_mult( sx, i_mult( 6, dim1 ) ) )] = L_add( s05, s07 );
+ move32();
+ re[add( i_mult( sx, i ), i_mult( sx, i_mult( 7, dim1 ) ) )] = L_sub( s08, s14 );
+ move32();
+ im[add( i_mult( sx, i ), i_mult( sx, i_mult( 7, dim1 ) ) )] = L_sub( s09, s15 );
+ move32();
+ }
+
+ return;
+}
+
+
+/*-----------------------------------------------------------------*
+ * BASOP_cfft_ivas()
+ *
+ * Complex valued FFT
+ *-----------------------------------------------------------------*/
+
+void BASOP_cfft_ivas(
+ Word32 *re, /* i/o: real part */
+ Word32 *im, /* i/o: imag part */
+ Word16 s, /* i : stride real and imag part */
+ Word16 *scale /* i : scalefactor */
+)
+{
+ Word32 x[2 * 64];
+
+ /* FFT for len = FDNS_NPTS */
+ BASOP_fftN2( re, im, RotVector_256, 8, 8, s, 8, x, 64 );
+ s = add( *scale, SCALEFACTOR64 );
+
+ *scale = s;
+ move16();
+
+ return;
+}
+
+#undef WMC_TOOL_SKIP
diff --git a/lib_com/fft_rel.c b/lib_com/fft_rel.c
deleted file mode 100644
index 1d020cabdd7d013f554eeb3d0a697e73682881d9..0000000000000000000000000000000000000000
--- a/lib_com/fft_rel.c
+++ /dev/null
@@ -1,878 +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 "prot_fx.h"
-#include "rom_com.h"
-#include "wmc_auto.h"
-
-/*---------------------------------------------------------------------*
- * Local constants
- *---------------------------------------------------------------------*/
-
-#define N_MAX_FFT 1024
-#define N_MAX_DIV2 ( N_MAX_FFT >> 1 )
-#define N_MAX_DIV4 ( N_MAX_DIV2 >> 1 )
-#define INV_SQR2_FX 23170
-#define N_MAX_SAS 256
-/*---------------------------------------------------------------------*
- * fft_rel()
- *
- * Computes the split-radix FFT in place for the real-valued
- * signal x of length n. The algorithm has been ported from
- * the Fortran code of [1].
- *
- * The function needs sine and cosine tables t_sin and t_cos,
- * and the constant N_MAX_FFT. The table entries are defined as
- * sin(2*pi*i) and cos(2*pi*i) for i = 0, 1, ..., N_MAX_FFT-1. The
- * implementation assumes that any entry will not be needed
- * outside the tables. Therefore, N_MAX_FFT and n must be properly
- * set. The function has been tested with the values n = 16,
- * 32, 64, 128, 256, and N_MAX_FFT = 1280.
- *
- * References
- * [1] H.V. Sorensen, D.L. Jones, M.T. Heideman, C.S. Burrus,
- * "Real-valued fast Fourier transform algorithm," IEEE
- * Trans. on Signal Processing, Vol.35, No.6, pp 849-863,
- * 1987.
- *
- * OUTPUT
- * x[0:n-1] Transform coeffients in the order re[0], re[1],
- * ..., re[n/2], im[n/2-1], ..., im[1].
- *---------------------------------------------------------------------*/
-
-void fft_rel(
- float x[], /* i/o: input/output vector */
- const int16_t n, /* i : vector length */
- const int16_t m /* i : log2 of vector length */
-)
-{
- int16_t i, j, k, n1, n2, n4;
- int16_t step;
- float xt, t1, t2;
- float *x0, *x1, *x2;
- float *xi2, *xi3, *xi4, *xi1;
- const float *s, *c;
- const int16_t *idx;
-
- /* !!!! NMAX = 256 is hardcoded here (similar optimizations should be done for NMAX > 256) !!! */
-
- float *x2even, *x2odd;
- float temp[512];
-
- if ( n == 128 || n == 256 || n == 512 )
- {
- idx = fft256_read_indexes;
-
- /* Combined Digit reverse counter & Length two butterflies */
- if ( n == 128 )
- {
- x2 = temp;
- for ( i = 0; i < 64; i++ )
- {
- j = *idx++;
- k = *idx++;
-
- *x2++ = x[j >> 1] + x[k >> 1];
- *x2++ = x[j >> 1] - x[k >> 1];
- }
- }
- else if ( n == 256 )
- {
- x2 = temp;
- for ( i = 0; i < 128; i++ )
- {
- j = *idx++;
- k = *idx++;
-
- *x2++ = x[j] + x[k];
- *x2++ = x[j] - x[k];
- }
- }
- else if ( n == 512 )
- {
- x2even = temp;
- x2odd = temp + 256;
-
- for ( i = 0; i < 128; i++ )
- {
- j = 2 * *idx++;
- k = 2 * *idx++;
-
- *x2even++ = x[j] + x[k];
- *x2even++ = x[j] - x[k];
- *x2odd++ = x[++j] + x[++k];
- *x2odd++ = x[j] - x[k];
- }
- }
-
- /*-----------------------------------------------------------------*
- * 1st Stage Loop has been Unrolled because n4 is '1' and that
- * allows the elimination of the 'for_ (j = 1; j < n4; j++)' loop
- * and the associated pointers initialization.
- * Also, it allows to Put the Data from 'temp' back into 'x' due
- * to the previous Combined Digit Reverse and Length two butterflies
- *-----------------------------------------------------------------*/
-
- /*for_ (k = 2; k < 3; k++)*/
- {
- x0 = temp;
- x1 = x0 + 2;
- x2 = x;
-
- for ( i = 0; i < n; i += 4 )
- {
- *x2++ = *x0++ + *x1; /* x[i] = xt + x[i+n2]; */
- *x2++ = *x0;
- *x2++ = *--x0 - *x1++; /* x[i+n2] = xt - x[i+n2]; */
- *x2++ = -*x1; /* x[i+n2+n4] = -x[i+n2+n4]; */
-
- x0 += 4;
- x1 += 3; /* x1 has already advanced */
- }
- }
- }
- else
- {
- /*-----------------------------------------------------------------*
- * Digit reverse counter
- *-----------------------------------------------------------------*/
-
- j = 0;
- x0 = &x[0];
- for ( i = 0; i < n - 1; i++ )
- {
- if ( i < j )
- {
- xt = x[j];
- x[j] = *x0;
- *x0 = xt;
- }
- x0++;
- k = n / 2;
- while ( k <= j )
- {
- j -= k;
- k = k >> 1;
- }
- j += k;
- }
-
- /*-----------------------------------------------------------------*
- * Length two butterflies
- *-----------------------------------------------------------------*/
-
- x0 = &x[0];
- x1 = &x[1];
- for ( i = 0; i < n / 2; i++ )
- {
- *x1 = *x0 - *x1;
- *x0 = *x0 * 2 - *x1;
-
- x0++;
- x0++;
- x1++;
- x1++;
- }
-
- /*-----------------------------------------------------------------*
- * 1st Stage Loop has been Unrolled because n4 is '1' and that
- * allows the elimination of the 'for_ (j = 1; j < n4; j++)' loop
- * and the associated pointers initialization.
- *-----------------------------------------------------------------*/
-
- /* for_ (k = 2; k < 3; k++) */
- {
- x0 = x;
- x1 = x0 + 2;
-
- for ( i = 0; i < n; i += 4 )
- {
- *x1 = *x0 - *x1; /* x[i+n2] = xt - x[i+n2]; */
- *x0 = *x0 * 2 - *x1++; /* x[i] = xt + x[i+n2]; */
- *x1 = -*x1; /* x[i+n2+n4] = -x[i+n2+n4]; */
-
- x0 += 4;
- x1 += 3; /* x1 has already advanced */
- }
- }
- }
-
- /*-----------------------------------------------------------------*
- * Other butterflies
- *
- * The implementation described in [1] has been changed by using
- * table lookup for evaluating sine and cosine functions. The
- * variable ind and its increment step are needed to access table
- * entries. Note that this implementation assumes n4 to be so
- * small that ind will never exceed the table. Thus the input
- * argument n and the constant N_MAX_FFT must be set properly.
- *-----------------------------------------------------------------*/
-
- n4 = 1;
- n2 = 2;
- n1 = 4;
-
- step = N_MAX_DIV4;
-
- for ( k = 3; k <= m; k++ )
- {
- step >>= 1;
- n4 <<= 1;
- n2 <<= 1;
- n1 <<= 1;
-
- x0 = x;
- x1 = x0 + n2;
- x2 = x1 + n4;
-
- for ( i = 0; i < n; i += n1 )
- {
- *x1 = *x0 - *x1; /* x[i+n2] = xt - x[i+n2]; */
- *x0 = *x0 * 2 - *x1; /* x[i] = xt + x[i+n2]; */
- *x2 = -*x2; /* x[i+n2+n4] = -x[i+n2+n4]; */
-
- s = sincos_t_ext;
- c = s + N_MAX_FFT / 4; /* 1024/4 = 256, 256/4=64 */
- xi1 = x0;
- xi3 = xi1 + n2;
- xi2 = xi3;
- x0 += n1;
- xi4 = x0;
-
- for ( j = 1; j < n4; j++ )
- {
- xi3++;
- xi1++;
- xi4--;
- xi2--;
- c += step;
- s += step; /* autoincrement by ar0 */
-
- t1 = *xi3 * *c + *xi4 * *s; /* t1 = *xi3**(pt_c+ind) + *xi4**(pt_s+ind); */
- t2 = *xi3 * *s - *xi4 * *c; /* t2 = *xi3**(pt_s+ind) - *xi4**(pt_c+ind); */
-
- *xi4 = *xi2 - t2;
- *xi2 = *xi1 - t1;
- *xi1 = *xi1 * 2 - *xi2;
- *xi3 = -2 * t2 - *xi4;
- }
-
- x1 += n1;
- x2 += n1;
- }
- }
-
- return;
-}
-
-void fft_rel_16_32fx(
- Word16 x[], /* i/o: input/output vector Qx */
- Word16 *q_x, /* extra scaling added on speech buffer*/
- Word16 i_subfr,
- const Word16 n, /* i : vector length */
- const Word16 m /* i : log2 of vector length */
-)
-{
- Word16 i, j, k, n1, n2, n4;
- Word16 step;
- Word32 xt, t1, t2;
- Word32 *x0, *x1, *x2;
- const Word16 *s, *c;
- Word32 *xi2, *xi3, *xi4, *xi1;
-
- Word32 fft_bff32[L_FFT];
- Copy_Scale_sig_16_32_no_sat( x, fft_bff32, L_FFT, 0 ); // copying x to fft_bff32 without scaling
-
- /*-----------------------------------------------------------------*
- * Digit reverse counter
- *-----------------------------------------------------------------*/
-
- j = 0;
- move16();
- x0 = &fft_bff32[0]; // Qx
- FOR( i = 0; i < n - 1; i++ )
- {
- IF( LT_16( i, j ) )
- {
- xt = fft_bff32[j]; // Qx
- move32();
- fft_bff32[j] = *x0; // Qx
- move32();
- *x0 = xt; // Qx
- move32();
- }
- x0++;
- k = shr( n, 1 );
- WHILE( ( k <= j ) )
- {
- j = sub( j, k );
- k = shr( k, 1 );
- }
- j = add( j, k );
- }
-
- /*-----------------------------------------------------------------*
- * Length two butterflies
- *-----------------------------------------------------------------*/
-
- x0 = &fft_bff32[0];
- x1 = &fft_bff32[1];
- FOR( i = 0; i < ( n >> 1 ); i++ )
- {
- xt = *x0;
- move32();
- *x0 = L_add( xt, *x1 );
- move32();
- *x1 = L_sub( xt, *x1 );
- move32();
- x0++;
- x0++;
- x1++;
- x1++;
- }
-
- /*-----------------------------------------------------------------*
- * Other butterflies
- *
- * The implementation described in [1] has been changed by using
- * table lookup for evaluating sine and cosine functions. The
- * variable ind and its increment step are needed to access table
- * entries. Note that this implementation assumes n4 to be so
- * small that ind will never exceed the table. Thus the input
- * argument n and the constant N_MAX_SAS must be set properly.
- *-----------------------------------------------------------------*/
-
- n2 = 1;
- move16();
- /* step = N_MAX_SAS/4; */
- FOR( k = 2; k <= m; k++ )
- {
- n4 = n2;
- move16();
- n2 = shl( n4, 1 );
- n1 = shl( n2, 1 );
-
- step = idiv1616( N_MAX_SAS, n1 );
-
- x0 = fft_bff32;
- x1 = fft_bff32 + n2;
- x2 = fft_bff32 + add( n2, n4 );
- FOR( i = 0; i < n; i += n1 )
- {
- xt = *x0;
- move32(); /* xt = x[i]; */
- *x0 = L_add( xt, *x1 );
- move32(); /* x[i] = xt + x[i+n2]; */
- *x1 = L_sub( xt, *x1 );
- move32(); /* x[i+n2] = xt - x[i+n2]; */
- *x2 = L_negate( *x2 );
- move32(); /* x[i+n2+n4] = -x[i+n2+n4]; */
-
-
- s = sincos_t_fx + step; // Q15
- c = s + 64; // Q15
- xi1 = fft_bff32 + add( i, 1 );
- xi3 = xi1 + n2;
- xi2 = xi3 - 2;
- xi4 = xi1 + sub( n1, 2 );
-
- FOR( j = 1; j < n4; j++ )
- {
- t1 = L_add( Mpy_32_16_1( *xi3, *c ), Mpy_32_16_1( *xi4, *s ) ); /* t1 = *xi3**(pt_c+ind) + *xi4**(pt_s+ind); Qx */
- t2 = L_sub( Mpy_32_16_1( *xi3, *s ), Mpy_32_16_1( *xi4, *c ) ); /* t2 = *xi3**(pt_s+ind) - *xi4**(pt_c+ind); Qx */
- *xi4 = L_sub( *xi2, t2 );
- move32();
- *xi3 = L_negate( L_add( *xi2, t2 ) );
- move32();
- *xi2 = L_sub( *xi1, t1 );
- move32();
- *xi1 = L_add( *xi1, t1 );
- move32();
-
- xi4--;
- xi2--;
- xi3++;
- xi1++;
- c += step;
- s += step; /* autoincrement by ar0 */
- }
-
- x0 += n1;
- x1 += n1;
- x2 += n1;
- }
- /* step = shr(step, 1); */
- }
- Word16 norm = L_norm_arr( fft_bff32, L_FFT );
- IF( i_subfr == 0 )
- {
- Copy_Scale_sig32_16( fft_bff32, x, L_FFT, norm );
- *q_x = sub( norm, 16 );
- move16();
- }
- ELSE
- {
- IF( LT_16( sub( norm, 16 ), *q_x ) )
- {
- scale_sig( x - L_FFT, L_FFT, sub( sub( norm, 16 ), *q_x ) );
- Copy_Scale_sig32_16( fft_bff32, x, L_FFT, norm );
- *q_x = sub( norm, 16 );
- move16();
- }
- ELSE
- {
- Copy_Scale_sig32_16( fft_bff32, x, L_FFT, add( 16, *q_x ) );
- }
- }
-
- return;
-}
-
-void fft_rel_fx(
- Word16 x[], /* i/o: input/output vector Qx */
- const Word16 n, /* i : vector length */
- const Word16 m /* i : log2 of vector length */
-)
-{
- Word16 i, j, k, n1, n2, n4;
- Word16 step;
- Word16 xt, t1, t2;
- Word16 *x0, *x1, *x2;
- const Word16 *s, *c;
- Word16 *xi2, *xi3, *xi4, *xi1;
-#ifdef BASOP_NOGLOB_DECLARE_LOCAL
- Flag Overflow = 0;
- move32();
-#endif
-
-
- /*-----------------------------------------------------------------*
- * Digit reverse counter
- *-----------------------------------------------------------------*/
-
- j = 0;
- move16();
- x0 = &x[0]; // Qx
- move16();
- FOR( i = 0; i < n - 1; i++ )
- {
- IF( LT_16( i, j ) )
- {
- xt = x[j]; // Qx
- move16();
- x[j] = *x0; // Qx
- move16();
- *x0 = xt; // Qx
- move16();
- }
- x0++;
- k = shr( n, 1 );
- WHILE( ( k <= j ) )
- {
- j = sub( j, k );
- k = shr( k, 1 );
- }
- j = add( j, k );
- }
-
- /*-----------------------------------------------------------------*
- * Length two butterflies
- *-----------------------------------------------------------------*/
-
- x0 = &x[0];
- move16();
- x1 = &x[1];
- move16();
- FOR( i = 0; i < ( n >> 1 ); i++ )
- {
- xt = *x0;
- move16();
- *x0 = add_o( xt, *x1, &Overflow );
- move16();
- *x1 = sub_o( xt, *x1, &Overflow );
- move16();
- x0++;
- x0++;
- x1++;
- x1++;
- }
-
- /*-----------------------------------------------------------------*
- * Other butterflies
- *
- * The implementation described in [1] has been changed by using
- * table lookup for evaluating sine and cosine functions. The
- * variable ind and its increment step are needed to access table
- * entries. Note that this implementation assumes n4 to be so
- * small that ind will never exceed the table. Thus the input
- * argument n and the constant N_MAX_SAS must be set properly.
- *-----------------------------------------------------------------*/
-
- n2 = 1;
- move16();
- /* step = N_MAX_SAS/4; */
- FOR( k = 2; k <= m; k++ )
- {
- n4 = n2;
- move16();
- n2 = shl( n4, 1 );
- n1 = shl( n2, 1 );
-
- step = idiv1616( N_MAX_SAS, n1 );
-
- x0 = x;
- x1 = x + n2;
- x2 = x + add( n2, n4 );
- FOR( i = 0; i < n; i += n1 )
- {
- xt = *x0;
- move16(); /* xt = x[i]; */
- *x0 = add_o( xt, *x1, &Overflow );
- move16(); /* x[i] = xt + x[i+n2]; */
- *x1 = sub_o( xt, *x1, &Overflow );
- move16(); /* x[i+n2] = xt - x[i+n2]; */
- *x2 = negate( *x2 );
- move16(); /* x[i+n2+n4] = -x[i+n2+n4]; */
-
-
- s = sincos_t_fx + step; // Q15
- c = s + 64; // Q15
- xi1 = x + add( i, 1 );
- xi3 = xi1 + n2;
- xi2 = xi3 - 2;
- xi4 = xi1 + sub( n1, 2 );
-
- FOR( j = 1; j < n4; j++ )
- {
- t1 = add_o( mult_r( *xi3, *c ), mult_r( *xi4, *s ), &Overflow ); /* t1 = *xi3**(pt_c+ind) + *xi4**(pt_s+ind); Qx */
- t2 = sub_o( mult_r( *xi3, *s ), mult_r( *xi4, *c ), &Overflow ); /* t2 = *xi3**(pt_s+ind) - *xi4**(pt_c+ind); Qx */
- *xi4 = sub_o( *xi2, t2, &Overflow );
- move16();
- *xi3 = negate( add_o( *xi2, t2, &Overflow ) );
- move16();
- *xi2 = sub_o( *xi1, t1, &Overflow );
- move16();
- *xi1 = add_o( *xi1, t1, &Overflow );
- move16();
-
- xi4--;
- xi2--;
- xi3++;
- xi1++;
- c += step;
- s += step; /* autoincrement by ar0 */
- }
-
- x0 += n1;
- x1 += n1;
- x2 += n1;
- }
- /* step = shr(step, 1); */
- }
-
- return;
-}
-
-void fft_rel_fx32(
- Word32 x[], /* i/o: input/output vector Qx */
- const Word16 n, /* i : vector length */
- const Word16 m /* i : log2 of vector length */
-)
-{
- Word16 i, j, k, n1, n2, n4;
- Word16 step;
- Word32 xt, t1, t2;
- Word32 *x0, *x1, *x2;
- Word32 *xi2, *xi3, *xi4, *xi1;
- const Word16 *s, *c;
- const Word16 *idx;
-
- /* !!!! NMAX = 256 is hardcoded here (similar optimizations should be done for NMAX > 256) !!! */
-
- Word32 *x2even, *x2odd;
- Word32 temp[512];
-
- test();
- test();
- IF( EQ_16( n, 128 ) || EQ_16( n, 256 ) || EQ_16( n, 512 ) )
- {
- idx = fft256_read_indexes;
-
- /* Combined Digit reverse counter & Length two butterflies */
- IF( EQ_16( n, 128 ) )
- {
- x2 = temp;
- FOR( i = 0; i < 64; i++ )
- {
- j = *idx++;
- move16();
- k = *idx++;
- move16();
-
- *x2++ = L_add( x[( j >> 1 )], x[( k >> 1 )] ); // Qx
- move16();
- *x2++ = L_sub( x[( j >> 1 )], x[( k >> 1 )] ); // Qx
- move16();
- }
- }
- ELSE IF( EQ_16( n, 256 ) )
- {
- x2 = temp;
- FOR( i = 0; i < 128; i++ )
- {
- j = *idx++;
- move16();
- k = *idx++;
- move16();
-
- *x2++ = L_add( x[j], x[k] ); // Qx
- move16();
- *x2++ = L_sub( x[j], x[k] ); // Qx
- move16();
- }
- }
- ELSE IF( EQ_16( n, 512 ) )
- {
- x2even = temp;
- x2odd = temp + 256;
-
- FOR( i = 0; i < 128; i++ )
- {
- j = shl( *idx, 1 );
- idx++;
- k = shl( *idx, 1 );
- idx++;
-
- *x2even++ = L_add( x[j], x[k] ); // Qx
- move16();
- *x2even++ = L_sub( x[j], x[k] ); // Qx
- move16();
- j = add( j, 1 );
- k = add( k, 1 );
- *x2odd++ = L_add( x[j], x[k] ); // Qx
- move16();
- *x2odd++ = L_sub( x[j], x[k] ); // Qx
- move16();
- }
- }
-
- /*-----------------------------------------------------------------*
- * 1st Stage Loop has been Unrolled because n4 is '1' and that
- * allows the elimination of the 'for_ (j = 1; j < n4; j++)' loop
- * and the associated pointers initialization.
- * Also, it allows to Put the Data from 'temp' back into 'x' due
- * to the previous Combined Digit Reverse and Length two butterflies
- *-----------------------------------------------------------------*/
-
- /*for_ (k = 2; k < 3; k++)*/
- {
- x0 = temp;
- x1 = x0 + 2;
- x2 = x; // Qx
-
- FOR( i = 0; i < n; i += 4 )
- {
- *x2++ = L_add( *x0++, *x1 ); /* x[i] = xt + x[i+n2]; */
- move16();
- *x2++ = *x0;
- move16();
- x0--;
- *x2++ = L_sub( *x0, *x1 ); /* x[i+n2] = xt - x[i+n2]; */
- move16();
- x1++;
- *x2++ = L_negate( *x1 ); /* x[i+n2+n4] = -x[i+n2+n4]; */
- move16();
-
- x0 += 4;
- x1 += 3; /* x1 has already advanced */
- }
- }
- }
- ELSE
- {
- /*-----------------------------------------------------------------*
- * Digit reverse counter
- *-----------------------------------------------------------------*/
-
- j = 0;
- move16();
- x0 = &x[0]; // Qx
- FOR( i = 0; i < ( n - 1 ); i++ )
- {
- IF( LT_16( i, j ) )
- {
- xt = x[j]; // Qx
- move32();
- x[j] = *x0;
- move32();
- *x0 = xt;
- move32();
- }
- x0++;
- k = shr( n, 1 );
- WHILE( ( k <= j ) )
- {
- j = sub( j, k );
- k = shr( k, 1 );
- }
- j = add( j, k );
- }
-
- /*-----------------------------------------------------------------*
- * Length two butterflies
- *-----------------------------------------------------------------*/
-
- x0 = &x[0]; // Qx
- x1 = &x[1]; // Qx
- FOR( i = 0; i < ( n >> 1 ); i++ )
- {
- *x1 = L_sub( *x0, *x1 ); // Qx
- move32();
- *x0 = L_sub( L_shl( *x0, 1 ), *x1 ); //*x0 * 2 - *x1 (Qx)
- move32();
-
- x0++;
- x0++;
- x1++;
- x1++;
- }
-
- /*-----------------------------------------------------------------*
- * 1st Stage Loop has been Unrolled because n4 is '1' and that
- * allows the elimination of the 'for_ (j = 1; j < n4; j++)' loop
- * and the associated pointers initialization.
- *-----------------------------------------------------------------*/
-
- /* for_ (k = 2; k < 3; k++) */
- {
- x0 = x; // Qx
- x1 = x0 + 2;
-
- FOR( i = 0; i < n; i += 4 )
- {
- *x1 = L_sub( *x0, *x1 ); /* x[i+n2] = xt - x[i+n2]; Qx*/
- move32();
- *x0 = L_sub( L_shl( *x0, 1 ), *x1++ ); /* x[i] = xt + x[i+n2]; */ /**x0 * 2 - *x1 (Qx)*/
- move32();
- *x1 = L_negate( *x1 ); /* x[i+n2+n4] = -x[i+n2+n4]; Qx*/
- move32();
-
- x0 += 4;
- x1 += 3; /* x1 has already advanced */
- }
- }
- }
-
- /*-----------------------------------------------------------------*
- * Other butterflies
- *
- * The implementation described in [1] has been changed by using
- * table lookup for evaluating sine and cosine functions. The
- * variable ind and its increment step are needed to access table
- * entries. Note that this implementation assumes n4 to be so
- * small that ind will never exceed the table. Thus the input
- * argument n and the constant N_MAX_FFT must be set properly.
- *-----------------------------------------------------------------*/
-
- n4 = 1;
- move16();
- n2 = 2;
- move16();
- n1 = 4;
- move16();
-
- step = N_MAX_DIV4;
- move16();
-
- FOR( k = 3; k <= m; k++ )
- {
- step = shr( step, 1 );
- n4 = shl( n4, 1 );
- n2 = shl( n2, 1 );
- n1 = shl( n1, 1 );
-
- x0 = x;
- x1 = x0 + n2;
- x2 = x1 + n4;
-
- FOR( i = 0; i < n; i += n1 )
- {
- *x1 = L_sub( *x0, *x1 ); /* x[i+n2] = xt - x[i+n2]; */
- move32();
- *x0 = L_sub( L_shl( *x0, 1 ), *x1 ); /* x[i] = xt + x[i+n2]; */ /**x0 * 2 - *x1 (Qx)*/
- move32();
- *x2 = L_negate( *x2 ); /* x[i+n2+n4] = -x[i+n2+n4]; Qx */
- move32();
-
- s = sincos_t_ext_fx; // Q15
- c = s + N_MAX_FFT / 4; /* 1024/4 = 256, 256/4=64 Q15*/
- xi1 = x0;
- xi3 = xi1 + n2;
- xi2 = xi3;
- x0 += n1;
- xi4 = x0;
-
- FOR( j = 1; j < n4; j++ )
- {
- xi3++;
- xi1++;
- xi4--;
- xi2--;
- c += step;
- s += step; /* autoincrement by ar0 */
-
- t1 = L_add( Mpy_32_16_1( *xi3, *c ), Mpy_32_16_1( *xi4, *s ) ); /* t1 = *xi3**(pt_c+ind) + *xi4**(pt_s+ind); Qx*/
- t2 = L_sub( Mpy_32_16_1( *xi3, *s ), Mpy_32_16_1( *xi4, *c ) ); /* t2 = *xi3**(pt_s+ind) - *xi4**(pt_c+ind); Qx*/
-
- *xi4 = L_sub( *xi2, t2 );
- move32();
- *xi2 = L_sub( *xi1, t1 );
- move32();
- *xi1 = L_sub( L_shl( *xi1, 1 ), *xi2 ); // Qx
- move32();
- *xi3 = L_negate( L_add( L_shl( t2, 1 ), *xi4 ) ); // Qx
- move32();
- }
-
- x1 += n1;
- x2 += n1;
- }
- }
-
- return;
-}
diff --git a/lib_com/fft_rel_fx.c b/lib_com/fft_rel_fx.c
index 5461ce55baae37f1bfdd25c36fac6607fd69e0c1..a0905cc1689e11358c49e235afd5c5c498cbdd96 100644
--- a/lib_com/fft_rel_fx.c
+++ b/lib_com/fft_rel_fx.c
@@ -2,11 +2,24 @@
EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
====================================================================================*/
+#include
#include "options.h" /* Compilation switches */
#include "prot_fx.h" /* Function prototypes */
#include "rom_com.h" /* Static table prototypes */
#include "stl.h"
#include "stdint.h"
+#include "wmc_auto.h"
+
+/*---------------------------------------------------------------------*
+ * Local constants
+ *---------------------------------------------------------------------*/
+
+#define N_MAX_FFT 1024
+#define N_MAX_DIV2 ( N_MAX_FFT >> 1 )
+#define N_MAX_DIV4 ( N_MAX_DIV2 >> 1 )
+#define INV_SQR2_FX 23170
+#define N_MAX_SAS 256
+
/*------------------------------------------------------------------
*
* This is an implementation of decimation-in-time FFT algorithm for
@@ -427,3 +440,832 @@ void r_fft_fx_lc(
c_fft_fx( phs_tbl, SIZE, NUM_STAGE, temp, out_ptr, isign );
}
}
+
+
+/*---------------------------------------------------------------------*
+ * fft_rel()
+ *
+ * Computes the split-radix FFT in place for the real-valued
+ * signal x of length n. The algorithm has been ported from
+ * the Fortran code of [1].
+ *
+ * The function needs sine and cosine tables t_sin and t_cos,
+ * and the constant N_MAX_FFT. The table entries are defined as
+ * sin(2*pi*i) and cos(2*pi*i) for i = 0, 1, ..., N_MAX_FFT-1. The
+ * implementation assumes that any entry will not be needed
+ * outside the tables. Therefore, N_MAX_FFT and n must be properly
+ * set. The function has been tested with the values n = 16,
+ * 32, 64, 128, 256, and N_MAX_FFT = 1280.
+ *
+ * References
+ * [1] H.V. Sorensen, D.L. Jones, M.T. Heideman, C.S. Burrus,
+ * "Real-valued fast Fourier transform algorithm," IEEE
+ * Trans. on Signal Processing, Vol.35, No.6, pp 849-863,
+ * 1987.
+ *
+ * OUTPUT
+ * x[0:n-1] Transform coeffients in the order re[0], re[1],
+ * ..., re[n/2], im[n/2-1], ..., im[1].
+ *---------------------------------------------------------------------*/
+
+void fft_rel(
+ float x[], /* i/o: input/output vector */
+ const int16_t n, /* i : vector length */
+ const int16_t m /* i : log2 of vector length */
+)
+{
+ int16_t i, j, k, n1, n2, n4;
+ int16_t step;
+ float xt, t1, t2;
+ float *x0, *x1, *x2;
+ float *xi2, *xi3, *xi4, *xi1;
+ const float *s, *c;
+ const int16_t *idx;
+
+ /* !!!! NMAX = 256 is hardcoded here (similar optimizations should be done for NMAX > 256) !!! */
+
+ float *x2even, *x2odd;
+ float temp[512];
+
+ if ( n == 128 || n == 256 || n == 512 )
+ {
+ idx = fft256_read_indexes;
+
+ /* Combined Digit reverse counter & Length two butterflies */
+ if ( n == 128 )
+ {
+ x2 = temp;
+ for ( i = 0; i < 64; i++ )
+ {
+ j = *idx++;
+ k = *idx++;
+
+ *x2++ = x[j >> 1] + x[k >> 1];
+ *x2++ = x[j >> 1] - x[k >> 1];
+ }
+ }
+ else if ( n == 256 )
+ {
+ x2 = temp;
+ for ( i = 0; i < 128; i++ )
+ {
+ j = *idx++;
+ k = *idx++;
+
+ *x2++ = x[j] + x[k];
+ *x2++ = x[j] - x[k];
+ }
+ }
+ else if ( n == 512 )
+ {
+ x2even = temp;
+ x2odd = temp + 256;
+
+ for ( i = 0; i < 128; i++ )
+ {
+ j = 2 * *idx++;
+ k = 2 * *idx++;
+
+ *x2even++ = x[j] + x[k];
+ *x2even++ = x[j] - x[k];
+ *x2odd++ = x[++j] + x[++k];
+ *x2odd++ = x[j] - x[k];
+ }
+ }
+
+ /*-----------------------------------------------------------------*
+ * 1st Stage Loop has been Unrolled because n4 is '1' and that
+ * allows the elimination of the 'for_ (j = 1; j < n4; j++)' loop
+ * and the associated pointers initialization.
+ * Also, it allows to Put the Data from 'temp' back into 'x' due
+ * to the previous Combined Digit Reverse and Length two butterflies
+ *-----------------------------------------------------------------*/
+
+ /*for_ (k = 2; k < 3; k++)*/
+ {
+ x0 = temp;
+ x1 = x0 + 2;
+ x2 = x;
+
+ for ( i = 0; i < n; i += 4 )
+ {
+ *x2++ = *x0++ + *x1; /* x[i] = xt + x[i+n2]; */
+ *x2++ = *x0;
+ *x2++ = *--x0 - *x1++; /* x[i+n2] = xt - x[i+n2]; */
+ *x2++ = -*x1; /* x[i+n2+n4] = -x[i+n2+n4]; */
+
+ x0 += 4;
+ x1 += 3; /* x1 has already advanced */
+ }
+ }
+ }
+ else
+ {
+ /*-----------------------------------------------------------------*
+ * Digit reverse counter
+ *-----------------------------------------------------------------*/
+
+ j = 0;
+ x0 = &x[0];
+ for ( i = 0; i < n - 1; i++ )
+ {
+ if ( i < j )
+ {
+ xt = x[j];
+ x[j] = *x0;
+ *x0 = xt;
+ }
+ x0++;
+ k = n / 2;
+ while ( k <= j )
+ {
+ j -= k;
+ k = k >> 1;
+ }
+ j += k;
+ }
+
+ /*-----------------------------------------------------------------*
+ * Length two butterflies
+ *-----------------------------------------------------------------*/
+
+ x0 = &x[0];
+ x1 = &x[1];
+ for ( i = 0; i < n / 2; i++ )
+ {
+ *x1 = *x0 - *x1;
+ *x0 = *x0 * 2 - *x1;
+
+ x0++;
+ x0++;
+ x1++;
+ x1++;
+ }
+
+ /*-----------------------------------------------------------------*
+ * 1st Stage Loop has been Unrolled because n4 is '1' and that
+ * allows the elimination of the 'for_ (j = 1; j < n4; j++)' loop
+ * and the associated pointers initialization.
+ *-----------------------------------------------------------------*/
+
+ /* for_ (k = 2; k < 3; k++) */
+ {
+ x0 = x;
+ x1 = x0 + 2;
+
+ for ( i = 0; i < n; i += 4 )
+ {
+ *x1 = *x0 - *x1; /* x[i+n2] = xt - x[i+n2]; */
+ *x0 = *x0 * 2 - *x1++; /* x[i] = xt + x[i+n2]; */
+ *x1 = -*x1; /* x[i+n2+n4] = -x[i+n2+n4]; */
+
+ x0 += 4;
+ x1 += 3; /* x1 has already advanced */
+ }
+ }
+ }
+
+ /*-----------------------------------------------------------------*
+ * Other butterflies
+ *
+ * The implementation described in [1] has been changed by using
+ * table lookup for evaluating sine and cosine functions. The
+ * variable ind and its increment step are needed to access table
+ * entries. Note that this implementation assumes n4 to be so
+ * small that ind will never exceed the table. Thus the input
+ * argument n and the constant N_MAX_FFT must be set properly.
+ *-----------------------------------------------------------------*/
+
+ n4 = 1;
+ n2 = 2;
+ n1 = 4;
+
+ step = N_MAX_DIV4;
+
+ for ( k = 3; k <= m; k++ )
+ {
+ step >>= 1;
+ n4 <<= 1;
+ n2 <<= 1;
+ n1 <<= 1;
+
+ x0 = x;
+ x1 = x0 + n2;
+ x2 = x1 + n4;
+
+ for ( i = 0; i < n; i += n1 )
+ {
+ *x1 = *x0 - *x1; /* x[i+n2] = xt - x[i+n2]; */
+ *x0 = *x0 * 2 - *x1; /* x[i] = xt + x[i+n2]; */
+ *x2 = -*x2; /* x[i+n2+n4] = -x[i+n2+n4]; */
+
+ s = sincos_t_ext;
+ c = s + N_MAX_FFT / 4; /* 1024/4 = 256, 256/4=64 */
+ xi1 = x0;
+ xi3 = xi1 + n2;
+ xi2 = xi3;
+ x0 += n1;
+ xi4 = x0;
+
+ for ( j = 1; j < n4; j++ )
+ {
+ xi3++;
+ xi1++;
+ xi4--;
+ xi2--;
+ c += step;
+ s += step; /* autoincrement by ar0 */
+
+ t1 = *xi3 * *c + *xi4 * *s; /* t1 = *xi3**(pt_c+ind) + *xi4**(pt_s+ind); */
+ t2 = *xi3 * *s - *xi4 * *c; /* t2 = *xi3**(pt_s+ind) - *xi4**(pt_c+ind); */
+
+ *xi4 = *xi2 - t2;
+ *xi2 = *xi1 - t1;
+ *xi1 = *xi1 * 2 - *xi2;
+ *xi3 = -2 * t2 - *xi4;
+ }
+
+ x1 += n1;
+ x2 += n1;
+ }
+ }
+
+ return;
+}
+
+void fft_rel_16_32fx(
+ Word16 x[], /* i/o: input/output vector Qx */
+ Word16 *q_x, /* extra scaling added on speech buffer*/
+ Word16 i_subfr,
+ const Word16 n, /* i : vector length */
+ const Word16 m /* i : log2 of vector length */
+)
+{
+ Word16 i, j, k, n1, n2, n4;
+ Word16 step;
+ Word32 xt, t1, t2;
+ Word32 *x0, *x1, *x2;
+ const Word16 *s, *c;
+ Word32 *xi2, *xi3, *xi4, *xi1;
+
+ Word32 fft_bff32[L_FFT];
+ Copy_Scale_sig_16_32_no_sat( x, fft_bff32, L_FFT, 0 ); // copying x to fft_bff32 without scaling
+
+ /*-----------------------------------------------------------------*
+ * Digit reverse counter
+ *-----------------------------------------------------------------*/
+
+ j = 0;
+ move16();
+ x0 = &fft_bff32[0]; // Qx
+ FOR( i = 0; i < n - 1; i++ )
+ {
+ IF( LT_16( i, j ) )
+ {
+ xt = fft_bff32[j]; // Qx
+ move32();
+ fft_bff32[j] = *x0; // Qx
+ move32();
+ *x0 = xt; // Qx
+ move32();
+ }
+ x0++;
+ k = shr( n, 1 );
+ WHILE( ( k <= j ) )
+ {
+ j = sub( j, k );
+ k = shr( k, 1 );
+ }
+ j = add( j, k );
+ }
+
+ /*-----------------------------------------------------------------*
+ * Length two butterflies
+ *-----------------------------------------------------------------*/
+
+ x0 = &fft_bff32[0];
+ x1 = &fft_bff32[1];
+ FOR( i = 0; i < ( n >> 1 ); i++ )
+ {
+ xt = *x0;
+ move32();
+ *x0 = L_add( xt, *x1 );
+ move32();
+ *x1 = L_sub( xt, *x1 );
+ move32();
+ x0++;
+ x0++;
+ x1++;
+ x1++;
+ }
+
+ /*-----------------------------------------------------------------*
+ * Other butterflies
+ *
+ * The implementation described in [1] has been changed by using
+ * table lookup for evaluating sine and cosine functions. The
+ * variable ind and its increment step are needed to access table
+ * entries. Note that this implementation assumes n4 to be so
+ * small that ind will never exceed the table. Thus the input
+ * argument n and the constant N_MAX_SAS must be set properly.
+ *-----------------------------------------------------------------*/
+
+ n2 = 1;
+ move16();
+ /* step = N_MAX_SAS/4; */
+ FOR( k = 2; k <= m; k++ )
+ {
+ n4 = n2;
+ move16();
+ n2 = shl( n4, 1 );
+ n1 = shl( n2, 1 );
+
+ step = idiv1616( N_MAX_SAS, n1 );
+
+ x0 = fft_bff32;
+ x1 = fft_bff32 + n2;
+ x2 = fft_bff32 + add( n2, n4 );
+ FOR( i = 0; i < n; i += n1 )
+ {
+ xt = *x0;
+ move32(); /* xt = x[i]; */
+ *x0 = L_add( xt, *x1 );
+ move32(); /* x[i] = xt + x[i+n2]; */
+ *x1 = L_sub( xt, *x1 );
+ move32(); /* x[i+n2] = xt - x[i+n2]; */
+ *x2 = L_negate( *x2 );
+ move32(); /* x[i+n2+n4] = -x[i+n2+n4]; */
+
+
+ s = sincos_t_fx + step; // Q15
+ c = s + 64; // Q15
+ xi1 = fft_bff32 + add( i, 1 );
+ xi3 = xi1 + n2;
+ xi2 = xi3 - 2;
+ xi4 = xi1 + sub( n1, 2 );
+
+ FOR( j = 1; j < n4; j++ )
+ {
+ t1 = L_add( Mpy_32_16_1( *xi3, *c ), Mpy_32_16_1( *xi4, *s ) ); /* t1 = *xi3**(pt_c+ind) + *xi4**(pt_s+ind); Qx */
+ t2 = L_sub( Mpy_32_16_1( *xi3, *s ), Mpy_32_16_1( *xi4, *c ) ); /* t2 = *xi3**(pt_s+ind) - *xi4**(pt_c+ind); Qx */
+ *xi4 = L_sub( *xi2, t2 );
+ move32();
+ *xi3 = L_negate( L_add( *xi2, t2 ) );
+ move32();
+ *xi2 = L_sub( *xi1, t1 );
+ move32();
+ *xi1 = L_add( *xi1, t1 );
+ move32();
+
+ xi4--;
+ xi2--;
+ xi3++;
+ xi1++;
+ c += step;
+ s += step; /* autoincrement by ar0 */
+ }
+
+ x0 += n1;
+ x1 += n1;
+ x2 += n1;
+ }
+ /* step = shr(step, 1); */
+ }
+ Word16 norm = L_norm_arr( fft_bff32, L_FFT );
+ IF( i_subfr == 0 )
+ {
+ Copy_Scale_sig32_16( fft_bff32, x, L_FFT, norm );
+ *q_x = sub( norm, 16 );
+ move16();
+ }
+ ELSE
+ {
+ IF( LT_16( sub( norm, 16 ), *q_x ) )
+ {
+ scale_sig( x - L_FFT, L_FFT, sub( sub( norm, 16 ), *q_x ) );
+ Copy_Scale_sig32_16( fft_bff32, x, L_FFT, norm );
+ *q_x = sub( norm, 16 );
+ move16();
+ }
+ ELSE
+ {
+ Copy_Scale_sig32_16( fft_bff32, x, L_FFT, add( 16, *q_x ) );
+ }
+ }
+
+ return;
+}
+
+void fft_rel_fx(
+ Word16 x[], /* i/o: input/output vector Qx */
+ const Word16 n, /* i : vector length */
+ const Word16 m /* i : log2 of vector length */
+)
+{
+ Word16 i, j, k, n1, n2, n4;
+ Word16 step;
+ Word16 xt, t1, t2;
+ Word16 *x0, *x1, *x2;
+ const Word16 *s, *c;
+ Word16 *xi2, *xi3, *xi4, *xi1;
+#ifdef BASOP_NOGLOB_DECLARE_LOCAL
+ Flag Overflow = 0;
+ move32();
+#endif
+
+
+ /*-----------------------------------------------------------------*
+ * Digit reverse counter
+ *-----------------------------------------------------------------*/
+
+ j = 0;
+ move16();
+ x0 = &x[0]; // Qx
+ move16();
+ FOR( i = 0; i < n - 1; i++ )
+ {
+ IF( LT_16( i, j ) )
+ {
+ xt = x[j]; // Qx
+ move16();
+ x[j] = *x0; // Qx
+ move16();
+ *x0 = xt; // Qx
+ move16();
+ }
+ x0++;
+ k = shr( n, 1 );
+ WHILE( ( k <= j ) )
+ {
+ j = sub( j, k );
+ k = shr( k, 1 );
+ }
+ j = add( j, k );
+ }
+
+ /*-----------------------------------------------------------------*
+ * Length two butterflies
+ *-----------------------------------------------------------------*/
+
+ x0 = &x[0];
+ move16();
+ x1 = &x[1];
+ move16();
+ FOR( i = 0; i < ( n >> 1 ); i++ )
+ {
+ xt = *x0;
+ move16();
+ *x0 = add_o( xt, *x1, &Overflow );
+ move16();
+ *x1 = sub_o( xt, *x1, &Overflow );
+ move16();
+ x0++;
+ x0++;
+ x1++;
+ x1++;
+ }
+
+ /*-----------------------------------------------------------------*
+ * Other butterflies
+ *
+ * The implementation described in [1] has been changed by using
+ * table lookup for evaluating sine and cosine functions. The
+ * variable ind and its increment step are needed to access table
+ * entries. Note that this implementation assumes n4 to be so
+ * small that ind will never exceed the table. Thus the input
+ * argument n and the constant N_MAX_SAS must be set properly.
+ *-----------------------------------------------------------------*/
+
+ n2 = 1;
+ move16();
+ /* step = N_MAX_SAS/4; */
+ FOR( k = 2; k <= m; k++ )
+ {
+ n4 = n2;
+ move16();
+ n2 = shl( n4, 1 );
+ n1 = shl( n2, 1 );
+
+ step = idiv1616( N_MAX_SAS, n1 );
+
+ x0 = x;
+ x1 = x + n2;
+ x2 = x + add( n2, n4 );
+ FOR( i = 0; i < n; i += n1 )
+ {
+ xt = *x0;
+ move16(); /* xt = x[i]; */
+ *x0 = add_o( xt, *x1, &Overflow );
+ move16(); /* x[i] = xt + x[i+n2]; */
+ *x1 = sub_o( xt, *x1, &Overflow );
+ move16(); /* x[i+n2] = xt - x[i+n2]; */
+ *x2 = negate( *x2 );
+ move16(); /* x[i+n2+n4] = -x[i+n2+n4]; */
+
+
+ s = sincos_t_fx + step; // Q15
+ c = s + 64; // Q15
+ xi1 = x + add( i, 1 );
+ xi3 = xi1 + n2;
+ xi2 = xi3 - 2;
+ xi4 = xi1 + sub( n1, 2 );
+
+ FOR( j = 1; j < n4; j++ )
+ {
+ t1 = add_o( mult_r( *xi3, *c ), mult_r( *xi4, *s ), &Overflow ); /* t1 = *xi3**(pt_c+ind) + *xi4**(pt_s+ind); Qx */
+ t2 = sub_o( mult_r( *xi3, *s ), mult_r( *xi4, *c ), &Overflow ); /* t2 = *xi3**(pt_s+ind) - *xi4**(pt_c+ind); Qx */
+ *xi4 = sub_o( *xi2, t2, &Overflow );
+ move16();
+ *xi3 = negate( add_o( *xi2, t2, &Overflow ) );
+ move16();
+ *xi2 = sub_o( *xi1, t1, &Overflow );
+ move16();
+ *xi1 = add_o( *xi1, t1, &Overflow );
+ move16();
+
+ xi4--;
+ xi2--;
+ xi3++;
+ xi1++;
+ c += step;
+ s += step; /* autoincrement by ar0 */
+ }
+
+ x0 += n1;
+ x1 += n1;
+ x2 += n1;
+ }
+ /* step = shr(step, 1); */
+ }
+
+ return;
+}
+
+void fft_rel_fx32(
+ Word32 x[], /* i/o: input/output vector Qx */
+ const Word16 n, /* i : vector length */
+ const Word16 m /* i : log2 of vector length */
+)
+{
+ Word16 i, j, k, n1, n2, n4;
+ Word16 step;
+ Word32 xt, t1, t2;
+ Word32 *x0, *x1, *x2;
+ Word32 *xi2, *xi3, *xi4, *xi1;
+ const Word16 *s, *c;
+ const Word16 *idx;
+
+ /* !!!! NMAX = 256 is hardcoded here (similar optimizations should be done for NMAX > 256) !!! */
+
+ Word32 *x2even, *x2odd;
+ Word32 temp[512];
+
+ test();
+ test();
+ IF( EQ_16( n, 128 ) || EQ_16( n, 256 ) || EQ_16( n, 512 ) )
+ {
+ idx = fft256_read_indexes;
+
+ /* Combined Digit reverse counter & Length two butterflies */
+ IF( EQ_16( n, 128 ) )
+ {
+ x2 = temp;
+ FOR( i = 0; i < 64; i++ )
+ {
+ j = *idx++;
+ move16();
+ k = *idx++;
+ move16();
+
+ *x2++ = L_add( x[( j >> 1 )], x[( k >> 1 )] ); // Qx
+ move16();
+ *x2++ = L_sub( x[( j >> 1 )], x[( k >> 1 )] ); // Qx
+ move16();
+ }
+ }
+ ELSE IF( EQ_16( n, 256 ) )
+ {
+ x2 = temp;
+ FOR( i = 0; i < 128; i++ )
+ {
+ j = *idx++;
+ move16();
+ k = *idx++;
+ move16();
+
+ *x2++ = L_add( x[j], x[k] ); // Qx
+ move16();
+ *x2++ = L_sub( x[j], x[k] ); // Qx
+ move16();
+ }
+ }
+ ELSE IF( EQ_16( n, 512 ) )
+ {
+ x2even = temp;
+ x2odd = temp + 256;
+
+ FOR( i = 0; i < 128; i++ )
+ {
+ j = shl( *idx, 1 );
+ idx++;
+ k = shl( *idx, 1 );
+ idx++;
+
+ *x2even++ = L_add( x[j], x[k] ); // Qx
+ move16();
+ *x2even++ = L_sub( x[j], x[k] ); // Qx
+ move16();
+ j = add( j, 1 );
+ k = add( k, 1 );
+ *x2odd++ = L_add( x[j], x[k] ); // Qx
+ move16();
+ *x2odd++ = L_sub( x[j], x[k] ); // Qx
+ move16();
+ }
+ }
+
+ /*-----------------------------------------------------------------*
+ * 1st Stage Loop has been Unrolled because n4 is '1' and that
+ * allows the elimination of the 'for_ (j = 1; j < n4; j++)' loop
+ * and the associated pointers initialization.
+ * Also, it allows to Put the Data from 'temp' back into 'x' due
+ * to the previous Combined Digit Reverse and Length two butterflies
+ *-----------------------------------------------------------------*/
+
+ /*for_ (k = 2; k < 3; k++)*/
+ {
+ x0 = temp;
+ x1 = x0 + 2;
+ x2 = x; // Qx
+
+ FOR( i = 0; i < n; i += 4 )
+ {
+ *x2++ = L_add( *x0++, *x1 ); /* x[i] = xt + x[i+n2]; */
+ move16();
+ *x2++ = *x0;
+ move16();
+ x0--;
+ *x2++ = L_sub( *x0, *x1 ); /* x[i+n2] = xt - x[i+n2]; */
+ move16();
+ x1++;
+ *x2++ = L_negate( *x1 ); /* x[i+n2+n4] = -x[i+n2+n4]; */
+ move16();
+
+ x0 += 4;
+ x1 += 3; /* x1 has already advanced */
+ }
+ }
+ }
+ ELSE
+ {
+ /*-----------------------------------------------------------------*
+ * Digit reverse counter
+ *-----------------------------------------------------------------*/
+
+ j = 0;
+ move16();
+ x0 = &x[0]; // Qx
+ FOR( i = 0; i < ( n - 1 ); i++ )
+ {
+ IF( LT_16( i, j ) )
+ {
+ xt = x[j]; // Qx
+ move32();
+ x[j] = *x0;
+ move32();
+ *x0 = xt;
+ move32();
+ }
+ x0++;
+ k = shr( n, 1 );
+ WHILE( ( k <= j ) )
+ {
+ j = sub( j, k );
+ k = shr( k, 1 );
+ }
+ j = add( j, k );
+ }
+
+ /*-----------------------------------------------------------------*
+ * Length two butterflies
+ *-----------------------------------------------------------------*/
+
+ x0 = &x[0]; // Qx
+ x1 = &x[1]; // Qx
+ FOR( i = 0; i < ( n >> 1 ); i++ )
+ {
+ *x1 = L_sub( *x0, *x1 ); // Qx
+ move32();
+ *x0 = L_sub( L_shl( *x0, 1 ), *x1 ); //*x0 * 2 - *x1 (Qx)
+ move32();
+
+ x0++;
+ x0++;
+ x1++;
+ x1++;
+ }
+
+ /*-----------------------------------------------------------------*
+ * 1st Stage Loop has been Unrolled because n4 is '1' and that
+ * allows the elimination of the 'for_ (j = 1; j < n4; j++)' loop
+ * and the associated pointers initialization.
+ *-----------------------------------------------------------------*/
+
+ /* for_ (k = 2; k < 3; k++) */
+ {
+ x0 = x; // Qx
+ x1 = x0 + 2;
+
+ FOR( i = 0; i < n; i += 4 )
+ {
+ *x1 = L_sub( *x0, *x1 ); /* x[i+n2] = xt - x[i+n2]; Qx*/
+ move32();
+ *x0 = L_sub( L_shl( *x0, 1 ), *x1++ ); /* x[i] = xt + x[i+n2]; */ /**x0 * 2 - *x1 (Qx)*/
+ move32();
+ *x1 = L_negate( *x1 ); /* x[i+n2+n4] = -x[i+n2+n4]; Qx*/
+ move32();
+
+ x0 += 4;
+ x1 += 3; /* x1 has already advanced */
+ }
+ }
+ }
+
+ /*-----------------------------------------------------------------*
+ * Other butterflies
+ *
+ * The implementation described in [1] has been changed by using
+ * table lookup for evaluating sine and cosine functions. The
+ * variable ind and its increment step are needed to access table
+ * entries. Note that this implementation assumes n4 to be so
+ * small that ind will never exceed the table. Thus the input
+ * argument n and the constant N_MAX_FFT must be set properly.
+ *-----------------------------------------------------------------*/
+
+ n4 = 1;
+ move16();
+ n2 = 2;
+ move16();
+ n1 = 4;
+ move16();
+
+ step = N_MAX_DIV4;
+ move16();
+
+ FOR( k = 3; k <= m; k++ )
+ {
+ step = shr( step, 1 );
+ n4 = shl( n4, 1 );
+ n2 = shl( n2, 1 );
+ n1 = shl( n1, 1 );
+
+ x0 = x;
+ x1 = x0 + n2;
+ x2 = x1 + n4;
+
+ FOR( i = 0; i < n; i += n1 )
+ {
+ *x1 = L_sub( *x0, *x1 ); /* x[i+n2] = xt - x[i+n2]; */
+ move32();
+ *x0 = L_sub( L_shl( *x0, 1 ), *x1 ); /* x[i] = xt + x[i+n2]; */ /**x0 * 2 - *x1 (Qx)*/
+ move32();
+ *x2 = L_negate( *x2 ); /* x[i+n2+n4] = -x[i+n2+n4]; Qx */
+ move32();
+
+ s = sincos_t_ext_fx; // Q15
+ c = s + N_MAX_FFT / 4; /* 1024/4 = 256, 256/4=64 Q15*/
+ xi1 = x0;
+ xi3 = xi1 + n2;
+ xi2 = xi3;
+ x0 += n1;
+ xi4 = x0;
+
+ FOR( j = 1; j < n4; j++ )
+ {
+ xi3++;
+ xi1++;
+ xi4--;
+ xi2--;
+ c += step;
+ s += step; /* autoincrement by ar0 */
+
+ t1 = L_add( Mpy_32_16_1( *xi3, *c ), Mpy_32_16_1( *xi4, *s ) ); /* t1 = *xi3**(pt_c+ind) + *xi4**(pt_s+ind); Qx*/
+ t2 = L_sub( Mpy_32_16_1( *xi3, *s ), Mpy_32_16_1( *xi4, *c ) ); /* t2 = *xi3**(pt_s+ind) - *xi4**(pt_c+ind); Qx*/
+
+ *xi4 = L_sub( *xi2, t2 );
+ move32();
+ *xi2 = L_sub( *xi1, t1 );
+ move32();
+ *xi1 = L_sub( L_shl( *xi1, 1 ), *xi2 ); // Qx
+ move32();
+ *xi3 = L_negate( L_add( L_shl( t2, 1 ), *xi4 ) ); // Qx
+ move32();
+ }
+
+ x1 += n1;
+ x2 += n1;
+ }
+ }
+
+ return;
+}
diff --git a/lib_com/fill_spectrum.c b/lib_com/fill_spectrum_fx.c
similarity index 100%
rename from lib_com/fill_spectrum.c
rename to lib_com/fill_spectrum_fx.c
diff --git a/lib_com/findpulse.c b/lib_com/findpulse_fx.c
similarity index 100%
rename from lib_com/findpulse.c
rename to lib_com/findpulse_fx.c
diff --git a/lib_com/gs_gains.c b/lib_com/gs_gains.c
deleted file mode 100644
index 8fa7694755c7c5ac9f912f26abdff9211895ff07..0000000000000000000000000000000000000000
--- a/lib_com/gs_gains.c
+++ /dev/null
@@ -1,425 +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_fx.h"
-#include "wmc_auto.h"
-
-static void GSC_gain_DQ_fx(
- const Word16 element_mode, /* i : element mode */
- const Word16 enc_dec, /* i : encoder/decoder flag */
- const Word16 coder_type, /* i : Coder type */
- const Word16 Mbands_gn, /* i : Number of band */
- const Word32 core_brate, /* i : Core bitrate */
- const Word16 mean_g, /* i : Average gain Q12 */
- const Word16 *Gain_in, /* i : Unquantized gain vector Q12 */
- Word16 *Gain_out /* o : Level adjusted unquantized gain vector Q12 */
-)
-{
- Word16 Gain_off;
- Word16 i;
-
- /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
- Gain_off = 0;
- move16();
-
- test();
- IF( coder_type == INACTIVE || EQ_16( coder_type, UNVOICED ) )
- {
- test();
- IF( LE_32( core_brate, ACELP_5k00 ) && EQ_16( coder_type, UNVOICED ) )
- {
- Gain_off = 1843; // 9/20 in Q12
- move16();
- }
- ELSE IF( LE_32( core_brate, ACELP_7k20 ) )
- {
- Gain_off = 1638; // 8/20 in Q12; /* 0 dB */
- move16();
- }
- ELSE IF( LE_32( core_brate, ACELP_8k00 ) )
- {
- Gain_off = 1351; // 6.6f/20 in Q12 /* ~-3.3 dB */
- move16();
- }
- ELSE IF( LE_32( core_brate, ACELP_9k60 ) )
- {
- Gain_off = 983; // 4.8f/20 in Q12 /* ~-2.4 dB */
- move16();
- }
- ELSE IF( LE_32( core_brate, ACELP_11k60 ) )
- {
- Gain_off = 717; // 3.5f/20 in Q12 /* ~-2.4 dB */
- move16();
- }
- ELSE IF( LE_32( core_brate, ACELP_13k20 ) )
- {
- Gain_off = 614; // 3.0f/20 in Q12 /* ~-2.4 dB */
- move16();
- }
- }
-
- test();
- IF( coder_type != INACTIVE && NE_16( coder_type, UNVOICED ) )
- {
- FOR( i = 0; i < Mbands_gn; i++ )
- {
- Gain_out[i] = add( Gain_in[i], mean_g ); // Q12
- move16();
- }
- }
- ELSE
- {
- /*mimic ACELP decay of energy for low rates*/
- test();
- IF( element_mode == EVS_MONO && EQ_16( enc_dec, DEC ) )
- {
- /* This is to keep EVS mono bit-exact with the standard (there might be a small desynchronization between encoder and decoder but there is no real quality or interop. issue) */
- FOR( i = 0; i < Mbands_gn; i++ )
- {
- Gain_out[i] = add( Gain_out[i], sub( mean_g, mult( Gain_off, div_s( i, Mbands_gn ) ) ) ); // Q12
- move16();
- // Gain_out[i] += mean_g - i * ( Gain_off / 20.f ) / ( (float) Mbands_gn );
- }
- }
- ELSE
- {
- FOR( i = 0; i < Mbands_gn; i++ )
- {
- Gain_out[i] = add( Gain_in[i], sub( mean_g, mult( Gain_off, div_s( i, Mbands_gn ) ) ) ); // Q12
- move16();
- // Gain_out[i] = Gain_in[i] + mean_g - ( i * ( Gain_off / 20.f ) / ( (float) Mbands_gn ) );
- }
- }
- }
-
- return;
-}
-
-Word16 gsc_gainQ_ivas_fx(
- BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
- const Word16 element_mode, /* i : element mode */
- const Word16 idchan, /* i : channel ID */
- const Word16 y_gain4[],
- /* i : Energy per band */ // Q12
- Word16 y_gainQ[],
- /* o : quantized energy per band */ // Q12
- const Word32 core_brate, /* i : Core rate */
- const Word16 coder_type, /* i : coding type */
- const Word16 bwidth, /* i : input signal bandwidth */
- const Word16 L_frame, /* i : frame length */
- const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */
- const Word32 core_brate_inp /* i : true core bitrate */
-)
-{
- Word16 y_gain_tmp[MBANDS_GN16k];
- Word16 y_gain_tmp2[MBANDS_GN16k];
- Word16 i, idx_g = 0;
- move16();
- Word16 mean_4g_fx[1], ftmp1_fx;
- Word16 Mbands_gn = MBANDS_GN;
- move16();
- Word16 y_gain_tmp3[MBANDS_GN];
- Word32 L_tmp;
-
- if ( EQ_16( L_frame, L_FRAME16k ) )
- {
- Mbands_gn = MBANDS_GN16k;
- move16();
- }
-
- mean_4g_fx[0] = 0;
- move32();
-
- test();
- test();
- IF( ( EQ_16( coder_type, AUDIO ) || coder_type == INACTIVE ) && bwidth == NB )
- {
- L_tmp = 0;
- move32();
- FOR( i = 0; i < 10; i++ )
- {
- L_tmp = L_add( L_tmp, y_gain4[i] );
- }
- L_tmp = L_sub( Mpy_32_16_1( L_tmp, 3277 /* (1/10.0f) in Q15 */ ), 2457 /* 0.6f in Q12 */ ); // Q12
- ftmp1_fx = extract_l( L_tmp );
- FOR( i = 0; i < Mbands_gn; i++ )
- {
- IF( LT_16( y_gain4[i], ftmp1_fx ) )
- {
- y_gain_tmp2[i] = ftmp1_fx; /*Q12*/
- }
- ELSE
- {
- y_gain_tmp2[i] = y_gain4[i]; /*Q12*/
- }
- move16();
- }
-
- /* Quantized mean gain without clipping */
- L_tmp = 0;
- move32();
- FOR( i = 0; i < 10; i++ )
- {
- L_tmp = L_add( L_tmp, y_gain4[i] );
- }
- L_tmp = Mpy_32_16_1( L_tmp, 3277 /* (1/10.0f) in Q15 */ ); // Q12
- mean_4g_fx[0] = extract_l( L_tmp ); // Q12
- move16();
- idx_g = vquant_fx( mean_4g_fx, Gain_meanNB_fx, mean_4g_fx, Gain_mean_dicNB_fx, 1, 64 );
- push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 );
-
- FOR( i = 0; i < Mbands_gn; i++ )
- {
- y_gain_tmp[i] = sub( y_gain_tmp2[i], mean_4g_fx[0] ); // Q12
- move16();
- }
-
- if ( LT_16( y_gain_tmp[9], -1229 /* -0.3f in Q12 */ ) )
- {
- y_gain_tmp[9] = -1229; /* -0.3f in Q12 */
- move16();
- }
-
- set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 );
- idx_g = vquant_fx( y_gain_tmp, Mean_dic_NB_fx, y_gain_tmp, Gain_dic1_NB_fx, 3, 64 );
- push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
-
- IF( LT_32( core_brate, ACELP_9k60 ) )
- {
- idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NB_fx, 3, 32 );
- push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
-
- idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NB_fx, 4, 16 );
- push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 );
- }
- ELSE
- {
- idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NBHR_fx, 3, 64 );
- push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
-
- idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NBHR_fx, 4, 128 );
- push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 7 );
- }
-
- test();
- IF( LE_32( core_brate, ACELP_9k60 ) && coder_type == INACTIVE )
- {
- /* Some energy is needed in high band for stat_noise_uv_enc() to be functional in inactive speech */
- y_gain_tmp[10] = mean_fx( y_gain_tmp + 6, 3 ); /*Q12*/
- move16();
- y_gain_tmp[11] = mean_fx( y_gain_tmp + 7, 3 ); /*Q12*/
- move16();
- y_gain_tmp[12] = mean_fx( y_gain_tmp + 8, 3 ); /*Q12*/
- move16();
- y_gain_tmp[13] = mean_fx( y_gain_tmp + 9, 3 ); /*Q12*/
- move16();
- y_gain_tmp[14] = mean_fx( y_gain_tmp + 10, 3 ); /*Q12*/
- move16();
- y_gain_tmp[15] = mean_fx( y_gain_tmp + 11, 3 ); /*Q12*/
- move16();
- }
- ELSE
- {
- set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 );
- }
- }
- ELSE
- {
- L_tmp = 0;
- move32();
- FOR( i = 0; i < 16; i++ )
- {
- L_tmp = L_add( L_tmp, y_gain4[i] );
- }
- L_tmp = Mpy_32_16_1( L_tmp, 2048 /* (1/16.f) in Q15 */ ); // Q12
- ftmp1_fx = extract_l( L_tmp );
- FOR( i = 0; i < Mbands_gn; i++ )
- {
- IF( LT_16( y_gain4[i], sub( ftmp1_fx, 2457 /* 0.6 in Q12*/ ) ) )
- {
- y_gain_tmp2[i] = sub( ftmp1_fx, 2457 /* 0.6 in Q12*/ );
- }
- ELSE IF( GT_16( y_gain4[i], add( ftmp1_fx, 2457 /* 0.6 in Q12*/ ) ) )
- {
- y_gain_tmp2[i] = add( ftmp1_fx, 2457 /* 0.6 in Q12*/ );
- }
- ELSE
- {
- y_gain_tmp2[i] = y_gain4[i];
- }
- move16();
- }
-
- L_tmp = 0;
- move32();
- FOR( i = 0; i < 16; i++ )
- {
- L_tmp = L_add( L_tmp, y_gain_tmp2[i] );
- }
- L_tmp = Mpy_32_16_1( L_tmp, 2048 /* (1/16.f) in Q15 */ ); // Q12
- mean_4g_fx[0] = extract_l( L_tmp ); // Q12
- move16();
- idx_g = vquant_fx( mean_4g_fx, mean_m_fx, mean_4g_fx, mean_gain_dic_fx, 1, 64 );
- push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 );
-
- /* Subtraction of the average gain */
- FOR( i = 0; i < Mbands_gn; i++ )
- {
- y_gain_tmp[i] = sub( y_gain_tmp2[i], mean_4g_fx[0] ); // Q12
- move16();
- }
-
- IF( LT_32( core_brate, ACELP_9k60 ) )
- {
- /* prediction and quantization of the average gain */
-
- /*--------------------------------------------------------------------------------------*
- * Quantization of the first 8 bands
- * Keep only 4 bands out of the last 8 bands
- *--------------------------------------------------------------------------------------*/
-
- Copy( y_gain_tmp, y_gain_tmp2, 8 );
-
- y_gain_tmp2[8] = y_gain_tmp[8];
- move16();
- y_gain_tmp2[9] = y_gain_tmp[10];
- move16();
- y_gain_tmp2[10] = y_gain_tmp[12];
- move16();
- y_gain_tmp2[11] = y_gain_tmp[14];
- move16();
-
- idx_g = 0;
- move16();
- idx_g = vquant_fx( y_gain_tmp2, YGain_mean_LR_fx, y_gain_tmp2, YGain_dic1_LR_fx, 3, 32 );
- push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
-
- test();
- test();
- test();
- IF( !( coder_type == INACTIVE && tdm_LRTD_flag == 0 && EQ_16( idchan, 1 ) ) || GT_32( core_brate_inp, GSC_LRES_GAINQ_LIMIT ) )
- {
- idx_g = vquant_fx( y_gain_tmp2 + 3, YGain_mean_LR_fx + 3, y_gain_tmp2 + 3, YGain_dic2_LR_fx, 4, 32 );
- push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
-
- /*----------------------------------------------------------------------*
- * Vector quantization of the first 8 bands + quantization of the 4 bands out of the last 8
- * Interpolation of the last 4 bands Q to create bands 8-16
- *----------------------------------------------------------------------*/
-
- idx_g = vquant_fx( y_gain_tmp2 + 7, YGain_mean_LR_fx + 7, y_gain_tmp2 + 7, YGain_dic3_LR_fx, 5, 32 );
- push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
-
- set16_fx( y_gain_tmp2 + 12, 0, MBANDS_GN - 12 );
-
- /* Update to quantized vector */
- Copy( y_gain_tmp2, y_gain_tmp, 8 );
-
- Copy( y_gain_tmp2 + 8, y_gain_tmp3, 4 );
- set16_fx( y_gain_tmp + 8, 0, 8 );
- fft_rel_fx( y_gain_tmp2 + 8, 4, 2 );
-
- Copy( y_gain_tmp2 + 8, y_gain_tmp + 8, 3 );
- y_gain_tmp[15] = y_gain_tmp2[11];
- move16();
- ifft_rel_fx( y_gain_tmp + 8, 8, 3 );
-
- FOR( i = 8; i < 16; i++ )
- {
- y_gain_tmp[i] = shl( mult( y_gain_tmp[i], 23101 /* 1.41 in Q14 */ ), 1 ); /*Q12*/
- move16();
- }
-
- y_gain_tmp[8] = y_gain_tmp3[0];
- move16();
- y_gain_tmp[10] = y_gain_tmp3[1];
- move16();
- y_gain_tmp[12] = y_gain_tmp3[2];
- move16();
- y_gain_tmp[14] = y_gain_tmp3[3];
- move16();
- }
- ELSE
- {
- Copy( y_gain_tmp2, y_gain_tmp, 3 );
- set16_fx( y_gain_tmp + 3, 0, MBANDS_GN16k - 3 );
- }
- }
- ELSE
- {
- IF( EQ_16( L_frame, L_FRAME ) )
- {
- idx_g = vquant_fx( y_gain_tmp, YG_mean16_fx, y_gain_tmp, YG_dicMR_1_fx, 4, 64 );
- push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
-
- idx_g = vquant_fx( y_gain_tmp + 4, YG_mean16_fx + 4, y_gain_tmp + 4, YG_dicMR_2_fx, 4, 32 );
- push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
-
- idx_g = vquant_fx( y_gain_tmp + 8, YG_mean16_fx + 8, y_gain_tmp + 8, YG_dicMR_3_fx, 4, 32 );
- push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
-
- idx_g = vquant_fx( y_gain_tmp + 12, YG_mean16_fx + 12, y_gain_tmp + 12, YG_dicMR_4_fx, 4, 16 );
- push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 );
- }
- ELSE
- {
- idx_g = vquant_fx( y_gain_tmp, YG_mean16HR_fx, y_gain_tmp, YG_dicHR_1_fx, 4, 128 );
- push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 7 );
-
- idx_g = vquant_fx( y_gain_tmp + 4, YG_mean16HR_fx + 4, y_gain_tmp + 4, YG_dicHR_2_fx, 4, 64 );
- push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
-
- idx_g = vquant_fx( y_gain_tmp + 8, YG_mean16HR_fx + 8, y_gain_tmp + 8, YG_dicHR_3_fx, 4, 64 );
- push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
-
- idx_g = vquant_fx( y_gain_tmp + 12, YG_mean16HR_16kHz_fx, y_gain_tmp + 12, YG_dicHR_4_16kHz_fx, 4, 64 );
- push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
-
- idx_g = vquant_fx( y_gain_tmp + 16, YG_meanL2G_16kHz_fx, y_gain_tmp + 16, YG_dicL2G_16kHz_fx, 2, 8 );
- push_indice( hBstr, IND_Y_GAIN_HF, idx_g, 3 );
- }
- }
- }
-
- GSC_gain_DQ_fx( element_mode, ENC, coder_type, Mbands_gn, core_brate, mean_4g_fx[0], y_gain_tmp, y_gainQ );
-
- return mean_4g_fx[0];
-}
diff --git a/lib_com/gs_gains_fx.c b/lib_com/gs_gains_fx.c
index ecfe9aae0f28d32e24ac362414cc1f52f47b58b4..f28af742fe673950c979fde8de6c8835711ebe89 100644
--- a/lib_com/gs_gains_fx.c
+++ b/lib_com/gs_gains_fx.c
@@ -34,11 +34,14 @@
EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
====================================================================================*/
+#include
+#include
#include "options.h" /* Compilation switches */
#include "cnst.h" /* Common constants */
#include "rom_com.h" /* Static table prototypes */
#include "prot_fx.h"
#include "stl.h"
+#include "wmc_auto.h"
/*-------------------------------------------------------------------*
* Local constants
@@ -66,6 +69,7 @@ static Word16 VDQ_vec_fx( Word16 *Qvec_out_fx, const Word16 *mean_dic_fx, const
/* RETURN ARGUMENTS : */
/* _ None */
/*========================================================================*/
+
void Comp_and_apply_gain_fx(
Word16 exc_diffQ[], /* i/o: Quantized excitation */
Word16 Ener_per_bd_iQ[], /* i : Target ener per band Q13 */
@@ -264,6 +268,7 @@ void Comp_and_apply_gain_ivas_fx(
/* RETURN ARGUMENTS : */
/* _ None */
/*========================================================================*/
+
static Word16 Comp_band_log_ener( /* o : Band gain Q12 */
const Word16 *pt_fx, /* i : Dct input Q_sc */
const Word16 Len, /* i : Lenght en energy accumulation */
@@ -363,127 +368,14 @@ void Ener_per_band_comp_ivas_fx(
return;
}
-void Ener_per_band_comp_ivas_fx_2(
- const Word16 exc_diff[], /* i : target signal Q_exc */
- Word16 y_gain4[], /* o : Energy per band to quantize Q12 */
- const Word16 Q_exc,
- const Word16 Mband, /* i : Max band */
- const Word16 Eflag, /* i : flag of highest band */
- const Word16 L_frame /* i : frame length */
-)
-{
- Word32 etmp, L_tmp;
- Word16 etmp_e;
- const Word16 *pt;
- Word16 i, j, tmp;
- tmp = add( shl( sub( Q15, Q_exc ), 1 ), 1 );
- pt = exc_diff;
- FOR( j = 0; j < 2; j++ )
- {
- y_gain4[j] = 0;
- move16();
- etmp = 42949673; /* 0.02 in Q31 */
- move32();
- etmp_e = 0;
- move16();
-
- pt = exc_diff + shl( j, 3 );
- FOR( i = 0; i < 8; i++ )
- {
- etmp = BASOP_Util_Add_Mant32Exp( etmp, etmp_e, L_mult0( *pt, *pt ), tmp, &etmp_e );
- pt++;
- }
-
- /* normalized to 16 bins to easy the quantization */
- etmp_e = add( etmp_e, 1 );
- etmp = Sqrt32( etmp, &etmp_e );
- etmp = BASOP_Util_Log10( etmp, etmp_e ); // Q25
- y_gain4[j] = extract_h( L_shl( etmp, 3 ) ); // Q12
- move16();
- }
-
- FOR( j = 1; j < Mband - 2; j++ )
- {
- etmp = 21474836; /* 0.01 in Q31 */
- move32();
- etmp_e = 0;
- move16();
-
- pt = exc_diff + shl( j, 4 );
- FOR( i = 0; i < 16; i++ )
- {
- etmp = BASOP_Util_Add_Mant32Exp( etmp, etmp_e, L_mult0( *pt, *pt ), tmp, &etmp_e );
- pt++;
- }
-
- etmp = Sqrt32( etmp, &etmp_e );
- etmp = BASOP_Util_Log10( etmp, etmp_e ); // Q25
- y_gain4[j + 1] = extract_h( L_shl( etmp, 3 ) ); // Q12
- move16();
- }
-
- IF( EQ_16( Eflag, 1 ) )
- {
- etmp = 21474836; /* 0.01 in Q31 */
- move32();
- etmp_e = 0;
- move16();
-
- pt = exc_diff + shl( j, 4 );
- FOR( i = 0; i < 32; i++ )
- {
- etmp = BASOP_Util_Add_Mant32Exp( etmp, etmp_e, L_mult0( *pt, *pt ), tmp, &etmp_e );
- pt++;
- }
-
- etmp_e = sub( etmp_e, 1 );
- etmp = Sqrt32( etmp, &etmp_e );
- etmp = BASOP_Util_Log10( etmp, etmp_e ); // Q25
- y_gain4[j + 1] = extract_h( L_shl( etmp, 3 ) ); // Q12
- move16();
- }
-
- IF( EQ_16( L_frame, L_FRAME16k ) )
- {
- etmp = 21474836; /* 0.01 in Q31 */
- move32();
- etmp_e = 0;
- move16();
-
- FOR( i = 0; i < 32; i++ )
- {
- etmp = BASOP_Util_Add_Mant32Exp( etmp, etmp_e, L_mult0( *pt, *pt ), tmp, &etmp_e );
- pt++;
- }
-
- Word16 tmp2 = sub( etmp_e, 1 );
- L_tmp = Sqrt32( etmp, &tmp2 );
- L_tmp = BASOP_Util_Log10( L_tmp, tmp2 ); // Q25
- y_gain4[j + 2] = extract_h( L_shl( L_tmp, 3 ) ); // Q12
- move16();
-
- FOR( i = 0; i < 32; i++ )
- {
- etmp = BASOP_Util_Add_Mant32Exp( etmp, etmp_e, L_mult0( *pt, *pt ), tmp, &etmp_e );
- pt++;
- }
-
- etmp_e = sub( etmp_e, 1 );
- etmp = Sqrt32( etmp, &etmp_e );
- etmp = BASOP_Util_Log10( etmp, etmp_e ); // Q25
- y_gain4[j + 3] = extract_h( L_shl( etmp, 3 ) ); // Q12
- move16();
- }
-
- return;
-}
/*-------------------------------------------------------------------*
* gsc_gainQ()
*
* Quantization of the energy per band
*-------------------------------------------------------------------*/
+
static void GSC_gain_adj(
const Word16 coder_type, /* i : Coder type */
const Word32 core_brate, /* i : Bit rate */
@@ -550,11 +442,13 @@ static void GSC_gain_adj(
return;
}
+
/*-------------------------------------------------------------------*
* GSC_gain_adj_ivas_fx()
*
* Quantization of the energy per band
*-------------------------------------------------------------------*/
+
static void GSC_gain_adj_ivas_fx(
const Word16 coder_type, /* i : Coder type */
const Word16 Mbands_gn, /* i : Number of band */
@@ -629,6 +523,404 @@ static void GSC_gain_adj_ivas_fx(
return;
}
+
+/*-------------------------------------------------------------------*
+ * GSC_gain_DQ()
+ *
+ * Form the final vector after gain quantization/Dequantization
+ * Common to both encoder and decoder
+ *-------------------------------------------------------------------*/
+
+static void GSC_gain_DQ_fx(
+ const Word16 element_mode, /* i : element mode */
+ const Word16 enc_dec, /* i : encoder/decoder flag */
+ const Word16 coder_type, /* i : Coder type */
+ const Word16 Mbands_gn, /* i : Number of band */
+ const Word32 core_brate, /* i : Core bitrate */
+ const Word16 mean_g, /* i : Average gain Q12 */
+ const Word16 *Gain_in, /* i : Unquantized gain vector Q12 */
+ Word16 *Gain_out /* o : Level adjusted unquantized gain vector Q12 */
+)
+{
+ Word16 Gain_off;
+ Word16 i;
+
+ /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */
+ Gain_off = 0;
+ move16();
+
+ test();
+ IF( coder_type == INACTIVE || EQ_16( coder_type, UNVOICED ) )
+ {
+ test();
+ IF( LE_32( core_brate, ACELP_5k00 ) && EQ_16( coder_type, UNVOICED ) )
+ {
+ Gain_off = 1843; // 9/20 in Q12
+ move16();
+ }
+ ELSE IF( LE_32( core_brate, ACELP_7k20 ) )
+ {
+ Gain_off = 1638; // 8/20 in Q12; /* 0 dB */
+ move16();
+ }
+ ELSE IF( LE_32( core_brate, ACELP_8k00 ) )
+ {
+ Gain_off = 1351; // 6.6f/20 in Q12 /* ~-3.3 dB */
+ move16();
+ }
+ ELSE IF( LE_32( core_brate, ACELP_9k60 ) )
+ {
+ Gain_off = 983; // 4.8f/20 in Q12 /* ~-2.4 dB */
+ move16();
+ }
+ ELSE IF( LE_32( core_brate, ACELP_11k60 ) )
+ {
+ Gain_off = 717; // 3.5f/20 in Q12 /* ~-2.4 dB */
+ move16();
+ }
+ ELSE IF( LE_32( core_brate, ACELP_13k20 ) )
+ {
+ Gain_off = 614; // 3.0f/20 in Q12 /* ~-2.4 dB */
+ move16();
+ }
+ }
+
+ test();
+ IF( coder_type != INACTIVE && NE_16( coder_type, UNVOICED ) )
+ {
+ FOR( i = 0; i < Mbands_gn; i++ )
+ {
+ Gain_out[i] = add( Gain_in[i], mean_g ); // Q12
+ move16();
+ }
+ }
+ ELSE
+ {
+ /*mimic ACELP decay of energy for low rates*/
+ test();
+ IF( element_mode == EVS_MONO && EQ_16( enc_dec, DEC ) )
+ {
+ /* This is to keep EVS mono bit-exact with the standard (there might be a small desynchronization between encoder and decoder but there is no real quality or interop. issue) */
+ FOR( i = 0; i < Mbands_gn; i++ )
+ {
+ Gain_out[i] = add( Gain_out[i], sub( mean_g, mult( Gain_off, div_s( i, Mbands_gn ) ) ) ); // Q12
+ move16();
+ // Gain_out[i] += mean_g - i * ( Gain_off / 20.f ) / ( (float) Mbands_gn );
+ }
+ }
+ ELSE
+ {
+ FOR( i = 0; i < Mbands_gn; i++ )
+ {
+ Gain_out[i] = add( Gain_in[i], sub( mean_g, mult( Gain_off, div_s( i, Mbands_gn ) ) ) ); // Q12
+ move16();
+ // Gain_out[i] = Gain_in[i] + mean_g - ( i * ( Gain_off / 20.f ) / ( (float) Mbands_gn ) );
+ }
+ }
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------*
+ * gsc_gainQ()
+ *
+ * Quantization of the energy per band
+ *-------------------------------------------------------------------*/
+
+Word16 gsc_gainQ_ivas_fx(
+ BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
+ const Word16 element_mode, /* i : element mode */
+ const Word16 idchan, /* i : channel ID */
+ const Word16 y_gain4[],
+ /* i : Energy per band */ // Q12
+ Word16 y_gainQ[],
+ /* o : quantized energy per band */ // Q12
+ const Word32 core_brate, /* i : Core rate */
+ const Word16 coder_type, /* i : coding type */
+ const Word16 bwidth, /* i : input signal bandwidth */
+ const Word16 L_frame, /* i : frame length */
+ const Word16 tdm_LRTD_flag, /* i : LRTD stereo mode flag */
+ const Word32 core_brate_inp /* i : true core bitrate */
+)
+{
+ Word16 y_gain_tmp[MBANDS_GN16k];
+ Word16 y_gain_tmp2[MBANDS_GN16k];
+ Word16 i, idx_g = 0;
+ move16();
+ Word16 mean_4g_fx[1], ftmp1_fx;
+ Word16 Mbands_gn = MBANDS_GN;
+ move16();
+ Word16 y_gain_tmp3[MBANDS_GN];
+ Word32 L_tmp;
+
+ if ( EQ_16( L_frame, L_FRAME16k ) )
+ {
+ Mbands_gn = MBANDS_GN16k;
+ move16();
+ }
+
+ mean_4g_fx[0] = 0;
+ move32();
+
+ test();
+ test();
+ IF( ( EQ_16( coder_type, AUDIO ) || coder_type == INACTIVE ) && bwidth == NB )
+ {
+ L_tmp = 0;
+ move32();
+ FOR( i = 0; i < 10; i++ )
+ {
+ L_tmp = L_add( L_tmp, y_gain4[i] );
+ }
+ L_tmp = L_sub( Mpy_32_16_1( L_tmp, 3277 /* (1/10.0f) in Q15 */ ), 2457 /* 0.6f in Q12 */ ); // Q12
+ ftmp1_fx = extract_l( L_tmp );
+ FOR( i = 0; i < Mbands_gn; i++ )
+ {
+ IF( LT_16( y_gain4[i], ftmp1_fx ) )
+ {
+ y_gain_tmp2[i] = ftmp1_fx; /*Q12*/
+ }
+ ELSE
+ {
+ y_gain_tmp2[i] = y_gain4[i]; /*Q12*/
+ }
+ move16();
+ }
+
+ /* Quantized mean gain without clipping */
+ L_tmp = 0;
+ move32();
+ FOR( i = 0; i < 10; i++ )
+ {
+ L_tmp = L_add( L_tmp, y_gain4[i] );
+ }
+ L_tmp = Mpy_32_16_1( L_tmp, 3277 /* (1/10.0f) in Q15 */ ); // Q12
+ mean_4g_fx[0] = extract_l( L_tmp ); // Q12
+ move16();
+ idx_g = vquant_fx( mean_4g_fx, Gain_meanNB_fx, mean_4g_fx, Gain_mean_dicNB_fx, 1, 64 );
+ push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 );
+
+ FOR( i = 0; i < Mbands_gn; i++ )
+ {
+ y_gain_tmp[i] = sub( y_gain_tmp2[i], mean_4g_fx[0] ); // Q12
+ move16();
+ }
+
+ if ( LT_16( y_gain_tmp[9], -1229 /* -0.3f in Q12 */ ) )
+ {
+ y_gain_tmp[9] = -1229; /* -0.3f in Q12 */
+ move16();
+ }
+
+ set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 );
+ idx_g = vquant_fx( y_gain_tmp, Mean_dic_NB_fx, y_gain_tmp, Gain_dic1_NB_fx, 3, 64 );
+ push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
+
+ IF( LT_32( core_brate, ACELP_9k60 ) )
+ {
+ idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NB_fx, 3, 32 );
+ push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
+
+ idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NB_fx, 4, 16 );
+ push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 );
+ }
+ ELSE
+ {
+ idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NBHR_fx, 3, 64 );
+ push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
+
+ idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NBHR_fx, 4, 128 );
+ push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 7 );
+ }
+
+ test();
+ IF( LE_32( core_brate, ACELP_9k60 ) && coder_type == INACTIVE )
+ {
+ /* Some energy is needed in high band for stat_noise_uv_enc() to be functional in inactive speech */
+ y_gain_tmp[10] = mean_fx( y_gain_tmp + 6, 3 ); /*Q12*/
+ move16();
+ y_gain_tmp[11] = mean_fx( y_gain_tmp + 7, 3 ); /*Q12*/
+ move16();
+ y_gain_tmp[12] = mean_fx( y_gain_tmp + 8, 3 ); /*Q12*/
+ move16();
+ y_gain_tmp[13] = mean_fx( y_gain_tmp + 9, 3 ); /*Q12*/
+ move16();
+ y_gain_tmp[14] = mean_fx( y_gain_tmp + 10, 3 ); /*Q12*/
+ move16();
+ y_gain_tmp[15] = mean_fx( y_gain_tmp + 11, 3 ); /*Q12*/
+ move16();
+ }
+ ELSE
+ {
+ set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 );
+ }
+ }
+ ELSE
+ {
+ L_tmp = 0;
+ move32();
+ FOR( i = 0; i < 16; i++ )
+ {
+ L_tmp = L_add( L_tmp, y_gain4[i] );
+ }
+ L_tmp = Mpy_32_16_1( L_tmp, 2048 /* (1/16.f) in Q15 */ ); // Q12
+ ftmp1_fx = extract_l( L_tmp );
+ FOR( i = 0; i < Mbands_gn; i++ )
+ {
+ IF( LT_16( y_gain4[i], sub( ftmp1_fx, 2457 /* 0.6 in Q12*/ ) ) )
+ {
+ y_gain_tmp2[i] = sub( ftmp1_fx, 2457 /* 0.6 in Q12*/ );
+ }
+ ELSE IF( GT_16( y_gain4[i], add( ftmp1_fx, 2457 /* 0.6 in Q12*/ ) ) )
+ {
+ y_gain_tmp2[i] = add( ftmp1_fx, 2457 /* 0.6 in Q12*/ );
+ }
+ ELSE
+ {
+ y_gain_tmp2[i] = y_gain4[i];
+ }
+ move16();
+ }
+
+ L_tmp = 0;
+ move32();
+ FOR( i = 0; i < 16; i++ )
+ {
+ L_tmp = L_add( L_tmp, y_gain_tmp2[i] );
+ }
+ L_tmp = Mpy_32_16_1( L_tmp, 2048 /* (1/16.f) in Q15 */ ); // Q12
+ mean_4g_fx[0] = extract_l( L_tmp ); // Q12
+ move16();
+ idx_g = vquant_fx( mean_4g_fx, mean_m_fx, mean_4g_fx, mean_gain_dic_fx, 1, 64 );
+ push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 );
+
+ /* Subtraction of the average gain */
+ FOR( i = 0; i < Mbands_gn; i++ )
+ {
+ y_gain_tmp[i] = sub( y_gain_tmp2[i], mean_4g_fx[0] ); // Q12
+ move16();
+ }
+
+ IF( LT_32( core_brate, ACELP_9k60 ) )
+ {
+ /* prediction and quantization of the average gain */
+
+ /*--------------------------------------------------------------------------------------*
+ * Quantization of the first 8 bands
+ * Keep only 4 bands out of the last 8 bands
+ *--------------------------------------------------------------------------------------*/
+
+ Copy( y_gain_tmp, y_gain_tmp2, 8 );
+
+ y_gain_tmp2[8] = y_gain_tmp[8];
+ move16();
+ y_gain_tmp2[9] = y_gain_tmp[10];
+ move16();
+ y_gain_tmp2[10] = y_gain_tmp[12];
+ move16();
+ y_gain_tmp2[11] = y_gain_tmp[14];
+ move16();
+
+ idx_g = 0;
+ move16();
+ idx_g = vquant_fx( y_gain_tmp2, YGain_mean_LR_fx, y_gain_tmp2, YGain_dic1_LR_fx, 3, 32 );
+ push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
+
+ test();
+ test();
+ test();
+ IF( !( coder_type == INACTIVE && tdm_LRTD_flag == 0 && EQ_16( idchan, 1 ) ) || GT_32( core_brate_inp, GSC_LRES_GAINQ_LIMIT ) )
+ {
+ idx_g = vquant_fx( y_gain_tmp2 + 3, YGain_mean_LR_fx + 3, y_gain_tmp2 + 3, YGain_dic2_LR_fx, 4, 32 );
+ push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
+
+ /*----------------------------------------------------------------------*
+ * Vector quantization of the first 8 bands + quantization of the 4 bands out of the last 8
+ * Interpolation of the last 4 bands Q to create bands 8-16
+ *----------------------------------------------------------------------*/
+
+ idx_g = vquant_fx( y_gain_tmp2 + 7, YGain_mean_LR_fx + 7, y_gain_tmp2 + 7, YGain_dic3_LR_fx, 5, 32 );
+ push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
+
+ set16_fx( y_gain_tmp2 + 12, 0, MBANDS_GN - 12 );
+
+ /* Update to quantized vector */
+ Copy( y_gain_tmp2, y_gain_tmp, 8 );
+
+ Copy( y_gain_tmp2 + 8, y_gain_tmp3, 4 );
+ set16_fx( y_gain_tmp + 8, 0, 8 );
+ fft_rel_fx( y_gain_tmp2 + 8, 4, 2 );
+
+ Copy( y_gain_tmp2 + 8, y_gain_tmp + 8, 3 );
+ y_gain_tmp[15] = y_gain_tmp2[11];
+ move16();
+ ifft_rel_fx( y_gain_tmp + 8, 8, 3 );
+
+ FOR( i = 8; i < 16; i++ )
+ {
+ y_gain_tmp[i] = shl( mult( y_gain_tmp[i], 23101 /* 1.41 in Q14 */ ), 1 ); /*Q12*/
+ move16();
+ }
+
+ y_gain_tmp[8] = y_gain_tmp3[0];
+ move16();
+ y_gain_tmp[10] = y_gain_tmp3[1];
+ move16();
+ y_gain_tmp[12] = y_gain_tmp3[2];
+ move16();
+ y_gain_tmp[14] = y_gain_tmp3[3];
+ move16();
+ }
+ ELSE
+ {
+ Copy( y_gain_tmp2, y_gain_tmp, 3 );
+ set16_fx( y_gain_tmp + 3, 0, MBANDS_GN16k - 3 );
+ }
+ }
+ ELSE
+ {
+ IF( EQ_16( L_frame, L_FRAME ) )
+ {
+ idx_g = vquant_fx( y_gain_tmp, YG_mean16_fx, y_gain_tmp, YG_dicMR_1_fx, 4, 64 );
+ push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
+
+ idx_g = vquant_fx( y_gain_tmp + 4, YG_mean16_fx + 4, y_gain_tmp + 4, YG_dicMR_2_fx, 4, 32 );
+ push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
+
+ idx_g = vquant_fx( y_gain_tmp + 8, YG_mean16_fx + 8, y_gain_tmp + 8, YG_dicMR_3_fx, 4, 32 );
+ push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 );
+
+ idx_g = vquant_fx( y_gain_tmp + 12, YG_mean16_fx + 12, y_gain_tmp + 12, YG_dicMR_4_fx, 4, 16 );
+ push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 );
+ }
+ ELSE
+ {
+ idx_g = vquant_fx( y_gain_tmp, YG_mean16HR_fx, y_gain_tmp, YG_dicHR_1_fx, 4, 128 );
+ push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 7 );
+
+ idx_g = vquant_fx( y_gain_tmp + 4, YG_mean16HR_fx + 4, y_gain_tmp + 4, YG_dicHR_2_fx, 4, 64 );
+ push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
+
+ idx_g = vquant_fx( y_gain_tmp + 8, YG_mean16HR_fx + 8, y_gain_tmp + 8, YG_dicHR_3_fx, 4, 64 );
+ push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
+
+ idx_g = vquant_fx( y_gain_tmp + 12, YG_mean16HR_16kHz_fx, y_gain_tmp + 12, YG_dicHR_4_16kHz_fx, 4, 64 );
+ push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 );
+
+ idx_g = vquant_fx( y_gain_tmp + 16, YG_meanL2G_16kHz_fx, y_gain_tmp + 16, YG_dicL2G_16kHz_fx, 2, 8 );
+ push_indice( hBstr, IND_Y_GAIN_HF, idx_g, 3 );
+ }
+ }
+ }
+
+ GSC_gain_DQ_fx( element_mode, ENC, coder_type, Mbands_gn, core_brate, mean_4g_fx[0], y_gain_tmp, y_gainQ );
+
+ return mean_4g_fx[0];
+}
+
+
/*==========================================================================*/
/* FUNCTION : Word16 gsc_gaindec_fx () */
/*--------------------------------------------------------------------------*/
@@ -649,6 +941,7 @@ static void GSC_gain_adj_ivas_fx(
/* RETURN ARGUMENTS : */
/* _ (Word16) : average frequency gain */
/*==========================================================================*/
+
Word16 gsc_gaindec_fx( /* o : average frequency gain */
Decoder_State *st_fx, /* i/o: decoder state structure */
Word16 y_gainQ_fx[], /* o : quantized gain per band */
@@ -786,6 +1079,7 @@ Word16 gsc_gaindec_fx( /* o : average frequency gai
return mean_4g_fx;
}
+
/*==========================================================================*/
/* FUNCTION : Word16 gsc_gaindec_ivas_fx () */
/*--------------------------------------------------------------------------*/
@@ -806,6 +1100,7 @@ Word16 gsc_gaindec_fx( /* o : average frequency gai
/* RETURN ARGUMENTS : */
/* _ (Word16) : average frequency gain */
/*==========================================================================*/
+
Word16 gsc_gaindec_ivas_fx( /* o : average frequency gain */
Decoder_State *st_fx, /* i/o: decoder state structure */
Word16 y_gainQ_fx[], /* o : quantized gain per band Q12 */
@@ -970,11 +1265,13 @@ Word16 gsc_gaindec_ivas_fx( /* o : average frequenc
return mean_4g_fx;
}
+
/*-------------------------------------------------------------------*
* gsc_gainQ()
*
* Quantization of the energy per band
*-------------------------------------------------------------------*/
+
Word16 gsc_gainQ_fx( /*Q12*/
BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */
const Word16 y_gain4[], /* i : Energy per band Q12 */
@@ -1200,11 +1497,14 @@ Word16 gsc_gainQ_fx( /*Q12*/
return mean_4g[0]; /*Q12*/
}
+
+
/*-------------------------------------------------------------------*
* VDQ_vec()
*
* Return the dequantized vector of index
*-------------------------------------------------------------------*/
+
static Word16 VDQ_vec_fx(
Word16 *Qvec_out_fx, /* o: Quanitzed vector */
const Word16 *mean_dic_fx, /* i: average codebook */
diff --git a/lib_com/hq2_core_com.c b/lib_com/hq2_core_com.c
deleted file mode 100644
index 121dae06a1ef18c4cd878c09921758a9d0ced65e..0000000000000000000000000000000000000000
--- a/lib_com/hq2_core_com.c
+++ /dev/null
@@ -1,177 +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_fx.h"
-#include "basop_util.h"
-#include "basop_proto_func.h"
-#include "wmc_auto.h"
-
-
-#define WMC_TOOL_SKIP
-void bit_allocation_second_fx2(
- Word32 *Rk, /* Q16 */
- Word32 *Rk_sort, /* Q16 */
- Word16 BANDS, /* Q0 */
- const Word16 *band_width, /* Q0 */
- Word16 *k_sort, /* Q0 */
- Word16 *k_num, /* Q0 */
- const Word16 *p2a_flags, /* Q0 */
- const Word16 p2a_bands, /* Q0 */
- const Word16 *last_bitalloc, /* Q0 */
- const Word16 input_frame /* Q0 */
-)
-{
- Word16 k, k2 = 0;
- Word16 ever_bits[BANDS_MAX], ever_sort[BANDS_MAX]; /*Q12 */
- Word16 class_flag = 0;
- Word16 rk_temp = 32767, ever_temp = 32767; /*Q12 */
- Word16 exp;
- Word16 tmp;
- Word32 L_tmp;
- move16();
- move16();
- move16();
- move16();
-
-
- FOR( k = 0; k < BANDS; k++ )
- {
- test();
- test();
- IF( ( ( sub( k_sort[k], sub( BANDS, p2a_bands ) ) >= 0 ) && ( sub( p2a_flags[k_sort[k]], 1 ) == 0 ) ) ||
- ( ( sub( k_sort[k], ( BANDS - 2 ) ) >= 0 ) && ( sub( last_bitalloc[k_sort[k] - ( BANDS - 2 )], 1 ) == 0 ) ) )
- {
- exp = norm_s( band_width[k_sort[k]] );
- tmp = shl( band_width[k_sort[k]], exp ); /*Q(exp) */
- tmp = div_s( 16384, tmp ); /*Q(15+14-exp = 29-exp) */
- L_tmp = Mult_32_16( Rk_sort[k], tmp ); /* Q(16+29-exp-15 = 30-exp) */
- tmp = sub( 18, exp );
- ever_bits[k] = extract_l( L_shr( L_tmp, tmp ) ); /*Q12 */
- if ( sub( ever_bits[k], rk_temp ) < 0 )
- {
- rk_temp = ever_bits[k]; /* Q12 */
- k2 = k;
- move16();
- move16();
- }
- class_flag = 1;
- move16();
- }
- }
- IF( class_flag == 0 || sub( input_frame, L_FRAME8k ) == 0 )
- {
- FOR( k = 0; k < BANDS; k++ )
- {
- test();
- IF( sub( k_sort[k], sub( BANDS, p2a_bands ) ) < 0 && Rk_sort[k] > 0 )
- {
- exp = norm_s( band_width[k_sort[k]] );
- tmp = shl( band_width[k_sort[k]], exp ); /*Q(exp) */
- tmp = div_s( 16384, tmp ); /*Q(15+14-exp = 29-exp) */
- L_tmp = Mult_32_16( Rk_sort[k], tmp ); /* Q(16+29-exp-15 = 30-exp) */
- tmp = sub( 18, exp );
- ever_sort[k] = extract_l( L_shr( L_tmp, tmp ) ); /*Q12 */
- move16();
- IF( sub( ever_sort[k], ever_temp ) < 0 )
- {
- ever_temp = ever_sort[k]; /* Q12 */
- move16();
- k2 = k;
- move16();
- }
- }
- }
- }
-
- k_num[0] = k2;
- move16();
- IF( sub( k_sort[k2], sub( BANDS, 1 ) ) == 0 )
- {
- FOR( k = 0; k < BANDS; k++ )
- {
- IF( sub( k_sort[k], sub( k_sort[k2], 1 ) ) == 0 )
- {
- k_num[1] = k; /* Q0 */
- move16();
- }
- }
- }
- ELSE IF( k_sort[k2] == 0 )
- {
- FOR( k = 0; k < BANDS; k++ )
- {
- IF( sub( k_sort[k], add( k_sort[k2], 1 ) ) == 0 )
- {
- k_num[1] = k; /* Q0 */
- move16();
- }
- }
- }
- ELSE
- {
- IF( L_sub( Rk[sub( k_sort[k2], 1 )], Rk[add( k_sort[k2], 1 )] ) < 0 )
- {
- FOR( k = 0; k < BANDS; k++ )
- {
- IF( sub( k_sort[k], sub( k_sort[k2], 1 ) ) == 0 )
- {
- k_num[1] = k; /* Q0 */
- move16();
- }
- }
- }
- ELSE
- {
- FOR( k = 0; k < BANDS; k++ )
- {
- IF( sub( k_sort[k], add( k_sort[k2], 1 ) ) == 0 )
- {
- k_num[1] = k; /* Q0 */
- move16();
- }
- }
- }
- }
-
- return;
-}
-
-#undef WMC_TOOL_SKIP
diff --git a/lib_com/hq_conf.c b/lib_com/hq_conf.c
deleted file mode 100644
index 90a256ceab3e43b00c51885fe3e3ac35efea1113..0000000000000000000000000000000000000000
--- a/lib_com/hq_conf.c
+++ /dev/null
@@ -1,303 +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 "rom_com.h"
-#include "prot_fx.h"
-#include "wmc_auto.h"
-
-
-void hq_configure_fx(
- const Word16 length, /* i : Frame length Q0 */
- const Word16 hqswb_clas, /* i : HQ SWB class Q0 */
- const Word32 core_brate, /* i : Codec bitrate Q0 */
- Word16 *num_sfm, /* o : Total number of subbands Q0 */
- Word16 *nb_sfm, /* o : Total number of coded bands Q0 */
- Word16 *start_norm, /* o : First norm to be SDE encoded Q0 */
- Word16 *num_env_bands, /* o : Number coded envelope bands Q0 */
- Word16 *numnrmibits, /* o : Number of bits in fall-back norm encoding Q0 */
- Word16 *hq_generic_offset, /* o : Freq offset for HQ GENERIC Q0 */
- Word16 *sfmsize, /* o : Subband bandwidths Q0 */
- Word16 *sfm_start, /* o : Subband start coefficients Q0 */
- Word16 *sfm_end /* o : Subband end coefficients Q0 */
-)
-{
- const Word16 *p_sfmsize;
- const Word16 *p_sfm_start;
- const Word16 *p_sfm_end;
- Word16 i, bw_ext;
-
- bw_ext = 0;
- move16();
-
- *start_norm = 0;
- move16();
-
- IF( EQ_16( length, L_SPEC48k ) )
- {
- IF( EQ_16( hqswb_clas, HQ_GEN_FB ) )
- {
- *num_sfm = NB_SFM;
- move16();
- p_sfmsize = band_len_HQ; /* Q0 */
- p_sfm_start = band_start_HQ; /* Q0 */
- p_sfm_end = band_end_HQ; /* Q0 */
-
- IF( GE_32( core_brate, HQ_32k ) )
- {
- *hq_generic_offset = HQ_GENERIC_FOFFSET_32K;
- move16();
- *num_env_bands = SFM_N_STA_10k;
- move16();
- }
- ELSE /*IF(EQ_32(core_brate, HQ_16k40) || EQ_32(core_brate, HQ_24k40))*/
- {
- *hq_generic_offset = HQ_GENERIC_FOFFSET_24K4;
- *num_env_bands = SFM_N_STA_8k;
- move16();
- move16();
- }
- *nb_sfm = *num_sfm;
- move16();
- }
- ELSE
- {
- IF( EQ_16( hqswb_clas, HQ_HARMONIC ) )
- {
- *num_sfm = SFM_N_HARM_FB;
- move16();
- *nb_sfm = SFM_N_HARM_FB;
- move16();
- *num_env_bands = SFM_N_HARM_FB;
- move16();
-
- p_sfmsize = band_len_harm; /* Q0 */
- p_sfm_start = band_start_harm; /* Q0 */
- p_sfm_end = band_end_harm; /* Q0 */
- }
- ELSE IF( EQ_16( hqswb_clas, HQ_HVQ ) )
- {
- IF( LT_32( core_brate, HQ_BWE_CROSSOVER_BRATE ) )
- {
- *num_sfm = SFM_N_HARM_FB;
- move16();
- *nb_sfm = HVQ_THRES_SFM_24k;
- move16();
- *num_env_bands = sub( *num_sfm, *nb_sfm );
- move16();
- *start_norm = HVQ_THRES_SFM_24k;
- move16();
- }
- ELSE
- {
- *num_sfm = SFM_N_HARM_FB;
- move16();
- *nb_sfm = HVQ_THRES_SFM_32k;
- move16();
- *num_env_bands = sub( *num_sfm, *nb_sfm );
- move16();
- *start_norm = HVQ_THRES_SFM_32k;
- move16();
- }
- p_sfmsize = band_len_harm; /* Q0 */
- p_sfm_start = band_start_harm; /* Q0 */
- p_sfm_end = band_end_harm; /* Q0 */
- }
- ELSE
- {
- *num_sfm = NB_SFM;
- move16();
- *nb_sfm = *num_sfm; /* Q0 */
- move16();
- *num_env_bands = NB_SFM;
- move16();
-
- p_sfmsize = band_len_HQ; /* Q0 */
- p_sfm_start = band_start_HQ; /* Q0 */
- p_sfm_end = band_end_HQ; /* Q0 */
- }
- }
- }
- ELSE IF( EQ_16( length, L_SPEC32k ) )
- {
- IF( EQ_16( hqswb_clas, HQ_HARMONIC ) )
- {
- *num_sfm = SFM_N_HARM;
- move16();
- *nb_sfm = SFM_N_HARM;
- move16();
- *num_env_bands = SFM_N_HARM;
- move16();
-
- p_sfmsize = band_len_harm; /* Q0 */
- p_sfm_start = band_start_harm; /* Q0 */
- p_sfm_end = band_end_harm; /* Q0 */
- }
- ELSE IF( EQ_16( hqswb_clas, HQ_HVQ ) )
- {
- IF( LT_32( core_brate, HQ_BWE_CROSSOVER_BRATE ) )
- {
- *num_sfm = SFM_N_HARM;
- move16();
- *nb_sfm = HVQ_THRES_SFM_24k;
- move16();
- *num_env_bands = sub( *num_sfm, *nb_sfm ); /* Q0 */
- move16();
-
- *start_norm = HVQ_THRES_SFM_24k;
- move16();
- }
- ELSE
- {
- *num_sfm = SFM_N_HARM;
- move16();
- *nb_sfm = HVQ_THRES_SFM_32k;
- move16();
- *num_env_bands = sub( *num_sfm, *nb_sfm ); /* Q0 */
- move16();
-
- *start_norm = HVQ_THRES_SFM_32k;
- move16();
- }
- p_sfmsize = band_len_harm;
- p_sfm_start = band_start_harm;
- p_sfm_end = band_end_harm;
- }
- ELSE IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) )
- {
- *num_sfm = SFM_N_SWB;
- move16();
- p_sfmsize = band_len_HQ; /* Q0 */
- p_sfm_start = band_start_HQ; /* Q0 */
- p_sfm_end = band_end_HQ; /* Q0 */
-
- IF( GE_32( core_brate, HQ_32k ) )
- {
- *hq_generic_offset = HQ_GENERIC_FOFFSET_32K;
- move16();
- *num_env_bands = SFM_N_STA_10k;
- move16();
- }
- ELSE /*if( EQ_32(core_brate, HQ_24k40))*/
- {
- *hq_generic_offset = HQ_GENERIC_FOFFSET_24K4;
- move16();
- *num_env_bands = SFM_N_STA_8k;
- move16();
- }
-
- *nb_sfm = *num_sfm;
- move16();
- }
- ELSE
- {
- /* HQ_NORMAL and HQ_TRANSIENT */
- *num_sfm = SFM_N_SWB;
- move16();
- *nb_sfm = *num_sfm;
- move16();
- *num_env_bands = SFM_N_SWB;
- move16();
-
- p_sfmsize = band_len_HQ; /* Q0 */
- p_sfm_start = band_start_HQ; /* Q0 */
- p_sfm_end = band_end_HQ; /* Q0 */
- }
- }
- ELSE IF( EQ_16( length, L_SPEC48k_EXT ) )
- {
- bw_ext = 1;
- p_sfmsize = band_len_HQ; /* Q0 */
- p_sfm_start = band_start_HQ; /* Q0 */
- p_sfm_end = band_end_HQ; /* Q0 */
- *num_sfm = NB_SFM;
- }
- ELSE IF( EQ_16( length, L_SPEC16k_EXT ) )
- {
- bw_ext = 1;
- move16();
- p_sfmsize = band_len_wb; /* Q0 */
- p_sfm_start = band_start_wb; /* Q0 */
- p_sfm_end = band_end_wb; /* Q0 */
- *num_sfm = SFM_N_WB;
- move16();
- }
- ELSE
- {
- *num_sfm = SFM_N_WB;
- move16();
- *nb_sfm = *num_sfm; /* Q0 */
- move16();
- *num_env_bands = SFM_N_WB;
- move16();
-
- p_sfmsize = band_len_wb; /* Q0 */
- p_sfm_start = band_start_wb; /* Q0 */
- p_sfm_end = band_end_wb; /* Q0 */
- }
- IF( bw_ext )
- {
- FOR( i = 0; i < *num_sfm; i++ )
- {
- /*sfmsize[i] = (int16_t)(1.25f * p_sfmsize[i]);*/
- sfmsize[i] = mult_r( shl( p_sfmsize[i], 1 ), 20480 /* 1.25 in Q14 */ ); /* Q0 */
- move16();
- /*sfm_start[i] = (int16_t)(1.25f * p_sfm_start[i]);*/
- sfm_start[i] = mult_r( shl( p_sfm_start[i], 1 ), 20480 /* 1.25 in Q14 */ ); /* Q0 */
- move16();
- /*sfm_end[i] = (int16_t)(1.25f * p_sfm_end[i]);*/
- sfm_end[i] = mult_r( shl( p_sfm_end[i], 1 ), 20480 /* 1.25 in Q14 */ ); /* Q0 */
- move16();
- }
- *nb_sfm = *num_sfm; /* Q0 */
- *num_env_bands = *num_sfm; /* Q0 */
- move16();
- move16();
- }
- ELSE
- {
- Copy( p_sfmsize, sfmsize, *num_sfm );
- Copy( p_sfm_start, sfm_start, *num_sfm );
- Copy( p_sfm_end, sfm_end, *num_sfm );
- }
-
- *numnrmibits = extract_l( L_mult0( sub( *num_env_bands, 1 ), NORMI_BITS ) );
- move16();
-
- return;
-}
diff --git a/lib_com/hq_conf_fx.c b/lib_com/hq_conf_fx.c
index f6a01adfc0d066e7db3de4204037be610dae2b72..b400624487bfbb9c5b3bd897c1d88f791382cbb2 100644
--- a/lib_com/hq_conf_fx.c
+++ b/lib_com/hq_conf_fx.c
@@ -8,6 +8,7 @@
#include "rom_com.h" /* Static table prototypes */
#include "prot_fx.h" /* Function prototypes */
#include "ivas_prot_fx.h"
+#include "wmc_auto.h"
/*--------------------------------------------------------------------------*
* hq_configure()
@@ -538,3 +539,263 @@ void hq_configure_evs_fx(
return;
}
+
+void hq_configure_fx(
+ const Word16 length, /* i : Frame length Q0 */
+ const Word16 hqswb_clas, /* i : HQ SWB class Q0 */
+ const Word32 core_brate, /* i : Codec bitrate Q0 */
+ Word16 *num_sfm, /* o : Total number of subbands Q0 */
+ Word16 *nb_sfm, /* o : Total number of coded bands Q0 */
+ Word16 *start_norm, /* o : First norm to be SDE encoded Q0 */
+ Word16 *num_env_bands, /* o : Number coded envelope bands Q0 */
+ Word16 *numnrmibits, /* o : Number of bits in fall-back norm encoding Q0 */
+ Word16 *hq_generic_offset, /* o : Freq offset for HQ GENERIC Q0 */
+ Word16 *sfmsize, /* o : Subband bandwidths Q0 */
+ Word16 *sfm_start, /* o : Subband start coefficients Q0 */
+ Word16 *sfm_end /* o : Subband end coefficients Q0 */
+)
+{
+ const Word16 *p_sfmsize;
+ const Word16 *p_sfm_start;
+ const Word16 *p_sfm_end;
+ Word16 i, bw_ext;
+
+ bw_ext = 0;
+ move16();
+
+ *start_norm = 0;
+ move16();
+
+ IF( EQ_16( length, L_SPEC48k ) )
+ {
+ IF( EQ_16( hqswb_clas, HQ_GEN_FB ) )
+ {
+ *num_sfm = NB_SFM;
+ move16();
+ p_sfmsize = band_len_HQ; /* Q0 */
+ p_sfm_start = band_start_HQ; /* Q0 */
+ p_sfm_end = band_end_HQ; /* Q0 */
+
+ IF( GE_32( core_brate, HQ_32k ) )
+ {
+ *hq_generic_offset = HQ_GENERIC_FOFFSET_32K;
+ move16();
+ *num_env_bands = SFM_N_STA_10k;
+ move16();
+ }
+ ELSE /*IF(EQ_32(core_brate, HQ_16k40) || EQ_32(core_brate, HQ_24k40))*/
+ {
+ *hq_generic_offset = HQ_GENERIC_FOFFSET_24K4;
+ *num_env_bands = SFM_N_STA_8k;
+ move16();
+ move16();
+ }
+ *nb_sfm = *num_sfm;
+ move16();
+ }
+ ELSE
+ {
+ IF( EQ_16( hqswb_clas, HQ_HARMONIC ) )
+ {
+ *num_sfm = SFM_N_HARM_FB;
+ move16();
+ *nb_sfm = SFM_N_HARM_FB;
+ move16();
+ *num_env_bands = SFM_N_HARM_FB;
+ move16();
+
+ p_sfmsize = band_len_harm; /* Q0 */
+ p_sfm_start = band_start_harm; /* Q0 */
+ p_sfm_end = band_end_harm; /* Q0 */
+ }
+ ELSE IF( EQ_16( hqswb_clas, HQ_HVQ ) )
+ {
+ IF( LT_32( core_brate, HQ_BWE_CROSSOVER_BRATE ) )
+ {
+ *num_sfm = SFM_N_HARM_FB;
+ move16();
+ *nb_sfm = HVQ_THRES_SFM_24k;
+ move16();
+ *num_env_bands = sub( *num_sfm, *nb_sfm );
+ move16();
+ *start_norm = HVQ_THRES_SFM_24k;
+ move16();
+ }
+ ELSE
+ {
+ *num_sfm = SFM_N_HARM_FB;
+ move16();
+ *nb_sfm = HVQ_THRES_SFM_32k;
+ move16();
+ *num_env_bands = sub( *num_sfm, *nb_sfm );
+ move16();
+ *start_norm = HVQ_THRES_SFM_32k;
+ move16();
+ }
+ p_sfmsize = band_len_harm; /* Q0 */
+ p_sfm_start = band_start_harm; /* Q0 */
+ p_sfm_end = band_end_harm; /* Q0 */
+ }
+ ELSE
+ {
+ *num_sfm = NB_SFM;
+ move16();
+ *nb_sfm = *num_sfm; /* Q0 */
+ move16();
+ *num_env_bands = NB_SFM;
+ move16();
+
+ p_sfmsize = band_len_HQ; /* Q0 */
+ p_sfm_start = band_start_HQ; /* Q0 */
+ p_sfm_end = band_end_HQ; /* Q0 */
+ }
+ }
+ }
+ ELSE IF( EQ_16( length, L_SPEC32k ) )
+ {
+ IF( EQ_16( hqswb_clas, HQ_HARMONIC ) )
+ {
+ *num_sfm = SFM_N_HARM;
+ move16();
+ *nb_sfm = SFM_N_HARM;
+ move16();
+ *num_env_bands = SFM_N_HARM;
+ move16();
+
+ p_sfmsize = band_len_harm; /* Q0 */
+ p_sfm_start = band_start_harm; /* Q0 */
+ p_sfm_end = band_end_harm; /* Q0 */
+ }
+ ELSE IF( EQ_16( hqswb_clas, HQ_HVQ ) )
+ {
+ IF( LT_32( core_brate, HQ_BWE_CROSSOVER_BRATE ) )
+ {
+ *num_sfm = SFM_N_HARM;
+ move16();
+ *nb_sfm = HVQ_THRES_SFM_24k;
+ move16();
+ *num_env_bands = sub( *num_sfm, *nb_sfm ); /* Q0 */
+ move16();
+
+ *start_norm = HVQ_THRES_SFM_24k;
+ move16();
+ }
+ ELSE
+ {
+ *num_sfm = SFM_N_HARM;
+ move16();
+ *nb_sfm = HVQ_THRES_SFM_32k;
+ move16();
+ *num_env_bands = sub( *num_sfm, *nb_sfm ); /* Q0 */
+ move16();
+
+ *start_norm = HVQ_THRES_SFM_32k;
+ move16();
+ }
+ p_sfmsize = band_len_harm;
+ p_sfm_start = band_start_harm;
+ p_sfm_end = band_end_harm;
+ }
+ ELSE IF( EQ_16( hqswb_clas, HQ_GEN_SWB ) )
+ {
+ *num_sfm = SFM_N_SWB;
+ move16();
+ p_sfmsize = band_len_HQ; /* Q0 */
+ p_sfm_start = band_start_HQ; /* Q0 */
+ p_sfm_end = band_end_HQ; /* Q0 */
+
+ IF( GE_32( core_brate, HQ_32k ) )
+ {
+ *hq_generic_offset = HQ_GENERIC_FOFFSET_32K;
+ move16();
+ *num_env_bands = SFM_N_STA_10k;
+ move16();
+ }
+ ELSE /*if( EQ_32(core_brate, HQ_24k40))*/
+ {
+ *hq_generic_offset = HQ_GENERIC_FOFFSET_24K4;
+ move16();
+ *num_env_bands = SFM_N_STA_8k;
+ move16();
+ }
+
+ *nb_sfm = *num_sfm;
+ move16();
+ }
+ ELSE
+ {
+ /* HQ_NORMAL and HQ_TRANSIENT */
+ *num_sfm = SFM_N_SWB;
+ move16();
+ *nb_sfm = *num_sfm;
+ move16();
+ *num_env_bands = SFM_N_SWB;
+ move16();
+
+ p_sfmsize = band_len_HQ; /* Q0 */
+ p_sfm_start = band_start_HQ; /* Q0 */
+ p_sfm_end = band_end_HQ; /* Q0 */
+ }
+ }
+ ELSE IF( EQ_16( length, L_SPEC48k_EXT ) )
+ {
+ bw_ext = 1;
+ p_sfmsize = band_len_HQ; /* Q0 */
+ p_sfm_start = band_start_HQ; /* Q0 */
+ p_sfm_end = band_end_HQ; /* Q0 */
+ *num_sfm = NB_SFM;
+ }
+ ELSE IF( EQ_16( length, L_SPEC16k_EXT ) )
+ {
+ bw_ext = 1;
+ move16();
+ p_sfmsize = band_len_wb; /* Q0 */
+ p_sfm_start = band_start_wb; /* Q0 */
+ p_sfm_end = band_end_wb; /* Q0 */
+ *num_sfm = SFM_N_WB;
+ move16();
+ }
+ ELSE
+ {
+ *num_sfm = SFM_N_WB;
+ move16();
+ *nb_sfm = *num_sfm; /* Q0 */
+ move16();
+ *num_env_bands = SFM_N_WB;
+ move16();
+
+ p_sfmsize = band_len_wb; /* Q0 */
+ p_sfm_start = band_start_wb; /* Q0 */
+ p_sfm_end = band_end_wb; /* Q0 */
+ }
+ IF( bw_ext )
+ {
+ FOR( i = 0; i < *num_sfm; i++ )
+ {
+ /*sfmsize[i] = (int16_t)(1.25f * p_sfmsize[i]);*/
+ sfmsize[i] = mult_r( shl( p_sfmsize[i], 1 ), 20480 /* 1.25 in Q14 */ ); /* Q0 */
+ move16();
+ /*sfm_start[i] = (int16_t)(1.25f * p_sfm_start[i]);*/
+ sfm_start[i] = mult_r( shl( p_sfm_start[i], 1 ), 20480 /* 1.25 in Q14 */ ); /* Q0 */
+ move16();
+ /*sfm_end[i] = (int16_t)(1.25f * p_sfm_end[i]);*/
+ sfm_end[i] = mult_r( shl( p_sfm_end[i], 1 ), 20480 /* 1.25 in Q14 */ ); /* Q0 */
+ move16();
+ }
+ *nb_sfm = *num_sfm; /* Q0 */
+ *num_env_bands = *num_sfm; /* Q0 */
+ move16();
+ move16();
+ }
+ ELSE
+ {
+ Copy( p_sfmsize, sfmsize, *num_sfm );
+ Copy( p_sfm_start, sfm_start, *num_sfm );
+ Copy( p_sfm_end, sfm_end, *num_sfm );
+ }
+
+ *numnrmibits = extract_l( L_mult0( sub( *num_env_bands, 1 ), NORMI_BITS ) );
+ move16();
+
+ return;
+}
diff --git a/lib_com/ifft_rel.c b/lib_com/ifft_rel_fx.c
similarity index 100%
rename from lib_com/ifft_rel.c
rename to lib_com/ifft_rel_fx.c
diff --git a/lib_com/int_lsp.c b/lib_com/int_lsp_fx.c
similarity index 100%
rename from lib_com/int_lsp.c
rename to lib_com/int_lsp_fx.c
diff --git a/lib_com/interleave_spectrum.c b/lib_com/interleave_spectrum_fx.c
similarity index 100%
rename from lib_com/interleave_spectrum.c
rename to lib_com/interleave_spectrum_fx.c
diff --git a/lib_com/interpol.c b/lib_com/interpol_fx.c
similarity index 100%
rename from lib_com/interpol.c
rename to lib_com/interpol_fx.c
diff --git a/lib_com/ivas_mcmasa_com-fx.c b/lib_com/ivas_mcmasa_com_fx.c
similarity index 100%
rename from lib_com/ivas_mcmasa_com-fx.c
rename to lib_com/ivas_mcmasa_com_fx.c
diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h
index 8b6cdcac91760e658892ed170ac55ea2b067430a..928736427e945ba397faf130be59b9a890e2a821 100644
--- a/lib_com/ivas_prot_fx.h
+++ b/lib_com/ivas_prot_fx.h
@@ -2127,13 +2127,6 @@ void small_reduction_direction_fx(
const Word16 raw_flag[MASA_MAXIMUM_CODING_SUBBANDS],
Word16 *diff );
-
-void sort_desc_ind_16_fx(
- Word16 *s, /* i/o: vector to be sorted Qx*/
- const Word16 len, /* i : vector length */
- Word16 *ind /* o : array of indices */
-);
-
void sort_desc_ind_32_fx(
Word32 *s, /* i/o: vector to be sorted Qx*/
const Word16 len, /* i : vector length */
@@ -6205,7 +6198,7 @@ void ivas_param_ism_compute_noisy_speech_flag_fx(
* DFT Stereo prototypes
*----------------------------------------------------------------------------------*/
-void stereo_dft_dec_destroy(
+void stereo_dft_dec_destroy_fx(
STEREO_DFT_DEC_DATA_HANDLE *hStereoDft /* i/o: decoder DFT stereo handle */
);
diff --git a/lib_com/lag_wind.c b/lib_com/lag_wind_fx.c
similarity index 100%
rename from lib_com/lag_wind.c
rename to lib_com/lag_wind_fx.c
diff --git a/lib_com/lerp.c b/lib_com/lerp_fx.c
similarity index 100%
rename from lib_com/lerp.c
rename to lib_com/lerp_fx.c
diff --git a/lib_com/modif_fs.c b/lib_com/modif_fs.c
deleted file mode 100644
index 10e64a57deb9efbc548a2416db10d1ec550d66cf..0000000000000000000000000000000000000000
--- a/lib_com/modif_fs.c
+++ /dev/null
@@ -1,469 +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_fx.h"
-#include "rom_com.h"
-#include "wmc_auto.h"
-
-
-/* IVAS 32-bit variant */
-void Interpolate_allpass_steep_fx32(
- const Word32 *in_fx, /* i : input array of size N Qx */
- Word32 *mem_fx, /* i/o: memory Qx */
- const Word16 N, /* i : number of input samples */
- Word32 *out_fx /* o : output array of size 2*N Qx */
-)
-{
- Word16 n, k;
- Word32 temp_fx[ALLPASSSECTIONS_STEEP - 1];
-
- /* upper allpass filter chain */
- FOR( k = 0; k < N; k++ )
- {
- temp_fx[0] = Madd_32_16( mem_fx[0], in_fx[k], AP2_STEEP_FX[0] ); // Qx
- move32();
- mem_fx[0] = Msub_32_16( in_fx[k], temp_fx[0], AP2_STEEP_FX[0] ); // Qx
- move32();
-
- /* for better performance, unroll this loop */
- FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ )
- {
- temp_fx[n] = Madd_32_16( mem_fx[n], temp_fx[n - 1], AP2_STEEP_FX[n] ); // Qx
- move32();
- mem_fx[n] = Msub_32_16( temp_fx[n - 1], temp_fx[n], AP2_STEEP_FX[n] ); // Qx
- move32();
- }
-
- out_fx[2 * k + 1] = Madd_32_16( mem_fx[ALLPASSSECTIONS_STEEP - 1], temp_fx[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
- move32();
- mem_fx[ALLPASSSECTIONS_STEEP - 1] = Msub_32_16( temp_fx[ALLPASSSECTIONS_STEEP - 2], out_fx[2 * k + 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
- move32();
- }
-
- /* lower allpass filter chain */
- FOR( k = 0; k < N; k++ )
- {
- temp_fx[0] = Madd_32_16( mem_fx[ALLPASSSECTIONS_STEEP], in_fx[k], AP1_STEEP_FX[0] ); // Qx
- move32();
- mem_fx[ALLPASSSECTIONS_STEEP] = Msub_32_16( in_fx[k], temp_fx[0], AP1_STEEP_FX[0] ); // Qx
- move32();
-
- /* for better performance, unroll this loop */
- FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ )
- {
- temp_fx[n] = Madd_32_16( mem_fx[ALLPASSSECTIONS_STEEP + n], temp_fx[n - 1], AP1_STEEP_FX[n] ); // Qx
- move32();
- mem_fx[ALLPASSSECTIONS_STEEP + n] = Msub_32_16( temp_fx[n - 1], temp_fx[n], AP1_STEEP_FX[n] ); // Qx
- move32();
- }
-
- out_fx[2 * k] = Madd_32_16( mem_fx[2 * ALLPASSSECTIONS_STEEP - 1], temp_fx[ALLPASSSECTIONS_STEEP - 2], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
- move32();
- mem_fx[2 * ALLPASSSECTIONS_STEEP - 1] = Msub_32_16( temp_fx[ALLPASSSECTIONS_STEEP - 2], out_fx[2 * k], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
- move32();
- }
-
- return;
-}
-
-/* IVAS 32-bit variant */
-void Decimate_allpass_steep_fx32(
- const Word32 *in, /* i : input array of size N Qx */
- Word32 *mem, /* i/o: memory Qx */
- const Word16 N, /* i : number of input samples */
- Word32 *out /* o : output array of size N/2 Qx */
-)
-{
- Word16 n, k;
- Word32 temp[ALLPASSSECTIONS_STEEP];
-
- /* upper allpass filter chain */
- FOR( k = 0; k < N / 2; k++ )
- {
-#ifdef OPT_STEREO_32KBPS_V1
- temp[0] = Madd_32_16( mem[0], in[2 * k], AP1_STEEP_FX[0] ); // Qx
- move32();
- mem[0] = Msub_32_16( in[2 * k], temp[0], AP1_STEEP_FX[0] ); // Qx
- move32();
-
- temp[1] = Madd_32_16( mem[1], temp[0], AP1_STEEP_FX[1] ); // Qx
- move32();
- mem[1] = Msub_32_16( temp[0], temp[1], AP1_STEEP_FX[1] ); // Qx
- move32();
-
- out[k] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP - 1], temp[ALLPASSSECTIONS_STEEP - 2], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
- move32();
- mem[ALLPASSSECTIONS_STEEP - 1] = Msub_32_16( temp[ALLPASSSECTIONS_STEEP - 2], out[k], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
- move32();
-#else /* OPT_STEREO_32KBPS_V1 */
- temp[0] = L_add( mem[0], Mpy_32_16_1( in[2 * k], AP1_STEEP_FX[0] ) ); // Qx
- move32();
- mem[0] = L_sub( in[2 * k], Mpy_32_16_1( temp[0], AP1_STEEP_FX[0] ) ); // Qx
- move32();
-
- temp[1] = L_add( mem[1], Mpy_32_16_1( temp[0], AP1_STEEP_FX[1] ) ); // Qx
- move32();
- mem[1] = L_sub( temp[0], Mpy_32_16_1( temp[1], AP1_STEEP_FX[1] ) ); // Qx
- move32();
-
- out[k] = L_add( mem[ALLPASSSECTIONS_STEEP - 1], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 2], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx
- move32();
- mem[ALLPASSSECTIONS_STEEP - 1] = L_sub( temp[ALLPASSSECTIONS_STEEP - 2], Mpy_32_16_1( out[k], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx
- move32();
-#endif /* OPT_STEREO_32KBPS_V1 */
- }
-
- /* lower allpass filter chain */
-#ifdef OPT_STEREO_32KBPS_V1
- temp[0] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP], mem[2 * ALLPASSSECTIONS_STEEP], AP2_STEEP_FX[0] ); // Qx
- move32();
- mem[ALLPASSSECTIONS_STEEP] = Msub_32_16( mem[2 * ALLPASSSECTIONS_STEEP], temp[0], AP2_STEEP_FX[0] ); // Qx
- move32();
-#else /* OPT_STEREO_32KBPS_V1 */
- temp[0] = L_add( mem[ALLPASSSECTIONS_STEEP], Mpy_32_16_1( mem[2 * ALLPASSSECTIONS_STEEP], AP2_STEEP_FX[0] ) ); // Qx
- move32();
- mem[ALLPASSSECTIONS_STEEP] = L_sub( mem[2 * ALLPASSSECTIONS_STEEP], Mpy_32_16_1( temp[0], AP2_STEEP_FX[0] ) ); // Qx
- move32();
-#endif /* OPT_STEREO_32KBPS_V1 */
-
- /* for better performance, unroll this loop */
- FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ )
- {
-#ifdef OPT_STEREO_32KBPS_V1
- temp[n] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP + n], temp[n - 1], AP2_STEEP_FX[n] ); // Qx
- move32();
- mem[ALLPASSSECTIONS_STEEP + 1] = Msub_32_16( temp[n - 1], temp[n], AP2_STEEP_FX[n] ); // Qx
- move32();
-#else /* OPT_STEREO_32KBPS_V1 */
- temp[n] = L_add( mem[ALLPASSSECTIONS_STEEP + n], Mpy_32_16_1( temp[n - 1], AP2_STEEP_FX[n] ) ); // Qx
- move32();
- /*if ( fabs( temp[n] ) < 1e-12 )
- {
- temp[n] = sign( temp[n] ) * 1e-12f;
- }*/
- mem[ALLPASSSECTIONS_STEEP + 1] = L_sub( temp[n - 1], Mpy_32_16_1( temp[n], AP2_STEEP_FX[n] ) ); // Qx
- move32();
-#endif /* OPT_STEREO_32KBPS_V1 */
- }
-
-#ifdef OPT_STEREO_32KBPS_V1
- temp[ALLPASSSECTIONS_STEEP - 1] = Madd_32_16( mem[2 * ALLPASSSECTIONS_STEEP - 1], temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
- move32();
-
- mem[2 * ALLPASSSECTIONS_STEEP - 1] = Msub_32_16( temp[ALLPASSSECTIONS_STEEP - 2], temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
- move32();
-#else /* OPT_STEREO_32KBPS_V1 */
- temp[ALLPASSSECTIONS_STEEP - 1] = L_add( mem[2 * ALLPASSSECTIONS_STEEP - 1], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx
- move32();
-
- mem[2 * ALLPASSSECTIONS_STEEP - 1] = L_sub( temp[ALLPASSSECTIONS_STEEP - 2], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx
- move32();
-#endif /* OPT_STEREO_32KBPS_V1 */
- out[0] = W_round48_L( W_mac_32_16( W_mult_32_16( out[0], 16384 /*0.5 in Q15*/ ), temp[ALLPASSSECTIONS_STEEP - 1], 16384 /*0.5 in Q15*/ ) ); // Qx
- move32();
-
- FOR( k = 1; k < N / 2; k++ )
- {
-#ifdef OPT_STEREO_32KBPS_V1
- temp[0] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP], in[2 * k - 1], AP2_STEEP_FX[0] ); // Qx
- move32();
- mem[ALLPASSSECTIONS_STEEP] = Msub_32_16( in[2 * k - 1], temp[0], AP2_STEEP_FX[0] ); // Qx
- move32();
-#else /* OPT_STEREO_32KBPS_V1 */
- temp[0] = L_add( mem[ALLPASSSECTIONS_STEEP], Mpy_32_16_1( in[sub( shl( k, 1 ), 1 )], AP2_STEEP_FX[0] ) ); // Qx
- move32();
- mem[ALLPASSSECTIONS_STEEP] = L_sub( in[sub( shl( k, 1 ), 1 )], Mpy_32_16_1( temp[0], AP2_STEEP_FX[0] ) ); // Qx
- move32();
-#endif /* OPT_STEREO_32KBPS_V1 */
-
- /* for better performance, unroll this loop */
- FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ )
- {
-#ifdef OPT_STEREO_32KBPS_V1
- temp[n] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP + n], temp[n - 1], AP2_STEEP_FX[n] ); // Qx
- move32();
- mem[ALLPASSSECTIONS_STEEP + n] = Msub_32_16( temp[n - 1], temp[n], AP2_STEEP_FX[n] ); // Qx
- move32();
-#else /* OPT_STEREO_32KBPS_V1 */
- temp[n] = L_add( mem[ALLPASSSECTIONS_STEEP + n], Mpy_32_16_1( temp[n - 1], AP2_STEEP_FX[n] ) ); // Qx
- move32();
- /*if ( fabs( temp[n] ) < 1e-12 )
- {
- temp[n] = sign( temp[n] ) * 1e-12f;
- }*/
- mem[ALLPASSSECTIONS_STEEP + n] = L_sub( temp[n - 1], Mpy_32_16_1( temp[n], AP2_STEEP_FX[n] ) ); // Qx
- move32();
-#endif /* OPT_STEREO_32KBPS_V1 */
- }
-
-#ifdef OPT_STEREO_32KBPS_V1
- temp[ALLPASSSECTIONS_STEEP - 1] = Madd_32_16( mem[2 * ALLPASSSECTIONS_STEEP - 1], temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
- move32();
- mem[2 * ALLPASSSECTIONS_STEEP - 1] = Msub_32_16( temp[ALLPASSSECTIONS_STEEP - 2], temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
- move32();
-#else /* OPT_STEREO_32KBPS_V1 */
- temp[ALLPASSSECTIONS_STEEP - 1] = L_add( mem[2 * ALLPASSSECTIONS_STEEP - 1], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx
- move32();
- mem[2 * ALLPASSSECTIONS_STEEP - 1] = L_sub( temp[ALLPASSSECTIONS_STEEP - 2], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx
- move32();
-#endif /* OPT_STEREO_32KBPS_V1 */
- out[k] = W_round48_L( W_mac_32_16( W_mult_32_16( out[k], 16384 /*0.5 in Q15*/ ), temp[ALLPASSSECTIONS_STEEP - 1], 16384 /*0.5 in Q15*/ ) ); // Qx
- move32();
- }
-
- /* z^(-1) */
- mem[2 * ALLPASSSECTIONS_STEEP] = in[N - 1];
- move32();
-
- return;
-}
-
-/* IVAS 32-bit variant */
-void interpolate_3_over_2_allpass_fx32(
- const Word32 *input, /* i : input signal Qx*/
- const Word16 len, /* i : number of input samples */
- Word32 *out, /* o : output signal Qx*/
- Word32 *mem /* i/o: memory Qx*/
-)
-{
- Word16 i, loop_len;
- Word32 Vu[2], Vm[2], Vl[2]; /* Outputs of three cascaded allpass stages (upper, middle, and lower) */
- Word32 out1_buff[L_FRAME32k * 3];
- Word32 *out1;
- Word32 mem_temp;
- const Word16 *filt_coeff = allpass_poles_3_ov_2; // Q15
-
- out1 = out1_buff;
-
- FOR( i = 0; i < len; i++ )
- {
- /* Upper branch */
-#ifdef OPT_STEREO_32KBPS_V1
- Vu[0] = Madd_32_16( mem[0], L_sub( input[i], mem[1] ), filt_coeff[0] ); // Qx + Q15 - Q15 -> Qx
- move32();
- Vu[1] = Madd_32_16( mem[1], L_sub( Vu[0], mem[2] ), filt_coeff[1] ); // Qx + Q15 - Q15 -> Qx
- move32();
- mem[3] = Madd_32_16( mem[2], L_sub( Vu[1], mem[3] ), filt_coeff[2] ); // Qx + Q15 - Q15 -> Qx
- move32();
-#else /* OPT_STEREO_32KBPS_V1 */
- Vu[0] = L_add( mem[0], Mpy_32_16_1( L_sub( input[i], mem[1] ), filt_coeff[0] ) ); // Qx + Q15 - Q15 -> Qx
- move32();
- Vu[1] = L_add( mem[1], Mpy_32_16_1( L_sub( Vu[0], mem[2] ), filt_coeff[1] ) ); // Qx + Q15 - Q15 -> Qx
- move32();
- mem[3] = L_add( mem[2], Mpy_32_16_1( L_sub( Vu[1], mem[3] ), filt_coeff[2] ) ); // Qx + Q15 - Q15 -> Qx
- move32();
-#endif /* OPT_STEREO_32KBPS_V1 */
-
- mem[1] = Vu[0]; // Qx
- move32();
- mem[2] = Vu[1]; // Qx
- move32();
- *out1++ = mem[3]; // Qx
- move32();
-
- /* Middle branch */
-#ifdef OPT_STEREO_32KBPS_V1
- Vm[0] = Madd_32_16( mem[0], L_sub( input[i], mem[4] ), filt_coeff[3] ); // Qx + Q15 - Q15 -> Qx
- move32();
- Vm[1] = Madd_32_16( mem[4], L_sub( Vm[0], mem[5] ), filt_coeff[4] ); // Qx + Q15 - Q15 -> Qx
- move32();
- mem[6] = Madd_32_16( mem[5], L_sub( Vm[1], mem[6] ), filt_coeff[5] ); // Qx + Q15 - Q15 -> Qx
- move32();
-#else /* OPT_STEREO_32KBPS_V1 */
- Vm[0] = L_add( mem[0], Mpy_32_16_1( L_sub( input[i], mem[4] ), filt_coeff[3] ) ); // Qx + Q15 - Q15 -> Qx
- move32();
- Vm[1] = L_add( mem[4], Mpy_32_16_1( L_sub( Vm[0], mem[5] ), filt_coeff[4] ) ); // Qx + Q15 - Q15 -> Qx
- move32();
- mem[6] = L_add( mem[5], Mpy_32_16_1( L_sub( Vm[1], mem[6] ), filt_coeff[5] ) ); // Qx + Q15 - Q15 -> Qx
- move32();
-#endif /* OPT_STEREO_32KBPS_V1 */
-
- mem[4] = Vm[0]; // Qx
- move32();
- mem[5] = Vm[1]; // Qx
- move32();
- *out1++ = mem[6]; // Qx
- move32();
-
- /* Lower branch */
-#ifdef OPT_STEREO_32KBPS_V1
- Vl[0] = Madd_32_16( mem[0], L_sub( input[i], mem[7] ), filt_coeff[6] ); // Qx + Q15 - Q15 -> Qx
- move32();
- Vl[1] = Madd_32_16( mem[7], L_sub( Vl[0], mem[8] ), filt_coeff[7] ); // Qx + Q15 - Q15 -> Qx
- move32();
- mem[9] = Madd_32_16( mem[8], L_sub( Vl[1], mem[9] ), filt_coeff[8] ); // Qx + Q15 - Q15 -> Qx
- move32();
-#else /* OPT_STEREO_32KBPS_V1 */
- Vl[0] = L_add( mem[0], Mpy_32_16_1( L_sub( input[i], mem[7] ), filt_coeff[6] ) ); // Qx + Q15 - Q15 -> Qx
- move32();
- Vl[1] = L_add( mem[7], Mpy_32_16_1( L_sub( Vl[0], mem[8] ), filt_coeff[7] ) ); // Qx + Q15 - Q15 -> Qx
- move32();
- mem[9] = L_add( mem[8], Mpy_32_16_1( L_sub( Vl[1], mem[9] ), filt_coeff[8] ) ); // Qx + Q15 - Q15 -> Qx
- move32();
-#endif /* OPT_STEREO_32KBPS_V1 */
-
- mem[0] = input[i]; // Qx
- move32();
- mem[7] = Vl[0]; // Qx
- move32();
- mem[8] = Vl[1]; // Qx
- move32();
- *out1++ = mem[9]; // Qx
- move32();
- }
-
- loop_len = shr( i_mult( len, 3 ), 1 );
-
- /*decimate by 2 and LPF*/
- FOR( i = 0; i < loop_len; i++ )
- {
- mem_temp = out1_buff[2 * i];
- move32();
-#ifdef OPT_STEREO_32KBPS_V1
- out[i] = Madd_32_16( Mpy_32_16_1( L_add( mem_temp, mem[10] ), 1550 ), L_add( mem[11], mem[14] ), -4965 ); // Qx + Q15 - Q15 -> Qx
- // 0.0473147f in Q15 -> 1550, -0.151521f in Q15 -> -4965
- out[i] = Madd_32_16( out[i], L_add( mem[12], mem[13] ), 20125 );
- // 0.614152f in Q15 -> 20125
-#else /* OPT_STEREO_32KBPS_V1 */
- out[i] = L_add( Mpy_32_16_1( L_add( mem_temp, mem[10] ), 1550 ), Mpy_32_16_1( L_add( mem[11], mem[14] ), -4965 ) ); // Qx + Q15 - Q15 -> Qx
- // 0.0473147f in Q15 -> 1550, -0.151521f in Q15 -> -4965
- out[i] = L_add( out[i], Mpy_32_16_1( L_add( mem[12], mem[13] ), 20125 ) );
- // 0.614152f in Q15 -> 20125
-#endif /* OPT_STEREO_32KBPS_V1 */
- mem[10] = mem[11]; // Qx
- move32();
- mem[11] = mem[12]; // Qx
- move32();
- mem[12] = mem[13]; // Qx
- move32();
- mem[13] = mem[14]; // Qx
- move32();
- mem[14] = mem_temp; // Qx
- move32();
- }
-
- return;
-}
-
-/* IVAS 32-bit variant */
-void interpolate_3_over_1_allpass_fx32(
- const Word32 *input, /* i : input signal Qx */
- const Word16 len, /* i : number of input samples */
- Word32 *out, /* o : output signal */
- Word32 *mem /* i/o: memory */
-)
-{
- Word16 i, tmp16;
- Word32 Vu[2], Vm[2], Vl[2]; /* Outputs of three cascaded allpass stages (upper, middle, and lower) */
- Word32 *out1;
- Word32 mem_temp;
- const Word16 *filt_coeff = allpass_poles_3_ov_2; // Qx
-
- out1 = &out[0];
-
- FOR( i = 0; i < len; i++ )
- {
- /* Upper branch */
- Vu[0] = L_add_sat( mem[0], Mpy_32_16_1( L_sub( input[i], mem[1] ), filt_coeff[0] ) ); // Qx
- move32();
- Vu[1] = L_add_sat( mem[1], Mpy_32_16_1( L_sub( Vu[0], mem[2] ), filt_coeff[1] ) ); // Qx
- move32();
- mem[3] = L_add_sat( mem[2], Mpy_32_16_1( L_sub( Vu[1], mem[3] ), filt_coeff[2] ) ); // Qx
- move32();
-
- mem[1] = Vu[0]; // Qx
- move32();
- mem[2] = Vu[1]; // Qx
- move32();
- *out1++ = mem[3]; // Qx
- move32();
-
- /* Middle branch */
- Vm[0] = L_add_sat( mem[0], Mpy_32_16_1( L_sub( input[i], mem[4] ), filt_coeff[3] ) ); // Qx
- move32();
- Vm[1] = L_add_sat( mem[4], Mpy_32_16_1( L_sub( Vm[0], mem[5] ), filt_coeff[4] ) ); // Qx
- move32();
- mem[6] = L_add_sat( mem[5], Mpy_32_16_1( L_sub( Vm[1], mem[6] ), filt_coeff[5] ) ); // Qx
- move32();
-
- mem[4] = Vm[0]; // Qx
- move32();
- mem[5] = Vm[1]; // Qx
- move32();
- *out1++ = mem[6]; // Qx
- move32();
-
- /* Lower branch */
- Vl[0] = L_add_sat( mem[0], Mpy_32_16_1( L_sub( input[i], mem[7] ), filt_coeff[6] ) ); // Qx
- move32();
- Vl[1] = L_add_sat( mem[7], Mpy_32_16_1( L_sub( Vl[0], mem[8] ), filt_coeff[7] ) ); // Qx
- move32();
- mem[9] = L_add_sat( mem[8], Mpy_32_16_1( L_sub( Vl[1], mem[9] ), filt_coeff[8] ) ); // Qx
- move32();
-
- mem[0] = input[i]; // Qx
- move32();
- mem[7] = Vl[0]; // Qx
- move32();
- mem[8] = Vl[1]; // Qx
- move32();
- *out1++ = mem[9]; // Qx
- move32();
- }
-
- /*LPF*/
- tmp16 = imult1616( len, 3 );
- FOR( i = 0; i < tmp16; i++ )
- {
- mem_temp = out[i]; // Qx
- move32();
- out[i] = L_sub_sat( Mpy_32_16_1( L_add_sat( mem[12], mem[11] ), 18768 ), Mpy_32_16_1( L_add_sat( mem_temp, mem[10] ), 2424 ) ); // Qx
- // 0.572769 in Q15 -> 18768, 0.074005 in Q15 -> 2424
- move32();
- mem[10] = mem[11]; // Qx
- move32();
- mem[11] = mem[12]; // Qx
- move32();
- mem[12] = mem_temp; // Qx
- move32();
- }
-
- return;
-}
diff --git a/lib_com/modif_fs_fx.c b/lib_com/modif_fs_fx.c
index bcbff13d57bebe95c3159b1b75e34fdc517fad79..2e39af523138f176abf849628d6f8ea46e6b6a29 100644
--- a/lib_com/modif_fs_fx.c
+++ b/lib_com/modif_fs_fx.c
@@ -3,6 +3,7 @@
====================================================================================*/
#include
+#include
#include "options.h" /* Compilation switches */
#include "cnst.h" /* Common constants */
#include "prot_fx.h"
@@ -11,6 +12,8 @@
#include "rom_enc.h" /* prototypes */
#include "basop_util.h"
#include "ivas_prot_fx.h"
+#include "wmc_auto.h"
+
/*-----------------------------------------------------------------*
* Local functions
@@ -39,6 +42,7 @@
/*------------------------------------------------------------------------------*/
/* CALLED FROM : TX/RX */
/*==============================================================================*/
+
Word16 modify_Fs_ivas_fx( /* o : length of output Q0 */
const Word16 sigIn_fx[], /* i : signal to decimate Q0 */
Word16 lg, /* i : length of input Q0 */
@@ -323,6 +327,7 @@ Word16 modify_Fs_ivas_fx( /* o : length of output Q
return lg_out;
}
+
Word16 modify_Fs_fx( /* o : length of output Q0 */
const Word16 sigIn_fx[], /* i : signal to decimate Q0 */
Word16 lg, /* i : length of input Q0 */
@@ -599,6 +604,7 @@ Word16 modify_Fs_fx( /* o : length of output Q0 */
return lg_out;
}
+
/*-------------------------------------------------------------------*
* modify_Fs_intcub3m_sup()
*
@@ -911,7 +917,6 @@ Word16 modify_Fs_intcub3m_sup_fx( /* o : length of output
/* RETURN ARGUMENTS : _ None. */
/*===================================================================*/
-
void Decimate_allpass_steep_fx(
const Word16 *in_fx,
Word16 mem[], /* array of size: 2*ALLPASSSECTIONS_STEEP+1 */
@@ -1040,6 +1045,158 @@ void Decimate_allpass_steep_fx(
move16(); /* Qx */
}
+/* IVAS 32-bit variant */
+void Decimate_allpass_steep_fx32(
+ const Word32 *in, /* i : input array of size N Qx */
+ Word32 *mem, /* i/o: memory Qx */
+ const Word16 N, /* i : number of input samples */
+ Word32 *out /* o : output array of size N/2 Qx */
+)
+{
+ Word16 n, k;
+ Word32 temp[ALLPASSSECTIONS_STEEP];
+
+ /* upper allpass filter chain */
+ FOR( k = 0; k < N / 2; k++ )
+ {
+#ifdef OPT_STEREO_32KBPS_V1
+ temp[0] = Madd_32_16( mem[0], in[2 * k], AP1_STEEP_FX[0] ); // Qx
+ move32();
+ mem[0] = Msub_32_16( in[2 * k], temp[0], AP1_STEEP_FX[0] ); // Qx
+ move32();
+
+ temp[1] = Madd_32_16( mem[1], temp[0], AP1_STEEP_FX[1] ); // Qx
+ move32();
+ mem[1] = Msub_32_16( temp[0], temp[1], AP1_STEEP_FX[1] ); // Qx
+ move32();
+
+ out[k] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP - 1], temp[ALLPASSSECTIONS_STEEP - 2], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
+ move32();
+ mem[ALLPASSSECTIONS_STEEP - 1] = Msub_32_16( temp[ALLPASSSECTIONS_STEEP - 2], out[k], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
+ move32();
+#else /* OPT_STEREO_32KBPS_V1 */
+ temp[0] = L_add( mem[0], Mpy_32_16_1( in[2 * k], AP1_STEEP_FX[0] ) ); // Qx
+ move32();
+ mem[0] = L_sub( in[2 * k], Mpy_32_16_1( temp[0], AP1_STEEP_FX[0] ) ); // Qx
+ move32();
+
+ temp[1] = L_add( mem[1], Mpy_32_16_1( temp[0], AP1_STEEP_FX[1] ) ); // Qx
+ move32();
+ mem[1] = L_sub( temp[0], Mpy_32_16_1( temp[1], AP1_STEEP_FX[1] ) ); // Qx
+ move32();
+
+ out[k] = L_add( mem[ALLPASSSECTIONS_STEEP - 1], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 2], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx
+ move32();
+ mem[ALLPASSSECTIONS_STEEP - 1] = L_sub( temp[ALLPASSSECTIONS_STEEP - 2], Mpy_32_16_1( out[k], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx
+ move32();
+#endif /* OPT_STEREO_32KBPS_V1 */
+ }
+
+ /* lower allpass filter chain */
+#ifdef OPT_STEREO_32KBPS_V1
+ temp[0] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP], mem[2 * ALLPASSSECTIONS_STEEP], AP2_STEEP_FX[0] ); // Qx
+ move32();
+ mem[ALLPASSSECTIONS_STEEP] = Msub_32_16( mem[2 * ALLPASSSECTIONS_STEEP], temp[0], AP2_STEEP_FX[0] ); // Qx
+ move32();
+#else /* OPT_STEREO_32KBPS_V1 */
+ temp[0] = L_add( mem[ALLPASSSECTIONS_STEEP], Mpy_32_16_1( mem[2 * ALLPASSSECTIONS_STEEP], AP2_STEEP_FX[0] ) ); // Qx
+ move32();
+ mem[ALLPASSSECTIONS_STEEP] = L_sub( mem[2 * ALLPASSSECTIONS_STEEP], Mpy_32_16_1( temp[0], AP2_STEEP_FX[0] ) ); // Qx
+ move32();
+#endif /* OPT_STEREO_32KBPS_V1 */
+
+ /* for better performance, unroll this loop */
+ FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ )
+ {
+#ifdef OPT_STEREO_32KBPS_V1
+ temp[n] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP + n], temp[n - 1], AP2_STEEP_FX[n] ); // Qx
+ move32();
+ mem[ALLPASSSECTIONS_STEEP + 1] = Msub_32_16( temp[n - 1], temp[n], AP2_STEEP_FX[n] ); // Qx
+ move32();
+#else /* OPT_STEREO_32KBPS_V1 */
+ temp[n] = L_add( mem[ALLPASSSECTIONS_STEEP + n], Mpy_32_16_1( temp[n - 1], AP2_STEEP_FX[n] ) ); // Qx
+ move32();
+ /*if ( fabs( temp[n] ) < 1e-12 )
+ {
+ temp[n] = sign( temp[n] ) * 1e-12f;
+ }*/
+ mem[ALLPASSSECTIONS_STEEP + 1] = L_sub( temp[n - 1], Mpy_32_16_1( temp[n], AP2_STEEP_FX[n] ) ); // Qx
+ move32();
+#endif /* OPT_STEREO_32KBPS_V1 */
+ }
+
+#ifdef OPT_STEREO_32KBPS_V1
+ temp[ALLPASSSECTIONS_STEEP - 1] = Madd_32_16( mem[2 * ALLPASSSECTIONS_STEEP - 1], temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
+ move32();
+
+ mem[2 * ALLPASSSECTIONS_STEEP - 1] = Msub_32_16( temp[ALLPASSSECTIONS_STEEP - 2], temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
+ move32();
+#else /* OPT_STEREO_32KBPS_V1 */
+ temp[ALLPASSSECTIONS_STEEP - 1] = L_add( mem[2 * ALLPASSSECTIONS_STEEP - 1], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx
+ move32();
+
+ mem[2 * ALLPASSSECTIONS_STEEP - 1] = L_sub( temp[ALLPASSSECTIONS_STEEP - 2], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx
+ move32();
+#endif /* OPT_STEREO_32KBPS_V1 */
+ out[0] = W_round48_L( W_mac_32_16( W_mult_32_16( out[0], 16384 /*0.5 in Q15*/ ), temp[ALLPASSSECTIONS_STEEP - 1], 16384 /*0.5 in Q15*/ ) ); // Qx
+ move32();
+
+ FOR( k = 1; k < N / 2; k++ )
+ {
+#ifdef OPT_STEREO_32KBPS_V1
+ temp[0] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP], in[2 * k - 1], AP2_STEEP_FX[0] ); // Qx
+ move32();
+ mem[ALLPASSSECTIONS_STEEP] = Msub_32_16( in[2 * k - 1], temp[0], AP2_STEEP_FX[0] ); // Qx
+ move32();
+#else /* OPT_STEREO_32KBPS_V1 */
+ temp[0] = L_add( mem[ALLPASSSECTIONS_STEEP], Mpy_32_16_1( in[sub( shl( k, 1 ), 1 )], AP2_STEEP_FX[0] ) ); // Qx
+ move32();
+ mem[ALLPASSSECTIONS_STEEP] = L_sub( in[sub( shl( k, 1 ), 1 )], Mpy_32_16_1( temp[0], AP2_STEEP_FX[0] ) ); // Qx
+ move32();
+#endif /* OPT_STEREO_32KBPS_V1 */
+
+ /* for better performance, unroll this loop */
+ FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ )
+ {
+#ifdef OPT_STEREO_32KBPS_V1
+ temp[n] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP + n], temp[n - 1], AP2_STEEP_FX[n] ); // Qx
+ move32();
+ mem[ALLPASSSECTIONS_STEEP + n] = Msub_32_16( temp[n - 1], temp[n], AP2_STEEP_FX[n] ); // Qx
+ move32();
+#else /* OPT_STEREO_32KBPS_V1 */
+ temp[n] = L_add( mem[ALLPASSSECTIONS_STEEP + n], Mpy_32_16_1( temp[n - 1], AP2_STEEP_FX[n] ) ); // Qx
+ move32();
+ /*if ( fabs( temp[n] ) < 1e-12 )
+ {
+ temp[n] = sign( temp[n] ) * 1e-12f;
+ }*/
+ mem[ALLPASSSECTIONS_STEEP + n] = L_sub( temp[n - 1], Mpy_32_16_1( temp[n], AP2_STEEP_FX[n] ) ); // Qx
+ move32();
+#endif /* OPT_STEREO_32KBPS_V1 */
+ }
+
+#ifdef OPT_STEREO_32KBPS_V1
+ temp[ALLPASSSECTIONS_STEEP - 1] = Madd_32_16( mem[2 * ALLPASSSECTIONS_STEEP - 1], temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
+ move32();
+ mem[2 * ALLPASSSECTIONS_STEEP - 1] = Msub_32_16( temp[ALLPASSSECTIONS_STEEP - 2], temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
+ move32();
+#else /* OPT_STEREO_32KBPS_V1 */
+ temp[ALLPASSSECTIONS_STEEP - 1] = L_add( mem[2 * ALLPASSSECTIONS_STEEP - 1], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx
+ move32();
+ mem[2 * ALLPASSSECTIONS_STEEP - 1] = L_sub( temp[ALLPASSSECTIONS_STEEP - 2], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx
+ move32();
+#endif /* OPT_STEREO_32KBPS_V1 */
+ out[k] = W_round48_L( W_mac_32_16( W_mult_32_16( out[k], 16384 /*0.5 in Q15*/ ), temp[ALLPASSSECTIONS_STEEP - 1], 16384 /*0.5 in Q15*/ ) ); // Qx
+ move32();
+ }
+
+ /* z^(-1) */
+ mem[2 * ALLPASSSECTIONS_STEEP] = in[N - 1];
+ move32();
+
+ return;
+}
+
/*-------------------------------------------------------------------*
* Interpolate_allpass_steep()
@@ -1122,6 +1279,66 @@ void Interpolate_allpass_steep_fx(
return;
}
+/* IVAS 32-bit variant */
+void Interpolate_allpass_steep_fx32(
+ const Word32 *in_fx, /* i : input array of size N Qx */
+ Word32 *mem_fx, /* i/o: memory Qx */
+ const Word16 N, /* i : number of input samples */
+ Word32 *out_fx /* o : output array of size 2*N Qx */
+)
+{
+ Word16 n, k;
+ Word32 temp_fx[ALLPASSSECTIONS_STEEP - 1];
+
+ /* upper allpass filter chain */
+ FOR( k = 0; k < N; k++ )
+ {
+ temp_fx[0] = Madd_32_16( mem_fx[0], in_fx[k], AP2_STEEP_FX[0] ); // Qx
+ move32();
+ mem_fx[0] = Msub_32_16( in_fx[k], temp_fx[0], AP2_STEEP_FX[0] ); // Qx
+ move32();
+
+ /* for better performance, unroll this loop */
+ FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ )
+ {
+ temp_fx[n] = Madd_32_16( mem_fx[n], temp_fx[n - 1], AP2_STEEP_FX[n] ); // Qx
+ move32();
+ mem_fx[n] = Msub_32_16( temp_fx[n - 1], temp_fx[n], AP2_STEEP_FX[n] ); // Qx
+ move32();
+ }
+
+ out_fx[2 * k + 1] = Madd_32_16( mem_fx[ALLPASSSECTIONS_STEEP - 1], temp_fx[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
+ move32();
+ mem_fx[ALLPASSSECTIONS_STEEP - 1] = Msub_32_16( temp_fx[ALLPASSSECTIONS_STEEP - 2], out_fx[2 * k + 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
+ move32();
+ }
+
+ /* lower allpass filter chain */
+ FOR( k = 0; k < N; k++ )
+ {
+ temp_fx[0] = Madd_32_16( mem_fx[ALLPASSSECTIONS_STEEP], in_fx[k], AP1_STEEP_FX[0] ); // Qx
+ move32();
+ mem_fx[ALLPASSSECTIONS_STEEP] = Msub_32_16( in_fx[k], temp_fx[0], AP1_STEEP_FX[0] ); // Qx
+ move32();
+
+ /* for better performance, unroll this loop */
+ FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ )
+ {
+ temp_fx[n] = Madd_32_16( mem_fx[ALLPASSSECTIONS_STEEP + n], temp_fx[n - 1], AP1_STEEP_FX[n] ); // Qx
+ move32();
+ mem_fx[ALLPASSSECTIONS_STEEP + n] = Msub_32_16( temp_fx[n - 1], temp_fx[n], AP1_STEEP_FX[n] ); // Qx
+ move32();
+ }
+
+ out_fx[2 * k] = Madd_32_16( mem_fx[2 * ALLPASSSECTIONS_STEEP - 1], temp_fx[ALLPASSSECTIONS_STEEP - 2], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
+ move32();
+ mem_fx[2 * ALLPASSSECTIONS_STEEP - 1] = Msub_32_16( temp_fx[ALLPASSSECTIONS_STEEP - 2], out_fx[2 * k], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
+ move32();
+ }
+
+ return;
+}
+
/*-------------------------------------------------------------------*
* interpolate_3_over_2_allpass_fx()
@@ -1250,6 +1467,133 @@ void interpolate_3_over_2_allpass_fx(
return;
}
+/* IVAS 32-bit variant */
+void interpolate_3_over_2_allpass_fx32(
+ const Word32 *input, /* i : input signal Qx*/
+ const Word16 len, /* i : number of input samples */
+ Word32 *out, /* o : output signal Qx*/
+ Word32 *mem /* i/o: memory Qx*/
+)
+{
+ Word16 i, loop_len;
+ Word32 Vu[2], Vm[2], Vl[2]; /* Outputs of three cascaded allpass stages (upper, middle, and lower) */
+ Word32 out1_buff[L_FRAME32k * 3];
+ Word32 *out1;
+ Word32 mem_temp;
+ const Word16 *filt_coeff = allpass_poles_3_ov_2; // Q15
+
+ out1 = out1_buff;
+
+ FOR( i = 0; i < len; i++ )
+ {
+ /* Upper branch */
+#ifdef OPT_STEREO_32KBPS_V1
+ Vu[0] = Madd_32_16( mem[0], L_sub( input[i], mem[1] ), filt_coeff[0] ); // Qx + Q15 - Q15 -> Qx
+ move32();
+ Vu[1] = Madd_32_16( mem[1], L_sub( Vu[0], mem[2] ), filt_coeff[1] ); // Qx + Q15 - Q15 -> Qx
+ move32();
+ mem[3] = Madd_32_16( mem[2], L_sub( Vu[1], mem[3] ), filt_coeff[2] ); // Qx + Q15 - Q15 -> Qx
+ move32();
+#else /* OPT_STEREO_32KBPS_V1 */
+ Vu[0] = L_add( mem[0], Mpy_32_16_1( L_sub( input[i], mem[1] ), filt_coeff[0] ) ); // Qx + Q15 - Q15 -> Qx
+ move32();
+ Vu[1] = L_add( mem[1], Mpy_32_16_1( L_sub( Vu[0], mem[2] ), filt_coeff[1] ) ); // Qx + Q15 - Q15 -> Qx
+ move32();
+ mem[3] = L_add( mem[2], Mpy_32_16_1( L_sub( Vu[1], mem[3] ), filt_coeff[2] ) ); // Qx + Q15 - Q15 -> Qx
+ move32();
+#endif /* OPT_STEREO_32KBPS_V1 */
+
+ mem[1] = Vu[0]; // Qx
+ move32();
+ mem[2] = Vu[1]; // Qx
+ move32();
+ *out1++ = mem[3]; // Qx
+ move32();
+
+ /* Middle branch */
+#ifdef OPT_STEREO_32KBPS_V1
+ Vm[0] = Madd_32_16( mem[0], L_sub( input[i], mem[4] ), filt_coeff[3] ); // Qx + Q15 - Q15 -> Qx
+ move32();
+ Vm[1] = Madd_32_16( mem[4], L_sub( Vm[0], mem[5] ), filt_coeff[4] ); // Qx + Q15 - Q15 -> Qx
+ move32();
+ mem[6] = Madd_32_16( mem[5], L_sub( Vm[1], mem[6] ), filt_coeff[5] ); // Qx + Q15 - Q15 -> Qx
+ move32();
+#else /* OPT_STEREO_32KBPS_V1 */
+ Vm[0] = L_add( mem[0], Mpy_32_16_1( L_sub( input[i], mem[4] ), filt_coeff[3] ) ); // Qx + Q15 - Q15 -> Qx
+ move32();
+ Vm[1] = L_add( mem[4], Mpy_32_16_1( L_sub( Vm[0], mem[5] ), filt_coeff[4] ) ); // Qx + Q15 - Q15 -> Qx
+ move32();
+ mem[6] = L_add( mem[5], Mpy_32_16_1( L_sub( Vm[1], mem[6] ), filt_coeff[5] ) ); // Qx + Q15 - Q15 -> Qx
+ move32();
+#endif /* OPT_STEREO_32KBPS_V1 */
+
+ mem[4] = Vm[0]; // Qx
+ move32();
+ mem[5] = Vm[1]; // Qx
+ move32();
+ *out1++ = mem[6]; // Qx
+ move32();
+
+ /* Lower branch */
+#ifdef OPT_STEREO_32KBPS_V1
+ Vl[0] = Madd_32_16( mem[0], L_sub( input[i], mem[7] ), filt_coeff[6] ); // Qx + Q15 - Q15 -> Qx
+ move32();
+ Vl[1] = Madd_32_16( mem[7], L_sub( Vl[0], mem[8] ), filt_coeff[7] ); // Qx + Q15 - Q15 -> Qx
+ move32();
+ mem[9] = Madd_32_16( mem[8], L_sub( Vl[1], mem[9] ), filt_coeff[8] ); // Qx + Q15 - Q15 -> Qx
+ move32();
+#else /* OPT_STEREO_32KBPS_V1 */
+ Vl[0] = L_add( mem[0], Mpy_32_16_1( L_sub( input[i], mem[7] ), filt_coeff[6] ) ); // Qx + Q15 - Q15 -> Qx
+ move32();
+ Vl[1] = L_add( mem[7], Mpy_32_16_1( L_sub( Vl[0], mem[8] ), filt_coeff[7] ) ); // Qx + Q15 - Q15 -> Qx
+ move32();
+ mem[9] = L_add( mem[8], Mpy_32_16_1( L_sub( Vl[1], mem[9] ), filt_coeff[8] ) ); // Qx + Q15 - Q15 -> Qx
+ move32();
+#endif /* OPT_STEREO_32KBPS_V1 */
+
+ mem[0] = input[i]; // Qx
+ move32();
+ mem[7] = Vl[0]; // Qx
+ move32();
+ mem[8] = Vl[1]; // Qx
+ move32();
+ *out1++ = mem[9]; // Qx
+ move32();
+ }
+
+ loop_len = shr( i_mult( len, 3 ), 1 );
+
+ /*decimate by 2 and LPF*/
+ FOR( i = 0; i < loop_len; i++ )
+ {
+ mem_temp = out1_buff[2 * i];
+ move32();
+#ifdef OPT_STEREO_32KBPS_V1
+ out[i] = Madd_32_16( Mpy_32_16_1( L_add( mem_temp, mem[10] ), 1550 ), L_add( mem[11], mem[14] ), -4965 ); // Qx + Q15 - Q15 -> Qx
+ // 0.0473147f in Q15 -> 1550, -0.151521f in Q15 -> -4965
+ out[i] = Madd_32_16( out[i], L_add( mem[12], mem[13] ), 20125 );
+ // 0.614152f in Q15 -> 20125
+#else /* OPT_STEREO_32KBPS_V1 */
+ out[i] = L_add( Mpy_32_16_1( L_add( mem_temp, mem[10] ), 1550 ), Mpy_32_16_1( L_add( mem[11], mem[14] ), -4965 ) ); // Qx + Q15 - Q15 -> Qx
+ // 0.0473147f in Q15 -> 1550, -0.151521f in Q15 -> -4965
+ out[i] = L_add( out[i], Mpy_32_16_1( L_add( mem[12], mem[13] ), 20125 ) );
+ // 0.614152f in Q15 -> 20125
+#endif /* OPT_STEREO_32KBPS_V1 */
+ mem[10] = mem[11]; // Qx
+ move32();
+ mem[11] = mem[12]; // Qx
+ move32();
+ mem[12] = mem[13]; // Qx
+ move32();
+ mem[13] = mem[14]; // Qx
+ move32();
+ mem[14] = mem_temp; // Qx
+ move32();
+ }
+
+ return;
+}
+
/*-------------------------------------------------------------------*
* interpolate_3_over_1_allpass_fx()
@@ -1445,6 +1789,92 @@ void interpolate_3_over_1_allpass_fx(
return;
}
+/* IVAS 32-bit variant */
+void interpolate_3_over_1_allpass_fx32(
+ const Word32 *input, /* i : input signal Qx */
+ const Word16 len, /* i : number of input samples */
+ Word32 *out, /* o : output signal */
+ Word32 *mem /* i/o: memory */
+)
+{
+ Word16 i, tmp16;
+ Word32 Vu[2], Vm[2], Vl[2]; /* Outputs of three cascaded allpass stages (upper, middle, and lower) */
+ Word32 *out1;
+ Word32 mem_temp;
+ const Word16 *filt_coeff = allpass_poles_3_ov_2; // Qx
+
+ out1 = &out[0];
+
+ FOR( i = 0; i < len; i++ )
+ {
+ /* Upper branch */
+ Vu[0] = L_add_sat( mem[0], Mpy_32_16_1( L_sub( input[i], mem[1] ), filt_coeff[0] ) ); // Qx
+ move32();
+ Vu[1] = L_add_sat( mem[1], Mpy_32_16_1( L_sub( Vu[0], mem[2] ), filt_coeff[1] ) ); // Qx
+ move32();
+ mem[3] = L_add_sat( mem[2], Mpy_32_16_1( L_sub( Vu[1], mem[3] ), filt_coeff[2] ) ); // Qx
+ move32();
+
+ mem[1] = Vu[0]; // Qx
+ move32();
+ mem[2] = Vu[1]; // Qx
+ move32();
+ *out1++ = mem[3]; // Qx
+ move32();
+
+ /* Middle branch */
+ Vm[0] = L_add_sat( mem[0], Mpy_32_16_1( L_sub( input[i], mem[4] ), filt_coeff[3] ) ); // Qx
+ move32();
+ Vm[1] = L_add_sat( mem[4], Mpy_32_16_1( L_sub( Vm[0], mem[5] ), filt_coeff[4] ) ); // Qx
+ move32();
+ mem[6] = L_add_sat( mem[5], Mpy_32_16_1( L_sub( Vm[1], mem[6] ), filt_coeff[5] ) ); // Qx
+ move32();
+
+ mem[4] = Vm[0]; // Qx
+ move32();
+ mem[5] = Vm[1]; // Qx
+ move32();
+ *out1++ = mem[6]; // Qx
+ move32();
+
+ /* Lower branch */
+ Vl[0] = L_add_sat( mem[0], Mpy_32_16_1( L_sub( input[i], mem[7] ), filt_coeff[6] ) ); // Qx
+ move32();
+ Vl[1] = L_add_sat( mem[7], Mpy_32_16_1( L_sub( Vl[0], mem[8] ), filt_coeff[7] ) ); // Qx
+ move32();
+ mem[9] = L_add_sat( mem[8], Mpy_32_16_1( L_sub( Vl[1], mem[9] ), filt_coeff[8] ) ); // Qx
+ move32();
+
+ mem[0] = input[i]; // Qx
+ move32();
+ mem[7] = Vl[0]; // Qx
+ move32();
+ mem[8] = Vl[1]; // Qx
+ move32();
+ *out1++ = mem[9]; // Qx
+ move32();
+ }
+
+ /*LPF*/
+ tmp16 = imult1616( len, 3 );
+ FOR( i = 0; i < tmp16; i++ )
+ {
+ mem_temp = out[i]; // Qx
+ move32();
+ out[i] = L_sub_sat( Mpy_32_16_1( L_add_sat( mem[12], mem[11] ), 18768 ), Mpy_32_16_1( L_add_sat( mem_temp, mem[10] ), 2424 ) ); // Qx
+ // 0.572769 in Q15 -> 18768, 0.074005 in Q15 -> 2424
+ move32();
+ mem[10] = mem[11]; // Qx
+ move32();
+ mem[11] = mem[12]; // Qx
+ move32();
+ mem[12] = mem_temp; // Qx
+ move32();
+ }
+
+ return;
+}
+
/*-------------------------------------------------------------------*
* decimate_3_over_2_allpass_fx()
diff --git a/lib_com/mslvq_com.c b/lib_com/mslvq_com.c
deleted file mode 100644
index 12234a4c055664712312c284ce500a2a019c119a..0000000000000000000000000000000000000000
--- a/lib_com/mslvq_com.c
+++ /dev/null
@@ -1,208 +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 "rom_com.h"
-#include "prot_fx.h"
-#include "wmc_auto.h"
-#include "ivas_prot_fx.h"
-
-/*-----------------------------------------------------------------*
- * Local function prototypes
- *-----------------------------------------------------------------*/
-
-static void make_offset_scale(
- const UWord32 tab_no_cv[],
- const Word8 *no_ld,
- const Word16 no_scl,
- UWord32 *offset_scale )
-{
- Word16 i;
-
- offset_scale[0] = 1;
- move32();
- FOR( i = 1; i <= no_scl; i++ )
- {
- offset_scale[i] = UL_addNsD( offset_scale[i - 1], tab_no_cv[(Word16) no_ld[i - 1]] );
- move32();
- }
-
- return;
-}
-
-/*-----------------------------------------------------------------*
- * create_offset()
- *
- *
- *-----------------------------------------------------------------*/
-
-void create_offset(
- UWord32 *offset_scale1,
- UWord32 *offset_scale2,
- const Word16 mode,
- const Word16 prediction_flag )
-{
- Word16 tmp, tmp1;
-
- if ( prediction_flag == 0 )
- {
- /* safety_net */
- tmp = no_lead_idx[mode][0];
- if ( ( tmp <= LIMIT_LEADER ) && ( tmp < no_lead_idx[mode][1] - 2 ) )
- {
- tmp += DELTA_LEADER;
- }
- make_offset_scale( table_no_cv, leaders_short[tmp], MAX_NO_SCALES, offset_scale1 );
- make_offset_scale( table_no_cv, leaders_short[no_lead_idx[mode][1]], MAX_NO_SCALES, offset_scale2 );
- }
- else
- {
- tmp = no_lead_p_idx[mode][0];
- tmp1 = no_lead_p_idx[mode][1];
- if ( ( tmp <= LIMIT_LEADER ) && ( tmp < tmp1 - 2 ) )
- {
- tmp += DELTA_LEADER;
- }
-
- if ( ( tmp == LIMIT_LEADER ) && ( tmp1 == 0 ) )
- {
- tmp += DELTA_LEADER;
- tmp1 = DELTA_LEADER;
- }
-
- make_offset_scale( table_no_cv, leaders_short[tmp], MAX_NO_SCALES, offset_scale1 );
- make_offset_scale( table_no_cv, leaders_short[tmp1], MAX_NO_SCALES, offset_scale2 );
- }
-
- return;
-}
-
-/*-----------------------------------------------------------------*
- * sort_desc_ind()
- *
- * sorts in descending order and computes indices in the sorted vector
- *-----------------------------------------------------------------*/
-void sort_desc_ind_16_fx(
- Word16 *s, /* i/o: vector to be sorted Qx*/
- const Word16 len, /* i : vector length */
- Word16 *ind /* o : array of indices */
-)
-{
- Word16 i, k, sorted, a;
- Word16 t;
-
- FOR( i = 0; i < len; i++ )
- {
- ind[i] = i;
- move16();
- }
- sorted = 0;
- move16();
- FOR( k = len - 1; k && !sorted; k-- )
- {
- sorted = 1;
- move16();
- FOR( i = 0; i < k; i++ )
- {
- IF( LT_16( s[i], s[i + 1] ) )
- {
- sorted = 0;
- move16();
- t = s[i];
- move16();
- s[i] = s[i + 1];
- move16();
- s[i + 1] = t;
- move16();
- a = ind[i];
- move16();
- ind[i] = ind[i + 1];
- move16();
- ind[i + 1] = a;
- move16();
- }
- }
- }
-
- return;
-}
-
-void sort_desc_ind_32_fx(
- Word32 *s, /* i/o: vector to be sorted Qx*/
- const Word16 len, /* i : vector length */
- Word16 *ind /* o : array of indices */
-)
-{
- Word16 i, k, sorted, a;
- Word32 t;
-
- FOR( i = 0; i < len; i++ )
- {
- ind[i] = i;
- move16();
- }
- sorted = 0;
- move16();
- FOR( k = len - 1; k && !sorted; k-- )
- {
- sorted = 1;
- move16();
- FOR( i = 0; i < k; i++ )
- {
- IF( LT_32( s[i], s[i + 1] ) )
- {
- sorted = 0;
- move16();
- t = s[i];
- move16();
- s[i] = s[i + 1];
- move16();
- s[i + 1] = t;
- move16();
- a = ind[i];
- move16();
- ind[i] = ind[i + 1];
- move16();
- ind[i + 1] = a;
- move16();
- }
- }
- }
-
- return;
-}
diff --git a/lib_com/mslvq_com_fx.c b/lib_com/mslvq_com_fx.c
index 7fcf36bfcfb81b1250315991a080644d2b49a6a0..8d5e8adf2c394a7799a75085ccaff97cf9b698e9 100644
--- a/lib_com/mslvq_com_fx.c
+++ b/lib_com/mslvq_com_fx.c
@@ -30,11 +30,16 @@
*******************************************************************************************************/
+#include
#include "options.h"
+#include "cnst.h"
#include "prot_fx.h"
#include "ivas_cnst.h"
#include "stl.h"
#include "rom_com.h"
+#include "ivas_prot_fx.h"
+#include "wmc_auto.h"
+
/*-----------------------------------------------------------------*
* Local functions
@@ -260,6 +265,25 @@ static void make_offset_scale_fx(
return;
}
+static void make_offset_scale(
+ const UWord32 tab_no_cv[],
+ const Word8 *no_ld,
+ const Word16 no_scl,
+ UWord32 *offset_scale )
+{
+ Word16 i;
+
+ offset_scale[0] = 1;
+ move32();
+ FOR( i = 1; i <= no_scl; i++ )
+ {
+ offset_scale[i] = UL_addNsD( offset_scale[i - 1], tab_no_cv[(Word16) no_ld[i - 1]] );
+ move32();
+ }
+
+ return;
+}
+
void init_offset_fx(
Word32 offset_scale1[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the first LSF subvector - safety net structures*/
Word32 offset_scale2[][MAX_NO_SCALES + 1], /* o: lattice truncation index offset for the second LSF subvector - safety net structures*/
@@ -1310,6 +1334,104 @@ static void put_value_fx(
return;
}
+/*-----------------------------------------------------------------*
+ * create_offset()
+ *
+ *
+ *-----------------------------------------------------------------*/
+
+void create_offset(
+ UWord32 *offset_scale1,
+ UWord32 *offset_scale2,
+ const Word16 mode,
+ const Word16 prediction_flag )
+{
+ Word16 tmp, tmp1;
+
+ if ( prediction_flag == 0 )
+ {
+ /* safety_net */
+ tmp = no_lead_idx[mode][0];
+ if ( ( tmp <= LIMIT_LEADER ) && ( tmp < no_lead_idx[mode][1] - 2 ) )
+ {
+ tmp += DELTA_LEADER;
+ }
+ make_offset_scale( table_no_cv, leaders_short[tmp], MAX_NO_SCALES, offset_scale1 );
+ make_offset_scale( table_no_cv, leaders_short[no_lead_idx[mode][1]], MAX_NO_SCALES, offset_scale2 );
+ }
+ else
+ {
+ tmp = no_lead_p_idx[mode][0];
+ tmp1 = no_lead_p_idx[mode][1];
+ if ( ( tmp <= LIMIT_LEADER ) && ( tmp < tmp1 - 2 ) )
+ {
+ tmp += DELTA_LEADER;
+ }
+
+ if ( ( tmp == LIMIT_LEADER ) && ( tmp1 == 0 ) )
+ {
+ tmp += DELTA_LEADER;
+ tmp1 = DELTA_LEADER;
+ }
+
+ make_offset_scale( table_no_cv, leaders_short[tmp], MAX_NO_SCALES, offset_scale1 );
+ make_offset_scale( table_no_cv, leaders_short[tmp1], MAX_NO_SCALES, offset_scale2 );
+ }
+
+ return;
+}
+
+/*-----------------------------------------------------------------*
+ * sort_desc_ind()
+ *
+ * sorts in descending order and computes indices in the sorted vector
+ *-----------------------------------------------------------------*/
+
+void sort_desc_ind_32_fx(
+ Word32 *s, /* i/o: vector to be sorted Qx*/
+ const Word16 len, /* i : vector length */
+ Word16 *ind /* o : array of indices */
+)
+{
+ Word16 i, k, sorted, a;
+ Word32 t;
+
+ FOR( i = 0; i < len; i++ )
+ {
+ ind[i] = i;
+ move16();
+ }
+ sorted = 0;
+ move16();
+ FOR( k = len - 1; k && !sorted; k-- )
+ {
+ sorted = 1;
+ move16();
+ FOR( i = 0; i < k; i++ )
+ {
+ IF( LT_32( s[i], s[i + 1] ) )
+ {
+ sorted = 0;
+ move16();
+ t = s[i];
+ move16();
+ s[i] = s[i + 1];
+ move16();
+ s[i + 1] = t;
+ move16();
+ a = ind[i];
+ move16();
+ ind[i] = ind[i + 1];
+ move16();
+ ind[i + 1] = a;
+ move16();
+ }
+ }
+ }
+
+ return;
+}
+
void deindex_lvq_SHB_fx(
UWord32 index,
Word16 *out,
diff --git a/lib_com/preemph.c b/lib_com/preemph.c
deleted file mode 100644
index 9ebc0f72a81c39542312ff9e6bbd3d76b5a49197..0000000000000000000000000000000000000000
--- a/lib_com/preemph.c
+++ /dev/null
@@ -1,72 +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 "prot_fx.h"
-#include "wmc_auto.h"
-
-/*-------------------------------------------------------------*
- * preemph_ivas_fx()
- *
- * Preemphasis: filtering through 1 - mu z^-1
- *-------------------------------------------------------------*/
-
-void preemph_ivas_fx(
- Word32 *signal, /* i/o: signal Qx*/
- const Word16 mu, /* i : preemphasis factor Q15*/
- const Word16 L, /* i : vector size Q0*/
- Word32 *mem /* i/o: memory (x[-1]) Qx*/
-)
-{
- Word16 i;
- Word32 temp;
-
- temp = signal[L - 1]; /* Qx */
- move32();
- FOR( i = L - 1; i > 0; i-- )
- {
- signal[i] = L_sub( signal[i], Mpy_32_16_1( signal[i - 1], mu ) ); /* Qx */
- move32();
- }
-
- signal[0] = L_sub( signal[0], Mpy_32_16_1( *mem, mu ) ); /* Qx */
- move32();
- *mem = temp; /* Qx */
- move32();
-
- return;
-}
diff --git a/lib_com/preemph_fx.c b/lib_com/preemph_fx.c
index 0790f6c3f2c8fdda954347962a335a029e7057f1..b7886cb65324d5bfb77d84fe104b24ff7abb7e33 100644
--- a/lib_com/preemph_fx.c
+++ b/lib_com/preemph_fx.c
@@ -1,14 +1,18 @@
/*====================================================================================
EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
====================================================================================*/
+
#include
#include "options.h" /* Compilation switches */
#include "prot_fx.h"
+#include "wmc_auto.h"
+
/*-------------------------------------------------------------*
* preemph_copy_fx()
*
* Preemphasis: filtering through 1 - mu z^-1
*-------------------------------------------------------------*/
+
void preemph_copy_fx(
const Word16 x[], /* i : input signal Qx */
Word16 y[], /* o : output signal Qx */
@@ -63,6 +67,38 @@ void preemph_copy_32fx(
move16();
}
+/*-------------------------------------------------------------*
+ * preemph_ivas_fx()
+ *
+ * Preemphasis: filtering through 1 - mu z^-1
+ *-------------------------------------------------------------*/
+
+void preemph_ivas_fx(
+ Word32 *signal, /* i/o: signal Qx*/
+ const Word16 mu, /* i : preemphasis factor Q15*/
+ const Word16 L, /* i : vector size Q0*/
+ Word32 *mem /* i/o: memory (x[-1]) Qx*/
+)
+{
+ Word16 i;
+ Word32 temp;
+
+ temp = signal[L - 1]; /* Qx */
+ move32();
+ FOR( i = L - 1; i > 0; i-- )
+ {
+ signal[i] = L_sub( signal[i], Mpy_32_16_1( signal[i - 1], mu ) ); /* Qx */
+ move32();
+ }
+
+ signal[0] = L_sub( signal[0], Mpy_32_16_1( *mem, mu ) ); /* Qx */
+ move32();
+ *mem = temp; /* Qx */
+ move32();
+
+ return;
+}
+
/*
* E_UTIL_f_preemph2
*
diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h
index 498be31379072cb95148cab1c0eae6187025a4bc..935139e426e901465cd0287637686c2bd07f24e3 100644
--- a/lib_com/prot_fx.h
+++ b/lib_com/prot_fx.h
@@ -1778,13 +1778,7 @@ void Ener_per_band_comp_ivas_fx(
const Word16 Eflag, /* i : flag of highest band */
const Word16 L_frame /* i : frame length */
);
-void Ener_per_band_comp_ivas_fx_2(
- const Word16 exc_diff_fx[], /* i : target signal Q_exc_diff */
- Word16 y_gain4_fx[], /* o : Energy per band to quantize Q12 */
- const Word16 Q_exc, /* i : frame length */
- const Word16 Mband, /* i : Max band */
- const Word16 Eflag, /* i : flag of highest band */
- const Word16 L_frame );
+
void Comp_and_apply_gain_fx(
Word16 exc_diffQ[], /* i/o: Quantized excitation */
Word16 Ener_per_bd_iQ[], /* i : Target ener per band Q13 */
@@ -1844,17 +1838,6 @@ void wtda_fx(
const Word16 L /* i : length */
);
-void wtda_ivas_fx(
- Word16 *new_audio, /* i : input audio Q0 */
- Word16 *Q, /* i/o : Q of input/Output Audio */
- Word16 *wtda_audio, /* o : windowed audio Qout */
- Word16 *old_wtda, /* i/o: windowed audio from previous frame Qout */
- Word16 *Qold_wtda,
- const Word16 left_mode, /* i : window overlap of previous frame (0: full, 2: none, or 3: half) */
- const Word16 right_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */
- const Word16 L /* i : length */
-);
-
void wtda_ext_fx(
const Word16 *new_audio, /* i : input audio (Q_in) */
Word16 *wtda_audio, /* o : windowed audio (Q_in) */
@@ -11144,31 +11127,6 @@ Word32 Mult_32_32(
Word32 a,
Word32 b );
-
-void bit_allocation_second_fx2(
- Word32 *Rk,
- Word32 *Rk_sort,
- Word16 BANDS,
- const Word16 *band_width,
- Word16 *k_sort,
- Word16 *k_num,
- const Word16 *p2a_flags,
- const Word16 p2a_bands,
- const Word16 *last_bitalloc,
- const Word16 input_frame );
-
-void bit_allocation_second_fx2(
- Word32 *Rk,
- Word32 *Rk_sort,
- Word16 BANDS,
- const Word16 *band_width,
- Word16 *k_sort,
- Word16 *k_num,
- const Word16 *p2a_flags,
- const Word16 p2a_bands,
- const Word16 *last_bitalloc,
- const Word16 input_frame );
-
#ifdef DEBUGGING
void read_next_force(
int16_t *force, /* i/o: force value (0/1, 0 = speech, 1 = music)*/
diff --git a/lib_com/tcx_mdct_window.c b/lib_com/tcx_mdct_window_fx.c
similarity index 100%
rename from lib_com/tcx_mdct_window.c
rename to lib_com/tcx_mdct_window_fx.c
diff --git a/lib_com/tec_com.c b/lib_com/tec_com_fx.c
similarity index 100%
rename from lib_com/tec_com.c
rename to lib_com/tec_com_fx.c
diff --git a/lib_com/wtda.c b/lib_com/wtda.c
deleted file mode 100644
index 3fb40813816c7b4462bdcc3ec82b8df2314fb845..0000000000000000000000000000000000000000
--- a/lib_com/wtda.c
+++ /dev/null
@@ -1,219 +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 "prot_fx.h"
-#include "rom_com.h"
-#include
-#include "wmc_auto.h"
-
-
-void wtda_fx32(
- const Word32 *new_audio, /* i : input audio Q11 */
- Word32 *wtda_audio, /* o : windowed audio Q11 */
- Word32 *old_wtda, /* i/o: windowed audio from previous frame */
- const Word16 left_mode, /* i : window overlap of previous frame (0: full, 2: none, or 3: half) */
- const Word16 right_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */
- const Word16 L /* i : length */
-)
-{
- Word16 i, decimate, decay;
- Word16 idx1, idx2, idx3, idx4;
- Word16 n, windecay48, windecay16;
- const Word32 *allsig_l, *allsig_r;
- Word16 win_right[R2_48];
- Word16 win_int_left[R1_16];
- Word16 win_left[R1_48];
- Word16 win_int_right[R2_16];
-
- tcx_get_windows_mode1( left_mode, right_mode, win_left, win_right, win_int_left, win_int_right, L );
-
- decimate = 1; /* L_FRAME 48k */
- move16();
- decay = 0;
- move16();
- windecay48 = extract_l( WINDECAY48 ); // (int16_t)(2 * ((float)L_FRAME48k * N_ZERO_MDCT_NS / FRAME_SIZE_NS)) + R1_48
-
- test();
- IF( EQ_16( L, L_FRAME32k ) || EQ_16( L, L_FRAME16k ) )
- {
- decimate = 3;
- move16();
- decay = 1;
- move16();
- }
- ELSE IF( EQ_16( L, L_FRAME8k ) )
- {
- decimate = 6;
- move16();
- decay = 2;
- move16();
- }
-
- SWITCH( L ) // (int16_t)((float)L * N_ZERO_MDCT_NS / FRAME_SIZE_NS)
- {
- case L_FRAME16k:
- n = 90;
- move16();
- BREAK;
- case L_FRAME32k:
- n = 180;
- move16();
- BREAK;
- case L_FRAME48k:
- n = 270;
- move16();
- BREAK;
- default:
- n = (Word16) ( ( L * N_ZERO_MDCT_NS ) / FRAME_SIZE_NS );
- move16();
- BREAK;
- }
-
- windecay16 = extract_l( WINDECAY16 ); // (int16_t)(2 * ((float)L_FRAME16k * N_ZERO_MDCT_NS / FRAME_SIZE_NS)) + R1_16;
-
- /* algorithmic delay reduction */
- i = 0;
- move16();
-
- IF( old_wtda == NULL )
- {
- allsig_r = new_audio + n;
- allsig_l = new_audio + n - L;
- }
- ELSE
- {
- allsig_r = new_audio + n;
- allsig_l = old_wtda + n;
- }
-
- IF( EQ_16( L, L_FRAME32k ) )
- {
- FOR( i = 0; i < ( L / 2 - n ); i += 2 )
- {
- idx1 = sub( sub( shr( L, 1 ), i ), 1 );
- idx2 = sub( sub( 3 * L_FRAME16k / 2 - 1, shr( i, 1 ) ), windecay16 );
- idx3 = add( shr( L, 1 ), i );
- idx4 = sub( add( 3 * L_FRAME16k / 2, shr( i, 1 ) ), windecay16 );
- wtda_audio[i] = L_sub_sat( Mpy_32_16_1( -allsig_r[idx1], win_int_right[idx2] ), Mpy_32_16_1( allsig_r[idx3], win_int_right[idx4] ) );
- move32();
-
- idx1 = sub( sub( shr( L, 1 ), add( i, 1 ) ), 1 );
- idx2 = sub( add( i_mult( ( sub( sub( 3 * L_FRAME16k / 2, shr( i, 1 ) ), 1 ) ), decimate ), decay ), windecay48 );
- idx3 = add( add( shr( L, 1 ), i ), 1 );
- idx4 = sub( sub( sub( i_mult( ( add( 3 * L_FRAME16k / 2 + 1, shr( i, 1 ) ) ), decimate ), decay ), 1 ), windecay48 );
- wtda_audio[i + 1] = L_sub_sat( Mpy_32_16_1( -allsig_r[idx1], win_right[idx2] ), Mpy_32_16_1( allsig_r[idx3], win_right[idx4] ) );
- move32();
- }
-
- FOR( i = L / 2 - n; i < L / 2; i += 2 )
- {
- wtda_audio[i] = L_negate( allsig_r[( ( ( L >> 1 ) - i ) - 1 )] );
- move32();
- wtda_audio[i + 1] = L_negate( allsig_r[( ( ( L >> 1 ) - ( i + 1 ) ) - 1 )] );
- move32();
- }
- FOR( i = 0; i < n; i += 2 )
- {
- wtda_audio[( i + ( L >> 1 ) )] = L_sub_sat( Mpy_32_16_1( allsig_l[i], win_left[( ( ( i >> 1 ) * decimate ) + decay )] ), new_audio[( ( n - i ) - 1 )] );
- move32();
- wtda_audio[( ( i + ( L >> 1 ) ) + 1 )] = L_sub_sat( Mpy_32_16_1( allsig_l[i + 1], win_int_left[i / 2] ), new_audio[( ( n - ( i + 1 ) ) - 1 )] );
- move32();
- }
-
- FOR( i = n; i < L / 2; i += 2 )
- {
- idx1 = i;
- move16();
- idx2 = add( i_mult( shr( i, 1 ), decimate ), decay );
- idx3 = sub( sub( L, i ), 1 );
- idx4 = sub( sub( i_mult( sub( shr( L, 1 ), shr( i, 1 ) ), decimate ), 1 ), decay );
- wtda_audio[( i + ( L >> 1 ) )] = L_sub_sat( Mpy_32_16_1( allsig_l[idx1], win_left[idx2] ), Mpy_32_16_1( allsig_l[idx3], win_left[idx4] ) );
- move32();
-
- idx1 = add( i, 1 );
- idx2 = shr( i, 1 );
- idx3 = sub( sub( L, add( i, 1 ) ), 1 );
- idx4 = sub( sub( shr( L, 1 ), shr( i, 1 ) ), 1 );
- wtda_audio[( ( i + ( L >> 1 ) ) + 1 )] = L_sub_sat( Mpy_32_16_1( allsig_l[idx1], win_int_left[idx2] ), Mpy_32_16_1( allsig_l[idx3], win_int_left[idx4] ) );
- move32();
- }
- }
- ELSE
- {
- FOR( i = 0; i < L / 2 - n; i++ )
- {
- idx1 = sub( sub( shr( L, 1 ), i ), 1 );
- idx2 = sub( add( sub( i_mult( i_mult( 3, shr( L, 1 ) ), decimate ), i_mult( add( i, 1 ), decimate ) ), decay ), windecay48 );
- idx3 = add( shr( L, 1 ), i );
- idx4 = sub( sub( add( sub( i_mult( i_mult( 3, shr( L, 1 ) ), decimate ), 1 ), i_mult( add( i, 1 ), decimate ) ), decay ), windecay48 );
- wtda_audio[i] = L_sub_sat( Mpy_32_16_1( -allsig_r[idx1], win_right[idx2] ), Mpy_32_16_1( allsig_r[idx3], win_right[idx4] ) );
- move32();
- }
-
- FOR( i = L / 2 - n; i < L / 2; i++ )
- {
- wtda_audio[i] = L_negate( allsig_r[( ( ( L >> 1 ) - i ) - 1 )] );
- move32();
- }
-
- FOR( i = 0; i < n; i++ )
- {
- wtda_audio[( i + ( L >> 1 ) )] = L_sub_sat( Mpy_32_16_1( allsig_l[i], win_left[( ( i * decimate ) + decay )] ), new_audio[( ( n - i ) - 1 )] );
- move32();
- }
-
- FOR( i = n; i < L / 2; i++ )
- {
- idx1 = i;
- move16();
- idx2 = add( i_mult( i, decimate ), decay );
- idx3 = sub( sub( L, i ), 1 );
- idx4 = sub( sub( sub( i_mult( L, decimate ), i_mult( i, decimate ) ), 1 ), decay );
- wtda_audio[( i + ( L >> 1 ) )] = L_sub_sat( Mpy_32_16_1( allsig_l[idx1], win_left[idx2] ), Mpy_32_16_1( allsig_l[idx3], win_left[idx4] ) );
- move32();
- }
- }
-
- IF( old_wtda != NULL )
- {
- Copy32( new_audio, old_wtda, L );
- }
-
- return;
-}
diff --git a/lib_com/wtda_fx.c b/lib_com/wtda_fx.c
index e060984dff14eb316ed1d965e06830487eb1624b..7943a87c5fc11a276127169b3e0dd8ee8f88895a 100644
--- a/lib_com/wtda_fx.c
+++ b/lib_com/wtda_fx.c
@@ -2,11 +2,14 @@
EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
====================================================================================*/
#include
+#include
#include "options.h" /* Compilation switches */
#include "cnst.h" /* Common constants */
#include "rom_com.h" /* Static table prototypes */
#include "prot_fx.h" /* required by wmc_tool */
#include "stat_com.h"
+#include "wmc_auto.h"
+
/*--------------------------------------------------------------------------*
* mvr2r_inv()
*
@@ -412,21 +415,19 @@ void wtda_fx(
return;
}
-
-void wtda_ivas_fx(
- Word16 *new_audio, /* i : input audio Q0 */
- Word16 *Q, /* i/o : Q of input/Output Audio */
- Word16 *wtda_audio, /* o : windowed audio Qout */
- Word16 *old_wtda, /* i/o: windowed audio from previous frame Qout */
- Word16 *Qold_wtda,
+void wtda_fx32(
+ const Word32 *new_audio, /* i : input audio Q11 */
+ Word32 *wtda_audio, /* o : windowed audio Q11 */
+ Word32 *old_wtda, /* i/o: windowed audio from previous frame */
const Word16 left_mode, /* i : window overlap of previous frame (0: full, 2: none, or 3: half) */
const Word16 right_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */
const Word16 L /* i : length */
)
{
Word16 i, decimate, decay;
+ Word16 idx1, idx2, idx3, idx4;
Word16 n, windecay48, windecay16;
- const Word16 *allsig_l, *allsig_r;
+ const Word32 *allsig_l, *allsig_r;
Word16 win_right[R2_48];
Word16 win_int_left[R1_16];
Word16 win_left[R1_48];
@@ -434,12 +435,11 @@ void wtda_ivas_fx(
tcx_get_windows_mode1( left_mode, right_mode, win_left, win_right, win_int_left, win_int_right, L );
- decimate = 1; /* L_FRAME48k */
+ decimate = 1; /* L_FRAME 48k */
move16();
decay = 0;
move16();
- windecay48 = ( 2 * ( (Word64) L_FRAME48k * N_ZERO_MDCT_NS / FRAME_SIZE_NS ) ) + R1_48;
- move16();
+ windecay48 = extract_l( WINDECAY48 ); // (int16_t)(2 * ((float)L_FRAME48k * N_ZERO_MDCT_NS / FRAME_SIZE_NS)) + R1_48
test();
IF( EQ_16( L, L_FRAME32k ) || EQ_16( L, L_FRAME16k ) )
@@ -457,10 +457,27 @@ void wtda_ivas_fx(
move16();
}
- n = extract_l( Mpy_32_32( L, 603979776 /* N_ZERO_MDCT_NS / FRAME_SIZE_NS in Q31 */ ) );
+ SWITCH( L ) // (int16_t)((float)L * N_ZERO_MDCT_NS / FRAME_SIZE_NS)
+ {
+ case L_FRAME16k:
+ n = 90;
+ move16();
+ BREAK;
+ case L_FRAME32k:
+ n = 180;
+ move16();
+ BREAK;
+ case L_FRAME48k:
+ n = 270;
+ move16();
+ BREAK;
+ default:
+ n = (Word16) ( ( L * N_ZERO_MDCT_NS ) / FRAME_SIZE_NS );
+ move16();
+ BREAK;
+ }
- windecay16 = ( 2 * ( L_FRAME16k * N_ZERO_MDCT_NS / FRAME_SIZE_NS ) ) + R1_16;
- move16();
+ windecay16 = extract_l( WINDECAY16 ); // (int16_t)(2 * ((float)L_FRAME16k * N_ZERO_MDCT_NS / FRAME_SIZE_NS)) + R1_16;
/* algorithmic delay reduction */
i = 0;
@@ -473,103 +490,106 @@ void wtda_ivas_fx(
}
ELSE
{
- /* Rescale signals if Q are not identical */
- IF( GT_16( *Qold_wtda, *Q ) )
- {
- Copy_Scale_sig( old_wtda, old_wtda, L, sub( *Q, *Qold_wtda ) );
- *Qold_wtda = *Q;
- move16();
- }
- ELSE IF( LT_16( *Qold_wtda, *Q ) )
- {
- Copy_Scale_sig( new_audio, new_audio, L, sub( *Qold_wtda, *Q ) );
- *Q = *Qold_wtda;
- move16();
- }
-
allsig_r = new_audio + n;
allsig_l = old_wtda + n;
}
IF( EQ_16( L, L_FRAME32k ) )
{
- FOR( i = 0; i < L / 2 - n; i += 2 )
+ FOR( i = 0; i < ( L / 2 - n ); i += 2 )
{
- wtda_audio[i] = round_fx( L_msu0( L_mult0( negate( allsig_r[L / 2 - i - 1] ), win_int_right[3 * L_FRAME16k / 2 - i / 2 - 1 - windecay16] ),
- allsig_r[L / 2 + i], win_int_right[3 * L_FRAME16k / 2 + i / 2 - windecay16] ) );
- move16();
- wtda_audio[i + 1] = round_fx( L_msu0( L_mult0( negate( allsig_r[L / 2 - ( i + 1 ) - 1] ), win_right[( 3 * L_FRAME16k / 2 - i / 2 - 1 ) * decimate + decay - windecay48] ),
- allsig_r[L / 2 + i + 1], win_right[( 3 * L_FRAME16k / 2 + 1 + i / 2 ) * decimate - decay - 1 - windecay48] ) );
- move16();
+ idx1 = sub( sub( shr( L, 1 ), i ), 1 );
+ idx2 = sub( sub( 3 * L_FRAME16k / 2 - 1, shr( i, 1 ) ), windecay16 );
+ idx3 = add( shr( L, 1 ), i );
+ idx4 = sub( add( 3 * L_FRAME16k / 2, shr( i, 1 ) ), windecay16 );
+ wtda_audio[i] = L_sub_sat( Mpy_32_16_1( -allsig_r[idx1], win_int_right[idx2] ), Mpy_32_16_1( allsig_r[idx3], win_int_right[idx4] ) );
+ move32();
+
+ idx1 = sub( sub( shr( L, 1 ), add( i, 1 ) ), 1 );
+ idx2 = sub( add( i_mult( ( sub( sub( 3 * L_FRAME16k / 2, shr( i, 1 ) ), 1 ) ), decimate ), decay ), windecay48 );
+ idx3 = add( add( shr( L, 1 ), i ), 1 );
+ idx4 = sub( sub( sub( i_mult( ( add( 3 * L_FRAME16k / 2 + 1, shr( i, 1 ) ) ), decimate ), decay ), 1 ), windecay48 );
+ wtda_audio[i + 1] = L_sub_sat( Mpy_32_16_1( -allsig_r[idx1], win_right[idx2] ), Mpy_32_16_1( allsig_r[idx3], win_right[idx4] ) );
+ move32();
}
FOR( i = L / 2 - n; i < L / 2; i += 2 )
{
- wtda_audio[i] = shr( negate( allsig_r[L / 2 - i - 1] ), 1 );
- move16();
- wtda_audio[i + 1] = shr( negate( allsig_r[L / 2 - ( i + 1 ) - 1] ), 1 );
- move16();
+ wtda_audio[i] = L_negate( allsig_r[( ( ( L >> 1 ) - i ) - 1 )] );
+ move32();
+ wtda_audio[i + 1] = L_negate( allsig_r[( ( ( L >> 1 ) - ( i + 1 ) ) - 1 )] );
+ move32();
}
-
FOR( i = 0; i < n; i += 2 )
{
- wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( allsig_l[i], win_left[( i / 2 ) * decimate + decay] ),
- new_audio[n - i - 1], MAX16B ) );
- move16();
- wtda_audio[i + L / 2 + 1] = round_fx( L_msu0( L_mult0( allsig_l[i + 1], win_int_left[i / 2] ),
- new_audio[n - ( i + 1 ) - 1], MAX16B ) );
- move16();
+ wtda_audio[( i + ( L >> 1 ) )] = L_sub_sat( Mpy_32_16_1( allsig_l[i], win_left[( ( ( i >> 1 ) * decimate ) + decay )] ), new_audio[( ( n - i ) - 1 )] );
+ move32();
+ wtda_audio[( ( i + ( L >> 1 ) ) + 1 )] = L_sub_sat( Mpy_32_16_1( allsig_l[i + 1], win_int_left[i / 2] ), new_audio[( ( n - ( i + 1 ) ) - 1 )] );
+ move32();
}
FOR( i = n; i < L / 2; i += 2 )
{
- wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( allsig_l[i], win_left[( i / 2 ) * decimate + decay] ),
- allsig_l[L - i - 1], win_left[( L / 2 - i / 2 ) * decimate - 1 - decay] ) );
- move16();
- wtda_audio[i + L / 2 + 1] = round_fx( L_msu0( L_mult0( allsig_l[i + 1], win_int_left[i / 2] ),
- allsig_l[L - ( i + 1 ) - 1], win_int_left[L / 2 - i / 2 - 1] ) );
+ idx1 = i;
move16();
+ idx2 = add( i_mult( shr( i, 1 ), decimate ), decay );
+ idx3 = sub( sub( L, i ), 1 );
+ idx4 = sub( sub( i_mult( sub( shr( L, 1 ), shr( i, 1 ) ), decimate ), 1 ), decay );
+ wtda_audio[( i + ( L >> 1 ) )] = L_sub_sat( Mpy_32_16_1( allsig_l[idx1], win_left[idx2] ), Mpy_32_16_1( allsig_l[idx3], win_left[idx4] ) );
+ move32();
+
+ idx1 = add( i, 1 );
+ idx2 = shr( i, 1 );
+ idx3 = sub( sub( L, add( i, 1 ) ), 1 );
+ idx4 = sub( sub( shr( L, 1 ), shr( i, 1 ) ), 1 );
+ wtda_audio[( ( i + ( L >> 1 ) ) + 1 )] = L_sub_sat( Mpy_32_16_1( allsig_l[idx1], win_int_left[idx2] ), Mpy_32_16_1( allsig_l[idx3], win_int_left[idx4] ) );
+ move32();
}
}
ELSE
{
FOR( i = 0; i < L / 2 - n; i++ )
{
- wtda_audio[i] = round_fx( L_msu0( L_mult0( negate( allsig_r[L / 2 - i - 1] ), win_right[3 * L / 2 * decimate - ( i + 1 ) * decimate + decay - windecay48] ),
- allsig_r[L / 2 + i], win_right[3 * L / 2 * decimate - 1 + ( i + 1 ) * decimate - decay - windecay48] ) );
- move16();
+ idx1 = sub( sub( shr( L, 1 ), i ), 1 );
+ idx2 = sub( add( sub( i_mult( i_mult( 3, shr( L, 1 ) ), decimate ), i_mult( add( i, 1 ), decimate ) ), decay ), windecay48 );
+ idx3 = add( shr( L, 1 ), i );
+ idx4 = sub( sub( add( sub( i_mult( i_mult( 3, shr( L, 1 ) ), decimate ), 1 ), i_mult( add( i, 1 ), decimate ) ), decay ), windecay48 );
+ wtda_audio[i] = L_sub_sat( Mpy_32_16_1( -allsig_r[idx1], win_right[idx2] ), Mpy_32_16_1( allsig_r[idx3], win_right[idx4] ) );
+ move32();
}
FOR( i = L / 2 - n; i < L / 2; i++ )
{
- wtda_audio[i] = shr( negate( allsig_r[L / 2 - i - 1] ), 1 );
- move16();
+ wtda_audio[i] = L_negate( allsig_r[( ( ( L >> 1 ) - i ) - 1 )] );
+ move32();
}
FOR( i = 0; i < n; i++ )
{
- wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( allsig_l[i], win_left[i * decimate + decay] ),
- new_audio[n - i - 1], MAX16B ) );
- move16();
+ wtda_audio[( i + ( L >> 1 ) )] = L_sub_sat( Mpy_32_16_1( allsig_l[i], win_left[( ( i * decimate ) + decay )] ), new_audio[( ( n - i ) - 1 )] );
+ move32();
}
FOR( i = n; i < L / 2; i++ )
{
- wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( allsig_l[i], win_left[i * decimate + decay] ),
- allsig_l[L - i - 1], win_left[L * decimate - i * decimate - 1 - decay] ) );
+ idx1 = i;
move16();
+ idx2 = add( i_mult( i, decimate ), decay );
+ idx3 = sub( sub( L, i ), 1 );
+ idx4 = sub( sub( sub( i_mult( L, decimate ), i_mult( i, decimate ) ), 1 ), decay );
+ wtda_audio[( i + ( L >> 1 ) )] = L_sub_sat( Mpy_32_16_1( allsig_l[idx1], win_left[idx2] ), Mpy_32_16_1( allsig_l[idx3], win_left[idx4] ) );
+ move32();
}
}
IF( old_wtda != NULL )
{
- Copy( new_audio, old_wtda, L );
+ Copy32( new_audio, old_wtda, L );
}
return;
}
-
void wtda_ext_fx(
const Word16 *new_audio, /* i : input audio (Q_in) */
Word16 *wtda_audio, /* o : windowed audio (Q_in - 1) */
diff --git a/lib_dec/ari_hm_dec.c b/lib_dec/ari_hm_dec_fx.c
similarity index 100%
rename from lib_dec/ari_hm_dec.c
rename to lib_dec/ari_hm_dec_fx.c
diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c
index c10c6beda022acd7c4dbefdb47d957741647b4c4..e26a56c1bb44b72f62e6c4bd06cc37c0619618f3 100644
--- a/lib_dec/ivas_cpe_dec_fx.c
+++ b/lib_dec/ivas_cpe_dec_fx.c
@@ -1264,7 +1264,7 @@ void destroy_cpe_dec(
IF( hCPE->hStereoDft != NULL )
{
- stereo_dft_dec_destroy( &( hCPE->hStereoDft ) );
+ stereo_dft_dec_destroy_fx( &( hCPE->hStereoDft ) );
hCPE->hStereoDft = NULL;
}
diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c
deleted file mode 100644
index 4770d21935134204355123ad7b3105131f63fe46..0000000000000000000000000000000000000000
--- a/lib_dec/ivas_init_dec.c
+++ /dev/null
@@ -1,3255 +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.
-
-*******************************************************************************************************/
-
-#include
-#include
-#include
-#include "options.h"
-#include "ivas_cnst.h"
-#include "ivas_prot_rend_fx.h"
-#include "rom_com.h"
-#include "ivas_rom_com.h"
-#include "ivas_stat_enc.h"
-#include "prot_fx.h"
-#include "wmc_auto.h"
-#include "ivas_prot_fx.h"
-
-
-/*-------------------------------------------------------------------*
- * Local function prototypes
- *-------------------------------------------------------------------*/
-
-static ivas_error ivas_read_format( Decoder_Struct *st_ivas, Word16 *num_bits_read );
-
-static ivas_error doSanityChecks_IVAS( Decoder_Struct *st_ivas );
-
-
-/*-------------------------------------------------------------------*
- * ivas_dec_setup()
- *
- * IVAS decoder setup
- *-------------------------------------------------------------------*/
-
-ivas_error ivas_dec_setup(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
- UWord16 *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */
- Word16 *data /* o : output synthesis signal */
-)
-{
- Word16 k, idx, num_bits_read;
- Word16 nchan_ism, element_mode_flag;
- Decoder_State *st;
- Word32 ivas_total_brate;
- ivas_error error;
-
- error = IVAS_ERR_OK;
- move32();
- num_bits_read = 0;
- move16();
- element_mode_flag = 0;
- move16();
-
- ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
- move32();
-
- /*-------------------------------------------------------------------*
- * Read IVAS format
- *-------------------------------------------------------------------*/
-
- ivas_read_format( st_ivas, &num_bits_read );
-
- Word16 SrcInd[MAX_NUM_TDREND_CHANNELS];
- Word16 num_src = 0;
- move16();
-
- /*-------------------------------------------------------------------*
- * Read other signling (ISM/MC mode, number of channels, etc.)
- *-------------------------------------------------------------------*/
-
- IF( is_DTXrate( ivas_total_brate ) == 0 )
- {
- /*-------------------------------------------------------------------*
- * Read IVAS format related signaling:
- * - in ISM : read number of objects
- * - in SBA : read SBA planar flag and SBA order
- * - in MASA : read number of TC
- * - in MC : read LS setup
- *-------------------------------------------------------------------*/
-
- IF( EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) )
- {
- element_mode_flag = 1;
- move16();
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) )
- {
- /* read the number of objects */
- st_ivas->nchan_transport = 1;
- move16();
- nchan_ism = 1;
- move16();
- Word32 res_dec, res_frac;
- iDiv_and_mod_32( ivas_total_brate, FRAMES_PER_SEC, &res_dec, &res_frac, 0 );
- k = extract_l( L_sub( res_dec, 1 ) );
-
- WHILE( st_ivas->bit_stream[k] && ( nchan_ism < MAX_NUM_OBJECTS ) )
- {
- nchan_ism = add( nchan_ism, 1 );
- k = sub( k, 1 );
- }
-
- st_ivas->nchan_ism = nchan_ism;
- move16();
-
- IF( NE_32( ( error = ivas_ism_dec_config_fx( st_ivas, st_ivas->ism_mode, nSamplesRendered, data ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) )
- {
- /* read Ambisonic (SBA) planar flag */
- st_ivas->sba_planar = st_ivas->bit_stream[num_bits_read];
- move16();
- num_bits_read = add( num_bits_read, SBA_PLANAR_BITS );
-
- /* read Ambisonic (SBA) order */
- st_ivas->sba_order = st_ivas->bit_stream[num_bits_read + 1];
- move16();
- st_ivas->sba_order = add( st_ivas->sba_order, shl( st_ivas->bit_stream[num_bits_read], 1 ) );
- move16();
- num_bits_read = add( num_bits_read, SBA_ORDER_BITS );
- test();
- test();
- IF( st_ivas->ini_frame > 0 && NE_32( ivas_total_brate, st_ivas->last_active_ivas_total_brate ) && GT_32( ivas_total_brate, IVAS_SID_5k2 ) )
- {
- IF( NE_32( ( error = ivas_sba_dec_reconfigure_fx( st_ivas, nSamplesRendered, data ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- ELSE
- {
- /* set Ambisonic (SBA) order used for analysis and coding */
- st_ivas->sba_analysis_order = ivas_sba_get_analysis_order_fx( ivas_total_brate, st_ivas->sba_order );
- move16();
- ivas_sba_config_fx( ivas_total_brate, st_ivas->sba_analysis_order, -1, &( st_ivas->nchan_transport ), st_ivas->sba_planar, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init );
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) )
- {
- /* read number of MASA transport channels */
- Word32 res_dec, res_frac;
- iDiv_and_mod_32( ivas_total_brate, FRAMES_PER_SEC, &res_dec, &res_frac, 0 );
- IF( st_ivas->bit_stream[res_dec - 1] )
- {
- st_ivas->nchan_transport = 2;
- move16();
- element_mode_flag = 1;
- move16();
- }
- ELSE
- {
- st_ivas->nchan_transport = 1;
- move16();
- }
-
- IF( st_ivas->ini_frame > 0 )
- {
- /* reconfigure in case a change of operation mode is detected */
- test();
- test();
- IF( ( GT_32( ivas_total_brate, IVAS_SID_5k2 ) && NE_32( ivas_total_brate, st_ivas->hDecoderConfig->last_ivas_total_brate ) ) || ( st_ivas->ini_active_frame == 0 ) )
- {
- IF( EQ_32( st_ivas->last_ivas_format, MASA_FORMAT ) )
- {
- test();
- test();
- test();
- IF( ( st_ivas->ini_active_frame == 0 ) && NE_32( ivas_total_brate, FRAME_NO_DATA ) && LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) && EQ_16( st_ivas->nCPE, 1 ) )
- {
- st_ivas->hCPE[0]->nchan_out = 1;
- move16();
- }
- ELSE
- {
- IF( NE_32( ( error = ivas_masa_dec_reconfigure_fx( st_ivas, nSamplesRendered, data ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- }
- ELSE
- {
- IF( NE_32( ( error = ivas_omasa_dec_config_fx( st_ivas, nSamplesRendered, &num_src, SrcInd, data ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- }
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
- {
- st_ivas->nchan_transport = 2; /* always 2 MASA transport channels */
- move16();
- /* for the DISC mode the number of objects are written at the end of the bitstream, in the MASA metadata */
-
- Word32 res_dec, res_frac;
- iDiv_and_mod_32( ivas_total_brate, FRAMES_PER_SEC, &res_dec, &res_frac, 0 );
- st_ivas->nchan_ism = add( add( shl( st_ivas->bit_stream[res_dec - 1], 1 ), st_ivas->bit_stream[res_dec - 2] ), 1 );
- move16();
- st_ivas->ism_mode = ivas_omasa_ism_mode_select_fx( ivas_total_brate, st_ivas->nchan_ism );
- move16();
- IF( st_ivas->ini_frame > 0 )
- {
- /* reconfigure in case a change of operation mode is detected */
- test();
- test();
- IF( ( GT_32( ivas_total_brate, IVAS_SID_5k2 ) && NE_32( ivas_total_brate, st_ivas->hDecoderConfig->last_ivas_total_brate ) ) || ( st_ivas->ini_active_frame == 0 ) )
- {
- IF( NE_32( ( error = ivas_omasa_dec_config_fx( st_ivas, nSamplesRendered, &num_src, SrcInd, data ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
- {
- /* the number of objects is written at the end of the bitstream, in the SBA metadata */
- Word32 res_dec, res_frac;
- iDiv_and_mod_32( ivas_total_brate, FRAMES_PER_SEC, &res_dec, &res_frac, 0 );
- st_ivas->nchan_ism = add( add( shl( st_ivas->bit_stream[res_dec - 1], 1 ), st_ivas->bit_stream[res_dec - 2] ), 1 );
- move16();
-
- test();
- IF( LT_32( ivas_total_brate, IVAS_24k4 ) || GE_32( ivas_total_brate, IVAS_256k ) )
- {
- /* read Ambisonic (SBA) planar flag */
- st_ivas->sba_planar = st_ivas->bit_stream[num_bits_read];
- move16();
- num_bits_read = add( num_bits_read, SBA_PLANAR_BITS );
- }
-
- st_ivas->sba_order = st_ivas->bit_stream[num_bits_read + 1];
- move16();
- st_ivas->sba_order = add( st_ivas->sba_order, shl( st_ivas->bit_stream[num_bits_read], 1 ) );
- move16();
- num_bits_read = add( num_bits_read, SBA_ORDER_BITS );
-
- /* read Ambisonic (SBA) order */
- if ( LT_32( ivas_total_brate, IVAS_256k ) )
- {
- st_ivas->sba_order = 3;
- move16();
- }
-
- test();
- IF( st_ivas->ini_frame > 0 && NE_32( ivas_total_brate, st_ivas->last_active_ivas_total_brate ) )
- {
- IF( NE_32( ( error = ivas_sba_dec_reconfigure_fx( st_ivas, nSamplesRendered, data ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- ELSE
- {
- /* set Ambisonic (SBA) order used for analysis and coding */
- st_ivas->sba_analysis_order = ivas_sba_get_analysis_order_fx( ivas_total_brate, st_ivas->sba_order );
- move16();
-
- ivas_sba_config_fx( ivas_total_brate, st_ivas->sba_analysis_order, -1, &( st_ivas->nchan_transport ), st_ivas->sba_planar, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init );
-
- /*correct number of CPEs for discrete ISM coding*/
- test();
- IF( st_ivas->ini_frame > 0 && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
- {
- st_ivas->nCPE = add( st_ivas->nCPE, shr( add( st_ivas->nchan_ism, 1 ), 1 ) );
- move16();
- }
- }
-
- IF( GE_32( ivas_total_brate, IVAS_256k ) )
- {
- st_ivas->ism_mode = ISM_SBA_MODE_DISC;
- move32();
- }
- ELSE
- {
- st_ivas->ism_mode = ISM_MODE_NONE;
- move32();
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) )
- {
- /* read MC configuration */
- idx = 0;
- move16();
- FOR( k = 0; k < MC_LS_SETUP_BITS; k++ )
- {
- IF( st_ivas->bit_stream[num_bits_read + k] )
- {
- idx = add( idx, shl( 1, sub( ( MC_LS_SETUP_BITS - 1 ), k ) ) );
- }
- }
- num_bits_read = add( num_bits_read, MC_LS_SETUP_BITS );
-
- /* select MC format mode; reconfigure the MC format decoder */
- IF( NE_32( ( error = ivas_mc_dec_config_fx( st_ivas, idx, nSamplesRendered, data ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- /*-------------------------------------------------------------------*
- * Read element mode
- *-------------------------------------------------------------------*/
-
- IF( st_ivas->ini_frame == 0 && element_mode_flag )
- {
- /* read stereo technology info */
- IF( LT_32( ivas_total_brate, MIN_BRATE_MDCT_STEREO ) )
- {
- /* 1 bit */
- IF( st_ivas->bit_stream[num_bits_read] )
- {
- st_ivas->element_mode_init = add( 1, IVAS_CPE_DFT );
- move16();
- }
- ELSE
- {
- st_ivas->element_mode_init = add( 0, IVAS_CPE_DFT );
- move16();
- }
- }
- ELSE
- {
- st_ivas->element_mode_init = IVAS_CPE_MDCT;
- move16();
- }
- }
- }
- ELSE IF( EQ_32( ivas_total_brate, IVAS_SID_5k2 ) )
- {
- SWITCH( st_ivas->sid_format )
- {
- case SID_DFT_STEREO:
- st_ivas->element_mode_init = IVAS_CPE_DFT;
- move16();
- BREAK;
- case SID_MDCT_STEREO:
- st_ivas->element_mode_init = IVAS_CPE_MDCT;
- move16();
- BREAK;
- case SID_ISM:
- st_ivas->element_mode_init = IVAS_SCE;
- move16();
- BREAK;
- case SID_MASA_1TC:
- st_ivas->element_mode_init = IVAS_SCE;
- move16();
- st_ivas->nchan_transport = 1;
- move16();
- BREAK;
- case SID_MASA_2TC:; // empyt statement for declaration
- Word32 res_dec, res_frac;
- iDiv_and_mod_32( ivas_total_brate, FRAMES_PER_SEC, &res_dec, &res_frac, 0 );
- IF( EQ_16( st_ivas->bit_stream[( res_dec - 1 ) - SID_FORMAT_NBITS], 1 ) )
- {
- st_ivas->element_mode_init = IVAS_CPE_MDCT;
- move16();
- }
- ELSE
- {
- st_ivas->element_mode_init = IVAS_CPE_DFT;
- move16();
- }
- st_ivas->nchan_transport = 2;
- move16();
- BREAK;
- case SID_SBA_1TC:
- st_ivas->element_mode_init = IVAS_SCE;
- move16();
- BREAK;
- case SID_SBA_2TC:
- st_ivas->element_mode_init = IVAS_CPE_MDCT;
- move16();
- BREAK;
- }
-
- test();
- IF( st_ivas->ini_frame > 0 && EQ_32( st_ivas->ivas_format, SBA_FORMAT ) )
- {
- Word16 nchan_transport_old, nchan_transport;
- nchan_transport_old = st_ivas->nchan_transport;
- move16();
- IF( ( EQ_16( st_ivas->sid_format, SID_SBA_2TC ) ) )
- {
- nchan_transport = 2;
- }
- ELSE
- {
- nchan_transport = 1;
- }
- move16();
-
- IF( NE_16( nchan_transport_old, nchan_transport ) )
- {
- /*Setting the default bitrate for the reconfig function*/
- IF( EQ_16( st_ivas->sid_format, SID_SBA_2TC ) )
- {
- st_ivas->hDecoderConfig->ivas_total_brate = IVAS_48k;
- move16();
- }
- ELSE
- {
- st_ivas->hDecoderConfig->ivas_total_brate = IVAS_24k4;
- move16();
- }
-
- IF( NE_32( ( error = ivas_sba_dec_reconfigure_fx( st_ivas, nSamplesRendered, data ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- st_ivas->last_active_ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
- move32();
- st_ivas->hDecoderConfig->ivas_total_brate = ivas_total_brate;
- move32();
- }
- }
-
- IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) )
- {
- ISM_MODE last_ism_mode = st_ivas->ism_mode;
- move32();
- /* read the number of objects */
- st_ivas->nchan_transport = 1;
- move16();
- nchan_ism = 1;
- move16();
- Word32 res_dec, res_frac;
- iDiv_and_mod_32( ivas_total_brate, FRAMES_PER_SEC, &res_dec, &res_frac, 0 );
- k = extract_l( L_sub( L_sub( res_dec, 1 ), SID_FORMAT_NBITS ) );
- move16();
-
- WHILE( st_ivas->bit_stream[k] && ( nchan_ism < MAX_NUM_OBJECTS ) )
- {
- nchan_ism = add( nchan_ism, 1 );
- k = sub( k, 1 );
- }
- k = sub( k, 1 );
-
- test();
- IF( st_ivas->ini_frame > 0 && NE_16( nchan_ism, st_ivas->nchan_ism ) )
- {
- return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "wrong number of objects signalled!" );
- }
-
- st_ivas->nchan_ism = nchan_ism;
- move16();
- /* read ism_mode */
- st_ivas->ism_mode = ISM_MODE_DISC;
- move32();
- IF( GT_16( nchan_ism, 2 ) )
- {
- k = sub( k, nchan_ism ); /* SID metadata flags */
- idx = st_ivas->bit_stream[k];
- move16();
- st_ivas->ism_mode = (ISM_MODE) add( idx, 1 );
- move32();
- }
-
- if ( st_ivas->ini_frame == 0 )
- {
- last_ism_mode = st_ivas->ism_mode;
- move32();
- }
-
- IF( NE_32( ( error = ivas_ism_dec_config_fx( st_ivas, last_ism_mode, nSamplesRendered, data ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- }
-
- /*-------------------------------------------------------------------*
- * Initialize decoder in the first good frame based on IVAS format
- * and number of transport channels
- *-------------------------------------------------------------------*/
- test();
- IF( st_ivas->ini_frame == 0 && NE_32( st_ivas->ivas_format, UNDEFINED_FORMAT ) )
- {
- IF( NE_32( ( error = doSanityChecks_IVAS( st_ivas ) ), IVAS_ERR_OK ) )
- {
- return IVAS_ERROR( error, "Sanity checks failed" );
- }
-
- IF( NE_32( ( error = ivas_init_decoder_fx( st_ivas ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
-
- /*----------------------------------------------------------------*
- * Reset bitstream pointers
- *----------------------------------------------------------------*/
-
- ivas_set_bitstream_pointers( st_ivas );
-
- reset_elements( st_ivas );
-
- /* update bitstream buffer pointer -> take into account already read bits */
- test();
- IF( ( st_ivas->nSCE > 0 ) || ( st_ivas->nCPE > 0 ) )
- {
- IF( st_ivas->nSCE > 0 )
- {
- st = st_ivas->hSCE[0]->hCoreCoder[0];
- }
- ELSE
- {
- st = st_ivas->hCPE[0]->hCoreCoder[0];
- }
- st->next_bit_pos = num_bits_read;
- move16();
- st->total_brate = ACELP_8k00; /* only temporary initialization - this is needed for get_next_indice() in the frame following NO_DATA frame */
- move32();
- }
-
- return error;
-}
-
-
-/*-------------------------------------------------------------------*
- * ivas_read_format()
- *
- * Read IVAS format signaling
- *-------------------------------------------------------------------*/
-
-static ivas_error ivas_read_format(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
- Word16 *num_bits_read /* o : number of IVAS signaling bits read from the bitstream */
-)
-{
- Word16 k, idx;
- Word32 ivas_total_brate;
- ivas_error error;
-
- error = IVAS_ERR_OK;
- move32();
-
- ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
- move32();
-
- *num_bits_read = 0;
- move16();
- test();
- test();
- IF( !st_ivas->bfi && is_DTXrate( ivas_total_brate ) == 0 )
- {
- /* read IVAS format */
- k = 0;
- move16();
- if ( st_ivas->bit_stream[*num_bits_read] )
- {
- k = 1;
- move16();
- }
- k = shl( k, 1 );
- ( *num_bits_read ) = add( ( *num_bits_read ), 1 );
- move16();
- if ( st_ivas->bit_stream[*num_bits_read] )
- {
- k = add( k, 1 );
- }
- ( *num_bits_read ) = add( ( *num_bits_read ), 1 );
- move16();
- SWITCH( k )
- {
- case 0:
- st_ivas->ivas_format = STEREO_FORMAT;
- move32();
- BREAK;
- case 1:
- st_ivas->ivas_format = MC_FORMAT;
- move32();
- BREAK;
- case 2:
- st_ivas->ivas_format = ISM_FORMAT;
- move32();
-
- IF( GE_32( ivas_total_brate, IVAS_24k4 ) )
- {
- IF( st_ivas->bit_stream[*num_bits_read] )
- {
- ( *num_bits_read ) = add( ( *num_bits_read ), 1 );
- move16();
- IF( st_ivas->bit_stream[*num_bits_read] )
- {
- st_ivas->ivas_format = SBA_ISM_FORMAT;
- move32();
- }
- ELSE
- {
- st_ivas->ivas_format = MASA_ISM_FORMAT;
- move32();
- }
- }
-
- ( *num_bits_read ) = add( ( *num_bits_read ), 1 );
- move16();
- }
- BREAK;
- case 3:
- IF( st_ivas->bit_stream[*num_bits_read] )
- {
- st_ivas->ivas_format = MASA_FORMAT;
- move32();
- }
- ELSE
- {
- st_ivas->ivas_format = SBA_FORMAT;
- move32();
- /* read Ambisonic (SBA) planar flag */
- st_ivas->sba_planar = st_ivas->bit_stream[( *num_bits_read ) + 1];
- move16();
-
- /* read Ambisonic (SBA) order */
- st_ivas->sba_order = st_ivas->bit_stream[( *num_bits_read ) + 2 + SBA_PLANAR_BITS];
- move16();
- st_ivas->sba_order = add( st_ivas->sba_order, shl( st_ivas->bit_stream[( *num_bits_read ) + 1 + SBA_PLANAR_BITS], 1 ) );
- move16();
- if ( st_ivas->sba_order == 0 )
- {
- st_ivas->ivas_format = SBA_ISM_FORMAT;
- move32();
- }
- }
- ( *num_bits_read ) = add( ( *num_bits_read ), 1 );
- move16();
-
- BREAK;
- }
- }
- ELSE IF( ( st_ivas->bfi == 0 ) && EQ_32( ivas_total_brate, IVAS_SID_5k2 ) )
- {
- /* read IVAS format in SID frame */
- idx = 0;
- move16();
- FOR( k = 0; k < SID_FORMAT_NBITS; k++ )
- {
- idx += st_ivas->bit_stream[k] << ( SID_FORMAT_NBITS - 1 - k );
- }
-
- ( *num_bits_read ) = add( *num_bits_read, SID_FORMAT_NBITS );
- move16();
- st_ivas->sid_format = idx;
- move16();
-
- SWITCH( idx )
- {
- case SID_DFT_STEREO:
- case SID_MDCT_STEREO:
- st_ivas->ivas_format = STEREO_FORMAT;
- move32();
- BREAK;
- case SID_ISM:
- st_ivas->ivas_format = ISM_FORMAT;
- move32();
- BREAK;
- case SID_MULTICHANNEL:
- st_ivas->ivas_format = MC_FORMAT;
- move32();
- BREAK;
- case SID_SBA_1TC:
- st_ivas->ivas_format = SBA_FORMAT;
- move32();
- st_ivas->element_mode_init = IVAS_SCE;
- move16();
- BREAK;
- case SID_SBA_2TC:
- st_ivas->ivas_format = SBA_FORMAT;
- move32();
- st_ivas->element_mode_init = IVAS_CPE_MDCT;
- move16();
- BREAK;
- case SID_MASA_1TC:
- st_ivas->ivas_format = MASA_FORMAT;
- move32();
- st_ivas->element_mode_init = IVAS_SCE;
- move16();
- BREAK;
- case SID_MASA_2TC:
- st_ivas->ivas_format = MASA_FORMAT;
- move32();
- Word32 res_dec, res_frac;
- iDiv_and_mod_32( ivas_total_brate, FRAMES_PER_SEC, &res_dec, &res_frac, 0 );
- IF( EQ_32( st_ivas->bit_stream[res_dec - 1], 1 ) )
- {
- st_ivas->element_mode_init = IVAS_CPE_MDCT;
- move16();
- }
- ELSE
- {
- st_ivas->element_mode_init = IVAS_CPE_DFT;
- move16();
- }
- BREAK;
- default:
- /* This should actually be impossible, since only 3 bits are read, so if this happens something is broken */
- return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Invalid value %c found in SID format field.", st_ivas->sid_format );
- }
-
- IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) )
- {
- if ( st_ivas->sba_analysis_order == 0 )
- {
- st_ivas->sba_analysis_order = SBA_FOA_ORDER;
- move16();
- }
- }
-
- /* reset bitstream handle to avoid BER detection after reading the 2400 kbps for ch0 */
- st_ivas->bit_stream = st_ivas->bit_stream + ( *num_bits_read );
- ( *num_bits_read ) = 0;
- move16();
- }
- ELSE
- {
- /* In SID/NO_DATA frames, use the previous frame IVAS format */
- }
-
- return error;
-}
-
-
-/*-------------------------------------------------------------------*
- * getNumChanSynthesis()
- *
- * get number of output channels used for synthesis/decoding
- * (often different from number of output channels!)
- *-------------------------------------------------------------------*/
-
-/*! r: number of channels to be synthesised */
-
-Word16 getNumChanSynthesis(
- Decoder_Struct *st_ivas /* i : IVAS decoder structure */
-)
-{
- Word16 n;
-
- n = add( st_ivas->nSCE, imult1616( CPE_CHANNELS, st_ivas->nCPE ) );
- test();
- test();
- IF( st_ivas->sba_dirac_stereo_flag )
- {
- n = CPE_CHANNELS;
- move16();
- }
- ELSE IF( ( st_ivas->hMCT != NULL || EQ_32( st_ivas->ivas_format, SBA_FORMAT ) ) && NE_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
- {
- n = st_ivas->nchan_transport;
- move16();
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
- {
- IF( EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
- {
- n = add( st_ivas->nchan_transport, st_ivas->nchan_ism );
- }
- ELSE
- {
- n = st_ivas->nchan_transport;
- move16();
- }
- }
-
- return n;
-}
-
-/*-------------------------------------------------------------------*
- * copy_decoder_config()
- *
- * Copy IVAS configuration structure to the CoreCoder state structure
- *-------------------------------------------------------------------*/
-
-void copy_decoder_config(
- Decoder_Struct *st_ivas, /* i : IVAS decoder structure */
- Decoder_State *st /* o : decoder state structure */
-)
-{
- st->output_Fs = st_ivas->hDecoderConfig->output_Fs;
- move32();
- st->Opt_AMR_WB = st_ivas->hDecoderConfig->Opt_AMR_WB;
- move16();
- st->codec_mode = st_ivas->codec_mode;
- move16();
- st->ini_frame = st_ivas->ini_frame;
- move16();
-
- st->bfi = st_ivas->bfi;
- move16();
-
- st->writeFECoffset = st_ivas->writeFECoffset;
- move16();
-
- st->element_mode = st_ivas->element_mode_init;
- move16();
-
- return;
-}
-
-/*-------------------------------------------------------------------*
- * ivas_init_decoder_front()
- *
- * Set decoder parameters to initial values
- *-------------------------------------------------------------------*/
-ivas_error ivas_init_decoder_front(
- Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
-)
-{
- ivas_error error;
-
- error = IVAS_ERR_OK;
- move32();
- /*-----------------------------------------------------------------*
- * Resets
- *-----------------------------------------------------------------*/
-
- st_ivas->nSCE = 0;
- move16();
- st_ivas->nCPE = 0;
- move16();
- st_ivas->nCPE_old = 0;
- move16();
- st_ivas->nchan_transport = -1;
- move16();
- st_ivas->ism_mode = ISM_MODE_NONE;
- move32();
- st_ivas->mc_mode = MC_MODE_NONE;
- move32();
- st_ivas->sba_dirac_stereo_flag = 0;
- move16();
-
- /* HRTF binauralization latency in ns */
- st_ivas->binaural_latency_ns = 0;
- move32();
-
- /*-------------------------------------------------------------------*
- * Allocate and initialize Custom loudspeaker layout handle
- *--------------------------------------------------------------------*/
-
- IF( st_ivas->hDecoderConfig->Opt_LsCustom )
- {
- IF( EQ_32( ( error = ivas_ls_custom_open_fx( &( st_ivas->hLsSetupCustom ) ) ), IVAS_ERR_OK ) )
- {
- set_zero_fx( ( st_ivas->hLsSetupCustom )->ls_azimuth_fx, MAX_OUTPUT_CHANNELS );
- set_zero_fx( ( st_ivas->hLsSetupCustom )->ls_elevation_fx, MAX_OUTPUT_CHANNELS );
- }
- ELSE
- {
- return error;
- }
- }
-
- /*-------------------------------------------------------------------*
- * Allocate and initialize Head-Tracking handle
- *--------------------------------------------------------------------*/
-
- IF( st_ivas->hDecoderConfig->Opt_Headrotation )
- {
- IF( NE_32( ( error = ivas_headTrack_open_fx( &( st_ivas->hHeadTrackData ) ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- error = ivas_orient_trk_SetTrackingType_fx( st_ivas->hHeadTrackData->OrientationTracker, st_ivas->hDecoderConfig->orientation_tracking );
- IF( NE_32( ( error ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- /*-------------------------------------------------------------------*
- * Allocate and initialize external orientation handle
- *--------------------------------------------------------------------*/
-
- IF( st_ivas->hDecoderConfig->Opt_ExternalOrientation )
- {
- IF( NE_32( ( error = ivas_external_orientation_open( &( st_ivas->hExtOrientationData ), st_ivas->hDecoderConfig->render_framesize ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- /*-------------------------------------------------------------------*
- * Allocate and initialize combined orientation handle
- *--------------------------------------------------------------------*/
- test();
- IF( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation )
- {
- IF( NE_32( ( error = ivas_combined_orientation_open( &( st_ivas->hCombinedOrientationData ), st_ivas->hDecoderConfig->output_Fs, st_ivas->hDecoderConfig->render_framesize ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- /*-------------------------------------------------------------------*
- * Allocate HRTF binary handle
- *--------------------------------------------------------------------*/
-
- IF( st_ivas->hDecoderConfig->Opt_HRTF_binary )
- {
- IF( NE_32( ( error = ivas_HRTF_binary_open_fx( &( st_ivas->hHrtfTD ) ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- IF( NE_32( ( error = ivas_HRTF_CRend_binary_open_fx( &( st_ivas->hSetOfHRTF ) ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- IF( NE_32( ( error = ivas_HRTF_fastconv_binary_open_fx( &st_ivas->hHrtfFastConv ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- IF( NE_32( ( error = ivas_HRTF_parambin_binary_open_fx( &st_ivas->hHrtfParambin ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- /*-------------------------------------------------------------------*
- * Allocate and initialize Binaural Renderer configuration handle
- *--------------------------------------------------------------------*/
- test();
- test();
- IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
- {
- IF( NE_32( ( error = ivas_render_config_open( &( st_ivas->hRenderConfig ) ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- IF( NE_32( ( error = ivas_render_config_init_from_rom_fx( &st_ivas->hRenderConfig ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- return error;
-}
-
-
-/*-------------------------------------------------------------------*
- * ivas_init_decoder()
- *
- * Initialize IVAS decoder state structure
- *-------------------------------------------------------------------*/
-ivas_error ivas_init_decoder_fx(
- Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
-)
-{
- Word16 i, n, k;
- Word16 sce_id, cpe_id;
- Word16 numCldfbAnalyses, numCldfbSyntheses;
- Word16 granularity, n_channels_transport_jbm;
- Word32 output_Fs, ivas_total_brate;
- Word32 binauralization_delay_ns;
- AUDIO_CONFIG output_config;
- DECODER_CONFIG_HANDLE hDecoderConfig;
- ivas_error error;
- Word32 ism_total_brate;
-
- error = IVAS_ERR_OK;
- move32();
- output_Fs = st_ivas->hDecoderConfig->output_Fs;
- move32();
- hDecoderConfig = st_ivas->hDecoderConfig;
- output_config = hDecoderConfig->output_config;
- ivas_total_brate = hDecoderConfig->ivas_total_brate;
- move32();
- hDecoderConfig->last_ivas_total_brate = ivas_total_brate;
- move32();
- st_ivas->last_active_ivas_total_brate = ivas_total_brate;
- move32();
- /*-----------------------------------------------------------------*
- * Set number of output channels for EXTERNAL output config.
- *-----------------------------------------------------------------*/
-
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
- {
- IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
- {
- hDecoderConfig->nchan_out = audioCfg2channels( IVAS_AUDIO_CONFIG_HOA3 );
- move16();
- hDecoderConfig->nchan_out = add( hDecoderConfig->nchan_out, st_ivas->nchan_ism );
- move16();
- }
- ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
- {
- hDecoderConfig->nchan_out = add( st_ivas->nchan_transport, st_ivas->nchan_ism );
- move16();
- }
- ELSE IF( !EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) )
- {
- hDecoderConfig->nchan_out = st_ivas->nchan_transport;
- move16();
- }
-
- st_ivas->hOutSetup.nchan_out_woLFE = hDecoderConfig->nchan_out;
- move16();
- }
-
- /*-----------------------------------------------------------------*
- * Set output and intern setup & renderer selection
- *-----------------------------------------------------------------*/
-
- st_ivas->intern_config = output_config;
- move32();
- ivas_output_init( &( st_ivas->hOutSetup ), output_config );
- test();
- IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) )
- {
- st_ivas->hOutSetup.ambisonics_order = SBA_HOA3_ORDER;
- move16();
- st_ivas->intern_config = IVAS_AUDIO_CONFIG_7_1_4;
- move32();
- st_ivas->hOutSetup.output_config = st_ivas->intern_config;
- move32();
- st_ivas->hOutSetup.nchan_out_woLFE = audioCfg2channels( st_ivas->intern_config );
- move16();
- }
- test();
- IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
- {
- st_ivas->hOutSetup.ambisonics_order = SBA_HOA3_ORDER;
- move32();
- st_ivas->intern_config = IVAS_AUDIO_CONFIG_HOA3;
- move32();
- st_ivas->hOutSetup.output_config = IVAS_AUDIO_CONFIG_HOA3;
- move32();
- st_ivas->hOutSetup.nchan_out_woLFE = audioCfg2channels( IVAS_AUDIO_CONFIG_HOA3 );
- move16();
- }
-
- /* Only initialize transport setup if it is used */
- IF( NE_32( st_ivas->transport_config, IVAS_AUDIO_CONFIG_INVALID ) )
- {
- ivas_output_init( &( st_ivas->hTransSetup ), st_ivas->transport_config );
- }
-
- test();
- IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) )
- {
- ivas_mcmasa_setNumTransportChannels_fx( &( st_ivas->nchan_transport ), &( st_ivas->element_mode_init ), ivas_total_brate );
-
- ivas_mcmasa_set_separate_channel_mode_fx( &( st_ivas->hOutSetup.separateChannelEnabled ), &( st_ivas->hOutSetup.separateChannelIndex ), ivas_total_brate );
- }
-
- ivas_renderer_select( st_ivas );
-
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
- {
- IF( EQ_16( ( error = ivas_ls_custom_output_init_fx( st_ivas ) ), IVAS_ERR_OK ) )
- {
- st_ivas->hOutSetup.ls_azimuth_fx = st_ivas->hLsSetupCustom->ls_azimuth_fx;
- move32();
- st_ivas->hOutSetup.ls_elevation_fx = st_ivas->hLsSetupCustom->ls_elevation_fx;
- move32();
- st_ivas->hIntSetup.ls_azimuth_fx = st_ivas->hLsSetupCustom->ls_azimuth_fx;
- move32();
- st_ivas->hIntSetup.ls_elevation_fx = st_ivas->hLsSetupCustom->ls_elevation_fx;
- move32();
- }
- ELSE
- {
- return error;
- }
- }
-
- ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->intern_config );
-
- test();
- IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) )
- {
- ivas_mcmasa_set_separate_channel_mode_fx( &( st_ivas->hIntSetup.separateChannelEnabled ), &( st_ivas->hIntSetup.separateChannelIndex ), ivas_total_brate );
-
- test();
- IF( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && st_ivas->hOutSetup.separateChannelEnabled )
- {
- st_ivas->hLsSetupCustom->separate_ch_found = 0;
- move16();
- IF( GE_16( st_ivas->hOutSetup.nchan_out_woLFE, MCMASA_MIN_SPEAKERS_SEPARATE_CENTER ) )
- {
- /* check for a speaker at (0, 0) if minimum speaker count is available */
- FOR( i = 0; i < st_ivas->hOutSetup.nchan_out_woLFE; i++ )
- {
- test();
- IF( ( L_shr( st_ivas->hOutSetup.ls_azimuth_fx[i], Q22 ) == 0 ) && ( L_shr( st_ivas->hOutSetup.ls_elevation_fx[i], Q22 ) == 0 ) )
- {
- st_ivas->hIntSetup.separateChannelIndex = i;
- move16();
- st_ivas->hLsSetupCustom->separate_ch_found = 1;
- move16();
- BREAK;
- }
- }
- }
- }
- }
-
-
- /*-----------------------------------------------------------------*
- * Allocate and initialize SCE/CPE and other handles
- *-----------------------------------------------------------------*/
-
- IF( EQ_32( st_ivas->ivas_format, MONO_FORMAT ) )
- {
- st_ivas->nSCE = 1; /* in mono, there is always only one SCE */
- move16();
- st_ivas->nCPE = 0;
- move16();
- st_ivas->nCPE_old = 0;
- move16();
- st_ivas->nchan_transport = 1;
- move16();
- sce_id = 0;
- move16();
-
- IF( NE_32( ( error = create_sce_dec( st_ivas, sce_id, ivas_total_brate ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] );
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) )
- {
- st_ivas->nchan_transport = CPE_CHANNELS;
- move16();
- st_ivas->intern_config = IVAS_AUDIO_CONFIG_STEREO;
- move32();
-
- st_ivas->nSCE = 0;
- move16();
- st_ivas->nCPE = 1; /* in stereo, there is always only one CPE */
- move16();
- st_ivas->nCPE_old = 0;
- move16();
- cpe_id = 0;
- move16();
-
- IF( NE_32( ( error = create_cpe_dec( st_ivas, cpe_id, ivas_total_brate ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- FOR( n = 0; n < st_ivas->nchan_transport; n++ )
- {
- reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] );
- }
-
- /* init EFAP for custom LS output and set hTransSetup */
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
- {
- IF( NE_32( ( error = efap_init_data_fx( &( st_ivas->hEFAPdata ), st_ivas->hOutSetup.ls_azimuth_fx, st_ivas->hOutSetup.ls_elevation_fx, st_ivas->hOutSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- ivas_output_init( &( st_ivas->hTransSetup ), IVAS_AUDIO_CONFIG_STEREO );
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) )
- {
- Word32 element_brate_tmp[MAX_NUM_OBJECTS];
-
- st_ivas->nSCE = st_ivas->nchan_transport; /* "st_ivas->nchan_transport" is known from ivas_dec_setup */
- move16();
- st_ivas->nCPE = 0;
- move16();
- st_ivas->nCPE_old = 0;
- move16();
- st_ivas->ism_extmeta_active = -1;
- move16();
- st_ivas->ism_extmeta_cnt = 0;
- move16();
- IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) )
- {
- st_ivas->nchan_transport = MAX_PARAM_ISM_WAVE;
- move16();
- st_ivas->nSCE = MAX_PARAM_ISM_WAVE;
- move16();
-
- IF( NE_32( ( error = ivas_param_ism_dec_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- IF( NE_32( ( error = ivas_ism_metadata_dec_create_fx( st_ivas, st_ivas->nSCE, element_brate_tmp ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
- {
- IF( NE_32( ( error = create_sce_dec( st_ivas, sce_id, element_brate_tmp[sce_id] ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] );
-
- st_ivas->hSCE[sce_id]->hCoreCoder[0]->is_ism_format = 1;
- move16();
- }
-
- st_ivas->hISMDTX.sce_id_dtx = 0;
- move16();
-
- IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) )
- {
- st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed2 = st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed3;
- move16();
- }
- ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MODE_DISC ) )
- {
- FOR( sce_id = 0; sce_id < st_ivas->nSCE; ++sce_id )
- {
- st_ivas->hSCE[sce_id]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed2 = add( 2, sce_id );
- move16();
- }
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) )
- {
- IF( NE_32( ( error = ivas_qmetadata_open_fx( &( st_ivas->hQMetaData ) ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- IF( NE_32( ( error = ivas_spar_dec_open_fx( st_ivas, 0 ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- set16_fx( st_ivas->hSpar->hFbMixer->cldfb_cross_fade_fx, 0, CLDFB_NO_COL_MAX );
- test();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_DEC ) && st_ivas->hOutSetup.is_loudspeaker_setup )
- {
- IF( NE_32( ( error = ivas_sba_get_hoa_dec_matrix_fx( st_ivas->hOutSetup, &st_ivas->hoa_dec_mtx, st_ivas->hIntSetup.ambisonics_order ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- Word16 hodirac_flag = ivas_get_hodirac_flag_fx( ivas_total_brate, st_ivas->sba_analysis_order );
- IF( hodirac_flag )
- {
- IF( NE_32( ( error = ivas_dirac_sba_config_fx( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, IVAS_MAX_NUM_BANDS, st_ivas->ivas_format ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- ELSE
- {
- IF( NE_32( ( error = ivas_dirac_sba_config_fx( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ), st_ivas->ivas_format ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
-
- test();
- test();
- IF( NE_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_FOA ) && NE_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) && NE_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_MONO ) )
- {
- IF( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_OPEN ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- st_ivas->hSpar->enc_param_start_band = st_ivas->hDirAC->hConfig->enc_param_start_band;
- move16();
- }
- ELSE
- {
- Word16 band_grouping[IVAS_MAX_NUM_BANDS + 1];
-
- st_ivas->hSpar->enc_param_start_band = s_min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND );
- move16();
- IF( ivas_get_hodirac_flag_fx( ivas_total_brate, st_ivas->sba_analysis_order ) )
- {
- st_ivas->hSpar->enc_param_start_band = 0;
- move16();
- set8_fx( (Word8 *) st_ivas->hQMetaData->twoDirBands, (Word8) 1, st_ivas->hQMetaData->q_direction[0].cfg.nbands );
- st_ivas->hQMetaData->numTwoDirBands = (UWord8) st_ivas->hQMetaData->q_direction[0].cfg.nbands;
- move16();
- }
-
- ivas_dirac_config_bands_fx( band_grouping, IVAS_MAX_NUM_BANDS, extract_l( Mpy_32_32_r( st_ivas->hDecoderConfig->output_Fs, INV_CLDFB_BANDWIDTH_Q31 ) ),
- st_ivas->hSpar->dirac_to_spar_md_bands, st_ivas->hQMetaData->useLowerBandRes, st_ivas->hSpar->enc_param_start_band, 0 );
- }
- st_ivas->sba_dirac_stereo_flag = ivas_get_sba_dirac_stereo_flag( st_ivas );
- move16();
- FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
- {
- Word32 res_dec, res_frac;
- iDiv_and_mod_32( ivas_total_brate, st_ivas->nchan_transport, &res_dec, &res_frac, 0 );
- IF( NE_32( ( error = create_sce_dec( st_ivas, sce_id, res_dec ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] );
- }
-
- FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
- {
- Word32 res_dec, res_frac;
- iDiv_and_mod_32( ivas_total_brate, st_ivas->nchan_transport, &res_dec, &res_frac, 0 );
- IF( NE_32( ( error = create_cpe_dec( st_ivas, cpe_id, (res_dec) *CPE_CHANNELS ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- FOR( n = 0; n < CPE_CHANNELS; n++ )
- {
- reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] );
- }
- }
-
- /* create CPE element for DFT Stereo like upmix */
- test();
- IF( st_ivas->sba_dirac_stereo_flag && ( st_ivas->nCPE == 0 ) )
- {
- Word32 res_dec, res_frac;
- iDiv_and_mod_32( ivas_total_brate, add( st_ivas->nSCE, st_ivas->nCPE ), &res_dec, &res_frac, 0 );
-
- IF( NE_32( ( error = create_cpe_dec( st_ivas, cpe_id, res_dec ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- st_ivas->hCPE[0]->hCoreCoder[0] = st_ivas->hSCE[0]->hCoreCoder[0]; /* don't allocate unnecessary core coder, simply point to core coder of SCE element */
- st_ivas->hCPE[0]->hCoreCoder[1] = NULL;
- }
-
- IF( GT_16( st_ivas->nCPE, 1 ) )
- {
- IF( NE_32( ( error = create_mct_dec_fx( st_ivas ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- /* set CNA/CNG flags */
- ivas_sba_set_cna_cng_flag( st_ivas );
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) )
- {
- /* if we start in ISM_MODE_NONE in MASA_ISM, that appears as normal MASA, but we may change to a mode with ISMs */
- st_ivas->ism_extmeta_active = -1;
- move16();
- st_ivas->ism_extmeta_cnt = 0;
- move16();
- IF( NE_32( ( error = ivas_qmetadata_open_fx( &( st_ivas->hQMetaData ) ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- IF( NE_32( ( error = ivas_masa_dec_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- test();
- test();
- test();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) || EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
- {
- IF( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_OPEN ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
- {
- Word32 res_dec, res_frac;
- iDiv_and_mod_32( ivas_total_brate, st_ivas->nchan_transport, &res_dec, &res_frac, 0 );
- IF( NE_32( ( error = create_sce_dec( st_ivas, sce_id, res_dec ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] );
- }
-
- FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
- {
- Word32 res_dec, res_frac;
- iDiv_and_mod_32( ivas_total_brate, st_ivas->nchan_transport, &res_dec, &res_frac, 0 );
- IF( NE_32( ( error = create_cpe_dec( st_ivas, cpe_id, L_shl( res_dec, 1 ) ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- FOR( n = 0; n < CPE_CHANNELS; n++ )
- {
- reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] );
- }
- }
-
- /* set CNA/CNG flags */
- ivas_sba_set_cna_cng_flag( st_ivas );
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
- {
- Word32 temp_brate[MAX_SCE];
- st_ivas->ism_extmeta_active = -1;
- move16();
- st_ivas->ism_extmeta_cnt = 0;
- move16();
-
- st_ivas->sba_dirac_stereo_flag = ivas_get_sba_dirac_stereo_flag( st_ivas );
- move16();
- IF( NE_32( ( error = ivas_qmetadata_open_fx( &( st_ivas->hQMetaData ) ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- IF( NE_32( ( error = ivas_spar_dec_open_fx( st_ivas, 0 ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- test();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_DEC ) && st_ivas->hOutSetup.is_loudspeaker_setup )
- {
- IF( NE_32( ( error = ivas_sba_get_hoa_dec_matrix_fx( st_ivas->hOutSetup, &st_ivas->hoa_dec_mtx, st_ivas->hIntSetup.ambisonics_order ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- Word16 hodirac_flag = ivas_get_hodirac_flag_fx( ivas_total_brate, st_ivas->sba_analysis_order );
- IF( hodirac_flag )
- {
- IF( NE_32( ( error = ivas_dirac_sba_config_fx( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, IVAS_MAX_NUM_BANDS, st_ivas->ivas_format ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- ELSE
- {
- IF( NE_32( ( error = ivas_dirac_sba_config_fx( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ), st_ivas->ivas_format ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
-
- test();
- test();
- IF( NE_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_FOA ) && NE_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) && NE_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_MONO ) )
- {
- IF( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_OPEN ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- st_ivas->hSpar->enc_param_start_band = st_ivas->hDirAC->hConfig->enc_param_start_band;
- move16();
- }
- ELSE
- {
- Word16 band_grouping[IVAS_MAX_NUM_BANDS + 1];
-
- st_ivas->hSpar->enc_param_start_band = s_min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND );
- move16();
- IF( ivas_get_hodirac_flag_fx( ivas_total_brate, st_ivas->sba_analysis_order ) )
- {
- st_ivas->hSpar->enc_param_start_band = 0;
- move16();
- set8_fx( (Word8 *) st_ivas->hQMetaData->twoDirBands, (Word8) 1, st_ivas->hQMetaData->q_direction[0].cfg.nbands );
- st_ivas->hQMetaData->numTwoDirBands = (UWord8) st_ivas->hQMetaData->q_direction[0].cfg.nbands;
- move16();
- }
-
- ivas_dirac_config_bands_fx( band_grouping, IVAS_MAX_NUM_BANDS, extract_l( Mpy_32_32_r( st_ivas->hDecoderConfig->output_Fs, INV_CLDFB_BANDWIDTH_Q31 ) ),
- st_ivas->hSpar->dirac_to_spar_md_bands, st_ivas->hQMetaData->useLowerBandRes, st_ivas->hSpar->enc_param_start_band, 0 );
- }
-
- FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
- {
- Word32 res_dec, res_frac;
- iDiv_and_mod_32( ivas_total_brate, st_ivas->nchan_transport, &res_dec, &res_frac, 0 );
- IF( NE_32( ( error = create_sce_dec( st_ivas, sce_id, res_dec ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] );
- }
-
- IF( EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
- {
- st_ivas->nCPE_old = st_ivas->nCPE;
- move16();
- st_ivas->nCPE = add( st_ivas->nCPE, shr( add( st_ivas->nchan_ism, 1 ), 1 ) );
- move16();
- st_ivas->element_mode_init = IVAS_CPE_MDCT;
- move16();
- }
-
- FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
- {
- Word32 res_dec, res_frac;
- iDiv_and_mod_32( ivas_total_brate, st_ivas->nchan_transport, &res_dec, &res_frac, 0 );
- IF( NE_32( ( error = create_cpe_dec( st_ivas, cpe_id, L_shl( res_dec, 1 ) ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- FOR( n = 0; n < CPE_CHANNELS; n++ )
- {
- reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] );
- }
- }
-
- /* create CPE element for DFT Stereo like upmix */
- test();
- IF( st_ivas->sba_dirac_stereo_flag && st_ivas->nCPE == 0 )
- {
- Word32 res_dec, res_frac;
- iDiv_and_mod_32( ivas_total_brate, add( st_ivas->nSCE, st_ivas->nCPE ), &res_dec, &res_frac, 0 );
- IF( NE_32( ( error = create_cpe_dec( st_ivas, cpe_id, res_dec ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- st_ivas->hCPE[0]->hCoreCoder[0] = st_ivas->hSCE[0]->hCoreCoder[0]; /* don't allocate unnecessary core coder, simply point to core coder of SCE element */
- st_ivas->hCPE[0]->hCoreCoder[1] = NULL;
- }
-
- IF( GT_16( st_ivas->nCPE, 1 ) )
- {
- IF( NE_32( ( error = create_mct_dec_fx( st_ivas ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- IF( EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
- {
- IF( NE_32( ( error = ivas_ism_metadata_dec_create_fx( st_ivas, st_ivas->nchan_ism, temp_brate ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- IF( NE_32( ( error = ivas_osba_data_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- /* set CNA/CNG flags */
- ivas_sba_set_cna_cng_flag( st_ivas );
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
- {
- st_ivas->ism_extmeta_active = -1;
- move16();
- st_ivas->ism_extmeta_cnt = 0;
- move16();
-
- IF( NE_32( ( error = ivas_qmetadata_open_fx( &( st_ivas->hQMetaData ) ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- k = 0;
- move16();
- ism_total_brate = 0;
- move32();
-
- WHILE( ( k < SIZE_IVAS_BRATE_TBL ) && ( ivas_total_brate != ivas_brate_tbl[k] ) )
- {
- k = add( k, 1 );
- }
- test();
- IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
- {
- /* one separated object */
- st_ivas->nSCE = 1;
- move16();
- ism_total_brate = sep_object_brate[k - 2][0];
- move32();
- IF( NE_32( ( error = create_sce_dec( st_ivas, 0, ism_total_brate ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- reset_indices_dec( st_ivas->hSCE[0]->hCoreCoder[0] );
-
- IF( NE_32( ( error = ivas_ism_metadata_dec_create_fx( st_ivas, 1, NULL ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
- {
- Word32 temp_brate[MAX_SCE];
- st_ivas->nSCE = st_ivas->nchan_ism; /* number of objects */
- move16();
- FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
- {
- temp_brate[sce_id] = sep_object_brate[k - 2][st_ivas->nSCE - 1];
- move32();
- ism_total_brate = L_add( ism_total_brate, temp_brate[sce_id] );
-
- IF( NE_32( ( error = create_sce_dec( st_ivas, sce_id, temp_brate[sce_id] ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] );
- }
-
- IF( NE_32( ( error = ivas_ism_metadata_dec_create_fx( st_ivas, st_ivas->nchan_ism, temp_brate ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- IF( NE_32( ( error = ivas_masa_dec_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- IF( NE_32( ( error = ivas_omasa_data_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- test();
- test();
- test();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) || EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
- {
- IF( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_OPEN ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- IF( NE_32( ( error = create_cpe_dec( st_ivas, 0, ivas_total_brate - ism_total_brate ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- FOR( n = 0; n < CPE_CHANNELS; n++ )
- {
- reset_indices_dec( st_ivas->hCPE[0]->hCoreCoder[n] );
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) )
- {
- IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCT ) )
- {
- /* init EFAP for custom LS setup */
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
- {
- IF( NE_32( ( error = efap_init_data_fx( &( st_ivas->hEFAPdata ), st_ivas->hLsSetupCustom->ls_azimuth_fx, st_ivas->hLsSetupCustom->ls_elevation_fx, st_ivas->hLsSetupCustom->num_spk, EFAP_MODE_EFAP ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- st_ivas->nchan_transport = ivas_mc_ls_setup_get_num_channels_fx( ivas_mc_map_output_config_to_mc_ls_setup_fx( st_ivas->transport_config ) );
- move16();
- st_ivas->nSCE = 0;
- move16();
- st_ivas->nCPE = shr( st_ivas->nchan_transport, 1 );
- move16();
- st_ivas->nCPE_old = 0;
- move16();
- st_ivas->element_mode_init = IVAS_CPE_MDCT;
- move16();
- FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
- {
- Word32 res_dec, res_frac;
- iDiv_and_mod_32( ivas_total_brate, sub( st_ivas->nchan_transport, 1 ), &res_dec, &res_frac, 0 );
- IF( NE_32( ( error = create_cpe_dec( st_ivas, cpe_id, L_shl( res_dec, 1 ) ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- FOR( n = 0; n < CPE_CHANNELS; n++ )
- {
- reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] );
- }
- }
-
- IF( NE_32( ( error = create_mct_dec_fx( st_ivas ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) )
- {
- /* init EFAP for custom LS setup */
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
- {
- IF( NE_32( ( error = efap_init_data_fx( &( st_ivas->hEFAPdata ), st_ivas->hLsSetupCustom->ls_azimuth_fx, st_ivas->hLsSetupCustom->ls_elevation_fx, st_ivas->hLsSetupCustom->num_spk, EFAP_MODE_EFAP ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- st_ivas->nSCE = 0;
- move16();
- st_ivas->nCPE = MC_PARAMUPMIX_MAX_TRANSPORT_CHANS >> 1;
- move16();
- st_ivas->nCPE_old = 0;
- move16();
- st_ivas->nchan_transport = MC_PARAMUPMIX_MAX_TRANSPORT_CHANS;
- move16();
-
- IF( NE_32( ( error = ivas_mc_paramupmix_dec_open( st_ivas ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- st_ivas->element_mode_init = IVAS_CPE_MDCT;
- move16();
- FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
- {
- Word32 res_dec, res_frac;
- iDiv_and_mod_32( ivas_total_brate, sub( st_ivas->nchan_transport, 1 ), &res_dec, &res_frac, 0 );
- IF( NE_32( ( error = create_cpe_dec( st_ivas, cpe_id, L_shl( res_dec, 1 ) ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- FOR( n = 0; n < CPE_CHANNELS; n++ )
- {
- reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] );
- }
- }
-
- IF( NE_32( ( error = create_mct_dec_fx( st_ivas ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) )
- {
- /* init EFAP for custom LS setup */
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
- {
- IF( NE_32( ( error = efap_init_data_fx( &( st_ivas->hEFAPdata ), st_ivas->hLsSetupCustom->ls_azimuth_fx, st_ivas->hLsSetupCustom->ls_elevation_fx, st_ivas->hLsSetupCustom->num_spk, EFAP_MODE_EFAP ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- IF( NE_32( ( error = ivas_param_mc_dec_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- st_ivas->hParamMC->proto_matrix_int_e = 0;
- move16();
- FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
- {
- Word32 res_dec, res_frac;
- iDiv_and_mod_32( ivas_total_brate, add( st_ivas->nSCE, st_ivas->nCPE ), &res_dec, &res_frac, 0 );
-
- IF( NE_32( ( error = create_cpe_dec( st_ivas, cpe_id, res_dec ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- FOR( n = 0; n < CPE_CHANNELS; n++ )
- {
- reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] );
- }
- }
-
- IF( GT_16( st_ivas->nCPE, 1 ) )
- {
- IF( NE_32( ( error = create_mct_dec_fx( st_ivas ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- }
- ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) )
- {
- Word32 brate_sce, brate_cpe;
-
- ivas_mcmasa_setNumTransportChannels_fx( &( st_ivas->nchan_transport ), &( st_ivas->element_mode_init ), ivas_total_brate );
-
- IF( NE_32( ( error = ivas_qmetadata_open_fx( &( st_ivas->hQMetaData ) ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- IF( NE_32( ( error = ivas_masa_dec_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
-
- {
- return error;
- }
-
- st_ivas->sba_dirac_stereo_flag = ivas_get_sba_dirac_stereo_flag( st_ivas );
- move16();
- test();
- IF( NE_32( st_ivas->renderer_type, RENDERER_DISABLE ) && NE_32( st_ivas->renderer_type, RENDERER_MCMASA_MONO_STEREO ) )
- {
- IF( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_OPEN ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- test();
- test();
- IF( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && st_ivas->hOutSetup.separateChannelEnabled && !st_ivas->hLsSetupCustom->separate_ch_found )
- {
- /* If no speaker matching the separated channel, compute panning gains for the separated channel. */
- IF( st_ivas->hVBAPdata == NULL )
- {
- /* Distribute signal to all channels if VBAP is not properly initialized. */
- Word16 inv_sqr, sqr, exp = 15, exp_sqr;
- move16();
- IF( EQ_16( st_ivas->hLsSetupCustom->num_spk, 1 ) )
- {
- inv_sqr = 32767; // (1.0f in Q15)-1
- move16();
- }
- ELSE
- {
- sqr = Sqrt16( st_ivas->hLsSetupCustom->num_spk, &exp );
- inv_sqr = BASOP_Util_Divide1616_Scale( 32767, sqr, &exp_sqr );
- exp_sqr = sub( exp_sqr, exp );
- IF( ( exp < 0 ) )
- {
- inv_sqr = shr( inv_sqr, exp ); // exp_sqr
- }
- ELSE
- {
- inv_sqr = shl( inv_sqr, exp ); // exp_sqr
- }
- }
- set16_fx( st_ivas->hLsSetupCustom->separate_ch_gains_fx, inv_sqr, st_ivas->hLsSetupCustom->num_spk );
- }
- }
-
-
- ivas_mcmasa_split_brate_fx( st_ivas->hOutSetup.separateChannelEnabled, ivas_total_brate, st_ivas->nSCE, st_ivas->nCPE, &brate_sce, &brate_cpe );
-
- FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
- {
- IF( NE_32( ( error = create_sce_dec( st_ivas, sce_id, brate_sce ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] );
- }
-
- FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
- {
- st_ivas->element_mode_init = IVAS_CPE_MDCT; /* element_mode_init was IVAS_SCE for SCE initialization */
- move16();
- IF( NE_32( ( error = create_cpe_dec( st_ivas, cpe_id, brate_cpe ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- FOR( n = 0; n < CPE_CHANNELS; n++ )
- {
- reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] );
- }
- }
-
- /* create CPE element for DFT Stereo like upmix */
- IF( st_ivas->sba_dirac_stereo_flag )
- {
- Word32 res_dec, res_frac;
- iDiv_and_mod_32( ivas_total_brate, add( st_ivas->nSCE, st_ivas->nCPE ), &res_dec, &res_frac, 0 );
- IF( NE_32( ( error = create_cpe_dec( st_ivas, cpe_id, res_dec ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- st_ivas->hCPE[0]->hCoreCoder[0] = st_ivas->hSCE[0]->hCoreCoder[0]; /* don't allocate unnecessary core coder, simply point to core coder of SCE element */
- st_ivas->hCPE[0]->hCoreCoder[1] = NULL;
- }
-
- /* set CNA/CNG flags */
- test();
- test();
- IF( EQ_16( st_ivas->nchan_transport, 1 ) && ( ( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) ) )
- {
- st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag = 1;
- move16();
- st_ivas->hSCE[0]->hCoreCoder[0]->cng_sba_flag = 1;
- move16();
- }
- }
- }
-
-
- /*-----------------------------------------------------------------*
- * Allocate and initialize HP20 filter memories
- *-----------------------------------------------------------------*/
-
- /* set number of output channels used for synthesis/decoding */
- n = getNumChanSynthesis( st_ivas );
-
- IF( n > 0 )
- {
- IF( ( st_ivas->mem_hp20_out_fx = (Word32 **) malloc( n * sizeof( Word32 * ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) );
- }
- }
- ELSE
- {
- st_ivas->mem_hp20_out_fx = NULL;
- }
-
- FOR( i = 0; i < n; i++ )
- {
- IF( ( st_ivas->mem_hp20_out_fx[i] = (Word32 *) malloc( ( L_HP20_MEM + 2 ) * sizeof( Word32 ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) );
- }
- set32_fx( st_ivas->mem_hp20_out_fx[i], 0, L_HP20_MEM + 2 );
- }
-
- /*-------------------------------------------------------------------*
- * Allocate and initialize rendering handles
- *--------------------------------------------------------------------*/
- test();
- test();
- test();
- test();
- test();
- test();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
- {
- IF( NE_32( ( error = ivas_binRenderer_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- /* ParamISM is handled separately from other common config */
- ELSE IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) && ( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) || EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) ) )
- {
- IF( NE_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) )
- {
- IF( NE_32( ( error = ivas_dirac_dec_binaural_copy_hrtfs_fx( &st_ivas->hHrtfParambin ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- IF( NE_32( ( error = ivas_dirac_dec_init_binaural_data_fx( st_ivas, st_ivas->hHrtfParambin ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) )
- {
- Word16 SrcInd[MAX_NUM_TDREND_CHANNELS];
- Word16 num_src;
- IF( NE_32( ( error = ivas_td_binaural_open_fx( st_ivas, SrcInd, &num_src ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- Word16 nchan_rend = num_src;
- move16();
- test();
- IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && NE_32( st_ivas->transport_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
- {
- nchan_rend = sub( nchan_rend, 1 ); /* Skip LFE channel -- added to the others */
- }
- FOR( Word16 nS = 0; nS < nchan_rend; nS++ )
- {
- TDREND_SRC_t *Src_p = st_ivas->hBinRendererTd->Sources[SrcInd[nS]];
- if ( Src_p->SrcSpatial_p != NULL )
- {
- Src_p->SrcSpatial_p->q_Pos_p = Q31;
- move16();
- }
- TDREND_SRC_SPATIAL_t *SrcSpatial_p = st_ivas->hBinRendererTd->Sources[nS]->SrcSpatial_p;
- SrcSpatial_p->q_Pos_p = Q31;
- move16();
- }
-
- IF( EQ_32( st_ivas->hIntSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
- {
- IF( NE_32( ( error = ivas_reverb_open_fx( &st_ivas->hReverb, st_ivas->hDecoderConfig->output_config, NULL, st_ivas->hBinRendererTd->HrFiltSet_p->lr_energy_and_iac_fx, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- granularity = NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES );
-
- n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas );
-
-
- IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, TC_BUFFER_MODE_RENDERER, n_channels_transport_jbm, n_channels_transport_jbm, n_channels_transport_jbm, granularity ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_MC ) )
- {
- IF( NE_32( ( error = ivas_ls_setup_conversion_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) )
- {
- IF( NE_32( ( error = ivas_mono_dmx_renderer_open( st_ivas ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) )
- {
- test();
- test();
- test();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) && EQ_32( st_ivas->ivas_format, MC_FORMAT ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) )
- {
- IF( NE_32( ( error = efap_init_data_fx( &( st_ivas->hEFAPdata ), st_ivas->hIntSetup.ls_azimuth_fx, st_ivas->hIntSetup.ls_elevation_fx, st_ivas->hIntSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- IF( NE_32( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config,
- st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs ) ),
- IVAS_ERR_OK ) )
- {
- return error;
- }
-
- st_ivas->binaural_latency_ns = st_ivas->hCrendWrapper->binaural_latency_ns;
- move32();
-
- test();
- IF( ( EQ_32( st_ivas->ivas_format, MC_FORMAT ) ) && ( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) ) )
- {
- granularity = NS2SA_FX2( output_Fs, CLDFB_SLOT_NS );
-
- n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas );
-
-
- IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, TC_BUFFER_MODE_RENDERER, n_channels_transport_jbm, MC_PARAMUPMIX_MAX_INPUT_CHANS, MC_PARAMUPMIX_MAX_INPUT_CHANS, granularity ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- ELSE
- {
- granularity = NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES );
-
- n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas );
-
- IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, TC_BUFFER_MODE_RENDERER, n_channels_transport_jbm, n_channels_transport_jbm, n_channels_transport_jbm, granularity ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- }
-
- IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
- {
- test();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
- {
- /* Allocate TD renderer for the objects in DISC mode */
- Word16 SrcInd[MAX_NUM_TDREND_CHANNELS];
- Word16 num_src;
- IF( NE_32( ( error = ivas_td_binaural_open_fx( st_ivas, SrcInd, &num_src ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- Word16 nchan_rend = num_src;
- move16();
- test();
- if ( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && NE_32( st_ivas->transport_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
- {
- nchan_rend = sub( nchan_rend, 1 ); /* Skip LFE channel -- added to the others */
- }
- FOR( Word16 nS = 0; nS < nchan_rend; nS++ )
- {
- TDREND_SRC_t *Src_p = st_ivas->hBinRendererTd->Sources[SrcInd[nS]];
- if ( Src_p->SrcSpatial_p != NULL )
- {
- Src_p->SrcSpatial_p->q_Pos_p = Q31;
- move16();
- }
- TDREND_SRC_SPATIAL_t *SrcSpatial_p = st_ivas->hBinRendererTd->Sources[nS]->SrcSpatial_p;
- SrcSpatial_p->q_Pos_p = Q31;
- move16();
- }
-
- /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
- IF( NE_32( ( error = ivas_omasa_separate_object_renderer_open( st_ivas ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- test();
- test();
- test();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && ( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) )
- {
- /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
- IF( NE_32( ( error = ivas_omasa_separate_object_renderer_open( st_ivas ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- }
-
- test();
- test();
- test();
- test();
- test();
- test();
- test();
- test();
- test();
- test();
- test();
- test();
- IF( ( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) || EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) &&
- ( EQ_32( st_ivas->ism_mode, ISM_MODE_DISC ) || EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) ) &&
- ( EQ_32( st_ivas->renderer_type, RENDERER_TD_PANNING ) ||
- EQ_32( st_ivas->renderer_type, RENDERER_NON_DIEGETIC_DOWNMIX ) ||
- EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ||
- EQ_32( st_ivas->renderer_type, RENDERER_OSBA_STEREO ) ||
- EQ_32( st_ivas->renderer_type, RENDERER_OSBA_AMBI ) ||
- EQ_32( st_ivas->renderer_type, RENDERER_OSBA_LS ) ||
- EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) ||
- EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ||
- EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) ) )
- {
- IF( NE_32( ( error = ivas_ism_renderer_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
- {
- test();
- test();
- IF( ( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) ) && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
- {
- /* Allocate TD renderer for the objects in DISC mode */
- Word16 SrcInd[MAX_NUM_TDREND_CHANNELS];
- Word16 num_src;
- IF( NE_32( ( error = ivas_td_binaural_open_fx( st_ivas, SrcInd, &num_src ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- Word16 nchan_rend = num_src;
- move16();
-
- test();
- if ( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && NE_32( st_ivas->transport_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
- {
- nchan_rend = sub( nchan_rend, 1 ); /* Skip LFE channel -- added to the others */
- }
- FOR( Word16 nS = 0; nS < nchan_rend; nS++ )
- {
- TDREND_SRC_t *Src_p = st_ivas->hBinRendererTd->Sources[SrcInd[nS]];
- if ( Src_p->SrcSpatial_p != NULL )
- {
- Src_p->SrcSpatial_p->q_Pos_p = Q31;
- move16();
- }
- TDREND_SRC_SPATIAL_t *SrcSpatial_p = st_ivas->hBinRendererTd->Sources[nS]->SrcSpatial_p;
- SrcSpatial_p->q_Pos_p = Q31;
- move16();
- }
- }
- }
-
- /*-----------------------------------------------------------------*
- * LFE handles for rendering after rendering to adjust LFE delay to binaural filter delay
- *-----------------------------------------------------------------*/
- test();
- IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCT ) || EQ_32( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) )
- {
- binauralization_delay_ns = st_ivas->binaural_latency_ns;
- move32();
- IF( st_ivas->hBinRenderer != NULL )
- {
- IF( st_ivas->hBinRenderer->render_lfe )
- {
- {
- /* Account for filterbank delay */
- binauralization_delay_ns = L_add( binauralization_delay_ns, IVAS_FB_DEC_DELAY_NS );
- }
- }
- ELSE
- {
- binauralization_delay_ns = 0;
- move32();
- }
- }
-
- IF( NE_32( ( error = ivas_create_lfe_dec_fx( &st_ivas->hLFE, output_Fs, binauralization_delay_ns ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- set32_fx( st_ivas->hLFE->prevsynth_buf_fx, 0, LFE_PLC_BUFLEN );
- set32_fx( st_ivas->hLFE->prior_out_buffer_fx, 0, L_FRAME48k );
- }
-
- /*-----------------------------------------------------------------*
- * CLDFB handles for rendering
- *-----------------------------------------------------------------*/
-
- ivas_init_dec_get_num_cldfb_instances_ivas_fx( st_ivas, &numCldfbAnalyses, &numCldfbSyntheses );
-
- FOR( i = 0; i < numCldfbAnalyses; i++ )
- {
- IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- FOR( ; i < MAX_INTERN_CHANNELS; i++ )
- {
- st_ivas->cldfbAnaDec[i] = NULL;
- }
-
- FOR( i = 0; i < numCldfbSyntheses; i++ )
- {
- IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- FOR( ; i < MAX_OUTPUT_CHANNELS; i++ )
- {
- st_ivas->cldfbSynDec[i] = NULL;
- }
-
- /* CLDFB Interpolation weights */
- test();
- test();
- test();
- IF( ( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) || EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) && !st_ivas->sba_dirac_stereo_flag && NE_16( st_ivas->hDecoderConfig->nchan_out, 1 ) )
- {
- Word16 Q_cldfbSynDec = Q11;
- move16();
- ivas_spar_get_cldfb_gains_fx( st_ivas->hSpar, st_ivas->cldfbAnaDec[0], st_ivas->cldfbSynDec[0], hDecoderConfig );
-
- FOR( i = 0; i < st_ivas->cldfbAnaDec[0]->cldfb_state_length; i++ )
- {
- st_ivas->cldfbAnaDec[0]->cldfb_state_fx[i] = L_shr( st_ivas->cldfbAnaDec[0]->cldfb_state_fx[i], 16 ); // Scaling down from 27 to 11
- move32();
- }
- st_ivas->cldfbAnaDec[0]->Q_cldfb_state = Q11;
- move16();
- FOR( i = 0; i < st_ivas->cldfbSynDec[0]->cldfb_state_length; i++ )
- {
- st_ivas->cldfbSynDec[0]->cldfb_state_fx[i] = L_shr( st_ivas->cldfbSynDec[0]->cldfb_state_fx[i], sub( 21, Q_cldfbSynDec ) ); // Scaling down from 21 to Q_cldfbSynDec
- move32();
- }
- st_ivas->cldfbSynDec[0]->Q_cldfb_state = Q11;
- move16();
- }
-
- /*-----------------------------------------------------------------*
- * Allocate and initialize limiter struct
- *-----------------------------------------------------------------*/
-
- IF( NE_32( ( error = ivas_limiter_open_fx( &st_ivas->hLimiter, hDecoderConfig->nchan_out, output_Fs ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- /*-----------------------------------------------------------------*
- * Allocate and initialize JBM struct + buffer
- *-----------------------------------------------------------------*/
-
- IF( st_ivas->hTcBuffer == NULL )
-
- {
- /* no module has yet open the TC buffer, open a default one */
- n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas );
-
- IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, ivas_jbm_dec_get_tc_buffer_mode( st_ivas ), n_channels_transport_jbm, n_channels_transport_jbm, n_channels_transport_jbm, NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- IF( st_ivas->hTcBuffer == NULL )
- {
- /* we need the handle anyway, but without the buffer*/
- IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, TC_BUFFER_MODE_NONE, 0, 0, 0, 1 ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
-
- IF( st_ivas->hJbmMetadata == NULL )
- {
- IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
- {
- IF( NE_32( ( error = ivas_jbm_dec_metadata_open( st_ivas ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- }
-
- /*-----------------------------------------------------------------*
- * Allocate floating-point output audio buffers
- *-----------------------------------------------------------------*/
- st_ivas->p_out_len = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate );
- move16();
- FOR( n = 0; n < ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); n++ )
- {
- /* note: these are intra-frame heap memories */
- IF( ( st_ivas->p_output_fx[n] = (Word32 *) malloc( ( 48000 / FRAMES_PER_SEC ) * sizeof( Word32 ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for floating-point output audio buffer!\n" ) );
- }
- set32_fx( st_ivas->p_output_fx[n], 0, 48000 / FRAMES_PER_SEC );
- }
-
- FOR( ; n < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; n++ )
- {
- st_ivas->p_output_fx[n] = NULL;
- }
- return error;
-}
-
-/*-------------------------------------------------------------------------
- * destroy_core_dec()
- *
- * Close core decoder handles
- *-------------------------------------------------------------------------*/
-
-void destroy_core_dec_fx(
- DEC_CORE_HANDLE hCoreCoder /* i/o: core decoder structure */
-)
-{
- IF( EQ_16( hCoreCoder->element_mode, EVS_MONO ) )
- {
- destroy_cldfb_decoder_fx( hCoreCoder );
- }
- ELSE
- {
- destroy_cldfb_decoder_ivas_fx( hCoreCoder );
- }
-
- IF( hCoreCoder->hGSCDec != NULL )
- {
- free( hCoreCoder->hGSCDec );
- hCoreCoder->hGSCDec = NULL;
- }
-
- IF( hCoreCoder->hPFstat != NULL )
- {
- free( hCoreCoder->hPFstat );
- hCoreCoder->hPFstat = NULL;
- }
-
- IF( hCoreCoder->hMusicPF != NULL )
- {
- free( hCoreCoder->hMusicPF );
- hCoreCoder->hMusicPF = NULL;
- }
-
- IF( hCoreCoder->hBPF != NULL )
- {
- free( hCoreCoder->hBPF );
- hCoreCoder->hBPF = NULL;
- }
-
- IF( hCoreCoder->hBWE_zero != NULL )
- {
- free( hCoreCoder->hBWE_zero );
- hCoreCoder->hBWE_zero = NULL;
- }
-
- IF( hCoreCoder->hTdCngDec != NULL )
- {
- free( hCoreCoder->hTdCngDec );
- hCoreCoder->hTdCngDec = NULL;
- }
-
- IF( hCoreCoder->hSC_VBR != NULL )
- {
- free( hCoreCoder->hSC_VBR );
- hCoreCoder->hSC_VBR = NULL;
- }
-
- IF( hCoreCoder->hAmrwb_IO != NULL )
- {
- free( hCoreCoder->hAmrwb_IO );
- hCoreCoder->hAmrwb_IO = NULL;
- }
-
- IF( hCoreCoder->hBWE_TD != NULL )
- {
- free( hCoreCoder->hBWE_TD );
- hCoreCoder->hBWE_TD = NULL;
- }
-
- IF( hCoreCoder->hBWE_FD != NULL )
- {
- free( hCoreCoder->hBWE_FD );
- hCoreCoder->hBWE_FD = NULL;
- }
-
- IF( hCoreCoder->hBWE_FD_HR != NULL )
- {
- free( hCoreCoder->hBWE_FD_HR );
- hCoreCoder->hBWE_FD_HR = NULL;
- }
-
- IF( hCoreCoder->hWIDec != NULL )
- {
- free( hCoreCoder->hWIDec );
- hCoreCoder->hWIDec = NULL;
- }
-
- IF( hCoreCoder->hTECDec != NULL )
- {
- free( hCoreCoder->hTECDec );
- hCoreCoder->hTECDec = NULL;
- }
-
- IF( hCoreCoder->hTcxLtpDec != NULL )
- {
- free( hCoreCoder->hTcxLtpDec );
- hCoreCoder->hTcxLtpDec = NULL;
- }
-
- IF( hCoreCoder->hTcxDec != NULL )
- {
- free( hCoreCoder->hTcxDec );
- hCoreCoder->hTcxDec = NULL;
- }
-
- IF( hCoreCoder->hTcxCfg != NULL )
- {
- free( hCoreCoder->hTcxCfg );
- hCoreCoder->hTcxCfg = NULL;
- }
-
- IF( hCoreCoder->hTonalMDCTConc != NULL )
- {
- free( hCoreCoder->hTonalMDCTConc );
- hCoreCoder->hTonalMDCTConc = NULL;
- }
-
- IF( hCoreCoder->hIGFDec != NULL )
- {
- free( hCoreCoder->hIGFDec );
- hCoreCoder->hIGFDec = NULL;
- }
-
- IF( hCoreCoder->hPlcInfo != NULL )
- {
- free( hCoreCoder->hPlcInfo );
- hCoreCoder->hPlcInfo = NULL;
- }
-
- IF( hCoreCoder->hHQ_core != NULL )
- {
- free( hCoreCoder->hHQ_core );
- hCoreCoder->hHQ_core = NULL;
- }
-
- IF( hCoreCoder->hHQ_nbfec != NULL )
- {
- free( hCoreCoder->hHQ_nbfec );
- hCoreCoder->hHQ_nbfec = NULL;
- }
-
- return;
-}
-
-/*-------------------------------------------------------------------------
- * ivas_initialize_handles_dec()
- *
- * NULL initialization of handles
- *-------------------------------------------------------------------------*/
-
-void ivas_initialize_handles_dec(
- Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
-)
-{
- Word16 i;
-
- FOR( i = 0; i < MAX_INTERN_CHANNELS; i++ )
- {
- st_ivas->cldfbAnaDec[i] = NULL;
- }
-
- FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ )
- {
- st_ivas->cldfbSynDec[i] = NULL;
- }
-
- /* SCE handles */
- FOR( i = 0; i < MAX_SCE; i++ )
- {
- st_ivas->hSCE[i] = NULL;
- }
-
- /* CPE handles */
- FOR( i = 0; i < MAX_CPE; i++ )
- {
- st_ivas->hCPE[i] = NULL;
- }
-
- st_ivas->bit_stream = NULL;
- st_ivas->mem_hp20_out_fx = NULL;
- st_ivas->hLimiter = NULL;
-
- /* ISM metadata handles */
- FOR( i = 0; i < MAX_NUM_OBJECTS; i++ )
- {
- st_ivas->hIsmMetaData[i] = NULL;
- }
-
- /* spatial coding handles */
- st_ivas->hDirAC = NULL;
- st_ivas->hParamIsmDec = NULL;
- st_ivas->hSpar = NULL;
- st_ivas->hMasa = NULL;
- st_ivas->hQMetaData = NULL;
- st_ivas->hMCT = NULL;
- st_ivas->hMCParamUpmix = NULL;
- st_ivas->hParamMC = NULL;
- st_ivas->hLFE = NULL;
-
- /* rendering handles */
- st_ivas->hBinRenderer = NULL;
- st_ivas->hDiracDecBin = NULL;
- st_ivas->hDirACRend = NULL;
- st_ivas->hSpatParamRendCom = NULL;
- st_ivas->hLsSetUpConversion = NULL;
- st_ivas->hEFAPdata = NULL;
- st_ivas->hVBAPdata = NULL;
- st_ivas->hIsmRendererData = NULL;
- st_ivas->hBinRendererTd = NULL;
- st_ivas->hMonoDmxRenderer = NULL;
- st_ivas->hCrendWrapper = NULL;
- st_ivas->hReverb = NULL;
- st_ivas->hSetOfHRTF = NULL;
- st_ivas->hHrtfFastConv = NULL;
- st_ivas->hHrtfParambin = NULL;
- st_ivas->hoa_dec_mtx = NULL;
- st_ivas->hMasaIsmData = NULL;
- st_ivas->hSbaIsmData = NULL;
-
- st_ivas->hHeadTrackData = NULL;
- st_ivas->hHrtfTD = NULL;
- st_ivas->hLsSetupCustom = NULL;
- st_ivas->hRenderConfig = NULL;
- st_ivas->hExtOrientationData = NULL;
- st_ivas->hCombinedOrientationData = NULL;
-
-
- /* JBM handles */
- st_ivas->hTcBuffer = NULL;
- st_ivas->hJbmMetadata = NULL;
-
- /* floating-point output audio buffers */
- FOR( i = 0; i < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; i++ )
- {
- st_ivas->p_output_fx[i] = NULL;
- }
-
- return;
-}
-
-
-/*-------------------------------------------------------------------------
- * ivas_destroy_dec()
- *
- * Close IVAS decoder handles
- *-------------------------------------------------------------------------*/
-
-void ivas_destroy_dec_fx(
- Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */
-)
-{
- Word16 i;
-
- /* CLDFB handles */
- FOR( i = 0; i < MAX_INTERN_CHANNELS; i++ )
- {
- IF( st_ivas->cldfbAnaDec[i] != NULL )
- {
- deleteCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ) );
- }
- }
-
- FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ )
- {
- IF( st_ivas->cldfbSynDec[i] != NULL )
- {
- deleteCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ) );
- }
- }
-
- /* SCE handles */
- FOR( i = 0; i < MAX_SCE; i++ )
- {
- IF( st_ivas->hSCE[i] != NULL )
- {
- destroy_sce_dec( st_ivas->hSCE[i] );
- st_ivas->hSCE[i] = NULL;
- }
- }
-
- /* CPE handles */
- FOR( i = 0; i < MAX_CPE; i++ )
- {
- IF( st_ivas->hCPE[i] != NULL )
- {
- /* set pointer to NULL as core coder already deallocated in destroy_sce_dec() */
- test();
- IF( st_ivas->sba_dirac_stereo_flag && EQ_16( st_ivas->nchan_transport, 1 ) )
- {
- st_ivas->hCPE[i]->hCoreCoder[0] = NULL;
- st_ivas->hCPE[i]->hCoreCoder[1] = NULL;
- }
- destroy_cpe_dec( st_ivas->hCPE[i] );
- st_ivas->hCPE[i] = NULL;
- }
- }
-
- /* HP20 filter handles */
- IF( st_ivas->mem_hp20_out_fx != NULL )
- {
- FOR( i = 0; i < getNumChanSynthesis( st_ivas ); i++ )
- {
- free( st_ivas->mem_hp20_out_fx[i] );
- st_ivas->mem_hp20_out_fx[i] = NULL;
- }
- free( st_ivas->mem_hp20_out_fx );
- st_ivas->mem_hp20_out_fx = NULL;
- }
-
- /* ISM metadata handles */
- ivas_ism_metadata_close( st_ivas->hIsmMetaData, 0 );
-
- /* ISM renderer handle */
- ivas_ism_renderer_close( &( st_ivas->hIsmRendererData ) );
-
- /* DirAC handle */
- IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) )
- {
- ivas_param_ism_dec_close_fx( &( st_ivas->hParamIsmDec ), &( st_ivas->hSpatParamRendCom ), st_ivas->hDecoderConfig->output_config );
- }
- ELSE
- {
- ivas_dirac_rend_close_fx( &( st_ivas->hDirACRend ) );
- ivas_spat_hSpatParamRendCom_close_fx( &( st_ivas->hSpatParamRendCom ) );
- ivas_dirac_dec_close_fx( &( st_ivas->hDirAC ) );
- }
-
- /* SPAR handle */
- ivas_spar_dec_close_fx( &( st_ivas->hSpar ), st_ivas->hDecoderConfig->output_Fs, 0 );
-
- /* HOA decoder matrix */
- IF( st_ivas->hoa_dec_mtx != NULL )
- {
- free( st_ivas->hoa_dec_mtx );
- st_ivas->hoa_dec_mtx = NULL;
- }
-
- /* MASA decoder structure */
-
- ivas_masa_dec_close_fx( &( st_ivas->hMasa ) );
- /* Qmetadata handle */
- ivas_qmetadata_close_fx( &st_ivas->hQMetaData );
-
- /* MCT handle */
- ivas_mct_dec_close( &st_ivas->hMCT );
-
- /* LFE handle */
- ivas_lfe_dec_close_fx( &( st_ivas->hLFE ) );
-
- /* Param-Upmix MC handle */
- ivas_mc_paramupmix_dec_close( &( st_ivas->hMCParamUpmix ) );
-
- /* Parametric MC handle */
- ivas_param_mc_dec_close_fx( &st_ivas->hParamMC );
-
- /* EFAP handle */
- efap_free_data_fx( &st_ivas->hEFAPdata );
-
- /* VBAP handle */
- vbap_free_data_fx( &( st_ivas->hVBAPdata ) );
- /* Fastconv binaural renderer handle */
- ivas_binRenderer_close_fx( &st_ivas->hBinRenderer );
-
- /* Parametric binaural renderer handle */
- ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin );
-
- /* Crend handle */
-
- ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) );
-
- /* Reverb handle */
- ivas_reverb_close( &st_ivas->hReverb );
-
- /* LS config converter handle */
-
- ivas_ls_setup_conversion_close_fx( &st_ivas->hLsSetUpConversion );
- /* Custom LS configuration handle */
- IF( st_ivas->hLsSetupCustom != NULL )
- {
- free( st_ivas->hLsSetupCustom );
- st_ivas->hLsSetupCustom = NULL;
- }
-
- /* Mono downmix structure */
- ivas_mono_dmx_renderer_close( &st_ivas->hMonoDmxRenderer );
-
- /* OSBA structure */
-
- ivas_osba_data_close_fx( &st_ivas->hSbaIsmData );
-
- /* OMASA structure */
- ivas_omasa_data_close_fx( &st_ivas->hMasaIsmData );
- /* Head track data handle */
- ivas_headTrack_close_fx( &st_ivas->hHeadTrackData );
-
- /* External orientation data handle */
- ivas_external_orientation_close_fx( &st_ivas->hExtOrientationData );
-
- /* Combined orientation data handle */
- ivas_combined_orientation_close_fx( &st_ivas->hCombinedOrientationData );
-
- /* Time Domain binaural renderer handle */
- IF( st_ivas->hBinRendererTd != NULL )
- {
- ivas_td_binaural_close_fx( &st_ivas->hBinRendererTd );
- }
- ELSE IF( st_ivas->hHrtfTD != NULL )
- {
- BSplineModelEvalDealloc_fx( &st_ivas->hHrtfTD->ModelParams, &st_ivas->hHrtfTD->ModelEval );
- ivas_HRTF_binary_close_fx( &st_ivas->hHrtfTD );
- }
-
- /* CRend binaural renderer handle */
- ivas_HRTF_CRend_binary_close_fx( &st_ivas->hSetOfHRTF );
-
- /* Fastconv HRTF memories */
- ivas_binaural_hrtf_close( &st_ivas->hHrtfFastConv );
-
- /* Fastconv HRTF filters */
- ivas_HRTF_fastconv_binary_close_fx( &st_ivas->hHrtfFastConv );
-
- /* Parametric binauralizer HRTF filters */
- ivas_HRTF_parambin_binary_close_fx( &st_ivas->hHrtfParambin );
-
- /* Config. Renderer */
- ivas_render_config_close( &( st_ivas->hRenderConfig ) );
-
- /* Limiter struct */
- ivas_limiter_close_fx( &( st_ivas->hLimiter ) );
-
- IF( st_ivas->hDecoderConfig != NULL )
- {
- free( st_ivas->hDecoderConfig );
- st_ivas->hDecoderConfig = NULL;
- }
-
- ivas_jbm_dec_tc_buffer_close( &st_ivas->hTcBuffer );
-
- IF( st_ivas->hJbmMetadata != NULL )
- {
- free( st_ivas->hJbmMetadata );
- st_ivas->hJbmMetadata = NULL;
- }
-
- /* floating-point output audio buffers */
- FOR( i = 0; i < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; i++ )
- {
-
- IF( st_ivas->p_output_fx[i] != NULL )
- {
- free( st_ivas->p_output_fx[i] );
- st_ivas->p_output_fx[i] = NULL;
- }
- }
-
- /* main IVAS handle */
- free( st_ivas );
-
- return;
-}
-
-
-/*-------------------------------------------------------------------*
- * ivas_init_dec_get_num_cldfb_instances()
- *
- * Return number of CLDFB analysis & synthesis instances
- *-------------------------------------------------------------------*/
-
-/*! r: number of cldfb instances */
-void ivas_init_dec_get_num_cldfb_instances(
- Decoder_Struct *st_ivas, /* i : IVAS decoder structure */
- Word16 *numCldfbAnalyses, /* o : number of needed CLDFB analysis instances */
- Word16 *numCldfbSyntheses /* o : number of needed CLDFB synthesis instances */
-)
-{
- IVAS_FORMAT ivas_format;
- *numCldfbAnalyses = st_ivas->nchan_transport;
- move16();
- *numCldfbSyntheses = st_ivas->hDecoderConfig->nchan_out;
- move16();
-
- test();
- IF( ( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_MODE_NONE ) ) )
- {
- ivas_format = SBA_FORMAT;
- move32();
- }
- ELSE
- {
- ivas_format = st_ivas->ivas_format;
- move32();
- }
-
- SWITCH( st_ivas->renderer_type )
- {
- case RENDERER_BINAURAL_PARAMETRIC:
- case RENDERER_BINAURAL_PARAMETRIC_ROOM:
- case RENDERER_STEREO_PARAMETRIC:
- IF( EQ_16( st_ivas->nchan_transport, 1 ) )
- {
- *numCldfbAnalyses = add( st_ivas->nchan_transport, 1 );
- move16();
- }
-
- test();
- IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) && st_ivas->hOutSetup.separateChannelEnabled )
- {
- *numCldfbAnalyses = add( st_ivas->nchan_transport, 1 );
- move16();
- }
-
- IF( EQ_32( ivas_format, SBA_ISM_FORMAT ) )
- {
- IF( EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
- {
- *numCldfbAnalyses = add( *numCldfbAnalyses, st_ivas->nchan_ism );
- move16();
- }
- }
-
- IF( EQ_32( ivas_format, MASA_ISM_FORMAT ) )
- {
- test();
- IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
- {
- *numCldfbAnalyses = add( *numCldfbAnalyses, st_ivas->nchan_ism );
- move16();
- }
- ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
- {
- *numCldfbAnalyses = add( st_ivas->nchan_transport, 1 );
- move16();
- }
- }
- IF( st_ivas->hDiracDecBin->useTdDecorr )
- {
- *numCldfbAnalyses = add( *numCldfbAnalyses, 2 );
- move16();
- }
- BREAK;
- case RENDERER_NON_DIEGETIC_DOWNMIX:
- case RENDERER_MONO_DOWNMIX:
- test();
- test();
- IF( EQ_32( ivas_format, ISM_FORMAT ) || EQ_32( ivas_format, MASA_ISM_FORMAT ) || EQ_32( ivas_format, SBA_ISM_FORMAT ) )
- {
- /* CLDFB not used in rendering */
- *numCldfbAnalyses = 0;
- move16();
- *numCldfbSyntheses = 0;
- move16();
- }
- BREAK;
- case RENDERER_DIRAC:
- IF( EQ_32( ivas_format, SBA_FORMAT ) )
- {
- *numCldfbAnalyses = st_ivas->hSpar->hFbMixer->fb_cfg->num_in_chans;
- move16();
-
- test();
- IF( st_ivas->hOutSetup.is_loudspeaker_setup && EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) )
- {
- *numCldfbSyntheses = st_ivas->hOutSetup.nchan_out_woLFE;
- move16();
- }
- ELSE IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_FOA ) )
- {
- *numCldfbSyntheses = st_ivas->hSpar->hFbMixer->fb_cfg->num_out_chans;
- move16();
- }
- ELSE
- {
- *numCldfbSyntheses = MAX_OUTPUT_CHANNELS;
- move16();
- }
- }
- IF( NE_32( ivas_format, SBA_FORMAT ) )
- {
- test();
- test();
- IF( GT_16( st_ivas->nchan_transport, 2 ) && ( st_ivas->sba_planar != 0 ) )
- {
- *numCldfbAnalyses = add( st_ivas->nchan_transport, 1 );
- move16();
- }
- ELSE IF( EQ_16( st_ivas->nchan_transport, 1 ) && EQ_32( st_ivas->hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
- {
- *numCldfbAnalyses = add( st_ivas->nchan_transport, 1 );
- move16();
- }
- }
- BREAK;
- case RENDERER_MC_PARAMMC:
- IF( LE_16( st_ivas->hDecoderConfig->nchan_out, 2 ) )
- {
- /* CLDFB not used in rendering */
- *numCldfbAnalyses = 0;
- move16();
- *numCldfbSyntheses = 0;
- move16();
- }
- ELSE
- {
- *numCldfbSyntheses = param_mc_get_num_cldfb_syntheses_fx( st_ivas );
- move16();
- }
- BREAK;
- case RENDERER_PARAM_ISM:
- /* Already correct with no exception */
- BREAK;
- case RENDERER_DISABLE:
- /* CLDFB not used */
- *numCldfbAnalyses = 0;
- move16();
- *numCldfbSyntheses = 0;
- move16();
- BREAK;
- case RENDERER_MC:
- case RENDERER_SBA_LINEAR_DEC:
- case RENDERER_TD_PANNING:
- case RENDERER_BINAURAL_OBJECTS_TD:
- case RENDERER_MCMASA_MONO_STEREO:
- case RENDERER_BINAURAL_MIXER_CONV:
- case RENDERER_BINAURAL_MIXER_CONV_ROOM:
- case RENDERER_BINAURAL_FASTCONV:
- case RENDERER_BINAURAL_FASTCONV_ROOM:
- case RENDERER_OSBA_STEREO:
- case RENDERER_OSBA_AMBI:
- case RENDERER_OSBA_LS:
- test();
- IF( EQ_32( ivas_format, SBA_FORMAT ) || EQ_32( ivas_format, SBA_ISM_FORMAT ) )
- {
- IF( st_ivas->sba_dirac_stereo_flag != 0 )
- {
- *numCldfbAnalyses = 0;
- move16();
- *numCldfbSyntheses = 0;
- move16();
- }
- ELSE
- {
- *numCldfbAnalyses = st_ivas->hSpar->hFbMixer->fb_cfg->num_in_chans;
- move16();
-
- test();
- IF( st_ivas->hOutSetup.is_loudspeaker_setup && EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) )
- {
- *numCldfbSyntheses = st_ivas->hOutSetup.nchan_out_woLFE;
- move16();
- }
- ELSE IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_FOA ) )
- {
- *numCldfbSyntheses = st_ivas->hSpar->hFbMixer->fb_cfg->num_out_chans;
- move16();
- }
- ELSE
- {
- *numCldfbSyntheses = MAX_OUTPUT_CHANNELS;
- move16();
- }
- test();
- IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
- {
- *numCldfbAnalyses = add( st_ivas->nchan_ism, st_ivas->hSpar->hFbMixer->fb_cfg->num_in_chans );
- move16();
- }
- }
- }
- ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) )
- {
- /* do nothing for ParamMC */
- }
- ELSE
- {
- /* CLDFB not used in rendering */
- *numCldfbAnalyses = 0;
- move16();
- *numCldfbSyntheses = 0;
- move16();
- }
- BREAK;
- case RENDERER_SBA_LINEAR_ENC:
- IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) )
- {
- *numCldfbSyntheses = param_mc_get_num_cldfb_syntheses_fx( st_ivas );
- move16();
- }
- ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) )
- {
- *numCldfbSyntheses = add( st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hIntSetup.num_lfe );
- move16();
- }
- ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) )
- {
- *numCldfbAnalyses = st_ivas->nchan_transport;
- move16();
- *numCldfbSyntheses = add( st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hIntSetup.num_lfe );
- move16();
- }
- ELSE
- {
- /* CLDFB not used in rendering */
- *numCldfbAnalyses = 0;
- move16();
- *numCldfbSyntheses = 0;
- move16();
- }
- BREAK;
- default:
- assert( 0 && "Renderer not handled for CLDFB reservation." );
- }
- test();
- test();
- IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) && NE_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_MONO ) && NE_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) )
- {
- test();
- test();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) || EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) )
- {
- *numCldfbAnalyses = s_max( MC_PARAMUPMIX_MAX_INPUT_CHANS, *numCldfbAnalyses );
- move16();
- }
- ELSE
- {
- *numCldfbAnalyses = s_max( MC_PARAMUPMIX_MIN_CLDFB, *numCldfbAnalyses );
- move16();
- }
- *numCldfbSyntheses = s_max( MC_PARAMUPMIX_MIN_CLDFB, *numCldfbSyntheses );
- move16();
- }
-
- return;
-}
-
-
-/*---------------------------------------------------------------------*
- * doSanityChecks_IVAS()
- *
- * Sanity checks - verify if the decoder set-up parameters are
- * not in conflict with the IVAS format
- *---------------------------------------------------------------------*/
-
-static ivas_error doSanityChecks_IVAS(
- Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
-)
-{
- Word32 output_Fs;
- AUDIO_CONFIG output_config;
-
- output_Fs = st_ivas->hDecoderConfig->output_Fs;
- move32();
- output_config = st_ivas->hDecoderConfig->output_config;
- move32();
- /*-----------------------------------------------------------------*
- * Sanity checks
- *-----------------------------------------------------------------*/
-
- IF( EQ_32( output_Fs, 8000 ) )
- {
- return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "8kHz output sampling rate is not supported in IVAS." );
- }
-
- assert( st_ivas->ivas_format != UNDEFINED_FORMAT && "\n IVAS format undefined" );
- assert( st_ivas->ivas_format != MONO_FORMAT && "\n Wrong IVAS format: MONO" );
-
- /* Verify output configuration compatible with non-diegetic panning */
- test();
- test();
- IF( st_ivas->hDecoderConfig->Opt_non_diegetic_pan && NE_32( st_ivas->ivas_format, MONO_FORMAT ) && NE_32( st_ivas->transport_config, IVAS_AUDIO_CONFIG_ISM1 ) )
- {
- return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Error: Non-diegetic panning not supported in this IVAS format" );
- }
-
- /* Verify stereo output configuration */
- IF( EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) )
- {
- test();
- test();
- test();
- test();
- test();
- test();
- test();
- IF( NE_32( output_config, IVAS_AUDIO_CONFIG_MONO ) && NE_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) && NE_32( output_config, IVAS_AUDIO_CONFIG_5_1 ) && NE_32( output_config, IVAS_AUDIO_CONFIG_7_1 ) && NE_32( output_config, IVAS_AUDIO_CONFIG_5_1_2 ) && NE_32( output_config, IVAS_AUDIO_CONFIG_5_1_4 ) && NE_32( output_config, IVAS_AUDIO_CONFIG_7_1_4 ) && NE_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
- {
- return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Wrong output configuration specified for Stereo!" );
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) )
- {
- /* Verify ISM output configuration */
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_INVALID ) )
- {
- return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified for ISM" );
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) )
- {
- /* Verify SBA output coniguration */
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_INVALID ) )
- {
- return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified for SBA" );
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) )
- {
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_INVALID ) )
- {
- return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified for MASA!" );
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) )
- {
- /* Verify MC output configuration */
- test();
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_INVALID ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
- {
- return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified for Multi-channel" );
- }
- }
-
-
- IF( st_ivas->hDecoderConfig->Opt_Headrotation )
- {
- test();
- test();
- IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) )
- {
- return IVAS_ERROR( IVAS_ERR_HEAD_ROTATION_NOT_SUPPORTED, "Wrong set-up: Head-rotation not supported in this configuration" );
- }
- }
-
- IF( st_ivas->hDecoderConfig->Opt_ExternalOrientation )
- {
- test();
- test();
- IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) )
- {
- return IVAS_ERROR( IVAS_ERR_EXT_ORIENTATION_NOT_SUPPORTED, "Wrong set-up: External orientation not supported in this configuration" );
- }
- }
-
- IF( st_ivas->hDecoderConfig->Opt_dpid_on )
- {
- test();
- IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) )
- {
- return IVAS_ERROR( IVAS_ERR_DIRECTIVITY_NOT_SUPPORTED, "Wrong set-up: Directivity is not supported in this output configuration." );
- }
- }
-
- IF( st_ivas->hDecoderConfig->Opt_aeid_on )
- {
- IF( NE_16( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
- {
- return IVAS_ERROR( IVAS_ERR_ACOUSTIC_ENVIRONMENT_NOT_SUPPORTED, "Wrong set-up: Acoustic environment is not supported in this output configuration." );
- }
- }
-
- IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
- {
- test();
- IF( NE_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
- {
-
- return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified for combined MASA and ISM format" );
- }
- }
-
-
- return IVAS_ERR_OK;
-}
diff --git a/lib_dec/ivas_init_dec_fx.c b/lib_dec/ivas_init_dec_fx.c
index ecd38aabe5cf2884d5365bd9aa09da56f1671310..463bc22fc5b242666573f76b1f26a46c9e79db62 100644
--- a/lib_dec/ivas_init_dec_fx.c
+++ b/lib_dec/ivas_init_dec_fx.c
@@ -1,4 +1,3120 @@
+/******************************************************************************************************
+
+ (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.
+
+*******************************************************************************************************/
+
+#include
+#include
+#include
+#include "options.h"
+#include "ivas_cnst.h"
+#include "ivas_prot_rend_fx.h"
+#include "rom_com.h"
+#include "ivas_rom_com.h"
+#include "ivas_stat_enc.h"
+#include "prot_fx.h"
+#include "wmc_auto.h"
#include "ivas_prot_fx.h"
+
+
+/*-------------------------------------------------------------------*
+ * Local function prototypes
+ *-------------------------------------------------------------------*/
+
+static ivas_error ivas_read_format( Decoder_Struct *st_ivas, Word16 *num_bits_read );
+
+static ivas_error doSanityChecks_IVAS( Decoder_Struct *st_ivas );
+
+
+/*-------------------------------------------------------------------*
+ * ivas_dec_setup()
+ *
+ * IVAS decoder setup
+ *-------------------------------------------------------------------*/
+
+ivas_error ivas_dec_setup(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ UWord16 *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */
+ Word16 *data /* o : output synthesis signal */
+)
+{
+ Word16 k, idx, num_bits_read;
+ Word16 nchan_ism, element_mode_flag;
+ Decoder_State *st;
+ Word32 ivas_total_brate;
+ ivas_error error;
+
+ error = IVAS_ERR_OK;
+ move32();
+ num_bits_read = 0;
+ move16();
+ element_mode_flag = 0;
+ move16();
+
+ ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
+ move32();
+
+ /*-------------------------------------------------------------------*
+ * Read IVAS format
+ *-------------------------------------------------------------------*/
+
+ ivas_read_format( st_ivas, &num_bits_read );
+
+ Word16 SrcInd[MAX_NUM_TDREND_CHANNELS];
+ Word16 num_src = 0;
+ move16();
+
+ /*-------------------------------------------------------------------*
+ * Read other signling (ISM/MC mode, number of channels, etc.)
+ *-------------------------------------------------------------------*/
+
+ IF( is_DTXrate( ivas_total_brate ) == 0 )
+ {
+ /*-------------------------------------------------------------------*
+ * Read IVAS format related signaling:
+ * - in ISM : read number of objects
+ * - in SBA : read SBA planar flag and SBA order
+ * - in MASA : read number of TC
+ * - in MC : read LS setup
+ *-------------------------------------------------------------------*/
+
+ IF( EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) )
+ {
+ element_mode_flag = 1;
+ move16();
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) )
+ {
+ /* read the number of objects */
+ st_ivas->nchan_transport = 1;
+ move16();
+ nchan_ism = 1;
+ move16();
+ Word32 res_dec, res_frac;
+ iDiv_and_mod_32( ivas_total_brate, FRAMES_PER_SEC, &res_dec, &res_frac, 0 );
+ k = extract_l( L_sub( res_dec, 1 ) );
+
+ WHILE( st_ivas->bit_stream[k] && ( nchan_ism < MAX_NUM_OBJECTS ) )
+ {
+ nchan_ism = add( nchan_ism, 1 );
+ k = sub( k, 1 );
+ }
+
+ st_ivas->nchan_ism = nchan_ism;
+ move16();
+
+ IF( NE_32( ( error = ivas_ism_dec_config_fx( st_ivas, st_ivas->ism_mode, nSamplesRendered, data ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) )
+ {
+ /* read Ambisonic (SBA) planar flag */
+ st_ivas->sba_planar = st_ivas->bit_stream[num_bits_read];
+ move16();
+ num_bits_read = add( num_bits_read, SBA_PLANAR_BITS );
+
+ /* read Ambisonic (SBA) order */
+ st_ivas->sba_order = st_ivas->bit_stream[num_bits_read + 1];
+ move16();
+ st_ivas->sba_order = add( st_ivas->sba_order, shl( st_ivas->bit_stream[num_bits_read], 1 ) );
+ move16();
+ num_bits_read = add( num_bits_read, SBA_ORDER_BITS );
+ test();
+ test();
+ IF( st_ivas->ini_frame > 0 && NE_32( ivas_total_brate, st_ivas->last_active_ivas_total_brate ) && GT_32( ivas_total_brate, IVAS_SID_5k2 ) )
+ {
+ IF( NE_32( ( error = ivas_sba_dec_reconfigure_fx( st_ivas, nSamplesRendered, data ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ ELSE
+ {
+ /* set Ambisonic (SBA) order used for analysis and coding */
+ st_ivas->sba_analysis_order = ivas_sba_get_analysis_order_fx( ivas_total_brate, st_ivas->sba_order );
+ move16();
+ ivas_sba_config_fx( ivas_total_brate, st_ivas->sba_analysis_order, -1, &( st_ivas->nchan_transport ), st_ivas->sba_planar, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init );
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) )
+ {
+ /* read number of MASA transport channels */
+ Word32 res_dec, res_frac;
+ iDiv_and_mod_32( ivas_total_brate, FRAMES_PER_SEC, &res_dec, &res_frac, 0 );
+ IF( st_ivas->bit_stream[res_dec - 1] )
+ {
+ st_ivas->nchan_transport = 2;
+ move16();
+ element_mode_flag = 1;
+ move16();
+ }
+ ELSE
+ {
+ st_ivas->nchan_transport = 1;
+ move16();
+ }
+
+ IF( st_ivas->ini_frame > 0 )
+ {
+ /* reconfigure in case a change of operation mode is detected */
+ test();
+ test();
+ IF( ( GT_32( ivas_total_brate, IVAS_SID_5k2 ) && NE_32( ivas_total_brate, st_ivas->hDecoderConfig->last_ivas_total_brate ) ) || ( st_ivas->ini_active_frame == 0 ) )
+ {
+ IF( EQ_32( st_ivas->last_ivas_format, MASA_FORMAT ) )
+ {
+ test();
+ test();
+ test();
+ IF( ( st_ivas->ini_active_frame == 0 ) && NE_32( ivas_total_brate, FRAME_NO_DATA ) && LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) && EQ_16( st_ivas->nCPE, 1 ) )
+ {
+ st_ivas->hCPE[0]->nchan_out = 1;
+ move16();
+ }
+ ELSE
+ {
+ IF( NE_32( ( error = ivas_masa_dec_reconfigure_fx( st_ivas, nSamplesRendered, data ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ }
+ ELSE
+ {
+ IF( NE_32( ( error = ivas_omasa_dec_config_fx( st_ivas, nSamplesRendered, &num_src, SrcInd, data ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ }
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
+ {
+ st_ivas->nchan_transport = 2; /* always 2 MASA transport channels */
+ move16();
+ /* for the DISC mode the number of objects are written at the end of the bitstream, in the MASA metadata */
+
+ Word32 res_dec, res_frac;
+ iDiv_and_mod_32( ivas_total_brate, FRAMES_PER_SEC, &res_dec, &res_frac, 0 );
+ st_ivas->nchan_ism = add( add( shl( st_ivas->bit_stream[res_dec - 1], 1 ), st_ivas->bit_stream[res_dec - 2] ), 1 );
+ move16();
+ st_ivas->ism_mode = ivas_omasa_ism_mode_select_fx( ivas_total_brate, st_ivas->nchan_ism );
+ move16();
+ IF( st_ivas->ini_frame > 0 )
+ {
+ /* reconfigure in case a change of operation mode is detected */
+ test();
+ test();
+ IF( ( GT_32( ivas_total_brate, IVAS_SID_5k2 ) && NE_32( ivas_total_brate, st_ivas->hDecoderConfig->last_ivas_total_brate ) ) || ( st_ivas->ini_active_frame == 0 ) )
+ {
+ IF( NE_32( ( error = ivas_omasa_dec_config_fx( st_ivas, nSamplesRendered, &num_src, SrcInd, data ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
+ {
+ /* the number of objects is written at the end of the bitstream, in the SBA metadata */
+ Word32 res_dec, res_frac;
+ iDiv_and_mod_32( ivas_total_brate, FRAMES_PER_SEC, &res_dec, &res_frac, 0 );
+ st_ivas->nchan_ism = add( add( shl( st_ivas->bit_stream[res_dec - 1], 1 ), st_ivas->bit_stream[res_dec - 2] ), 1 );
+ move16();
+
+ test();
+ IF( LT_32( ivas_total_brate, IVAS_24k4 ) || GE_32( ivas_total_brate, IVAS_256k ) )
+ {
+ /* read Ambisonic (SBA) planar flag */
+ st_ivas->sba_planar = st_ivas->bit_stream[num_bits_read];
+ move16();
+ num_bits_read = add( num_bits_read, SBA_PLANAR_BITS );
+ }
+
+ st_ivas->sba_order = st_ivas->bit_stream[num_bits_read + 1];
+ move16();
+ st_ivas->sba_order = add( st_ivas->sba_order, shl( st_ivas->bit_stream[num_bits_read], 1 ) );
+ move16();
+ num_bits_read = add( num_bits_read, SBA_ORDER_BITS );
+
+ /* read Ambisonic (SBA) order */
+ if ( LT_32( ivas_total_brate, IVAS_256k ) )
+ {
+ st_ivas->sba_order = 3;
+ move16();
+ }
+
+ test();
+ IF( st_ivas->ini_frame > 0 && NE_32( ivas_total_brate, st_ivas->last_active_ivas_total_brate ) )
+ {
+ IF( NE_32( ( error = ivas_sba_dec_reconfigure_fx( st_ivas, nSamplesRendered, data ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ ELSE
+ {
+ /* set Ambisonic (SBA) order used for analysis and coding */
+ st_ivas->sba_analysis_order = ivas_sba_get_analysis_order_fx( ivas_total_brate, st_ivas->sba_order );
+ move16();
+
+ ivas_sba_config_fx( ivas_total_brate, st_ivas->sba_analysis_order, -1, &( st_ivas->nchan_transport ), st_ivas->sba_planar, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init );
+
+ /*correct number of CPEs for discrete ISM coding*/
+ test();
+ IF( st_ivas->ini_frame > 0 && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
+ {
+ st_ivas->nCPE = add( st_ivas->nCPE, shr( add( st_ivas->nchan_ism, 1 ), 1 ) );
+ move16();
+ }
+ }
+
+ IF( GE_32( ivas_total_brate, IVAS_256k ) )
+ {
+ st_ivas->ism_mode = ISM_SBA_MODE_DISC;
+ move32();
+ }
+ ELSE
+ {
+ st_ivas->ism_mode = ISM_MODE_NONE;
+ move32();
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) )
+ {
+ /* read MC configuration */
+ idx = 0;
+ move16();
+ FOR( k = 0; k < MC_LS_SETUP_BITS; k++ )
+ {
+ IF( st_ivas->bit_stream[num_bits_read + k] )
+ {
+ idx = add( idx, shl( 1, sub( ( MC_LS_SETUP_BITS - 1 ), k ) ) );
+ }
+ }
+ num_bits_read = add( num_bits_read, MC_LS_SETUP_BITS );
+
+ /* select MC format mode; reconfigure the MC format decoder */
+ IF( NE_32( ( error = ivas_mc_dec_config_fx( st_ivas, idx, nSamplesRendered, data ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ /*-------------------------------------------------------------------*
+ * Read element mode
+ *-------------------------------------------------------------------*/
+
+ IF( st_ivas->ini_frame == 0 && element_mode_flag )
+ {
+ /* read stereo technology info */
+ IF( LT_32( ivas_total_brate, MIN_BRATE_MDCT_STEREO ) )
+ {
+ /* 1 bit */
+ IF( st_ivas->bit_stream[num_bits_read] )
+ {
+ st_ivas->element_mode_init = add( 1, IVAS_CPE_DFT );
+ move16();
+ }
+ ELSE
+ {
+ st_ivas->element_mode_init = add( 0, IVAS_CPE_DFT );
+ move16();
+ }
+ }
+ ELSE
+ {
+ st_ivas->element_mode_init = IVAS_CPE_MDCT;
+ move16();
+ }
+ }
+ }
+ ELSE IF( EQ_32( ivas_total_brate, IVAS_SID_5k2 ) )
+ {
+ SWITCH( st_ivas->sid_format )
+ {
+ case SID_DFT_STEREO:
+ st_ivas->element_mode_init = IVAS_CPE_DFT;
+ move16();
+ BREAK;
+ case SID_MDCT_STEREO:
+ st_ivas->element_mode_init = IVAS_CPE_MDCT;
+ move16();
+ BREAK;
+ case SID_ISM:
+ st_ivas->element_mode_init = IVAS_SCE;
+ move16();
+ BREAK;
+ case SID_MASA_1TC:
+ st_ivas->element_mode_init = IVAS_SCE;
+ move16();
+ st_ivas->nchan_transport = 1;
+ move16();
+ BREAK;
+ case SID_MASA_2TC:; // empyt statement for declaration
+ Word32 res_dec, res_frac;
+ iDiv_and_mod_32( ivas_total_brate, FRAMES_PER_SEC, &res_dec, &res_frac, 0 );
+ IF( EQ_16( st_ivas->bit_stream[( res_dec - 1 ) - SID_FORMAT_NBITS], 1 ) )
+ {
+ st_ivas->element_mode_init = IVAS_CPE_MDCT;
+ move16();
+ }
+ ELSE
+ {
+ st_ivas->element_mode_init = IVAS_CPE_DFT;
+ move16();
+ }
+ st_ivas->nchan_transport = 2;
+ move16();
+ BREAK;
+ case SID_SBA_1TC:
+ st_ivas->element_mode_init = IVAS_SCE;
+ move16();
+ BREAK;
+ case SID_SBA_2TC:
+ st_ivas->element_mode_init = IVAS_CPE_MDCT;
+ move16();
+ BREAK;
+ }
+
+ test();
+ IF( st_ivas->ini_frame > 0 && EQ_32( st_ivas->ivas_format, SBA_FORMAT ) )
+ {
+ Word16 nchan_transport_old, nchan_transport;
+ nchan_transport_old = st_ivas->nchan_transport;
+ move16();
+ IF( ( EQ_16( st_ivas->sid_format, SID_SBA_2TC ) ) )
+ {
+ nchan_transport = 2;
+ }
+ ELSE
+ {
+ nchan_transport = 1;
+ }
+ move16();
+
+ IF( NE_16( nchan_transport_old, nchan_transport ) )
+ {
+ /*Setting the default bitrate for the reconfig function*/
+ IF( EQ_16( st_ivas->sid_format, SID_SBA_2TC ) )
+ {
+ st_ivas->hDecoderConfig->ivas_total_brate = IVAS_48k;
+ move16();
+ }
+ ELSE
+ {
+ st_ivas->hDecoderConfig->ivas_total_brate = IVAS_24k4;
+ move16();
+ }
+
+ IF( NE_32( ( error = ivas_sba_dec_reconfigure_fx( st_ivas, nSamplesRendered, data ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ st_ivas->last_active_ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
+ move32();
+ st_ivas->hDecoderConfig->ivas_total_brate = ivas_total_brate;
+ move32();
+ }
+ }
+
+ IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) )
+ {
+ ISM_MODE last_ism_mode = st_ivas->ism_mode;
+ move32();
+ /* read the number of objects */
+ st_ivas->nchan_transport = 1;
+ move16();
+ nchan_ism = 1;
+ move16();
+ Word32 res_dec, res_frac;
+ iDiv_and_mod_32( ivas_total_brate, FRAMES_PER_SEC, &res_dec, &res_frac, 0 );
+ k = extract_l( L_sub( L_sub( res_dec, 1 ), SID_FORMAT_NBITS ) );
+ move16();
+
+ WHILE( st_ivas->bit_stream[k] && ( nchan_ism < MAX_NUM_OBJECTS ) )
+ {
+ nchan_ism = add( nchan_ism, 1 );
+ k = sub( k, 1 );
+ }
+ k = sub( k, 1 );
+
+ test();
+ IF( st_ivas->ini_frame > 0 && NE_16( nchan_ism, st_ivas->nchan_ism ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "wrong number of objects signalled!" );
+ }
+
+ st_ivas->nchan_ism = nchan_ism;
+ move16();
+ /* read ism_mode */
+ st_ivas->ism_mode = ISM_MODE_DISC;
+ move32();
+ IF( GT_16( nchan_ism, 2 ) )
+ {
+ k = sub( k, nchan_ism ); /* SID metadata flags */
+ idx = st_ivas->bit_stream[k];
+ move16();
+ st_ivas->ism_mode = (ISM_MODE) add( idx, 1 );
+ move32();
+ }
+
+ if ( st_ivas->ini_frame == 0 )
+ {
+ last_ism_mode = st_ivas->ism_mode;
+ move32();
+ }
+
+ IF( NE_32( ( error = ivas_ism_dec_config_fx( st_ivas, last_ism_mode, nSamplesRendered, data ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ }
+
+ /*-------------------------------------------------------------------*
+ * Initialize decoder in the first good frame based on IVAS format
+ * and number of transport channels
+ *-------------------------------------------------------------------*/
+ test();
+ IF( st_ivas->ini_frame == 0 && NE_32( st_ivas->ivas_format, UNDEFINED_FORMAT ) )
+ {
+ IF( NE_32( ( error = doSanityChecks_IVAS( st_ivas ) ), IVAS_ERR_OK ) )
+ {
+ return IVAS_ERROR( error, "Sanity checks failed" );
+ }
+
+ IF( NE_32( ( error = ivas_init_decoder_fx( st_ivas ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+
+ /*----------------------------------------------------------------*
+ * Reset bitstream pointers
+ *----------------------------------------------------------------*/
+
+ ivas_set_bitstream_pointers( st_ivas );
+
+ reset_elements( st_ivas );
+
+ /* update bitstream buffer pointer -> take into account already read bits */
+ test();
+ IF( ( st_ivas->nSCE > 0 ) || ( st_ivas->nCPE > 0 ) )
+ {
+ IF( st_ivas->nSCE > 0 )
+ {
+ st = st_ivas->hSCE[0]->hCoreCoder[0];
+ }
+ ELSE
+ {
+ st = st_ivas->hCPE[0]->hCoreCoder[0];
+ }
+ st->next_bit_pos = num_bits_read;
+ move16();
+ st->total_brate = ACELP_8k00; /* only temporary initialization - this is needed for get_next_indice() in the frame following NO_DATA frame */
+ move32();
+ }
+
+ return error;
+}
+
+
+/*-------------------------------------------------------------------*
+ * ivas_read_format()
+ *
+ * Read IVAS format signaling
+ *-------------------------------------------------------------------*/
+
+static ivas_error ivas_read_format(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ Word16 *num_bits_read /* o : number of IVAS signaling bits read from the bitstream */
+)
+{
+ Word16 k, idx;
+ Word32 ivas_total_brate;
+ ivas_error error;
+
+ error = IVAS_ERR_OK;
+ move32();
+
+ ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
+ move32();
+
+ *num_bits_read = 0;
+ move16();
+ test();
+ test();
+ IF( !st_ivas->bfi && is_DTXrate( ivas_total_brate ) == 0 )
+ {
+ /* read IVAS format */
+ k = 0;
+ move16();
+ if ( st_ivas->bit_stream[*num_bits_read] )
+ {
+ k = 1;
+ move16();
+ }
+ k = shl( k, 1 );
+ ( *num_bits_read ) = add( ( *num_bits_read ), 1 );
+ move16();
+ if ( st_ivas->bit_stream[*num_bits_read] )
+ {
+ k = add( k, 1 );
+ }
+ ( *num_bits_read ) = add( ( *num_bits_read ), 1 );
+ move16();
+ SWITCH( k )
+ {
+ case 0:
+ st_ivas->ivas_format = STEREO_FORMAT;
+ move32();
+ BREAK;
+ case 1:
+ st_ivas->ivas_format = MC_FORMAT;
+ move32();
+ BREAK;
+ case 2:
+ st_ivas->ivas_format = ISM_FORMAT;
+ move32();
+
+ IF( GE_32( ivas_total_brate, IVAS_24k4 ) )
+ {
+ IF( st_ivas->bit_stream[*num_bits_read] )
+ {
+ ( *num_bits_read ) = add( ( *num_bits_read ), 1 );
+ move16();
+ IF( st_ivas->bit_stream[*num_bits_read] )
+ {
+ st_ivas->ivas_format = SBA_ISM_FORMAT;
+ move32();
+ }
+ ELSE
+ {
+ st_ivas->ivas_format = MASA_ISM_FORMAT;
+ move32();
+ }
+ }
+
+ ( *num_bits_read ) = add( ( *num_bits_read ), 1 );
+ move16();
+ }
+ BREAK;
+ case 3:
+ IF( st_ivas->bit_stream[*num_bits_read] )
+ {
+ st_ivas->ivas_format = MASA_FORMAT;
+ move32();
+ }
+ ELSE
+ {
+ st_ivas->ivas_format = SBA_FORMAT;
+ move32();
+ /* read Ambisonic (SBA) planar flag */
+ st_ivas->sba_planar = st_ivas->bit_stream[( *num_bits_read ) + 1];
+ move16();
+
+ /* read Ambisonic (SBA) order */
+ st_ivas->sba_order = st_ivas->bit_stream[( *num_bits_read ) + 2 + SBA_PLANAR_BITS];
+ move16();
+ st_ivas->sba_order = add( st_ivas->sba_order, shl( st_ivas->bit_stream[( *num_bits_read ) + 1 + SBA_PLANAR_BITS], 1 ) );
+ move16();
+ if ( st_ivas->sba_order == 0 )
+ {
+ st_ivas->ivas_format = SBA_ISM_FORMAT;
+ move32();
+ }
+ }
+ ( *num_bits_read ) = add( ( *num_bits_read ), 1 );
+ move16();
+
+ BREAK;
+ }
+ }
+ ELSE IF( ( st_ivas->bfi == 0 ) && EQ_32( ivas_total_brate, IVAS_SID_5k2 ) )
+ {
+ /* read IVAS format in SID frame */
+ idx = 0;
+ move16();
+ FOR( k = 0; k < SID_FORMAT_NBITS; k++ )
+ {
+ idx += st_ivas->bit_stream[k] << ( SID_FORMAT_NBITS - 1 - k );
+ }
+
+ ( *num_bits_read ) = add( *num_bits_read, SID_FORMAT_NBITS );
+ move16();
+ st_ivas->sid_format = idx;
+ move16();
+
+ SWITCH( idx )
+ {
+ case SID_DFT_STEREO:
+ case SID_MDCT_STEREO:
+ st_ivas->ivas_format = STEREO_FORMAT;
+ move32();
+ BREAK;
+ case SID_ISM:
+ st_ivas->ivas_format = ISM_FORMAT;
+ move32();
+ BREAK;
+ case SID_MULTICHANNEL:
+ st_ivas->ivas_format = MC_FORMAT;
+ move32();
+ BREAK;
+ case SID_SBA_1TC:
+ st_ivas->ivas_format = SBA_FORMAT;
+ move32();
+ st_ivas->element_mode_init = IVAS_SCE;
+ move16();
+ BREAK;
+ case SID_SBA_2TC:
+ st_ivas->ivas_format = SBA_FORMAT;
+ move32();
+ st_ivas->element_mode_init = IVAS_CPE_MDCT;
+ move16();
+ BREAK;
+ case SID_MASA_1TC:
+ st_ivas->ivas_format = MASA_FORMAT;
+ move32();
+ st_ivas->element_mode_init = IVAS_SCE;
+ move16();
+ BREAK;
+ case SID_MASA_2TC:
+ st_ivas->ivas_format = MASA_FORMAT;
+ move32();
+ Word32 res_dec, res_frac;
+ iDiv_and_mod_32( ivas_total_brate, FRAMES_PER_SEC, &res_dec, &res_frac, 0 );
+ IF( EQ_32( st_ivas->bit_stream[res_dec - 1], 1 ) )
+ {
+ st_ivas->element_mode_init = IVAS_CPE_MDCT;
+ move16();
+ }
+ ELSE
+ {
+ st_ivas->element_mode_init = IVAS_CPE_DFT;
+ move16();
+ }
+ BREAK;
+ default:
+ /* This should actually be impossible, since only 3 bits are read, so if this happens something is broken */
+ return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Invalid value %c found in SID format field.", st_ivas->sid_format );
+ }
+
+ IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) )
+ {
+ if ( st_ivas->sba_analysis_order == 0 )
+ {
+ st_ivas->sba_analysis_order = SBA_FOA_ORDER;
+ move16();
+ }
+ }
+
+ /* reset bitstream handle to avoid BER detection after reading the 2400 kbps for ch0 */
+ st_ivas->bit_stream = st_ivas->bit_stream + ( *num_bits_read );
+ ( *num_bits_read ) = 0;
+ move16();
+ }
+ ELSE
+ {
+ /* In SID/NO_DATA frames, use the previous frame IVAS format */
+ }
+
+ return error;
+}
+
+
+/*-------------------------------------------------------------------*
+ * getNumChanSynthesis()
+ *
+ * get number of output channels used for synthesis/decoding
+ * (often different from number of output channels!)
+ *-------------------------------------------------------------------*/
+
+/*! r: number of channels to be synthesised */
+
+Word16 getNumChanSynthesis(
+ Decoder_Struct *st_ivas /* i : IVAS decoder structure */
+)
+{
+ Word16 n;
+
+ n = add( st_ivas->nSCE, imult1616( CPE_CHANNELS, st_ivas->nCPE ) );
+ test();
+ test();
+ IF( st_ivas->sba_dirac_stereo_flag )
+ {
+ n = CPE_CHANNELS;
+ move16();
+ }
+ ELSE IF( ( st_ivas->hMCT != NULL || EQ_32( st_ivas->ivas_format, SBA_FORMAT ) ) && NE_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
+ {
+ n = st_ivas->nchan_transport;
+ move16();
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
+ {
+ IF( EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
+ {
+ n = add( st_ivas->nchan_transport, st_ivas->nchan_ism );
+ }
+ ELSE
+ {
+ n = st_ivas->nchan_transport;
+ move16();
+ }
+ }
+
+ return n;
+}
+
+/*-------------------------------------------------------------------*
+ * copy_decoder_config()
+ *
+ * Copy IVAS configuration structure to the CoreCoder state structure
+ *-------------------------------------------------------------------*/
+
+void copy_decoder_config(
+ Decoder_Struct *st_ivas, /* i : IVAS decoder structure */
+ Decoder_State *st /* o : decoder state structure */
+)
+{
+ st->output_Fs = st_ivas->hDecoderConfig->output_Fs;
+ move32();
+ st->Opt_AMR_WB = st_ivas->hDecoderConfig->Opt_AMR_WB;
+ move16();
+ st->codec_mode = st_ivas->codec_mode;
+ move16();
+ st->ini_frame = st_ivas->ini_frame;
+ move16();
+
+ st->bfi = st_ivas->bfi;
+ move16();
+
+ st->writeFECoffset = st_ivas->writeFECoffset;
+ move16();
+
+ st->element_mode = st_ivas->element_mode_init;
+ move16();
+
+ return;
+}
+
+/*-------------------------------------------------------------------*
+ * ivas_init_decoder_front()
+ *
+ * Set decoder parameters to initial values
+ *-------------------------------------------------------------------*/
+ivas_error ivas_init_decoder_front(
+ Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
+)
+{
+ ivas_error error;
+
+ error = IVAS_ERR_OK;
+ move32();
+ /*-----------------------------------------------------------------*
+ * Resets
+ *-----------------------------------------------------------------*/
+
+ st_ivas->nSCE = 0;
+ move16();
+ st_ivas->nCPE = 0;
+ move16();
+ st_ivas->nCPE_old = 0;
+ move16();
+ st_ivas->nchan_transport = -1;
+ move16();
+ st_ivas->ism_mode = ISM_MODE_NONE;
+ move32();
+ st_ivas->mc_mode = MC_MODE_NONE;
+ move32();
+ st_ivas->sba_dirac_stereo_flag = 0;
+ move16();
+
+ /* HRTF binauralization latency in ns */
+ st_ivas->binaural_latency_ns = 0;
+ move32();
+
+ /*-------------------------------------------------------------------*
+ * Allocate and initialize Custom loudspeaker layout handle
+ *--------------------------------------------------------------------*/
+
+ IF( st_ivas->hDecoderConfig->Opt_LsCustom )
+ {
+ IF( EQ_32( ( error = ivas_ls_custom_open_fx( &( st_ivas->hLsSetupCustom ) ) ), IVAS_ERR_OK ) )
+ {
+ set_zero_fx( ( st_ivas->hLsSetupCustom )->ls_azimuth_fx, MAX_OUTPUT_CHANNELS );
+ set_zero_fx( ( st_ivas->hLsSetupCustom )->ls_elevation_fx, MAX_OUTPUT_CHANNELS );
+ }
+ ELSE
+ {
+ return error;
+ }
+ }
+
+ /*-------------------------------------------------------------------*
+ * Allocate and initialize Head-Tracking handle
+ *--------------------------------------------------------------------*/
+
+ IF( st_ivas->hDecoderConfig->Opt_Headrotation )
+ {
+ IF( NE_32( ( error = ivas_headTrack_open_fx( &( st_ivas->hHeadTrackData ) ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ error = ivas_orient_trk_SetTrackingType_fx( st_ivas->hHeadTrackData->OrientationTracker, st_ivas->hDecoderConfig->orientation_tracking );
+ IF( NE_32( ( error ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ /*-------------------------------------------------------------------*
+ * Allocate and initialize external orientation handle
+ *--------------------------------------------------------------------*/
+
+ IF( st_ivas->hDecoderConfig->Opt_ExternalOrientation )
+ {
+ IF( NE_32( ( error = ivas_external_orientation_open( &( st_ivas->hExtOrientationData ), st_ivas->hDecoderConfig->render_framesize ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ /*-------------------------------------------------------------------*
+ * Allocate and initialize combined orientation handle
+ *--------------------------------------------------------------------*/
+ test();
+ IF( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation )
+ {
+ IF( NE_32( ( error = ivas_combined_orientation_open( &( st_ivas->hCombinedOrientationData ), st_ivas->hDecoderConfig->output_Fs, st_ivas->hDecoderConfig->render_framesize ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ /*-------------------------------------------------------------------*
+ * Allocate HRTF binary handle
+ *--------------------------------------------------------------------*/
+
+ IF( st_ivas->hDecoderConfig->Opt_HRTF_binary )
+ {
+ IF( NE_32( ( error = ivas_HRTF_binary_open_fx( &( st_ivas->hHrtfTD ) ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ IF( NE_32( ( error = ivas_HRTF_CRend_binary_open_fx( &( st_ivas->hSetOfHRTF ) ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ IF( NE_32( ( error = ivas_HRTF_fastconv_binary_open_fx( &st_ivas->hHrtfFastConv ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ IF( NE_32( ( error = ivas_HRTF_parambin_binary_open_fx( &st_ivas->hHrtfParambin ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ /*-------------------------------------------------------------------*
+ * Allocate and initialize Binaural Renderer configuration handle
+ *--------------------------------------------------------------------*/
+ test();
+ test();
+ IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
+ {
+ IF( NE_32( ( error = ivas_render_config_open( &( st_ivas->hRenderConfig ) ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ IF( NE_32( ( error = ivas_render_config_init_from_rom_fx( &st_ivas->hRenderConfig ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ return error;
+}
+
+
+/*-------------------------------------------------------------------*
+ * ivas_init_decoder()
+ *
+ * Initialize IVAS decoder state structure
+ *-------------------------------------------------------------------*/
+ivas_error ivas_init_decoder_fx(
+ Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
+)
+{
+ Word16 i, n, k;
+ Word16 sce_id, cpe_id;
+ Word16 numCldfbAnalyses, numCldfbSyntheses;
+ Word16 granularity, n_channels_transport_jbm;
+ Word32 output_Fs, ivas_total_brate;
+ Word32 binauralization_delay_ns;
+ AUDIO_CONFIG output_config;
+ DECODER_CONFIG_HANDLE hDecoderConfig;
+ ivas_error error;
+ Word32 ism_total_brate;
+
+ error = IVAS_ERR_OK;
+ move32();
+ output_Fs = st_ivas->hDecoderConfig->output_Fs;
+ move32();
+ hDecoderConfig = st_ivas->hDecoderConfig;
+ output_config = hDecoderConfig->output_config;
+ ivas_total_brate = hDecoderConfig->ivas_total_brate;
+ move32();
+ hDecoderConfig->last_ivas_total_brate = ivas_total_brate;
+ move32();
+ st_ivas->last_active_ivas_total_brate = ivas_total_brate;
+ move32();
+ /*-----------------------------------------------------------------*
+ * Set number of output channels for EXTERNAL output config.
+ *-----------------------------------------------------------------*/
+
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
+ {
+ IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
+ {
+ hDecoderConfig->nchan_out = audioCfg2channels( IVAS_AUDIO_CONFIG_HOA3 );
+ move16();
+ hDecoderConfig->nchan_out = add( hDecoderConfig->nchan_out, st_ivas->nchan_ism );
+ move16();
+ }
+ ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
+ {
+ hDecoderConfig->nchan_out = add( st_ivas->nchan_transport, st_ivas->nchan_ism );
+ move16();
+ }
+ ELSE IF( !EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) )
+ {
+ hDecoderConfig->nchan_out = st_ivas->nchan_transport;
+ move16();
+ }
+
+ st_ivas->hOutSetup.nchan_out_woLFE = hDecoderConfig->nchan_out;
+ move16();
+ }
+
+ /*-----------------------------------------------------------------*
+ * Set output and intern setup & renderer selection
+ *-----------------------------------------------------------------*/
+
+ st_ivas->intern_config = output_config;
+ move32();
+ ivas_output_init( &( st_ivas->hOutSetup ), output_config );
+ test();
+ IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) )
+ {
+ st_ivas->hOutSetup.ambisonics_order = SBA_HOA3_ORDER;
+ move16();
+ st_ivas->intern_config = IVAS_AUDIO_CONFIG_7_1_4;
+ move32();
+ st_ivas->hOutSetup.output_config = st_ivas->intern_config;
+ move32();
+ st_ivas->hOutSetup.nchan_out_woLFE = audioCfg2channels( st_ivas->intern_config );
+ move16();
+ }
+ test();
+ IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
+ {
+ st_ivas->hOutSetup.ambisonics_order = SBA_HOA3_ORDER;
+ move32();
+ st_ivas->intern_config = IVAS_AUDIO_CONFIG_HOA3;
+ move32();
+ st_ivas->hOutSetup.output_config = IVAS_AUDIO_CONFIG_HOA3;
+ move32();
+ st_ivas->hOutSetup.nchan_out_woLFE = audioCfg2channels( IVAS_AUDIO_CONFIG_HOA3 );
+ move16();
+ }
+
+ /* Only initialize transport setup if it is used */
+ IF( NE_32( st_ivas->transport_config, IVAS_AUDIO_CONFIG_INVALID ) )
+ {
+ ivas_output_init( &( st_ivas->hTransSetup ), st_ivas->transport_config );
+ }
+
+ test();
+ IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) )
+ {
+ ivas_mcmasa_setNumTransportChannels_fx( &( st_ivas->nchan_transport ), &( st_ivas->element_mode_init ), ivas_total_brate );
+
+ ivas_mcmasa_set_separate_channel_mode_fx( &( st_ivas->hOutSetup.separateChannelEnabled ), &( st_ivas->hOutSetup.separateChannelIndex ), ivas_total_brate );
+ }
+
+ ivas_renderer_select( st_ivas );
+
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
+ {
+ IF( EQ_16( ( error = ivas_ls_custom_output_init_fx( st_ivas ) ), IVAS_ERR_OK ) )
+ {
+ st_ivas->hOutSetup.ls_azimuth_fx = st_ivas->hLsSetupCustom->ls_azimuth_fx;
+ move32();
+ st_ivas->hOutSetup.ls_elevation_fx = st_ivas->hLsSetupCustom->ls_elevation_fx;
+ move32();
+ st_ivas->hIntSetup.ls_azimuth_fx = st_ivas->hLsSetupCustom->ls_azimuth_fx;
+ move32();
+ st_ivas->hIntSetup.ls_elevation_fx = st_ivas->hLsSetupCustom->ls_elevation_fx;
+ move32();
+ }
+ ELSE
+ {
+ return error;
+ }
+ }
+
+ ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->intern_config );
+
+ test();
+ IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) )
+ {
+ ivas_mcmasa_set_separate_channel_mode_fx( &( st_ivas->hIntSetup.separateChannelEnabled ), &( st_ivas->hIntSetup.separateChannelIndex ), ivas_total_brate );
+
+ test();
+ IF( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && st_ivas->hOutSetup.separateChannelEnabled )
+ {
+ st_ivas->hLsSetupCustom->separate_ch_found = 0;
+ move16();
+ IF( GE_16( st_ivas->hOutSetup.nchan_out_woLFE, MCMASA_MIN_SPEAKERS_SEPARATE_CENTER ) )
+ {
+ /* check for a speaker at (0, 0) if minimum speaker count is available */
+ FOR( i = 0; i < st_ivas->hOutSetup.nchan_out_woLFE; i++ )
+ {
+ test();
+ IF( ( L_shr( st_ivas->hOutSetup.ls_azimuth_fx[i], Q22 ) == 0 ) && ( L_shr( st_ivas->hOutSetup.ls_elevation_fx[i], Q22 ) == 0 ) )
+ {
+ st_ivas->hIntSetup.separateChannelIndex = i;
+ move16();
+ st_ivas->hLsSetupCustom->separate_ch_found = 1;
+ move16();
+ BREAK;
+ }
+ }
+ }
+ }
+ }
+
+
+ /*-----------------------------------------------------------------*
+ * Allocate and initialize SCE/CPE and other handles
+ *-----------------------------------------------------------------*/
+
+ IF( EQ_32( st_ivas->ivas_format, MONO_FORMAT ) )
+ {
+ st_ivas->nSCE = 1; /* in mono, there is always only one SCE */
+ move16();
+ st_ivas->nCPE = 0;
+ move16();
+ st_ivas->nCPE_old = 0;
+ move16();
+ st_ivas->nchan_transport = 1;
+ move16();
+ sce_id = 0;
+ move16();
+
+ IF( NE_32( ( error = create_sce_dec( st_ivas, sce_id, ivas_total_brate ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] );
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) )
+ {
+ st_ivas->nchan_transport = CPE_CHANNELS;
+ move16();
+ st_ivas->intern_config = IVAS_AUDIO_CONFIG_STEREO;
+ move32();
+
+ st_ivas->nSCE = 0;
+ move16();
+ st_ivas->nCPE = 1; /* in stereo, there is always only one CPE */
+ move16();
+ st_ivas->nCPE_old = 0;
+ move16();
+ cpe_id = 0;
+ move16();
+
+ IF( NE_32( ( error = create_cpe_dec( st_ivas, cpe_id, ivas_total_brate ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ FOR( n = 0; n < st_ivas->nchan_transport; n++ )
+ {
+ reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] );
+ }
+
+ /* init EFAP for custom LS output and set hTransSetup */
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
+ {
+ IF( NE_32( ( error = efap_init_data_fx( &( st_ivas->hEFAPdata ), st_ivas->hOutSetup.ls_azimuth_fx, st_ivas->hOutSetup.ls_elevation_fx, st_ivas->hOutSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ ivas_output_init( &( st_ivas->hTransSetup ), IVAS_AUDIO_CONFIG_STEREO );
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) )
+ {
+ Word32 element_brate_tmp[MAX_NUM_OBJECTS];
+
+ st_ivas->nSCE = st_ivas->nchan_transport; /* "st_ivas->nchan_transport" is known from ivas_dec_setup */
+ move16();
+ st_ivas->nCPE = 0;
+ move16();
+ st_ivas->nCPE_old = 0;
+ move16();
+ st_ivas->ism_extmeta_active = -1;
+ move16();
+ st_ivas->ism_extmeta_cnt = 0;
+ move16();
+ IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) )
+ {
+ st_ivas->nchan_transport = MAX_PARAM_ISM_WAVE;
+ move16();
+ st_ivas->nSCE = MAX_PARAM_ISM_WAVE;
+ move16();
+
+ IF( NE_32( ( error = ivas_param_ism_dec_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ IF( NE_32( ( error = ivas_ism_metadata_dec_create_fx( st_ivas, st_ivas->nSCE, element_brate_tmp ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
+ {
+ IF( NE_32( ( error = create_sce_dec( st_ivas, sce_id, element_brate_tmp[sce_id] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] );
+
+ st_ivas->hSCE[sce_id]->hCoreCoder[0]->is_ism_format = 1;
+ move16();
+ }
+
+ st_ivas->hISMDTX.sce_id_dtx = 0;
+ move16();
+
+ IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) )
+ {
+ st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed2 = st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed3;
+ move16();
+ }
+ ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MODE_DISC ) )
+ {
+ FOR( sce_id = 0; sce_id < st_ivas->nSCE; ++sce_id )
+ {
+ st_ivas->hSCE[sce_id]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed2 = add( 2, sce_id );
+ move16();
+ }
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) )
+ {
+ IF( NE_32( ( error = ivas_qmetadata_open_fx( &( st_ivas->hQMetaData ) ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ IF( NE_32( ( error = ivas_spar_dec_open_fx( st_ivas, 0 ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ set16_fx( st_ivas->hSpar->hFbMixer->cldfb_cross_fade_fx, 0, CLDFB_NO_COL_MAX );
+ test();
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_DEC ) && st_ivas->hOutSetup.is_loudspeaker_setup )
+ {
+ IF( NE_32( ( error = ivas_sba_get_hoa_dec_matrix_fx( st_ivas->hOutSetup, &st_ivas->hoa_dec_mtx, st_ivas->hIntSetup.ambisonics_order ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ Word16 hodirac_flag = ivas_get_hodirac_flag_fx( ivas_total_brate, st_ivas->sba_analysis_order );
+ IF( hodirac_flag )
+ {
+ IF( NE_32( ( error = ivas_dirac_sba_config_fx( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, IVAS_MAX_NUM_BANDS, st_ivas->ivas_format ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ ELSE
+ {
+ IF( NE_32( ( error = ivas_dirac_sba_config_fx( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ), st_ivas->ivas_format ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+
+ test();
+ test();
+ IF( NE_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_FOA ) && NE_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) && NE_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_MONO ) )
+ {
+ IF( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_OPEN ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ st_ivas->hSpar->enc_param_start_band = st_ivas->hDirAC->hConfig->enc_param_start_band;
+ move16();
+ }
+ ELSE
+ {
+ Word16 band_grouping[IVAS_MAX_NUM_BANDS + 1];
+
+ st_ivas->hSpar->enc_param_start_band = s_min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND );
+ move16();
+ IF( ivas_get_hodirac_flag_fx( ivas_total_brate, st_ivas->sba_analysis_order ) )
+ {
+ st_ivas->hSpar->enc_param_start_band = 0;
+ move16();
+ set8_fx( (Word8 *) st_ivas->hQMetaData->twoDirBands, (Word8) 1, st_ivas->hQMetaData->q_direction[0].cfg.nbands );
+ st_ivas->hQMetaData->numTwoDirBands = (UWord8) st_ivas->hQMetaData->q_direction[0].cfg.nbands;
+ move16();
+ }
+
+ ivas_dirac_config_bands_fx( band_grouping, IVAS_MAX_NUM_BANDS, extract_l( Mpy_32_32_r( st_ivas->hDecoderConfig->output_Fs, INV_CLDFB_BANDWIDTH_Q31 ) ),
+ st_ivas->hSpar->dirac_to_spar_md_bands, st_ivas->hQMetaData->useLowerBandRes, st_ivas->hSpar->enc_param_start_band, 0 );
+ }
+ st_ivas->sba_dirac_stereo_flag = ivas_get_sba_dirac_stereo_flag( st_ivas );
+ move16();
+ FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
+ {
+ Word32 res_dec, res_frac;
+ iDiv_and_mod_32( ivas_total_brate, st_ivas->nchan_transport, &res_dec, &res_frac, 0 );
+ IF( NE_32( ( error = create_sce_dec( st_ivas, sce_id, res_dec ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] );
+ }
+
+ FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
+ {
+ Word32 res_dec, res_frac;
+ iDiv_and_mod_32( ivas_total_brate, st_ivas->nchan_transport, &res_dec, &res_frac, 0 );
+ IF( NE_32( ( error = create_cpe_dec( st_ivas, cpe_id, (res_dec) *CPE_CHANNELS ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ FOR( n = 0; n < CPE_CHANNELS; n++ )
+ {
+ reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] );
+ }
+ }
+
+ /* create CPE element for DFT Stereo like upmix */
+ test();
+ IF( st_ivas->sba_dirac_stereo_flag && ( st_ivas->nCPE == 0 ) )
+ {
+ Word32 res_dec, res_frac;
+ iDiv_and_mod_32( ivas_total_brate, add( st_ivas->nSCE, st_ivas->nCPE ), &res_dec, &res_frac, 0 );
+
+ IF( NE_32( ( error = create_cpe_dec( st_ivas, cpe_id, res_dec ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ st_ivas->hCPE[0]->hCoreCoder[0] = st_ivas->hSCE[0]->hCoreCoder[0]; /* don't allocate unnecessary core coder, simply point to core coder of SCE element */
+ st_ivas->hCPE[0]->hCoreCoder[1] = NULL;
+ }
+
+ IF( GT_16( st_ivas->nCPE, 1 ) )
+ {
+ IF( NE_32( ( error = create_mct_dec_fx( st_ivas ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ /* set CNA/CNG flags */
+ ivas_sba_set_cna_cng_flag( st_ivas );
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) )
+ {
+ /* if we start in ISM_MODE_NONE in MASA_ISM, that appears as normal MASA, but we may change to a mode with ISMs */
+ st_ivas->ism_extmeta_active = -1;
+ move16();
+ st_ivas->ism_extmeta_cnt = 0;
+ move16();
+ IF( NE_32( ( error = ivas_qmetadata_open_fx( &( st_ivas->hQMetaData ) ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ IF( NE_32( ( error = ivas_masa_dec_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ test();
+ test();
+ test();
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) || EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
+ {
+ IF( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_OPEN ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
+ {
+ Word32 res_dec, res_frac;
+ iDiv_and_mod_32( ivas_total_brate, st_ivas->nchan_transport, &res_dec, &res_frac, 0 );
+ IF( NE_32( ( error = create_sce_dec( st_ivas, sce_id, res_dec ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] );
+ }
+
+ FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
+ {
+ Word32 res_dec, res_frac;
+ iDiv_and_mod_32( ivas_total_brate, st_ivas->nchan_transport, &res_dec, &res_frac, 0 );
+ IF( NE_32( ( error = create_cpe_dec( st_ivas, cpe_id, L_shl( res_dec, 1 ) ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ FOR( n = 0; n < CPE_CHANNELS; n++ )
+ {
+ reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] );
+ }
+ }
+
+ /* set CNA/CNG flags */
+ ivas_sba_set_cna_cng_flag( st_ivas );
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
+ {
+ Word32 temp_brate[MAX_SCE];
+ st_ivas->ism_extmeta_active = -1;
+ move16();
+ st_ivas->ism_extmeta_cnt = 0;
+ move16();
+
+ st_ivas->sba_dirac_stereo_flag = ivas_get_sba_dirac_stereo_flag( st_ivas );
+ move16();
+ IF( NE_32( ( error = ivas_qmetadata_open_fx( &( st_ivas->hQMetaData ) ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ IF( NE_32( ( error = ivas_spar_dec_open_fx( st_ivas, 0 ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ test();
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_DEC ) && st_ivas->hOutSetup.is_loudspeaker_setup )
+ {
+ IF( NE_32( ( error = ivas_sba_get_hoa_dec_matrix_fx( st_ivas->hOutSetup, &st_ivas->hoa_dec_mtx, st_ivas->hIntSetup.ambisonics_order ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ Word16 hodirac_flag = ivas_get_hodirac_flag_fx( ivas_total_brate, st_ivas->sba_analysis_order );
+ IF( hodirac_flag )
+ {
+ IF( NE_32( ( error = ivas_dirac_sba_config_fx( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, IVAS_MAX_NUM_BANDS, st_ivas->ivas_format ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ ELSE
+ {
+ IF( NE_32( ( error = ivas_dirac_sba_config_fx( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ), st_ivas->ivas_format ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+
+ test();
+ test();
+ IF( NE_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_FOA ) && NE_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) && NE_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_MONO ) )
+ {
+ IF( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_OPEN ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ st_ivas->hSpar->enc_param_start_band = st_ivas->hDirAC->hConfig->enc_param_start_band;
+ move16();
+ }
+ ELSE
+ {
+ Word16 band_grouping[IVAS_MAX_NUM_BANDS + 1];
+
+ st_ivas->hSpar->enc_param_start_band = s_min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND );
+ move16();
+ IF( ivas_get_hodirac_flag_fx( ivas_total_brate, st_ivas->sba_analysis_order ) )
+ {
+ st_ivas->hSpar->enc_param_start_band = 0;
+ move16();
+ set8_fx( (Word8 *) st_ivas->hQMetaData->twoDirBands, (Word8) 1, st_ivas->hQMetaData->q_direction[0].cfg.nbands );
+ st_ivas->hQMetaData->numTwoDirBands = (UWord8) st_ivas->hQMetaData->q_direction[0].cfg.nbands;
+ move16();
+ }
+
+ ivas_dirac_config_bands_fx( band_grouping, IVAS_MAX_NUM_BANDS, extract_l( Mpy_32_32_r( st_ivas->hDecoderConfig->output_Fs, INV_CLDFB_BANDWIDTH_Q31 ) ),
+ st_ivas->hSpar->dirac_to_spar_md_bands, st_ivas->hQMetaData->useLowerBandRes, st_ivas->hSpar->enc_param_start_band, 0 );
+ }
+
+ FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
+ {
+ Word32 res_dec, res_frac;
+ iDiv_and_mod_32( ivas_total_brate, st_ivas->nchan_transport, &res_dec, &res_frac, 0 );
+ IF( NE_32( ( error = create_sce_dec( st_ivas, sce_id, res_dec ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] );
+ }
+
+ IF( EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
+ {
+ st_ivas->nCPE_old = st_ivas->nCPE;
+ move16();
+ st_ivas->nCPE = add( st_ivas->nCPE, shr( add( st_ivas->nchan_ism, 1 ), 1 ) );
+ move16();
+ st_ivas->element_mode_init = IVAS_CPE_MDCT;
+ move16();
+ }
+
+ FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
+ {
+ Word32 res_dec, res_frac;
+ iDiv_and_mod_32( ivas_total_brate, st_ivas->nchan_transport, &res_dec, &res_frac, 0 );
+ IF( NE_32( ( error = create_cpe_dec( st_ivas, cpe_id, L_shl( res_dec, 1 ) ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ FOR( n = 0; n < CPE_CHANNELS; n++ )
+ {
+ reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] );
+ }
+ }
+
+ /* create CPE element for DFT Stereo like upmix */
+ test();
+ IF( st_ivas->sba_dirac_stereo_flag && st_ivas->nCPE == 0 )
+ {
+ Word32 res_dec, res_frac;
+ iDiv_and_mod_32( ivas_total_brate, add( st_ivas->nSCE, st_ivas->nCPE ), &res_dec, &res_frac, 0 );
+ IF( NE_32( ( error = create_cpe_dec( st_ivas, cpe_id, res_dec ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ st_ivas->hCPE[0]->hCoreCoder[0] = st_ivas->hSCE[0]->hCoreCoder[0]; /* don't allocate unnecessary core coder, simply point to core coder of SCE element */
+ st_ivas->hCPE[0]->hCoreCoder[1] = NULL;
+ }
+
+ IF( GT_16( st_ivas->nCPE, 1 ) )
+ {
+ IF( NE_32( ( error = create_mct_dec_fx( st_ivas ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ IF( EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
+ {
+ IF( NE_32( ( error = ivas_ism_metadata_dec_create_fx( st_ivas, st_ivas->nchan_ism, temp_brate ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ IF( NE_32( ( error = ivas_osba_data_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ /* set CNA/CNG flags */
+ ivas_sba_set_cna_cng_flag( st_ivas );
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
+ {
+ st_ivas->ism_extmeta_active = -1;
+ move16();
+ st_ivas->ism_extmeta_cnt = 0;
+ move16();
+
+ IF( NE_32( ( error = ivas_qmetadata_open_fx( &( st_ivas->hQMetaData ) ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ k = 0;
+ move16();
+ ism_total_brate = 0;
+ move32();
+
+ WHILE( ( k < SIZE_IVAS_BRATE_TBL ) && ( ivas_total_brate != ivas_brate_tbl[k] ) )
+ {
+ k = add( k, 1 );
+ }
+ test();
+ IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
+ {
+ /* one separated object */
+ st_ivas->nSCE = 1;
+ move16();
+ ism_total_brate = sep_object_brate[k - 2][0];
+ move32();
+ IF( NE_32( ( error = create_sce_dec( st_ivas, 0, ism_total_brate ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ reset_indices_dec( st_ivas->hSCE[0]->hCoreCoder[0] );
+
+ IF( NE_32( ( error = ivas_ism_metadata_dec_create_fx( st_ivas, 1, NULL ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
+ {
+ Word32 temp_brate[MAX_SCE];
+ st_ivas->nSCE = st_ivas->nchan_ism; /* number of objects */
+ move16();
+ FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
+ {
+ temp_brate[sce_id] = sep_object_brate[k - 2][st_ivas->nSCE - 1];
+ move32();
+ ism_total_brate = L_add( ism_total_brate, temp_brate[sce_id] );
+
+ IF( NE_32( ( error = create_sce_dec( st_ivas, sce_id, temp_brate[sce_id] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] );
+ }
+
+ IF( NE_32( ( error = ivas_ism_metadata_dec_create_fx( st_ivas, st_ivas->nchan_ism, temp_brate ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ IF( NE_32( ( error = ivas_masa_dec_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ IF( NE_32( ( error = ivas_omasa_data_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ test();
+ test();
+ test();
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) || EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
+ {
+ IF( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_OPEN ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ IF( NE_32( ( error = create_cpe_dec( st_ivas, 0, ivas_total_brate - ism_total_brate ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ FOR( n = 0; n < CPE_CHANNELS; n++ )
+ {
+ reset_indices_dec( st_ivas->hCPE[0]->hCoreCoder[n] );
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) )
+ {
+ IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCT ) )
+ {
+ /* init EFAP for custom LS setup */
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
+ {
+ IF( NE_32( ( error = efap_init_data_fx( &( st_ivas->hEFAPdata ), st_ivas->hLsSetupCustom->ls_azimuth_fx, st_ivas->hLsSetupCustom->ls_elevation_fx, st_ivas->hLsSetupCustom->num_spk, EFAP_MODE_EFAP ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ st_ivas->nchan_transport = ivas_mc_ls_setup_get_num_channels_fx( ivas_mc_map_output_config_to_mc_ls_setup_fx( st_ivas->transport_config ) );
+ move16();
+ st_ivas->nSCE = 0;
+ move16();
+ st_ivas->nCPE = shr( st_ivas->nchan_transport, 1 );
+ move16();
+ st_ivas->nCPE_old = 0;
+ move16();
+ st_ivas->element_mode_init = IVAS_CPE_MDCT;
+ move16();
+ FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
+ {
+ Word32 res_dec, res_frac;
+ iDiv_and_mod_32( ivas_total_brate, sub( st_ivas->nchan_transport, 1 ), &res_dec, &res_frac, 0 );
+ IF( NE_32( ( error = create_cpe_dec( st_ivas, cpe_id, L_shl( res_dec, 1 ) ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ FOR( n = 0; n < CPE_CHANNELS; n++ )
+ {
+ reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] );
+ }
+ }
+
+ IF( NE_32( ( error = create_mct_dec_fx( st_ivas ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) )
+ {
+ /* init EFAP for custom LS setup */
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
+ {
+ IF( NE_32( ( error = efap_init_data_fx( &( st_ivas->hEFAPdata ), st_ivas->hLsSetupCustom->ls_azimuth_fx, st_ivas->hLsSetupCustom->ls_elevation_fx, st_ivas->hLsSetupCustom->num_spk, EFAP_MODE_EFAP ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ st_ivas->nSCE = 0;
+ move16();
+ st_ivas->nCPE = MC_PARAMUPMIX_MAX_TRANSPORT_CHANS >> 1;
+ move16();
+ st_ivas->nCPE_old = 0;
+ move16();
+ st_ivas->nchan_transport = MC_PARAMUPMIX_MAX_TRANSPORT_CHANS;
+ move16();
+
+ IF( NE_32( ( error = ivas_mc_paramupmix_dec_open( st_ivas ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ st_ivas->element_mode_init = IVAS_CPE_MDCT;
+ move16();
+ FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
+ {
+ Word32 res_dec, res_frac;
+ iDiv_and_mod_32( ivas_total_brate, sub( st_ivas->nchan_transport, 1 ), &res_dec, &res_frac, 0 );
+ IF( NE_32( ( error = create_cpe_dec( st_ivas, cpe_id, L_shl( res_dec, 1 ) ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ FOR( n = 0; n < CPE_CHANNELS; n++ )
+ {
+ reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] );
+ }
+ }
+
+ IF( NE_32( ( error = create_mct_dec_fx( st_ivas ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) )
+ {
+ /* init EFAP for custom LS setup */
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
+ {
+ IF( NE_32( ( error = efap_init_data_fx( &( st_ivas->hEFAPdata ), st_ivas->hLsSetupCustom->ls_azimuth_fx, st_ivas->hLsSetupCustom->ls_elevation_fx, st_ivas->hLsSetupCustom->num_spk, EFAP_MODE_EFAP ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ IF( NE_32( ( error = ivas_param_mc_dec_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ st_ivas->hParamMC->proto_matrix_int_e = 0;
+ move16();
+ FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
+ {
+ Word32 res_dec, res_frac;
+ iDiv_and_mod_32( ivas_total_brate, add( st_ivas->nSCE, st_ivas->nCPE ), &res_dec, &res_frac, 0 );
+
+ IF( NE_32( ( error = create_cpe_dec( st_ivas, cpe_id, res_dec ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ FOR( n = 0; n < CPE_CHANNELS; n++ )
+ {
+ reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] );
+ }
+ }
+
+ IF( GT_16( st_ivas->nCPE, 1 ) )
+ {
+ IF( NE_32( ( error = create_mct_dec_fx( st_ivas ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) )
+ {
+ Word32 brate_sce, brate_cpe;
+
+ ivas_mcmasa_setNumTransportChannels_fx( &( st_ivas->nchan_transport ), &( st_ivas->element_mode_init ), ivas_total_brate );
+
+ IF( NE_32( ( error = ivas_qmetadata_open_fx( &( st_ivas->hQMetaData ) ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ IF( NE_32( ( error = ivas_masa_dec_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
+
+ {
+ return error;
+ }
+
+ st_ivas->sba_dirac_stereo_flag = ivas_get_sba_dirac_stereo_flag( st_ivas );
+ move16();
+ test();
+ IF( NE_32( st_ivas->renderer_type, RENDERER_DISABLE ) && NE_32( st_ivas->renderer_type, RENDERER_MCMASA_MONO_STEREO ) )
+ {
+ IF( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_OPEN ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ test();
+ test();
+ IF( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && st_ivas->hOutSetup.separateChannelEnabled && !st_ivas->hLsSetupCustom->separate_ch_found )
+ {
+ /* If no speaker matching the separated channel, compute panning gains for the separated channel. */
+ IF( st_ivas->hVBAPdata == NULL )
+ {
+ /* Distribute signal to all channels if VBAP is not properly initialized. */
+ Word16 inv_sqr, sqr, exp = 15, exp_sqr;
+ move16();
+ IF( EQ_16( st_ivas->hLsSetupCustom->num_spk, 1 ) )
+ {
+ inv_sqr = 32767; // (1.0f in Q15)-1
+ move16();
+ }
+ ELSE
+ {
+ sqr = Sqrt16( st_ivas->hLsSetupCustom->num_spk, &exp );
+ inv_sqr = BASOP_Util_Divide1616_Scale( 32767, sqr, &exp_sqr );
+ exp_sqr = sub( exp_sqr, exp );
+ IF( ( exp < 0 ) )
+ {
+ inv_sqr = shr( inv_sqr, exp ); // exp_sqr
+ }
+ ELSE
+ {
+ inv_sqr = shl( inv_sqr, exp ); // exp_sqr
+ }
+ }
+ set16_fx( st_ivas->hLsSetupCustom->separate_ch_gains_fx, inv_sqr, st_ivas->hLsSetupCustom->num_spk );
+ }
+ }
+
+
+ ivas_mcmasa_split_brate_fx( st_ivas->hOutSetup.separateChannelEnabled, ivas_total_brate, st_ivas->nSCE, st_ivas->nCPE, &brate_sce, &brate_cpe );
+
+ FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
+ {
+ IF( NE_32( ( error = create_sce_dec( st_ivas, sce_id, brate_sce ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] );
+ }
+
+ FOR( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
+ {
+ st_ivas->element_mode_init = IVAS_CPE_MDCT; /* element_mode_init was IVAS_SCE for SCE initialization */
+ move16();
+ IF( NE_32( ( error = create_cpe_dec( st_ivas, cpe_id, brate_cpe ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ FOR( n = 0; n < CPE_CHANNELS; n++ )
+ {
+ reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] );
+ }
+ }
+
+ /* create CPE element for DFT Stereo like upmix */
+ IF( st_ivas->sba_dirac_stereo_flag )
+ {
+ Word32 res_dec, res_frac;
+ iDiv_and_mod_32( ivas_total_brate, add( st_ivas->nSCE, st_ivas->nCPE ), &res_dec, &res_frac, 0 );
+ IF( NE_32( ( error = create_cpe_dec( st_ivas, cpe_id, res_dec ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ st_ivas->hCPE[0]->hCoreCoder[0] = st_ivas->hSCE[0]->hCoreCoder[0]; /* don't allocate unnecessary core coder, simply point to core coder of SCE element */
+ st_ivas->hCPE[0]->hCoreCoder[1] = NULL;
+ }
+
+ /* set CNA/CNG flags */
+ test();
+ test();
+ IF( EQ_16( st_ivas->nchan_transport, 1 ) && ( ( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) ) )
+ {
+ st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag = 1;
+ move16();
+ st_ivas->hSCE[0]->hCoreCoder[0]->cng_sba_flag = 1;
+ move16();
+ }
+ }
+ }
+
+
+ /*-----------------------------------------------------------------*
+ * Allocate and initialize HP20 filter memories
+ *-----------------------------------------------------------------*/
+
+ /* set number of output channels used for synthesis/decoding */
+ n = getNumChanSynthesis( st_ivas );
+
+ IF( n > 0 )
+ {
+ IF( ( st_ivas->mem_hp20_out_fx = (Word32 **) malloc( n * sizeof( Word32 * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) );
+ }
+ }
+ ELSE
+ {
+ st_ivas->mem_hp20_out_fx = NULL;
+ }
+
+ FOR( i = 0; i < n; i++ )
+ {
+ IF( ( st_ivas->mem_hp20_out_fx[i] = (Word32 *) malloc( ( L_HP20_MEM + 2 ) * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) );
+ }
+ set32_fx( st_ivas->mem_hp20_out_fx[i], 0, L_HP20_MEM + 2 );
+ }
+
+ /*-------------------------------------------------------------------*
+ * Allocate and initialize rendering handles
+ *--------------------------------------------------------------------*/
+ test();
+ test();
+ test();
+ test();
+ test();
+ test();
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
+ {
+ IF( NE_32( ( error = ivas_binRenderer_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ /* ParamISM is handled separately from other common config */
+ ELSE IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) && ( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) || EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) ) )
+ {
+ IF( NE_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) )
+ {
+ IF( NE_32( ( error = ivas_dirac_dec_binaural_copy_hrtfs_fx( &st_ivas->hHrtfParambin ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ IF( NE_32( ( error = ivas_dirac_dec_init_binaural_data_fx( st_ivas, st_ivas->hHrtfParambin ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) )
+ {
+ Word16 SrcInd[MAX_NUM_TDREND_CHANNELS];
+ Word16 num_src;
+ IF( NE_32( ( error = ivas_td_binaural_open_fx( st_ivas, SrcInd, &num_src ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ Word16 nchan_rend = num_src;
+ move16();
+ test();
+ IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && NE_32( st_ivas->transport_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
+ {
+ nchan_rend = sub( nchan_rend, 1 ); /* Skip LFE channel -- added to the others */
+ }
+ FOR( Word16 nS = 0; nS < nchan_rend; nS++ )
+ {
+ TDREND_SRC_t *Src_p = st_ivas->hBinRendererTd->Sources[SrcInd[nS]];
+ if ( Src_p->SrcSpatial_p != NULL )
+ {
+ Src_p->SrcSpatial_p->q_Pos_p = Q31;
+ move16();
+ }
+ TDREND_SRC_SPATIAL_t *SrcSpatial_p = st_ivas->hBinRendererTd->Sources[nS]->SrcSpatial_p;
+ SrcSpatial_p->q_Pos_p = Q31;
+ move16();
+ }
+
+ IF( EQ_32( st_ivas->hIntSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
+ {
+ IF( NE_32( ( error = ivas_reverb_open_fx( &st_ivas->hReverb, st_ivas->hDecoderConfig->output_config, NULL, st_ivas->hBinRendererTd->HrFiltSet_p->lr_energy_and_iac_fx, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ granularity = NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES );
+
+ n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas );
+
+
+ IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, TC_BUFFER_MODE_RENDERER, n_channels_transport_jbm, n_channels_transport_jbm, n_channels_transport_jbm, granularity ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_MC ) )
+ {
+ IF( NE_32( ( error = ivas_ls_setup_conversion_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) )
+ {
+ IF( NE_32( ( error = ivas_mono_dmx_renderer_open( st_ivas ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) )
+ {
+ test();
+ test();
+ test();
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) && EQ_32( st_ivas->ivas_format, MC_FORMAT ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) )
+ {
+ IF( NE_32( ( error = efap_init_data_fx( &( st_ivas->hEFAPdata ), st_ivas->hIntSetup.ls_azimuth_fx, st_ivas->hIntSetup.ls_elevation_fx, st_ivas->hIntSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ IF( NE_32( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config,
+ st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs ) ),
+ IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ st_ivas->binaural_latency_ns = st_ivas->hCrendWrapper->binaural_latency_ns;
+ move32();
+
+ test();
+ IF( ( EQ_32( st_ivas->ivas_format, MC_FORMAT ) ) && ( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) ) )
+ {
+ granularity = NS2SA_FX2( output_Fs, CLDFB_SLOT_NS );
+
+ n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas );
+
+
+ IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, TC_BUFFER_MODE_RENDERER, n_channels_transport_jbm, MC_PARAMUPMIX_MAX_INPUT_CHANS, MC_PARAMUPMIX_MAX_INPUT_CHANS, granularity ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ ELSE
+ {
+ granularity = NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES );
+
+ n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas );
+
+ IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, TC_BUFFER_MODE_RENDERER, n_channels_transport_jbm, n_channels_transport_jbm, n_channels_transport_jbm, granularity ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ }
+
+ IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
+ {
+ test();
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
+ {
+ /* Allocate TD renderer for the objects in DISC mode */
+ Word16 SrcInd[MAX_NUM_TDREND_CHANNELS];
+ Word16 num_src;
+ IF( NE_32( ( error = ivas_td_binaural_open_fx( st_ivas, SrcInd, &num_src ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ Word16 nchan_rend = num_src;
+ move16();
+ test();
+ if ( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && NE_32( st_ivas->transport_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
+ {
+ nchan_rend = sub( nchan_rend, 1 ); /* Skip LFE channel -- added to the others */
+ }
+ FOR( Word16 nS = 0; nS < nchan_rend; nS++ )
+ {
+ TDREND_SRC_t *Src_p = st_ivas->hBinRendererTd->Sources[SrcInd[nS]];
+ if ( Src_p->SrcSpatial_p != NULL )
+ {
+ Src_p->SrcSpatial_p->q_Pos_p = Q31;
+ move16();
+ }
+ TDREND_SRC_SPATIAL_t *SrcSpatial_p = st_ivas->hBinRendererTd->Sources[nS]->SrcSpatial_p;
+ SrcSpatial_p->q_Pos_p = Q31;
+ move16();
+ }
+
+ /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
+ IF( NE_32( ( error = ivas_omasa_separate_object_renderer_open( st_ivas ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ test();
+ test();
+ test();
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) && ( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) ) )
+ {
+ /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
+ IF( NE_32( ( error = ivas_omasa_separate_object_renderer_open( st_ivas ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ }
+
+ test();
+ test();
+ test();
+ test();
+ test();
+ test();
+ test();
+ test();
+ test();
+ test();
+ test();
+ test();
+ IF( ( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) || EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) &&
+ ( EQ_32( st_ivas->ism_mode, ISM_MODE_DISC ) || EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) ) &&
+ ( EQ_32( st_ivas->renderer_type, RENDERER_TD_PANNING ) ||
+ EQ_32( st_ivas->renderer_type, RENDERER_NON_DIEGETIC_DOWNMIX ) ||
+ EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ||
+ EQ_32( st_ivas->renderer_type, RENDERER_OSBA_STEREO ) ||
+ EQ_32( st_ivas->renderer_type, RENDERER_OSBA_AMBI ) ||
+ EQ_32( st_ivas->renderer_type, RENDERER_OSBA_LS ) ||
+ EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) ||
+ EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ||
+ EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) ) )
+ {
+ IF( NE_32( ( error = ivas_ism_renderer_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
+ {
+ test();
+ test();
+ IF( ( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) ) && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
+ {
+ /* Allocate TD renderer for the objects in DISC mode */
+ Word16 SrcInd[MAX_NUM_TDREND_CHANNELS];
+ Word16 num_src;
+ IF( NE_32( ( error = ivas_td_binaural_open_fx( st_ivas, SrcInd, &num_src ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ Word16 nchan_rend = num_src;
+ move16();
+
+ test();
+ if ( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && NE_32( st_ivas->transport_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
+ {
+ nchan_rend = sub( nchan_rend, 1 ); /* Skip LFE channel -- added to the others */
+ }
+ FOR( Word16 nS = 0; nS < nchan_rend; nS++ )
+ {
+ TDREND_SRC_t *Src_p = st_ivas->hBinRendererTd->Sources[SrcInd[nS]];
+ if ( Src_p->SrcSpatial_p != NULL )
+ {
+ Src_p->SrcSpatial_p->q_Pos_p = Q31;
+ move16();
+ }
+ TDREND_SRC_SPATIAL_t *SrcSpatial_p = st_ivas->hBinRendererTd->Sources[nS]->SrcSpatial_p;
+ SrcSpatial_p->q_Pos_p = Q31;
+ move16();
+ }
+ }
+ }
+
+ /*-----------------------------------------------------------------*
+ * LFE handles for rendering after rendering to adjust LFE delay to binaural filter delay
+ *-----------------------------------------------------------------*/
+ test();
+ IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCT ) || EQ_32( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) )
+ {
+ binauralization_delay_ns = st_ivas->binaural_latency_ns;
+ move32();
+ IF( st_ivas->hBinRenderer != NULL )
+ {
+ IF( st_ivas->hBinRenderer->render_lfe )
+ {
+ {
+ /* Account for filterbank delay */
+ binauralization_delay_ns = L_add( binauralization_delay_ns, IVAS_FB_DEC_DELAY_NS );
+ }
+ }
+ ELSE
+ {
+ binauralization_delay_ns = 0;
+ move32();
+ }
+ }
+
+ IF( NE_32( ( error = ivas_create_lfe_dec_fx( &st_ivas->hLFE, output_Fs, binauralization_delay_ns ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ set32_fx( st_ivas->hLFE->prevsynth_buf_fx, 0, LFE_PLC_BUFLEN );
+ set32_fx( st_ivas->hLFE->prior_out_buffer_fx, 0, L_FRAME48k );
+ }
+
+ /*-----------------------------------------------------------------*
+ * CLDFB handles for rendering
+ *-----------------------------------------------------------------*/
+
+ ivas_init_dec_get_num_cldfb_instances_ivas_fx( st_ivas, &numCldfbAnalyses, &numCldfbSyntheses );
+
+ FOR( i = 0; i < numCldfbAnalyses; i++ )
+ {
+ IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ FOR( ; i < MAX_INTERN_CHANNELS; i++ )
+ {
+ st_ivas->cldfbAnaDec[i] = NULL;
+ }
+
+ FOR( i = 0; i < numCldfbSyntheses; i++ )
+ {
+ IF( NE_32( ( error = openCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ FOR( ; i < MAX_OUTPUT_CHANNELS; i++ )
+ {
+ st_ivas->cldfbSynDec[i] = NULL;
+ }
+
+ /* CLDFB Interpolation weights */
+ test();
+ test();
+ test();
+ IF( ( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) || EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) && !st_ivas->sba_dirac_stereo_flag && NE_16( st_ivas->hDecoderConfig->nchan_out, 1 ) )
+ {
+ Word16 Q_cldfbSynDec = Q11;
+ move16();
+ ivas_spar_get_cldfb_gains_fx( st_ivas->hSpar, st_ivas->cldfbAnaDec[0], st_ivas->cldfbSynDec[0], hDecoderConfig );
+
+ FOR( i = 0; i < st_ivas->cldfbAnaDec[0]->cldfb_state_length; i++ )
+ {
+ st_ivas->cldfbAnaDec[0]->cldfb_state_fx[i] = L_shr( st_ivas->cldfbAnaDec[0]->cldfb_state_fx[i], 16 ); // Scaling down from 27 to 11
+ move32();
+ }
+ st_ivas->cldfbAnaDec[0]->Q_cldfb_state = Q11;
+ move16();
+ FOR( i = 0; i < st_ivas->cldfbSynDec[0]->cldfb_state_length; i++ )
+ {
+ st_ivas->cldfbSynDec[0]->cldfb_state_fx[i] = L_shr( st_ivas->cldfbSynDec[0]->cldfb_state_fx[i], sub( 21, Q_cldfbSynDec ) ); // Scaling down from 21 to Q_cldfbSynDec
+ move32();
+ }
+ st_ivas->cldfbSynDec[0]->Q_cldfb_state = Q11;
+ move16();
+ }
+
+ /*-----------------------------------------------------------------*
+ * Allocate and initialize limiter struct
+ *-----------------------------------------------------------------*/
+
+ IF( NE_32( ( error = ivas_limiter_open_fx( &st_ivas->hLimiter, hDecoderConfig->nchan_out, output_Fs ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ /*-----------------------------------------------------------------*
+ * Allocate and initialize JBM struct + buffer
+ *-----------------------------------------------------------------*/
+
+ IF( st_ivas->hTcBuffer == NULL )
+
+ {
+ /* no module has yet open the TC buffer, open a default one */
+ n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas );
+
+ IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, ivas_jbm_dec_get_tc_buffer_mode( st_ivas ), n_channels_transport_jbm, n_channels_transport_jbm, n_channels_transport_jbm, NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ IF( st_ivas->hTcBuffer == NULL )
+ {
+ /* we need the handle anyway, but without the buffer*/
+ IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, TC_BUFFER_MODE_NONE, 0, 0, 0, 1 ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ IF( st_ivas->hJbmMetadata == NULL )
+ {
+ IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
+ {
+ IF( NE_32( ( error = ivas_jbm_dec_metadata_open( st_ivas ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ }
+
+ /*-----------------------------------------------------------------*
+ * Allocate floating-point output audio buffers
+ *-----------------------------------------------------------------*/
+ st_ivas->p_out_len = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate );
+ move16();
+ FOR( n = 0; n < ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); n++ )
+ {
+ /* note: these are intra-frame heap memories */
+ IF( ( st_ivas->p_output_fx[n] = (Word32 *) malloc( ( 48000 / FRAMES_PER_SEC ) * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for floating-point output audio buffer!\n" ) );
+ }
+ set32_fx( st_ivas->p_output_fx[n], 0, 48000 / FRAMES_PER_SEC );
+ }
+
+ FOR( ; n < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; n++ )
+ {
+ st_ivas->p_output_fx[n] = NULL;
+ }
+ return error;
+}
+
+/*-------------------------------------------------------------------------
+ * destroy_core_dec()
+ *
+ * Close core decoder handles
+ *-------------------------------------------------------------------------*/
+
+void destroy_core_dec_fx(
+ DEC_CORE_HANDLE hCoreCoder /* i/o: core decoder structure */
+)
+{
+ IF( EQ_16( hCoreCoder->element_mode, EVS_MONO ) )
+ {
+ destroy_cldfb_decoder_fx( hCoreCoder );
+ }
+ ELSE
+ {
+ destroy_cldfb_decoder_ivas_fx( hCoreCoder );
+ }
+
+ IF( hCoreCoder->hGSCDec != NULL )
+ {
+ free( hCoreCoder->hGSCDec );
+ hCoreCoder->hGSCDec = NULL;
+ }
+
+ IF( hCoreCoder->hPFstat != NULL )
+ {
+ free( hCoreCoder->hPFstat );
+ hCoreCoder->hPFstat = NULL;
+ }
+
+ IF( hCoreCoder->hMusicPF != NULL )
+ {
+ free( hCoreCoder->hMusicPF );
+ hCoreCoder->hMusicPF = NULL;
+ }
+
+ IF( hCoreCoder->hBPF != NULL )
+ {
+ free( hCoreCoder->hBPF );
+ hCoreCoder->hBPF = NULL;
+ }
+
+ IF( hCoreCoder->hBWE_zero != NULL )
+ {
+ free( hCoreCoder->hBWE_zero );
+ hCoreCoder->hBWE_zero = NULL;
+ }
+
+ IF( hCoreCoder->hTdCngDec != NULL )
+ {
+ free( hCoreCoder->hTdCngDec );
+ hCoreCoder->hTdCngDec = NULL;
+ }
+
+ IF( hCoreCoder->hSC_VBR != NULL )
+ {
+ free( hCoreCoder->hSC_VBR );
+ hCoreCoder->hSC_VBR = NULL;
+ }
+
+ IF( hCoreCoder->hAmrwb_IO != NULL )
+ {
+ free( hCoreCoder->hAmrwb_IO );
+ hCoreCoder->hAmrwb_IO = NULL;
+ }
+
+ IF( hCoreCoder->hBWE_TD != NULL )
+ {
+ free( hCoreCoder->hBWE_TD );
+ hCoreCoder->hBWE_TD = NULL;
+ }
+
+ IF( hCoreCoder->hBWE_FD != NULL )
+ {
+ free( hCoreCoder->hBWE_FD );
+ hCoreCoder->hBWE_FD = NULL;
+ }
+
+ IF( hCoreCoder->hBWE_FD_HR != NULL )
+ {
+ free( hCoreCoder->hBWE_FD_HR );
+ hCoreCoder->hBWE_FD_HR = NULL;
+ }
+
+ IF( hCoreCoder->hWIDec != NULL )
+ {
+ free( hCoreCoder->hWIDec );
+ hCoreCoder->hWIDec = NULL;
+ }
+
+ IF( hCoreCoder->hTECDec != NULL )
+ {
+ free( hCoreCoder->hTECDec );
+ hCoreCoder->hTECDec = NULL;
+ }
+
+ IF( hCoreCoder->hTcxLtpDec != NULL )
+ {
+ free( hCoreCoder->hTcxLtpDec );
+ hCoreCoder->hTcxLtpDec = NULL;
+ }
+
+ IF( hCoreCoder->hTcxDec != NULL )
+ {
+ free( hCoreCoder->hTcxDec );
+ hCoreCoder->hTcxDec = NULL;
+ }
+
+ IF( hCoreCoder->hTcxCfg != NULL )
+ {
+ free( hCoreCoder->hTcxCfg );
+ hCoreCoder->hTcxCfg = NULL;
+ }
+
+ IF( hCoreCoder->hTonalMDCTConc != NULL )
+ {
+ free( hCoreCoder->hTonalMDCTConc );
+ hCoreCoder->hTonalMDCTConc = NULL;
+ }
+
+ IF( hCoreCoder->hIGFDec != NULL )
+ {
+ free( hCoreCoder->hIGFDec );
+ hCoreCoder->hIGFDec = NULL;
+ }
+
+ IF( hCoreCoder->hPlcInfo != NULL )
+ {
+ free( hCoreCoder->hPlcInfo );
+ hCoreCoder->hPlcInfo = NULL;
+ }
+
+ IF( hCoreCoder->hHQ_core != NULL )
+ {
+ free( hCoreCoder->hHQ_core );
+ hCoreCoder->hHQ_core = NULL;
+ }
+
+ IF( hCoreCoder->hHQ_nbfec != NULL )
+ {
+ free( hCoreCoder->hHQ_nbfec );
+ hCoreCoder->hHQ_nbfec = NULL;
+ }
+
+ return;
+}
+
+/*-------------------------------------------------------------------------
+ * ivas_initialize_handles_dec()
+ *
+ * NULL initialization of handles
+ *-------------------------------------------------------------------------*/
+
+void ivas_initialize_handles_dec(
+ Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
+)
+{
+ Word16 i;
+
+ FOR( i = 0; i < MAX_INTERN_CHANNELS; i++ )
+ {
+ st_ivas->cldfbAnaDec[i] = NULL;
+ }
+
+ FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ )
+ {
+ st_ivas->cldfbSynDec[i] = NULL;
+ }
+
+ /* SCE handles */
+ FOR( i = 0; i < MAX_SCE; i++ )
+ {
+ st_ivas->hSCE[i] = NULL;
+ }
+
+ /* CPE handles */
+ FOR( i = 0; i < MAX_CPE; i++ )
+ {
+ st_ivas->hCPE[i] = NULL;
+ }
+
+ st_ivas->bit_stream = NULL;
+ st_ivas->mem_hp20_out_fx = NULL;
+ st_ivas->hLimiter = NULL;
+
+ /* ISM metadata handles */
+ FOR( i = 0; i < MAX_NUM_OBJECTS; i++ )
+ {
+ st_ivas->hIsmMetaData[i] = NULL;
+ }
+
+ /* spatial coding handles */
+ st_ivas->hDirAC = NULL;
+ st_ivas->hParamIsmDec = NULL;
+ st_ivas->hSpar = NULL;
+ st_ivas->hMasa = NULL;
+ st_ivas->hQMetaData = NULL;
+ st_ivas->hMCT = NULL;
+ st_ivas->hMCParamUpmix = NULL;
+ st_ivas->hParamMC = NULL;
+ st_ivas->hLFE = NULL;
+
+ /* rendering handles */
+ st_ivas->hBinRenderer = NULL;
+ st_ivas->hDiracDecBin = NULL;
+ st_ivas->hDirACRend = NULL;
+ st_ivas->hSpatParamRendCom = NULL;
+ st_ivas->hLsSetUpConversion = NULL;
+ st_ivas->hEFAPdata = NULL;
+ st_ivas->hVBAPdata = NULL;
+ st_ivas->hIsmRendererData = NULL;
+ st_ivas->hBinRendererTd = NULL;
+ st_ivas->hMonoDmxRenderer = NULL;
+ st_ivas->hCrendWrapper = NULL;
+ st_ivas->hReverb = NULL;
+ st_ivas->hSetOfHRTF = NULL;
+ st_ivas->hHrtfFastConv = NULL;
+ st_ivas->hHrtfParambin = NULL;
+ st_ivas->hoa_dec_mtx = NULL;
+ st_ivas->hMasaIsmData = NULL;
+ st_ivas->hSbaIsmData = NULL;
+
+ st_ivas->hHeadTrackData = NULL;
+ st_ivas->hHrtfTD = NULL;
+ st_ivas->hLsSetupCustom = NULL;
+ st_ivas->hRenderConfig = NULL;
+ st_ivas->hExtOrientationData = NULL;
+ st_ivas->hCombinedOrientationData = NULL;
+
+
+ /* JBM handles */
+ st_ivas->hTcBuffer = NULL;
+ st_ivas->hJbmMetadata = NULL;
+
+ /* floating-point output audio buffers */
+ FOR( i = 0; i < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; i++ )
+ {
+ st_ivas->p_output_fx[i] = NULL;
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * ivas_destroy_dec()
+ *
+ * Close IVAS decoder handles
+ *-------------------------------------------------------------------------*/
+
+void ivas_destroy_dec_fx(
+ Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */
+)
+{
+ Word16 i;
+
+ /* CLDFB handles */
+ FOR( i = 0; i < MAX_INTERN_CHANNELS; i++ )
+ {
+ IF( st_ivas->cldfbAnaDec[i] != NULL )
+ {
+ deleteCldfb_ivas_fx( &( st_ivas->cldfbAnaDec[i] ) );
+ }
+ }
+
+ FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ )
+ {
+ IF( st_ivas->cldfbSynDec[i] != NULL )
+ {
+ deleteCldfb_ivas_fx( &( st_ivas->cldfbSynDec[i] ) );
+ }
+ }
+
+ /* SCE handles */
+ FOR( i = 0; i < MAX_SCE; i++ )
+ {
+ IF( st_ivas->hSCE[i] != NULL )
+ {
+ destroy_sce_dec( st_ivas->hSCE[i] );
+ st_ivas->hSCE[i] = NULL;
+ }
+ }
+
+ /* CPE handles */
+ FOR( i = 0; i < MAX_CPE; i++ )
+ {
+ IF( st_ivas->hCPE[i] != NULL )
+ {
+ /* set pointer to NULL as core coder already deallocated in destroy_sce_dec() */
+ test();
+ IF( st_ivas->sba_dirac_stereo_flag && EQ_16( st_ivas->nchan_transport, 1 ) )
+ {
+ st_ivas->hCPE[i]->hCoreCoder[0] = NULL;
+ st_ivas->hCPE[i]->hCoreCoder[1] = NULL;
+ }
+ destroy_cpe_dec( st_ivas->hCPE[i] );
+ st_ivas->hCPE[i] = NULL;
+ }
+ }
+
+ /* HP20 filter handles */
+ IF( st_ivas->mem_hp20_out_fx != NULL )
+ {
+ FOR( i = 0; i < getNumChanSynthesis( st_ivas ); i++ )
+ {
+ free( st_ivas->mem_hp20_out_fx[i] );
+ st_ivas->mem_hp20_out_fx[i] = NULL;
+ }
+ free( st_ivas->mem_hp20_out_fx );
+ st_ivas->mem_hp20_out_fx = NULL;
+ }
+
+ /* ISM metadata handles */
+ ivas_ism_metadata_close( st_ivas->hIsmMetaData, 0 );
+
+ /* ISM renderer handle */
+ ivas_ism_renderer_close( &( st_ivas->hIsmRendererData ) );
+
+ /* DirAC handle */
+ IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) )
+ {
+ ivas_param_ism_dec_close_fx( &( st_ivas->hParamIsmDec ), &( st_ivas->hSpatParamRendCom ), st_ivas->hDecoderConfig->output_config );
+ }
+ ELSE
+ {
+ ivas_dirac_rend_close_fx( &( st_ivas->hDirACRend ) );
+ ivas_spat_hSpatParamRendCom_close_fx( &( st_ivas->hSpatParamRendCom ) );
+ ivas_dirac_dec_close_fx( &( st_ivas->hDirAC ) );
+ }
+
+ /* SPAR handle */
+ ivas_spar_dec_close_fx( &( st_ivas->hSpar ), st_ivas->hDecoderConfig->output_Fs, 0 );
+
+ /* HOA decoder matrix */
+ IF( st_ivas->hoa_dec_mtx != NULL )
+ {
+ free( st_ivas->hoa_dec_mtx );
+ st_ivas->hoa_dec_mtx = NULL;
+ }
+
+ /* MASA decoder structure */
+
+ ivas_masa_dec_close_fx( &( st_ivas->hMasa ) );
+ /* Qmetadata handle */
+ ivas_qmetadata_close_fx( &st_ivas->hQMetaData );
+
+ /* MCT handle */
+ ivas_mct_dec_close( &st_ivas->hMCT );
+
+ /* LFE handle */
+ ivas_lfe_dec_close_fx( &( st_ivas->hLFE ) );
+
+ /* Param-Upmix MC handle */
+ ivas_mc_paramupmix_dec_close( &( st_ivas->hMCParamUpmix ) );
+
+ /* Parametric MC handle */
+ ivas_param_mc_dec_close_fx( &st_ivas->hParamMC );
+
+ /* EFAP handle */
+ efap_free_data_fx( &st_ivas->hEFAPdata );
+
+ /* VBAP handle */
+ vbap_free_data_fx( &( st_ivas->hVBAPdata ) );
+ /* Fastconv binaural renderer handle */
+ ivas_binRenderer_close_fx( &st_ivas->hBinRenderer );
+
+ /* Parametric binaural renderer handle */
+ ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin );
+
+ /* Crend handle */
+
+ ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) );
+
+ /* Reverb handle */
+ ivas_reverb_close( &st_ivas->hReverb );
+
+ /* LS config converter handle */
+
+ ivas_ls_setup_conversion_close_fx( &st_ivas->hLsSetUpConversion );
+ /* Custom LS configuration handle */
+ IF( st_ivas->hLsSetupCustom != NULL )
+ {
+ free( st_ivas->hLsSetupCustom );
+ st_ivas->hLsSetupCustom = NULL;
+ }
+
+ /* Mono downmix structure */
+ ivas_mono_dmx_renderer_close( &st_ivas->hMonoDmxRenderer );
+
+ /* OSBA structure */
+
+ ivas_osba_data_close_fx( &st_ivas->hSbaIsmData );
+
+ /* OMASA structure */
+ ivas_omasa_data_close_fx( &st_ivas->hMasaIsmData );
+ /* Head track data handle */
+ ivas_headTrack_close_fx( &st_ivas->hHeadTrackData );
+
+ /* External orientation data handle */
+ ivas_external_orientation_close_fx( &st_ivas->hExtOrientationData );
+
+ /* Combined orientation data handle */
+ ivas_combined_orientation_close_fx( &st_ivas->hCombinedOrientationData );
+
+ /* Time Domain binaural renderer handle */
+ IF( st_ivas->hBinRendererTd != NULL )
+ {
+ ivas_td_binaural_close_fx( &st_ivas->hBinRendererTd );
+ }
+ ELSE IF( st_ivas->hHrtfTD != NULL )
+ {
+ BSplineModelEvalDealloc_fx( &st_ivas->hHrtfTD->ModelParams, &st_ivas->hHrtfTD->ModelEval );
+ ivas_HRTF_binary_close_fx( &st_ivas->hHrtfTD );
+ }
+
+ /* CRend binaural renderer handle */
+ ivas_HRTF_CRend_binary_close_fx( &st_ivas->hSetOfHRTF );
+
+ /* Fastconv HRTF memories */
+ ivas_binaural_hrtf_close( &st_ivas->hHrtfFastConv );
+
+ /* Fastconv HRTF filters */
+ ivas_HRTF_fastconv_binary_close_fx( &st_ivas->hHrtfFastConv );
+
+ /* Parametric binauralizer HRTF filters */
+ ivas_HRTF_parambin_binary_close_fx( &st_ivas->hHrtfParambin );
+
+ /* Config. Renderer */
+ ivas_render_config_close( &( st_ivas->hRenderConfig ) );
+
+ /* Limiter struct */
+ ivas_limiter_close_fx( &( st_ivas->hLimiter ) );
+
+ IF( st_ivas->hDecoderConfig != NULL )
+ {
+ free( st_ivas->hDecoderConfig );
+ st_ivas->hDecoderConfig = NULL;
+ }
+
+ ivas_jbm_dec_tc_buffer_close( &st_ivas->hTcBuffer );
+
+ IF( st_ivas->hJbmMetadata != NULL )
+ {
+ free( st_ivas->hJbmMetadata );
+ st_ivas->hJbmMetadata = NULL;
+ }
+
+ /* floating-point output audio buffers */
+ FOR( i = 0; i < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; i++ )
+ {
+
+ IF( st_ivas->p_output_fx[i] != NULL )
+ {
+ free( st_ivas->p_output_fx[i] );
+ st_ivas->p_output_fx[i] = NULL;
+ }
+ }
+
+ /* main IVAS handle */
+ free( st_ivas );
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------*
+ * ivas_init_dec_get_num_cldfb_instances()
+ *
+ * Return number of CLDFB analysis & synthesis instances
+ *-------------------------------------------------------------------*/
+
+/*! r: number of cldfb instances */
+void ivas_init_dec_get_num_cldfb_instances(
+ Decoder_Struct *st_ivas, /* i : IVAS decoder structure */
+ Word16 *numCldfbAnalyses, /* o : number of needed CLDFB analysis instances */
+ Word16 *numCldfbSyntheses /* o : number of needed CLDFB synthesis instances */
+)
+{
+ IVAS_FORMAT ivas_format;
+ *numCldfbAnalyses = st_ivas->nchan_transport;
+ move16();
+ *numCldfbSyntheses = st_ivas->hDecoderConfig->nchan_out;
+ move16();
+
+ test();
+ IF( ( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_MODE_NONE ) ) )
+ {
+ ivas_format = SBA_FORMAT;
+ move32();
+ }
+ ELSE
+ {
+ ivas_format = st_ivas->ivas_format;
+ move32();
+ }
+
+ SWITCH( st_ivas->renderer_type )
+ {
+ case RENDERER_BINAURAL_PARAMETRIC:
+ case RENDERER_BINAURAL_PARAMETRIC_ROOM:
+ case RENDERER_STEREO_PARAMETRIC:
+ IF( EQ_16( st_ivas->nchan_transport, 1 ) )
+ {
+ *numCldfbAnalyses = add( st_ivas->nchan_transport, 1 );
+ move16();
+ }
+
+ test();
+ IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) && st_ivas->hOutSetup.separateChannelEnabled )
+ {
+ *numCldfbAnalyses = add( st_ivas->nchan_transport, 1 );
+ move16();
+ }
+
+ IF( EQ_32( ivas_format, SBA_ISM_FORMAT ) )
+ {
+ IF( EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
+ {
+ *numCldfbAnalyses = add( *numCldfbAnalyses, st_ivas->nchan_ism );
+ move16();
+ }
+ }
+
+ IF( EQ_32( ivas_format, MASA_ISM_FORMAT ) )
+ {
+ test();
+ IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
+ {
+ *numCldfbAnalyses = add( *numCldfbAnalyses, st_ivas->nchan_ism );
+ move16();
+ }
+ ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
+ {
+ *numCldfbAnalyses = add( st_ivas->nchan_transport, 1 );
+ move16();
+ }
+ }
+ IF( st_ivas->hDiracDecBin->useTdDecorr )
+ {
+ *numCldfbAnalyses = add( *numCldfbAnalyses, 2 );
+ move16();
+ }
+ BREAK;
+ case RENDERER_NON_DIEGETIC_DOWNMIX:
+ case RENDERER_MONO_DOWNMIX:
+ test();
+ test();
+ IF( EQ_32( ivas_format, ISM_FORMAT ) || EQ_32( ivas_format, MASA_ISM_FORMAT ) || EQ_32( ivas_format, SBA_ISM_FORMAT ) )
+ {
+ /* CLDFB not used in rendering */
+ *numCldfbAnalyses = 0;
+ move16();
+ *numCldfbSyntheses = 0;
+ move16();
+ }
+ BREAK;
+ case RENDERER_DIRAC:
+ IF( EQ_32( ivas_format, SBA_FORMAT ) )
+ {
+ *numCldfbAnalyses = st_ivas->hSpar->hFbMixer->fb_cfg->num_in_chans;
+ move16();
+
+ test();
+ IF( st_ivas->hOutSetup.is_loudspeaker_setup && EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) )
+ {
+ *numCldfbSyntheses = st_ivas->hOutSetup.nchan_out_woLFE;
+ move16();
+ }
+ ELSE IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_FOA ) )
+ {
+ *numCldfbSyntheses = st_ivas->hSpar->hFbMixer->fb_cfg->num_out_chans;
+ move16();
+ }
+ ELSE
+ {
+ *numCldfbSyntheses = MAX_OUTPUT_CHANNELS;
+ move16();
+ }
+ }
+ IF( NE_32( ivas_format, SBA_FORMAT ) )
+ {
+ test();
+ test();
+ IF( GT_16( st_ivas->nchan_transport, 2 ) && ( st_ivas->sba_planar != 0 ) )
+ {
+ *numCldfbAnalyses = add( st_ivas->nchan_transport, 1 );
+ move16();
+ }
+ ELSE IF( EQ_16( st_ivas->nchan_transport, 1 ) && EQ_32( st_ivas->hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
+ {
+ *numCldfbAnalyses = add( st_ivas->nchan_transport, 1 );
+ move16();
+ }
+ }
+ BREAK;
+ case RENDERER_MC_PARAMMC:
+ IF( LE_16( st_ivas->hDecoderConfig->nchan_out, 2 ) )
+ {
+ /* CLDFB not used in rendering */
+ *numCldfbAnalyses = 0;
+ move16();
+ *numCldfbSyntheses = 0;
+ move16();
+ }
+ ELSE
+ {
+ *numCldfbSyntheses = param_mc_get_num_cldfb_syntheses_fx( st_ivas );
+ move16();
+ }
+ BREAK;
+ case RENDERER_PARAM_ISM:
+ /* Already correct with no exception */
+ BREAK;
+ case RENDERER_DISABLE:
+ /* CLDFB not used */
+ *numCldfbAnalyses = 0;
+ move16();
+ *numCldfbSyntheses = 0;
+ move16();
+ BREAK;
+ case RENDERER_MC:
+ case RENDERER_SBA_LINEAR_DEC:
+ case RENDERER_TD_PANNING:
+ case RENDERER_BINAURAL_OBJECTS_TD:
+ case RENDERER_MCMASA_MONO_STEREO:
+ case RENDERER_BINAURAL_MIXER_CONV:
+ case RENDERER_BINAURAL_MIXER_CONV_ROOM:
+ case RENDERER_BINAURAL_FASTCONV:
+ case RENDERER_BINAURAL_FASTCONV_ROOM:
+ case RENDERER_OSBA_STEREO:
+ case RENDERER_OSBA_AMBI:
+ case RENDERER_OSBA_LS:
+ test();
+ IF( EQ_32( ivas_format, SBA_FORMAT ) || EQ_32( ivas_format, SBA_ISM_FORMAT ) )
+ {
+ IF( st_ivas->sba_dirac_stereo_flag != 0 )
+ {
+ *numCldfbAnalyses = 0;
+ move16();
+ *numCldfbSyntheses = 0;
+ move16();
+ }
+ ELSE
+ {
+ *numCldfbAnalyses = st_ivas->hSpar->hFbMixer->fb_cfg->num_in_chans;
+ move16();
+
+ test();
+ IF( st_ivas->hOutSetup.is_loudspeaker_setup && EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) )
+ {
+ *numCldfbSyntheses = st_ivas->hOutSetup.nchan_out_woLFE;
+ move16();
+ }
+ ELSE IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_FOA ) )
+ {
+ *numCldfbSyntheses = st_ivas->hSpar->hFbMixer->fb_cfg->num_out_chans;
+ move16();
+ }
+ ELSE
+ {
+ *numCldfbSyntheses = MAX_OUTPUT_CHANNELS;
+ move16();
+ }
+ test();
+ IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
+ {
+ *numCldfbAnalyses = add( st_ivas->nchan_ism, st_ivas->hSpar->hFbMixer->fb_cfg->num_in_chans );
+ move16();
+ }
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) )
+ {
+ /* do nothing for ParamMC */
+ }
+ ELSE
+ {
+ /* CLDFB not used in rendering */
+ *numCldfbAnalyses = 0;
+ move16();
+ *numCldfbSyntheses = 0;
+ move16();
+ }
+ BREAK;
+ case RENDERER_SBA_LINEAR_ENC:
+ IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) )
+ {
+ *numCldfbSyntheses = param_mc_get_num_cldfb_syntheses_fx( st_ivas );
+ move16();
+ }
+ ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) )
+ {
+ *numCldfbSyntheses = add( st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hIntSetup.num_lfe );
+ move16();
+ }
+ ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) )
+ {
+ *numCldfbAnalyses = st_ivas->nchan_transport;
+ move16();
+ *numCldfbSyntheses = add( st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hIntSetup.num_lfe );
+ move16();
+ }
+ ELSE
+ {
+ /* CLDFB not used in rendering */
+ *numCldfbAnalyses = 0;
+ move16();
+ *numCldfbSyntheses = 0;
+ move16();
+ }
+ BREAK;
+ default:
+ assert( 0 && "Renderer not handled for CLDFB reservation." );
+ }
+ test();
+ test();
+ IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) && NE_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_MONO ) && NE_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) )
+ {
+ test();
+ test();
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) || EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) )
+ {
+ *numCldfbAnalyses = s_max( MC_PARAMUPMIX_MAX_INPUT_CHANS, *numCldfbAnalyses );
+ move16();
+ }
+ ELSE
+ {
+ *numCldfbAnalyses = s_max( MC_PARAMUPMIX_MIN_CLDFB, *numCldfbAnalyses );
+ move16();
+ }
+ *numCldfbSyntheses = s_max( MC_PARAMUPMIX_MIN_CLDFB, *numCldfbSyntheses );
+ move16();
+ }
+
+ return;
+}
+
void ivas_init_dec_get_num_cldfb_instances_ivas_fx(
Decoder_Struct *st_ivas, /* i : IVAS decoder structure */
Word16 *numCldfbAnalyses, /* o : number of needed CLDFB analysis instances */
@@ -260,3 +3376,142 @@ void ivas_init_dec_get_num_cldfb_instances_ivas_fx(
return;
}
+
+
+/*---------------------------------------------------------------------*
+ * doSanityChecks_IVAS()
+ *
+ * Sanity checks - verify if the decoder set-up parameters are
+ * not in conflict with the IVAS format
+ *---------------------------------------------------------------------*/
+
+static ivas_error doSanityChecks_IVAS(
+ Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
+)
+{
+ Word32 output_Fs;
+ AUDIO_CONFIG output_config;
+
+ output_Fs = st_ivas->hDecoderConfig->output_Fs;
+ move32();
+ output_config = st_ivas->hDecoderConfig->output_config;
+ move32();
+ /*-----------------------------------------------------------------*
+ * Sanity checks
+ *-----------------------------------------------------------------*/
+
+ IF( EQ_32( output_Fs, 8000 ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "8kHz output sampling rate is not supported in IVAS." );
+ }
+
+ assert( st_ivas->ivas_format != UNDEFINED_FORMAT && "\n IVAS format undefined" );
+ assert( st_ivas->ivas_format != MONO_FORMAT && "\n Wrong IVAS format: MONO" );
+
+ /* Verify output configuration compatible with non-diegetic panning */
+ test();
+ test();
+ IF( st_ivas->hDecoderConfig->Opt_non_diegetic_pan && NE_32( st_ivas->ivas_format, MONO_FORMAT ) && NE_32( st_ivas->transport_config, IVAS_AUDIO_CONFIG_ISM1 ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Error: Non-diegetic panning not supported in this IVAS format" );
+ }
+
+ /* Verify stereo output configuration */
+ IF( EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) )
+ {
+ test();
+ test();
+ test();
+ test();
+ test();
+ test();
+ test();
+ IF( NE_32( output_config, IVAS_AUDIO_CONFIG_MONO ) && NE_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) && NE_32( output_config, IVAS_AUDIO_CONFIG_5_1 ) && NE_32( output_config, IVAS_AUDIO_CONFIG_7_1 ) && NE_32( output_config, IVAS_AUDIO_CONFIG_5_1_2 ) && NE_32( output_config, IVAS_AUDIO_CONFIG_5_1_4 ) && NE_32( output_config, IVAS_AUDIO_CONFIG_7_1_4 ) && NE_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Wrong output configuration specified for Stereo!" );
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) )
+ {
+ /* Verify ISM output configuration */
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_INVALID ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified for ISM" );
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) )
+ {
+ /* Verify SBA output coniguration */
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_INVALID ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified for SBA" );
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) )
+ {
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_INVALID ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified for MASA!" );
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) )
+ {
+ /* Verify MC output configuration */
+ test();
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_INVALID ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified for Multi-channel" );
+ }
+ }
+
+
+ IF( st_ivas->hDecoderConfig->Opt_Headrotation )
+ {
+ test();
+ test();
+ IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_HEAD_ROTATION_NOT_SUPPORTED, "Wrong set-up: Head-rotation not supported in this configuration" );
+ }
+ }
+
+ IF( st_ivas->hDecoderConfig->Opt_ExternalOrientation )
+ {
+ test();
+ test();
+ IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_EXT_ORIENTATION_NOT_SUPPORTED, "Wrong set-up: External orientation not supported in this configuration" );
+ }
+ }
+
+ IF( st_ivas->hDecoderConfig->Opt_dpid_on )
+ {
+ test();
+ IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_DIRECTIVITY_NOT_SUPPORTED, "Wrong set-up: Directivity is not supported in this output configuration." );
+ }
+ }
+
+ IF( st_ivas->hDecoderConfig->Opt_aeid_on )
+ {
+ IF( NE_16( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
+ {
+ return IVAS_ERROR( IVAS_ERR_ACOUSTIC_ENVIRONMENT_NOT_SUPPORTED, "Wrong set-up: Acoustic environment is not supported in this output configuration." );
+ }
+ }
+
+ IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
+ {
+ test();
+ IF( NE_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
+ {
+
+ return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified for combined MASA and ISM format" );
+ }
+ }
+
+
+ return IVAS_ERR_OK;
+}
diff --git a/lib_dec/ivas_rom_dec.c b/lib_dec/ivas_rom_dec_fx.c
similarity index 100%
rename from lib_dec/ivas_rom_dec.c
rename to lib_dec/ivas_rom_dec_fx.c
diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec_fx.c
similarity index 100%
rename from lib_dec/ivas_stereo_cng_dec.c
rename to lib_dec/ivas_stereo_cng_dec_fx.c
diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c
deleted file mode 100644
index 92ae9159cd99b32fcbf18839bed6508bc7bcbe70..0000000000000000000000000000000000000000
--- a/lib_dec/ivas_stereo_dft_dec.c
+++ /dev/null
@@ -1,494 +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.
-
-*******************************************************************************************************/
-
-#include
-#include
-#include "options.h"
-#include
-#include "cnst.h"
-#include "rom_com.h"
-#include "rom_dec.h"
-#include "prot_fx.h"
-#include "ivas_cnst.h"
-#include "ivas_rom_com.h"
-#include "ivas_rom_com_fx.h"
-#include "ivas_rom_dec.h"
-#include "wmc_auto.h"
-#include "ivas_prot_fx.h"
-
-/*-------------------------------------------------------------------*
- * Local constants
- *-------------------------------------------------------------------*/
-
-#define STEFI_DELAY_IND( d, buf_ind ) ( ( buf_ind ) + STEREO_DFT_PAST_MAX - ( d ) + 1 ) % STEREO_DFT_PAST_MAX
-
-#define STEREO_DFT_RES_RATIO_LIMIT_FX ( Word32 )( 0x170A3D71 )
-#define STEREO_DFT_STEFFI_DELAY_SHORT 2
-#define STEREO_DFT_STEFFI_DELAY_LONG 4
-#define STEREO_DFT_STEFFI_DELAY_OFFSET 2
-
-
-#define STEREO_DFT_BPF_SIZE 40 /* BPF: Number of weights for BPF in DFT: 40*40Hz=1.6kHz*/
-
-
-/*-------------------------------------------------------------------------
- * Local function prototypes
- *-------------------------------------------------------------------------*/
-
-
-/*-------------------------------------------------------------------------
- * stereo_dft_dec_create()
- *
- * Create DFT stereo handle
- *------------------------------------------------------------------------*/
-
-
-/*-------------------------------------------------------------------------
- * stereo_dft_dec_open()
- *
- * Open DFT decoder stereo handle
- *-------------------------------------------------------------------------*/
-
-
-/*-------------------------------------------------------------------------
- * stereo_dft_dec_reset()
- *
- * Reset DFT stereo memories
- *------------------------------------------------------------------------*/
-
-/*-------------------------------------------------------------------------
- * stereo_dft_dec_update()
- *
- * Update DFT memories for new frame
- *-------------------------------------------------------------------------*/
-
-/*-------------------------------------------------------------------------
- * stereo_dft_dec_destroy()
- *
- * destroy DFT stereo handle
- *-------------------------------------------------------------------------*/
-
-void stereo_dft_dec_destroy(
- STEREO_DFT_DEC_DATA_HANDLE *hStereoDft_glob /* i/o: decoder DFT stereo handle */
-)
-{
- STEREO_DFT_DEC_DATA_HANDLE hStereoDft;
-
- hStereoDft = *hStereoDft_glob;
-
- IF( hStereoDft->hConfig != NULL )
- {
- free( hStereoDft->hConfig );
- hStereoDft->hConfig = NULL;
- }
-
- IF( hStereoDft->hBpf != NULL )
- {
- free( hStereoDft->hBpf );
- hStereoDft->hBpf = NULL;
- }
-
- IF( hStereoDft->hTcxLtpDec != NULL )
- {
- free( hStereoDft->hTcxLtpDec );
- hStereoDft->hTcxLtpDec = NULL;
- }
-
- free( hStereoDft );
- hStereoDft = NULL;
-
- return;
-}
-
-
-/*-------------------------------------------------------------------------
- * stereo_dft_dec_analyze()
- *
- * DFT analysis on a 20ms frame
- *-------------------------------------------------------------------------*/
-
-void stereo_dft_dec_analyze_fx(
- CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */
- const Word32 *input_fx, /* i : input signal q*/
- Word32 out_DFT_fx[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* o : DFT buffers q_out_DFT*/
- const Word16 chan, /* i : channel number Q0*/
- const Word16 input_frame, /* i : input frame size Q0*/
- const Word16 output_frame, /* i : output frame size Q0*/
- const DFT_STEREO_DEC_ANA_TYPE ana_type, /* i : type of signal to analyse */
- const Word16 k_offset, /* i : offset of DFT Q0*/
- const Word16 delay, /* i : delay in samples FOR input signal Q0*/
- Word16 *q,
- Word16 *q_out_DFT )
-{
-
- Word16 i, k;
- STEREO_DFT_DEC_DATA_HANDLE hStereoDft;
- Word32 *pInput_fx, *pInput_buff_fx;
- Word32 *mem_fx, input_buff_fx[STEREO_DFT32MS_OVL_MAX + L_FRAME48k];
- Word32 DFT_fx[STEREO_DFT32MS_N_MAX], *pDFT_out_fx;
- Word16 NFFT, NFFT_core, ovl, zp;
- Word16 offset;
- Word32 fac_fx;
- const Word16 *trigo_fx, *win_left_fx, *win_right_fx, *win2_fx;
- Word16 trigo_dec_fx[STEREO_DFT32MS_N_MAX / 2 + 1];
- Word16 trigo_step;
- Word32 inputFs;
- Word16 delay_dec;
- Word16 mem_size;
- Word16 ovl2;
-
- push_wmops( "DFT_analysis" );
-
- hStereoDft = hCPE->hStereoDft;
-
- assert( output_frame == STEREO_DFT_NBDIV * hStereoDft->N );
-
- /*-----------------------------------------------------------------*
- * Initialization
- *-----------------------------------------------------------------*/
-
- IF( EQ_16( input_frame, output_frame ) )
- {
- trigo_fx = hStereoDft->dft_trigo_fx;
- trigo_step = i_mult( hStereoDft->dft_trigo_step, STEREO_DFT_TRIGO_DEC_STEP ); /* Q0 */
- win_right_fx = hStereoDft->win32ms_fx; /* Q15 */
- win_left_fx = hStereoDft->win32ms_fx; /* Q15 */
- win2_fx = hStereoDft->win232ms_fx; /* Q15 */
-
- test();
- IF( EQ_32( ana_type, DFT_STEREO_DEC_ANA_BPF ) )
- {
- assert( ( chan == 0 ) && "DFT stereo: BPF memory only FOR M channel" );
- mem_fx = hCPE->input_mem_BPF_fx[chan]; /* Q11 */
- }
- ELSE IF( EQ_32( ana_type, DFT_STEREO_DEC_ANA_LB ) || EQ_32( ana_type, DFT_STEREO_DEC_ANA_LB_ADD ) )
- {
- mem_fx = hCPE->input_mem_LB_fx[chan]; /* Q11 */
- }
- ELSE
- {
- mem_fx = hCPE->input_mem_fx[chan]; /* Q11 */
- }
- }
- ELSE IF( EQ_16( input_frame, L_FRAME ) )
- {
- trigo_fx = hStereoDft->dft_trigo_12k8_fx; /* Q15 */
- trigo_step = STEREO_DFT_TRIGO_SRATE_12k8_STEP * STEREO_DFT_TRIGO_DEC_STEP;
- move16();
- win_right_fx = hStereoDft->win32ms_12k8_fx; /* Q15 */
- win_left_fx = hStereoDft->win32ms_12k8_fx; /* Q15 */
- win2_fx = hStereoDft->win232ms_12k8_fx; /* Q15 */
-
- test();
- IF( EQ_32( ana_type, DFT_STEREO_DEC_ANA_BPF ) )
- {
- assert( ( chan == 0 ) && "DFT stereo: BPF memory only FOR M channel" );
- mem_fx = hCPE->input_mem_BPF_fx[chan]; /* Q11 */
- }
- ELSE IF( EQ_32( ana_type, DFT_STEREO_DEC_ANA_LB ) || EQ_32( ana_type, DFT_STEREO_DEC_ANA_LB_ADD ) )
- {
- mem_fx = hCPE->input_mem_LB_fx[chan]; /* Q11 */
- }
- ELSE
- {
- assert( ( chan == 1 ) && "12.8kHz sampling rate only FOR second channel, i.e. residual coding or allpass signal" );
- mem_fx = hCPE->input_mem_fx[chan]; /* Q11 */
- }
- }
- ELSE IF( EQ_16( input_frame, L_FRAME16k ) )
- {
- trigo_fx = hStereoDft->dft_trigo_16k_fx; /* Q15 */
- trigo_step = STEREO_DFT_TRIGO_SRATE_16k_STEP * STEREO_DFT_TRIGO_DEC_STEP;
- move16();
- win_right_fx = hStereoDft->win32ms_16k_fx; /* Q15 */
- win_left_fx = hStereoDft->win32ms_16k_fx; /* Q15 */
- win2_fx = hStereoDft->win232ms_16k_fx; /* Q15 */
-
- test();
- IF( EQ_32( ana_type, DFT_STEREO_DEC_ANA_BPF ) )
- {
- assert( ( chan == 0 ) && "DFT stereo: BPF memory only FOR M channel" );
- mem_fx = hCPE->input_mem_BPF_fx[chan]; /* Q11 */
- }
- ELSE IF( EQ_32( ana_type, DFT_STEREO_DEC_ANA_LB ) || EQ_32( ana_type, DFT_STEREO_DEC_ANA_LB_ADD ) )
- {
- mem_fx = hCPE->input_mem_LB_fx[chan]; /* Q11 */
- }
- ELSE
- {
- assert( ( chan == 1 ) && ( hCPE->hStereoDft->hConfig->res_pred_mode == STEREO_DFT_RESPRED_ESF ) && "16kHz sampling rate only FOR second channel with allpass signal" );
- mem_fx = hCPE->input_mem_fx[chan]; /* Q11 */
- }
- }
- ELSE IF( EQ_16( input_frame, L_FRAME8k ) )
- {
- assert( ( chan == 1 ) && "DFT stereo: 8kHz analysis only FOR residual coding" );
- trigo_fx = hStereoDft->dft_trigo_8k_fx; /* Q15 */
- trigo_step = STEREO_DFT_TRIGO_SRATE_8k_STEP * STEREO_DFT_TRIGO_DEC_STEP;
- move16();
- win_right_fx = hStereoDft->win32ms_8k_fx; /* Q15 */
- win_left_fx = hStereoDft->win32ms_8k_fx; /* Q15 */
- win2_fx = hStereoDft->win232ms_8k_fx; /* Q15 */
- mem_fx = hCPE->input_mem_fx[chan]; /* Q11 */
- }
- ELSE
- {
- IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error in DFT stereo: sampling rate not supported" );
- mem_fx = NULL; /* to avoid compilation warning */
- trigo_fx = NULL; /* to avoid compilation warning */
- trigo_step = -1; /* to avoid compilation warning */
- move16();
- win_right_fx = NULL; /* to avoid compilation warning */
- win_left_fx = NULL; /* to avoid compilation warning */
- win2_fx = NULL; /* to avoid compilation warning */
- }
-
- inputFs = L_mult0( input_frame, FRAMES_PER_SEC ); /* Q0 */
- delay_dec = NS2SA_FX2( inputFs, STEREO_DFT32MS_OVL_NS );
- move16();
- zp = NS2SA_FX2( inputFs, STEREO_DFT32MS_ZP_NS );
- move16();
- ovl = NS2SA_FX2( inputFs, STEREO_DFT32MS_OVL_NS );
- move16();
- NFFT = NS2SA_FX2( inputFs, STEREO_DFT32MS_N_NS );
- Word16 qfac_fx;
- fac_fx = BASOP_Util_Divide3232_Scale_newton( hStereoDft->NFFT, NFFT, &qfac_fx ); /* qfac_fx */
- qfac_fx = sub( 31, qfac_fx );
- ovl2 = NS2SA_FX2( inputFs, STEREO_DFT32MS_OVL2_NS );
- move16();
-
- /* Offset FOR the time buffers */
- assert( ( delay >= -NS2SA( input_frame * FRAMES_PER_SEC, STEREO_DFT_DELAY_DEC_BWE_NS + STEREO_DFT_OVL_NS / 2 ) ) && ( delay <= NS2SA( input_frame * FRAMES_PER_SEC, STEREO_DFT_OVL_NS ) ) );
- mem_size = add( delay_dec, delay );
-
- /* Update buffers */
- Copy32( mem_fx, input_buff_fx, mem_size ); /* Q11 */
- Copy32( input_fx, input_buff_fx + mem_size, input_frame ); /* q */
- Copy32( input_buff_fx + input_frame, mem_fx, mem_size ); /* q */
- pInput_buff_fx = input_buff_fx; /* q */
-
- test();
- IF( EQ_16( hCPE->nchan_out, 1 ) && ( hCPE->hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF ) )
- {
- pop_wmops();
- return;
- }
-
-
- /*-----------------------------------------------------------------*
- * DFT Analysis: loop over frame
- *-----------------------------------------------------------------*/
-
- assert( ( k_offset <= STEREO_DFT_NBDIV ) );
-
- FOR( i = 0; i < NFFT / 4; i++ )
- {
- trigo_dec_fx[i] = trigo_fx[i * trigo_step];
- move16();
- trigo_dec_fx[NFFT / 2 - i] = trigo_fx[i * trigo_step];
- move16();
- }
- trigo_dec_fx[NFFT / 4] = trigo_fx[NFFT / 4 * trigo_step];
- move16();
-
- FOR( k = 0; k < STEREO_DFT_NBDIV - k_offset; k++ )
- {
- set32_fx( DFT_fx, 0, STEREO_DFT32MS_N_MAX );
- IF( k == 0 )
- {
- offset = 0;
- move16();
- }
- ELSE
- {
- /* If OVL2 = OVL offset = 10ms */
- offset = NS2SA_FX2( inputFs, STEREO_DFT32MS_WIN_CENTER_NS - STEREO_DFT32MS_OVL2_NS / 2 );
- move16();
- }
-
- pInput_fx = pInput_buff_fx + offset; /* q */
- pDFT_out_fx = out_DFT_fx[chan] + i_mult( k, STEREO_DFT32MS_N_MAX ); /* q_out_DFT */
-
- /*Forwards FFT: L and R*/
- /* Zero Padding & Flat Portion */
- Copy32( pInput_fx, DFT_fx + zp, sub( NFFT, i_mult( 2, zp ) ) ); /* q */
-
- /* Overlapping portions */
- IF( k == 0 )
- {
- FOR( i = 0; i < ovl; i++ )
- {
- DFT_fx[i + zp] = Mpy_32_16_1( DFT_fx[i + zp], win_left_fx[STEREO_DFT32MS_STEP * i] ); /* q */
- move32();
- }
- FOR( i = 0; i < ovl2; i++ )
- {
- DFT_fx[NFFT - zp - 1 - i] = Mpy_32_16_1( DFT_fx[NFFT - zp - 1 - i], win2_fx[i] ); /* q */
- move32();
- }
- }
- ELSE
- {
- FOR( i = 0; i < ovl2; i++ )
- {
- DFT_fx[i + zp] = Mpy_32_16_1( DFT_fx[i + zp], win2_fx[i] ); /* q */
- move32();
- }
- FOR( i = 0; i < ovl; i++ )
- {
- DFT_fx[NFFT - zp - i - 1] = Mpy_32_16_1( DFT_fx[NFFT - zp - i - 1], win_right_fx[STEREO_DFT32MS_STEP * i] ); /* q */
- move32();
- }
- }
- Word16 q_DFT, q_shift, guarded_bits;
- q_DFT = *q;
- move16();
- guarded_bits = find_guarded_bits_fx( NFFT );
- q_shift = sub( L_norm_arr( DFT_fx, NFFT ), guarded_bits );
-
- FOR( Word16 j = 0; j < NFFT; j++ )
- {
- DFT_fx[j] = L_shl( DFT_fx[j], q_shift ); /* q + q_shift*/
- move32();
- }
-
- q_DFT = add( q_DFT, q_shift );
-
- rfft_fx( DFT_fx, trigo_dec_fx, NFFT, -1 );
-
- q_shift = sub( L_norm_arr( DFT_fx, NFFT ), sub( 31, qfac_fx ) );
- FOR( Word16 j = 0; j < NFFT; j++ )
- {
- DFT_fx[j] = L_shl( DFT_fx[j], q_shift ); /* q + q_shift */
- move32();
- }
- q_DFT = add( q_DFT, q_shift );
- IF( sub( q_out_DFT[chan], q_DFT ) > 0 )
- {
- FOR( Word32 j = 0; j < NFFT; j++ )
- {
- out_DFT_fx[chan][j] = L_shr( out_DFT_fx[chan][j], sub( q_out_DFT[chan], q_DFT ) ); /* q_DFT */
- move32();
- }
- q_out_DFT[chan] = q_DFT;
- move16();
- }
- ELSE
- {
- FOR( Word32 j = 0; j < NFFT; j++ )
- {
- DFT_fx[j] = L_shr( DFT_fx[j], sub( q_DFT, q_out_DFT[chan] ) ); /* q_DFT */
- move32();
- }
- q_DFT = q_out_DFT[chan];
- move16();
- }
-
- /*Resampling: filtering+scaling*/
- test();
- test();
- IF( ( ana_type == DFT_STEREO_DEC_ANA_FB ) || EQ_32( ana_type, DFT_STEREO_DEC_ANA_LB ) || EQ_32( ana_type, DFT_STEREO_DEC_ANA_NOCORE ) )
- {
- pDFT_out_fx[0] = L_shl( Mpy_32_32( DFT_fx[0], fac_fx ), sub( 31, qfac_fx ) ); /*DC*/ /* qDFT */
- move32();
- IF( EQ_16( NFFT, hStereoDft->NFFT ) ) /*Nyquist*/
- {
- pDFT_out_fx[1] = L_shl( Mpy_32_32( DFT_fx[1], fac_fx ), sub( 31, qfac_fx ) ); /* qDFT */
- move32();
- }
- ELSE
- {
- pDFT_out_fx[1] = 0;
- move32();
- }
- FOR( i = 2; i < NFFT; i++ )
- {
- pDFT_out_fx[i] = L_shl( Mpy_32_32( DFT_fx[i], fac_fx ), sub( 31, qfac_fx ) ); /* qDFT */
- move32();
- }
- FOR( i = NFFT; i < hStereoDft->NFFT; i++ )
- {
- pDFT_out_fx[i] = 0; /* qDFT */
- move32();
- }
- }
- ELSE IF( EQ_32( ana_type, DFT_STEREO_DEC_ANA_BPF ) )
- {
- pDFT_out_fx[0] = L_sub( pDFT_out_fx[0], L_shl( Mpy_32_32( Mpy_32_32( DFT_fx[0], fac_fx ), dft_bpf_weights_fx[0] ), sub( 32, qfac_fx ) ) ); /* qDFT */
- move32();
-
- FOR( i = 1; i < STEREO_DFT_BPF_SIZE; i++ )
- {
- pDFT_out_fx[2 * i] = L_sub( pDFT_out_fx[2 * i], L_shl( Mpy_32_32( Mpy_32_32( DFT_fx[2 * i], fac_fx ), dft_bpf_weights_fx[i] ), sub( 32, qfac_fx ) ) ); /* qDFT */
- move32();
- pDFT_out_fx[2 * i + 1] = L_sub( pDFT_out_fx[2 * i + 1], L_shl( Mpy_32_32( Mpy_32_32( DFT_fx[2 * i + 1], fac_fx ), dft_bpf_weights_fx[i] ), sub( 32, qfac_fx ) ) ); /* qDFT */
- move32();
- }
- }
- ELSE IF( EQ_32( ana_type, DFT_STEREO_DEC_ANA_HB_ADD ) )
- {
- NFFT_core = NS2SA_FX2( L_mult0( hCPE->hCoreCoder[0]->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_N_NS ); /* Q0 */
- move16();
-
- FOR( i = NFFT_core; i < NFFT; i++ )
- {
- pDFT_out_fx[i] = L_add( L_shl( Mpy_32_32( DFT_fx[i], fac_fx ), sub( 31, qfac_fx ) ), pDFT_out_fx[i] ); /* qDFT */
- move32();
- }
- }
- ELSE
- {
- pDFT_out_fx[0] = L_add( pDFT_out_fx[0], L_shl( Mpy_32_32( DFT_fx[0], fac_fx ), sub( 31, qfac_fx ) ) ); /*DC*/ /* qDFT */
- move32();
- IF( EQ_16( NFFT, hStereoDft->NFFT ) ) /*Nyquist*/
- {
- pDFT_out_fx[1] = L_add( L_shl( Mpy_32_32( DFT_fx[1], fac_fx ), sub( 31, qfac_fx ) ), pDFT_out_fx[1] ); /* qDFT */
- move32();
- }
- FOR( i = 2; i < NFFT; i++ )
- {
- pDFT_out_fx[i] = L_add( L_shl( Mpy_32_32( DFT_fx[i], fac_fx ), sub( 31, qfac_fx ) ), pDFT_out_fx[i] ); /* qDFT */
- move32();
- }
- }
- }
-
- pop_wmops();
- return;
-}
-
-
-/*---------------------------------------------------------------
- * stereo_dft_dec_smooth_parameters()
- *
- *
- * ---------------------------------------------------------------*/
diff --git a/lib_dec/ivas_stereo_dft_dec_fx.c b/lib_dec/ivas_stereo_dft_dec_fx.c
index f1ccc1d7fa81481b32a5fc30eba536694d6ade93..914c7fad17b255839f68fe1cfd598a15caef587a 100644
--- a/lib_dec/ivas_stereo_dft_dec_fx.c
+++ b/lib_dec/ivas_stereo_dft_dec_fx.c
@@ -268,7 +268,7 @@ void stereo_dft_dec_reset_fx(
}
/*-------------------------------------------------------------------------
- * stereo_dft_dec_open()
+ * stereo_dft_dec_open_fx()
*
* Open DFT decoder stereo handle
*-------------------------------------------------------------------------*/
@@ -684,6 +684,402 @@ void stereo_dft_dec_update_fx(
return;
}
+/*-------------------------------------------------------------------------
+ * stereo_dft_dec_destroy_fx()
+ *
+ * destroy DFT stereo handle
+ *-------------------------------------------------------------------------*/
+
+void stereo_dft_dec_destroy_fx(
+ STEREO_DFT_DEC_DATA_HANDLE *hStereoDft_glob /* i/o: decoder DFT stereo handle */
+)
+{
+ STEREO_DFT_DEC_DATA_HANDLE hStereoDft;
+
+ hStereoDft = *hStereoDft_glob;
+
+ IF( hStereoDft->hConfig != NULL )
+ {
+ free( hStereoDft->hConfig );
+ hStereoDft->hConfig = NULL;
+ }
+
+ IF( hStereoDft->hBpf != NULL )
+ {
+ free( hStereoDft->hBpf );
+ hStereoDft->hBpf = NULL;
+ }
+
+ IF( hStereoDft->hTcxLtpDec != NULL )
+ {
+ free( hStereoDft->hTcxLtpDec );
+ hStereoDft->hTcxLtpDec = NULL;
+ }
+
+ free( hStereoDft );
+ hStereoDft = NULL;
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * stereo_dft_dec_analyze_fx()
+ *
+ * DFT analysis on a 20ms frame
+ *-------------------------------------------------------------------------*/
+
+void stereo_dft_dec_analyze_fx(
+ CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */
+ const Word32 *input_fx, /* i : input signal q*/
+ Word32 out_DFT_fx[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* o : DFT buffers q_out_DFT*/
+ const Word16 chan, /* i : channel number Q0*/
+ const Word16 input_frame, /* i : input frame size Q0*/
+ const Word16 output_frame, /* i : output frame size Q0*/
+ const DFT_STEREO_DEC_ANA_TYPE ana_type, /* i : type of signal to analyse */
+ const Word16 k_offset, /* i : offset of DFT Q0*/
+ const Word16 delay, /* i : delay in samples FOR input signal Q0*/
+ Word16 *q,
+ Word16 *q_out_DFT )
+{
+
+ Word16 i, k;
+ STEREO_DFT_DEC_DATA_HANDLE hStereoDft;
+ Word32 *pInput_fx, *pInput_buff_fx;
+ Word32 *mem_fx, input_buff_fx[STEREO_DFT32MS_OVL_MAX + L_FRAME48k];
+ Word32 DFT_fx[STEREO_DFT32MS_N_MAX], *pDFT_out_fx;
+ Word16 NFFT, NFFT_core, ovl, zp;
+ Word16 offset;
+ Word32 fac_fx;
+ const Word16 *trigo_fx, *win_left_fx, *win_right_fx, *win2_fx;
+ Word16 trigo_dec_fx[STEREO_DFT32MS_N_MAX / 2 + 1];
+ Word16 trigo_step;
+ Word32 inputFs;
+ Word16 delay_dec;
+ Word16 mem_size;
+ Word16 ovl2;
+
+ push_wmops( "DFT_analysis" );
+
+ hStereoDft = hCPE->hStereoDft;
+
+ assert( output_frame == STEREO_DFT_NBDIV * hStereoDft->N );
+
+ /*-----------------------------------------------------------------*
+ * Initialization
+ *-----------------------------------------------------------------*/
+
+ IF( EQ_16( input_frame, output_frame ) )
+ {
+ trigo_fx = hStereoDft->dft_trigo_fx;
+ trigo_step = i_mult( hStereoDft->dft_trigo_step, STEREO_DFT_TRIGO_DEC_STEP ); /* Q0 */
+ win_right_fx = hStereoDft->win32ms_fx; /* Q15 */
+ win_left_fx = hStereoDft->win32ms_fx; /* Q15 */
+ win2_fx = hStereoDft->win232ms_fx; /* Q15 */
+
+ test();
+ IF( EQ_32( ana_type, DFT_STEREO_DEC_ANA_BPF ) )
+ {
+ assert( ( chan == 0 ) && "DFT stereo: BPF memory only FOR M channel" );
+ mem_fx = hCPE->input_mem_BPF_fx[chan]; /* Q11 */
+ }
+ ELSE IF( EQ_32( ana_type, DFT_STEREO_DEC_ANA_LB ) || EQ_32( ana_type, DFT_STEREO_DEC_ANA_LB_ADD ) )
+ {
+ mem_fx = hCPE->input_mem_LB_fx[chan]; /* Q11 */
+ }
+ ELSE
+ {
+ mem_fx = hCPE->input_mem_fx[chan]; /* Q11 */
+ }
+ }
+ ELSE IF( EQ_16( input_frame, L_FRAME ) )
+ {
+ trigo_fx = hStereoDft->dft_trigo_12k8_fx; /* Q15 */
+ trigo_step = STEREO_DFT_TRIGO_SRATE_12k8_STEP * STEREO_DFT_TRIGO_DEC_STEP;
+ move16();
+ win_right_fx = hStereoDft->win32ms_12k8_fx; /* Q15 */
+ win_left_fx = hStereoDft->win32ms_12k8_fx; /* Q15 */
+ win2_fx = hStereoDft->win232ms_12k8_fx; /* Q15 */
+
+ test();
+ IF( EQ_32( ana_type, DFT_STEREO_DEC_ANA_BPF ) )
+ {
+ assert( ( chan == 0 ) && "DFT stereo: BPF memory only FOR M channel" );
+ mem_fx = hCPE->input_mem_BPF_fx[chan]; /* Q11 */
+ }
+ ELSE IF( EQ_32( ana_type, DFT_STEREO_DEC_ANA_LB ) || EQ_32( ana_type, DFT_STEREO_DEC_ANA_LB_ADD ) )
+ {
+ mem_fx = hCPE->input_mem_LB_fx[chan]; /* Q11 */
+ }
+ ELSE
+ {
+ assert( ( chan == 1 ) && "12.8kHz sampling rate only FOR second channel, i.e. residual coding or allpass signal" );
+ mem_fx = hCPE->input_mem_fx[chan]; /* Q11 */
+ }
+ }
+ ELSE IF( EQ_16( input_frame, L_FRAME16k ) )
+ {
+ trigo_fx = hStereoDft->dft_trigo_16k_fx; /* Q15 */
+ trigo_step = STEREO_DFT_TRIGO_SRATE_16k_STEP * STEREO_DFT_TRIGO_DEC_STEP;
+ move16();
+ win_right_fx = hStereoDft->win32ms_16k_fx; /* Q15 */
+ win_left_fx = hStereoDft->win32ms_16k_fx; /* Q15 */
+ win2_fx = hStereoDft->win232ms_16k_fx; /* Q15 */
+
+ test();
+ IF( EQ_32( ana_type, DFT_STEREO_DEC_ANA_BPF ) )
+ {
+ assert( ( chan == 0 ) && "DFT stereo: BPF memory only FOR M channel" );
+ mem_fx = hCPE->input_mem_BPF_fx[chan]; /* Q11 */
+ }
+ ELSE IF( EQ_32( ana_type, DFT_STEREO_DEC_ANA_LB ) || EQ_32( ana_type, DFT_STEREO_DEC_ANA_LB_ADD ) )
+ {
+ mem_fx = hCPE->input_mem_LB_fx[chan]; /* Q11 */
+ }
+ ELSE
+ {
+ assert( ( chan == 1 ) && ( hCPE->hStereoDft->hConfig->res_pred_mode == STEREO_DFT_RESPRED_ESF ) && "16kHz sampling rate only FOR second channel with allpass signal" );
+ mem_fx = hCPE->input_mem_fx[chan]; /* Q11 */
+ }
+ }
+ ELSE IF( EQ_16( input_frame, L_FRAME8k ) )
+ {
+ assert( ( chan == 1 ) && "DFT stereo: 8kHz analysis only FOR residual coding" );
+ trigo_fx = hStereoDft->dft_trigo_8k_fx; /* Q15 */
+ trigo_step = STEREO_DFT_TRIGO_SRATE_8k_STEP * STEREO_DFT_TRIGO_DEC_STEP;
+ move16();
+ win_right_fx = hStereoDft->win32ms_8k_fx; /* Q15 */
+ win_left_fx = hStereoDft->win32ms_8k_fx; /* Q15 */
+ win2_fx = hStereoDft->win232ms_8k_fx; /* Q15 */
+ mem_fx = hCPE->input_mem_fx[chan]; /* Q11 */
+ }
+ ELSE
+ {
+ IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error in DFT stereo: sampling rate not supported" );
+ mem_fx = NULL; /* to avoid compilation warning */
+ trigo_fx = NULL; /* to avoid compilation warning */
+ trigo_step = -1; /* to avoid compilation warning */
+ move16();
+ win_right_fx = NULL; /* to avoid compilation warning */
+ win_left_fx = NULL; /* to avoid compilation warning */
+ win2_fx = NULL; /* to avoid compilation warning */
+ }
+
+ inputFs = L_mult0( input_frame, FRAMES_PER_SEC ); /* Q0 */
+ delay_dec = NS2SA_FX2( inputFs, STEREO_DFT32MS_OVL_NS );
+ move16();
+ zp = NS2SA_FX2( inputFs, STEREO_DFT32MS_ZP_NS );
+ move16();
+ ovl = NS2SA_FX2( inputFs, STEREO_DFT32MS_OVL_NS );
+ move16();
+ NFFT = NS2SA_FX2( inputFs, STEREO_DFT32MS_N_NS );
+ Word16 qfac_fx;
+ fac_fx = BASOP_Util_Divide3232_Scale_newton( hStereoDft->NFFT, NFFT, &qfac_fx ); /* qfac_fx */
+ qfac_fx = sub( 31, qfac_fx );
+ ovl2 = NS2SA_FX2( inputFs, STEREO_DFT32MS_OVL2_NS );
+ move16();
+
+ /* Offset FOR the time buffers */
+ assert( ( delay >= -NS2SA( input_frame * FRAMES_PER_SEC, STEREO_DFT_DELAY_DEC_BWE_NS + STEREO_DFT_OVL_NS / 2 ) ) && ( delay <= NS2SA( input_frame * FRAMES_PER_SEC, STEREO_DFT_OVL_NS ) ) );
+ mem_size = add( delay_dec, delay );
+
+ /* Update buffers */
+ Copy32( mem_fx, input_buff_fx, mem_size ); /* Q11 */
+ Copy32( input_fx, input_buff_fx + mem_size, input_frame ); /* q */
+ Copy32( input_buff_fx + input_frame, mem_fx, mem_size ); /* q */
+ pInput_buff_fx = input_buff_fx; /* q */
+
+ test();
+ IF( EQ_16( hCPE->nchan_out, 1 ) && ( hCPE->hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF ) )
+ {
+ pop_wmops();
+ return;
+ }
+
+
+ /*-----------------------------------------------------------------*
+ * DFT Analysis: loop over frame
+ *-----------------------------------------------------------------*/
+
+ assert( ( k_offset <= STEREO_DFT_NBDIV ) );
+
+ FOR( i = 0; i < NFFT / 4; i++ )
+ {
+ trigo_dec_fx[i] = trigo_fx[i * trigo_step];
+ move16();
+ trigo_dec_fx[NFFT / 2 - i] = trigo_fx[i * trigo_step];
+ move16();
+ }
+ trigo_dec_fx[NFFT / 4] = trigo_fx[NFFT / 4 * trigo_step];
+ move16();
+
+ FOR( k = 0; k < STEREO_DFT_NBDIV - k_offset; k++ )
+ {
+ set32_fx( DFT_fx, 0, STEREO_DFT32MS_N_MAX );
+ IF( k == 0 )
+ {
+ offset = 0;
+ move16();
+ }
+ ELSE
+ {
+ /* If OVL2 = OVL offset = 10ms */
+ offset = NS2SA_FX2( inputFs, STEREO_DFT32MS_WIN_CENTER_NS - STEREO_DFT32MS_OVL2_NS / 2 );
+ move16();
+ }
+
+ pInput_fx = pInput_buff_fx + offset; /* q */
+ pDFT_out_fx = out_DFT_fx[chan] + i_mult( k, STEREO_DFT32MS_N_MAX ); /* q_out_DFT */
+
+ /*Forwards FFT: L and R*/
+ /* Zero Padding & Flat Portion */
+ Copy32( pInput_fx, DFT_fx + zp, sub( NFFT, i_mult( 2, zp ) ) ); /* q */
+
+ /* Overlapping portions */
+ IF( k == 0 )
+ {
+ FOR( i = 0; i < ovl; i++ )
+ {
+ DFT_fx[i + zp] = Mpy_32_16_1( DFT_fx[i + zp], win_left_fx[STEREO_DFT32MS_STEP * i] ); /* q */
+ move32();
+ }
+ FOR( i = 0; i < ovl2; i++ )
+ {
+ DFT_fx[NFFT - zp - 1 - i] = Mpy_32_16_1( DFT_fx[NFFT - zp - 1 - i], win2_fx[i] ); /* q */
+ move32();
+ }
+ }
+ ELSE
+ {
+ FOR( i = 0; i < ovl2; i++ )
+ {
+ DFT_fx[i + zp] = Mpy_32_16_1( DFT_fx[i + zp], win2_fx[i] ); /* q */
+ move32();
+ }
+ FOR( i = 0; i < ovl; i++ )
+ {
+ DFT_fx[NFFT - zp - i - 1] = Mpy_32_16_1( DFT_fx[NFFT - zp - i - 1], win_right_fx[STEREO_DFT32MS_STEP * i] ); /* q */
+ move32();
+ }
+ }
+ Word16 q_DFT, q_shift, guarded_bits;
+ q_DFT = *q;
+ move16();
+ guarded_bits = find_guarded_bits_fx( NFFT );
+ q_shift = sub( L_norm_arr( DFT_fx, NFFT ), guarded_bits );
+
+ FOR( Word16 j = 0; j < NFFT; j++ )
+ {
+ DFT_fx[j] = L_shl( DFT_fx[j], q_shift ); /* q + q_shift*/
+ move32();
+ }
+
+ q_DFT = add( q_DFT, q_shift );
+
+ rfft_fx( DFT_fx, trigo_dec_fx, NFFT, -1 );
+
+ q_shift = sub( L_norm_arr( DFT_fx, NFFT ), sub( 31, qfac_fx ) );
+ FOR( Word16 j = 0; j < NFFT; j++ )
+ {
+ DFT_fx[j] = L_shl( DFT_fx[j], q_shift ); /* q + q_shift */
+ move32();
+ }
+ q_DFT = add( q_DFT, q_shift );
+ IF( sub( q_out_DFT[chan], q_DFT ) > 0 )
+ {
+ FOR( Word32 j = 0; j < NFFT; j++ )
+ {
+ out_DFT_fx[chan][j] = L_shr( out_DFT_fx[chan][j], sub( q_out_DFT[chan], q_DFT ) ); /* q_DFT */
+ move32();
+ }
+ q_out_DFT[chan] = q_DFT;
+ move16();
+ }
+ ELSE
+ {
+ FOR( Word32 j = 0; j < NFFT; j++ )
+ {
+ DFT_fx[j] = L_shr( DFT_fx[j], sub( q_DFT, q_out_DFT[chan] ) ); /* q_DFT */
+ move32();
+ }
+ q_DFT = q_out_DFT[chan];
+ move16();
+ }
+
+ /*Resampling: filtering+scaling*/
+ test();
+ test();
+ IF( ( ana_type == DFT_STEREO_DEC_ANA_FB ) || EQ_32( ana_type, DFT_STEREO_DEC_ANA_LB ) || EQ_32( ana_type, DFT_STEREO_DEC_ANA_NOCORE ) )
+ {
+ pDFT_out_fx[0] = L_shl( Mpy_32_32( DFT_fx[0], fac_fx ), sub( 31, qfac_fx ) ); /*DC*/ /* qDFT */
+ move32();
+ IF( EQ_16( NFFT, hStereoDft->NFFT ) ) /*Nyquist*/
+ {
+ pDFT_out_fx[1] = L_shl( Mpy_32_32( DFT_fx[1], fac_fx ), sub( 31, qfac_fx ) ); /* qDFT */
+ move32();
+ }
+ ELSE
+ {
+ pDFT_out_fx[1] = 0;
+ move32();
+ }
+ FOR( i = 2; i < NFFT; i++ )
+ {
+ pDFT_out_fx[i] = L_shl( Mpy_32_32( DFT_fx[i], fac_fx ), sub( 31, qfac_fx ) ); /* qDFT */
+ move32();
+ }
+ FOR( i = NFFT; i < hStereoDft->NFFT; i++ )
+ {
+ pDFT_out_fx[i] = 0; /* qDFT */
+ move32();
+ }
+ }
+ ELSE IF( EQ_32( ana_type, DFT_STEREO_DEC_ANA_BPF ) )
+ {
+ pDFT_out_fx[0] = L_sub( pDFT_out_fx[0], L_shl( Mpy_32_32( Mpy_32_32( DFT_fx[0], fac_fx ), dft_bpf_weights_fx[0] ), sub( 32, qfac_fx ) ) ); /* qDFT */
+ move32();
+
+ FOR( i = 1; i < STEREO_DFT_BPF_SIZE; i++ )
+ {
+ pDFT_out_fx[2 * i] = L_sub( pDFT_out_fx[2 * i], L_shl( Mpy_32_32( Mpy_32_32( DFT_fx[2 * i], fac_fx ), dft_bpf_weights_fx[i] ), sub( 32, qfac_fx ) ) ); /* qDFT */
+ move32();
+ pDFT_out_fx[2 * i + 1] = L_sub( pDFT_out_fx[2 * i + 1], L_shl( Mpy_32_32( Mpy_32_32( DFT_fx[2 * i + 1], fac_fx ), dft_bpf_weights_fx[i] ), sub( 32, qfac_fx ) ) ); /* qDFT */
+ move32();
+ }
+ }
+ ELSE IF( EQ_32( ana_type, DFT_STEREO_DEC_ANA_HB_ADD ) )
+ {
+ NFFT_core = NS2SA_FX2( L_mult0( hCPE->hCoreCoder[0]->L_frame, FRAMES_PER_SEC ), STEREO_DFT32MS_N_NS ); /* Q0 */
+ move16();
+
+ FOR( i = NFFT_core; i < NFFT; i++ )
+ {
+ pDFT_out_fx[i] = L_add( L_shl( Mpy_32_32( DFT_fx[i], fac_fx ), sub( 31, qfac_fx ) ), pDFT_out_fx[i] ); /* qDFT */
+ move32();
+ }
+ }
+ ELSE
+ {
+ pDFT_out_fx[0] = L_add( pDFT_out_fx[0], L_shl( Mpy_32_32( DFT_fx[0], fac_fx ), sub( 31, qfac_fx ) ) ); /*DC*/ /* qDFT */
+ move32();
+ IF( EQ_16( NFFT, hStereoDft->NFFT ) ) /*Nyquist*/
+ {
+ pDFT_out_fx[1] = L_add( L_shl( Mpy_32_32( DFT_fx[1], fac_fx ), sub( 31, qfac_fx ) ), pDFT_out_fx[1] ); /* qDFT */
+ move32();
+ }
+ FOR( i = 2; i < NFFT; i++ )
+ {
+ pDFT_out_fx[i] = L_add( L_shl( Mpy_32_32( DFT_fx[i], fac_fx ), sub( 31, qfac_fx ) ), pDFT_out_fx[i] ); /* qDFT */
+ move32();
+ }
+ }
+ }
+
+ pop_wmops();
+ return;
+}
+
+
/*-------------------------------------------------------------------------
* stereo_dft_dec_synthesize_fx()
*
diff --git a/lib_dec/ivas_stereo_switching_dec_fx.c b/lib_dec/ivas_stereo_switching_dec_fx.c
index 677c91ef02395a546bc5d4c4a0f9043174e28175..522e741e82b87d6c3b43800adab58f3b91f170a0 100644
--- a/lib_dec/ivas_stereo_switching_dec_fx.c
+++ b/lib_dec/ivas_stereo_switching_dec_fx.c
@@ -512,7 +512,7 @@ ivas_error stereo_memory_dec_fx(
/* deallocate data structure of the previous CPE mode */
IF( hCPE->hStereoDft != NULL )
{
- stereo_dft_dec_destroy( &( hCPE->hStereoDft ) );
+ stereo_dft_dec_destroy_fx( &( hCPE->hStereoDft ) );
hCPE->hStereoDft = NULL;
}
@@ -684,7 +684,7 @@ ivas_error stereo_memory_dec_fx(
/* deallocate data structure of the previous CPE mode */
IF( hCPE->hStereoDft != NULL )
{
- stereo_dft_dec_destroy( &( hCPE->hStereoDft ) );
+ stereo_dft_dec_destroy_fx( &( hCPE->hStereoDft ) );
hCPE->hStereoDft = NULL;
}
diff --git a/lib_dec/jbm_jb4_circularbuffer.c b/lib_dec/jbm_jb4_circularbuffer_fx.c
similarity index 100%
rename from lib_dec/jbm_jb4_circularbuffer.c
rename to lib_dec/jbm_jb4_circularbuffer_fx.c
diff --git a/lib_dec/jbm_jb4_inputbuffer.c b/lib_dec/jbm_jb4_inputbuffer_fx.c
similarity index 100%
rename from lib_dec/jbm_jb4_inputbuffer.c
rename to lib_dec/jbm_jb4_inputbuffer_fx.c
diff --git a/lib_dec/jbm_jb4_jmf.c b/lib_dec/jbm_jb4_jmf_fx.c
similarity index 100%
rename from lib_dec/jbm_jb4_jmf.c
rename to lib_dec/jbm_jb4_jmf_fx.c
diff --git a/lib_dec/jbm_jb4sb.c b/lib_dec/jbm_jb4sb_fx.c
similarity index 100%
rename from lib_dec/jbm_jb4sb.c
rename to lib_dec/jbm_jb4sb_fx.c
diff --git a/lib_dec/jbm_pcmdsp_apa.c b/lib_dec/jbm_pcmdsp_apa_fx.c
similarity index 100%
rename from lib_dec/jbm_pcmdsp_apa.c
rename to lib_dec/jbm_pcmdsp_apa_fx.c
diff --git a/lib_dec/jbm_pcmdsp_similarityestimation.c b/lib_dec/jbm_pcmdsp_similarityestimation_fx.c
similarity index 100%
rename from lib_dec/jbm_pcmdsp_similarityestimation.c
rename to lib_dec/jbm_pcmdsp_similarityestimation_fx.c
diff --git a/lib_dec/jbm_pcmdsp_window.c b/lib_dec/jbm_pcmdsp_window_fx.c
similarity index 100%
rename from lib_dec/jbm_pcmdsp_window.c
rename to lib_dec/jbm_pcmdsp_window_fx.c
diff --git a/lib_dec/rom_dec.c b/lib_dec/rom_dec_fx.c
similarity index 100%
rename from lib_dec/rom_dec.c
rename to lib_dec/rom_dec_fx.c
diff --git a/lib_enc/cod4t64_fast.c b/lib_enc/cod4t64_fast_fx.c
similarity index 100%
rename from lib_enc/cod4t64_fast.c
rename to lib_enc/cod4t64_fast_fx.c
diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc_fx.c
similarity index 100%
rename from lib_enc/lib_enc.c
rename to lib_enc/lib_enc_fx.c
diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c
deleted file mode 100644
index 60375ddcce113a6c5ac6236fdbd3afd55aec93e9..0000000000000000000000000000000000000000
--- a/lib_enc/lsf_msvq_ma_enc.c
+++ /dev/null
@@ -1,794 +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 "prot_fx.h"
-#include "rom_com.h"
-#include "rom_enc.h"
-#include "basop_proto_func.h"
-#include "wmc_auto.h"
-
-#ifndef swap
-#define swap( x, y, type ) \
- { \
- type u__p; \
- u__p = x; \
- x = y; \
- y = u__p; \
- }
-#endif
-
-/*--------------------------------------------------------------------------*
- * Local constants
- *--------------------------------------------------------------------------*/
-
-#define kMaxC 8
-
-/*--------------------------------------------------------------------------*
- * msvq_encmsvq_stage1_dct_search()
- *
- * stage1 search in a segmentwise truncated dct N domain without weights
- *--------------------------------------------------------------------------*/
-
-/*! r: (p_max , best candidate sofar ) */
-Word16 msvq_stage1_dct_search_fx(
- const Word32 *u_fx, /* i : target exp : u_e */
- const Word16 u_e, /* i : exp for target Q0 */
- const Word16 N, /* i : target length and IDCT synthesis length */
- const Word16 maxC_st1, /* i : number of final stage 1 candidates to provide */
- const DCTTYPE dcttype, /* e.g. DCT_T2_16_XX, DCT_T2_24_XX; */
- const Word16 max_dct_trunc, /* i : maximum of truncation lenghts */
- Word32 *invTrfMatrix_fx, /* i : IDCT synthesis matrix for dim N Q31 */
- const Word16 *midQ_truncQ_fx, /* i : midQ vector */
- const Word32 *dct_scaleF_fx, /* i : global scale factors Q10 */
- const Word16 n_segm, /* i : number of segments */
- const Word16 *cols_per_segment, /* i : remaining length per segment */
- const Word16 *trunc_dct_cols_per_segment, /* i : trunc length per segment */
- const Word16 *entries_per_segment, /* i : number of rows per segment */
- const Word16 *cum_entries_per_segment, /* i : number of cumulative entries */
- const Word8 *const W8Qx_dct_sections[], /* i : Word8(byte) segment table ptrs */
- const Word16 *col_syn_shift[], /* i : columnwise syn shift tables */
- const Word8 *segm_neighbour_fwd, /* i : circular neighbour list fwd */
- const Word8 *segm_neighbour_rev, /* i : circular neighbour list reverse */
- const Word16 npost_check, /* i : number of neigbours to check , should be even */
- Word32 *st1_mse_ptr_fx, /* i : dynRAM buffer for MSEs exp : u_e */
- Word16 *indices_st1_local, /* o : selected cand indices */
- Word32 *st1_syn_vec_ptr_fx, /* i/o: buffer for IDCT24 synthesis i :exp : u_e */
- Word32 *dist1_ptr_fx, /* o : resulting stage 1 MSEs in DCT-N domain */
- Word16 *dist1_ptr_e )
-{
- Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC]; // Q20
- Word32 u_mr_fx[FDCNG_VQ_MAX_LEN];
- Word16 dist1_ptr_e_buf[2 * LSFMBEST_MAX];
- Word64 mse_trunc_segm_fx[FDCNG_VQ_DCT_NSEGM];
- Word32 tmp_fx, check_mse;
- Word16 tmp_e, check_mse_e;
- Word64 mse_fx; /* Word64 in BASOP */
-
- Word16 p_max, c, c2, segm, j_full, j, i;
- Word16 n_ana, p_mins[2], idx_min[2];
-
- Word16 st1_mse_ptr_e[128];
-
- const Word8 *cbpW8;
- const Word16 *dct_col_shift_tab;
-
- Word32 *st1_mse_pair_fx;
- Word16 *st1_mse_pair_e;
- Word16 *st1_idx_pair;
-
- Word32 tmp2_fx;
- Word16 check_ind[FDCNG_VQ_DCT_NPOST];
- assert( ( npost_check % 2 == 0 ) && ( npost_check <= FDCNG_VQ_DCT_NPOST ) );
-
- assert( n_segm <= FDCNG_VQ_DCT_NSEGM );
-
- n_ana = N; /* VQ stage#1 core is currently always using stored DCT N coeffs */
- move16();
- assert( n_ana >= max_dct_trunc ); /* check for FDCNGVQ WB , SWB, FB operation */
-
- /* remove mid stage#1 vector, in original input domain */
- tmp_e = s_max( 12, u_e );
- FOR( i = 0; i < n_ana; i++ )
- {
- u_mr_fx[i] = L_sub( L_shl( u_fx[i], sub( u_e, tmp_e ) ), L_shl( midQ_truncQ_fx[i], sub( Q31 - Q10, tmp_e ) ) ); // tmp_e
- move32();
- }
-
- dctT2_N_apply_matrix_fx( (const Word32 *) u_mr_fx, dct_target_fx, s_min( max_dct_trunc, n_ana ), n_ana, invTrfMatrix_fx, max_dct_trunc, dcttype ); // exp : tmp_e
-
- /* init search state ptr's at the top */
- set32_fx( dist1_ptr_fx, MAX_32, maxC_st1 );
- set16_fx( dist1_ptr_e_buf, 32, maxC_st1 );
- st1_mse_pair_fx = &( dist1_ptr_fx[0] ); /* req. ptr post upd +=2 */ // st1_mse_pair_e
- st1_mse_pair_e = &( dist1_ptr_e_buf[0] ); /* req. ptr post upd +=2 */
- st1_idx_pair = &( indices_st1_local[0] ); /* req. ptr post upd +=2 */
- set64_fx( mse_trunc_segm_fx, 0, n_segm );
-
- // set16_fx( mse_trunc_segm_e, u_e, FDCNG_VQ_DCT_NSEGM );
-
- FOR( segm = 0; segm < n_segm; segm++ )
- { /* point to a new paired location for each segment */
- p_max = 0; /* req. to point to one of 1 or 0, this init can potentially be omitted here,as p_max is always 1 or 0 */
- move16();
-
- /* compute segment common trunction error in dctN domain */
-
- FOR( i = 0; i < trunc_dct_cols_per_segment[segm]; i++ )
- {
- mse_trunc_segm_fx[segm] = W_mac_32_32( mse_trunc_segm_fx[segm], dct_target_fx[cols_per_segment[segm] + i], dct_target_fx[cols_per_segment[segm] + i] ); // Q41
- move64();
- }
-
- cbpW8 = W8Qx_dct_sections[segm]; /* Word8 column variable Qx storage , table ptr init */
-
- FOR( j = 0; j < entries_per_segment[segm]; j++ )
- {
- /* unweighted segmented search DCT domain loop */
- j_full = add( j, cum_entries_per_segment[segm] ); /* or simply use j_full++ */
-
- mse_fx = mse_trunc_segm_fx[segm]; /* init mse with with common mse truncation part, in BASOP a move32() */ // Q41
- move64();
-
- dct_col_shift_tab = col_syn_shift[segm]; /* ptr init */
-
- FOR( c2 = 0; c2 < cols_per_segment[segm]; c2++ )
- {
-#define WMC_TOOL_SKIP
- tmp_fx = L_sub( dct_target_fx[c2], Mpy_32_32( L_shl( cbpW8[c2], add( sub( Q31, tmp_e ), dct_col_shift_tab[c2] ) ), dct_scaleF_fx[1] ) ); /* note: BASOP shift left defined for signed integers */
- LOGIC( 1 );
- SHIFT( 1 );
- ADD( 1 ); /* in BASOP: s_and(for W8->W16), shl(), sub()*/
-#undef WMC_TOOL_SKIP
- mse_fx = W_mac_32_32( mse_fx, tmp_fx, tmp_fx ); /* L_mac or L_mac0() square Word16 -> Word32*/ // Q41
- }
- Word16 L_tmp = W_norm( mse_fx );
- st1_mse_ptr_fx[j_full] = W_extract_h( W_lshl( mse_fx, L_tmp ) ); /* save MSE in shared dynamic RAM, move32() in BASOP */ // st1_mse_ptr_e
- move32();
- st1_mse_ptr_e[j_full] = sub( shl( tmp_e, 1 ), L_tmp );
- move16();
-
-#define WMC_TOOL_SKIP
- cbpW8 += cols_per_segment[segm]; /* fixed pointer increment for each segment */
-#undef WMC_TOOL_SKIP
-
- /* overwrite with a new worst index at p_max */
-
- /* Note: The three inner loop if's below are not 100% properly instrumented by WMC tool */
- // if ( st1_mse_ptr_fx[j_full] < st1_mse_pair_fx[p_max] ) /* L_sub */
- IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( st1_mse_ptr_fx[j_full], st1_mse_ptr_e[j_full], st1_mse_pair_fx[p_max], st1_mse_pair_e[p_max] ), -1 ) ) /* L_sub */
- {
- st1_idx_pair[p_max] = j_full; /* move16, single BASOP */
- move16();
- } /* BASOP 2 ops */
-
- IF( EQ_16( st1_idx_pair[p_max], j_full ) )
- { /* idx updated --> also update mse */
- st1_mse_pair_fx[p_max] = st1_mse_ptr_fx[j_full]; /* move32(), single BASOP */
- move32();
- st1_mse_pair_e[p_max] = st1_mse_ptr_e[j_full]; /* move32(), single BASOP */
- move16();
- } /* BASOP 3 ops */
-
- /* avoid WC costly candidate list management by always updating p_max,
- as we have only a pair in each segment to maintain */
- p_max = 0;
- move16();
- if ( EQ_16( BASOP_Util_Cmp_Mant32Exp( st1_mse_pair_fx[0], st1_mse_pair_e[0], st1_mse_pair_fx[1], st1_mse_pair_e[1] ), -1 ) ) /* L_sub()*/
- {
- p_max = 1; /* move16() */
- move16();
- } /* BASOP 3 ops ,Note 2 ops possible in BASOP with L_sub and L_lshr */
-
- /* Note: logical shift right not available in ANSI-C */
- /* p_max = (st1_mse_pair[0] - st1_mse_pair[1]) ">>>" 31; */
- /* in java logical shift right is available as >>> , in BASOP it is available as L_lshr */
-
- /* Cost: weighted sum with cond moves ('if') => 8 in float , 7 in BASOP with L_lshr */
- } /* j in section */
-
- st1_mse_pair_fx += 2; /* req. ptr init */
- st1_mse_pair_e += 2; /* req. ptr init */
- st1_idx_pair += 2; /* req. ptr init */
-
- } /* next segment */
-
- tmp_e = 0;
- move16();
- FOR( j = 0; j < maxC_st1; j++ )
- {
- /* compute_full mse using stored DCT24 domain MSE's */
- /* calculate MSE from stage1 inner using existing inner DCT domain variables */
- tmp_e = s_max( dist1_ptr_e_buf[j], tmp_e );
- }
-
- FOR( j = 0; j < maxC_st1; j++ )
- {
- /* compute_full mse using stored DCT24 domain MSE's */
- /* calculate MSE from stage1 inner using existing inner DCT domain variables */
- dist1_ptr_fx[j] = L_shr( dist1_ptr_fx[j], sub( tmp_e, dist1_ptr_e_buf[j] ) );
- move32();
- *dist1_ptr_e = tmp_e;
- move16();
- }
-
-
- assert( ( maxC_st1 >= 3 ) );
- assert( ( maxC_st1 <= 8 ) );
-
- p_max = maximum_32_fx( dist1_ptr_fx, maxC_st1, NULL ); /* establish current worst candidate for MSVQ stage#2 among all maxC_st1 candidates so far */
-
- p_mins[0] = minimum_32_fx( dist1_ptr_fx, maxC_st1, NULL ); /* find best entry among all maxC_pre */
- move16();
- tmp_fx = dist1_ptr_fx[p_mins[0]];
- move32();
- dist1_ptr_fx[p_mins[0]] = MAX_32; /* exclude 1st */
- move32();
-
- p_mins[1] = minimum_32_fx( dist1_ptr_fx, maxC_st1, NULL ); /* find 2nd best entry */
- move16();
- tmp2_fx = dist1_ptr_fx[p_mins[1]];
- move32();
- dist1_ptr_fx[p_mins[1]] = MAX_32; /* exclude 2nd */
- move32();
-
- dist1_ptr_fx[p_mins[0]] = tmp_fx; /* restore 1st */
- move32();
- dist1_ptr_fx[p_mins[1]] = tmp2_fx; /* restore 2nd */
- move32();
-
- idx_min[0] = indices_st1_local[p_mins[0]];
- move16();
- idx_min[1] = indices_st1_local[p_mins[1]];
- move16();
-
-
- /* use global exclusion list to never reselect the two (best) global MSE values sofar */
- st1_mse_ptr_fx[idx_min[0]] = MAX_32; /* move32() */
- move32();
- st1_mse_ptr_e[idx_min[0]] = MAX_16;
- move16();
- st1_mse_ptr_fx[idx_min[1]] = MAX_32; /* move32() */
- move32();
- st1_mse_ptr_e[idx_min[1]] = MAX_16;
- move16();
-
- /* circular MSE-neigbour list in use to potentially replace some segment search candidates */
- /* using both 1st and 2nd best neighbours in fwd and rev directions */
- check_ind[0] = segm_neighbour_fwd[idx_min[0]];
- move16();
- check_ind[1] = segm_neighbour_rev[idx_min[0]];
- move16();
-
- check_ind[2] = segm_neighbour_fwd[idx_min[1]];
- move16();
- check_ind[3] = segm_neighbour_rev[idx_min[1]];
- move16();
-
- check_ind[4] = segm_neighbour_fwd[check_ind[0]];
- move16();
- check_ind[5] = segm_neighbour_rev[check_ind[1]];
- move16();
-
- check_ind[6] = segm_neighbour_fwd[check_ind[2]];
- move16();
- check_ind[FDCNG_VQ_DCT_NPOST - 1] = segm_neighbour_rev[check_ind[3]];
- move16();
-
- FOR( i = 0; i < npost_check; i++ )
- {
- /* move MSE from DCT-inner loop search to input synthesis domain */
- /* multiplication by fdcng_dct_scaleF[2] to get the float outer loop scale correct in IDCT synthesis domain */
- check_mse = st1_mse_ptr_fx[check_ind[i]];
- move32();
- check_mse_e = st1_mse_ptr_e[check_ind[i]];
- move16();
-
- IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( check_mse, check_mse_e, dist1_ptr_fx[p_max], *dist1_ptr_e ), -1 ) )
- { /* new winner , replace worst */
- dist1_ptr_fx[p_max] = L_shl( check_mse, sub( check_mse_e, *dist1_ptr_e ) );
- move32();
- indices_st1_local[p_max] = check_ind[i];
- move16();
- st1_mse_ptr_fx[check_ind[i]] = MAX_32; /* exclude, BASOP: move32() */
- move32();
- st1_mse_ptr_e[check_ind[i]] = MAX_16;
- move16();
- p_max = maximum_32_fx( dist1_ptr_fx, maxC_st1, NULL ); /* establish a new current worst candidate among all maxC */
- }
- }
-
- /* extract the selected stage one vectors in DCT_N domain , apply IDCT_N and scale up */
- /* always extract full length signal(e.g. 24) to be able to update WB(e.g. N_in==21) candidate MSE values */
- /* in the case that only a part of the IDCT N vector is in final use */
-
- /* note: synthesis not yet fully parameterized/generalized for other IDCT lengths */
- assert( N == 24 );
- {
- FOR( c = 0; c < maxC_st1; c++ )
- {
- dec_FDCNG_MSVQ_stage1_fx( indices_st1_local[c], N, invTrfMatrix_fx, dcttype + 1, &( st1_syn_vec_ptr_fx[c * N] ), NULL ); // Q11 : output
- scale_sig32( &( st1_syn_vec_ptr_fx[c * N] ), N, sub( 11, s_max( u_e, 12 ) ) );
- }
- }
-
- return p_max; /*ptr to worst performing candidate */
-}
-
-
-/*--------------------------------------------------------------------------*
- * msvq_stage1_dct_recalc_candidates_fdcng_wb()
- *
- * recalc MSE for fdcng WB(0..20) coeffs ,
- essentially subtract res21^2 ,res22^2, res23^2 that was included in stage1 MSE in the DCT24 domain truncated search,
- excludes the waveform contributions at pos 21,22,23 to the MSE, important to keep the WB MSEs update for the subsequent stages
- *--------------------------------------------------------------------------*/
-
-/*! r: (updated p_max) */
-Word16 msvq_stage1_dct_recalc_candidates_fdcng_wb_fx(
- const Word32 *st1_syn_vec_ptr_fx, /* i : IDCT24 synthesis vectors st1_syn_vec_e*/
- const Word16 st1_syn_vec_e, /* i : exp for IDCT24 synthesis vectors */
- const Word32 *u_fx, /* i : target signal u_e*/
- const Word16 u_e, /* i : exp for target signal */
- const Word16 maxC_st1, /* i : number of candidates in stage1 */
- Word32 *dist_ptr_fx, /* i/o: updated MSE vector for stage1 */
- Word16 *dist_ptr_e /* i/o: exp for updated MSE vector for stage1 */
-)
-{
- Word16 i;
- Word16 p_max_local, c;
- const Word32 *p2_fx;
- Word16 tmp_e;
- Word32 res24_fx, high_diff_fx[FDCNG_VQ_MAX_LEN - FDCNG_VQ_MAX_LEN_WB];
- Word64 acc;
- Word16 res24_e[FD_CNG_maxC_37bits];
- Word16 dist_e;
-
- dist_e = *dist_ptr_e;
- move16();
- FOR( c = 0; c < maxC_st1; c++ )
- { /* point to extended synthesis part */
- p2_fx = (const Word32 *) &( st1_syn_vec_ptr_fx[c * FDCNG_VQ_MAX_LEN + FDCNG_VQ_MAX_LEN_WB] ); /* ptr init to synthesis candidate c */
- tmp_e = s_max( st1_syn_vec_e, u_e );
- tmp_e = add( tmp_e, 1 );
- /* for stage#1 use "u" instead of the shortened resid[0], to access the extended/extrapolated input target */
- FOR( i = 0; i < FDCNG_VQ_MAX_LEN - FDCNG_VQ_MAX_LEN_WB; i++ )
- {
- high_diff_fx[i] = L_sub( L_shr( p2_fx[i], sub( tmp_e, st1_syn_vec_e ) ), L_shr( u_fx[FDCNG_VQ_MAX_LEN_WB + i], sub( tmp_e, u_e ) ) ); // tmp_e
- move32();
- }
- acc = 0;
- move64();
- FOR( i = 0; i < FDCNG_VQ_MAX_LEN - FDCNG_VQ_MAX_LEN_WB; i++ )
- {
- acc = W_mac_32_32( acc, high_diff_fx[i], high_diff_fx[i] );
- }
- res24_e[c] = tmp_e;
- move16();
- tmp_e = W_norm( acc );
- res24_fx = W_extract_h( W_shl( acc, tmp_e ) );
-
- res24_e[c] = sub( shl( res24_e[c], 1 ), tmp_e );
- move16();
-
- dist_ptr_fx[c] = BASOP_Util_Add_Mant32Exp( dist_ptr_fx[c], *dist_ptr_e, L_negate( res24_fx ), res24_e[c], &res24_e[c] ); /* remove DCT24 high band error contribution */
- move32();
- dist_e = s_max( dist_e, res24_e[c] );
- move16();
- }
-
-
- FOR( c = 0; c < maxC_st1; c++ )
- {
- dist_ptr_fx[c] = L_shl( dist_ptr_fx[c], sub( res24_e[c], dist_e ) );
- move32();
- }
- *dist_ptr_e = dist_e;
- move16();
- /* finally update p_max, as it may potentially change,
- due to the core DCT24 search originally optimizing over the longer basis vectors than DCT21 */
- p_max_local = maximum_32_fx( dist_ptr_fx, maxC_st1, NULL );
-
- return p_max_local;
-}
-
-
-/*--------------------------------------------------------------------------*
- * msvq_enc()
- *
- * MSVQ encoder
- *--------------------------------------------------------------------------*/
-
-
-void msvq_enc_ivas_fx(
- const Word16 *const *cb, /* i : Codebook (indexed cb[*stages][levels][p]) Q_cb */
- const Word16 Q_cb, /* i : Codebook Q */
- const Word16 dims[], /* i : Dimension of each codebook stage (NULL: full dim.) */
- const Word16 offs[], /* i : Starting dimension of each codebook stage (NULL: 0) */
- const Word32 u_fx[], /* i : Vector to be encoded (prediction and mean removed) (exp : u_e) */
- const Word16 u_e, /* i : Exponent for Vector to be encoded */
- const Word16 *levels, /* i : Number of levels in each stage */
- const Word16 maxC, /* i : Tree search size (number of candidates kept from from one stage to the next == M-best) */
- const Word16 stages, /* i : Number of stages */
- const Word16 w[], /* i : Weights Q8 */
- const Word16 N, /* i : Vector dimension */
- const Word16 maxN, /* i : Codebook dimension */
- const Word16 applyDCT_flag, /* i : applyDCT flag */
- Word32 *invTrfMatrix_fx, /* i/o: synthesis matrix Q31 */
- Word16 Idx[] /* o : Indices */
-)
-{
- Word16 j;
- const Word16 *cbp, *cb_stage;
- Word32 resid_buf_fx[2 * LSFMBEST_MAX * M_MAX], *resid_fx[2];
- Word32 *pTmp, *p1, *p2; // pTmp_e
- Word16 pTmp_e;
- Word16 *indices[2], m, s, c, c2, p_max, i;
- Word16 idx_buf[2 * LSFMBEST_MAX * MAX_VQ_STAGES_USED], parents[LSFMBEST_MAX];
- Word32 dist_buf_fx[2 * LSFMBEST_MAX], *dist_fx[2], tmp, en, ss2, Tmp[M_MAX];
- Word16 dist_buf_e[2 * LSFMBEST_MAX], *dist_e[2];
- Word16 tmp_e, tmp_n, en_e;
- Word16 resid_e;
- Word16 n, maxn, start;
- Word64 W_acc; /*64 bit accumulator*/
-
- Word32 *st1_syn_vec_ptr_fx = &( resid_buf_fx[1 * LSFMBEST_MAX * M_MAX] ) - FDCNG_VQ_MAX_LEN * maxC;
- Word32 *st1_mse_ptr_fx = &( resid_buf_fx[1 * LSFMBEST_MAX * M_MAX] ) - ( levels[0] );
- Word16 indices_st1_local[FDCNG_VQ_DCT_NSEGM * 2];
-
- /*----------------------------------------------------------------*
- * Allocate memory for previous (parent) and current nodes.
- * Parent node is indexed [0], current node is indexed [1].
- *----------------------------------------------------------------*/
- indices[0] = idx_buf;
- indices[1] = idx_buf + maxC * stages; /*move16();*/
- /*vr_iset(0, idx_buf, 2*stages*maxC);*/
- set16_fx( idx_buf, 0, (Word16) ( 2 * stages * maxC ) );
-
- resid_fx[0] = resid_buf_fx;
- resid_fx[1] = resid_buf_fx + maxC * N; /*move16();*/
-
- dist_fx[0] = dist_buf_fx;
- dist_e[0] = dist_buf_e;
- dist_fx[1] = dist_buf_fx + maxC;
- dist_e[1] = dist_buf_e + maxC;
-
- /*vr_iset(0, parents, maxC);*/
- set16_fx( parents, 0, maxC );
-
- /*----------------------------------------------------------------*
- * LSF weights are normalized, so it is always better to multiply it first
- * Set up inital distance vector
- *----------------------------------------------------------------*/
- W_acc = W_mult_32_32( Mpy_32_16_1( u_fx[0], shl( w[0], 2 ) ), u_fx[0] ); // 2*Qu - 6 + 1
- FOR( j = 1; j < N; j++ )
- {
- W_acc = W_mac_32_32( W_acc, Mpy_32_16_1( u_fx[j], shl( w[j], 2 ) ), u_fx[j] ); // 2*Qu - 6 + 1
- }
-
- tmp_n = W_norm( W_acc );
- ss2 = W_extract_h( W_shl( W_acc, tmp_n ) );
- tmp_e = sub( add( shl( u_e, 1 ), 5 ), tmp_n );
-
- /* Set up inital error (residual) vectors */
- pTmp = resid_fx[1]; /*move16();*/
- resid_e = u_e;
- move16();
- IF( applyDCT_flag != 0 )
- {
- resid_e = s_max( u_e, 12 );
- }
- FOR( c = 0; c < maxC; c++ )
- {
- Copy32( u_fx, pTmp + c * N, N );
- test();
- IF( applyDCT_flag != 0 && LT_16( u_e, 12 ) )
- {
- scale_sig32( pTmp + c * N, N, sub( u_e, resid_e ) );
- }
- dist_fx[1][c] = ss2;
- move32();
- dist_e[1][c] = tmp_e;
- move16();
- }
-
- /* Loop over all stages */
- m = 1;
- move16();
- FOR( s = 0; s < stages; s++ )
- {
- /* codebook pointer is set to point to first stage */
- cbp = cb[s]; /*Q_cb*/
- cb_stage = cbp;
-
- /* Set up pointers to parent and current nodes */
- swap( indices[0], indices[1], Word16 * );
- move16();
- move16();
- move16();
- swap( resid_fx[0], resid_fx[1], Word32 * );
- move32();
- move32();
- move32();
- swap( dist_fx[0], dist_fx[1], Word32 * );
- swap( dist_e[0], dist_e[1], Word16 * );
- move32();
- move32();
- move32();
- move16();
- move16();
- move16();
-
- /* p_max points to maximum distortion node (worst of best) */
- p_max = 0;
- move16();
-
- n = N;
- move16();
- maxn = maxN;
- move16();
- if ( dims )
- {
- n = dims[s];
- move16();
- }
- if ( dims )
- {
- maxn = n;
- move16();
- }
-
- assert( ( maxn % 4 ) == 0 );
-
- start = 0;
- move16();
- if ( offs )
- {
- start = offs[s];
- move16();
- }
-
- set32_fx( Tmp, 0, start );
- set32_fx( Tmp + start + n, 0, sub( N, add( start, n ) ) );
-
- /* Set distortions to a large value */
- FOR( j = 0; j < maxC; j++ )
- {
- dist_fx[1][j] = MAX_32;
- move32();
- dist_e[1][j] = MAX_16 / 2;
- move16();
- }
-
- test();
- IF( !s && applyDCT_flag != 0 ) /* means: m==1 */
- {
- /* stage 1 candidates search in truncated dct24 domain without any weights */
- assert( N == FDCNG_VQ_MAX_LEN || N == FDCNG_VQ_MAX_LEN_WB ); /* 21 and 24 allowed */
- assert( maxC == 2 * FDCNG_VQ_DCT_NSEGM );
- p_max = msvq_stage1_dct_search_fx( u_fx, u_e, FDCNG_VQ_MAX_LEN, maxC, DCT_T2_24_XX, FDCNG_VQ_DCT_MAXTRUNC, (Word32 *) invTrfMatrix_fx, cdk1r_tr_midQ_truncQ_fx, fdcng_dct_scaleF_fx, FDCNG_VQ_DCT_NSEGM,
- cdk1_ivas_cols_per_segment, cdk1_ivas_trunc_dct_cols_per_segment, cdk1_ivas_entries_per_segment, cdk1_ivas_cum_entries_per_segment, cdk_37bits_ivas_stage1_W8Qx_dct_sections,
- stage1_dct_col_syn_shift, cdk1_ivas_segm_neighbour_fwd, cdk1_ivas_segm_neighbour_rev, FDCNG_VQ_DCT_NPOST, st1_mse_ptr_fx, indices_st1_local, st1_syn_vec_ptr_fx, dist_fx[1], &dist_e[1][0] );
-
- /* move established stage#1 indices to the global MSVQ list structure */
- set16_fx( dist_e[1], dist_e[1][0], maxC );
- FOR( c = 0; c < maxC; c++ )
- {
- indices[1][c * stages] = indices_st1_local[c];
- move16();
- }
- }
- ELSE
- {
- FOR( j = 0; j < levels[s]; j++ )
- {
- /* Compute weighted codebook element and its energy */
- en = 0;
- move32();
- en_e = 0;
- move16();
- W_acc = 0;
- move64();
- FOR( c2 = 0; c2 < n; c2++ )
- {
- Tmp[start + c2] = L_mult0( shl( w[start + c2], 2 ), cbp[c2] );
- move32();
- W_acc = W_mac_32_16( W_acc, Tmp[start + c2], cbp[c2] );
- }
-
- tmp_n = W_norm( W_acc );
-
- en = W_extract_h( W_shl( W_acc, tmp_n ) );
- en_e = sub( sub( 52, shl( Q_cb, 1 ) ), tmp_n );
-
- cbp += maxn; /* pointer is incremented */
-
- /* Iterate over all parent nodes */
- FOR( c = 0; c < m; c++ )
- {
- pTmp = &resid_fx[0][c * N];
- pTmp_e = resid_e;
- move16();
- /*tmp = (*pTmp++) * Tmp[0];*/
- W_acc = W_mult_32_32( pTmp[0], Tmp[0] );
-
- FOR( i = 1; i < N; i++ )
- {
- W_acc = W_mac_32_32( W_acc, pTmp[i], Tmp[i] );
- }
- tmp_n = W_norm( W_acc );
- tmp = W_extract_h( W_shl( W_acc, tmp_n ) );
- tmp_e = sub( add( pTmp_e, sub( Q31 - Q10, Q_cb ) ), tmp_n );
-
-
- tmp_n = s_max( tmp_e, en_e );
- tmp_n = s_max( dist_e[0][c], tmp_n );
-
- IF( NE_16( dist_e[0][c], MAX_16 / 2 ) )
- {
- tmp_n = add( tmp_n, 2 );
- tmp = L_sub( L_shl( en, sub( en_e, tmp_n ) ), L_shl( tmp, add( sub( tmp_e, tmp_n ), 1 ) ) );
- tmp = L_add( tmp, L_shl( dist_fx[0][c], sub( dist_e[0][c], tmp_n ) ) );
- }
- ELSE
- {
- tmp = MAX_32 - 1;
- move32();
- tmp_n = MAX_16 / 2;
- move32();
- }
-
- IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( tmp, tmp_n, dist_fx[1][p_max], dist_e[1][p_max] ), -1 ) )
- {
- /* Replace worst */
- dist_fx[1][p_max] = tmp;
- move32();
- dist_e[1][p_max] = tmp_n;
- move16();
- indices[1][p_max * stages + s] = j;
- move16();
- parents[p_max] = c;
- move16();
-
- p_max = 0;
- move16();
- tmp_e = p_max;
- move16();
-
- tmp_n = dist_e[1][0];
- move16();
- FOR( c2 = 1; c2 < maxC; c2++ )
- {
- if ( EQ_16( BASOP_Util_Cmp_Mant32Exp( dist_fx[1][c2], dist_e[1][c2], dist_fx[1][p_max], dist_e[1][p_max] ), 1 ) )
- {
- p_max = c2;
- move16();
- }
- test();
- if ( GT_16( dist_e[1][c2], tmp_n ) && NE_16( dist_e[1][c2], MAX_16 / 2 ) )
- {
- tmp_n = dist_e[1][c2];
- move16();
- }
- }
- FOR( c2 = 0; c2 < maxC; c2++ )
- {
- IF( NE_16( dist_e[1][c2], MAX_16 / 2 ) )
- {
- dist_fx[1][c2] = L_shl( dist_fx[1][c2], sub( dist_e[1][c2], tmp_n ) );
- move32();
- dist_e[1][c2] = tmp_n;
- move16();
- }
- }
- } /*IF (L_sub(tmp,dist[1][p_max]) < 0) */
- } /* FOR (c=0; c= max_dct_trunc ); /* check for FDCNGVQ WB , SWB, FB operation */
+
+ /* remove mid stage#1 vector, in original input domain */
+ tmp_e = s_max( 12, u_e );
+ FOR( i = 0; i < n_ana; i++ )
+ {
+ u_mr_fx[i] = L_sub( L_shl( u_fx[i], sub( u_e, tmp_e ) ), L_shl( midQ_truncQ_fx[i], sub( Q31 - Q10, tmp_e ) ) ); // tmp_e
+ move32();
+ }
+
+ dctT2_N_apply_matrix_fx( (const Word32 *) u_mr_fx, dct_target_fx, s_min( max_dct_trunc, n_ana ), n_ana, invTrfMatrix_fx, max_dct_trunc, dcttype ); // exp : tmp_e
+
+ /* init search state ptr's at the top */
+ set32_fx( dist1_ptr_fx, MAX_32, maxC_st1 );
+ set16_fx( dist1_ptr_e_buf, 32, maxC_st1 );
+ st1_mse_pair_fx = &( dist1_ptr_fx[0] ); /* req. ptr post upd +=2 */ // st1_mse_pair_e
+ st1_mse_pair_e = &( dist1_ptr_e_buf[0] ); /* req. ptr post upd +=2 */
+ st1_idx_pair = &( indices_st1_local[0] ); /* req. ptr post upd +=2 */
+ set64_fx( mse_trunc_segm_fx, 0, n_segm );
+
+ // set16_fx( mse_trunc_segm_e, u_e, FDCNG_VQ_DCT_NSEGM );
+
+ FOR( segm = 0; segm < n_segm; segm++ )
+ { /* point to a new paired location for each segment */
+ p_max = 0; /* req. to point to one of 1 or 0, this init can potentially be omitted here,as p_max is always 1 or 0 */
+ move16();
+
+ /* compute segment common trunction error in dctN domain */
+
+ FOR( i = 0; i < trunc_dct_cols_per_segment[segm]; i++ )
+ {
+ mse_trunc_segm_fx[segm] = W_mac_32_32( mse_trunc_segm_fx[segm], dct_target_fx[cols_per_segment[segm] + i], dct_target_fx[cols_per_segment[segm] + i] ); // Q41
+ move64();
+ }
+
+ cbpW8 = W8Qx_dct_sections[segm]; /* Word8 column variable Qx storage , table ptr init */
+
+ FOR( j = 0; j < entries_per_segment[segm]; j++ )
+ {
+ /* unweighted segmented search DCT domain loop */
+ j_full = add( j, cum_entries_per_segment[segm] ); /* or simply use j_full++ */
+
+ mse_fx = mse_trunc_segm_fx[segm]; /* init mse with with common mse truncation part, in BASOP a move32() */ // Q41
+ move64();
+
+ dct_col_shift_tab = col_syn_shift[segm]; /* ptr init */
+
+ FOR( c2 = 0; c2 < cols_per_segment[segm]; c2++ )
+ {
+#define WMC_TOOL_SKIP
+ tmp_fx = L_sub( dct_target_fx[c2], Mpy_32_32( L_shl( cbpW8[c2], add( sub( Q31, tmp_e ), dct_col_shift_tab[c2] ) ), dct_scaleF_fx[1] ) ); /* note: BASOP shift left defined for signed integers */
+ LOGIC( 1 );
+ SHIFT( 1 );
+ ADD( 1 ); /* in BASOP: s_and(for W8->W16), shl(), sub()*/
+#undef WMC_TOOL_SKIP
+ mse_fx = W_mac_32_32( mse_fx, tmp_fx, tmp_fx ); /* L_mac or L_mac0() square Word16 -> Word32*/ // Q41
+ }
+ Word16 L_tmp = W_norm( mse_fx );
+ st1_mse_ptr_fx[j_full] = W_extract_h( W_lshl( mse_fx, L_tmp ) ); /* save MSE in shared dynamic RAM, move32() in BASOP */ // st1_mse_ptr_e
+ move32();
+ st1_mse_ptr_e[j_full] = sub( shl( tmp_e, 1 ), L_tmp );
+ move16();
+
+#define WMC_TOOL_SKIP
+ cbpW8 += cols_per_segment[segm]; /* fixed pointer increment for each segment */
+#undef WMC_TOOL_SKIP
+
+ /* overwrite with a new worst index at p_max */
+
+ /* Note: The three inner loop if's below are not 100% properly instrumented by WMC tool */
+ // if ( st1_mse_ptr_fx[j_full] < st1_mse_pair_fx[p_max] ) /* L_sub */
+ IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( st1_mse_ptr_fx[j_full], st1_mse_ptr_e[j_full], st1_mse_pair_fx[p_max], st1_mse_pair_e[p_max] ), -1 ) ) /* L_sub */
+ {
+ st1_idx_pair[p_max] = j_full; /* move16, single BASOP */
+ move16();
+ } /* BASOP 2 ops */
+
+ IF( EQ_16( st1_idx_pair[p_max], j_full ) )
+ { /* idx updated --> also update mse */
+ st1_mse_pair_fx[p_max] = st1_mse_ptr_fx[j_full]; /* move32(), single BASOP */
+ move32();
+ st1_mse_pair_e[p_max] = st1_mse_ptr_e[j_full]; /* move32(), single BASOP */
+ move16();
+ } /* BASOP 3 ops */
+
+ /* avoid WC costly candidate list management by always updating p_max,
+ as we have only a pair in each segment to maintain */
+ p_max = 0;
+ move16();
+ if ( EQ_16( BASOP_Util_Cmp_Mant32Exp( st1_mse_pair_fx[0], st1_mse_pair_e[0], st1_mse_pair_fx[1], st1_mse_pair_e[1] ), -1 ) ) /* L_sub()*/
+ {
+ p_max = 1; /* move16() */
+ move16();
+ } /* BASOP 3 ops ,Note 2 ops possible in BASOP with L_sub and L_lshr */
+
+ /* Note: logical shift right not available in ANSI-C */
+ /* p_max = (st1_mse_pair[0] - st1_mse_pair[1]) ">>>" 31; */
+ /* in java logical shift right is available as >>> , in BASOP it is available as L_lshr */
+
+ /* Cost: weighted sum with cond moves ('if') => 8 in float , 7 in BASOP with L_lshr */
+ } /* j in section */
+
+ st1_mse_pair_fx += 2; /* req. ptr init */
+ st1_mse_pair_e += 2; /* req. ptr init */
+ st1_idx_pair += 2; /* req. ptr init */
+
+ } /* next segment */
+
+ tmp_e = 0;
+ move16();
+ FOR( j = 0; j < maxC_st1; j++ )
+ {
+ /* compute_full mse using stored DCT24 domain MSE's */
+ /* calculate MSE from stage1 inner using existing inner DCT domain variables */
+ tmp_e = s_max( dist1_ptr_e_buf[j], tmp_e );
+ }
+
+ FOR( j = 0; j < maxC_st1; j++ )
+ {
+ /* compute_full mse using stored DCT24 domain MSE's */
+ /* calculate MSE from stage1 inner using existing inner DCT domain variables */
+ dist1_ptr_fx[j] = L_shr( dist1_ptr_fx[j], sub( tmp_e, dist1_ptr_e_buf[j] ) );
+ move32();
+ *dist1_ptr_e = tmp_e;
+ move16();
+ }
+
+
+ assert( ( maxC_st1 >= 3 ) );
+ assert( ( maxC_st1 <= 8 ) );
+
+ p_max = maximum_32_fx( dist1_ptr_fx, maxC_st1, NULL ); /* establish current worst candidate for MSVQ stage#2 among all maxC_st1 candidates so far */
+
+ p_mins[0] = minimum_32_fx( dist1_ptr_fx, maxC_st1, NULL ); /* find best entry among all maxC_pre */
+ move16();
+ tmp_fx = dist1_ptr_fx[p_mins[0]];
+ move32();
+ dist1_ptr_fx[p_mins[0]] = MAX_32; /* exclude 1st */
+ move32();
+
+ p_mins[1] = minimum_32_fx( dist1_ptr_fx, maxC_st1, NULL ); /* find 2nd best entry */
+ move16();
+ tmp2_fx = dist1_ptr_fx[p_mins[1]];
+ move32();
+ dist1_ptr_fx[p_mins[1]] = MAX_32; /* exclude 2nd */
+ move32();
+
+ dist1_ptr_fx[p_mins[0]] = tmp_fx; /* restore 1st */
+ move32();
+ dist1_ptr_fx[p_mins[1]] = tmp2_fx; /* restore 2nd */
+ move32();
+
+ idx_min[0] = indices_st1_local[p_mins[0]];
+ move16();
+ idx_min[1] = indices_st1_local[p_mins[1]];
+ move16();
+
+
+ /* use global exclusion list to never reselect the two (best) global MSE values sofar */
+ st1_mse_ptr_fx[idx_min[0]] = MAX_32; /* move32() */
+ move32();
+ st1_mse_ptr_e[idx_min[0]] = MAX_16;
+ move16();
+ st1_mse_ptr_fx[idx_min[1]] = MAX_32; /* move32() */
+ move32();
+ st1_mse_ptr_e[idx_min[1]] = MAX_16;
+ move16();
+
+ /* circular MSE-neigbour list in use to potentially replace some segment search candidates */
+ /* using both 1st and 2nd best neighbours in fwd and rev directions */
+ check_ind[0] = segm_neighbour_fwd[idx_min[0]];
+ move16();
+ check_ind[1] = segm_neighbour_rev[idx_min[0]];
+ move16();
+
+ check_ind[2] = segm_neighbour_fwd[idx_min[1]];
+ move16();
+ check_ind[3] = segm_neighbour_rev[idx_min[1]];
+ move16();
+
+ check_ind[4] = segm_neighbour_fwd[check_ind[0]];
+ move16();
+ check_ind[5] = segm_neighbour_rev[check_ind[1]];
+ move16();
+
+ check_ind[6] = segm_neighbour_fwd[check_ind[2]];
+ move16();
+ check_ind[FDCNG_VQ_DCT_NPOST - 1] = segm_neighbour_rev[check_ind[3]];
+ move16();
+
+ FOR( i = 0; i < npost_check; i++ )
+ {
+ /* move MSE from DCT-inner loop search to input synthesis domain */
+ /* multiplication by fdcng_dct_scaleF[2] to get the float outer loop scale correct in IDCT synthesis domain */
+ check_mse = st1_mse_ptr_fx[check_ind[i]];
+ move32();
+ check_mse_e = st1_mse_ptr_e[check_ind[i]];
+ move16();
+
+ IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( check_mse, check_mse_e, dist1_ptr_fx[p_max], *dist1_ptr_e ), -1 ) )
+ { /* new winner , replace worst */
+ dist1_ptr_fx[p_max] = L_shl( check_mse, sub( check_mse_e, *dist1_ptr_e ) );
+ move32();
+ indices_st1_local[p_max] = check_ind[i];
+ move16();
+ st1_mse_ptr_fx[check_ind[i]] = MAX_32; /* exclude, BASOP: move32() */
+ move32();
+ st1_mse_ptr_e[check_ind[i]] = MAX_16;
+ move16();
+ p_max = maximum_32_fx( dist1_ptr_fx, maxC_st1, NULL ); /* establish a new current worst candidate among all maxC */
+ }
+ }
+
+ /* extract the selected stage one vectors in DCT_N domain , apply IDCT_N and scale up */
+ /* always extract full length signal(e.g. 24) to be able to update WB(e.g. N_in==21) candidate MSE values */
+ /* in the case that only a part of the IDCT N vector is in final use */
+
+ /* note: synthesis not yet fully parameterized/generalized for other IDCT lengths */
+ assert( N == 24 );
+ {
+ FOR( c = 0; c < maxC_st1; c++ )
+ {
+ dec_FDCNG_MSVQ_stage1_fx( indices_st1_local[c], N, invTrfMatrix_fx, dcttype + 1, &( st1_syn_vec_ptr_fx[c * N] ), NULL ); // Q11 : output
+ scale_sig32( &( st1_syn_vec_ptr_fx[c * N] ), N, sub( 11, s_max( u_e, 12 ) ) );
+ }
+ }
+
+ return p_max; /*ptr to worst performing candidate */
+}
+
+
+/*--------------------------------------------------------------------------*
+ * msvq_stage1_dct_recalc_candidates_fdcng_wb()
+ *
+ * recalc MSE for fdcng WB(0..20) coeffs ,
+ essentially subtract res21^2 ,res22^2, res23^2 that was included in stage1 MSE in the DCT24 domain truncated search,
+ excludes the waveform contributions at pos 21,22,23 to the MSE, important to keep the WB MSEs update for the subsequent stages
+ *--------------------------------------------------------------------------*/
+
+/*! r: (updated p_max) */
+Word16 msvq_stage1_dct_recalc_candidates_fdcng_wb_fx(
+ const Word32 *st1_syn_vec_ptr_fx, /* i : IDCT24 synthesis vectors st1_syn_vec_e*/
+ const Word16 st1_syn_vec_e, /* i : exp for IDCT24 synthesis vectors */
+ const Word32 *u_fx, /* i : target signal u_e*/
+ const Word16 u_e, /* i : exp for target signal */
+ const Word16 maxC_st1, /* i : number of candidates in stage1 */
+ Word32 *dist_ptr_fx, /* i/o: updated MSE vector for stage1 */
+ Word16 *dist_ptr_e /* i/o: exp for updated MSE vector for stage1 */
+)
+{
+ Word16 i;
+ Word16 p_max_local, c;
+ const Word32 *p2_fx;
+ Word16 tmp_e;
+ Word32 res24_fx, high_diff_fx[FDCNG_VQ_MAX_LEN - FDCNG_VQ_MAX_LEN_WB];
+ Word64 acc;
+ Word16 res24_e[FD_CNG_maxC_37bits];
+ Word16 dist_e;
+
+ dist_e = *dist_ptr_e;
+ move16();
+ FOR( c = 0; c < maxC_st1; c++ )
+ { /* point to extended synthesis part */
+ p2_fx = (const Word32 *) &( st1_syn_vec_ptr_fx[c * FDCNG_VQ_MAX_LEN + FDCNG_VQ_MAX_LEN_WB] ); /* ptr init to synthesis candidate c */
+ tmp_e = s_max( st1_syn_vec_e, u_e );
+ tmp_e = add( tmp_e, 1 );
+ /* for stage#1 use "u" instead of the shortened resid[0], to access the extended/extrapolated input target */
+ FOR( i = 0; i < FDCNG_VQ_MAX_LEN - FDCNG_VQ_MAX_LEN_WB; i++ )
+ {
+ high_diff_fx[i] = L_sub( L_shr( p2_fx[i], sub( tmp_e, st1_syn_vec_e ) ), L_shr( u_fx[FDCNG_VQ_MAX_LEN_WB + i], sub( tmp_e, u_e ) ) ); // tmp_e
+ move32();
+ }
+ acc = 0;
+ move64();
+ FOR( i = 0; i < FDCNG_VQ_MAX_LEN - FDCNG_VQ_MAX_LEN_WB; i++ )
+ {
+ acc = W_mac_32_32( acc, high_diff_fx[i], high_diff_fx[i] );
+ }
+ res24_e[c] = tmp_e;
+ move16();
+ tmp_e = W_norm( acc );
+ res24_fx = W_extract_h( W_shl( acc, tmp_e ) );
+
+ res24_e[c] = sub( shl( res24_e[c], 1 ), tmp_e );
+ move16();
+
+ dist_ptr_fx[c] = BASOP_Util_Add_Mant32Exp( dist_ptr_fx[c], *dist_ptr_e, L_negate( res24_fx ), res24_e[c], &res24_e[c] ); /* remove DCT24 high band error contribution */
+ move32();
+ dist_e = s_max( dist_e, res24_e[c] );
+ move16();
+ }
+
+
+ FOR( c = 0; c < maxC_st1; c++ )
+ {
+ dist_ptr_fx[c] = L_shl( dist_ptr_fx[c], sub( res24_e[c], dist_e ) );
+ move32();
+ }
+ *dist_ptr_e = dist_e;
+ move16();
+ /* finally update p_max, as it may potentially change,
+ due to the core DCT24 search originally optimizing over the longer basis vectors than DCT21 */
+ p_max_local = maximum_32_fx( dist_ptr_fx, maxC_st1, NULL );
+
+ return p_max_local;
+}
+
+
/*--------------------------------------------------------------------------*
* depack_mul_values_fx()
*
*--------------------------------------------------------------------------*/
+
static Word32 depack_mul_values_fx( Word16 *Tmp, const Word16 *w, const Word16 *cbp, const Word16 N )
{
Word16 i, val0, val1, val2, val3;
@@ -65,10 +440,13 @@ static Word32 depack_mul_values_fx( Word16 *Tmp, const Word16 *w, const Word16 *
return en;
}
+
+
/*--------------------------------------------------------------------------*
* depack_sub_values()
*
*--------------------------------------------------------------------------*/
+
static void depack_sub_values_fx( Word16 *pTmp, const Word16 *p1, const Word16 *cbp, const Word16 N )
{
Word16 j, val0, val1, val2, val3;
@@ -88,11 +466,14 @@ static void depack_sub_values_fx( Word16 *pTmp, const Word16 *p1, const Word16 *
move16(); /*3Q12*1.28*/
}
}
+
+
/*--------------------------------------------------------------------------*
* msvq_enc_find_p_max_8()
*
* Unroll of inner search loop for maxC == 8
*--------------------------------------------------------------------------*/
+
static Word16 msvq_enc_find_p_max_8_fx( Word32 dist[] )
{
Word16 p_max;
@@ -139,11 +520,14 @@ static Word16 msvq_enc_find_p_max_8_fx( Word32 dist[] )
BASOP_SATURATE_WARNING_ON_EVS
return p_max;
}
+
+
/*--------------------------------------------------------------------------*
* msvq_enc_find_p_max_6()
*
* Unroll of inner search loop for maxC == 6
*--------------------------------------------------------------------------*/
+
static Word16 msvq_enc_find_p_max_6_fx( Word32 dist[] )
{
Word16 p_max;
@@ -180,11 +564,14 @@ static Word16 msvq_enc_find_p_max_6_fx( Word32 dist[] )
BASOP_SATURATE_WARNING_ON_EVS
return p_max;
}
+
+
/*--------------------------------------------------------------------------*
* msvq_enc_fx()
*
* MSVQ encoder
*--------------------------------------------------------------------------*/
+
void msvq_enc_fx(
const Word16 *const *cb, /* i : Codebook (indexed cb[*stages][levels][p]) (0Q15) */
const Word16 dims[], /* i : Dimension of each codebook stage (NULL: full dim.) */
@@ -400,6 +787,449 @@ void msvq_enc_fx(
return;
}
+
+/*--------------------------------------------------------------------------*
+ * msvq_enc_ivas_fx()
+ *
+ * MSVQ encoder
+ *--------------------------------------------------------------------------*/
+
+void msvq_enc_ivas_fx(
+ const Word16 *const *cb, /* i : Codebook (indexed cb[*stages][levels][p]) Q_cb */
+ const Word16 Q_cb, /* i : Codebook Q */
+ const Word16 dims[], /* i : Dimension of each codebook stage (NULL: full dim.) */
+ const Word16 offs[], /* i : Starting dimension of each codebook stage (NULL: 0) */
+ const Word32 u_fx[], /* i : Vector to be encoded (prediction and mean removed) (exp : u_e) */
+ const Word16 u_e, /* i : Exponent for Vector to be encoded */
+ const Word16 *levels, /* i : Number of levels in each stage */
+ const Word16 maxC, /* i : Tree search size (number of candidates kept from from one stage to the next == M-best) */
+ const Word16 stages, /* i : Number of stages */
+ const Word16 w[], /* i : Weights Q8 */
+ const Word16 N, /* i : Vector dimension */
+ const Word16 maxN, /* i : Codebook dimension */
+ const Word16 applyDCT_flag, /* i : applyDCT flag */
+ Word32 *invTrfMatrix_fx, /* i/o: synthesis matrix Q31 */
+ Word16 Idx[] /* o : Indices */
+)
+{
+ Word16 j;
+ const Word16 *cbp, *cb_stage;
+ Word32 resid_buf_fx[2 * LSFMBEST_MAX * M_MAX], *resid_fx[2];
+ Word32 *pTmp, *p1, *p2; // pTmp_e
+ Word16 pTmp_e;
+ Word16 *indices[2], m, s, c, c2, p_max, i;
+ Word16 idx_buf[2 * LSFMBEST_MAX * MAX_VQ_STAGES_USED], parents[LSFMBEST_MAX];
+ Word32 dist_buf_fx[2 * LSFMBEST_MAX], *dist_fx[2], tmp, en, ss2, Tmp[M_MAX];
+ Word16 dist_buf_e[2 * LSFMBEST_MAX], *dist_e[2];
+ Word16 tmp_e, tmp_n, en_e;
+ Word16 resid_e;
+ Word16 n, maxn, start;
+ Word64 W_acc; /*64 bit accumulator*/
+
+ Word32 *st1_syn_vec_ptr_fx = &( resid_buf_fx[1 * LSFMBEST_MAX * M_MAX] ) - FDCNG_VQ_MAX_LEN * maxC;
+ Word32 *st1_mse_ptr_fx = &( resid_buf_fx[1 * LSFMBEST_MAX * M_MAX] ) - ( levels[0] );
+ Word16 indices_st1_local[FDCNG_VQ_DCT_NSEGM * 2];
+
+ /*----------------------------------------------------------------*
+ * Allocate memory for previous (parent) and current nodes.
+ * Parent node is indexed [0], current node is indexed [1].
+ *----------------------------------------------------------------*/
+ indices[0] = idx_buf;
+ indices[1] = idx_buf + maxC * stages; /*move16();*/
+ /*vr_iset(0, idx_buf, 2*stages*maxC);*/
+ set16_fx( idx_buf, 0, (Word16) ( 2 * stages * maxC ) );
+
+ resid_fx[0] = resid_buf_fx;
+ resid_fx[1] = resid_buf_fx + maxC * N; /*move16();*/
+
+ dist_fx[0] = dist_buf_fx;
+ dist_e[0] = dist_buf_e;
+ dist_fx[1] = dist_buf_fx + maxC;
+ dist_e[1] = dist_buf_e + maxC;
+
+ /*vr_iset(0, parents, maxC);*/
+ set16_fx( parents, 0, maxC );
+
+ /*----------------------------------------------------------------*
+ * LSF weights are normalized, so it is always better to multiply it first
+ * Set up inital distance vector
+ *----------------------------------------------------------------*/
+ W_acc = W_mult_32_32( Mpy_32_16_1( u_fx[0], shl( w[0], 2 ) ), u_fx[0] ); // 2*Qu - 6 + 1
+ FOR( j = 1; j < N; j++ )
+ {
+ W_acc = W_mac_32_32( W_acc, Mpy_32_16_1( u_fx[j], shl( w[j], 2 ) ), u_fx[j] ); // 2*Qu - 6 + 1
+ }
+
+ tmp_n = W_norm( W_acc );
+ ss2 = W_extract_h( W_shl( W_acc, tmp_n ) );
+ tmp_e = sub( add( shl( u_e, 1 ), 5 ), tmp_n );
+
+ /* Set up inital error (residual) vectors */
+ pTmp = resid_fx[1]; /*move16();*/
+ resid_e = u_e;
+ move16();
+ IF( applyDCT_flag != 0 )
+ {
+ resid_e = s_max( u_e, 12 );
+ }
+ FOR( c = 0; c < maxC; c++ )
+ {
+ Copy32( u_fx, pTmp + c * N, N );
+ test();
+ IF( applyDCT_flag != 0 && LT_16( u_e, 12 ) )
+ {
+ scale_sig32( pTmp + c * N, N, sub( u_e, resid_e ) );
+ }
+ dist_fx[1][c] = ss2;
+ move32();
+ dist_e[1][c] = tmp_e;
+ move16();
+ }
+
+ /* Loop over all stages */
+ m = 1;
+ move16();
+ FOR( s = 0; s < stages; s++ )
+ {
+ /* codebook pointer is set to point to first stage */
+ cbp = cb[s]; /*Q_cb*/
+ cb_stage = cbp;
+
+ /* Set up pointers to parent and current nodes */
+ swap( indices[0], indices[1], Word16 * );
+ move16();
+ move16();
+ move16();
+ swap( resid_fx[0], resid_fx[1], Word32 * );
+ move32();
+ move32();
+ move32();
+ swap( dist_fx[0], dist_fx[1], Word32 * );
+ swap( dist_e[0], dist_e[1], Word16 * );
+ move32();
+ move32();
+ move32();
+ move16();
+ move16();
+ move16();
+
+ /* p_max points to maximum distortion node (worst of best) */
+ p_max = 0;
+ move16();
+
+ n = N;
+ move16();
+ maxn = maxN;
+ move16();
+ if ( dims )
+ {
+ n = dims[s];
+ move16();
+ }
+ if ( dims )
+ {
+ maxn = n;
+ move16();
+ }
+
+ assert( ( maxn % 4 ) == 0 );
+
+ start = 0;
+ move16();
+ if ( offs )
+ {
+ start = offs[s];
+ move16();
+ }
+
+ set32_fx( Tmp, 0, start );
+ set32_fx( Tmp + start + n, 0, sub( N, add( start, n ) ) );
+
+ /* Set distortions to a large value */
+ FOR( j = 0; j < maxC; j++ )
+ {
+ dist_fx[1][j] = MAX_32;
+ move32();
+ dist_e[1][j] = MAX_16 / 2;
+ move16();
+ }
+
+ test();
+ IF( !s && applyDCT_flag != 0 ) /* means: m==1 */
+ {
+ /* stage 1 candidates search in truncated dct24 domain without any weights */
+ assert( N == FDCNG_VQ_MAX_LEN || N == FDCNG_VQ_MAX_LEN_WB ); /* 21 and 24 allowed */
+ assert( maxC == 2 * FDCNG_VQ_DCT_NSEGM );
+ p_max = msvq_stage1_dct_search_fx( u_fx, u_e, FDCNG_VQ_MAX_LEN, maxC, DCT_T2_24_XX, FDCNG_VQ_DCT_MAXTRUNC, (Word32 *) invTrfMatrix_fx, cdk1r_tr_midQ_truncQ_fx, fdcng_dct_scaleF_fx, FDCNG_VQ_DCT_NSEGM,
+ cdk1_ivas_cols_per_segment, cdk1_ivas_trunc_dct_cols_per_segment, cdk1_ivas_entries_per_segment, cdk1_ivas_cum_entries_per_segment, cdk_37bits_ivas_stage1_W8Qx_dct_sections,
+ stage1_dct_col_syn_shift, cdk1_ivas_segm_neighbour_fwd, cdk1_ivas_segm_neighbour_rev, FDCNG_VQ_DCT_NPOST, st1_mse_ptr_fx, indices_st1_local, st1_syn_vec_ptr_fx, dist_fx[1], &dist_e[1][0] );
+
+ /* move established stage#1 indices to the global MSVQ list structure */
+ set16_fx( dist_e[1], dist_e[1][0], maxC );
+ FOR( c = 0; c < maxC; c++ )
+ {
+ indices[1][c * stages] = indices_st1_local[c];
+ move16();
+ }
+ }
+ ELSE
+ {
+ FOR( j = 0; j < levels[s]; j++ )
+ {
+ /* Compute weighted codebook element and its energy */
+ en = 0;
+ move32();
+ en_e = 0;
+ move16();
+ W_acc = 0;
+ move64();
+ FOR( c2 = 0; c2 < n; c2++ )
+ {
+ Tmp[start + c2] = L_mult0( shl( w[start + c2], 2 ), cbp[c2] );
+ move32();
+ W_acc = W_mac_32_16( W_acc, Tmp[start + c2], cbp[c2] );
+ }
+
+ tmp_n = W_norm( W_acc );
+
+ en = W_extract_h( W_shl( W_acc, tmp_n ) );
+ en_e = sub( sub( 52, shl( Q_cb, 1 ) ), tmp_n );
+
+ cbp += maxn; /* pointer is incremented */
+
+ /* Iterate over all parent nodes */
+ FOR( c = 0; c < m; c++ )
+ {
+ pTmp = &resid_fx[0][c * N];
+ pTmp_e = resid_e;
+ move16();
+ /*tmp = (*pTmp++) * Tmp[0];*/
+ W_acc = W_mult_32_32( pTmp[0], Tmp[0] );
+
+ FOR( i = 1; i < N; i++ )
+ {
+ W_acc = W_mac_32_32( W_acc, pTmp[i], Tmp[i] );
+ }
+ tmp_n = W_norm( W_acc );
+ tmp = W_extract_h( W_shl( W_acc, tmp_n ) );
+ tmp_e = sub( add( pTmp_e, sub( Q31 - Q10, Q_cb ) ), tmp_n );
+
+
+ tmp_n = s_max( tmp_e, en_e );
+ tmp_n = s_max( dist_e[0][c], tmp_n );
+
+ IF( NE_16( dist_e[0][c], MAX_16 / 2 ) )
+ {
+ tmp_n = add( tmp_n, 2 );
+ tmp = L_sub( L_shl( en, sub( en_e, tmp_n ) ), L_shl( tmp, add( sub( tmp_e, tmp_n ), 1 ) ) );
+ tmp = L_add( tmp, L_shl( dist_fx[0][c], sub( dist_e[0][c], tmp_n ) ) );
+ }
+ ELSE
+ {
+ tmp = MAX_32 - 1;
+ move32();
+ tmp_n = MAX_16 / 2;
+ move32();
+ }
+
+ IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( tmp, tmp_n, dist_fx[1][p_max], dist_e[1][p_max] ), -1 ) )
+ {
+ /* Replace worst */
+ dist_fx[1][p_max] = tmp;
+ move32();
+ dist_e[1][p_max] = tmp_n;
+ move16();
+ indices[1][p_max * stages + s] = j;
+ move16();
+ parents[p_max] = c;
+ move16();
+
+ p_max = 0;
+ move16();
+ tmp_e = p_max;
+ move16();
+
+ tmp_n = dist_e[1][0];
+ move16();
+ FOR( c2 = 1; c2 < maxC; c2++ )
+ {
+ if ( EQ_16( BASOP_Util_Cmp_Mant32Exp( dist_fx[1][c2], dist_e[1][c2], dist_fx[1][p_max], dist_e[1][p_max] ), 1 ) )
+ {
+ p_max = c2;
+ move16();
+ }
+ test();
+ if ( GT_16( dist_e[1][c2], tmp_n ) && NE_16( dist_e[1][c2], MAX_16 / 2 ) )
+ {
+ tmp_n = dist_e[1][c2];
+ move16();
+ }
+ }
+ FOR( c2 = 0; c2 < maxC; c2++ )
+ {
+ IF( NE_16( dist_e[1][c2], MAX_16 / 2 ) )
+ {
+ dist_fx[1][c2] = L_shl( dist_fx[1][c2], sub( dist_e[1][c2], tmp_n ) );
+ move32();
+ dist_e[1][c2] = tmp_n;
+ move16();
+ }
+ }
+ } /*IF (L_sub(tmp,dist[1][p_max]) < 0) */
+ } /* FOR (c=0; c
-#include "options.h"
-#include "ivas_cnst.h"
-#include "prot_fx.h"
-#include "ivas_prot_rend_fx.h"
-#include "ivas_rom_com.h"
-#include "ivas_rom_com_fx.h"
-#include "wmc_auto.h"
-#include "ivas_prot_fx.h"
-/*-------------------------------------------------------------------------*
- * audioCfg2channels()
- *
- * Map Audio configuration to number of channels
- *-------------------------------------------------------------------------*/
-
-/*! r: number of audio channels */
-Word16 audioCfg2channels(
- AUDIO_CONFIG output_config /* i : output audio configuration */
-)
-{
- Word16 nchan_out;
-
- SWITCH( output_config )
- {
- case IVAS_AUDIO_CONFIG_MONO:
- nchan_out = 1;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_STEREO:
- nchan_out = 2;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_5_1:
- nchan_out = 6;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_7_1:
- nchan_out = 8;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_5_1_2:
- nchan_out = 8;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_5_1_4:
- nchan_out = 10;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_7_1_4:
- nchan_out = 12;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_FOA:
- nchan_out = 4;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_HOA2:
- nchan_out = 9;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_HOA3:
- nchan_out = 16;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_OBA:
- nchan_out = 8;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_BINAURAL:
- case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR:
- case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB:
- nchan_out = 2;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_ISM1:
- nchan_out = 1;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_ISM2:
- nchan_out = 2;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_ISM3:
- nchan_out = 3;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_ISM4:
- nchan_out = 4;
- move16();
- BREAK;
- default:
- IVAS_ERROR( IVAS_ERR_INTERNAL, "Error: illegal output configuration\n" );
- nchan_out = -1;
- move16();
- BREAK;
- }
-
- return ( nchan_out );
-}
-
-/*-------------------------------------------------------------------------*
- * ivas_output_init()
- *
- * Initialize and configure IVAS output parameters
- *-------------------------------------------------------------------------*/
-void ivas_output_init(
- IVAS_OUTPUT_SETUP *hOutSetup, /* o : IVAS output setup structure */
- const AUDIO_CONFIG output_config /* i : output audio configuration */
-)
-{
- Word16 nchan_out;
-
- /* set general default values */
- hOutSetup->output_config = output_config;
- move16();
- hOutSetup->is_loudspeaker_setup = 0;
- move16();
- hOutSetup->is_binaural_setup = 0;
- move16();
- hOutSetup->ambisonics_order = -1;
- move16();
- hOutSetup->separateChannelEnabled = 0;
- move16();
- hOutSetup->separateChannelIndex = 0;
- move16();
-
- IF( EQ_16( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
- {
- hOutSetup->is_loudspeaker_setup = 1;
- move16();
- /* set in ivas_init_decoder: */
- /* hOutSetup->ls_azimuth */
- /* hOutSetup->ls_elevation */
- /* hOutSetup->num_lfe */
- /* hOutSetup->index_lfe[0] */
- /* hOutSetup->is_planar_setup */
- }
- ELSE
- {
- /* Set default values for all other than custom LS setup */
- hOutSetup->ls_azimuth_fx = NULL;
- hOutSetup->ls_elevation_fx = NULL;
- hOutSetup->num_lfe = 0;
- move16();
- hOutSetup->index_lfe[0] = -1;
- move16();
- hOutSetup->is_planar_setup = 0;
- move16();
-
- /* set output setup specific values */
- SWITCH( output_config )
- {
- case IVAS_AUDIO_CONFIG_MONO:
- hOutSetup->is_loudspeaker_setup = 1;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_STEREO:
- hOutSetup->is_loudspeaker_setup = 1;
- move16();
- hOutSetup->ls_azimuth_fx = ls_azimuth_CICP2_fx; // Q22
- hOutSetup->ls_elevation_fx = ls_elevation_CICP2_fx; // Q22
- BREAK;
- case IVAS_AUDIO_CONFIG_FOA:
- hOutSetup->ambisonics_order = SBA_FOA_ORDER;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_HOA2:
- hOutSetup->ambisonics_order = SBA_HOA2_ORDER;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_HOA3:
- hOutSetup->ambisonics_order = SBA_HOA3_ORDER;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_5_1:
- hOutSetup->num_lfe = 1;
- move16();
- hOutSetup->index_lfe[0] = 3;
- move16();
- hOutSetup->is_loudspeaker_setup = 1;
- move16();
- hOutSetup->ls_azimuth_fx = ls_azimuth_CICP6_fx; // Q22
- hOutSetup->ls_elevation_fx = ls_elevation_CICP6_fx; // Q22
- hOutSetup->is_planar_setup = 1;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_7_1:
- hOutSetup->num_lfe = 1;
- move16();
- hOutSetup->index_lfe[0] = 3;
- move16();
- hOutSetup->is_loudspeaker_setup = 1;
- move16();
- hOutSetup->ls_azimuth_fx = ls_azimuth_CICP12_fx; // Q22
- hOutSetup->ls_elevation_fx = ls_elevation_CICP12_fx; // Q22
- hOutSetup->is_planar_setup = 1;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_5_1_2:
- hOutSetup->num_lfe = 1;
- move16();
- hOutSetup->index_lfe[0] = 3;
- move16();
- hOutSetup->is_loudspeaker_setup = 1;
- move16();
- hOutSetup->ls_azimuth_fx = ls_azimuth_CICP14_fx; // Q22
- hOutSetup->ls_elevation_fx = ls_elevation_CICP14_fx; // Q22
- hOutSetup->is_planar_setup = 0;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_5_1_4:
- hOutSetup->num_lfe = 1;
- move16();
- hOutSetup->index_lfe[0] = 3;
- move16();
- hOutSetup->is_loudspeaker_setup = 1;
- move16();
- hOutSetup->ls_azimuth_fx = ls_azimuth_CICP16_fx; // Q22
- hOutSetup->ls_elevation_fx = ls_elevation_CICP16_fx; // Q22
- hOutSetup->is_planar_setup = 0;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_7_1_4:
- hOutSetup->num_lfe = 1;
- move16();
- hOutSetup->index_lfe[0] = 3;
- move16();
- hOutSetup->is_loudspeaker_setup = 1;
- move16();
- hOutSetup->ls_azimuth_fx = ls_azimuth_CICP19_fx; // Q22
- hOutSetup->ls_elevation_fx = ls_elevation_CICP19_fx; // Q22
- hOutSetup->is_planar_setup = 0;
- move16();
- BREAK;
- case IVAS_AUDIO_CONFIG_BINAURAL:
- case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR:
- case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB:
- case IVAS_AUDIO_CONFIG_ISM1:
- case IVAS_AUDIO_CONFIG_ISM2:
- case IVAS_AUDIO_CONFIG_ISM3:
- case IVAS_AUDIO_CONFIG_ISM4:
- hOutSetup->is_binaural_setup = 1;
- move16();
- case IVAS_AUDIO_CONFIG_EXTERNAL:
- /* Default values are used */
- BREAK;
- default:
- return;
- }
- }
-
- test();
- IF( NE_16( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) && NE_16( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
- {
- nchan_out = audioCfg2channels( output_config );
- hOutSetup->nchan_out_woLFE = sub( nchan_out, hOutSetup->num_lfe );
- move16();
- }
-
- return;
-}
-
-
-/*-----------------------------------------------------------------*
- * ivas_get_nchan_buffers_dec()
- *
- * Return number of decoder audio buffers
- *-----------------------------------------------------------------*/
-
-/*! r: number of decoder buffers */
-Word16 ivas_get_nchan_buffers_dec(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
- const Word16 sba_analysis_order, /* i : SBA order evaluated in SBA decoder */
- const Word32 ivas_total_brate /* i : total IVAS bitrate */
-)
-{
- Word16 nchan_out_buff;
- AUDIO_CONFIG output_config;
-
- output_config = st_ivas->hDecoderConfig->output_config;
- move16();
-
- nchan_out_buff = MAX_OUTPUT_CHANNELS;
- move16();
-
- IF( EQ_32( st_ivas->ivas_format, MONO_FORMAT ) )
- {
- nchan_out_buff = st_ivas->hDecoderConfig->nchan_out;
- move16();
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) )
- {
- nchan_out_buff = s_max( st_ivas->hDecoderConfig->nchan_out, CPE_CHANNELS );
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) )
- {
- nchan_out_buff = st_ivas->nchan_ism;
- move16();
-
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
- {
- nchan_out_buff = s_max( nchan_out_buff, add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ) );
- }
- ELSE IF( NE_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
- {
- nchan_out_buff = s_max( audioCfg2channels( st_ivas->transport_config ), audioCfg2channels( st_ivas->intern_config ) );
- nchan_out_buff = s_max( nchan_out_buff, audioCfg2channels( output_config ) );
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) )
- {
- Word16 nchan_internal;
- nchan_internal = ivas_sba_get_nchan_metadata_fx( sba_analysis_order, ivas_total_brate );
- nchan_out_buff = st_ivas->hDecoderConfig->nchan_out;
- move16();
-
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
- {
- nchan_out_buff = s_max( nchan_out_buff, add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ) );
- }
- ELSE
- {
- nchan_out_buff = s_max( audioCfg2channels( st_ivas->transport_config ), audioCfg2channels( st_ivas->intern_config ) );
- nchan_out_buff = s_max( nchan_out_buff, audioCfg2channels( output_config ) );
- }
- nchan_out_buff = s_max( nchan_out_buff, nchan_internal );
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) )
- {
- nchan_out_buff = CPE_CHANNELS;
- move16();
-
- test();
- test();
- test();
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
- {
- nchan_out_buff = s_max( nchan_out_buff, add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ) );
- }
- ELSE IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
- {
- nchan_out_buff = shl( CPE_CHANNELS, 1 );
- }
- ELSE IF( NE_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
- {
- nchan_out_buff = s_max( nchan_out_buff, audioCfg2channels( st_ivas->intern_config ) );
- nchan_out_buff = s_max( nchan_out_buff, audioCfg2channels( output_config ) );
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
- {
- nchan_out_buff = add( st_ivas->nchan_ism, CPE_CHANNELS );
-
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
- {
- nchan_out_buff = s_max( nchan_out_buff, add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ) );
- }
- ELSE IF( NE_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
- {
- nchan_out_buff = s_max( nchan_out_buff, audioCfg2channels( st_ivas->intern_config ) );
- nchan_out_buff = s_max( nchan_out_buff, audioCfg2channels( output_config ) );
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
- {
- Word16 nchan_internal;
- nchan_internal = ivas_sba_get_nchan_metadata_fx( sba_analysis_order, ivas_total_brate );
- nchan_out_buff = add( st_ivas->nchan_ism, st_ivas->nchan_transport );
-
- IF( st_ivas->hMCT != NULL )
- {
- nchan_out_buff = shl( shr( add( nchan_out_buff, 1 ), 1 ), 1 ); /* ensure odd number of channels in MCT */
- }
-
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
- {
- nchan_out_buff = s_max( nchan_out_buff, add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ) );
- }
- ELSE IF( NE_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
- {
- nchan_out_buff = s_max( nchan_out_buff, audioCfg2channels( st_ivas->intern_config ) );
- nchan_out_buff = s_max( nchan_out_buff, audioCfg2channels( output_config ) );
-
- test();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_OSBA_AMBI ) || EQ_32( st_ivas->renderer_type, RENDERER_OSBA_LS ) )
- {
- nchan_out_buff = s_max( add( nchan_out_buff, st_ivas->nchan_ism ), audioCfg2channels( output_config ) ); /* needed for ivas_sba_upmixer_renderer() */
- }
- ELSE
- {
- nchan_out_buff = s_max( add( nchan_out_buff, st_ivas->nchan_ism ), audioCfg2channels( output_config ) ); /* needed for ivas_spar_dec_upmixer_sf() which is based on 'nchan_out' */
- }
- }
- ELSE IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
- {
- nchan_out_buff = add( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_ism ); /*take into account sba_ch_idx' in ivas_dec() */
- }
-
- test();
- IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) ) )
- {
- nchan_out_buff = s_max( nchan_out_buff, add( nchan_internal, st_ivas->nchan_ism ) );
- }
- nchan_out_buff = s_min( nchan_out_buff, MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS );
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) )
- {
- nchan_out_buff = st_ivas->hDecoderConfig->nchan_out;
-
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
- {
- nchan_out_buff = s_max( nchan_out_buff, add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ) );
- }
- ELSE
- {
- nchan_out_buff = s_max( audioCfg2channels( st_ivas->transport_config ), audioCfg2channels( st_ivas->intern_config ) );
- nchan_out_buff = s_max( nchan_out_buff, audioCfg2channels( output_config ) );
- }
- }
-
-
- return nchan_out_buff;
-}
-
-/*-------------------------------------------------------------------*
- * ivas_output_buff_dec()
- *
- * Allocate/reallocate output audio buffers
- *-------------------------------------------------------------------*/
-ivas_error ivas_output_buff_dec_fx(
- Word32 *p_output_f[], /* i/o: output audio buffers */
- const Word16 nchan_out_buff_old, /* i : previous frame number of output channels */
- const Word16 nchan_out_buff /* i : number of output channels */
-)
-{
- Word16 ch;
- IF( GT_16( nchan_out_buff, nchan_out_buff_old ) )
- {
- FOR( ch = nchan_out_buff_old; ch < nchan_out_buff; ch++ )
- {
- /* note: these are intra-frame heap memories */
- IF( ( p_output_f[ch] = (Word32 *) malloc( ( 48000 / FRAMES_PER_SEC ) * sizeof( Word32 ) ) ) == NULL ) /* note: 32000 == max internal sampling rate */
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for floating-point output audio buffer!\n" ) );
- }
- }
- }
- ELSE
- {
- FOR( ch = nchan_out_buff; ch < nchan_out_buff_old; ch++ )
- {
- free( p_output_f[ch] );
- p_output_f[ch] = NULL;
- }
- }
- return IVAS_ERR_OK;
-}
diff --git a/lib_rend/ivas_output_init_fx.c b/lib_rend/ivas_output_init_fx.c
index 3b01f62ca0af91b601d6b42e79f8426dfdd906c1..057161c7c4c366ae8b0b8a872d1fbd99af657fa6 100644
--- a/lib_rend/ivas_output_init_fx.c
+++ b/lib_rend/ivas_output_init_fx.c
@@ -1,7 +1,459 @@
+/******************************************************************************************************
-#include "ivas_prot_fx.h"
-#include "ivas_prot_rend_fx.h"
+ (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.
+
+*******************************************************************************************************/
+
+#include
#include
+#include "options.h"
+#include "ivas_cnst.h"
+#include "prot_fx.h"
+#include "ivas_prot_rend_fx.h"
+#include "ivas_rom_com.h"
+#include "ivas_rom_com_fx.h"
+#include "wmc_auto.h"
+#include "ivas_prot_fx.h"
+/*-------------------------------------------------------------------------*
+ * audioCfg2channels()
+ *
+ * Map Audio configuration to number of channels
+ *-------------------------------------------------------------------------*/
+
+/*! r: number of audio channels */
+Word16 audioCfg2channels(
+ AUDIO_CONFIG output_config /* i : output audio configuration */
+)
+{
+ Word16 nchan_out;
+
+ SWITCH( output_config )
+ {
+ case IVAS_AUDIO_CONFIG_MONO:
+ nchan_out = 1;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_STEREO:
+ nchan_out = 2;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_5_1:
+ nchan_out = 6;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_7_1:
+ nchan_out = 8;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_5_1_2:
+ nchan_out = 8;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_5_1_4:
+ nchan_out = 10;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_7_1_4:
+ nchan_out = 12;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_FOA:
+ nchan_out = 4;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_HOA2:
+ nchan_out = 9;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_HOA3:
+ nchan_out = 16;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_OBA:
+ nchan_out = 8;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_BINAURAL:
+ case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR:
+ case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB:
+ nchan_out = 2;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_ISM1:
+ nchan_out = 1;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_ISM2:
+ nchan_out = 2;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_ISM3:
+ nchan_out = 3;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_ISM4:
+ nchan_out = 4;
+ move16();
+ BREAK;
+ default:
+ IVAS_ERROR( IVAS_ERR_INTERNAL, "Error: illegal output configuration\n" );
+ nchan_out = -1;
+ move16();
+ BREAK;
+ }
+
+ return ( nchan_out );
+}
+
+/*-------------------------------------------------------------------------*
+ * ivas_output_init()
+ *
+ * Initialize and configure IVAS output parameters
+ *-------------------------------------------------------------------------*/
+void ivas_output_init(
+ IVAS_OUTPUT_SETUP *hOutSetup, /* o : IVAS output setup structure */
+ const AUDIO_CONFIG output_config /* i : output audio configuration */
+)
+{
+ Word16 nchan_out;
+
+ /* set general default values */
+ hOutSetup->output_config = output_config;
+ move16();
+ hOutSetup->is_loudspeaker_setup = 0;
+ move16();
+ hOutSetup->is_binaural_setup = 0;
+ move16();
+ hOutSetup->ambisonics_order = -1;
+ move16();
+ hOutSetup->separateChannelEnabled = 0;
+ move16();
+ hOutSetup->separateChannelIndex = 0;
+ move16();
+
+ IF( EQ_16( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
+ {
+ hOutSetup->is_loudspeaker_setup = 1;
+ move16();
+ /* set in ivas_init_decoder: */
+ /* hOutSetup->ls_azimuth */
+ /* hOutSetup->ls_elevation */
+ /* hOutSetup->num_lfe */
+ /* hOutSetup->index_lfe[0] */
+ /* hOutSetup->is_planar_setup */
+ }
+ ELSE
+ {
+ /* Set default values for all other than custom LS setup */
+ hOutSetup->ls_azimuth_fx = NULL;
+ hOutSetup->ls_elevation_fx = NULL;
+ hOutSetup->num_lfe = 0;
+ move16();
+ hOutSetup->index_lfe[0] = -1;
+ move16();
+ hOutSetup->is_planar_setup = 0;
+ move16();
+
+ /* set output setup specific values */
+ SWITCH( output_config )
+ {
+ case IVAS_AUDIO_CONFIG_MONO:
+ hOutSetup->is_loudspeaker_setup = 1;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_STEREO:
+ hOutSetup->is_loudspeaker_setup = 1;
+ move16();
+ hOutSetup->ls_azimuth_fx = ls_azimuth_CICP2_fx; // Q22
+ hOutSetup->ls_elevation_fx = ls_elevation_CICP2_fx; // Q22
+ BREAK;
+ case IVAS_AUDIO_CONFIG_FOA:
+ hOutSetup->ambisonics_order = SBA_FOA_ORDER;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_HOA2:
+ hOutSetup->ambisonics_order = SBA_HOA2_ORDER;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_HOA3:
+ hOutSetup->ambisonics_order = SBA_HOA3_ORDER;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_5_1:
+ hOutSetup->num_lfe = 1;
+ move16();
+ hOutSetup->index_lfe[0] = 3;
+ move16();
+ hOutSetup->is_loudspeaker_setup = 1;
+ move16();
+ hOutSetup->ls_azimuth_fx = ls_azimuth_CICP6_fx; // Q22
+ hOutSetup->ls_elevation_fx = ls_elevation_CICP6_fx; // Q22
+ hOutSetup->is_planar_setup = 1;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_7_1:
+ hOutSetup->num_lfe = 1;
+ move16();
+ hOutSetup->index_lfe[0] = 3;
+ move16();
+ hOutSetup->is_loudspeaker_setup = 1;
+ move16();
+ hOutSetup->ls_azimuth_fx = ls_azimuth_CICP12_fx; // Q22
+ hOutSetup->ls_elevation_fx = ls_elevation_CICP12_fx; // Q22
+ hOutSetup->is_planar_setup = 1;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_5_1_2:
+ hOutSetup->num_lfe = 1;
+ move16();
+ hOutSetup->index_lfe[0] = 3;
+ move16();
+ hOutSetup->is_loudspeaker_setup = 1;
+ move16();
+ hOutSetup->ls_azimuth_fx = ls_azimuth_CICP14_fx; // Q22
+ hOutSetup->ls_elevation_fx = ls_elevation_CICP14_fx; // Q22
+ hOutSetup->is_planar_setup = 0;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_5_1_4:
+ hOutSetup->num_lfe = 1;
+ move16();
+ hOutSetup->index_lfe[0] = 3;
+ move16();
+ hOutSetup->is_loudspeaker_setup = 1;
+ move16();
+ hOutSetup->ls_azimuth_fx = ls_azimuth_CICP16_fx; // Q22
+ hOutSetup->ls_elevation_fx = ls_elevation_CICP16_fx; // Q22
+ hOutSetup->is_planar_setup = 0;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_7_1_4:
+ hOutSetup->num_lfe = 1;
+ move16();
+ hOutSetup->index_lfe[0] = 3;
+ move16();
+ hOutSetup->is_loudspeaker_setup = 1;
+ move16();
+ hOutSetup->ls_azimuth_fx = ls_azimuth_CICP19_fx; // Q22
+ hOutSetup->ls_elevation_fx = ls_elevation_CICP19_fx; // Q22
+ hOutSetup->is_planar_setup = 0;
+ move16();
+ BREAK;
+ case IVAS_AUDIO_CONFIG_BINAURAL:
+ case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR:
+ case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB:
+ case IVAS_AUDIO_CONFIG_ISM1:
+ case IVAS_AUDIO_CONFIG_ISM2:
+ case IVAS_AUDIO_CONFIG_ISM3:
+ case IVAS_AUDIO_CONFIG_ISM4:
+ hOutSetup->is_binaural_setup = 1;
+ move16();
+ case IVAS_AUDIO_CONFIG_EXTERNAL:
+ /* Default values are used */
+ BREAK;
+ default:
+ return;
+ }
+ }
+
+ test();
+ IF( NE_16( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) && NE_16( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
+ {
+ nchan_out = audioCfg2channels( output_config );
+ hOutSetup->nchan_out_woLFE = sub( nchan_out, hOutSetup->num_lfe );
+ move16();
+ }
+
+ return;
+}
+
+
+/*-----------------------------------------------------------------*
+ * ivas_get_nchan_buffers_dec()
+ *
+ * Return number of decoder audio buffers
+ *-----------------------------------------------------------------*/
+
+/*! r: number of decoder buffers */
+Word16 ivas_get_nchan_buffers_dec(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ const Word16 sba_analysis_order, /* i : SBA order evaluated in SBA decoder */
+ const Word32 ivas_total_brate /* i : total IVAS bitrate */
+)
+{
+ Word16 nchan_out_buff;
+ AUDIO_CONFIG output_config;
+
+ output_config = st_ivas->hDecoderConfig->output_config;
+ move16();
+
+ nchan_out_buff = MAX_OUTPUT_CHANNELS;
+ move16();
+
+ IF( EQ_32( st_ivas->ivas_format, MONO_FORMAT ) )
+ {
+ nchan_out_buff = st_ivas->hDecoderConfig->nchan_out;
+ move16();
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) )
+ {
+ nchan_out_buff = s_max( st_ivas->hDecoderConfig->nchan_out, CPE_CHANNELS );
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) )
+ {
+ nchan_out_buff = st_ivas->nchan_ism;
+ move16();
+
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
+ {
+ nchan_out_buff = s_max( nchan_out_buff, add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ) );
+ }
+ ELSE IF( NE_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
+ {
+ nchan_out_buff = s_max( audioCfg2channels( st_ivas->transport_config ), audioCfg2channels( st_ivas->intern_config ) );
+ nchan_out_buff = s_max( nchan_out_buff, audioCfg2channels( output_config ) );
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) )
+ {
+ Word16 nchan_internal;
+ nchan_internal = ivas_sba_get_nchan_metadata_fx( sba_analysis_order, ivas_total_brate );
+ nchan_out_buff = st_ivas->hDecoderConfig->nchan_out;
+ move16();
+
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
+ {
+ nchan_out_buff = s_max( nchan_out_buff, add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ) );
+ }
+ ELSE
+ {
+ nchan_out_buff = s_max( audioCfg2channels( st_ivas->transport_config ), audioCfg2channels( st_ivas->intern_config ) );
+ nchan_out_buff = s_max( nchan_out_buff, audioCfg2channels( output_config ) );
+ }
+ nchan_out_buff = s_max( nchan_out_buff, nchan_internal );
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) )
+ {
+ nchan_out_buff = CPE_CHANNELS;
+ move16();
+
+ test();
+ test();
+ test();
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
+ {
+ nchan_out_buff = s_max( nchan_out_buff, add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ) );
+ }
+ ELSE IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
+ {
+ nchan_out_buff = shl( CPE_CHANNELS, 1 );
+ }
+ ELSE IF( NE_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
+ {
+ nchan_out_buff = s_max( nchan_out_buff, audioCfg2channels( st_ivas->intern_config ) );
+ nchan_out_buff = s_max( nchan_out_buff, audioCfg2channels( output_config ) );
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
+ {
+ nchan_out_buff = add( st_ivas->nchan_ism, CPE_CHANNELS );
+
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
+ {
+ nchan_out_buff = s_max( nchan_out_buff, add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ) );
+ }
+ ELSE IF( NE_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
+ {
+ nchan_out_buff = s_max( nchan_out_buff, audioCfg2channels( st_ivas->intern_config ) );
+ nchan_out_buff = s_max( nchan_out_buff, audioCfg2channels( output_config ) );
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
+ {
+ Word16 nchan_internal;
+ nchan_internal = ivas_sba_get_nchan_metadata_fx( sba_analysis_order, ivas_total_brate );
+ nchan_out_buff = add( st_ivas->nchan_ism, st_ivas->nchan_transport );
+
+ IF( st_ivas->hMCT != NULL )
+ {
+ nchan_out_buff = shl( shr( add( nchan_out_buff, 1 ), 1 ), 1 ); /* ensure odd number of channels in MCT */
+ }
+
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
+ {
+ nchan_out_buff = s_max( nchan_out_buff, add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ) );
+ }
+ ELSE IF( NE_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
+ {
+ nchan_out_buff = s_max( nchan_out_buff, audioCfg2channels( st_ivas->intern_config ) );
+ nchan_out_buff = s_max( nchan_out_buff, audioCfg2channels( output_config ) );
+
+ test();
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_OSBA_AMBI ) || EQ_32( st_ivas->renderer_type, RENDERER_OSBA_LS ) )
+ {
+ nchan_out_buff = s_max( add( nchan_out_buff, st_ivas->nchan_ism ), audioCfg2channels( output_config ) ); /* needed for ivas_sba_upmixer_renderer() */
+ }
+ ELSE
+ {
+ nchan_out_buff = s_max( add( nchan_out_buff, st_ivas->nchan_ism ), audioCfg2channels( output_config ) ); /* needed for ivas_spar_dec_upmixer_sf() which is based on 'nchan_out' */
+ }
+ }
+ ELSE IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
+ {
+ nchan_out_buff = add( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_ism ); /*take into account sba_ch_idx' in ivas_dec() */
+ }
+
+ test();
+ IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) ) )
+ {
+ nchan_out_buff = s_max( nchan_out_buff, add( nchan_internal, st_ivas->nchan_ism ) );
+ }
+ nchan_out_buff = s_min( nchan_out_buff, MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS );
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) )
+ {
+ nchan_out_buff = st_ivas->hDecoderConfig->nchan_out;
+
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
+ {
+ nchan_out_buff = s_max( nchan_out_buff, add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ) );
+ }
+ ELSE
+ {
+ nchan_out_buff = s_max( audioCfg2channels( st_ivas->transport_config ), audioCfg2channels( st_ivas->intern_config ) );
+ nchan_out_buff = s_max( nchan_out_buff, audioCfg2channels( output_config ) );
+ }
+ }
+
+
+ return nchan_out_buff;
+}
Word16 ivas_get_nchan_buffers_dec_ivas_fx(
Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
@@ -159,6 +611,42 @@ Word16 ivas_get_nchan_buffers_dec_ivas_fx(
return nchan_out_buff;
}
+
+/*-------------------------------------------------------------------*
+ * ivas_output_buff_dec()
+ *
+ * Allocate/reallocate output audio buffers
+ *-------------------------------------------------------------------*/
+ivas_error ivas_output_buff_dec_fx(
+ Word32 *p_output_f[], /* i/o: output audio buffers */
+ const Word16 nchan_out_buff_old, /* i : previous frame number of output channels */
+ const Word16 nchan_out_buff /* i : number of output channels */
+)
+{
+ Word16 ch;
+ IF( GT_16( nchan_out_buff, nchan_out_buff_old ) )
+ {
+ FOR( ch = nchan_out_buff_old; ch < nchan_out_buff; ch++ )
+ {
+ /* note: these are intra-frame heap memories */
+ IF( ( p_output_f[ch] = (Word32 *) malloc( ( 48000 / FRAMES_PER_SEC ) * sizeof( Word32 ) ) ) == NULL ) /* note: 32000 == max internal sampling rate */
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for floating-point output audio buffer!\n" ) );
+ }
+ }
+ }
+ ELSE
+ {
+ FOR( ch = nchan_out_buff; ch < nchan_out_buff_old; ch++ )
+ {
+ free( p_output_f[ch] );
+ p_output_f[ch] = NULL;
+ }
+ }
+ return IVAS_ERR_OK;
+}
+
+
/*---------------------------------------------------------------------*
* get_channel_config()
*
diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend_fx.c
similarity index 100%
rename from lib_rend/lib_rend.c
rename to lib_rend/lib_rend_fx.c