From 48f94db17c0b7d5932cd21b09799e0fd5b79f88a Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 20 May 2025 07:30:10 +0530 Subject: [PATCH] Renaming and cleanup of files --- Workspace_msvc/lib_com.vcxproj | 51 +- Workspace_msvc/lib_com.vcxproj.filters | 153 +- Workspace_msvc/lib_dec.vcxproj | 24 +- Workspace_msvc/lib_dec.vcxproj.filters | 96 +- Workspace_msvc/lib_enc.vcxproj | 7 +- Workspace_msvc/lib_enc.vcxproj.filters | 17 +- Workspace_msvc/lib_rend.vcxproj | 5 +- Workspace_msvc/lib_rend.vcxproj.filters | 11 +- lib_com/{cldfb_evs.c => cldfb_evs_fx.c} | 0 lib_com/{cldfb.c => cldfb_fx.c} | 0 ...dec_tcx_common.c => codec_tcx_common_fx.c} | 0 ...core_com_config.c => core_com_config_fx.c} | 0 lib_com/{deemph.c => deemph_fx.c} | 0 lib_com/{delay_comp.c => delay_comp_fx.c} | 0 lib_com/{enr_1_az.c => enr_1_az_fx.c} | 0 lib_com/{env_adj.c => env_adj_fx.c} | 0 lib_com/{env_stab.c => env_stab_fx.c} | 0 .../{env_stab_trans.c => env_stab_trans_fx.c} | 0 lib_com/fft.c | 366 -- lib_com/fft_fx.c | 316 +- lib_com/fft_rel.c | 878 ----- lib_com/fft_rel_fx.c | 842 +++++ .../{fill_spectrum.c => fill_spectrum_fx.c} | 0 lib_com/{findpulse.c => findpulse_fx.c} | 0 lib_com/gs_gains.c | 425 --- lib_com/gs_gains_fx.c | 528 ++- lib_com/hq2_core_com.c | 177 - lib_com/hq_conf.c | 303 -- lib_com/hq_conf_fx.c | 261 ++ lib_com/{ifft_rel.c => ifft_rel_fx.c} | 0 lib_com/{int_lsp.c => int_lsp_fx.c} | 0 ...ve_spectrum.c => interleave_spectrum_fx.c} | 0 lib_com/{interpol.c => interpol_fx.c} | 0 ...s_mcmasa_com-fx.c => ivas_mcmasa_com_fx.c} | 0 lib_com/ivas_prot_fx.h | 9 +- lib_com/{lag_wind.c => lag_wind_fx.c} | 0 lib_com/{lerp.c => lerp_fx.c} | 0 lib_com/modif_fs.c | 469 --- lib_com/modif_fs_fx.c | 432 ++- lib_com/mslvq_com.c | 208 -- lib_com/mslvq_com_fx.c | 122 + lib_com/preemph.c | 72 - lib_com/preemph_fx.c | 36 + lib_com/prot_fx.h | 44 +- ...tcx_mdct_window.c => tcx_mdct_window_fx.c} | 0 lib_com/{tec_com.c => tec_com_fx.c} | 0 lib_com/wtda.c | 219 -- lib_com/wtda_fx.c | 146 +- lib_dec/{ari_hm_dec.c => ari_hm_dec_fx.c} | 0 lib_dec/ivas_cpe_dec_fx.c | 2 +- lib_dec/ivas_init_dec.c | 3255 ----------------- lib_dec/ivas_init_dec_fx.c | 3255 +++++++++++++++++ lib_dec/{ivas_rom_dec.c => ivas_rom_dec_fx.c} | 0 ...reo_cng_dec.c => ivas_stereo_cng_dec_fx.c} | 0 lib_dec/ivas_stereo_dft_dec.c | 494 --- lib_dec/ivas_stereo_dft_dec_fx.c | 398 +- lib_dec/ivas_stereo_switching_dec_fx.c | 4 +- ...arbuffer.c => jbm_jb4_circularbuffer_fx.c} | 0 ...inputbuffer.c => jbm_jb4_inputbuffer_fx.c} | 0 lib_dec/{jbm_jb4_jmf.c => jbm_jb4_jmf_fx.c} | 0 lib_dec/{jbm_jb4sb.c => jbm_jb4sb_fx.c} | 0 .../{jbm_pcmdsp_apa.c => jbm_pcmdsp_apa_fx.c} | 0 ...c => jbm_pcmdsp_similarityestimation_fx.c} | 0 ...pcmdsp_window.c => jbm_pcmdsp_window_fx.c} | 0 lib_dec/{rom_dec.c => rom_dec_fx.c} | 0 lib_enc/{cod4t64_fast.c => cod4t64_fast_fx.c} | 0 lib_enc/{lib_enc.c => lib_enc_fx.c} | 0 lib_enc/lsf_msvq_ma_enc.c | 794 ---- lib_enc/lsf_msvq_ma_enc_fx.c | 921 ++++- lib_enc/{rom_enc.c => rom_enc_fx.c} | 0 lib_rend/ivas_output_init.c | 489 --- lib_rend/ivas_output_init_fx.c | 492 ++- lib_rend/{lib_rend.c => lib_rend_fx.c} | 0 73 files changed, 7647 insertions(+), 8674 deletions(-) rename lib_com/{cldfb_evs.c => cldfb_evs_fx.c} (100%) rename lib_com/{cldfb.c => cldfb_fx.c} (100%) rename lib_com/{codec_tcx_common.c => codec_tcx_common_fx.c} (100%) rename lib_com/{core_com_config.c => core_com_config_fx.c} (100%) rename lib_com/{deemph.c => deemph_fx.c} (100%) rename lib_com/{delay_comp.c => delay_comp_fx.c} (100%) rename lib_com/{enr_1_az.c => enr_1_az_fx.c} (100%) rename lib_com/{env_adj.c => env_adj_fx.c} (100%) rename lib_com/{env_stab.c => env_stab_fx.c} (100%) rename lib_com/{env_stab_trans.c => env_stab_trans_fx.c} (100%) delete mode 100644 lib_com/fft.c delete mode 100644 lib_com/fft_rel.c rename lib_com/{fill_spectrum.c => fill_spectrum_fx.c} (100%) rename lib_com/{findpulse.c => findpulse_fx.c} (100%) delete mode 100644 lib_com/gs_gains.c delete mode 100644 lib_com/hq2_core_com.c delete mode 100644 lib_com/hq_conf.c rename lib_com/{ifft_rel.c => ifft_rel_fx.c} (100%) rename lib_com/{int_lsp.c => int_lsp_fx.c} (100%) rename lib_com/{interleave_spectrum.c => interleave_spectrum_fx.c} (100%) rename lib_com/{interpol.c => interpol_fx.c} (100%) rename lib_com/{ivas_mcmasa_com-fx.c => ivas_mcmasa_com_fx.c} (100%) rename lib_com/{lag_wind.c => lag_wind_fx.c} (100%) rename lib_com/{lerp.c => lerp_fx.c} (100%) delete mode 100644 lib_com/modif_fs.c delete mode 100644 lib_com/mslvq_com.c delete mode 100644 lib_com/preemph.c rename lib_com/{tcx_mdct_window.c => tcx_mdct_window_fx.c} (100%) rename lib_com/{tec_com.c => tec_com_fx.c} (100%) delete mode 100644 lib_com/wtda.c rename lib_dec/{ari_hm_dec.c => ari_hm_dec_fx.c} (100%) delete mode 100644 lib_dec/ivas_init_dec.c rename lib_dec/{ivas_rom_dec.c => ivas_rom_dec_fx.c} (100%) rename lib_dec/{ivas_stereo_cng_dec.c => ivas_stereo_cng_dec_fx.c} (100%) delete mode 100644 lib_dec/ivas_stereo_dft_dec.c rename lib_dec/{jbm_jb4_circularbuffer.c => jbm_jb4_circularbuffer_fx.c} (100%) rename lib_dec/{jbm_jb4_inputbuffer.c => jbm_jb4_inputbuffer_fx.c} (100%) rename lib_dec/{jbm_jb4_jmf.c => jbm_jb4_jmf_fx.c} (100%) rename lib_dec/{jbm_jb4sb.c => jbm_jb4sb_fx.c} (100%) rename lib_dec/{jbm_pcmdsp_apa.c => jbm_pcmdsp_apa_fx.c} (100%) rename lib_dec/{jbm_pcmdsp_similarityestimation.c => jbm_pcmdsp_similarityestimation_fx.c} (100%) rename lib_dec/{jbm_pcmdsp_window.c => jbm_pcmdsp_window_fx.c} (100%) rename lib_dec/{rom_dec.c => rom_dec_fx.c} (100%) rename lib_enc/{cod4t64_fast.c => cod4t64_fast_fx.c} (100%) rename lib_enc/{lib_enc.c => lib_enc_fx.c} (100%) delete mode 100644 lib_enc/lsf_msvq_ma_enc.c rename lib_enc/{rom_enc.c => rom_enc_fx.c} (100%) delete mode 100644 lib_rend/ivas_output_init.c rename lib_rend/{lib_rend.c => lib_rend_fx.c} (100%) diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 7a2aa8a7f..91401ee2e 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 89b47a3fc..3b781aa40 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 12f77b346..1ae8c4d93 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 25079058c..170eada9a 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 86dcef905..af16efedf 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 899097163..e8f429f49 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 e47858ae3..0a00f9331 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 5c4a49011..820a5c044 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 e262f3909..000000000 --- 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 5ee509879..40c978014 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 1d020cabd..000000000 --- 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 5461ce55b..a0905cc16 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 8fa769475..000000000 --- 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 ecfe9aae0..f28af742f 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 121dae06a..000000000 --- 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 90a256cea..000000000 --- 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 f6a01adfc..b40062448 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 8b6cdcac9..928736427 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 10e64a57d..000000000 --- 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 bcbff13d5..2e39af523 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 12234a4c0..000000000 --- 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 7fcf36bfc..8d5e8adf2 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 9ebc0f72a..000000000 --- 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 0790f6c3f..b7886cb65 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 498be3137..935139e42 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 3fb408138..000000000 --- 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 e060984df..7943a87c5 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 c10c6beda..e26a56c1b 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 4770d2193..000000000 --- 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 ecd38aabe..463bc22fc 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 92ae9159c..000000000 --- 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 f1ccc1d7f..914c7fad1 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 677c91ef0..522e741e8 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 60375ddcc..000000000 --- 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 3b01f62ca..057161c7c 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 -- GitLab