diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj
index a8063b8498401f1f8f9954fbf75efe81d1425bea..144ceed2da76407275b45f89b40ec7240b71df16 100644
--- a/Workspace_msvc/lib_com.vcxproj
+++ b/Workspace_msvc/lib_com.vcxproj
@@ -261,7 +261,6 @@
-
diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters
index c33a360403d72a43643e3956c57da676d39cefc0..f9d7920ca2d85337fc08ed083b6d6eb2242def73 100644
--- a/Workspace_msvc/lib_com.vcxproj.filters
+++ b/Workspace_msvc/lib_com.vcxproj.filters
@@ -445,9 +445,6 @@
common_ivas_c
-
- common_ivas_c
-
common_ivas_c
diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj
index 94abc50aeb37d4287d726c4f49e69c126faace87..3bde19ca477629259cb331c6220c55f063e40eb1 100644
--- a/Workspace_msvc/lib_dec.vcxproj
+++ b/Workspace_msvc/lib_dec.vcxproj
@@ -327,8 +327,7 @@
-
-
+
diff --git a/Workspace_msvc/lib_dec.vcxproj.filters b/Workspace_msvc/lib_dec.vcxproj.filters
index 13ac1ed64628a7efbfa6924b8d44db15839fbf3b..155b8dfc458ebc9e0526b83aab251c90a792f1ac 100644
--- a/Workspace_msvc/lib_dec.vcxproj.filters
+++ b/Workspace_msvc/lib_dec.vcxproj.filters
@@ -527,9 +527,6 @@
dec_ivas_c
-
- dec_ivas_c
-
dec_ivas_c
@@ -539,9 +536,6 @@
dec_ivas_c
-
- dec_ivas_c
-
dec_ivas_c
@@ -584,6 +578,9 @@
dec_ivas_c
+
+ dec_ivas_c
+
diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj
index 7eb81ef8e2423ddfa7364bcea9314ab3e01a93fe..0e21d3f4a3c11d5a8d20efdca714f2e1dc74474a 100644
--- a/Workspace_msvc/lib_enc.vcxproj
+++ b/Workspace_msvc/lib_enc.vcxproj
@@ -215,8 +215,7 @@
-
-
+
diff --git a/Workspace_msvc/lib_enc.vcxproj.filters b/Workspace_msvc/lib_enc.vcxproj.filters
index 5874c4a6277819ef4fbd409eaeba58d02c1daf59..471a5f9a640c236fff4c2a4df8c28a569de7c245 100644
--- a/Workspace_msvc/lib_enc.vcxproj.filters
+++ b/Workspace_msvc/lib_enc.vcxproj.filters
@@ -575,13 +575,10 @@
enc_ivas_c
-
- enc_ivas_c
-
enc_ivas_c
-
+
enc_ivas_c
diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h
index ac4cd3fce1698012896cf5977dc7eb9c9a20e419..4bb7546b2459996f0de319b8651e7927b52fead3 100644
--- a/lib_com/ivas_prot.h
+++ b/lib_com/ivas_prot.h
@@ -182,9 +182,9 @@ ivas_error pre_proc_front_ivas(
const int16_t localVAD_HE_SAD_LR[CPE_CHANNELS], /* i : HE-SAD flag without hangover, LR channels */
float band_energies_LR[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN */
const int16_t flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz */
- const int16_t spar_front_vad_flag, /* i : front-VAD flag to overwrite VAD decision */
- const int16_t spar_force_front_vad, /* i : flag to force VAD decision */
- const int16_t spar_front_vad_dtx_flag /* i : front-VAD DTX flag to overwrite VAD decision*/
+ const int16_t front_vad_flag, /* i : front-VAD flag to overwrite VAD decision */
+ const int16_t force_front_vad, /* i : flag to force VAD decision */
+ const int16_t front_vad_dtx_flag /* i : front-VAD DTX flag to overwrite VAD decision*/
);
ivas_error pre_proc_ivas(
@@ -3827,15 +3827,6 @@ void ivas_tda( const float *pIn, float *pOut, const int16_t length );
void ivas_imdct( const float *pIn, float *pOut, const int16_t length );
void ivas_itda( const float *re, float *pOut, const int16_t length );
-/* FOA module */
-ivas_error ivas_spar_enc_process(
- Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */
- const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */
- BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */
- const int16_t front_vad_flag, /* i : front-VAD decision */
- float ppPcm_in[][L_FRAME48k] /* i/o: input/transport audio channels */
-);
-
void ivas_spar_get_cldfb_gains(
SPAR_DEC_HANDLE hSpar,
HANDLE_CLDFB_FILTER_BANK cldfbAnaDec0,
@@ -3856,18 +3847,18 @@ void ivas_spar_dec_upmixer(
const int16_t output_frame /* i : output frame length */
);
-/* FOA MD module */
+/* MD module */
ivas_error ivas_spar_md_enc_open(
- ivas_spar_md_enc_state_t **hMdEnc, /* i/o: SPAR MD encoder handle */
+ ivas_spar_md_enc_state_t **hMdEnc, /* i/o: SPAR MD encoder handle */
const ENCODER_CONFIG_HANDLE hEncoderConfig /* i : configuration structure */
);
void ivas_spar_md_enc_close(
- ivas_spar_md_enc_state_t **hMdEnc /* i/o: SPAR MD encoder handle */
+ ivas_spar_md_enc_state_t **hMdEnc /* i/o: SPAR MD encoder handle */
);
ivas_error ivas_spar_md_enc_process(
- ivas_spar_md_enc_state_t *hMdEnc, /* i/o: SPAR MD encoder handle */
+ ivas_spar_md_enc_state_t *hMdEnc, /* i/o: SPAR MD encoder handle */
const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */
ivas_spar_md_enc_in_buf_t *pIn_buf,
BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */
@@ -3931,32 +3922,27 @@ void ivas_get_spar_md_from_dirac(
);
ivas_error ivas_spar_md_dec_open(
- ivas_spar_md_dec_state_t **hMdDec_out, /* i/o: SPAR MD decoder handle */
+ ivas_spar_md_dec_state_t **hMdDec_out, /* i/o: SPAR MD decoder handle */
const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */
const int16_t num_channels /* i : number of internal channels */
);
void ivas_spar_md_dec_close(
- ivas_spar_md_dec_state_t **hMdDec /* i/o: SPAR MD decoder handle */
-);
-
-void ivas_spar_dec_MD(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
- Decoder_State *st0 /* i/o: decoder state structure - for bitstream handling*/
+ ivas_spar_md_dec_state_t **hMdDec /* i/o: SPAR MD decoder handle */
);
void ivas_spar_get_parameters(
- SPAR_DEC_HANDLE hSpar, /* i/o: SPAR FOA decoder handle */
- const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */
- const int16_t ts, /* i : time slot index */
- const int16_t num_ch_out, /* i : number of channels out */
- const int16_t num_ch_in, /* i : number of channels in */
- const int16_t num_spar_bands, /* i : number of SPAR bands */
- float par_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS] /* o : mixing matrix */
+ SPAR_DEC_HANDLE hSpar, /* i/o: SPAR decoder handle */
+ const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */
+ const int16_t ts, /* i : time slot index */
+ const int16_t num_ch_out, /* i : number of channels out */
+ const int16_t num_ch_in, /* i : number of channels in */
+ const int16_t num_spar_bands, /* i : number of SPAR bands */
+ float par_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS] /* o : mixing matrix */
);
ivas_error ivas_spar_md_dec_init(
- ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */
+ ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */
const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */
const int16_t num_channels /* i : number of internal channels */
);
@@ -3970,27 +3956,27 @@ void ivas_spar_md_dec_process(
void ivas_spar_to_dirac(
Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
- ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */
+ ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */
const int16_t dtx_vad, /* i : DTX frame flag */
const int16_t num_bands_out /* i : number of output bands */
);
void ivas_spar_update_md_hist(
- ivas_spar_md_dec_state_t *hMdDec /* i/o: SPAR MD decoder handle */
+ ivas_spar_md_dec_state_t *hMdDec /* i/o: SPAR MD decoder handle */
);
void ivas_spar_smooth_md_dtx(
- ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */
+ ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */
const int16_t num_bands_out /* i : number of output bands */
);
void ivas_spar_setup_md_smoothing(
- ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */
+ ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */
const int16_t num_bands_out /* i : number of output bands */
);
void ivas_spar_dec_gen_umx_mat(
- ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */
+ ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */
const int16_t nchan_transport, /* i : number of transport channels */
const int16_t num_bands_out, /* i : number of output bands */
const int16_t bfi /* i : bad frame indicator */
diff --git a/lib_com/ivas_spar_com.c b/lib_com/ivas_spar_com.c
index 93dd07bdd147163327bb86405cc53d450584134a..baf63f6e35ae84a9d6408289b9b8eacc40453048 100644
--- a/lib_com/ivas_spar_com.c
+++ b/lib_com/ivas_spar_com.c
@@ -2088,3 +2088,183 @@ int16_t ivas_get_bits_to_encode(
return bits_req;
}
+
+
+/*-----------------------------------------------------------------------------------------*
+ * Function ivas_spar_set_bitrate_config()
+ *
+ * Set SPAR bitrate config
+ *-----------------------------------------------------------------------------------------*/
+
+void ivas_spar_set_bitrate_config(
+ ivas_spar_md_com_cfg *pSpar_md_cfg, /* i/o: SPAR MD config. handle */
+ const int16_t table_idx, /* i : config. table index */
+ const int16_t num_bands /* i : number of bands */
+)
+{
+ int32_t ivas_total_brate;
+ int16_t i, total_bits, max_bits, code, length;
+ int16_t sba_order;
+ int16_t md_coding_bits_header;
+ pSpar_md_cfg->nchan_transport = ivas_spar_br_table_consts[table_idx].nchan_transport;
+
+ for ( i = 0; i < pSpar_md_cfg->nchan_transport; i++ )
+ {
+ pSpar_md_cfg->max_freq_per_chan[i] = ivas_spar_br_table_consts[table_idx].fpcs;
+ }
+
+ pSpar_md_cfg->active_w = ivas_spar_br_table_consts[table_idx].active_w;
+ pSpar_md_cfg->agc_bits_ch_idx = ivas_spar_br_table_consts[table_idx].agc_bits_ch_idx;
+ ivas_spar_get_uniform_quant_strat( pSpar_md_cfg, table_idx );
+
+ if ( pSpar_md_cfg->quant_strat->C.q_levels[0] == 0 || pSpar_md_cfg->quant_strat->C.q_levels[1] == 0 || pSpar_md_cfg->quant_strat->PR.q_levels[0] == 0 || pSpar_md_cfg->quant_strat->PR.q_levels[1] == 0 || pSpar_md_cfg->quant_strat->P_c.q_levels[0] == 0 || pSpar_md_cfg->quant_strat->P_c.q_levels[1] == 0 || pSpar_md_cfg->quant_strat->P_r.q_levels[0] == 0 || pSpar_md_cfg->quant_strat->P_r.q_levels[1] == 0 )
+ {
+ pSpar_md_cfg->gen_bs = 0;
+ }
+ else
+ {
+ if ( 0 != pSpar_md_cfg->gen_bs )
+ {
+ pSpar_md_cfg->quant_strat_bits = ivas_get_bits_to_encode( MAX_QUANT_STRATS );
+ }
+ }
+
+ /* BLOCK: getEntropyCoderModels */
+
+ pSpar_md_cfg->remix_unmix_order = ivas_spar_br_table_consts[table_idx].dmx_str;
+
+ /* bits per block*/
+ total_bits = 0;
+ max_bits = 0;
+
+ ivas_total_brate = ivas_spar_br_table_consts[table_idx].ivas_total_brate;
+ sba_order = ivas_spar_br_table_consts[table_idx].sba_order;
+ ivas_get_spar_table_idx( ivas_total_brate, sba_order, ivas_spar_br_table_consts[table_idx].bwidth, &code, &length );
+
+ for ( i = 0; i < pSpar_md_cfg->nchan_transport; i++ )
+ {
+ total_bits += ( int16_t )( ivas_spar_br_table_consts[table_idx].evs_brs[i][0] / FRAMES_PER_SEC );
+ max_bits += ( int16_t )( ivas_spar_br_table_consts[table_idx].evs_brs[i][1] / FRAMES_PER_SEC );
+ }
+ if ( ivas_total_brate >= IVAS_256k )
+ {
+ pSpar_md_cfg->tgt_bits_per_blk = ( int16_t )( ivas_total_brate / FRAMES_PER_SEC ) - IVAS_FORMAT_SIGNALING_NBITS_SBA - SBA_PLANAR_BITS - SBA_ORDER_BITS - length - total_bits;
+
+ pSpar_md_cfg->max_bits_per_blk = ( int16_t )( ivas_total_brate / FRAMES_PER_SEC ) - IVAS_FORMAT_SIGNALING_NBITS_SBA - SBA_PLANAR_BITS - SBA_ORDER_BITS - length - max_bits;
+
+ // TODO : do this for lower bitrates as well once order/planar bits are added
+ md_coding_bits_header = SPAR_NUM_CODING_STRAT_BITS + pSpar_md_cfg->quant_strat_bits;
+ pSpar_md_cfg->tgt_bits_per_blk -= md_coding_bits_header;
+ pSpar_md_cfg->max_bits_per_blk -= md_coding_bits_header;
+
+ pSpar_md_cfg->tgt_bits_per_blk = (int16_t) ceilf( ( 1.0f * pSpar_md_cfg->tgt_bits_per_blk * num_bands ) / IVAS_MAX_NUM_BANDS );
+ pSpar_md_cfg->max_bits_per_blk = (int16_t) ceilf( ( 1.0f * pSpar_md_cfg->max_bits_per_blk * num_bands ) / IVAS_MAX_NUM_BANDS );
+
+ pSpar_md_cfg->tgt_bits_per_blk += md_coding_bits_header;
+ pSpar_md_cfg->max_bits_per_blk += md_coding_bits_header;
+ }
+ else
+ {
+ pSpar_md_cfg->tgt_bits_per_blk = ( int16_t )( ivas_total_brate / FRAMES_PER_SEC ) - IVAS_FORMAT_SIGNALING_NBITS_SBA - length - total_bits;
+
+ pSpar_md_cfg->max_bits_per_blk = ( int16_t )( ivas_total_brate / FRAMES_PER_SEC ) - IVAS_FORMAT_SIGNALING_NBITS_SBA - length - max_bits;
+
+ pSpar_md_cfg->tgt_bits_per_blk = (int16_t) ceilf( ( 1.0f * pSpar_md_cfg->tgt_bits_per_blk * num_bands ) / IVAS_MAX_NUM_BANDS );
+ pSpar_md_cfg->max_bits_per_blk = (int16_t) ceilf( ( 1.0f * pSpar_md_cfg->max_bits_per_blk * num_bands ) / IVAS_MAX_NUM_BANDS );
+ }
+
+ return;
+}
+
+#ifdef FIX_I1_113
+/*-----------------------------------------------------------------------------------------*
+ * Function ivas_spar_bitrate_dist()
+ *
+ * Set SPAR bitrate distribution
+ *-----------------------------------------------------------------------------------------*/
+
+// this function is not currently used but it is kept for future use
+void ivas_spar_bitrate_dist(
+ int32_t core_brates_act[], /* o : bitrates per core-coder */
+ const int16_t nAvailBits, /* i : number of available bits */
+ const int32_t ivas_total_brate, /* i : IVAS total bitrate */
+ const int16_t sba_order, /* i : Ambisonic (SBA) order */
+ const int16_t bwidth /* i : audio bandwidth */
+)
+{
+ int16_t i, nchan_transport, table_idx, bitlen;
+ int16_t core_bits_act[FOA_CHANNELS], core_range_bits[FOA_CHANNELS];
+ int16_t sum_core_act_bits, residual_bits, overflow_bits;
+
+ table_idx = ivas_get_spar_table_idx( ivas_total_brate, sba_order, bwidth, &bitlen, NULL );
+
+ nchan_transport = ivas_spar_br_table_consts[table_idx].nchan_transport;
+
+ sum_core_act_bits = 0;
+ for ( i = 0; i < nchan_transport; i++ )
+ {
+ core_bits_act[i] = ( int16_t )( ivas_spar_br_table_consts[table_idx].evs_brs[i][0] / FRAMES_PER_SEC );
+
+ sum_core_act_bits += core_bits_act[i];
+ }
+
+ residual_bits = nAvailBits - sum_core_act_bits;
+
+ /* First compute core-coder bits as per bitrate distribution table and MD bitrate*/
+ if ( residual_bits > 0 )
+ {
+ for ( i = 0; i < nchan_transport; i++ )
+ {
+ core_range_bits[i] = ( int16_t )( ( ivas_spar_br_table_consts[table_idx].evs_brs[i][2] - ivas_spar_br_table_consts[table_idx].evs_brs[i][0] ) / FRAMES_PER_SEC );
+ core_bits_act[i] += min( residual_bits, core_range_bits[i] );
+ residual_bits -= core_range_bits[i];
+
+ if ( residual_bits <= 0 )
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ for ( i = 0; i < nchan_transport; i++ )
+ {
+ core_range_bits[i] = ( int16_t )( ( ivas_spar_br_table_consts[table_idx].evs_brs[i][0] - ivas_spar_br_table_consts[table_idx].evs_brs[i][1] ) / FRAMES_PER_SEC );
+ }
+
+ overflow_bits = -residual_bits;
+
+ for ( i = 0; i < nchan_transport; i++ )
+ {
+ core_bits_act[nchan_transport - 1 - i] -= min( overflow_bits, core_range_bits[nchan_transport - 1 - i] );
+ overflow_bits -= core_range_bits[nchan_transport - 1 - i];
+
+ if ( overflow_bits <= 0 )
+ {
+ break;
+ }
+ }
+
+ if ( overflow_bits > 0 )
+ {
+ int16_t overflow_bits_ch;
+ overflow_bits_ch = overflow_bits / nchan_transport;
+
+ for ( i = 0; i < nchan_transport; i++ )
+ {
+ core_bits_act[i] -= overflow_bits_ch;
+ overflow_bits -= overflow_bits_ch;
+ }
+
+ core_bits_act[nchan_transport - 1] -= max( 0, overflow_bits );
+ }
+ }
+
+ for ( i = 0; i < nchan_transport; i++ )
+ {
+ core_brates_act[i] = core_bits_act[i] * FRAMES_PER_SEC;
+ }
+
+ return;
+}
+#endif
diff --git a/lib_com/ivas_spar_foa_br_dist.c b/lib_com/ivas_spar_foa_br_dist.c
deleted file mode 100644
index 5bbb771848dab776dc3112c58fb690b7d3a0bab7..0000000000000000000000000000000000000000
--- a/lib_com/ivas_spar_foa_br_dist.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/******************************************************************************************************
-
- (C) 2022 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 "math.h"
-#include "options.h"
-#ifdef DEBUGGING
-#include "debug.h"
-#endif
-#include "prot.h"
-#include "ivas_prot.h"
-#include "ivas_rom_com.h"
-#include "ivas_stat_com.h"
-#include
-#include "wmops.h"
-
-
-/*-----------------------------------------------------------------------------------------*
- * Function ivas_spar_set_bitrate_config()
- *
- * Set SPAR bitrate config
- *-----------------------------------------------------------------------------------------*/
-
-void ivas_spar_set_bitrate_config(
- ivas_spar_md_com_cfg *pSpar_md_cfg, /* i/o: SPAR MD config. handle */
- const int16_t table_idx, /* i : config. table index */
- const int16_t num_bands /* i : number of bands */
-)
-{
- int32_t ivas_total_brate;
- int16_t i, total_bits, max_bits, code, length;
- int16_t sba_order;
- int16_t md_coding_bits_header;
- pSpar_md_cfg->nchan_transport = ivas_spar_br_table_consts[table_idx].nchan_transport;
-
- for ( i = 0; i < pSpar_md_cfg->nchan_transport; i++ )
- {
- pSpar_md_cfg->max_freq_per_chan[i] = ivas_spar_br_table_consts[table_idx].fpcs;
- }
-
- pSpar_md_cfg->active_w = ivas_spar_br_table_consts[table_idx].active_w;
- pSpar_md_cfg->agc_bits_ch_idx = ivas_spar_br_table_consts[table_idx].agc_bits_ch_idx;
- ivas_spar_get_uniform_quant_strat( pSpar_md_cfg, table_idx );
-
- if ( pSpar_md_cfg->quant_strat->C.q_levels[0] == 0 || pSpar_md_cfg->quant_strat->C.q_levels[1] == 0 || pSpar_md_cfg->quant_strat->PR.q_levels[0] == 0 || pSpar_md_cfg->quant_strat->PR.q_levels[1] == 0 || pSpar_md_cfg->quant_strat->P_c.q_levels[0] == 0 || pSpar_md_cfg->quant_strat->P_c.q_levels[1] == 0 || pSpar_md_cfg->quant_strat->P_r.q_levels[0] == 0 || pSpar_md_cfg->quant_strat->P_r.q_levels[1] == 0 )
- {
- pSpar_md_cfg->gen_bs = 0;
- }
- else
- {
- if ( 0 != pSpar_md_cfg->gen_bs )
- {
- pSpar_md_cfg->quant_strat_bits = ivas_get_bits_to_encode( MAX_QUANT_STRATS );
- }
- }
-
- /* BLOCK: getEntropyCoderModels */
-
- pSpar_md_cfg->remix_unmix_order = ivas_spar_br_table_consts[table_idx].dmx_str;
-
- /* bits per block*/
- total_bits = 0;
- max_bits = 0;
-
- ivas_total_brate = ivas_spar_br_table_consts[table_idx].ivas_total_brate;
- sba_order = ivas_spar_br_table_consts[table_idx].sba_order;
- ivas_get_spar_table_idx( ivas_total_brate, sba_order, ivas_spar_br_table_consts[table_idx].bwidth, &code, &length );
-
- for ( i = 0; i < pSpar_md_cfg->nchan_transport; i++ )
- {
- total_bits += (int16_t) ( ivas_spar_br_table_consts[table_idx].evs_brs[i][0] / FRAMES_PER_SEC );
- max_bits += (int16_t) ( ivas_spar_br_table_consts[table_idx].evs_brs[i][1] / FRAMES_PER_SEC );
- }
- if ( ivas_total_brate >= IVAS_256k )
- {
- pSpar_md_cfg->tgt_bits_per_blk = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC ) - IVAS_FORMAT_SIGNALING_NBITS_SBA - SBA_PLANAR_BITS - SBA_ORDER_BITS - length - total_bits;
-
- pSpar_md_cfg->max_bits_per_blk = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC ) - IVAS_FORMAT_SIGNALING_NBITS_SBA - SBA_PLANAR_BITS - SBA_ORDER_BITS - length - max_bits;
-
- // TODO : do this for lower bitrates as well once order/planar bits are added
- md_coding_bits_header = SPAR_NUM_CODING_STRAT_BITS + pSpar_md_cfg->quant_strat_bits;
- pSpar_md_cfg->tgt_bits_per_blk -= md_coding_bits_header;
- pSpar_md_cfg->max_bits_per_blk -= md_coding_bits_header;
-
- pSpar_md_cfg->tgt_bits_per_blk = (int16_t) ceilf( ( 1.0f * pSpar_md_cfg->tgt_bits_per_blk * num_bands ) / IVAS_MAX_NUM_BANDS );
- pSpar_md_cfg->max_bits_per_blk = (int16_t) ceilf( ( 1.0f * pSpar_md_cfg->max_bits_per_blk * num_bands ) / IVAS_MAX_NUM_BANDS );
-
- pSpar_md_cfg->tgt_bits_per_blk += md_coding_bits_header;
- pSpar_md_cfg->max_bits_per_blk += md_coding_bits_header;
- }
- else
- {
- pSpar_md_cfg->tgt_bits_per_blk = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC ) - IVAS_FORMAT_SIGNALING_NBITS_SBA - length - total_bits;
-
- pSpar_md_cfg->max_bits_per_blk = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC ) - IVAS_FORMAT_SIGNALING_NBITS_SBA - length - max_bits;
-
- pSpar_md_cfg->tgt_bits_per_blk = (int16_t) ceilf( ( 1.0f * pSpar_md_cfg->tgt_bits_per_blk * num_bands ) / IVAS_MAX_NUM_BANDS );
- pSpar_md_cfg->max_bits_per_blk = (int16_t) ceilf( ( 1.0f * pSpar_md_cfg->max_bits_per_blk * num_bands ) / IVAS_MAX_NUM_BANDS );
- }
-
- return;
-}
-
-#ifdef FIX_I1_113
-/*-----------------------------------------------------------------------------------------*
- * Function ivas_spar_bitrate_dist()
- *
- * Set SPAR bitrate distribution
- *-----------------------------------------------------------------------------------------*/
-
-// this function is not currently used but it is kept for future use
-void ivas_spar_bitrate_dist(
- int32_t core_brates_act[], /* o : bitrates per core-coder */
- const int16_t nAvailBits, /* i : number of available bits */
- const int32_t ivas_total_brate, /* i : IVAS total bitrate */
- const int16_t sba_order, /* i : Ambisonic (SBA) order */
- const int16_t bwidth /* i : audio bandwidth */
-)
-{
- int16_t i, nchan_transport, table_idx, bitlen;
- int16_t core_bits_act[FOA_CHANNELS], core_range_bits[FOA_CHANNELS];
- int16_t sum_core_act_bits, residual_bits, overflow_bits;
-
- table_idx = ivas_get_spar_table_idx( ivas_total_brate, sba_order, bwidth, &bitlen, NULL );
-
- nchan_transport = ivas_spar_br_table_consts[table_idx].nchan_transport;
-
- sum_core_act_bits = 0;
- for ( i = 0; i < nchan_transport; i++ )
- {
- core_bits_act[i] = (int16_t) ( ivas_spar_br_table_consts[table_idx].evs_brs[i][0] / FRAMES_PER_SEC );
-
- sum_core_act_bits += core_bits_act[i];
- }
-
- residual_bits = nAvailBits - sum_core_act_bits;
-
- /* First compute core-coder bits as per bitrate distribution table and MD bitrate*/
- if ( residual_bits > 0 )
- {
- for ( i = 0; i < nchan_transport; i++ )
- {
- core_range_bits[i] = (int16_t) ( ( ivas_spar_br_table_consts[table_idx].evs_brs[i][2] - ivas_spar_br_table_consts[table_idx].evs_brs[i][0] ) / FRAMES_PER_SEC );
- core_bits_act[i] += min( residual_bits, core_range_bits[i] );
- residual_bits -= core_range_bits[i];
-
- if ( residual_bits <= 0 )
- {
- break;
- }
- }
- }
- else
- {
- for ( i = 0; i < nchan_transport; i++ )
- {
- core_range_bits[i] = (int16_t) ( ( ivas_spar_br_table_consts[table_idx].evs_brs[i][0] - ivas_spar_br_table_consts[table_idx].evs_brs[i][1] ) / FRAMES_PER_SEC );
- }
-
- overflow_bits = -residual_bits;
-
- for ( i = 0; i < nchan_transport; i++ )
- {
- core_bits_act[nchan_transport - 1 - i] -= min( overflow_bits, core_range_bits[nchan_transport - 1 - i] );
- overflow_bits -= core_range_bits[nchan_transport - 1 - i];
-
- if ( overflow_bits <= 0 )
- {
- break;
- }
- }
-
- if ( overflow_bits > 0 )
- {
- int16_t overflow_bits_ch;
- overflow_bits_ch = overflow_bits / nchan_transport;
-
- for ( i = 0; i < nchan_transport; i++ )
- {
- core_bits_act[i] -= overflow_bits_ch;
- overflow_bits -= overflow_bits_ch;
- }
-
- core_bits_act[nchan_transport - 1] -= max( 0, overflow_bits );
- }
- }
-
- for ( i = 0; i < nchan_transport; i++ )
- {
- core_brates_act[i] = core_bits_act[i] * FRAMES_PER_SEC;
- }
-
- return;
-}
-#endif
diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c
index 87ff95a81aedc43223bcbf8b2cbfe91e3c04501b..95a2d7d61ead739b5536a95d71cc974f93a9d096 100644
--- a/lib_dec/ivas_spar_decoder.c
+++ b/lib_dec/ivas_spar_decoder.c
@@ -45,6 +45,16 @@
#include
#include "wmops.h"
+#ifdef DEBUG_SPAR_FOA
+extern FILE *fFb_pcm;
+#endif
+
+/*-------------------------------------------------------------------*
+ * Local function prototypes
+ *--------------------------------------------------------------------*/
+
+static void ivas_spar_dec_MD( Decoder_Struct *st_ivas, Decoder_State *st0 );
+
/*-------------------------------------------------------------------------
* ivas_spar_dec_open()
@@ -259,3 +269,961 @@ ivas_error ivas_spar_dec(
return error;
}
+
+
+/*---------------------------------------------------------------------*
+ * Function ivas_get_spar_table_idx_from_coded_idx()
+ *
+ * Get SPAR table index
+ *---------------------------------------------------------------------*/
+
+static int16_t ivas_get_spar_table_idx_from_coded_idx(
+ const int32_t ivas_total_brate, /* i : IVAS total bitrate */
+ const int16_t sba_order, /* i : Ambisonic (SBA) order */
+ Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/
+ int16_t *bitlen /* o : number of bits */
+)
+{
+ int16_t table_idx, ind1[IVAS_SPAR_BR_TABLE_LEN];
+ int16_t i, j, ind2;
+
+ j = 0;
+ for ( i = 0; i < IVAS_SPAR_BR_TABLE_LEN; i++ )
+ {
+ ind1[j] = 0;
+ if ( ( ivas_spar_br_table_consts[i].ivas_total_brate == ivas_total_brate ) &&
+ ( ivas_spar_br_table_consts[i].sba_order == sba_order ) )
+ {
+ ind1[j++] = i;
+ }
+ }
+
+ assert( j > 0 );
+
+ *bitlen = ivas_get_bits_to_encode( j - 1 );
+
+ ind2 = get_next_indice( st0, *bitlen );
+
+ table_idx = ind1[ind2];
+
+ return table_idx;
+}
+
+
+/*---------------------------------------------------------------------*
+ * Function ivas_parse_spar_header()
+ *
+ * Get SPAR table index
+ *---------------------------------------------------------------------*/
+
+static int16_t ivas_parse_spar_header(
+ const int32_t ivas_total_brate, /* i : IVAS total bitrate */
+ const int16_t sba_order, /* i : Ambisonic (SBA) order */
+ Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/
+ int16_t *table_idx )
+{
+ int16_t bitlen, bwidth;
+
+ *table_idx = ivas_get_spar_table_idx_from_coded_idx( ivas_total_brate, sba_order, st0, &bitlen );
+
+ bwidth = ivas_spar_br_table_consts[( *table_idx )].bwidth;
+
+ return bwidth;
+}
+
+
+static float get_random_number(
+ int16_t *seed )
+{
+ float x = (float) own_random( seed ) / 32768.0f;
+
+ return x;
+}
+
+
+static float matrix_det(
+ const float a00,
+ const float a01,
+ const float a10,
+ const float a11 )
+{
+ return a00 * a11 - a01 * a10;
+}
+
+
+static void matrix_inverse(
+ float in[3][3],
+ float out[3][3],
+ const int16_t size )
+{
+ float det, fac;
+ float eps = 1e-16f;
+
+ if ( size == 1 )
+ {
+ out[0][0] = 1.0f / max( in[0][0], eps );
+
+ return;
+ }
+ else if ( size == 2 )
+ {
+ det = matrix_det( in[0][1], in[0][1], in[1][0], in[1][1] );
+ fac = 1.0f / max( det, eps );
+
+ out[0][0] = in[1][1] * fac;
+ out[1][0] = in[1][0] * ( -fac );
+
+ out[0][1] = in[0][1] * ( -fac );
+ out[1][1] = in[0][0] * fac;
+
+ return;
+ }
+
+ det = in[0][0] * matrix_det( in[1][1], in[1][2], in[2][1], in[2][2] ) - in[1][0] * matrix_det( in[0][1], in[0][2], in[2][1], in[2][2] ) + in[2][0] * matrix_det( in[0][1], in[0][2], in[1][1], in[1][2] );
+ fac = 1.0f / max( det, eps );
+
+ out[0][0] = matrix_det( in[1][1], in[1][2], in[2][1], in[2][2] ) * fac;
+ out[1][0] = matrix_det( in[1][0], in[1][2], in[2][0], in[2][2] ) * ( -fac );
+ out[2][0] = matrix_det( in[1][0], in[1][1], in[2][0], in[2][1] ) * fac;
+
+ out[0][1] = matrix_det( in[0][1], in[0][2], in[2][1], in[2][2] ) * ( -fac );
+ out[1][1] = matrix_det( in[0][0], in[0][2], in[2][0], in[2][2] ) * fac;
+ out[2][1] = matrix_det( in[0][0], in[0][1], in[2][0], in[2][1] ) * ( -fac );
+
+ out[0][2] = matrix_det( in[0][1], in[0][2], in[1][1], in[1][2] ) * fac;
+ out[1][2] = matrix_det( in[0][0], in[0][2], in[1][0], in[1][2] ) * ( -fac );
+ out[2][2] = matrix_det( in[0][0], in[0][1], in[1][0], in[1][1] ) * fac;
+
+ return;
+}
+
+
+/*---------------------------------------------------------------------*
+ * Function ivas_spar_get_cldfb_gains()
+ *
+ *
+ *---------------------------------------------------------------------*/
+
+void ivas_spar_get_cldfb_gains(
+ SPAR_DEC_HANDLE hSpar,
+ HANDLE_CLDFB_FILTER_BANK cldfbAnaDec0,
+ HANDLE_CLDFB_FILTER_BANK cldfbSynDec0,
+ const DECODER_CONFIG_HANDLE hDecoderConfig )
+{
+ float output_Fs = (float) hDecoderConfig->output_Fs;
+ int16_t pt_len, stride, num_cldfb_bands, decfb_delay;
+ int16_t encfb_delay, cf_start, cf_end, cf_len;
+ float *weights;
+ int16_t ts, cf_cldfb_start, cf_cldfb_end;
+ float cf_start_s, cf_len_s;
+ int16_t sample, num_cf_slots, num_samples;
+ float T[3 * CLDFB_NO_CHANNELS_MAX + 10 * CLDFB_NO_CHANNELS_MAX - CLDFB_NO_CHANNELS_MAX][3];
+ float Tt_T[3][3];
+ float Tt_T_inv[3][3];
+ float Tt_tgt[3];
+ float ts_inout[CLDFB_NO_CHANNELS_MAX];
+ float ts_re[CLDFB_NO_CHANNELS_MAX];
+ float ts_im[CLDFB_NO_CHANNELS_MAX];
+ float *pp_ts_im[1], *pp_ts_re[1];
+ float tgt[( 3 - 1 ) * CLDFB_NO_CHANNELS_MAX + 10 * CLDFB_NO_CHANNELS_MAX];
+ int16_t seed, split_band, slot_row, slot_col, slot, tmp_idx;
+
+ pt_len = cldfbAnaDec0->p_filter_length;
+ num_cldfb_bands = cldfbAnaDec0->no_channels;
+
+ stride = NS2SA( output_Fs, DELAY_CLDFB_NS );
+ encfb_delay = NS2SA( output_Fs, IVAS_FB_ENC_DELAY_NS );
+ decfb_delay = NS2SA( output_Fs, IVAS_FB_DEC_DELAY_NS );
+
+ cf_start = (int16_t) hSpar->hFbMixer->cross_fade_start_offset - encfb_delay + decfb_delay; /* time domain after CLDFB synthesis*/
+ cf_end = (int16_t) hSpar->hFbMixer->cross_fade_end_offset - encfb_delay + decfb_delay;
+ cf_len = cf_end - cf_start;
+ weights = hSpar->hFbMixer->cldfb_cross_fade;
+
+ cf_cldfb_start = (int16_t) ceil( ( cf_start - decfb_delay / 2 ) / (float) stride - 0.5f );
+ cf_cldfb_end = ( int16_t )( ( cf_start - decfb_delay / 2 + cf_len ) / (float) stride - 0.5f );
+
+ num_cf_slots = cf_cldfb_end - cf_cldfb_start + 1;
+ num_samples = num_cf_slots * stride + pt_len - stride;
+ seed = RANDOM_INITSEED;
+ split_band = SPAR_DIRAC_SPLIT_START_BAND;
+ pp_ts_im[0] = ts_im;
+ pp_ts_re[0] = ts_re;
+ set_f( tgt, 0, ( 3 - 1 ) * CLDFB_NO_CHANNELS_MAX + 10 * CLDFB_NO_CHANNELS_MAX );
+
+ cf_start_s = ( cf_start - decfb_delay / 2 ) / output_Fs;
+ cf_len_s = hSpar->hFbMixer->cross_fade_end_offset / output_Fs - hSpar->hFbMixer->cross_fade_start_offset / output_Fs;
+
+ for ( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ )
+ {
+ weights[ts] = ( ( ( ts + 0.5f ) * stride / output_Fs ) - cf_start_s ) / cf_len_s;
+ weights[ts] = max( min( weights[ts], 1.0f ), 0.0f );
+ }
+ hSpar->hFbMixer->cldfb_cross_fade_start = cf_cldfb_start;
+ hSpar->hFbMixer->cldfb_cross_fade_end = cf_cldfb_end;
+ hSpar->hFbMixer->cldfb_latency = decfb_delay;
+
+ if ( num_cf_slots > 3 || pt_len > 10 * CLDFB_NO_CHANNELS_MAX || stride > CLDFB_NO_CHANNELS_MAX || split_band == IVAS_MAX_NUM_BANDS )
+ {
+ return;
+ }
+
+ /* optimization*/
+ /* compute time-domain cross-fade for considered time slots*/
+ tmp_idx = cf_start - cf_cldfb_start * stride;
+ for ( sample = 0; sample < cf_len; sample++ )
+ {
+ /* increasing window function */
+ tgt[tmp_idx++] = hSpar->hFbMixer->pFilterbank_cross_fade[sample];
+ }
+
+ for ( ; tmp_idx < num_samples; tmp_idx++ )
+ {
+ /* fill up with ones*/
+ tgt[tmp_idx] = 1.0f;
+ }
+
+ for ( sample = 0; sample < num_samples; sample++ )
+ {
+ /* initialize trasnform matrix with zeros*/
+ T[sample][0] = T[sample][1] = T[sample][2] = 0.0f;
+ }
+
+ for ( sample = 0; sample < pt_len - stride; sample++ )
+ {
+ /* fill internal CLDFB analysis time buffer with data*/
+ float x = get_random_number( &seed );
+
+ cldfbAnaDec0->cldfb_state[sample] = x;
+ }
+
+ for ( slot = 0; slot < num_cf_slots; slot++ )
+ {
+ for ( sample = 0; sample < stride; sample++ )
+ {
+ float x = get_random_number( &seed );
+ ts_inout[sample] = x;
+ }
+
+ cldfbAnalysis_ts( ts_inout, ts_re, ts_im, num_cldfb_bands, cldfbAnaDec0 );
+ cldfb_reset_memory( cldfbSynDec0 );
+ cldfbSynthesis( pp_ts_re, pp_ts_im, ts_inout, num_cldfb_bands, cldfbSynDec0 );
+
+ for ( sample = 0; sample < stride; sample++ )
+ {
+ T[slot * stride + sample][slot] = ts_inout[sample];
+ }
+
+ tmp_idx = pt_len - 1;
+ for ( sample = stride; sample < pt_len; sample++ )
+ {
+ T[slot * stride + sample][slot] = cldfbSynDec0->cldfb_state[tmp_idx--];
+ }
+ }
+
+ /* target is synthesis output times the cross-fade window*/
+ for ( sample = 0; sample < num_samples; sample++ )
+ {
+ tgt[sample] *= ( T[sample][0] + T[sample][1] + T[sample][2] );
+ }
+
+ /* compute matrices */
+ for ( slot_row = 0; slot_row < num_cf_slots; slot_row++ )
+ {
+ for ( slot_col = slot_row; slot_col < num_cf_slots; slot_col++ )
+ {
+ Tt_T[slot_row][slot_col] = 0.0f;
+ for ( sample = 0; sample < num_samples; sample++ )
+ {
+ Tt_T[slot_row][slot_col] += T[sample][slot_row] * T[sample][slot_col];
+ }
+ }
+ }
+
+ Tt_T[1][0] = Tt_T[0][1];
+ Tt_T[2][0] = Tt_T[0][2];
+ Tt_T[2][1] = Tt_T[1][2];
+
+ for ( slot_row = 0; slot_row < num_cf_slots; slot_row++ )
+ {
+ Tt_tgt[slot_row] = 0.0f;
+ for ( sample = 0; sample < num_samples; sample++ )
+ {
+ Tt_tgt[slot_row] += T[sample][slot_row] * tgt[sample];
+ }
+ }
+
+ matrix_inverse( Tt_T, Tt_T_inv, num_cf_slots );
+
+ /* compute the optimal coefficients */
+ for ( slot_row = 0; slot_row < num_cf_slots; slot_row++ )
+ {
+ float tmp = 0.0f;
+ for ( slot_col = 0; slot_col < num_cf_slots; slot_col++ )
+ {
+ tmp += Tt_T_inv[slot_row][slot_col] * Tt_tgt[slot_col];
+ }
+ weights[cf_cldfb_start + slot_row] = max( min( tmp, 1.0f ), 0.0f );
+ }
+
+ cldfb_reset_memory( cldfbSynDec0 );
+ cldfb_reset_memory( cldfbAnaDec0 );
+
+ return;
+}
+
+
+/*---------------------------------------------------------------------*
+ * Function ivas_is_res_channel()
+ *
+ * determines if an FOA input channel is transmitted as residual channel.
+ *---------------------------------------------------------------------*/
+
+/* !r: 1 if prediction residual channel */
+int16_t ivas_is_res_channel(
+ const int16_t ch, /* i : ch index in WYZX ordering */
+ const int16_t nchan_transport /* i : number of transport channels (1-4) */
+)
+{
+ const int16_t rc_map[FOA_CHANNELS][FOA_CHANNELS] = {
+ { 0, 0, 0, 0 },
+ { 0, 1, 0, 0 },
+ { 0, 1, 0, 1 },
+ { 0, 1, 1, 1 }
+ };
+
+ if ( ch >= FOA_CHANNELS )
+ {
+ /* never transmitted */
+ return 0;
+ }
+ assert( nchan_transport <= FOA_CHANNELS );
+
+ return ( rc_map[nchan_transport - 1][ch] );
+}
+
+
+/*-------------------------------------------------------------------*
+ * ivas_spar_dec_MD()
+ *
+ * IVAS SPAR MD decoder
+ *-------------------------------------------------------------------*/
+
+static void ivas_spar_dec_MD(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
+ Decoder_State *st0 /* i/o: decoder state structure - for bitstream handling*/
+)
+{
+ int16_t num_channels, table_idx, num_bands_out, bfi, sba_order;
+ int32_t ivas_total_brate;
+ DECODER_CONFIG_HANDLE hDecoderConfig = st_ivas->hDecoderConfig;
+ SPAR_DEC_HANDLE pState = st_ivas->hSpar;
+
+ wmops_sub_start( "ivas_spar_dec_MD" );
+
+ /*---------------------------------------------------------------------*
+ * Initialization
+ *---------------------------------------------------------------------*/
+
+ sba_order = min( st_ivas->sba_order, IVAS_MAX_SBA_ORDER );
+ bfi = st_ivas->bfi;
+ ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
+ num_channels = ivas_sba_get_nchan_metadata( sba_order );
+ num_bands_out = pState->hFbMixer->pFb->filterbank_num_bands;
+
+ if ( ivas_total_brate > FRAME_NO_DATA && !bfi )
+ {
+ if ( ivas_total_brate > IVAS_SID_5k )
+ {
+ ivas_parse_spar_header( hDecoderConfig->ivas_total_brate, sba_order, st0, &table_idx );
+
+ pState->hMdDec->spar_md.num_bands = min( SPAR_DIRAC_SPLIT_START_BAND, IVAS_MAX_NUM_BANDS );
+
+ if ( pState->hMdDec->table_idx != table_idx )
+ {
+ pState->hMdDec->table_idx = table_idx;
+ pState->hTdDecorr->ducking_flag = ivas_spar_br_table_consts[table_idx].td_ducking;
+
+ ivas_spar_md_dec_init( pState->hMdDec, hDecoderConfig, num_channels );
+ }
+ }
+
+ /*---------------------------------------------------------------------*
+ * Decode MD
+ *---------------------------------------------------------------------*/
+
+ ivas_spar_md_dec_process( st_ivas, st0, num_bands_out, sba_order );
+
+ /*---------------------------------------------------------------------*
+ * read PCA bits
+ *---------------------------------------------------------------------*/
+
+#ifdef SBA_CLEANING
+ if ( pState->hPCA != NULL )
+#else
+ if ( hDecoderConfig->ivas_total_brate == PCA_BRATE && sba_order == 1 )
+#endif
+ {
+ ivas_pca_read_bits( st0, pState->hPCA );
+ }
+#ifndef SBA_CLEANING
+ else
+ {
+ pState->hPCA->pca_bypass = PCA_MODE_INACTIVE;
+ }
+#endif
+
+ /*---------------------------------------------------------------------*
+ * Read AGC bits
+ *---------------------------------------------------------------------*/
+
+ if ( ivas_total_brate > IVAS_SID_5k && !bfi && pState->hMdDec->dtx_vad )
+ {
+ pState->AGC_flag = get_next_indice( st0, 1 );
+
+ ivas_agc_read_bits( pState->hAgcDec, st0, pState->hMdDec->spar_md_cfg.nchan_transport, pState->AGC_flag );
+ }
+
+ /*---------------------------------------------------------------------*
+ * MD smoothing
+ *---------------------------------------------------------------------*/
+
+ if ( st0->m_old_frame_type == ZERO_FRAME && ivas_total_brate == IVAS_SID_5k && st0->prev_bfi == 0 && pState->hMdDec->spar_md_cfg.nchan_transport == 1 )
+ {
+ ivas_spar_setup_md_smoothing( pState->hMdDec, num_bands_out );
+ }
+ else
+ {
+ ivas_spar_update_md_hist( pState->hMdDec );
+ }
+ }
+ else
+ {
+ if ( !bfi )
+ {
+ ivas_spar_smooth_md_dtx( pState->hMdDec, num_bands_out );
+ }
+
+ set_s( pState->hMdDec->valid_bands, 0, IVAS_MAX_NUM_BANDS );
+ }
+
+ wmops_sub_end();
+ return;
+}
+
+
+/*-------------------------------------------------------------------*
+ * ivas_spar_get_cldfb_slot_gain()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+static float ivas_spar_get_cldfb_slot_gain(
+ SPAR_DEC_HANDLE hSpar, /* i/o: SPAR decoder handle */
+ const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */
+ const int16_t time_slot_idx,
+ int16_t *time_slot_idx0,
+ int16_t *time_slot_idx1,
+ float *weight_lowfreq )
+{
+ SPAR_DEC_HANDLE pState = hSpar;
+ float weight;
+ float output_Fs, encfb_delay, decfb_delay;
+ float xfade_start_ns;
+ int16_t xfade_delay_subframes;
+ int16_t i_hist;
+ int16_t split_band;
+
+ *weight_lowfreq = pState->hFbMixer->cldfb_cross_fade[time_slot_idx];
+
+ output_Fs = (float) hDecoderConfig->output_Fs;
+ encfb_delay = IVAS_FB_ENC_DELAY_NS;
+ decfb_delay = IVAS_FB_DEC_DELAY_NS;
+ xfade_start_ns = pState->hFbMixer->cross_fade_start_offset / output_Fs * 1000000000.f - encfb_delay + decfb_delay * 0.5f;
+ xfade_delay_subframes = ( int16_t )( xfade_start_ns / ( FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ) );
+
+ i_hist = 4 - xfade_delay_subframes;
+ split_band = SPAR_DIRAC_SPLIT_START_BAND;
+
+ if ( split_band < IVAS_MAX_NUM_BANDS )
+ {
+ if ( hSpar->i_subframe > 3 )
+ {
+ weight = (float) ( time_slot_idx % MAX_PARAM_SPATIAL_SUBFRAMES ) / (float) MAX_PARAM_SPATIAL_SUBFRAMES;
+ }
+ else
+ {
+ weight = 0.0f;
+ }
+ *time_slot_idx0 = i_hist;
+ *time_slot_idx1 = i_hist + 1;
+ }
+ else
+ {
+ /* determine cross-fade gain for current frame Parameters*/
+ *time_slot_idx0 = pState->hFbMixer->cldfb_cross_fade_start;
+ *time_slot_idx1 = pState->hFbMixer->cldfb_cross_fade_end;
+ weight = *weight_lowfreq;
+ }
+
+ return weight;
+}
+
+
+/*-------------------------------------------------------------------*
+ * ivas_spar_get_parameters()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+void ivas_spar_get_parameters(
+ SPAR_DEC_HANDLE hSpar, /* i/o: SPAR decoder handle */
+ const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */
+ const int16_t ts,
+ const int16_t num_ch_out,
+ const int16_t num_ch_in,
+ const int16_t num_spar_bands,
+ float par_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS] )
+{
+ int16_t spar_band, out_ch, in_ch;
+ float weight, weight_20ms;
+ int16_t ts0, ts1, split_band;
+
+ weight = ivas_spar_get_cldfb_slot_gain( hSpar, hDecoderConfig, ts, &ts0, &ts1, &weight_20ms );
+
+ split_band = SPAR_DIRAC_SPLIT_START_BAND;
+ for ( spar_band = 0; spar_band < num_spar_bands; spar_band++ )
+ {
+ for ( out_ch = 0; out_ch < num_ch_out; out_ch++ )
+ {
+ for ( in_ch = 0; in_ch < num_ch_in; in_ch++ )
+ {
+ if ( split_band < IVAS_MAX_NUM_BANDS
+ /* 20ms cross-fade for Transport channels in all frequency bands */
+ && ( 0 == ivas_is_res_channel( out_ch, hSpar->hMdDec->spar_md_cfg.nchan_transport ) ) /* sub-frame processing for missing channels in all frequency bands*/
+ )
+ {
+ if ( hSpar->i_subframe > 3 )
+ {
+ par_mat[out_ch][in_ch][spar_band] = ( 1.0f - weight ) * hSpar->hMdDec->mixer_mat_prev[ts0][out_ch][in_ch][spar_band] +
+ weight * hSpar->hMdDec->mixer_mat_prev[ts1][out_ch][in_ch][spar_band];
+ }
+ else
+ {
+ par_mat[out_ch][in_ch][spar_band] = hSpar->hMdDec->mixer_mat[out_ch][in_ch][spar_band];
+ }
+ }
+ else
+ {
+ /* 20ms Transport channel reconstruction with matching encoder/decoder processing */
+ int16_t prev_idx = SPAR_DIRAC_SPLIT_START_BAND < IVAS_MAX_NUM_BANDS ? 1 : 0; /* if SPAR_DIRAC_SPLIT_START_BAND == IVAS_MAX_NUM_BANDS, then the sub-frame mixer_mat delay line is not active */
+ par_mat[out_ch][in_ch][spar_band] = ( 1.0f - weight_20ms ) * hSpar->hMdDec->mixer_mat_prev[prev_idx][out_ch][in_ch][spar_band] + weight_20ms * hSpar->hMdDec->mixer_mat[out_ch][in_ch][spar_band];
+ }
+ }
+ }
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------*
+ * ivas_spar_get_skip_mat()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+static void ivas_spar_get_skip_mat(
+ SPAR_DEC_HANDLE hSpar, /* i/o: SPAR decoder handle */
+ const int16_t num_ch_out,
+ const int16_t num_ch_in,
+ const int16_t num_spar_bands,
+ int16_t skip_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH] )
+{
+ int16_t spar_band, out_ch, in_ch;
+ int16_t i_ts, skip_flag;
+
+ for ( out_ch = 0; out_ch < num_ch_out; out_ch++ )
+ {
+ for ( in_ch = 0; in_ch < num_ch_in; in_ch++ )
+ {
+ skip_mat[out_ch][in_ch] = 1;
+ skip_flag = 1;
+
+ for ( i_ts = 0; i_ts < MAX_PARAM_SPATIAL_SUBFRAMES; i_ts++ )
+ {
+ for ( spar_band = 0; spar_band < num_spar_bands; spar_band++ )
+ {
+ if ( hSpar->hMdDec->mixer_mat_prev[1 + i_ts][out_ch][in_ch][spar_band] != 0.0f || hSpar->hMdDec->mixer_mat[out_ch][in_ch][spar_band + i_ts * MAX_PARAM_SPATIAL_SUBFRAMES] != 0.0f )
+ {
+ skip_flag = 0;
+ break;
+ }
+ }
+
+ if ( skip_flag == 0 )
+ {
+ skip_mat[out_ch][in_ch] = 0;
+ break;
+ }
+ }
+ }
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------*
+ * ivas_spar_foa_dec_upmixer()
+ *
+ * IVAS SPAR upmixer
+ *-------------------------------------------------------------------*/
+
+void ivas_spar_dec_upmixer(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
+ float output[][L_FRAME48k], /* i/o: input/output audio channels */
+ const int16_t nchan_internal, /* i : number of internal channels */
+ const int16_t output_frame /* i : output frame length */
+)
+{
+ int16_t cldfb_band, num_cldfb_bands, numch_in, numch_out;
+ float *cldfb_in_ts_re[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX];
+ float *cldfb_in_ts_im[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX];
+ int16_t i, b, ts, out_ch, in_ch;
+ int16_t num_spar_bands, spar_band, nchan_transport;
+ int16_t num_in_ingest, num_bands_out, split_band;
+ float Pcm_tmp[MAX_OUTPUT_CHANNELS][L_FRAME48k];
+ int16_t numch_out_dirac;
+ float *pPcm_tmp[MAX_OUTPUT_CHANNELS];
+ float mixer_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS];
+ int16_t b_skip_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
+ DECODER_CONFIG_HANDLE hDecoderConfig;
+ SPAR_DEC_HANDLE pState, hSpar;
+
+ wmops_sub_start( "ivas_spar_dec_upmixer" );
+
+ hSpar = st_ivas->hSpar;
+ pState = hSpar;
+ hDecoderConfig = st_ivas->hDecoderConfig;
+ num_bands_out = pState->hFbMixer->pFb->filterbank_num_bands;
+ nchan_transport = pState->hMdDec->spar_md_cfg.nchan_transport;
+
+ num_cldfb_bands = hSpar->hFbMixer->pFb->fb_bin_to_band.num_cldfb_bands;
+ numch_in = hSpar->hFbMixer->fb_cfg->num_in_chans;
+ numch_out = hSpar->hFbMixer->fb_cfg->num_out_chans;
+
+#ifdef DEBUG_SPAR_FOA
+ if ( fFb_pcm != NULL )
+ {
+ for ( i = 0; i < output_frame; i++ )
+ {
+ for ( int16_t j = 0; j < nchan_transport; j++ )
+ {
+ fscanf( fFb_pcm, "%f\n", &output[j][i] );
+ }
+ }
+ }
+#endif
+
+ /* by-pass EVS */
+#ifdef DEBUG_SPAR_BYPASS_EVS_CODEC
+ /*write the core coder output to a file for debugging*/
+ {
+ float tmp;
+ int16_t pcm, j;
+ for ( j = 0; j < output_frame; j++ )
+ {
+ for ( i = 0; i < nchan_transport; i++ )
+ {
+ tmp = roundf( output[i][j] * PCM16_TO_FLT_FAC );
+ pcm = ( tmp > MAX16B_FLT ) ? MAX16B : ( tmp < MIN16B_FLT ) ? MIN16B : (short) tmp;
+ dbgwrite( &pcm, sizeof( int16_t ), 1, 1, "dmx_dec.raw" );
+ }
+ }
+ }
+
+ /*overwrite the core coder output with core input for debugging*/
+ {
+ static FILE *fid_enc = 0;
+ int16_t smp;
+
+ if ( !fid_enc )
+ {
+ fid_enc = fopen( "evs_input_float.raw", "rb" );
+ }
+ for ( smp = 0; smp < L_FRAME48k; smp++ )
+ {
+ for ( in_ch = 0; in_ch < nchan_transport; in_ch++ )
+ {
+ fread( &output[in_ch][smp], sizeof( float ), 1, fid_enc );
+ }
+ }
+ }
+#endif
+
+ /*---------------------------------------------------------------------*
+ * AGC
+ *---------------------------------------------------------------------*/
+
+ ivas_agc_dec_process( pState->hAgcDec, output, output, nchan_transport, output_frame );
+
+ /*---------------------------------------------------------------------*
+ * TD Decorr and pcm ingest
+ *---------------------------------------------------------------------*/
+
+ if ( pState->hMdDec->td_decorr_flag )
+ {
+ num_in_ingest = nchan_internal;
+ }
+ else
+ {
+ num_in_ingest = nchan_transport;
+ }
+
+ for ( i = 0; i < nchan_internal; i++ )
+ {
+ pPcm_tmp[i] = Pcm_tmp[i];
+ }
+
+ /*---------------------------------------------------------------------*
+ * PCA decoder
+ *---------------------------------------------------------------------*/
+
+#ifdef SBA_CLEANING
+ if ( pState->hPCA != NULL )
+#endif
+ {
+ ivas_pca_dec( pState->hPCA, output_frame, num_in_ingest, hDecoderConfig->ivas_total_brate, hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, output );
+ }
+
+ /*---------------------------------------------------------------------*
+ * TD decorrelation
+ *---------------------------------------------------------------------*/
+
+ if ( pState->hMdDec->td_decorr_flag )
+ {
+ ivas_td_decorr_process( pState->hTdDecorr, output, pPcm_tmp, output_frame );
+
+ for ( i = 0; i < nchan_internal - nchan_transport; i++ )
+ {
+ mvr2r( pPcm_tmp[pState->hTdDecorr->num_apd_outputs - 1 - i], output[nchan_internal - 1 - i], output_frame );
+ }
+
+ pState->hFbMixer->fb_cfg->num_in_chans = num_in_ingest;
+ }
+ else
+ {
+ pState->hFbMixer->fb_cfg->num_in_chans = num_in_ingest;
+ }
+
+ /*---------------------------------------------------------------------*
+ * Prepare CLDFB buffers
+ *---------------------------------------------------------------------*/
+
+ /* set-up pointers */
+ if ( st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_FOA )
+ {
+ /* at this point, output channels are used as intermediate procesing buffers */
+ for ( in_ch = 0; in_ch < MAX_OUTPUT_CHANNELS; in_ch++ )
+ {
+ for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ )
+ {
+ cldfb_in_ts_re[in_ch][ts] = &Pcm_tmp[in_ch][ts * num_cldfb_bands];
+ cldfb_in_ts_im[in_ch][ts] = &Pcm_tmp[in_ch][ts * num_cldfb_bands + 4 * num_cldfb_bands];
+ }
+ }
+ }
+ else
+ {
+ for ( in_ch = 0; in_ch < numch_in; in_ch++ )
+ {
+ for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ )
+ {
+ cldfb_in_ts_re[in_ch][ts] = &Pcm_tmp[in_ch][ts * num_cldfb_bands];
+ cldfb_in_ts_im[in_ch][ts] = &Pcm_tmp[in_ch][ts * num_cldfb_bands + 4 * num_cldfb_bands];
+ }
+ }
+ }
+
+ /*---------------------------------------------------------------------*
+ * Gen umx mat
+ *---------------------------------------------------------------------*/
+
+ ivas_spar_dec_gen_umx_mat( pState->hMdDec, nchan_transport, num_bands_out, st_ivas->bfi );
+
+
+ /*---------------------------------------------------------------------*
+ * CLDFB Processing and Synthesis
+ *---------------------------------------------------------------------*/
+
+ num_spar_bands = hSpar->hFbMixer->pFb->filterbank_num_bands;
+
+ /* apply parameters */
+ /* determine if we can skip certain data */
+ ivas_spar_get_skip_mat( hSpar, numch_out, numch_in, num_spar_bands, b_skip_mat ); /* this can be precomputed based on bitrate and format*/
+
+ numch_out_dirac = st_ivas->hDecoderConfig->nchan_out;
+
+ for ( int16_t i_sf = 0; i_sf < MAX_PARAM_SPATIAL_SUBFRAMES; i_sf++ )
+ {
+ /* CLDFB analysis of incoming frame */
+ for ( in_ch = 0; in_ch < numch_in; in_ch++ )
+ {
+ for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ )
+ {
+ cldfbAnalysis_ts(
+ &output[in_ch][( ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES ) * num_cldfb_bands],
+ cldfb_in_ts_re[in_ch][ts],
+ cldfb_in_ts_im[in_ch][ts],
+ num_cldfb_bands,
+ st_ivas->cldfbAnaDec[in_ch] );
+ }
+ }
+
+ for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ )
+ {
+ /* determine SPAR parameters for this time slots */
+ ivas_spar_get_parameters( hSpar, st_ivas->hDecoderConfig, ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES, numch_out, numch_in, num_spar_bands, mixer_mat );
+
+ for ( cldfb_band = 0; cldfb_band < num_cldfb_bands; cldfb_band++ )
+ {
+ float out_re[IVAS_SPAR_MAX_CH];
+ float out_im[IVAS_SPAR_MAX_CH];
+ float cldfb_par;
+ ivas_fb_bin_to_band_data_t *bin2band = &pState->hFbMixer->pFb->fb_bin_to_band;
+
+ for ( out_ch = 0; out_ch < numch_out; out_ch++ )
+ {
+ out_re[out_ch] = 0.0f;
+ out_im[out_ch] = 0.0f;
+
+ for ( in_ch = 0; in_ch < numch_in; in_ch++ )
+ {
+ if ( b_skip_mat[out_ch][in_ch] )
+ {
+ continue;
+ }
+ else if ( cldfb_band < CLDFB_PAR_WEIGHT_START_BAND ) /* tuning parameter, depends on how much SPAR Filters overlap for the CLDFB bands */
+ {
+ spar_band = bin2band->p_cldfb_map_to_spar_band[cldfb_band];
+ cldfb_par = mixer_mat[out_ch][in_ch][spar_band];
+ }
+ else
+ {
+ cldfb_par = 0.0f;
+ for ( spar_band = bin2band->p_spar_start_bands[cldfb_band]; spar_band < num_spar_bands; spar_band++ )
+ {
+ /* accumulate contributions from all SPAR bands */
+ cldfb_par += mixer_mat[out_ch][in_ch][spar_band] * bin2band->pp_cldfb_weights_per_spar_band[cldfb_band][spar_band];
+ }
+ }
+
+ out_re[out_ch] += cldfb_in_ts_re[in_ch][ts][cldfb_band] * cldfb_par;
+ out_im[out_ch] += cldfb_in_ts_im[in_ch][ts][cldfb_band] * cldfb_par;
+ }
+ }
+
+ /*update CLDFB data with the parameter-modified data*/
+ for ( out_ch = 0; out_ch < numch_out; out_ch++ )
+ {
+ cldfb_in_ts_re[out_ch][ts][cldfb_band] = out_re[out_ch];
+ cldfb_in_ts_im[out_ch][ts][cldfb_band] = out_im[out_ch];
+ }
+ }
+ }
+
+ if ( st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_FOA )
+ {
+#ifdef SBA_CLEANING
+ ivas_dirac_dec( st_ivas, output, nchan_internal, cldfb_in_ts_re, cldfb_in_ts_im, i_sf );
+#else
+ nchan_transport = ivas_sba_get_nchan_metadata( st_ivas->sba_order ); // VE: == nchan_internal that is already set correctly
+
+ ivas_dirac_dec( st_ivas, output, nchan_transport, cldfb_in_ts_re, cldfb_in_ts_im, i_sf );
+#endif
+ }
+
+ if ( st_ivas->hDirAC != NULL )
+ {
+ int16_t outchannels, idx_in, idx_lfe, ch;
+ idx_in = 0;
+ idx_lfe = 0;
+
+ outchannels = st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe;
+ for ( ch = 0; ch < outchannels; ch++ )
+ {
+ if ( ( st_ivas->hOutSetup.num_lfe > 0 ) && ( st_ivas->hOutSetup.index_lfe[idx_lfe] == ch ) )
+ {
+ set_zero( &( output[ch][i_sf * MAX_PARAM_SPATIAL_SUBFRAMES * num_cldfb_bands] ), MAX_PARAM_SPATIAL_SUBFRAMES * num_cldfb_bands );
+
+ if ( idx_lfe < ( st_ivas->hDirAC->hOutSetup.num_lfe - 1 ) )
+ {
+ idx_lfe++;
+ }
+ }
+ else
+ {
+ if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_FOA ||
+ !( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL || st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM ) )
+ {
+ for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ )
+ {
+ cldfbSynthesis(
+ &cldfb_in_ts_re[idx_in][ts],
+ &cldfb_in_ts_im[idx_in][ts],
+ &output[ch][( ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES ) * num_cldfb_bands],
+ num_cldfb_bands,
+ st_ivas->cldfbSynDec[idx_in] );
+ }
+ }
+ idx_in++;
+ }
+ }
+ }
+ else
+ {
+ /* CLDFB to time synthesis (overwrite mixer output) */
+ for ( out_ch = 0; out_ch < numch_out_dirac; out_ch++ )
+ {
+ for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ )
+ {
+ cldfbSynthesis(
+ &cldfb_in_ts_re[out_ch][ts],
+ &cldfb_in_ts_im[out_ch][ts],
+ &output[out_ch][( ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES ) * num_cldfb_bands],
+ num_cldfb_bands,
+ st_ivas->cldfbSynDec[out_ch]
+
+ );
+ }
+ }
+ }
+
+ split_band = SPAR_DIRAC_SPLIT_START_BAND;
+ if ( split_band < IVAS_MAX_NUM_BANDS )
+ {
+ pState->i_subframe++;
+ pState->i_subframe = min( pState->i_subframe, MAX_PARAM_SPATIAL_SUBFRAMES );
+ mvr2r( pState->hMdDec->mixer_mat_prev[1][0][0], pState->hMdDec->mixer_mat_prev[0][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS );
+ mvr2r( pState->hMdDec->mixer_mat_prev[2][0][0], pState->hMdDec->mixer_mat_prev[1][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS );
+ mvr2r( pState->hMdDec->mixer_mat_prev[3][0][0], pState->hMdDec->mixer_mat_prev[2][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS );
+ mvr2r( pState->hMdDec->mixer_mat_prev[4][0][0], pState->hMdDec->mixer_mat_prev[3][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS );
+
+ for ( out_ch = 0; out_ch < numch_out; out_ch++ )
+ {
+ for ( in_ch = 0; in_ch < numch_in; in_ch++ )
+ {
+ for ( b = 0; b < num_spar_bands; b++ )
+ {
+ pState->hMdDec->mixer_mat_prev[4][out_ch][in_ch][b] = pState->hMdDec->mixer_mat[out_ch][in_ch][b + i_sf * IVAS_MAX_NUM_BANDS];
+ }
+ }
+ }
+ }
+ }
+
+ wmops_sub_end();
+
+ return;
+}
diff --git a/lib_dec/ivas_spar_foa_dec.c b/lib_dec/ivas_spar_foa_dec.c
deleted file mode 100644
index cbc685bb76c95e5af433f3b8904b9ee20d2b9119..0000000000000000000000000000000000000000
--- a/lib_dec/ivas_spar_foa_dec.c
+++ /dev/null
@@ -1,1012 +0,0 @@
-/******************************************************************************************************
-
- (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
- Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
- Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
- Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
- contributors to this repository. All Rights Reserved.
-
- This software is protected by copyright law and by international treaties.
- The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
- Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
- Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
- Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
- contributors to this repository retain full ownership rights in their respective contributions in
- the software. This notice grants no license of any kind, including but not limited to patent
- license, nor is any license granted by implication, estoppel or otherwise.
-
- Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
- contributions.
-
- This software is provided "AS IS", without any express or implied warranties. The software is in the
- development stage. It is intended exclusively for experts who have experience with such software and
- solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
- and fitness for a particular purpose are hereby disclaimed and excluded.
-
- Any dispute, controversy or claim arising under or in relation to providing this software shall be
- submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
- accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
- the United Nations Convention on Contracts on the International Sales of Goods.
-
-*******************************************************************************************************/
-
-#include
-#include "options.h"
-#ifdef DEBUGGING
-#include "debug.h"
-#endif
-#include "math.h"
-#include "ivas_prot.h"
-#include "prot.h"
-#include "ivas_rom_com.h"
-#include
-#include "wmops.h"
-
-
-#ifdef DEBUG_SPAR_FOA
-extern FILE *fFb_pcm;
-#endif
-
-/*----------------------------------------------------------------------*
- * Local constants
- *----------------------------------------------------------------------*/
-
-
-/*---------------------------------------------------------------------*
- * Function ivas_get_spar_table_idx_from_coded_idx()
- *
- * Get SPAR table index
- *---------------------------------------------------------------------*/
-
-static int16_t ivas_get_spar_table_idx_from_coded_idx(
- const int32_t ivas_total_brate, /* i : IVAS total bitrate */
- const int16_t sba_order, /* i : Ambisonic (SBA) order */
- Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/
- int16_t *bitlen /* o : number of bits */
-)
-{
- int16_t table_idx, ind1[IVAS_SPAR_BR_TABLE_LEN];
- int16_t i, j, ind2;
-
- j = 0;
- for ( i = 0; i < IVAS_SPAR_BR_TABLE_LEN; i++ )
- {
- ind1[j] = 0;
- if ( ( ivas_spar_br_table_consts[i].ivas_total_brate == ivas_total_brate ) &&
- ( ivas_spar_br_table_consts[i].sba_order == sba_order ) )
- {
- ind1[j++] = i;
- }
- }
-
- assert( j > 0 );
-
- *bitlen = ivas_get_bits_to_encode( j - 1 );
-
- ind2 = get_next_indice( st0, *bitlen );
-
- table_idx = ind1[ind2];
-
- return table_idx;
-}
-
-
-/*---------------------------------------------------------------------*
- * Function ivas_parse_spar_header()
- *
- * Get SPAR table index
- *---------------------------------------------------------------------*/
-
-static int16_t ivas_parse_spar_header(
- const int32_t ivas_total_brate, /* i : IVAS total bitrate */
- const int16_t sba_order, /* i : Ambisonic (SBA) order */
- Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/
- int16_t *table_idx )
-{
- int16_t bitlen, bwidth;
-
- *table_idx = ivas_get_spar_table_idx_from_coded_idx( ivas_total_brate, sba_order, st0, &bitlen );
-
- bwidth = ivas_spar_br_table_consts[( *table_idx )].bwidth;
-
- return bwidth;
-}
-
-
-static float get_random_number(
- int16_t *seed )
-{
- float x = (float) own_random( seed ) / 32768.0f;
-
- return x;
-}
-
-
-static float matrix_det(
- const float a00,
- const float a01,
- const float a10,
- const float a11 )
-{
- return a00 * a11 - a01 * a10;
-}
-
-
-static void matrix_inverse(
- float in[3][3],
- float out[3][3],
- const int16_t size )
-{
- float det, fac;
- float eps = 1e-16f;
-
- if ( size == 1 )
- {
- out[0][0] = 1.0f / max( in[0][0], eps );
-
- return;
- }
- else if ( size == 2 )
- {
- det = matrix_det( in[0][1], in[0][1], in[1][0], in[1][1] );
- fac = 1.0f / max( det, eps );
-
- out[0][0] = in[1][1] * fac;
- out[1][0] = in[1][0] * ( -fac );
-
- out[0][1] = in[0][1] * ( -fac );
- out[1][1] = in[0][0] * fac;
-
- return;
- }
-
- det = in[0][0] * matrix_det( in[1][1], in[1][2], in[2][1], in[2][2] ) - in[1][0] * matrix_det( in[0][1], in[0][2], in[2][1], in[2][2] ) + in[2][0] * matrix_det( in[0][1], in[0][2], in[1][1], in[1][2] );
- fac = 1.0f / max( det, eps );
-
- out[0][0] = matrix_det( in[1][1], in[1][2], in[2][1], in[2][2] ) * fac;
- out[1][0] = matrix_det( in[1][0], in[1][2], in[2][0], in[2][2] ) * ( -fac );
- out[2][0] = matrix_det( in[1][0], in[1][1], in[2][0], in[2][1] ) * fac;
-
- out[0][1] = matrix_det( in[0][1], in[0][2], in[2][1], in[2][2] ) * ( -fac );
- out[1][1] = matrix_det( in[0][0], in[0][2], in[2][0], in[2][2] ) * fac;
- out[2][1] = matrix_det( in[0][0], in[0][1], in[2][0], in[2][1] ) * ( -fac );
-
- out[0][2] = matrix_det( in[0][1], in[0][2], in[1][1], in[1][2] ) * fac;
- out[1][2] = matrix_det( in[0][0], in[0][2], in[1][0], in[1][2] ) * ( -fac );
- out[2][2] = matrix_det( in[0][0], in[0][1], in[1][0], in[1][1] ) * fac;
-
- return;
-}
-
-
-/*---------------------------------------------------------------------*
- * Function ivas_spar_get_cldfb_gains()
- *
- *
- *---------------------------------------------------------------------*/
-
-void ivas_spar_get_cldfb_gains(
- SPAR_DEC_HANDLE hSpar,
- HANDLE_CLDFB_FILTER_BANK cldfbAnaDec0,
- HANDLE_CLDFB_FILTER_BANK cldfbSynDec0,
- const DECODER_CONFIG_HANDLE hDecoderConfig )
-{
- float output_Fs = (float) hDecoderConfig->output_Fs;
- int16_t pt_len, stride, num_cldfb_bands, decfb_delay;
- int16_t encfb_delay, cf_start, cf_end, cf_len;
- float *weights;
- int16_t ts, cf_cldfb_start, cf_cldfb_end;
- float cf_start_s, cf_len_s;
- int16_t sample, num_cf_slots, num_samples;
- float T[3 * CLDFB_NO_CHANNELS_MAX + 10 * CLDFB_NO_CHANNELS_MAX - CLDFB_NO_CHANNELS_MAX][3];
- float Tt_T[3][3];
- float Tt_T_inv[3][3];
- float Tt_tgt[3];
- float ts_inout[CLDFB_NO_CHANNELS_MAX];
- float ts_re[CLDFB_NO_CHANNELS_MAX];
- float ts_im[CLDFB_NO_CHANNELS_MAX];
- float *pp_ts_im[1], *pp_ts_re[1];
- float tgt[( 3 - 1 ) * CLDFB_NO_CHANNELS_MAX + 10 * CLDFB_NO_CHANNELS_MAX];
- int16_t seed, split_band, slot_row, slot_col, slot, tmp_idx;
-
- pt_len = cldfbAnaDec0->p_filter_length;
- num_cldfb_bands = cldfbAnaDec0->no_channels;
-
- stride = NS2SA( output_Fs, DELAY_CLDFB_NS );
- encfb_delay = NS2SA( output_Fs, IVAS_FB_ENC_DELAY_NS );
- decfb_delay = NS2SA( output_Fs, IVAS_FB_DEC_DELAY_NS );
-
- cf_start = (int16_t) hSpar->hFbMixer->cross_fade_start_offset - encfb_delay + decfb_delay; /* time domain after CLDFB synthesis*/
- cf_end = (int16_t) hSpar->hFbMixer->cross_fade_end_offset - encfb_delay + decfb_delay;
- cf_len = cf_end - cf_start;
- weights = hSpar->hFbMixer->cldfb_cross_fade;
-
- cf_cldfb_start = (int16_t) ceil( ( cf_start - decfb_delay / 2 ) / (float) stride - 0.5f );
- cf_cldfb_end = (int16_t) ( ( cf_start - decfb_delay / 2 + cf_len ) / (float) stride - 0.5f );
-
- num_cf_slots = cf_cldfb_end - cf_cldfb_start + 1;
- num_samples = num_cf_slots * stride + pt_len - stride;
- seed = RANDOM_INITSEED;
- split_band = SPAR_DIRAC_SPLIT_START_BAND;
- pp_ts_im[0] = ts_im;
- pp_ts_re[0] = ts_re;
- set_f( tgt, 0, ( 3 - 1 ) * CLDFB_NO_CHANNELS_MAX + 10 * CLDFB_NO_CHANNELS_MAX );
-
- cf_start_s = ( cf_start - decfb_delay / 2 ) / output_Fs;
- cf_len_s = hSpar->hFbMixer->cross_fade_end_offset / output_Fs - hSpar->hFbMixer->cross_fade_start_offset / output_Fs;
-
- for ( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ )
- {
- weights[ts] = ( ( ( ts + 0.5f ) * stride / output_Fs ) - cf_start_s ) / cf_len_s;
- weights[ts] = max( min( weights[ts], 1.0f ), 0.0f );
- }
- hSpar->hFbMixer->cldfb_cross_fade_start = cf_cldfb_start;
- hSpar->hFbMixer->cldfb_cross_fade_end = cf_cldfb_end;
- hSpar->hFbMixer->cldfb_latency = decfb_delay;
-
- if ( num_cf_slots > 3 || pt_len > 10 * CLDFB_NO_CHANNELS_MAX || stride > CLDFB_NO_CHANNELS_MAX || split_band == IVAS_MAX_NUM_BANDS )
- {
- return;
- }
-
- /* optimization*/
- /* compute time-domain cross-fade for considered time slots*/
- tmp_idx = cf_start - cf_cldfb_start * stride;
- for ( sample = 0; sample < cf_len; sample++ )
- {
- /* increasing window function */
- tgt[tmp_idx++] = hSpar->hFbMixer->pFilterbank_cross_fade[sample];
- }
-
- for ( ; tmp_idx < num_samples; tmp_idx++ )
- {
- /* fill up with ones*/
- tgt[tmp_idx] = 1.0f;
- }
-
- for ( sample = 0; sample < num_samples; sample++ )
- {
- /* initialize trasnform matrix with zeros*/
- T[sample][0] = T[sample][1] = T[sample][2] = 0.0f;
- }
-
- for ( sample = 0; sample < pt_len - stride; sample++ )
- {
- /* fill internal CLDFB analysis time buffer with data*/
- float x = get_random_number( &seed );
-
- cldfbAnaDec0->cldfb_state[sample] = x;
- }
-
- for ( slot = 0; slot < num_cf_slots; slot++ )
- {
- for ( sample = 0; sample < stride; sample++ )
- {
- float x = get_random_number( &seed );
- ts_inout[sample] = x;
- }
-
- cldfbAnalysis_ts( ts_inout, ts_re, ts_im, num_cldfb_bands, cldfbAnaDec0 );
- cldfb_reset_memory( cldfbSynDec0 );
- cldfbSynthesis( pp_ts_re, pp_ts_im, ts_inout, num_cldfb_bands, cldfbSynDec0 );
-
- for ( sample = 0; sample < stride; sample++ )
- {
- T[slot * stride + sample][slot] = ts_inout[sample];
- }
-
- tmp_idx = pt_len - 1;
- for ( sample = stride; sample < pt_len; sample++ )
- {
- T[slot * stride + sample][slot] = cldfbSynDec0->cldfb_state[tmp_idx--];
- }
- }
-
- /* target is synthesis output times the cross-fade window*/
- for ( sample = 0; sample < num_samples; sample++ )
- {
- tgt[sample] *= ( T[sample][0] + T[sample][1] + T[sample][2] );
- }
-
- /* compute matrices */
- for ( slot_row = 0; slot_row < num_cf_slots; slot_row++ )
- {
- for ( slot_col = slot_row; slot_col < num_cf_slots; slot_col++ )
- {
- Tt_T[slot_row][slot_col] = 0.0f;
- for ( sample = 0; sample < num_samples; sample++ )
- {
- Tt_T[slot_row][slot_col] += T[sample][slot_row] * T[sample][slot_col];
- }
- }
- }
-
- Tt_T[1][0] = Tt_T[0][1];
- Tt_T[2][0] = Tt_T[0][2];
- Tt_T[2][1] = Tt_T[1][2];
-
- for ( slot_row = 0; slot_row < num_cf_slots; slot_row++ )
- {
- Tt_tgt[slot_row] = 0.0f;
- for ( sample = 0; sample < num_samples; sample++ )
- {
- Tt_tgt[slot_row] += T[sample][slot_row] * tgt[sample];
- }
- }
-
- matrix_inverse( Tt_T, Tt_T_inv, num_cf_slots );
-
- /* compute the optimal coefficients */
- for ( slot_row = 0; slot_row < num_cf_slots; slot_row++ )
- {
- float tmp = 0.0f;
- for ( slot_col = 0; slot_col < num_cf_slots; slot_col++ )
- {
- tmp += Tt_T_inv[slot_row][slot_col] * Tt_tgt[slot_col];
- }
- weights[cf_cldfb_start + slot_row] = max( min( tmp, 1.0f ), 0.0f );
- }
-
- cldfb_reset_memory( cldfbSynDec0 );
- cldfb_reset_memory( cldfbAnaDec0 );
-
- return;
-}
-
-
-/*---------------------------------------------------------------------*
- * Function ivas_is_res_channel()
- *
- * determines if an FOA input channel is transmitted as residual channel.
- *---------------------------------------------------------------------*/
-
-/* !r: 1 if prediction residual channel */
-int16_t ivas_is_res_channel(
- const int16_t ch, /* i : ch index in WYZX ordering */
- const int16_t nchan_transport /* i : number of transport channels (1-4) */
-)
-{
- const int16_t rc_map[FOA_CHANNELS][FOA_CHANNELS] = {
- { 0, 0, 0, 0 },
- { 0, 1, 0, 0 },
- { 0, 1, 0, 1 },
- { 0, 1, 1, 1 }
- };
-
- if ( ch >= FOA_CHANNELS )
- {
- /* never transmitted */
- return 0;
- }
- assert( nchan_transport <= FOA_CHANNELS );
-
- return ( rc_map[nchan_transport - 1][ch] );
-}
-
-
-/*-------------------------------------------------------------------*
- * ivas_spar_dec_MD()
- *
- * IVAS SPAR MD decoder
- *-------------------------------------------------------------------*/
-
-void ivas_spar_dec_MD(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
- Decoder_State *st0 /* i/o: decoder state structure - for bitstream handling*/
-)
-{
- int16_t num_channels, table_idx, num_bands_out, bfi, sba_order;
- int32_t ivas_total_brate;
- DECODER_CONFIG_HANDLE hDecoderConfig = st_ivas->hDecoderConfig;
- SPAR_DEC_HANDLE pState = st_ivas->hSpar;
-
- wmops_sub_start( "ivas_spar_dec_MD" );
-
- /*---------------------------------------------------------------------*
- * Initialization
- *---------------------------------------------------------------------*/
-
- sba_order = min( st_ivas->sba_order, IVAS_MAX_SBA_ORDER );
- bfi = st_ivas->bfi;
- ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
- num_channels = ivas_sba_get_nchan_metadata( sba_order );
- num_bands_out = pState->hFbMixer->pFb->filterbank_num_bands;
-
- if ( ivas_total_brate > FRAME_NO_DATA && !bfi )
- {
- if ( ivas_total_brate > IVAS_SID_5k )
- {
- ivas_parse_spar_header( hDecoderConfig->ivas_total_brate, sba_order, st0, &table_idx );
-
- pState->hMdDec->spar_md.num_bands = min( SPAR_DIRAC_SPLIT_START_BAND, IVAS_MAX_NUM_BANDS );
-
- if ( pState->hMdDec->table_idx != table_idx )
- {
- pState->hMdDec->table_idx = table_idx;
- pState->hTdDecorr->ducking_flag = ivas_spar_br_table_consts[table_idx].td_ducking;
-
- ivas_spar_md_dec_init( pState->hMdDec, hDecoderConfig, num_channels );
- }
- }
-
- /*---------------------------------------------------------------------*
- * Decode MD
- *---------------------------------------------------------------------*/
-
- ivas_spar_md_dec_process( st_ivas, st0, num_bands_out, sba_order );
-
- /*---------------------------------------------------------------------*
- * read PCA bits
- *---------------------------------------------------------------------*/
-
-#ifdef SBA_CLEANING
- if ( pState->hPCA != NULL )
-#else
- if ( hDecoderConfig->ivas_total_brate == PCA_BRATE && sba_order == 1 )
-#endif
- {
- ivas_pca_read_bits( st0, pState->hPCA );
- }
-#ifndef SBA_CLEANING
- else
- {
- pState->hPCA->pca_bypass = PCA_MODE_INACTIVE;
- }
-#endif
-
- /*---------------------------------------------------------------------*
- * Read AGC bits
- *---------------------------------------------------------------------*/
-
- if ( ivas_total_brate > IVAS_SID_5k && !bfi && pState->hMdDec->dtx_vad )
- {
- pState->AGC_flag = get_next_indice( st0, 1 );
-
- ivas_agc_read_bits( pState->hAgcDec, st0, pState->hMdDec->spar_md_cfg.nchan_transport, pState->AGC_flag );
- }
-
- /*---------------------------------------------------------------------*
- * MD smoothing
- *---------------------------------------------------------------------*/
-
- if ( st0->m_old_frame_type == ZERO_FRAME && ivas_total_brate == IVAS_SID_5k && st0->prev_bfi == 0 && pState->hMdDec->spar_md_cfg.nchan_transport == 1 )
- {
- ivas_spar_setup_md_smoothing( pState->hMdDec, num_bands_out );
- }
- else
- {
- ivas_spar_update_md_hist( pState->hMdDec );
- }
- }
- else
- {
- if ( !bfi )
- {
- ivas_spar_smooth_md_dtx( pState->hMdDec, num_bands_out );
- }
-
- set_s( pState->hMdDec->valid_bands, 0, IVAS_MAX_NUM_BANDS );
- }
-
- wmops_sub_end();
- return;
-}
-
-
-/*-------------------------------------------------------------------*
- * ivas_spar_get_cldfb_slot_gain()
- *
- *
- *-------------------------------------------------------------------*/
-
-static float ivas_spar_get_cldfb_slot_gain(
- SPAR_DEC_HANDLE hSpar, /* i/o: SPAR FOA decoder handle */
- const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */
- const int16_t time_slot_idx,
- int16_t *time_slot_idx0,
- int16_t *time_slot_idx1,
- float *weight_lowfreq )
-{
- SPAR_DEC_HANDLE pState = hSpar;
- float weight;
- float output_Fs, encfb_delay, decfb_delay;
- float xfade_start_ns;
- int16_t xfade_delay_subframes;
- int16_t i_hist;
- int16_t split_band;
-
- *weight_lowfreq = pState->hFbMixer->cldfb_cross_fade[time_slot_idx];
-
- output_Fs = (float) hDecoderConfig->output_Fs;
- encfb_delay = IVAS_FB_ENC_DELAY_NS;
- decfb_delay = IVAS_FB_DEC_DELAY_NS;
- xfade_start_ns = pState->hFbMixer->cross_fade_start_offset / output_Fs * 1000000000.f - encfb_delay + decfb_delay * 0.5f;
- xfade_delay_subframes = (int16_t) ( xfade_start_ns / ( FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ) );
-
- i_hist = 4 - xfade_delay_subframes;
- split_band = SPAR_DIRAC_SPLIT_START_BAND;
-
- if ( split_band < IVAS_MAX_NUM_BANDS )
- {
- if ( hSpar->i_subframe > 3 )
- {
- weight = (float) ( time_slot_idx % MAX_PARAM_SPATIAL_SUBFRAMES ) / (float) MAX_PARAM_SPATIAL_SUBFRAMES;
- }
- else
- {
- weight = 0.0f;
- }
- *time_slot_idx0 = i_hist;
- *time_slot_idx1 = i_hist + 1;
- }
- else
- {
- /* determine cross-fade gain for current frame Parameters*/
- *time_slot_idx0 = pState->hFbMixer->cldfb_cross_fade_start;
- *time_slot_idx1 = pState->hFbMixer->cldfb_cross_fade_end;
- weight = *weight_lowfreq;
- }
-
- return weight;
-}
-
-
-/*-------------------------------------------------------------------*
- * ivas_spar_get_parameters()
- *
- *
- *-------------------------------------------------------------------*/
-
-void ivas_spar_get_parameters(
- SPAR_DEC_HANDLE hSpar, /* i/o: SPAR FOA decoder handle */
- const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */
- const int16_t ts,
- const int16_t num_ch_out,
- const int16_t num_ch_in,
- const int16_t num_spar_bands,
- float par_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS] )
-{
- int16_t spar_band, out_ch, in_ch;
- float weight, weight_20ms;
- int16_t ts0, ts1, split_band;
-
- weight = ivas_spar_get_cldfb_slot_gain( hSpar, hDecoderConfig, ts, &ts0, &ts1, &weight_20ms );
-
- split_band = SPAR_DIRAC_SPLIT_START_BAND;
- for ( spar_band = 0; spar_band < num_spar_bands; spar_band++ )
- {
- for ( out_ch = 0; out_ch < num_ch_out; out_ch++ )
- {
- for ( in_ch = 0; in_ch < num_ch_in; in_ch++ )
- {
- if ( split_band < IVAS_MAX_NUM_BANDS
- /* 20ms cross-fade for Transport channels in all frequency bands */
- && ( 0 == ivas_is_res_channel( out_ch, hSpar->hMdDec->spar_md_cfg.nchan_transport ) ) /* sub-frame processing for missing channels in all frequency bands*/
- )
- {
- if ( hSpar->i_subframe > 3 )
- {
- par_mat[out_ch][in_ch][spar_band] = ( 1.0f - weight ) * hSpar->hMdDec->mixer_mat_prev[ts0][out_ch][in_ch][spar_band] +
- weight * hSpar->hMdDec->mixer_mat_prev[ts1][out_ch][in_ch][spar_band];
- }
- else
- {
- par_mat[out_ch][in_ch][spar_band] = hSpar->hMdDec->mixer_mat[out_ch][in_ch][spar_band];
- }
- }
- else
- {
- /* 20ms Transport channel reconstruction with matching encoder/decoder processing */
- int16_t prev_idx = SPAR_DIRAC_SPLIT_START_BAND < IVAS_MAX_NUM_BANDS ? 1 : 0; /* if SPAR_DIRAC_SPLIT_START_BAND == IVAS_MAX_NUM_BANDS, then the sub-frame mixer_mat delay line is not active */
- par_mat[out_ch][in_ch][spar_band] = ( 1.0f - weight_20ms ) * hSpar->hMdDec->mixer_mat_prev[prev_idx][out_ch][in_ch][spar_band] + weight_20ms * hSpar->hMdDec->mixer_mat[out_ch][in_ch][spar_band];
- }
- }
- }
- }
-
- return;
-}
-
-
-/*-------------------------------------------------------------------*
- * ivas_spar_get_skip_mat()
- *
- *
- *-------------------------------------------------------------------*/
-
-static void ivas_spar_get_skip_mat(
- SPAR_DEC_HANDLE hSpar, /* i/o: SPAR FOA decoder handle */
- const int16_t num_ch_out,
- const int16_t num_ch_in,
- const int16_t num_spar_bands,
- int16_t skip_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH] )
-{
- int16_t spar_band, out_ch, in_ch;
- int16_t i_ts, skip_flag;
-
- for ( out_ch = 0; out_ch < num_ch_out; out_ch++ )
- {
- for ( in_ch = 0; in_ch < num_ch_in; in_ch++ )
- {
- skip_mat[out_ch][in_ch] = 1;
- skip_flag = 1;
-
- for ( i_ts = 0; i_ts < MAX_PARAM_SPATIAL_SUBFRAMES; i_ts++ )
- {
- for ( spar_band = 0; spar_band < num_spar_bands; spar_band++ )
- {
- if ( hSpar->hMdDec->mixer_mat_prev[1 + i_ts][out_ch][in_ch][spar_band] != 0.0f || hSpar->hMdDec->mixer_mat[out_ch][in_ch][spar_band + i_ts * MAX_PARAM_SPATIAL_SUBFRAMES] != 0.0f )
- {
- skip_flag = 0;
- break;
- }
- }
-
- if ( skip_flag == 0 )
- {
- skip_mat[out_ch][in_ch] = 0;
- break;
- }
- }
- }
- }
-
- return;
-}
-
-
-/*-------------------------------------------------------------------*
- * ivas_spar_foa_dec_upmixer()
- *
- * IVAS SPAR upmixer
- *-------------------------------------------------------------------*/
-
-void ivas_spar_dec_upmixer(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
- float output[][L_FRAME48k], /* i/o: input/output audio channels */
- const int16_t nchan_internal, /* i : number of internal channels */
- const int16_t output_frame /* i : output frame length */
-)
-{
- int16_t cldfb_band, num_cldfb_bands, numch_in, numch_out;
- float *cldfb_in_ts_re[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX];
- float *cldfb_in_ts_im[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX];
- int16_t i, b, ts, out_ch, in_ch;
- int16_t num_spar_bands, spar_band, nchan_transport;
- int16_t num_in_ingest, num_bands_out, split_band;
- float Pcm_tmp[MAX_OUTPUT_CHANNELS][L_FRAME48k];
- int16_t numch_out_dirac;
- float *pPcm_tmp[MAX_OUTPUT_CHANNELS];
- float mixer_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS];
- int16_t b_skip_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
- DECODER_CONFIG_HANDLE hDecoderConfig;
- SPAR_DEC_HANDLE pState, hSpar;
-
- wmops_sub_start( "ivas_spar_dec_upmixer" );
-
- hSpar = st_ivas->hSpar;
- pState = hSpar;
- hDecoderConfig = st_ivas->hDecoderConfig;
- num_bands_out = pState->hFbMixer->pFb->filterbank_num_bands;
- nchan_transport = pState->hMdDec->spar_md_cfg.nchan_transport;
-
- num_cldfb_bands = hSpar->hFbMixer->pFb->fb_bin_to_band.num_cldfb_bands;
- numch_in = hSpar->hFbMixer->fb_cfg->num_in_chans;
- numch_out = hSpar->hFbMixer->fb_cfg->num_out_chans;
-
-#ifdef DEBUG_SPAR_FOA
- if ( fFb_pcm != NULL )
- {
- for ( i = 0; i < output_frame; i++ )
- {
- for ( int16_t j = 0; j < nchan_transport; j++ )
- {
- fscanf( fFb_pcm, "%f\n", &output[j][i] );
- }
- }
- }
-#endif
-
- /* by-pass EVS */
-#ifdef DEBUG_SPAR_BYPASS_EVS_CODEC
- /*write the core coder output to a file for debugging*/
- {
- float tmp;
- int16_t pcm, j;
- for ( j = 0; j < output_frame; j++ )
- {
- for ( i = 0; i < nchan_transport; i++ )
- {
- tmp = roundf( output[i][j] * PCM16_TO_FLT_FAC );
- pcm = ( tmp > MAX16B_FLT ) ? MAX16B : ( tmp < MIN16B_FLT ) ? MIN16B
- : (short) tmp;
- dbgwrite( &pcm, sizeof( int16_t ), 1, 1, "dmx_dec.raw" );
- }
- }
- }
-
- /*overwrite the core coder output with core input for debugging*/
- {
- static FILE *fid_enc = 0;
- int16_t smp;
-
- if ( !fid_enc )
- {
- fid_enc = fopen( "evs_input_float.raw", "rb" );
- }
- for ( smp = 0; smp < L_FRAME48k; smp++ )
- {
- for ( in_ch = 0; in_ch < nchan_transport; in_ch++ )
- {
- fread( &output[in_ch][smp], sizeof( float ), 1, fid_enc );
- }
- }
- }
-#endif
-
- /*---------------------------------------------------------------------*
- * AGC
- *---------------------------------------------------------------------*/
-
- ivas_agc_dec_process( pState->hAgcDec, output, output, nchan_transport, output_frame );
-
- /*---------------------------------------------------------------------*
- * TD Decorr and pcm ingest
- *---------------------------------------------------------------------*/
-
- if ( pState->hMdDec->td_decorr_flag )
- {
- num_in_ingest = nchan_internal;
- }
- else
- {
- num_in_ingest = nchan_transport;
- }
-
- for ( i = 0; i < nchan_internal; i++ )
- {
- pPcm_tmp[i] = Pcm_tmp[i];
- }
-
- /*---------------------------------------------------------------------*
- * PCA decoder
- *---------------------------------------------------------------------*/
-
-#ifdef SBA_CLEANING
- if ( pState->hPCA != NULL )
-#endif
- {
- ivas_pca_dec( pState->hPCA, output_frame, num_in_ingest, hDecoderConfig->ivas_total_brate, hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, output );
- }
-
- /*---------------------------------------------------------------------*
- * TD decorrelation
- *---------------------------------------------------------------------*/
-
- if ( pState->hMdDec->td_decorr_flag )
- {
- ivas_td_decorr_process( pState->hTdDecorr, output, pPcm_tmp, output_frame );
-
- for ( i = 0; i < nchan_internal - nchan_transport; i++ )
- {
- mvr2r( pPcm_tmp[pState->hTdDecorr->num_apd_outputs - 1 - i], output[nchan_internal - 1 - i], output_frame );
- }
-
- pState->hFbMixer->fb_cfg->num_in_chans = num_in_ingest;
- }
- else
- {
- pState->hFbMixer->fb_cfg->num_in_chans = num_in_ingest;
- }
-
- /*---------------------------------------------------------------------*
- * Prepare CLDFB buffers
- *---------------------------------------------------------------------*/
-
- /* set-up pointers */
- if ( st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_FOA )
- {
- /* at this point, output channels are used as intermediate procesing buffers */
- for ( in_ch = 0; in_ch < MAX_OUTPUT_CHANNELS; in_ch++ )
- {
- for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ )
- {
- cldfb_in_ts_re[in_ch][ts] = &Pcm_tmp[in_ch][ts * num_cldfb_bands];
- cldfb_in_ts_im[in_ch][ts] = &Pcm_tmp[in_ch][ts * num_cldfb_bands + 4 * num_cldfb_bands];
- }
- }
- }
- else
- {
- for ( in_ch = 0; in_ch < numch_in; in_ch++ )
- {
- for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ )
- {
- cldfb_in_ts_re[in_ch][ts] = &Pcm_tmp[in_ch][ts * num_cldfb_bands];
- cldfb_in_ts_im[in_ch][ts] = &Pcm_tmp[in_ch][ts * num_cldfb_bands + 4 * num_cldfb_bands];
- }
- }
- }
-
-
- /*---------------------------------------------------------------------*
- * Gen umx mat
- *---------------------------------------------------------------------*/
-
- ivas_spar_dec_gen_umx_mat( pState->hMdDec, nchan_transport, num_bands_out, st_ivas->bfi );
-
-
- /*---------------------------------------------------------------------*
- * CLDFB Processing and Synthesis
- *---------------------------------------------------------------------*/
-
- num_spar_bands = hSpar->hFbMixer->pFb->filterbank_num_bands;
-
- /* apply parameters */
- /* determine if we can skip certain data */
- ivas_spar_get_skip_mat( hSpar, numch_out, numch_in, num_spar_bands, b_skip_mat ); /* this can be precomputed based on bitrate and format*/
-
- numch_out_dirac = st_ivas->hDecoderConfig->nchan_out;
-
- for ( int16_t i_sf = 0; i_sf < MAX_PARAM_SPATIAL_SUBFRAMES; i_sf++ )
- {
- /* CLDFB analysis of incoming frame */
- for ( in_ch = 0; in_ch < numch_in; in_ch++ )
- {
- for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ )
- {
- cldfbAnalysis_ts(
- &output[in_ch][( ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES ) * num_cldfb_bands],
- cldfb_in_ts_re[in_ch][ts],
- cldfb_in_ts_im[in_ch][ts],
- num_cldfb_bands,
- st_ivas->cldfbAnaDec[in_ch] );
- }
- }
-
- for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ )
- {
- /* determine SPAR parameters for this time slots */
- ivas_spar_get_parameters( hSpar, st_ivas->hDecoderConfig, ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES, numch_out, numch_in, num_spar_bands, mixer_mat );
-
- for ( cldfb_band = 0; cldfb_band < num_cldfb_bands; cldfb_band++ )
- {
- float out_re[IVAS_SPAR_MAX_CH];
- float out_im[IVAS_SPAR_MAX_CH];
- float cldfb_par;
- ivas_fb_bin_to_band_data_t *bin2band = &pState->hFbMixer->pFb->fb_bin_to_band;
-
- for ( out_ch = 0; out_ch < numch_out; out_ch++ )
- {
- out_re[out_ch] = 0.0f;
- out_im[out_ch] = 0.0f;
-
- for ( in_ch = 0; in_ch < numch_in; in_ch++ )
- {
- if ( b_skip_mat[out_ch][in_ch] )
- {
- continue;
- }
- else if ( cldfb_band < CLDFB_PAR_WEIGHT_START_BAND ) /* tuning parameter, depends on how much SPAR Filters overlap for the CLDFB bands */
- {
- spar_band = bin2band->p_cldfb_map_to_spar_band[cldfb_band];
- cldfb_par = mixer_mat[out_ch][in_ch][spar_band];
- }
- else
- {
- cldfb_par = 0.0f;
- for ( spar_band = bin2band->p_spar_start_bands[cldfb_band]; spar_band < num_spar_bands; spar_band++ )
- {
- /* accumulate contributions from all SPAR bands */
- cldfb_par += mixer_mat[out_ch][in_ch][spar_band] * bin2band->pp_cldfb_weights_per_spar_band[cldfb_band][spar_band];
- }
- }
-
- out_re[out_ch] += cldfb_in_ts_re[in_ch][ts][cldfb_band] * cldfb_par;
- out_im[out_ch] += cldfb_in_ts_im[in_ch][ts][cldfb_band] * cldfb_par;
- }
- }
-
- /*update CLDFB data with the parameter-modified data*/
- for ( out_ch = 0; out_ch < numch_out; out_ch++ )
- {
- cldfb_in_ts_re[out_ch][ts][cldfb_band] = out_re[out_ch];
- cldfb_in_ts_im[out_ch][ts][cldfb_band] = out_im[out_ch];
- }
- }
- }
-
- if ( st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_FOA )
- {
-#ifdef SBA_CLEANING
- ivas_dirac_dec( st_ivas, output, nchan_internal, cldfb_in_ts_re, cldfb_in_ts_im, i_sf );
-#else
- nchan_transport = ivas_sba_get_nchan_metadata( st_ivas->sba_order ); // VE: == nchan_internal that is already set correctly
-
- ivas_dirac_dec( st_ivas, output, nchan_transport, cldfb_in_ts_re, cldfb_in_ts_im, i_sf );
-#endif
- }
-
- if ( st_ivas->hDirAC != NULL )
- {
- int16_t outchannels, idx_in, idx_lfe, ch;
- idx_in = 0;
- idx_lfe = 0;
-
- outchannels = st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe;
- for ( ch = 0; ch < outchannels; ch++ )
- {
- if ( ( st_ivas->hOutSetup.num_lfe > 0 ) && ( st_ivas->hOutSetup.index_lfe[idx_lfe] == ch ) )
- {
- set_zero( &( output[ch][i_sf * MAX_PARAM_SPATIAL_SUBFRAMES * num_cldfb_bands] ), MAX_PARAM_SPATIAL_SUBFRAMES * num_cldfb_bands );
-
- if ( idx_lfe < ( st_ivas->hDirAC->hOutSetup.num_lfe - 1 ) )
- {
- idx_lfe++;
- }
- }
- else
- {
- if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_FOA ||
- !( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL || st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM ) )
- {
- for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ )
- {
- cldfbSynthesis(
- &cldfb_in_ts_re[idx_in][ts],
- &cldfb_in_ts_im[idx_in][ts],
- &output[ch][( ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES ) * num_cldfb_bands],
- num_cldfb_bands,
- st_ivas->cldfbSynDec[idx_in] );
- }
- }
- idx_in++;
- }
- }
- }
- else
- {
- /* CLDFB to time synthesis (overwrite mixer output) */
- for ( out_ch = 0; out_ch < numch_out_dirac; out_ch++ )
- {
- for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ )
- {
- cldfbSynthesis(
- &cldfb_in_ts_re[out_ch][ts],
- &cldfb_in_ts_im[out_ch][ts],
- &output[out_ch][( ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES ) * num_cldfb_bands],
- num_cldfb_bands,
- st_ivas->cldfbSynDec[out_ch]
-
- );
- }
- }
- }
-
- split_band = SPAR_DIRAC_SPLIT_START_BAND;
- if ( split_band < IVAS_MAX_NUM_BANDS )
- {
- pState->i_subframe++;
- pState->i_subframe = min( pState->i_subframe, MAX_PARAM_SPATIAL_SUBFRAMES );
- mvr2r( pState->hMdDec->mixer_mat_prev[1][0][0], pState->hMdDec->mixer_mat_prev[0][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS );
- mvr2r( pState->hMdDec->mixer_mat_prev[2][0][0], pState->hMdDec->mixer_mat_prev[1][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS );
- mvr2r( pState->hMdDec->mixer_mat_prev[3][0][0], pState->hMdDec->mixer_mat_prev[2][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS );
- mvr2r( pState->hMdDec->mixer_mat_prev[4][0][0], pState->hMdDec->mixer_mat_prev[3][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS );
-
- for ( out_ch = 0; out_ch < numch_out; out_ch++ )
- {
- for ( in_ch = 0; in_ch < numch_in; in_ch++ )
- {
- for ( b = 0; b < num_spar_bands; b++ )
- {
- pState->hMdDec->mixer_mat_prev[4][out_ch][in_ch][b] = pState->hMdDec->mixer_mat[out_ch][in_ch][b + i_sf * IVAS_MAX_NUM_BANDS];
- }
- }
- }
- }
- }
-
- wmops_sub_end();
-
- return;
-}
diff --git a/lib_dec/ivas_spar_foa_md_dec.c b/lib_dec/ivas_spar_md_dec.c
similarity index 99%
rename from lib_dec/ivas_spar_foa_md_dec.c
rename to lib_dec/ivas_spar_md_dec.c
index 56fdf91bcfbcb96fe612109ac36086b4c785f288..291bbc56193f345ce5c27603a1fcb5e9cc350a20 100644
--- a/lib_dec/ivas_spar_foa_md_dec.c
+++ b/lib_dec/ivas_spar_md_dec.c
@@ -603,7 +603,7 @@ static ivas_error ivas_spar_set_dec_config(
/*-----------------------------------------------------------------------------------------*
* Function ivas_spar_foa_md_dec_process()
*
- * SPAR FOA Meta Data decoder process
+ * SPAR Meta Data decoder process
*-----------------------------------------------------------------------------------------*/
void ivas_spar_md_dec_process(
diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h
index e09632c1f5cd3d6549f867ec7083d20bfc67b8a0..b9218ecaaa2ced195a0c553a1769668a0e8558cb 100644
--- a/lib_dec/ivas_stat_dec.h
+++ b/lib_dec/ivas_stat_dec.h
@@ -780,7 +780,7 @@ typedef struct ivas_param_mc_dec_data_structure
* SPAR decoder structures
*------------------------------------------------------------------------------------------*/
-/* SPAR FOA MD structure */
+/* SPAR MD structure */
typedef struct ivas_spar_dec_matrices_t
{
float ***C_re;
@@ -865,7 +865,6 @@ typedef struct
} PCA_DEC_STATE;
-/* SPAR FOA structures */
/* main SPAR decoder structure */
typedef struct ivas_spar_dec_lib_t
{
@@ -879,6 +878,7 @@ typedef struct ivas_spar_dec_lib_t
int16_t enc_param_start_band;
int32_t core_nominal_brate; /* Nominal bitrate for core coding */
int32_t i_subframe;
+
} SPAR_DEC_DATA, *SPAR_DEC_HANDLE;
diff --git a/lib_enc/ivas_agc_enc.c b/lib_enc/ivas_agc_enc.c
index d001f8f48485860a46a4d2e04d988d59f6bf6353..45326ce8a713c003a1a947fdae0806dd9d003c09 100644
--- a/lib_enc/ivas_agc_enc.c
+++ b/lib_enc/ivas_agc_enc.c
@@ -475,7 +475,7 @@ void ivas_agc_enc_process(
if ( ivas_agc_writeBits( agcOut, pIn_buf, pState ) )
{
/* TODO: return error once error codes are harmonized */
- IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "SPAR FOA ENC AGC Failed to open agcOut\n " );
+ IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "SPAR ENC AGC Failed to open agcOut\n " );
}
#endif
diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c
index c0dc1b7276676ef26410cda18f54a8ec923a8099..ea2694a8881369ae1f3e3138e68b926b165224f4 100644
--- a/lib_enc/ivas_core_pre_proc_front.c
+++ b/lib_enc/ivas_core_pre_proc_front.c
@@ -98,9 +98,9 @@ ivas_error pre_proc_front_ivas(
const int16_t localVAD_HE_SAD_LR[CPE_CHANNELS], /* i : HE-SAD flag without hangover, LR channels */
float band_energies_LR[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN */
const int16_t flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz */
- const int16_t spar_front_vad_flag, /* i : front-VAD flag to overwrite VAD decision */
- const int16_t spar_force_front_vad, /* i : flag to force VAD decision */
- const int16_t spar_front_vad_dtx_flag /* i : front-VAD DTX flag to overwrite VAD decision*/
+ const int16_t front_vad_flag, /* i : front-VAD flag to overwrite VAD decision */
+ const int16_t force_front_vad, /* i : flag to force VAD decision */
+ const int16_t front_vad_dtx_flag /* i : front-VAD DTX flag to overwrite VAD decision*/
)
{
float *inp_12k8, *new_inp_12k8; /* pointers to current frame and new data */
@@ -442,11 +442,11 @@ ivas_error pre_proc_front_ivas(
}
#endif
- if ( spar_force_front_vad == 1 || spar_front_vad_flag == 1 )
+ if ( force_front_vad == 1 || front_vad_flag == 1 )
{
/* overwrite VAD decision with front-VAD decision if external VAD is set to 1*/
- st->vad_flag = spar_front_vad_flag;
- st->localVAD = spar_front_vad_flag;
+ st->vad_flag = front_vad_flag;
+ st->localVAD = front_vad_flag;
}
if ( ( hCPE != NULL && !( lr_vad_enabled && st->idchan == 0 ) ) || hSCE != NULL )
@@ -466,10 +466,10 @@ ivas_error pre_proc_front_ivas(
*vad_hover_flag = *vad_flag_dtx && !( LR_localVAD || st->localVAD );
}
- if ( spar_force_front_vad == 1 || spar_front_vad_dtx_flag == 1 )
+ if ( force_front_vad == 1 || front_vad_dtx_flag == 1 )
{
/* overwrite VAD decision with front-VAD decision if external VAD is set to 1*/
- *vad_flag_dtx = spar_front_vad_dtx_flag;
+ *vad_flag_dtx = front_vad_dtx_flag;
}
/*----------------------------------------------------------------*
diff --git a/lib_enc/ivas_entropy_coder.c b/lib_enc/ivas_entropy_coder.c
index 3dfe74fef21d88055d23b906ad50a8d62df8d287..d43d1e4f6c8941b339a12b992186b7888208472c 100644
--- a/lib_enc/ivas_entropy_coder.c
+++ b/lib_enc/ivas_entropy_coder.c
@@ -132,7 +132,7 @@ static ivas_error ivas_get_dyn_freq_model(
if ( fabs( curr_bps_min - ref_min_bps ) > MREF_BPS_TOL )
{
- return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "SPAR FOA model selection min BPS mismatch: %f, ref: %f, diff: %f \n", curr_bps_min, ref_min_bps, curr_bps_min - ref_min_bps );
+ return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "SPAR model selection min BPS mismatch: %f, ref: %f, diff: %f \n", curr_bps_min, ref_min_bps, curr_bps_min - ref_min_bps );
}
else
{
diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc.c
index 0e67b75cb59f69d18faae889b849e608ec4dc98d..c78bce4b859e54073743bc34535f5139d991cce2 100644
--- a/lib_enc/ivas_init_enc.c
+++ b/lib_enc/ivas_init_enc.c
@@ -430,11 +430,10 @@ ivas_error ivas_init_encoder(
return error;
}
}
+
+ if ( ( error = ivas_dirac_enc_open( st_ivas ) ) != IVAS_ERR_OK )
{
- if ( ( error = ivas_dirac_enc_open( st_ivas ) ) != IVAS_ERR_OK )
- {
- return error;
- }
+ return error;
}
}
else
@@ -459,6 +458,11 @@ ivas_error ivas_init_encoder(
st_ivas->hSCE[sce_id]->hMetaData->ind_list = ind_list_metadata[sce_id];
reset_indices_enc( st_ivas->hSCE[sce_id]->hMetaData, MAX_BITS_METADATA );
+
+ if ( st_ivas->sba_mode == SBA_MODE_SPAR && st_ivas->hEncoderConfig->Opt_DTX_ON )
+ {
+ st_ivas->hSCE[sce_id]->hCoreCoder[0]->dtx_sce_sba = 1;
+ }
}
for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
diff --git a/lib_enc/ivas_sce_enc.c b/lib_enc/ivas_sce_enc.c
index c6bf72e4a74af21fe3afa1ba3ce445512f6823c6..388e7b4875537f9878b543365f958a98526beb97 100644
--- a/lib_enc/ivas_sce_enc.c
+++ b/lib_enc/ivas_sce_enc.c
@@ -175,18 +175,11 @@ ivas_error ivas_sce_enc(
* Front Pre-processing
*----------------------------------------------------------------*/
- if ( st_ivas->sba_mode == SBA_MODE_SPAR && st_ivas->hEncoderConfig->Opt_DTX_ON )
- {
- st->dtx_sce_sba = 1;
- }
-
error = pre_proc_front_ivas( hSCE, NULL, hSCE->element_brate, nb_bits_metadata, input_frame, 0, old_inp_12k8[0], old_inp_16k[0],
&Etot[0], &ener[0], &relE[0], A[0], Aw[0], epsP[0], lsp_new[0], lsp_mid[0],
&vad_hover_flag[0], &attack_flag[0], realBuffer[0], imagBuffer[0], old_wsp[0], pitch_fr[0], voicing_fr[0], &loc_harm[0], &cor_map_sum[0], &vad_flag_dtx[0], enerBuffer[0],
- fft_buff[0], A[0], lsp_new[0], currFlatness[0], 0, fr_bands, Etot_LR, lf_E, localVAD_HE_SAD, NULL,
- flag_16k_smc,
+ fft_buff[0], A[0], lsp_new[0], currFlatness[0], 0, fr_bands, Etot_LR, lf_E, localVAD_HE_SAD, NULL, flag_16k_smc,
st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_flag : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->force_front_vad : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_dtx_flag : 0 );
-
if ( error != IVAS_ERR_OK )
{
return error;
diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c
index 8254f306b7005cc8f4271e678e318b188a112e5c..2647d96df3fcf68d60863336e09f92c52e3392f2 100644
--- a/lib_enc/ivas_spar_encoder.c
+++ b/lib_enc/ivas_spar_encoder.c
@@ -39,10 +39,18 @@
#include "ivas_rom_com.h"
#include "ivas_stat_com.h"
#include "prot.h"
+#include "math.h"
#include
#include "wmops.h"
+/*-------------------------------------------------------------------*
+ * Local function prototypes
+ *--------------------------------------------------------------------*/
+
+static ivas_error ivas_spar_enc_process( Encoder_Struct *st_ivas, const ENCODER_CONFIG_HANDLE hEncoderConfig, BSTR_ENC_HANDLE hMetaData, const int16_t front_vad_flag, float data_f[][L_FRAME48k] );
+
+
/*-------------------------------------------------------------------------
* ivas_spar_enc_open()
*
@@ -317,3 +325,617 @@ ivas_error ivas_spar_enc(
return error;
}
+
+#ifdef DEBUG_SPAR_FOA
+extern FILE *fEvs_enc_in;
+extern FILE *fFb_out[4];
+#endif
+
+
+/*-----------------------------------------------------------------------------------------*
+ * Function ivas_spar_enc_get_windowed_fr()
+ *
+ * Get windowed FRs
+ *-----------------------------------------------------------------------------------------*/
+
+static void ivas_spar_enc_get_windowed_fr(
+ IVAS_FB_MIXER_HANDLE hFbMixer,
+ float *pIn_blocks[IVAS_SPAR_MAX_CH],
+ ivas_enc_cov_handler_in_buf_t *pCov_in_buf,
+ const int16_t input_frame,
+ const int16_t nchan_inp,
+ const int16_t num_past_samples )
+{
+ int16_t i, j, rev_offset;
+
+ for ( i = 0; i < nchan_inp; i++ )
+ {
+ const int16_t stride = hFbMixer->pFb->fb_bin_to_band.short_stride;
+ float tmp_buf[MDFT_FB_BANDS_240 * 2];
+ int16_t win_len = (int16_t) hFbMixer->ana_window_offset;
+ float *mdft_in_ptr = tmp_buf + stride - win_len;
+ float tmp_in_block[L_FRAME48k + MDFT_FB_BANDS_240];
+ float *data_ptr = tmp_in_block;
+ float *fr_re_ptr = pCov_in_buf->ppIn_FR_real[i];
+ float *fr_im_ptr = pCov_in_buf->ppIn_FR_imag[i];
+
+ set_f( tmp_buf, 0, MDFT_FB_BANDS_240 * 2 );
+
+ /* copy input data, because pIn_blocks and fr_re_ptr + fr_im_ptr use the same memory */
+ mvr2r( &pIn_blocks[i][input_frame - num_past_samples], tmp_in_block, input_frame + win_len );
+
+ for ( int16_t blk = 0; blk < input_frame / stride; blk++ )
+ {
+
+ for ( j = 0; j < win_len; j++ )
+ {
+ mdft_in_ptr[j] = data_ptr[j] * hFbMixer->pAna_window[j];
+ }
+
+ for ( j = win_len; j < stride; j++ )
+ {
+ mdft_in_ptr[j] = data_ptr[j];
+ }
+
+ rev_offset = win_len - 1;
+ for ( j = stride; j < stride + win_len; j++ )
+ {
+ mdft_in_ptr[j] = data_ptr[j] * hFbMixer->pAna_window[rev_offset--];
+ }
+
+ ivas_mdft( tmp_buf, fr_re_ptr, fr_im_ptr, stride << 1, stride );
+
+ data_ptr += stride;
+ fr_re_ptr += stride;
+ fr_im_ptr += stride;
+ }
+ }
+
+ return;
+}
+
+
+/*-----------------------------------------------------------------------------------------*
+ * Function ivas_spar_enc_process()
+ *
+ * Process call for SPAR encoder
+ *-----------------------------------------------------------------------------------------*/
+
+static ivas_error ivas_spar_enc_process(
+ Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */
+ const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */
+ BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */
+ const int16_t front_vad_flag, /* i : front-VAD decision */
+ float data_f[][L_FRAME48k] /* i/o: input/transport audio channels */
+)
+{
+ float pcm_tmp[IVAS_SPAR_MAX_CH][L_FRAME48k * 2];
+ float *p_pcm_tmp[IVAS_SPAR_MAX_CH];
+ int16_t i, j, k, b, i_ts, input_frame, num_bands_bw;
+ int16_t dtx_vad, dtx_cov_flag, dtx_silence_mode;
+ int32_t ivas_total_brate, input_Fs;
+ ivas_enc_cov_handler_in_buf_t cov_in_buf;
+ float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
+ float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
+ ivas_spar_md_enc_in_buf_t md_in_buf;
+ int16_t nchan_inp, nchan_transport, bwidth, sba_order;
+ int16_t table_idx;
+ int16_t in_out_mixer_map[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH];
+ ivas_error error;
+ const int16_t *order;
+ SPAR_ENC_HANDLE pState = st_ivas->hSpar;
+ IVAS_QMETADATA_HANDLE hQMetaData = st_ivas->hQMetaData;
+ int16_t ts, l_ts, orig_dirac_bands, num_del_samples;
+ float *ppIn_FR_real[IVAS_SPAR_MAX_CH], *ppIn_FR_imag[IVAS_SPAR_MAX_CH];
+ float w_del_buf[IVAS_FB_1MS_48K_SAMP];
+ float dir[3], avg_dir[3];
+ float energySum, vecLen;
+
+ wmops_sub_start( "ivas_spar_enc_process" );
+
+ /*-----------------------------------------------------------------------------------------*
+ * Initialization
+ *-----------------------------------------------------------------------------------------*/
+
+ error = IVAS_ERR_OK;
+
+ input_Fs = hEncoderConfig->input_Fs;
+ ivas_total_brate = hEncoderConfig->ivas_total_brate;
+ num_del_samples = pState->hFbMixer->fb_cfg->fb_latency;
+
+ input_frame = ( int16_t )( input_Fs / FRAMES_PER_SEC );
+ sba_order = min( hEncoderConfig->sba_order, IVAS_MAX_SBA_ORDER );
+ nchan_inp = ivas_sba_get_nchan_metadata( sba_order );
+ assert( nchan_inp <= hEncoderConfig->nchan_inp );
+
+ for ( i = FOA_CHANNELS + 1; i < nchan_inp; i++ )
+ {
+ mvr2r( data_f[HOA_keep_ind[i]], data_f[i], input_frame );
+ }
+
+ table_idx = ivas_get_spar_table_idx( ivas_total_brate, sba_order, SPAR_CONFIG_BW, NULL, NULL );
+
+ /*-----------------------------------------------------------------------------------------*
+ * Transient detector
+ *-----------------------------------------------------------------------------------------*/
+
+ cov_in_buf.transient_det = ivas_transient_det_process( pState->hTranDet, data_f[0], input_frame );
+
+ /* store previous input samples for W in local buffer */
+ assert( num_del_samples <= IVAS_FB_1MS_48K_SAMP );
+ mvr2r( &pState->hFbMixer->ppFilterbank_prior_input[0][pState->hFbMixer->fb_cfg->prior_input_length - num_del_samples], w_del_buf, num_del_samples );
+
+ /*-----------------------------------------------------------------------------------------*
+ * FB mixer ingest
+ *-----------------------------------------------------------------------------------------*/
+
+ for ( i = 0; i < nchan_inp; i++ )
+ {
+ p_pcm_tmp[i] = pcm_tmp[i];
+ }
+
+ /* run Filter Bank overlapping MDFT analysis first, then we can use the temporary buffer for Parameter MDFT analysis*/
+ ivas_fb_mixer_pcm_ingest( pState->hFbMixer, data_f, p_pcm_tmp, input_frame );
+
+ /* prepare Parameter MDFT analysis */
+ for ( i = 0; i < nchan_inp; i++ )
+ {
+ cov_in_buf.ppIn_FR_real[i] = p_pcm_tmp[i];
+ cov_in_buf.ppIn_FR_imag[i] = p_pcm_tmp[i] + input_frame;
+ }
+
+ for ( i = 0; i < nchan_inp; i++ )
+ {
+ p_pcm_tmp[i] = &data_f[i][0];
+ ppIn_FR_real[i] = cov_in_buf.ppIn_FR_real[i];
+ ppIn_FR_imag[i] = cov_in_buf.ppIn_FR_imag[i];
+ }
+
+ l_ts = input_frame / MAX_PARAM_SPATIAL_SUBFRAMES;
+
+ for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ )
+ {
+ ivas_fb_mixer_get_windowed_fr( pState->hFbMixer, p_pcm_tmp, ppIn_FR_real, ppIn_FR_imag, l_ts, l_ts );
+ ivas_fb_mixer_update_prior_input( pState->hFbMixer, p_pcm_tmp, l_ts );
+
+ for ( i = 0; i < nchan_inp; i++ )
+ {
+ p_pcm_tmp[i] += l_ts;
+ ppIn_FR_real[i] += l_ts;
+ ppIn_FR_imag[i] += l_ts;
+ }
+ }
+
+ /* turn pointers back to the local buffer, needed for the following processing */
+ for ( i = 0; i < nchan_inp; i++ )
+ {
+ p_pcm_tmp[i] = pcm_tmp[i];
+ }
+
+ cov_in_buf.num_ch = nchan_inp;
+
+ dtx_vad = ( hEncoderConfig->Opt_DTX_ON == 1 ) ? front_vad_flag : 1;
+
+ /*-----------------------------------------------------------------------------------------*
+ * DirAC encoding
+ *-----------------------------------------------------------------------------------------*/
+
+ ivas_dirac_param_est_enc( st_ivas->hDirAC, hQMetaData->q_direction, hQMetaData->useLowerRes,
+ data_f, cov_in_buf.ppIn_FR_real, cov_in_buf.ppIn_FR_imag, input_frame );
+
+ if ( hQMetaData->q_direction->cfg.nbands > 0 )
+ {
+ orig_dirac_bands = hQMetaData->q_direction[0].cfg.nbands;
+
+ if ( dtx_vad == 1 )
+ {
+ /* WB 4TC mode bit : disable for now*/
+ push_next_indice( hMetaData, 0, 1 );
+ ivas_qmetadata_enc_encode( hMetaData, hQMetaData );
+ }
+ else
+ {
+ hQMetaData->q_direction[0].cfg.nbands = DIRAC_DTX_BANDS;
+
+ /* compute directions */
+ for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
+ {
+ set_zero( dir, 3 );
+ set_zero( avg_dir, 3 );
+ energySum = 0.0f;
+
+ /*combine all dirac bands except the last one, handle last band separately, last band covers BW above WB*/
+ for ( j = 0; j < orig_dirac_bands - 1; j++ )
+ {
+ ivas_qmetadata_azimuth_elevation_to_direction_vector( hQMetaData->q_direction[0].band_data[j].azimuth[i], hQMetaData->q_direction[0].band_data[j].elevation[i], &dir[0] );
+ vecLen = hQMetaData->q_direction[0].band_data[j].energy_ratio[i] * st_ivas->hDirAC->buffer_energy[i * orig_dirac_bands + j];
+
+ avg_dir[0] += dir[0] * vecLen;
+ avg_dir[1] += dir[1] * vecLen;
+ avg_dir[2] += dir[2] * vecLen;
+
+ energySum += st_ivas->hDirAC->buffer_energy[i * orig_dirac_bands + j];
+ }
+
+ ivas_qmetadata_direction_vector_to_azimuth_elevation( &avg_dir[0], &hQMetaData->q_direction[0].band_data[0].azimuth[i], &hQMetaData->q_direction[0].band_data[0].elevation[i] );
+ hQMetaData->q_direction[0].band_data[0].energy_ratio[i] = sqrtf( dotp( avg_dir, avg_dir, 3 ) ) / ( energySum + EPSILON );
+
+ hQMetaData->q_direction[0].band_data[1].azimuth[i] = hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].azimuth[i];
+ hQMetaData->q_direction[0].band_data[1].elevation[i] = hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].elevation[i];
+ hQMetaData->q_direction[0].band_data[1].energy_ratio[i] = hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].energy_ratio[i];
+ }
+
+ /* 1 bit to indicate mode MD coding : temp solution*/
+ push_next_indice( hMetaData, 1, 1 );
+
+ /* encode SID parameters */
+ ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, -1, SBA_FORMAT, st_ivas->sba_mode );
+ }
+
+ for ( b = hQMetaData->q_direction->cfg.start_band; b < hQMetaData->q_direction->cfg.nbands; b++ )
+ {
+ for ( i_ts = 0; i_ts < ( ( dtx_vad == 1 ) ? hQMetaData->q_direction[0].cfg.nblocks : 1 ); i_ts++ )
+ {
+ hQMetaData->q_direction->band_data[b].azimuth[i_ts] = hQMetaData->q_direction->band_data[b].q_azimuth[i_ts];
+ hQMetaData->q_direction->band_data[b].elevation[i_ts] = hQMetaData->q_direction->band_data[b].q_elevation[i_ts];
+ hQMetaData->q_direction[0].band_data[b].energy_ratio[0] = 1.0f - diffuseness_reconstructions[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]];
+ }
+ }
+
+ if ( dtx_vad == 0 )
+ {
+
+ for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
+ {
+ hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].azimuth[i] = hQMetaData->q_direction[0].band_data[1].azimuth[0];
+ hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].elevation[i] = hQMetaData->q_direction[0].band_data[1].elevation[0];
+ hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].energy_ratio[i] = hQMetaData->q_direction[0].band_data[1].energy_ratio[0];
+ }
+
+ for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
+ {
+ for ( j = orig_dirac_bands - 2; j >= 0; j-- )
+ {
+ hQMetaData->q_direction[0].band_data[j].azimuth[i] = hQMetaData->q_direction[0].band_data[0].azimuth[0];
+ hQMetaData->q_direction[0].band_data[j].elevation[i] = hQMetaData->q_direction[0].band_data[0].elevation[0];
+ hQMetaData->q_direction[0].band_data[j].energy_ratio[i] = hQMetaData->q_direction[0].band_data[0].energy_ratio[0];
+ }
+ }
+
+ hQMetaData->q_direction->cfg.nbands = orig_dirac_bands;
+ }
+ }
+
+
+ /*-----------------------------------------------------------------------------------------*
+ * Pre-proc flags
+ *-----------------------------------------------------------------------------------------*/
+
+ /* use just VAD function to get VAD flags */
+ dtx_vad = ( hEncoderConfig->Opt_DTX_ON == 1 ) ? front_vad_flag : 1;
+ dtx_cov_flag = ( dtx_vad == 1 ) ? 0 : 1;
+ dtx_silence_mode = 0;
+ bwidth = ivas_get_bw_idx_from_sample_rate( input_Fs );
+ bwidth = min( bwidth, hEncoderConfig->max_bwidth );
+
+ /*-----------------------------------------------------------------------------------------*
+ * Covariance process
+ *-----------------------------------------------------------------------------------------*/
+
+ cov_in_buf.num_ch = nchan_inp;
+
+ for ( i = 0; i < nchan_inp; i++ )
+ {
+ for ( j = 0; j < nchan_inp; j++ )
+ {
+ cov_real[i][j] = pState->hMdEnc->cov_real[i][j];
+ cov_dtx_real[i][j] = pState->hMdEnc->cov_dtx_real[i][j];
+ }
+ }
+
+ cov_in_buf.dtx_cov_flag = dtx_cov_flag;
+ ivas_enc_cov_handler_process( pState->hCovEnc, &cov_in_buf, cov_real, cov_dtx_real, pState->hFbMixer->pFb, 0, pState->hFbMixer->pFb->filterbank_num_bands );
+
+ if ( pState->hMdEnc->table_idx != table_idx )
+ {
+ pState->hMdEnc->table_idx = table_idx;
+ ivas_spar_set_bitrate_config( &pState->hMdEnc->spar_md_cfg, table_idx, SPAR_DIRAC_SPLIT_START_BAND );
+ }
+
+ nchan_transport = pState->hMdEnc->spar_md_cfg.nchan_transport;
+
+ /*-----------------------------------------------------------------------------------------*
+ * MetaData encoder
+ *-----------------------------------------------------------------------------------------*/
+
+ num_bands_bw = ivas_get_num_bands_from_bw_idx( bwidth );
+
+ if ( dtx_vad == 0 )
+ {
+ for ( i = 0; i < nchan_inp; i++ )
+ {
+ for ( j = 0; j < nchan_inp; j++ )
+ {
+ md_in_buf.cov_real[i][j] = cov_dtx_real[i][j];
+ for ( k = num_bands_bw; k < IVAS_MAX_NUM_BANDS; k++ )
+ {
+ md_in_buf.cov_real[i][j][k] = 0;
+ }
+ }
+ }
+ }
+ else
+ {
+ for ( i = 0; i < nchan_inp; i++ )
+ {
+ for ( j = 0; j < nchan_inp; j++ )
+ {
+ md_in_buf.cov_real[i][j] = cov_real[i][j];
+ for ( k = num_bands_bw; k < IVAS_MAX_NUM_BANDS; k++ )
+ {
+ md_in_buf.cov_real[i][j][k] = 0;
+ }
+ }
+ }
+ }
+
+ md_in_buf.num_bands = ivas_get_num_bands_from_bw_idx( SPAR_CONFIG_BW );
+ md_in_buf.num_bands = min( md_in_buf.num_bands, SPAR_DIRAC_SPLIT_START_BAND );
+
+ md_in_buf.dtx_vad = dtx_vad;
+
+ ivas_spar_md_enc_process( pState->hMdEnc, hEncoderConfig, &md_in_buf, hMetaData, dtx_silence_mode );
+
+ if ( st_ivas->sba_mode == SBA_MODE_SPAR )
+ {
+ float azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
+ float ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
+ float diffuseness[IVAS_MAX_NUM_BANDS];
+ float Wscale_d[IVAS_MAX_NUM_BANDS];
+ int16_t d_start_band, d_end_band;
+ int16_t dirac_band_idx;
+
+ d_start_band = st_ivas->hSpar->enc_param_start_band;
+ d_end_band = IVAS_MAX_NUM_BANDS;
+
+ for ( b = d_start_band; b < d_end_band; b++ )
+ {
+ dirac_band_idx = st_ivas->hSpar->dirac_to_spar_md_bands[b] - d_start_band;
+ for ( i_ts = 0; i_ts < hQMetaData->q_direction->cfg.nblocks; i_ts++ )
+ {
+ azi_dirac[b][i_ts] = hQMetaData->q_direction->band_data[dirac_band_idx].azimuth[i_ts];
+ ele_dirac[b][i_ts] = hQMetaData->q_direction->band_data[dirac_band_idx].elevation[i_ts];
+ }
+ diffuseness[b] = 1.0f - hQMetaData->q_direction->band_data[dirac_band_idx].energy_ratio[0];
+ }
+
+ if ( ( d_start_band >= 6 ) && ( dtx_vad == 1 ) )
+ {
+ for ( i = 0; i < IVAS_SPAR_MAX_CH - 1; i++ )
+ {
+ pState->hMdEnc->spar_md.band_coeffs[d_start_band - 1].P_re[i] =
+ pState->hMdEnc->spar_md.band_coeffs[d_start_band - 1].P_quant_re[i];
+ }
+ }
+
+ for ( b = d_start_band; b < d_end_band; b++ )
+ {
+ Wscale_d[b] = 1.0f;
+ for ( i = 1; i < nchan_inp; i++ )
+ {
+ Wscale_d[b] += md_in_buf.cov_real[i][i][b] / max( EPSILON, md_in_buf.cov_real[0][0][b] );
+ }
+ Wscale_d[b] = Wscale_d[b] / ( 1.0f + (float) sba_order ); /*DirAC normalized signal variance sums to 1 + order*/
+ Wscale_d[b] = sqrtf( Wscale_d[b] );
+ Wscale_d[b] = min( 2.0f, max( Wscale_d[b], 1.0f ) );
+ }
+
+ ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, 1, pState->hMdEnc->mixer_mat, &pState->hMdEnc->spar_md, &pState->hMdEnc->spar_md_cfg,
+ d_start_band, d_end_band, sba_order, dtx_vad, Wscale_d );
+ }
+
+
+ /*-----------------------------------------------------------------------------------------*
+ * FB mixer
+ *-----------------------------------------------------------------------------------------*/
+
+ ivas_fb_mixer_get_in_out_mapping( pState->hFbMixer->fb_cfg, nchan_transport, ENC, remix_order_set[pState->hMdEnc->spar_md_cfg.remix_unmix_order], in_out_mixer_map );
+
+#ifdef DEBUG_SPAR_FOA
+ {
+ static FILE *f_mat = 0;
+
+ if ( f_mat == 0 )
+ f_mat = fopen( "mixer_mat_enc", "w" );
+
+ for ( i = 0; i < pState->hFbMixer->fb_cfg->num_out_chans; i++ )
+ {
+ for ( j = 0; j < pState->hFbMixer->fb_cfg->num_in_chans; j++ )
+ {
+ for ( k = 0; k < pState->hFbMixer->pFb->filterbank_num_bands; k++ )
+ {
+ fprintf( f_mat, "%f\n", pState->hMdEnc->mixer_mat[i][j][k] );
+
+ if ( ( in_out_mixer_map[i][j] == 0 ) && ( fabs( pState->hMdEnc->mixer_mat[i][j][k] ) > 1e-20 ) )
+ {
+ assert( 0 && "Non zero value in unexpected mixer map!!!" );
+ }
+ }
+ }
+ }
+ }
+#endif
+#ifdef DEBUG_SPAR_DIRAC_WRITE_OUT_PRED_PARS
+ {
+ static FILE *fid = 0;
+ int16_t band = 9;
+ if ( !fid )
+ {
+ fid = fopen( "pred_coeffs_enc.txt", "wt" );
+ }
+ fprintf( fid, "%.6f\n", pState->hMdEnc->mixer_mat[1][0][band] );
+ }
+#endif
+
+ ivas_fb_mixer_process( pState->hFbMixer, pState->hMdEnc->mixer_mat, p_pcm_tmp, input_frame, in_out_mixer_map );
+
+ /* move delayed W into output buffer unless activeW operation*/
+ if ( pState->hFbMixer->fb_cfg->active_w_mixing == 0 )
+ {
+ mvr2r( w_del_buf, p_pcm_tmp[0], num_del_samples );
+ mvr2r( data_f[0], p_pcm_tmp[0] + num_del_samples, input_frame - num_del_samples );
+ }
+
+ /*-----------------------------------------------------------------------------------------*
+ * PCA encoder
+ *-----------------------------------------------------------------------------------------*/
+
+ if ( pState->hPCA != NULL )
+ {
+ ivas_pca_enc( hEncoderConfig, pState->hPCA, hMetaData, p_pcm_tmp, input_frame, FOA_CHANNELS );
+ }
+ else
+ {
+ if ( ivas_total_brate == PCA_BRATE && sba_order == 1 )
+ {
+ /* write PCA bypass bit */
+ push_next_indice( hMetaData, PCA_MODE_INACTIVE, 1 );
+ }
+ }
+
+
+#ifdef SPAR_HOA_DBG
+ /*FILE *fp = fopen("int_enc_dmx.raw", "ab");
+ for (int16_t t = 0; t < 960; t++)
+ {
+ for (int16_t c = 0; c < pState->hFbMixer->filterbank_num_out_chans; c++)
+ {
+ for ( k = 0; k < 2; k++ )
+ {
+ fb_mixer_in_buf.ppMixer[i][j][k] = pState->hMdEnc->mixer_mat[i][j];
+ }
+ }
+ }
+ fclose( fp );*/
+#endif
+ /*-----------------------------------------------------------------------------------------*
+ * AGC
+ *-----------------------------------------------------------------------------------------*/
+
+ if ( dtx_vad == 1 )
+ {
+ if ( hEncoderConfig->Opt_AGC_ON > 0 )
+ {
+ ivas_agc_enc_process( pState->hAgcEnc, hMetaData, p_pcm_tmp, p_pcm_tmp, pState->hFbMixer->fb_cfg->num_out_chans, hEncoderConfig );
+ }
+ else
+ {
+ push_next_indice( hMetaData, 0, 1 );
+ }
+ }
+
+#ifdef DEBUG_SPAR_BYPASS_EVS_CODEC
+ {
+ static FILE *fid_enc = 0;
+ static float delay_buf[576 * 4] = { 0 };
+ int16_t smp, ch, buf_idx, framelen = input_frame, delay = 576;
+ if ( !fid_enc )
+ {
+ fid_enc = fopen( "evs_input_float.raw", "wb" );
+ }
+
+ /* write out buffer */
+ for ( smp = 0; smp < delay * nchan_transport; smp++ )
+ {
+ fwrite( &delay_buf[smp], sizeof( float ), 1, fid_enc );
+ }
+
+ for ( smp = 0; smp < framelen - delay; smp++ )
+ {
+ for ( ch = 0; ch < nchan_transport; ch++ )
+ {
+ fwrite( &p_pcm_tmp[ch][smp], sizeof( float ), 1, fid_enc );
+ }
+ }
+
+ /* update delay buffer*/
+ buf_idx = 0;
+ for ( ; smp < framelen; smp++ )
+ {
+ for ( ch = 0; ch < nchan_transport; ch++ )
+ {
+ delay_buf[buf_idx++] = p_pcm_tmp[ch][smp];
+ }
+ }
+ }
+#endif
+
+#ifdef DEBUG_SPAR_FOA
+ float tmp;
+ int16_t pcm;
+
+ for ( j = 0; j < input_frame; j++ )
+ {
+ for ( i = 0; i < nchan_transport; i++ )
+ {
+ tmp = roundf( p_pcm_tmp[i][j] * PCM16_TO_FLT_FAC );
+ pcm = ( tmp > MAX16B_FLT ) ? MAX16B : ( tmp < MIN16B_FLT ) ? MIN16B : (short) tmp;
+ dbgwrite( &pcm, sizeof( int16_t ), 1, 1, "dmx.raw" );
+ }
+ }
+
+ /* Plug evs i/p from Matlab */
+ if ( fEvs_enc_in != NULL )
+ {
+ /*printf("evs enc in file found\n");*/
+ float tmp_in = 0;
+ int16_t diff[FOA_CHANNELS][L_FRAME48k], tmp16;
+ int16_t max_diff = 0;
+ int16_t abs_tol = 8;
+
+ for ( i = 0; i < input_frame; i++ )
+ {
+ for ( j = 0; j < nchan_transport; j++ )
+ {
+ tmp = p_pcm_tmp[j][i];
+ tmp = roundf( tmp * PCM16_TO_FLT_FAC );
+ tmp16 = ( tmp > MAX16B_FLT ) ? MAX16B : ( tmp < MIN16B_FLT ) ? MIN16B : (int16_t) tmp;
+ fscanf( fEvs_enc_in, "%f\n", &tmp_in );
+ p_pcm_tmp[j][i] = tmp_in;
+
+ tmp = roundf( tmp_in * PCM16_TO_FLT_FAC );
+ pcm = ( tmp > MAX16B_FLT ) ? MAX16B : ( tmp < MIN16B_FLT ) ? MIN16B : (int16_t) tmp;
+ diff[j][i] = (int16_t) abs( tmp16 - pcm );
+ max_diff = max( max_diff, diff[j][i] );
+ }
+ }
+
+ if ( max_diff > abs_tol )
+ {
+ IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "SPAR ENC fb mixer out mismatch, max diff = %d", max_diff );
+ }
+ }
+#endif
+
+ /*-----------------------------------------------------------------------------------------*
+ * Re-order the dmx back to ACN/SN3D format
+ *-----------------------------------------------------------------------------------------*/
+
+ order = remix_order_set[pState->hMdEnc->spar_md_cfg.remix_unmix_order];
+
+ for ( i = 0; i < input_frame; i++ )
+ {
+ for ( j = 0; j < nchan_transport; j++ )
+ {
+ data_f[order[j]][i] = p_pcm_tmp[j][i] * PCM16_TO_FLT_FAC;
+ }
+ for ( ; j < IVAS_SPAR_MAX_DMX_CHS; j++ )
+ {
+ data_f[order[j]][i] = 0;
+ }
+ }
+
+ wmops_sub_end();
+
+ return error;
+}
diff --git a/lib_enc/ivas_spar_foa_enc.c b/lib_enc/ivas_spar_foa_enc.c
deleted file mode 100644
index 913ed599bbae02af5f914e9ac34ccbcef88d79bc..0000000000000000000000000000000000000000
--- a/lib_enc/ivas_spar_foa_enc.c
+++ /dev/null
@@ -1,661 +0,0 @@
-/******************************************************************************************************
-
- (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
- Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
- Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
- Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
- contributors to this repository. All Rights Reserved.
-
- This software is protected by copyright law and by international treaties.
- The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
- Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
- Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
- Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
- contributors to this repository retain full ownership rights in their respective contributions in
- the software. This notice grants no license of any kind, including but not limited to patent
- license, nor is any license granted by implication, estoppel or otherwise.
-
- Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
- contributions.
-
- This software is provided "AS IS", without any express or implied warranties. The software is in the
- development stage. It is intended exclusively for experts who have experience with such software and
- solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
- and fitness for a particular purpose are hereby disclaimed and excluded.
-
- Any dispute, controversy or claim arising under or in relation to providing this software shall be
- submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
- accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
- the United Nations Convention on Contracts on the International Sales of Goods.
-
-*******************************************************************************************************/
-
-#include
-#include "options.h"
-#ifdef DEBUGGING
-#include "debug.h"
-#endif
-#include "ivas_prot.h"
-#include "prot.h"
-#include "ivas_rom_com.h"
-#include "ivas_stat_com.h"
-#include "math.h"
-#include
-#include "wmops.h"
-
-#ifdef DEBUG_SPAR_FOA
-extern FILE *fEvs_enc_in;
-extern FILE *fFb_out[4];
-#endif
-
-
-/*-----------------------------------------------------------------------------------------*
- * Function ivas_spar_enc_get_windowed_fr()
- *
- * Get windowed FRs
- *-----------------------------------------------------------------------------------------*/
-
-static void ivas_spar_enc_get_windowed_fr(
- IVAS_FB_MIXER_HANDLE hFbMixer,
- float *pIn_blocks[IVAS_SPAR_MAX_CH],
- ivas_enc_cov_handler_in_buf_t *pCov_in_buf,
- const int16_t input_frame,
- const int16_t nchan_inp,
- const int16_t num_past_samples )
-{
- int16_t i, j, rev_offset;
-
- for ( i = 0; i < nchan_inp; i++ )
- {
- const int16_t stride = hFbMixer->pFb->fb_bin_to_band.short_stride;
- float tmp_buf[MDFT_FB_BANDS_240 * 2];
- int16_t win_len = (int16_t) hFbMixer->ana_window_offset;
- float *mdft_in_ptr = tmp_buf + stride - win_len;
- float tmp_in_block[L_FRAME48k + MDFT_FB_BANDS_240];
- float *data_ptr = tmp_in_block;
- float *fr_re_ptr = pCov_in_buf->ppIn_FR_real[i];
- float *fr_im_ptr = pCov_in_buf->ppIn_FR_imag[i];
-
- set_f( tmp_buf, 0, MDFT_FB_BANDS_240 * 2 );
-
- /* copy input data, because pIn_blocks and fr_re_ptr + fr_im_ptr use the same memory */
- mvr2r( &pIn_blocks[i][input_frame - num_past_samples], tmp_in_block, input_frame + win_len );
-
- for ( int16_t blk = 0; blk < input_frame / stride; blk++ )
- {
-
- for ( j = 0; j < win_len; j++ )
- {
- mdft_in_ptr[j] = data_ptr[j] * hFbMixer->pAna_window[j];
- }
-
- for ( j = win_len; j < stride; j++ )
- {
- mdft_in_ptr[j] = data_ptr[j];
- }
-
- rev_offset = win_len - 1;
- for ( j = stride; j < stride + win_len; j++ )
- {
- mdft_in_ptr[j] = data_ptr[j] * hFbMixer->pAna_window[rev_offset--];
- }
-
- ivas_mdft( tmp_buf, fr_re_ptr, fr_im_ptr, stride << 1, stride );
-
- data_ptr += stride;
- fr_re_ptr += stride;
- fr_im_ptr += stride;
- }
- }
-
- return;
-}
-
-
-/*-----------------------------------------------------------------------------------------*
- * Function ivas_spar_enc_process()
- *
- * Process call for SPAR encoder
- *-----------------------------------------------------------------------------------------*/
-
-ivas_error ivas_spar_enc_process(
- Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */
- const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */
- BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */
- const int16_t front_vad_flag, /* i : front-VAD decision */
- float data_f[][L_FRAME48k] /* i/o: input/transport audio channels */
-)
-{
- float pcm_tmp[IVAS_SPAR_MAX_CH][L_FRAME48k * 2];
- float *p_pcm_tmp[IVAS_SPAR_MAX_CH];
- int16_t i, j, k, b, i_ts, input_frame, num_bands_bw;
- int16_t dtx_vad, dtx_cov_flag, dtx_silence_mode;
- int32_t ivas_total_brate, input_Fs;
- ivas_enc_cov_handler_in_buf_t cov_in_buf;
- float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
- float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
- ivas_spar_md_enc_in_buf_t md_in_buf;
- int16_t nchan_inp, nchan_transport, bwidth, sba_order;
- int16_t table_idx;
- int16_t in_out_mixer_map[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH];
- ivas_error error;
- const int16_t *order;
- SPAR_ENC_HANDLE pState = st_ivas->hSpar;
- IVAS_QMETADATA_HANDLE hQMetaData = st_ivas->hQMetaData;
- int16_t ts, l_ts, orig_dirac_bands, num_del_samples;
- float *ppIn_FR_real[IVAS_SPAR_MAX_CH], *ppIn_FR_imag[IVAS_SPAR_MAX_CH];
- float w_del_buf[IVAS_FB_1MS_48K_SAMP];
- float dir[3], avg_dir[3];
- float energySum, vecLen;
-
- wmops_sub_start( "ivas_spar_enc_process" );
-
- /*-----------------------------------------------------------------------------------------*
- * Initialization
- *-----------------------------------------------------------------------------------------*/
-
- error = IVAS_ERR_OK;
-
- input_Fs = hEncoderConfig->input_Fs;
- ivas_total_brate = hEncoderConfig->ivas_total_brate;
- num_del_samples = pState->hFbMixer->fb_cfg->fb_latency;
-
- input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC );
- sba_order = min( hEncoderConfig->sba_order, IVAS_MAX_SBA_ORDER );
- nchan_inp = ivas_sba_get_nchan_metadata( sba_order );
- assert( nchan_inp <= hEncoderConfig->nchan_inp );
-
- for ( i = FOA_CHANNELS + 1; i < nchan_inp; i++ )
- {
- mvr2r( data_f[HOA_keep_ind[i]], data_f[i], input_frame );
- }
-
- table_idx = ivas_get_spar_table_idx( ivas_total_brate, sba_order, SPAR_CONFIG_BW, NULL, NULL );
-
- /*-----------------------------------------------------------------------------------------*
- * Transient detector
- *-----------------------------------------------------------------------------------------*/
-
- cov_in_buf.transient_det = ivas_transient_det_process( pState->hTranDet, data_f[0], input_frame );
-
- /* store previous input samples for W in local buffer */
- assert( num_del_samples <= IVAS_FB_1MS_48K_SAMP );
- mvr2r( &pState->hFbMixer->ppFilterbank_prior_input[0][pState->hFbMixer->fb_cfg->prior_input_length - num_del_samples], w_del_buf, num_del_samples );
-
- /*-----------------------------------------------------------------------------------------*
- * FB mixer ingest
- *-----------------------------------------------------------------------------------------*/
-
- for ( i = 0; i < nchan_inp; i++ )
- {
- p_pcm_tmp[i] = pcm_tmp[i];
- }
-
- /* run Filter Bank overlapping MDFT analysis first, then we can use the temporary buffer for Parameter MDFT analysis*/
- ivas_fb_mixer_pcm_ingest( pState->hFbMixer, data_f, p_pcm_tmp, input_frame );
-
- /* prepare Parameter MDFT analysis */
- for ( i = 0; i < nchan_inp; i++ )
- {
- cov_in_buf.ppIn_FR_real[i] = p_pcm_tmp[i];
- cov_in_buf.ppIn_FR_imag[i] = p_pcm_tmp[i] + input_frame;
- }
-
- for ( i = 0; i < nchan_inp; i++ )
- {
- p_pcm_tmp[i] = &data_f[i][0];
- ppIn_FR_real[i] = cov_in_buf.ppIn_FR_real[i];
- ppIn_FR_imag[i] = cov_in_buf.ppIn_FR_imag[i];
- }
-
- l_ts = input_frame / MAX_PARAM_SPATIAL_SUBFRAMES;
-
- for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ )
- {
- ivas_fb_mixer_get_windowed_fr( pState->hFbMixer, p_pcm_tmp, ppIn_FR_real, ppIn_FR_imag, l_ts, l_ts );
- ivas_fb_mixer_update_prior_input( pState->hFbMixer, p_pcm_tmp, l_ts );
-
- for ( i = 0; i < nchan_inp; i++ )
- {
- p_pcm_tmp[i] += l_ts;
- ppIn_FR_real[i] += l_ts;
- ppIn_FR_imag[i] += l_ts;
- }
- }
-
- /* turn pointers back to the local buffer, needed for the following processing */
- for ( i = 0; i < nchan_inp; i++ )
- {
- p_pcm_tmp[i] = pcm_tmp[i];
- }
-
- cov_in_buf.num_ch = nchan_inp;
-
- dtx_vad = ( hEncoderConfig->Opt_DTX_ON == 1 ) ? front_vad_flag : 1;
-
- /*-----------------------------------------------------------------------------------------*
- * DirAC encoding
- *-----------------------------------------------------------------------------------------*/
-
- ivas_dirac_param_est_enc( st_ivas->hDirAC, hQMetaData->q_direction, hQMetaData->useLowerRes,
- data_f, cov_in_buf.ppIn_FR_real, cov_in_buf.ppIn_FR_imag, input_frame );
-
- if ( hQMetaData->q_direction->cfg.nbands > 0 )
- {
- orig_dirac_bands = hQMetaData->q_direction[0].cfg.nbands;
-
- if ( dtx_vad == 1 )
- {
- /* WB 4TC mode bit : disable for now*/
- push_next_indice( hMetaData, 0, 1 );
- ivas_qmetadata_enc_encode( hMetaData, hQMetaData );
- }
- else
- {
- hQMetaData->q_direction[0].cfg.nbands = DIRAC_DTX_BANDS;
-
- /* compute directions */
- for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
- {
- set_zero( dir, 3 );
- set_zero( avg_dir, 3 );
- energySum = 0.0f;
-
- /*combine all dirac bands except the last one, handle last band separately, last band covers BW above WB*/
- for ( j = 0; j < orig_dirac_bands - 1; j++ )
- {
- ivas_qmetadata_azimuth_elevation_to_direction_vector( hQMetaData->q_direction[0].band_data[j].azimuth[i], hQMetaData->q_direction[0].band_data[j].elevation[i], &dir[0] );
- vecLen = hQMetaData->q_direction[0].band_data[j].energy_ratio[i] * st_ivas->hDirAC->buffer_energy[i * orig_dirac_bands + j];
-
- avg_dir[0] += dir[0] * vecLen;
- avg_dir[1] += dir[1] * vecLen;
- avg_dir[2] += dir[2] * vecLen;
-
- energySum += st_ivas->hDirAC->buffer_energy[i * orig_dirac_bands + j];
- }
-
- ivas_qmetadata_direction_vector_to_azimuth_elevation( &avg_dir[0], &hQMetaData->q_direction[0].band_data[0].azimuth[i], &hQMetaData->q_direction[0].band_data[0].elevation[i] );
- hQMetaData->q_direction[0].band_data[0].energy_ratio[i] = sqrtf( dotp( avg_dir, avg_dir, 3 ) ) / ( energySum + EPSILON );
-
- hQMetaData->q_direction[0].band_data[1].azimuth[i] = hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].azimuth[i];
- hQMetaData->q_direction[0].band_data[1].elevation[i] = hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].elevation[i];
- hQMetaData->q_direction[0].band_data[1].energy_ratio[i] = hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].energy_ratio[i];
- }
-
- /* 1 bit to indicate mode MD coding : temp solution*/
- push_next_indice( hMetaData, 1, 1 );
-
- /* encode SID parameters */
- ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, -1, SBA_FORMAT, st_ivas->sba_mode );
- }
-
- for ( b = hQMetaData->q_direction->cfg.start_band; b < hQMetaData->q_direction->cfg.nbands; b++ )
- {
- for ( i_ts = 0; i_ts < ( ( dtx_vad == 1 ) ? hQMetaData->q_direction[0].cfg.nblocks : 1 ); i_ts++ )
- {
- hQMetaData->q_direction->band_data[b].azimuth[i_ts] = hQMetaData->q_direction->band_data[b].q_azimuth[i_ts];
- hQMetaData->q_direction->band_data[b].elevation[i_ts] = hQMetaData->q_direction->band_data[b].q_elevation[i_ts];
- hQMetaData->q_direction[0].band_data[b].energy_ratio[0] = 1.0f - diffuseness_reconstructions[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]];
- }
- }
-
- if ( dtx_vad == 0 )
- {
-
- for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
- {
- hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].azimuth[i] = hQMetaData->q_direction[0].band_data[1].azimuth[0];
- hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].elevation[i] = hQMetaData->q_direction[0].band_data[1].elevation[0];
- hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].energy_ratio[i] = hQMetaData->q_direction[0].band_data[1].energy_ratio[0];
- }
-
- for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
- {
- for ( j = orig_dirac_bands - 2; j >= 0; j-- )
- {
- hQMetaData->q_direction[0].band_data[j].azimuth[i] = hQMetaData->q_direction[0].band_data[0].azimuth[0];
- hQMetaData->q_direction[0].band_data[j].elevation[i] = hQMetaData->q_direction[0].band_data[0].elevation[0];
- hQMetaData->q_direction[0].band_data[j].energy_ratio[i] = hQMetaData->q_direction[0].band_data[0].energy_ratio[0];
- }
- }
-
- hQMetaData->q_direction->cfg.nbands = orig_dirac_bands;
- }
- }
-
-
- /*-----------------------------------------------------------------------------------------*
- * Pre-proc flags
- *-----------------------------------------------------------------------------------------*/
-
- /* use just VAD function to get VAD flags */
- dtx_vad = ( hEncoderConfig->Opt_DTX_ON == 1 ) ? front_vad_flag : 1;
- dtx_cov_flag = ( dtx_vad == 1 ) ? 0 : 1;
- dtx_silence_mode = 0;
- bwidth = ivas_get_bw_idx_from_sample_rate( input_Fs );
- bwidth = min( bwidth, hEncoderConfig->max_bwidth );
-
- /*-----------------------------------------------------------------------------------------*
- * Covariance process
- *-----------------------------------------------------------------------------------------*/
-
- cov_in_buf.num_ch = nchan_inp;
-
- for ( i = 0; i < nchan_inp; i++ )
- {
- for ( j = 0; j < nchan_inp; j++ )
- {
- cov_real[i][j] = pState->hMdEnc->cov_real[i][j];
- cov_dtx_real[i][j] = pState->hMdEnc->cov_dtx_real[i][j];
- }
- }
-
- cov_in_buf.dtx_cov_flag = dtx_cov_flag;
- ivas_enc_cov_handler_process( pState->hCovEnc, &cov_in_buf, cov_real, cov_dtx_real, pState->hFbMixer->pFb, 0, pState->hFbMixer->pFb->filterbank_num_bands );
-
- if ( pState->hMdEnc->table_idx != table_idx )
- {
- pState->hMdEnc->table_idx = table_idx;
- ivas_spar_set_bitrate_config( &pState->hMdEnc->spar_md_cfg, table_idx, SPAR_DIRAC_SPLIT_START_BAND );
- }
-
- nchan_transport = pState->hMdEnc->spar_md_cfg.nchan_transport;
-
- /*-----------------------------------------------------------------------------------------*
- * MetaData encoder
- *-----------------------------------------------------------------------------------------*/
-
- num_bands_bw = ivas_get_num_bands_from_bw_idx( bwidth );
-
- if ( dtx_vad == 0 )
- {
- for ( i = 0; i < nchan_inp; i++ )
- {
- for ( j = 0; j < nchan_inp; j++ )
- {
- md_in_buf.cov_real[i][j] = cov_dtx_real[i][j];
- for ( k = num_bands_bw; k < IVAS_MAX_NUM_BANDS; k++ )
- {
- md_in_buf.cov_real[i][j][k] = 0;
- }
- }
- }
- }
- else
- {
- for ( i = 0; i < nchan_inp; i++ )
- {
- for ( j = 0; j < nchan_inp; j++ )
- {
- md_in_buf.cov_real[i][j] = cov_real[i][j];
- for ( k = num_bands_bw; k < IVAS_MAX_NUM_BANDS; k++ )
- {
- md_in_buf.cov_real[i][j][k] = 0;
- }
- }
- }
- }
-
- md_in_buf.num_bands = ivas_get_num_bands_from_bw_idx( SPAR_CONFIG_BW );
- md_in_buf.num_bands = min( md_in_buf.num_bands, SPAR_DIRAC_SPLIT_START_BAND );
-
- md_in_buf.dtx_vad = dtx_vad;
-
- ivas_spar_md_enc_process( pState->hMdEnc, hEncoderConfig, &md_in_buf, hMetaData, dtx_silence_mode );
-
- if ( st_ivas->sba_mode == SBA_MODE_SPAR )
- {
- float azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
- float ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
- float diffuseness[IVAS_MAX_NUM_BANDS];
- float Wscale_d[IVAS_MAX_NUM_BANDS];
- int16_t d_start_band, d_end_band;
- int16_t dirac_band_idx;
-
- d_start_band = st_ivas->hSpar->enc_param_start_band;
- d_end_band = IVAS_MAX_NUM_BANDS;
-
- for ( b = d_start_band; b < d_end_band; b++ )
- {
- dirac_band_idx = st_ivas->hSpar->dirac_to_spar_md_bands[b] - d_start_band;
- for ( i_ts = 0; i_ts < hQMetaData->q_direction->cfg.nblocks; i_ts++ )
- {
- azi_dirac[b][i_ts] = hQMetaData->q_direction->band_data[dirac_band_idx].azimuth[i_ts];
- ele_dirac[b][i_ts] = hQMetaData->q_direction->band_data[dirac_band_idx].elevation[i_ts];
- }
- diffuseness[b] = 1.0f - hQMetaData->q_direction->band_data[dirac_band_idx].energy_ratio[0];
- }
-
- if ( ( d_start_band >= 6 ) && ( dtx_vad == 1 ) )
- {
- for ( i = 0; i < IVAS_SPAR_MAX_CH - 1; i++ )
- {
- pState->hMdEnc->spar_md.band_coeffs[d_start_band - 1].P_re[i] =
- pState->hMdEnc->spar_md.band_coeffs[d_start_band - 1].P_quant_re[i];
- }
- }
-
- for ( b = d_start_band; b < d_end_band; b++ )
- {
- Wscale_d[b] = 1.0f;
- for ( i = 1; i < nchan_inp; i++ )
- {
- Wscale_d[b] += md_in_buf.cov_real[i][i][b] / max( EPSILON, md_in_buf.cov_real[0][0][b] );
- }
- Wscale_d[b] = Wscale_d[b] / ( 1.0f + (float) sba_order ); /*DirAC normalized signal variance sums to 1 + order*/
- Wscale_d[b] = sqrtf( Wscale_d[b] );
- Wscale_d[b] = min( 2.0f, max( Wscale_d[b], 1.0f ) );
- }
-
- ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, 1, pState->hMdEnc->mixer_mat, &pState->hMdEnc->spar_md, &pState->hMdEnc->spar_md_cfg,
- d_start_band, d_end_band, sba_order, dtx_vad, Wscale_d );
- }
-
-
- /*-----------------------------------------------------------------------------------------*
- * FB mixer
- *-----------------------------------------------------------------------------------------*/
-
- ivas_fb_mixer_get_in_out_mapping( pState->hFbMixer->fb_cfg, nchan_transport, ENC, remix_order_set[pState->hMdEnc->spar_md_cfg.remix_unmix_order], in_out_mixer_map );
-
-#ifdef DEBUG_SPAR_FOA
- {
- static FILE *f_mat = 0;
-
- if ( f_mat == 0 )
- f_mat = fopen( "mixer_mat_enc", "w" );
-
- for ( i = 0; i < pState->hFbMixer->fb_cfg->num_out_chans; i++ )
- {
- for ( j = 0; j < pState->hFbMixer->fb_cfg->num_in_chans; j++ )
- {
- for ( k = 0; k < pState->hFbMixer->pFb->filterbank_num_bands; k++ )
- {
- fprintf( f_mat, "%f\n", pState->hMdEnc->mixer_mat[i][j][k] );
-
- if ( ( in_out_mixer_map[i][j] == 0 ) && ( fabs( pState->hMdEnc->mixer_mat[i][j][k] ) > 1e-20 ) )
- {
- assert( 0 && "Non zero value in unexpected mixer map!!!" );
- }
- }
- }
- }
- }
-#endif
-#ifdef DEBUG_SPAR_DIRAC_WRITE_OUT_PRED_PARS
- {
- static FILE *fid = 0;
- int16_t band = 9;
- if ( !fid )
- {
- fid = fopen( "pred_coeffs_enc.txt", "wt" );
- }
- fprintf( fid, "%.6f\n", pState->hMdEnc->mixer_mat[1][0][band] );
- }
-#endif
-
- ivas_fb_mixer_process( pState->hFbMixer, pState->hMdEnc->mixer_mat, p_pcm_tmp, input_frame, in_out_mixer_map );
-
- /* move delayed W into output buffer unless activeW operation*/
- if ( pState->hFbMixer->fb_cfg->active_w_mixing == 0 )
- {
- mvr2r( w_del_buf, p_pcm_tmp[0], num_del_samples );
- mvr2r( data_f[0], p_pcm_tmp[0] + num_del_samples, input_frame - num_del_samples );
- }
-
- /*-----------------------------------------------------------------------------------------*
- * PCA encoder
- *-----------------------------------------------------------------------------------------*/
-
- if ( pState->hPCA != NULL )
- {
- ivas_pca_enc( hEncoderConfig, pState->hPCA, hMetaData, p_pcm_tmp, input_frame, FOA_CHANNELS );
- }
- else
- {
- if ( ivas_total_brate == PCA_BRATE && sba_order == 1 )
- {
- /* write PCA bypass bit */
- push_next_indice( hMetaData, PCA_MODE_INACTIVE, 1 );
- }
- }
-
-
-#ifdef SPAR_HOA_DBG
- /*FILE *fp = fopen("int_enc_dmx.raw", "ab");
- for (int16_t t = 0; t < 960; t++)
- {
- for (int16_t c = 0; c < pState->hFbMixer->filterbank_num_out_chans; c++)
- {
- for ( k = 0; k < 2; k++ )
- {
- fb_mixer_in_buf.ppMixer[i][j][k] = pState->hMdEnc->mixer_mat[i][j];
- }
- }
- }
- fclose( fp );*/
-#endif
- /*-----------------------------------------------------------------------------------------*
- * AGC
- *-----------------------------------------------------------------------------------------*/
-
- if ( dtx_vad == 1 )
- {
- if ( hEncoderConfig->Opt_AGC_ON > 0 )
- {
- ivas_agc_enc_process( pState->hAgcEnc, hMetaData, p_pcm_tmp, p_pcm_tmp, pState->hFbMixer->fb_cfg->num_out_chans, hEncoderConfig );
- }
- else
- {
- push_next_indice( hMetaData, 0, 1 );
- }
- }
-
-#ifdef DEBUG_SPAR_BYPASS_EVS_CODEC
- {
- static FILE *fid_enc = 0;
- static float delay_buf[576 * 4] = { 0 };
- int16_t smp, ch, buf_idx, framelen = input_frame, delay = 576;
- if ( !fid_enc )
- {
- fid_enc = fopen( "evs_input_float.raw", "wb" );
- }
-
- /* write out buffer */
- for ( smp = 0; smp < delay * nchan_transport; smp++ )
- {
- fwrite( &delay_buf[smp], sizeof( float ), 1, fid_enc );
- }
-
- for ( smp = 0; smp < framelen - delay; smp++ )
- {
- for ( ch = 0; ch < nchan_transport; ch++ )
- {
- fwrite( &p_pcm_tmp[ch][smp], sizeof( float ), 1, fid_enc );
- }
- }
-
- /* update delay buffer*/
- buf_idx = 0;
- for ( ; smp < framelen; smp++ )
- {
- for ( ch = 0; ch < nchan_transport; ch++ )
- {
- delay_buf[buf_idx++] = p_pcm_tmp[ch][smp];
- }
- }
- }
-#endif
-
-#ifdef DEBUG_SPAR_FOA
- float tmp;
- int16_t pcm;
-
- for ( j = 0; j < input_frame; j++ )
- {
- for ( i = 0; i < nchan_transport; i++ )
- {
- tmp = roundf( p_pcm_tmp[i][j] * PCM16_TO_FLT_FAC );
- pcm = ( tmp > MAX16B_FLT ) ? MAX16B : ( tmp < MIN16B_FLT ) ? MIN16B
- : (short) tmp;
- dbgwrite( &pcm, sizeof( int16_t ), 1, 1, "dmx.raw" );
- }
- }
-
- /* Plug evs i/p from Matlab */
- if ( fEvs_enc_in != NULL )
- {
- /*printf("evs enc in file found\n");*/
- float tmp_in = 0;
- int16_t diff[FOA_CHANNELS][L_FRAME48k], tmp16;
- int16_t max_diff = 0;
- int16_t abs_tol = 8;
-
- for ( i = 0; i < input_frame; i++ )
- {
- for ( j = 0; j < nchan_transport; j++ )
- {
- tmp = p_pcm_tmp[j][i];
- tmp = roundf( tmp * PCM16_TO_FLT_FAC );
- tmp16 = ( tmp > MAX16B_FLT ) ? MAX16B : ( tmp < MIN16B_FLT ) ? MIN16B
- : (int16_t) tmp;
- fscanf( fEvs_enc_in, "%f\n", &tmp_in );
- p_pcm_tmp[j][i] = tmp_in;
-
- tmp = roundf( tmp_in * PCM16_TO_FLT_FAC );
- pcm = ( tmp > MAX16B_FLT ) ? MAX16B : ( tmp < MIN16B_FLT ) ? MIN16B
- : (int16_t) tmp;
- diff[j][i] = (int16_t) abs( tmp16 - pcm );
- max_diff = max( max_diff, diff[j][i] );
- }
- }
-
- if ( max_diff > abs_tol )
- {
- IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "SPAR FOA ENC fb mixer out mismatch, max diff = %d", max_diff );
- }
- }
-#endif
-
- /*-----------------------------------------------------------------------------------------*
- * Re-order the dmx back to ACN/SN3D format
- *-----------------------------------------------------------------------------------------*/
-
- order = remix_order_set[pState->hMdEnc->spar_md_cfg.remix_unmix_order];
-
- for ( i = 0; i < input_frame; i++ )
- {
- for ( j = 0; j < nchan_transport; j++ )
- {
- data_f[order[j]][i] = p_pcm_tmp[j][i] * PCM16_TO_FLT_FAC;
- }
- for ( ; j < IVAS_SPAR_MAX_DMX_CHS; j++ )
- {
- data_f[order[j]][i] = 0;
- }
- }
-
- wmops_sub_end();
-
- return error;
-}
diff --git a/lib_enc/ivas_spar_foa_md_enc.c b/lib_enc/ivas_spar_md_enc.c
similarity index 99%
rename from lib_enc/ivas_spar_foa_md_enc.c
rename to lib_enc/ivas_spar_md_enc.c
index f99c21c1df4bc34fe577904e1f7a42b36b66e127..e2e0796aa4192c5618712292b3d2eb816dde8d04 100644
--- a/lib_enc/ivas_spar_foa_md_enc.c
+++ b/lib_enc/ivas_spar_md_enc.c
@@ -417,7 +417,7 @@ static ivas_error ivas_spar_md_enc_init(
/*-----------------------------------------------------------------------------------------*
* Function ivas_spar_set_enc_config()
*
- * Set configuration for SPAR FOA md gen
+ * Set configuration for SPAR MD gen
*-----------------------------------------------------------------------------------------*/
static ivas_error ivas_spar_set_enc_config(
diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h
index b542859db0c9e5d1ba31535383d50494152029f3..331e1a75e7ef0fb8be8ef58eaf4c6ac2fdee911d 100644
--- a/lib_enc/ivas_stat_enc.h
+++ b/lib_enc/ivas_stat_enc.h
@@ -593,7 +593,7 @@ typedef struct ivas_dirac_enc_data_structure
* SPAR encoder structures
*----------------------------------------------------------------------------------*/
-/* SPAR AGC structures */
+/* AGC structures */
typedef struct ivas_agc_enc_chan_state_t
{
int16_t lastExp;
@@ -616,7 +616,7 @@ typedef struct ivas_agc_enc_state_t
} ivas_agc_enc_state_t;
-/* SPAR covariance structures */
+/* covariance structures */
typedef struct ivas_enc_cov_handler_state_t
{
ivas_cov_smooth_state_t *pCov_state;
@@ -655,7 +655,6 @@ typedef struct ivas_spar_md_enc_state_t
} ivas_spar_md_enc_state_t;
-
typedef struct ivas_spar_md_enc_in_buf_t
{
float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
@@ -664,7 +663,6 @@ typedef struct ivas_spar_md_enc_in_buf_t
} ivas_spar_md_enc_in_buf_t;
-
/* PCA structure */
typedef struct
{
@@ -678,10 +676,6 @@ typedef struct
} PCA_ENC_STATE;
-
-/* SPAR FOA structures */
-
-
/* SPAR main structure */
typedef struct ivas_spar_enc_lib_t
{
@@ -710,7 +704,6 @@ typedef struct ivas_spar_enc_lib_t
typedef struct ivas_param_mc_enc_data_structure
{
-
IVAS_FB_MIXER_HANDLE hFbMixer;
int16_t transient_detector_delay;
const float *dmx_factors;