diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj
index 81461f72d2784597e850681bf32755b0d1a71cfc..ef31eea686298eeea16af44df5c8347944440ce1 100644
--- a/Workspace_msvc/lib_dec.vcxproj
+++ b/Workspace_msvc/lib_dec.vcxproj
@@ -213,6 +213,8 @@
+
+
@@ -222,7 +224,6 @@
-
diff --git a/Workspace_msvc/lib_dec.vcxproj.filters b/Workspace_msvc/lib_dec.vcxproj.filters
index 170eada9ad30e017f4f3652be5ee6f08f2080937..59e2aa52d33a60e51eea8424e13518b64b9869b3 100644
--- a/Workspace_msvc/lib_dec.vcxproj.filters
+++ b/Workspace_msvc/lib_dec.vcxproj.filters
@@ -326,9 +326,6 @@
decoder_all_c
-
- decoder_ivas_c
-
decoder_ivas_c
@@ -362,9 +359,6 @@
decoder_ivas_c
-
- decoder_ivas_c
-
decoder_ivas_c
@@ -509,6 +503,12 @@
decoder_all_c
+
+ decoder_ivas_c
+
+
+ decoder_ivas_c
+
diff --git a/lib_dec/ivas_dec_fx.c b/lib_dec/ivas_dec_fx.c
new file mode 100644
index 0000000000000000000000000000000000000000..bd3eab3e4feb8c9131b76321da996b6d835e91f4
--- /dev/null
+++ b/lib_dec/ivas_dec_fx.c
@@ -0,0 +1,1565 @@
+/******************************************************************************************************
+
+ (C) 2022-2026 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"
+#include "ivas_cnst.h"
+#include "prot_fx.h"
+#include "ivas_prot_fx.h"
+#include "ivas_prot_rend_fx.h"
+#include "ivas_rom_com.h"
+#include "wmc_auto.h"
+#ifdef DEBUGGING
+#include "debug.h"
+#endif
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_dec()
+ *
+ * Principal IVAS decoder routine, decoding of metadata and transport channels
+ *--------------------------------------------------------------------------*/
+
+ivas_error ivas_dec_fx(
+ Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
+)
+{
+ Word16 ch, n, output_frame, nchan_out, i, s;
+ Decoder_State *st; /* used for bitstream handling */
+ Word32 *p_output_fx[MAX_TRANSPORT_CHANNELS]; /* buffer for output synthesis */
+ Word16 nchan_remapped;
+ Word16 nb_bits_metadata[MAX_SCE + 1];
+ Word32 output_Fs, ivas_total_brate;
+ AUDIO_CONFIG output_config;
+ ivas_error error;
+ Word16 num_md_sub_frames;
+ Word32 ism_total_brate;
+
+ push_wmops( "ivas_dec" );
+ /*----------------------------------------------------------------*
+ * Initialization of local vars after struct has been set
+ *----------------------------------------------------------------*/
+
+ output_Fs = st_ivas->hDecoderConfig->output_Fs;
+ move32();
+ nchan_out = st_ivas->hTcBuffer->nchan_transport_rend;
+ move16();
+ output_config = st_ivas->hDecoderConfig->output_config;
+ ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
+ move32();
+
+ output_frame = extract_l( Mult_32_16( output_Fs, INV_FRAME_PER_SEC_Q15 ) ) /* output_Fs / FRAMES_PER_SEC */;
+
+ /* set pointers to transport channels audio */
+ FOR( n = 0; n < MAX_TRANSPORT_CHANNELS; n++ )
+ {
+ p_output_fx[n] = st_ivas->p_output_fx[n];
+ IF( p_output_fx[n] != NULL )
+ {
+ set32_fx( p_output_fx[n], 0, L_FRAME48k );
+ }
+ }
+
+ /*----------------------------------------------------------------*
+ * Decoding + pre-rendering
+ *----------------------------------------------------------------*/
+
+ test();
+ IF( EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) )
+
+ {
+ st_ivas->hCPE[0]->element_brate = ivas_total_brate;
+ move32();
+ IF( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, 0 ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* HP filtering */
+ FOR( n = 0; n < s_min( nchan_out, st_ivas->nchan_transport ); n++ )
+ {
+ hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs );
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) )
+ {
+ /* Metadata decoding and configuration */
+ test();
+ IF( EQ_32( ivas_total_brate, IVAS_SID_5k2 ) || EQ_32( ivas_total_brate, FRAME_NO_DATA ) )
+ {
+ ivas_ism_dtx_dec_fx( st_ivas, nb_bits_metadata );
+
+ IF( ( error = ivas_sce_dec_fx( st_ivas, st_ivas->hISMDTX.sce_id_dtx, &p_output_fx[st_ivas->hISMDTX.sce_id_dtx], output_frame, nb_bits_metadata[st_ivas->hISMDTX.sce_id_dtx] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ ivas_ism_dtx_limit_noise_energy_for_near_silence_fx( st_ivas->hSCE, st_ivas->hISMDTX.sce_id_dtx, st_ivas->nchan_transport );
+
+ ivas_param_ism_dec_dequant_md_fx( st_ivas );
+ }
+ ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) )
+ {
+ IF( NE_32( ( error = ivas_ism_metadata_dec_fx( ivas_total_brate, st_ivas->nchan_ism, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, st_ivas->hParamIsmDec->hParamIsm, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt, st_ivas->hSCE[0]->hCoreCoder[0] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ ivas_param_ism_dec_dequant_md_fx( st_ivas );
+ }
+ ELSE /* ISM_MODE_DISC */
+ {
+ IF( NE_32( ( error = ivas_ism_metadata_dec_fx( ivas_total_brate, st_ivas->nchan_ism, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, NULL, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt, st_ivas->hSCE[0]->hCoreCoder[0] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ FOR( n = 0; n < st_ivas->nchan_transport; n++ )
+ {
+ /* for DTX frames, dominant object has already been decoded before */
+ test();
+ test();
+ IF( !( ( EQ_32( ivas_total_brate, IVAS_SID_5k2 ) || EQ_32( ivas_total_brate, FRAME_NO_DATA ) ) && EQ_16( n, st_ivas->hISMDTX.sce_id_dtx ) ) )
+ {
+ IF( NE_32( ( error = ivas_sce_dec_fx( st_ivas, n, &p_output_fx[n], output_frame, nb_bits_metadata[n] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ /* HP filtering */
+ hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs );
+ }
+
+ test();
+ test();
+ test();
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) )
+ {
+ ivas_ism_mono_dmx_fx( st_ivas, p_output_fx, output_frame );
+
+ Scale_sig32( p_output_fx[0], output_frame, Q11 - Q8 );
+ }
+ ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) && ( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) || EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) ) )
+ {
+ /* loudness correction */
+ ivas_dirac_dec_binaural_sba_gain_fx( p_output_fx, st_ivas->nchan_transport, output_frame ); /*returns Q-1*/
+
+ FOR( i = 0; i < st_ivas->nchan_transport; i++ )
+ {
+ Scale_sig32( p_output_fx[i], output_frame, 1 ); // Q-1 -> Q
+ }
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) || EQ_32( st_ivas->ivas_format, MASA_FORMAT ) )
+ {
+ set16_fx( nb_bits_metadata, 0, MAX_SCE );
+
+ /* read parameters from the bitstream */
+ test();
+ IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) && st_ivas->hQMetaData != NULL )
+ {
+ // st = ( st_ivas->nSCE > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0];
+ IF( st_ivas->nSCE > 0 )
+ {
+ st = st_ivas->hSCE[0]->hCoreCoder[0];
+ }
+ ELSE
+ {
+ st = st_ivas->hCPE[0]->hCoreCoder[0];
+ }
+
+ IF( NE_32( ( error = ivas_masa_decode_fx( st_ivas, st, &nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) )
+ {
+ IF( NE_32( ( error = ivas_spar_dec_fx( st_ivas, nb_bits_metadata ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ test();
+ IF( EQ_16( st_ivas->nchan_transport, CPE_CHANNELS ) && GE_16( st_ivas->nCPE, 1 ) )
+ {
+ st_ivas->hCPE[0]->brate_surplus = 0;
+ move32();
+ st_ivas->hCPE[0]->element_brate = ivas_total_brate;
+ move32();
+ }
+
+ /* core-decoding of transport channels */
+ IF( EQ_16( st_ivas->nSCE, 1 ) )
+ {
+ IF( NE_32( ( error = ivas_sce_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ ELSE IF( EQ_16( st_ivas->nCPE, 1 ) )
+ {
+ IF( NE_32( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ ELSE IF( GT_16( st_ivas->nCPE, 1 ) )
+ {
+ IF( NE_32( ( error = ivas_mct_dec_fx( st_ivas, p_output_fx, output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ /* TCs remapping */
+ nchan_remapped = st_ivas->nchan_transport;
+ move16();
+
+ test();
+ test();
+ test();
+ test();
+ test();
+ IF( st_ivas->sba_dirac_stereo_flag )
+ {
+ nchan_remapped = nchan_out;
+ move16();
+
+ IF( EQ_16( st_ivas->ivas_format, SBA_FORMAT ) )
+ {
+ FOR( i = 0; i < st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport; i++ )
+ {
+ Scale_sig32( p_output_fx[i], output_frame, Q14 - Q11 ); // Q14
+ }
+ SPAR_DEC_HANDLE hSpar = st_ivas->hSpar;
+ Word16 nchan_transport;
+ nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport;
+ move16();
+ nchan_out = nchan_transport;
+ move16();
+
+ ivas_agc_dec_process_fx( st_ivas->hSpar->hAgcDec, ( p_output_fx ), ( p_output_fx ), st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, output_frame );
+
+ IF( st_ivas->hSpar->hPCA != NULL )
+ {
+ ivas_pca_dec_fx( st_ivas->hSpar->hPCA, output_frame, st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, ivas_total_brate, st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, p_output_fx );
+ }
+
+ ivas_spar_dec_gen_umx_mat_fx( st_ivas->hSpar->hMdDec, st_ivas->nchan_transport, IVAS_MAX_NUM_BANDS, st_ivas->bfi, ivas_get_spar_dec_md_num_subframes( st_ivas->sba_order, ivas_total_brate, st_ivas->last_active_ivas_total_brate ) );
+ }
+
+ ivas_sba_dirac_stereo_dec_fx( st_ivas, p_output_fx, output_frame );
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) && LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) && ( GT_32( ivas_total_brate, IVAS_SID_5k2 ) || ( LE_32( ivas_total_brate, IVAS_SID_5k2 ) && st_ivas->nCPE > 0 && EQ_16( st_ivas->hCPE[0]->nchan_out, 1 ) ) ) )
+ {
+ nchan_remapped = 1; /* Only one channel transported */
+ move16();
+ }
+
+ /* HP filtering */
+ FOR( n = 0; n < nchan_remapped; n++ )
+ {
+ hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs );
+ }
+
+ IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) )
+ {
+ nchan_remapped = ivas_sba_remapTCs_fx( p_output_fx, st_ivas, output_frame );
+
+ test();
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
+ {
+ num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( st_ivas->sba_analysis_order, ivas_total_brate, st_ivas->last_active_ivas_total_brate );
+
+ SPAR_DEC_HANDLE hSpar = st_ivas->hSpar;
+ Word16 Q_p_output = MAX_16, temp_min;
+ move16();
+ Word16 nchan_transport;
+
+ nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport;
+ move16();
+ nchan_out = nchan_transport;
+ move16();
+ FOR( ch = 0; ch < nchan_transport; ch++ )
+ {
+ temp_min = L_norm_arr( p_output_fx[ch], output_frame );
+ Q_p_output = s_min( Q_p_output, temp_min );
+ }
+ Q_p_output = sub( Q_p_output, 2 );
+ if ( GT_16( Q_p_output, 20 ) )
+ {
+ Q_p_output = 20;
+ move16();
+ }
+ FOR( ch = 0; ch < nchan_transport; ch++ )
+ {
+ Scale_sig32( p_output_fx[ch], output_frame, Q_p_output ); // Q(11+Q_p_output)
+ }
+
+ ivas_sba_mix_matrix_determiner_fx( st_ivas->hSpar, p_output_fx, st_ivas->bfi, nchan_remapped, output_frame, num_md_sub_frames, Q_p_output );
+ FOR( Word16 c = 0; c < nchan_transport; c++ )
+ {
+ Scale_sig32( p_output_fx[c], output_frame, 11 ); // Q11
+ }
+ }
+ ELSE IF( NE_32( st_ivas->renderer_type, RENDERER_DISABLE ) )
+ {
+ Word16 size = st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport;
+ move16();
+ if ( EQ_16( st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, 3 ) )
+ size = add( size, 1 );
+
+ FOR( i = 0; i < size; i++ )
+ {
+ Scale_sig32( p_output_fx[i], output_frame, Q14 - Q11 ); // Q14
+ }
+
+ ivas_spar_dec_agc_pca_fx( st_ivas, p_output_fx, output_frame );
+ }
+ }
+
+ test();
+ test();
+ IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) )
+ {
+ Word16 q_shift = 0;
+ move16();
+
+ ivas_masa_prerender_fx( st_ivas, p_output_fx, &q_shift, output_frame, nchan_remapped );
+
+ FOR( i = 0; i < CPE_CHANNELS; i++ )
+ {
+ Scale_sig32( p_output_fx[i], output_frame, negate( q_shift ) );
+ }
+
+ test();
+ /* external output */
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) && EQ_32( st_ivas->hMasa->config.input_ivas_format, MASA_ISM_FORMAT ) )
+ {
+ FOR( n = 0; n < st_ivas->nchan_ism; n++ )
+ {
+ set_zero_fx( p_output_fx[add( st_ivas->nchan_transport, n )], output_frame );
+ }
+
+ ivas_omasa_rearrange_channels_fx( p_output_fx, st_ivas->nchan_ism, output_frame );
+ }
+ }
+ ELSE IF( EQ_16( st_ivas->ivas_format, SBA_FORMAT ) && ( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) )
+ {
+ /* loudness correction */
+ ivas_dirac_dec_binaural_sba_gain_fx( p_output_fx, nchan_remapped, output_frame );
+
+ FOR( i = 0; i < st_ivas->nchan_transport; i++ )
+ {
+ Scale_sig32( p_output_fx[i], output_frame, 1 ); // Q-1 -> Q
+ }
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
+ {
+ Word16 nchan_ism, nchan_transport_ism;
+ Word16 dirac_bs_md_write_idx;
+
+ set16_fx( nb_bits_metadata, 0, MAX_SCE + 1 );
+
+ /* Set the number of objects for the parametric rendering */
+ dirac_bs_md_write_idx = 0;
+ move16();
+ IF( st_ivas->hSpatParamRendCom != NULL )
+ {
+ st_ivas->hSpatParamRendCom->numIsmDirections = 0;
+ move16();
+ test();
+ if ( NE_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && NE_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
+ {
+ st_ivas->hSpatParamRendCom->numIsmDirections = st_ivas->nchan_ism;
+ move16();
+ }
+
+ dirac_bs_md_write_idx = st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx; /* Store the write-index for this frame */
+ move16();
+ }
+
+ /* MASA metadata decoding */
+ IF( NE_32( ( error = ivas_masa_decode_fx( st_ivas, st_ivas->hCPE[0]->hCoreCoder[0], &nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ /* Configuration of combined-format bit-budget distribution */
+ ivas_set_surplus_brate_dec( st_ivas, &ism_total_brate );
+
+ st_ivas->hCPE[0]->hCoreCoder[0]->bit_stream = &( st_ivas->bit_stream[( ism_total_brate / FRAMES_PER_SEC )] );
+
+ IF( NE_32( ( error = ivas_omasa_ism_metadata_dec_fx( st_ivas, ism_total_brate, &nchan_ism, &nchan_transport_ism, dirac_bs_md_write_idx, &nb_bits_metadata[1] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ FOR( n = 0; n < nchan_transport_ism; n++ )
+ {
+ IF( NE_32( ( error = ivas_sce_dec_fx( st_ivas, n, &p_output_fx[st_ivas->nchan_transport + n], output_frame, nb_bits_metadata[1] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ /* decode MASA channels */
+ IF( NE_32( ( error = ivas_cpe_dec_fx( st_ivas, 0, p_output_fx, output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ IF( EQ_16( st_ivas->hCPE[0]->nchan_out, 1 ) )
+ {
+ Copy32( p_output_fx[0], p_output_fx[1], output_frame ); /* Copy mono signal to stereo output channels */
+ }
+
+ FOR( n = 0; n < getNumChanSynthesis( st_ivas ); n++ )
+ {
+ hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs );
+ }
+
+ Word16 output_q = Q11;
+ move16();
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) )
+ {
+ ivas_ism_mono_dmx_fx( st_ivas, p_output_fx, output_frame );
+
+ output_q = Q8;
+ move16();
+ }
+ ELSE IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
+ {
+ IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
+ {
+ ivas_omasa_rearrange_channels_fx( p_output_fx, nchan_transport_ism, output_frame );
+ }
+ ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
+ {
+ /* Convert separate object to MASA, combine with the original MASA, and output combined MASA + empty objects. */
+ ivas_omasa_combine_separate_ism_with_masa_fx( st_ivas, p_output_fx, &output_q, st_ivas->nchan_ism, output_frame );
+ }
+ ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
+ {
+ /* Extract objects from MASA, output MASA + all objects (i.e., extracted and separated objects) */
+ ivas_omasa_render_objects_from_mix_fx( st_ivas, p_output_fx, st_ivas->nchan_ism, output_frame, &output_q );
+ }
+ }
+
+ IF( NE_16( output_q, Q11 ) )
+ {
+ FOR( n = 0; n < s_max( getNumChanSynthesis( st_ivas ), nchan_transport_ism + st_ivas->nchan_transport ); n++ )
+ {
+ Scale_sig32( p_output_fx[n], output_frame, sub( Q11, output_q ) ); // Q11
+ }
+ st_ivas->hCPE[0]->q_output_mem_fx[0] = output_q;
+ st_ivas->hCPE[0]->q_output_mem_fx[1] = output_q;
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
+ {
+ Word16 nchan_ism, sba_ch_idx;
+
+ set16_fx( nb_bits_metadata, 0, MAX_SCE + 1 );
+ nchan_ism = st_ivas->nchan_ism;
+ move16();
+ IF( EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
+ {
+ /* set ISM parameters and decode ISM metadata in OSBA format */
+ IF( NE_32( ( error = ivas_osba_ism_metadata_dec_fx( st_ivas, ivas_total_brate, &nchan_ism, &nb_bits_metadata[1] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ sba_ch_idx = st_ivas->nchan_ism;
+ move16();
+ }
+ ELSE
+ {
+ nb_bits_metadata[1] = add( nb_bits_metadata[1], NO_BITS_MASA_ISM_NO_OBJ );
+ sba_ch_idx = 0;
+ move16();
+ move16();
+ }
+
+ /* SBA metadata decoding */
+ IF( NE_32( ( error = ivas_spar_dec_fx( st_ivas, nb_bits_metadata ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ test();
+ IF( EQ_16( st_ivas->nchan_transport, CPE_CHANNELS ) && GE_16( st_ivas->nCPE, 1 ) )
+ {
+ st_ivas->hCPE[0]->element_brate = ivas_total_brate;
+ move32();
+ }
+
+ /* core-decoding of transport channels */
+ IF( EQ_16( st_ivas->nSCE, 1 ) )
+ {
+ IF( NE_32( ( error = ivas_sce_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ ELSE IF( EQ_16( st_ivas->nCPE, 1 ) )
+ {
+ IF( NE_32( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, add( nb_bits_metadata[0], nb_bits_metadata[1] ) ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ ELSE IF( GT_16( st_ivas->nCPE, 1 ) )
+ {
+ IF( NE_32( ( error = ivas_mct_dec_fx( st_ivas, p_output_fx, output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ IF( st_ivas->sba_dirac_stereo_flag )
+ {
+ FOR( i = 0; i < st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport; i++ )
+ {
+ Scale_sig32( p_output_fx[i + sba_ch_idx], output_frame, Q14 - Q11 ); // Q14
+ }
+ SPAR_DEC_HANDLE hSpar = st_ivas->hSpar;
+ Word16 nchan_transport;
+ nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport;
+ move16();
+ nchan_out = nchan_transport;
+ move16();
+ ivas_agc_dec_process_fx( st_ivas->hSpar->hAgcDec, ( p_output_fx + sba_ch_idx ), ( p_output_fx + sba_ch_idx ), st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, output_frame );
+
+ IF( st_ivas->hSpar->hPCA != NULL )
+ {
+ ivas_pca_dec_fx( st_ivas->hSpar->hPCA, output_frame, st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, &p_output_fx[sba_ch_idx] );
+ }
+
+ ivas_spar_dec_gen_umx_mat_fx( st_ivas->hSpar->hMdDec, st_ivas->nchan_transport, IVAS_MAX_NUM_BANDS, st_ivas->bfi, ivas_get_spar_dec_md_num_subframes( st_ivas->sba_order, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate ) );
+
+ ivas_sba_dirac_stereo_dec_fx( st_ivas, &p_output_fx[sba_ch_idx], output_frame );
+ }
+
+ /* HP filtering */
+ FOR( n = 0; n < getNumChanSynthesis( st_ivas ); n++ )
+ {
+ hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs );
+ }
+
+ nchan_remapped = ivas_sba_remapTCs_fx( &p_output_fx[sba_ch_idx], st_ivas, output_frame );
+
+ test();
+ test();
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
+ {
+ num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate );
+ SPAR_DEC_HANDLE hSpar = st_ivas->hSpar;
+ Word16 nchan_transport;
+ // num_bands_out = hSpar->hFbMixer->pFb->filterbank_num_bands;
+ nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport;
+ move16();
+ nchan_out = nchan_transport;
+ move16();
+ Word16 Q_p_output;
+ Word16 min_norm = 31;
+ move16();
+
+ FOR( ch = 0; ch < nchan_transport; ++ch )
+ {
+ Word16 norm = L_norm_arr( p_output_fx[sba_ch_idx + ch], output_frame ); // Normalize per channel
+ min_norm = s_min( norm, min_norm );
+ }
+
+ Q_p_output = s_max( 3, sub( min_norm, 1 ) );
+
+ Q_p_output = s_min( Q_p_output, 19 ); // to restrict Q-factor of p_ouptut to Q30
+ FOR( ch = 0; ch < nchan_transport; ch++ )
+ {
+ Scale_sig32( p_output_fx[sba_ch_idx + ch], output_frame, Q_p_output ); // Q_p_output + Q11
+ }
+ Q_p_output = add( Q11, Q_p_output );
+ hSpar->hMdDec->Q_mixer_mat = 31;
+ move16();
+
+ ivas_sba_mix_matrix_determiner_fx( st_ivas->hSpar, &p_output_fx[sba_ch_idx], st_ivas->bfi, nchan_remapped, output_frame, num_md_sub_frames, sub( Q_p_output, Q11 ) );
+ FOR( Word16 c = 0; c < nchan_transport; c++ )
+ {
+ Scale_sig32( p_output_fx[sba_ch_idx + c], output_frame, Q11 ); // Q11
+ }
+ }
+ ELSE IF( NE_32( st_ivas->renderer_type, RENDERER_DISABLE ) && st_ivas->sba_dirac_stereo_flag == 0 )
+ {
+ Word16 size = add( st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, sba_ch_idx );
+ if ( EQ_16( size, 3 ) )
+ {
+ size = add( size, 1 );
+ }
+
+ FOR( i = sba_ch_idx; i < size; i++ )
+ {
+ Scale_sig32( p_output_fx[i], output_frame, ( Q14 - Q11 ) ); // Q14
+ }
+
+ ivas_spar_dec_agc_pca_fx( st_ivas, &p_output_fx[sba_ch_idx], output_frame );
+ }
+
+ test();
+ test();
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
+ {
+ /* loudness correction */
+ ivas_dirac_dec_binaural_sba_gain_fx( &p_output_fx[sba_ch_idx], nchan_remapped, output_frame ); /*returns Q-1*/
+
+ FOR( i = 0; i < nchan_remapped; i++ )
+ {
+ Scale_sig32( p_output_fx[i], output_frame, 1 ); // Q-1 -> Q
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
+ {
+ ivas_ism_mono_dmx_fx( st_ivas, p_output_fx, output_frame );
+
+ Scale_sig32( p_output_fx[0], output_frame, Q11 - Q8 ); // Q11
+
+ /* add W */
+ FOR( n = 0; n < nchan_out; n++ )
+ {
+ v_add_32( p_output_fx[n], p_output_fx[n + s_max( nchan_out, nchan_ism )], p_output_fx[n], output_frame );
+ }
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) )
+ {
+ IF( st_ivas->nSCE > 0 )
+ {
+ st = st_ivas->hSCE[0]->hCoreCoder[0];
+ }
+ ELSE
+ {
+ st = st_ivas->hCPE[0]->hCoreCoder[0];
+ }
+
+ IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCT ) )
+ {
+ /* LFE channel decoder */
+ ivas_lfe_dec_fx( st_ivas->hLFE, st, output_frame, st_ivas->bfi, p_output_fx[LFE_CHANNEL] );
+
+ Scale_sig32( p_output_fx[LFE_CHANNEL], output_frame, Q11 - Q9 ); // Q11
+
+ IF( NE_32( ( error = ivas_mct_dec_fx( st_ivas, p_output_fx, output_frame, 0 ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ /* HP filtering */
+ FOR( n = 0; n < st_ivas->nchan_transport; n++ )
+ {
+ IF( NE_16( n, LFE_CHANNEL ) )
+ {
+ hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs );
+ }
+ }
+
+ test();
+ test();
+ test();
+ IF( NE_32( st_ivas->transport_config, st_ivas->intern_config ) && ( NE_32( st_ivas->intern_config, IVAS_AUDIO_CONFIG_FOA ) || NE_32( st_ivas->intern_config, IVAS_AUDIO_CONFIG_HOA2 ) || NE_32( st_ivas->intern_config, IVAS_AUDIO_CONFIG_HOA3 ) ) )
+ {
+ IF( GE_16( add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ), add( st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hIntSetup.num_lfe ) ) )
+ {
+ ivas_mc2sba_fx( st_ivas->hTransSetup, p_output_fx, p_output_fx, output_frame, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE_FX );
+ }
+ }
+
+ test();
+ test();
+ IF( ( EQ_32( st_ivas->renderer_type, RENDERER_MC ) || EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) && GE_16( add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ), add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ) ) )
+ {
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_MC ) )
+ {
+ s = Q16 - Q11;
+ move16();
+ s = sub( s, find_guarded_bits_fx( st_ivas->nchan_transport ) );
+ FOR( i = 0; i < s_max( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_transport ); ++i )
+ {
+ Scale_sig32( p_output_fx[i], output_frame, s ); // Q(11+s)
+ }
+ ivas_ls_setup_conversion_fx( st_ivas, st_ivas->nchan_transport, output_frame, p_output_fx, p_output_fx );
+ FOR( i = 0; i < s_max( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_transport ); ++i )
+ {
+ Scale_sig32( p_output_fx[i], output_frame, negate( s ) ); // Q11
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) )
+ {
+ ivas_mc2sba_fx( st_ivas->hIntSetup, p_output_fx, p_output_fx, output_frame, st_ivas->hOutSetup.ambisonics_order, 0 );
+ }
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) )
+ {
+ /* LFE channel decoder */
+ ivas_lfe_dec_fx( st_ivas->hLFE, st, output_frame, st_ivas->bfi, p_output_fx[LFE_CHANNEL] );
+
+ Scale_sig32( p_output_fx[LFE_CHANNEL], output_frame, Q11 - Q9 ); // Q11
+
+ ivas_mc_paramupmix_dec_read_BS( st_ivas, st, st_ivas->hMCParamUpmix, &nb_bits_metadata[0] );
+
+ IF( NE_32( ( error = ivas_mct_dec_fx( st_ivas, p_output_fx, output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ /* HP filtering */
+ FOR( n = 0; n < st_ivas->nchan_transport; n++ )
+ {
+ IF( NE_16( n, LFE_CHANNEL ) )
+ {
+ hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs );
+ }
+ }
+
+ /* Rendering */
+ test();
+ test();
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_MC ) && ( EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) ) )
+ {
+ /* Compensate loudness for not doing full upmix */
+ FOR( n = 4; n < 8; n++ )
+ {
+ Scale_sig32( p_output_fx[n], output_frame, 1 );
+ }
+
+ test();
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) )
+ {
+ s = Q16 - Q11;
+ move16();
+ Word16 nchan_transport;
+ nchan_transport = audioCfg2channels( IVAS_AUDIO_CONFIG_5_1_2 );
+ s = sub( s, find_guarded_bits_fx( nchan_transport ) );
+ FOR( i = 0; i < s_max( st_ivas->hDecoderConfig->nchan_out, nchan_transport ); ++i )
+ {
+ Scale_sig32( p_output_fx[i], output_frame, s );
+ }
+
+ ivas_ls_setup_conversion_fx( st_ivas, nchan_transport, output_frame, p_output_fx, p_output_fx );
+
+ FOR( i = 0; i < s_max( st_ivas->hDecoderConfig->nchan_out, nchan_transport ); ++i )
+ {
+ Scale_sig32( p_output_fx[i], output_frame, negate( s ) );
+ }
+ }
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) )
+ {
+ /* read Parametric MC parameters from the bitstream */
+ ivas_param_mc_dec_read_BS_fx( ivas_total_brate, st, st_ivas->hParamMC, &nb_bits_metadata[0] );
+
+ IF( EQ_16( st_ivas->nCPE, 1 ) )
+ {
+ IF( NE_32( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ ELSE IF( GT_16( st_ivas->nCPE, 1 ) )
+ {
+ IF( NE_32( ( error = ivas_mct_dec_fx( st_ivas, p_output_fx, output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+
+ /* HP filtering */
+ FOR( n = 0; n < st_ivas->nchan_transport; n++ )
+ {
+ hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs );
+ }
+
+ /* Rendering */
+ test();
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) )
+ {
+ ivas_ls_setup_conversion_fx( st_ivas, st_ivas->nchan_transport, output_frame, p_output_fx, p_output_fx );
+ }
+ }
+ ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) )
+ {
+ IF( st_ivas->hOutSetup.separateChannelEnabled )
+ {
+ st = st_ivas->hCPE[0]->hCoreCoder[0]; /* Metadata is always with CPE in the case of separated channel */
+ }
+
+ /* read McMASA parameters from the bitstream */
+ IF( NE_32( ( error = ivas_masa_decode_fx( st_ivas, st, &nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ IF( st_ivas->hOutSetup.separateChannelEnabled )
+ {
+ /* Decode the transport audio signals */
+ IF( NE_32( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ /* Identify the index of the separated channel, always LFE_CHANNEL-1 here */
+ n = LFE_CHANNEL - 1;
+ move16();
+
+ /* Decode the separated channel to output[n] to be combined with the synthesized channels */
+ IF( NE_32( ( error = ivas_sce_dec_fx( st_ivas, 0, &p_output_fx[n], output_frame, 0 ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ test();
+ test();
+ test();
+ test();
+ test();
+ test();
+ test();
+ /* Delay the separated channel to sync with CLDFB delay of the DirAC synthesis, and synthesize the LFE signal. */
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_7_1 ) ||
+ EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1_4 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_7_1_4 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1_2 ) || ( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && st_ivas->hOutSetup.num_lfe > 0 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
+ {
+ ivas_lfe_synth_with_filters_fx( st_ivas->hMasa->hMasaLfeSynth, p_output_fx, output_frame, n, LFE_CHANNEL );
+ }
+ ELSE IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && st_ivas->hOutSetup.num_lfe == 0 )
+ {
+ /* Delay the separated channel to sync with the DirAC rendering */
+ delay_signal32_fx( p_output_fx[n], output_frame, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_size );
+ }
+ }
+ ELSE
+ {
+ IF( EQ_16( st_ivas->nSCE, 1 ) )
+ {
+ IF( NE_32( ( error = ivas_sce_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ ELSE IF( EQ_16( st_ivas->nCPE, 1 ) )
+ {
+ IF( NE_32( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ }
+
+ IF( st_ivas->sba_dirac_stereo_flag != 0 ) /* use the flag to trigger the DFT upmix */
+ {
+ ivas_sba_dirac_stereo_dec_fx( st_ivas, p_output_fx, output_frame );
+ }
+
+ /* HP filtering */
+ FOR( n = 0; n < getNumChanSynthesis( st_ivas ); n++ )
+ {
+ hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs );
+ }
+
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_MCMASA_MONO_STEREO ) )
+ {
+ ivas_mono_stereo_downmix_mcmasa_fx( st_ivas, p_output_fx, output_frame );
+ }
+ }
+ }
+
+ /*----------------------------------------------------------------*
+ * Common updates
+ *----------------------------------------------------------------*/
+
+ IF( !st_ivas->bfi ) /* do not update if first frame(s) are lost or NO_DATA */
+ {
+ st_ivas->hDecoderConfig->last_ivas_total_brate = ivas_total_brate;
+ move32();
+ IF( LE_32( ivas_total_brate, IVAS_SID_5k2 ) )
+ {
+ st_ivas->last_active_ivas_total_brate = st_ivas->last_active_ivas_total_brate;
+ move32();
+ }
+ ELSE
+ {
+ st_ivas->last_active_ivas_total_brate = ivas_total_brate;
+ move32();
+ }
+ }
+
+ test();
+ test();
+ if ( LT_16( st_ivas->ini_frame, MAX_FRAME_COUNTER ) && !( st_ivas->bfi && st_ivas->ini_frame == 0 ) ) /* keep "st_ivas->ini_frame = 0" until first good received frame */
+ {
+ st_ivas->ini_frame = add( st_ivas->ini_frame, 1 );
+ move16();
+ }
+
+ test();
+ test();
+ if ( LT_16( st_ivas->ini_active_frame, MAX_FRAME_COUNTER ) && !( st_ivas->bfi && st_ivas->ini_frame == 0 ) && GT_32( ivas_total_brate, IVAS_SID_5k2 ) ) /* needed in MASA decoder in case the first active frame is BFI, and there were SID-frames decoded before */
+ {
+ st_ivas->ini_active_frame = add( st_ivas->ini_active_frame, 1 );
+ move16();
+ }
+
+ st_ivas->last_ivas_format = st_ivas->ivas_format;
+ move32();
+ pop_wmops();
+
+ return IVAS_ERR_OK;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_dec_get_num_tc_channels()
+ *
+ * Get the number of transport channels provided to the renderer
+ *--------------------------------------------------------------------------*/
+
+Word16 ivas_dec_get_num_tc_channels_fx(
+ Decoder_Struct *st_ivas /* i : IVAS decoder handle */
+)
+{
+ Word16 num_tc;
+ Word32 ivas_total_brate;
+ AUDIO_CONFIG output_config;
+
+ IF( EQ_16( st_ivas->renderer_type, RENDERER_DISABLE ) )
+ {
+ num_tc = st_ivas->hDecoderConfig->nchan_out;
+ move16();
+ }
+ ELSE
+ {
+ num_tc = st_ivas->nchan_transport;
+ move16();
+ }
+ output_config = st_ivas->hDecoderConfig->output_config;
+ move16();
+
+ ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
+ move32();
+
+ test();
+ test();
+ test();
+ test();
+ IF( EQ_32( st_ivas->ivas_format, MONO_FORMAT ) )
+ {
+ num_tc = 1;
+ move16();
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) && EQ_16( st_ivas->hDecoderConfig->nchan_out, 1 ) )
+ {
+ num_tc = 1;
+ move16();
+ }
+ ELSE IF( EQ_16( st_ivas->ivas_format, ISM_FORMAT ) )
+ {
+ if ( EQ_16( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) )
+ {
+ num_tc = 1;
+ move16();
+ }
+ }
+ ELSE IF( EQ_16( st_ivas->ivas_format, SBA_FORMAT ) || EQ_16( st_ivas->ivas_format, MASA_FORMAT ) )
+ {
+ test();
+ test();
+ test();
+ test();
+ test();
+ test();
+ IF( st_ivas->sba_dirac_stereo_flag )
+ {
+ num_tc = CPE_CHANNELS;
+ move16();
+ }
+ ELSE IF( EQ_16( st_ivas->ivas_format, MASA_FORMAT ) && LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) && ( GT_32( ivas_total_brate, IVAS_SID_5k2 ) || ( LE_32( ivas_total_brate, IVAS_SID_5k2 ) && GT_16( st_ivas->nCPE, 0 ) && st_ivas->hCPE[0] != NULL && EQ_16( st_ivas->hCPE[0]->nchan_out, 1 ) ) ) )
+ {
+ num_tc = 1; /* Only one channel transported */
+ move16();
+ }
+
+ test();
+ test();
+ test();
+ test();
+ IF( EQ_16( st_ivas->ivas_format, MASA_FORMAT ) && EQ_16( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) && EQ_16( st_ivas->nchan_transport, 2 ) && LT_32( st_ivas->hDecoderConfig->ivas_total_brate, MASA_STEREO_MIN_BITRATE ) && GT_32( st_ivas->hDecoderConfig->ivas_total_brate, IVAS_SID_5k2 ) )
+ {
+ num_tc = CPE_CHANNELS;
+ move16();
+ }
+ IF( EQ_16( st_ivas->ivas_format, SBA_FORMAT ) )
+ {
+ if ( EQ_16( num_tc, 3 ) )
+ {
+ num_tc = add( num_tc, 1 );
+ }
+ }
+ }
+ ELSE IF( EQ_16( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
+ {
+ IF( NE_16( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
+ {
+ test();
+ IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
+ {
+ num_tc = add( num_tc, 1 );
+ }
+ ELSE IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
+ {
+ num_tc = add( num_tc, st_ivas->nchan_ism );
+ }
+ }
+ }
+ ELSE IF( EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
+ {
+ if ( st_ivas->sba_dirac_stereo_flag )
+ {
+ num_tc = CPE_CHANNELS;
+ move16();
+ }
+
+ if ( EQ_16( num_tc, 3 ) )
+ {
+ num_tc = add( num_tc, 1 );
+ }
+ if ( EQ_16( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
+ {
+ num_tc = add( num_tc, st_ivas->nchan_ism );
+ }
+ }
+ ELSE IF( EQ_16( st_ivas->ivas_format, MC_FORMAT ) )
+ {
+ IF( EQ_16( output_config, IVAS_AUDIO_CONFIG_MONO ) )
+ {
+ num_tc = 1;
+ move16();
+ }
+ ELSE IF( EQ_16( output_config, IVAS_AUDIO_CONFIG_STEREO ) )
+ {
+ num_tc = 2;
+ move16();
+ }
+ ELSE IF( EQ_16( st_ivas->mc_mode, MC_MODE_MCT ) )
+ {
+ /* do all static dmx already in the TC decoder if less channels than transported... */
+ test();
+ test();
+ test();
+ test();
+ test();
+ IF( NE_16( st_ivas->transport_config, st_ivas->intern_config ) && ( EQ_16( st_ivas->intern_config, IVAS_AUDIO_CONFIG_FOA ) || EQ_16( st_ivas->intern_config, IVAS_AUDIO_CONFIG_HOA2 ) || EQ_16( st_ivas->intern_config, IVAS_AUDIO_CONFIG_HOA3 ) ) )
+ {
+ if ( GE_16( add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ), add( st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hIntSetup.num_lfe ) ) )
+ {
+ num_tc = add( st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hIntSetup.num_lfe );
+ }
+ }
+ ELSE IF( ( EQ_16( st_ivas->renderer_type, RENDERER_MC ) || EQ_16( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) && GE_16( add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ), add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ) ) )
+ {
+ num_tc = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe );
+ }
+ }
+ ELSE IF( EQ_16( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) )
+ {
+ num_tc = MC_PARAMUPMIX_MAX_TRANSPORT_CHANS;
+ move16();
+ }
+ ELSE IF( EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) )
+ {
+ if ( st_ivas->hOutSetup.separateChannelEnabled )
+ {
+ num_tc = add( num_tc, 1 );
+ }
+
+ test();
+ test();
+ test();
+ test();
+ test();
+ test();
+ test();
+ if ( st_ivas->hOutSetup.separateChannelEnabled && ( EQ_16( output_config, IVAS_AUDIO_CONFIG_5_1 ) || EQ_16( output_config, IVAS_AUDIO_CONFIG_7_1 ) ||
+ EQ_16( output_config, IVAS_AUDIO_CONFIG_5_1_4 ) || EQ_16( output_config, IVAS_AUDIO_CONFIG_7_1_4 ) ||
+ EQ_16( output_config, IVAS_AUDIO_CONFIG_5_1_2 ) || ( EQ_16( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && st_ivas->hOutSetup.num_lfe > 0 ) ) )
+ {
+ /* LFE is synthesized in TD with the TCs*/
+ num_tc = add( num_tc, 1 );
+ }
+ }
+ }
+
+ return num_tc;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_dec_get_tc_buffer_mode()
+ *
+ *
+ *--------------------------------------------------------------------------*/
+
+TC_BUFFER_MODE ivas_dec_get_tc_buffer_mode_fx(
+ Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
+)
+{
+ TC_BUFFER_MODE buffer_mode;
+
+ buffer_mode = TC_BUFFER_MODE_BUFFER;
+ move16();
+
+ SWITCH( st_ivas->renderer_type )
+ {
+ /* all renderers where we are done after TC decoding (might include DMX to mono/stereo */
+ case RENDERER_DISABLE:
+ case RENDERER_MCMASA_MONO_STEREO:
+ case RENDERER_OSBA_STEREO:
+ case RENDERER_MONO_DOWNMIX:
+ buffer_mode = TC_BUFFER_MODE_BUFFER;
+ move16();
+ BREAK;
+ case RENDERER_NON_DIEGETIC_DOWNMIX:
+ case RENDERER_TD_PANNING:
+ case RENDERER_BINAURAL_OBJECTS_TD:
+ case RENDERER_BINAURAL_FASTCONV:
+ case RENDERER_BINAURAL_FASTCONV_ROOM:
+ case RENDERER_BINAURAL_PARAMETRIC:
+ case RENDERER_BINAURAL_PARAMETRIC_ROOM:
+ case RENDERER_STEREO_PARAMETRIC:
+ case RENDERER_DIRAC:
+ case RENDERER_PARAM_ISM:
+ case RENDERER_BINAURAL_MIXER_CONV:
+ case RENDERER_BINAURAL_MIXER_CONV_ROOM:
+ case RENDERER_OMASA_OBJECT_EXT:
+ case RENDERER_OMASA_MIX_EXT:
+ case RENDERER_OSBA_AMBI:
+ case RENDERER_OSBA_LS:
+ buffer_mode = TC_BUFFER_MODE_RENDERER;
+ move16();
+ BREAK;
+ case RENDERER_MC_PARAMMC:
+ IF( EQ_32( st_ivas->hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) )
+ {
+ buffer_mode = TC_BUFFER_MODE_BUFFER; /* TCs are already the DMX to mono or stereo */
+ move16();
+ }
+ ELSE
+ {
+ buffer_mode = TC_BUFFER_MODE_RENDERER;
+ move16();
+ }
+ BREAK;
+ case RENDERER_MC:
+ if ( NE_16( ivas_dec_get_num_tc_channels_fx( st_ivas ), st_ivas->hDecoderConfig->nchan_out ) )
+ {
+ buffer_mode = TC_BUFFER_MODE_RENDERER;
+ move16();
+ }
+ BREAK;
+ case RENDERER_SBA_LINEAR_ENC:
+ test();
+ test();
+ test();
+ test();
+ IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && EQ_32( st_ivas->mc_mode, MC_MODE_MCT ) && ( EQ_32( st_ivas->renderer_type, RENDERER_MC ) || EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) && GE_16( ( add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ) ), ( add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ) ) ) )
+ {
+ buffer_mode = TC_BUFFER_MODE_BUFFER;
+ move16();
+ }
+ ELSE
+ {
+ buffer_mode = TC_BUFFER_MODE_RENDERER;
+ move16();
+ }
+ BREAK;
+ case RENDERER_SBA_LINEAR_DEC:
+ test();
+ test();
+ IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) && ( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) ) )
+ {
+ buffer_mode = TC_BUFFER_MODE_BUFFER;
+ move16();
+ }
+ ELSE
+ {
+ buffer_mode = TC_BUFFER_MODE_RENDERER;
+ move16();
+ }
+ BREAK;
+ }
+
+ return buffer_mode;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_dec_tc_audio_allocate()
+ *
+ * allocate and initialize TC audio buffer
+ *--------------------------------------------------------------------------*/
+
+static ivas_error ivas_dec_tc_audio_allocate_fx(
+ DECODER_TC_BUFFER_HANDLE hTcBuffer, /* i/o: TC buffer handle */
+ const Word32 output_Fs, /* i : output sampling rate */
+ const Word16 Opt_tsm /* i : TSM option flag */
+)
+{
+ Word16 nsamp_to_allocate;
+ Word16 ch_idx, n_samp_full, n_samp_residual, offset;
+
+ IF( Opt_tsm )
+ {
+ n_samp_full = NS2SA_FX2( output_Fs, MAX_JBM_L_FRAME_NS );
+ n_samp_full = s_max( n_samp_full, L_FRAME48k ); /* buffers are shared between 'hTcBuffer->tc[]' and 'p_output_f[]': ensure minimal length */
+ n_samp_residual = sub( hTcBuffer->n_samples_granularity, 1 );
+ }
+ ELSE
+ {
+ n_samp_full = extract_l( Mpy_32_32( output_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) );
+ n_samp_residual = 0;
+ move16();
+ }
+
+ nsamp_to_allocate = imult1616( s_max( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full ), n_samp_full );
+
+ IF( Opt_tsm )
+ {
+ /* note: this is stack memory buffer for TC decoded and also time-scale modified audio signals */
+ IF( ( hTcBuffer->tc_buffer_fx = (Word32 *) malloc( nsamp_to_allocate * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TC Buffer\n" ) );
+ }
+ set_zero_fx( hTcBuffer->tc_buffer_fx, nsamp_to_allocate );
+
+ offset = 0;
+ move16();
+ FOR( ch_idx = 0; ch_idx < s_max( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full ); ch_idx++ )
+ {
+ hTcBuffer->tc_fx[ch_idx] = &hTcBuffer->tc_buffer_fx[offset];
+ offset = add( offset, n_samp_full );
+ }
+ FOR( ; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
+ {
+ hTcBuffer->tc_fx[ch_idx] = NULL;
+ }
+
+ /* memory buffer for TC audio samples not rendered in the previous frame */
+ FOR( ch_idx = 0; ch_idx < hTcBuffer->nchan_transport_internal; ch_idx++ )
+ {
+ IF( ( hTcBuffer->tc_buffer_old_fx[ch_idx] = (Word32 *) malloc( n_samp_residual * sizeof( Word32 ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TC Buffer\n" ) );
+ }
+ set_zero_fx( hTcBuffer->tc_buffer_old_fx[ch_idx], n_samp_residual );
+ }
+ FOR( ; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
+ {
+ hTcBuffer->tc_buffer_old_fx[ch_idx] = NULL;
+ }
+ }
+ else
+ {
+ hTcBuffer->tc_buffer_fx = NULL;
+
+ FOR( ch_idx = 0; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
+ {
+ hTcBuffer->tc_fx[ch_idx] = NULL;
+ }
+
+ FOR( ch_idx = 0; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
+ {
+ hTcBuffer->tc_buffer_old_fx[ch_idx] = NULL;
+ }
+ }
+
+ hTcBuffer->tc_buffer2_fx = NULL;
+
+ return IVAS_ERR_OK;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_dec_tc_buffer_open()
+ *
+ * Open and initialize transport channel buffer handle
+ *--------------------------------------------------------------------------*/
+
+ivas_error ivas_dec_tc_buffer_open_fx(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ const TC_BUFFER_MODE tc_buffer_mode, /* i : buffer mode */
+ const Word16 nchan_transport_rend, /* i : number of TCs for rendering */
+ const Word16 nchan_transport_internal, /* i : number of totally buffered channels */
+ const Word16 nchan_full, /* i : number of channels to fully store */
+ const Word16 n_samples_granularity /* i : granularity of the renderer/buffer */
+)
+{
+ DECODER_TC_BUFFER_HANDLE hTcBuffer;
+ Word16 nMaxSlotsPerSubframe;
+ ivas_error error;
+ Word16 tmp, tmp_e;
+
+ /*-----------------------------------------------------------------*
+ * prepare library opening
+ *-----------------------------------------------------------------*/
+
+ IF( ( hTcBuffer = (DECODER_TC_BUFFER_HANDLE) malloc( sizeof( DECODER_TC_BUFFER ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TC Buffer\n" ) );
+ }
+
+ hTcBuffer->tc_buffer_mode = tc_buffer_mode;
+ move16();
+ hTcBuffer->nchan_transport_rend = nchan_transport_rend;
+ move16();
+ hTcBuffer->nchan_transport_internal = nchan_transport_internal;
+ move16();
+ hTcBuffer->nchan_buffer_full = nchan_full;
+ move16();
+ hTcBuffer->n_samples_granularity = n_samples_granularity;
+ move16();
+ hTcBuffer->n_samples_available = 0;
+ move16();
+ hTcBuffer->n_samples_buffered = 0;
+ move16();
+ hTcBuffer->n_samples_rendered = 0;
+ move16();
+ hTcBuffer->slots_rendered = 0;
+ move16();
+ hTcBuffer->subframes_rendered = 0;
+ move16();
+ hTcBuffer->n_samples_discard = 0;
+ move16();
+ hTcBuffer->n_samples_flushed = 0;
+ move16();
+ hTcBuffer->nb_subframes = MAX_PARAM_SPATIAL_SUBFRAMES;
+ move16();
+
+ /* nMaxSlotsPerSubframe = (Word16)(st_ivas->hDecoderConfig->output_Fs / (FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES)) / st_ivas->hTcBuffer->n_samples_granularity; */
+ tmp = extract_l( Mpy_32_16_1( st_ivas->hDecoderConfig->output_Fs, ONE_BY_SUBFR_PER_SEC_Q15 ) );
+ tmp = BASOP_Util_Divide1616_Scale( tmp, hTcBuffer->n_samples_granularity, &tmp_e );
+ nMaxSlotsPerSubframe = shr( tmp, sub( 15, tmp_e ) ); /* Q0 */
+
+ hTcBuffer->num_slots = mult0( nMaxSlotsPerSubframe, MAX_PARAM_SPATIAL_SUBFRAMES );
+ move16();
+
+ set16_fx( hTcBuffer->subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS );
+ set16_fx( hTcBuffer->subframe_nbslots, nMaxSlotsPerSubframe, MAX_PARAM_SPATIAL_SUBFRAMES );
+
+ IF( ( error = ivas_dec_tc_audio_allocate_fx( hTcBuffer, st_ivas->hDecoderConfig->output_Fs, st_ivas->hDecoderConfig->Opt_tsm ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ st_ivas->hTcBuffer = hTcBuffer;
+
+ return IVAS_ERR_OK;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_jbm_dec_tc_audio_deallocate()
+ *
+ * deallocate TC audio buffer
+ *--------------------------------------------------------------------------*/
+
+static void ivas_jbm_dec_tc_audio_deallocate_fx(
+ DECODER_TC_BUFFER_HANDLE hTcBuffer /* i/o: JBM TSM buffer handle */
+)
+{
+ Word16 ch_idx;
+
+ IF( hTcBuffer != NULL )
+ {
+ IF( hTcBuffer->tc_buffer_fx != NULL )
+ {
+ FOR( ch_idx = 0; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
+ {
+ hTcBuffer->tc_fx[ch_idx] = NULL;
+ }
+
+ free( hTcBuffer->tc_buffer_fx );
+ hTcBuffer->tc_buffer_fx = NULL;
+ }
+
+ FOR( ch_idx = 0; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
+ {
+ IF( hTcBuffer->tc_buffer_old_fx[ch_idx] != NULL )
+ {
+ free( hTcBuffer->tc_buffer_old_fx[ch_idx] );
+ hTcBuffer->tc_buffer_old_fx[ch_idx] = NULL;
+ }
+ }
+
+ IF( hTcBuffer->tc_buffer2_fx != NULL )
+ {
+ free( hTcBuffer->tc_buffer2_fx );
+ hTcBuffer->tc_buffer2_fx = NULL;
+ }
+ }
+
+ return;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_dec_tc_buffer_close()
+ *
+ * Close transport channel buffer handle
+ *--------------------------------------------------------------------------*/
+
+void ivas_dec_tc_buffer_close_fx(
+ DECODER_TC_BUFFER_HANDLE *phTcBuffer /* i/o: TC buffer handle */
+)
+{
+ IF( *phTcBuffer != NULL )
+ {
+ ivas_jbm_dec_tc_audio_deallocate_fx( *phTcBuffer );
+
+ free( *phTcBuffer );
+ *phTcBuffer = NULL;
+ }
+
+ return;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_dec_tc_buffer_reconfigure()
+ *
+ * Reconfigure transport channel buffer handle
+ *--------------------------------------------------------------------------*/
+
+ivas_error ivas_dec_tc_buffer_reconfigure_fx(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ const TC_BUFFER_MODE tc_buffer_mode, /* i : new buffer mode */
+ const Word16 nchan_transport_rend, /* i : new number of TCs for rendering */
+ const Word16 nchan_transport_internal, /* i : new number of totally buffered channels */
+ const Word16 nchan_full, /* i : new number of channels to fully store */
+ const Word16 n_samples_granularity /* i : new granularity of the renderer/buffer */
+)
+{
+ Word16 ch_idx, num_tc_buffer_mem, n_samples_still_available;
+ Word32 tc_buffer_mem[MAX_INTERN_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES - 1];
+ ivas_error error;
+ DECODER_TC_BUFFER_HANDLE hTcBuffer;
+
+ hTcBuffer = st_ivas->hTcBuffer;
+ move16();
+
+ num_tc_buffer_mem = 0;
+ move16();
+ n_samples_still_available = 0;
+ move16();
+
+ IF( st_ivas->hDecoderConfig->Opt_tsm )
+ {
+ /* save samples of the TC buffer from the previous frame */
+ num_tc_buffer_mem = s_min( hTcBuffer->nchan_transport_internal, nchan_transport_internal );
+ n_samples_still_available = sub( hTcBuffer->n_samples_buffered, hTcBuffer->n_samples_rendered );
+
+ /* what is remaining from last frame needs always be smaller than the new granularity */
+ assert( n_samples_still_available < n_samples_granularity );
+
+ FOR( ch_idx = 0; ch_idx < num_tc_buffer_mem; ch_idx++ )
+ {
+ Copy32( hTcBuffer->tc_buffer_old_fx[ch_idx] + hTcBuffer->n_samples_flushed, tc_buffer_mem[ch_idx], n_samples_still_available );
+ }
+ }
+
+ /* if granularity changes, adapt subframe_nb_slots */
+ IF( NE_16( n_samples_granularity, hTcBuffer->n_samples_granularity ) )
+ {
+ Word16 nMaxSlotsPerSubframeNew;
+ Word16 tmp, tmp_e;
+
+ /* nMaxSlotsPerSubframeNew = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ) / n_samples_granularity; */
+ tmp = extract_l( Mpy_32_16_1( st_ivas->hDecoderConfig->output_Fs, ONE_BY_SUBFR_PER_SEC_Q15 ) );
+ tmp = BASOP_Util_Divide1616_Scale( tmp, n_samples_granularity, &tmp_e );
+ nMaxSlotsPerSubframeNew = shr( tmp, sub( 15, tmp_e ) ); /* Q0 */
+
+ /* if samples were flushed, take that into account here */
+ test();
+ IF( LT_16( n_samples_granularity, hTcBuffer->n_samples_granularity ) && hTcBuffer->n_samples_flushed > 0 )
+ {
+ hTcBuffer->subframe_nbslots[hTcBuffer->subframes_rendered - 1] = idiv1616( hTcBuffer->n_samples_flushed, n_samples_granularity );
+ hTcBuffer->n_samples_flushed = 0;
+ move16();
+ move16();
+ }
+ ELSE
+ {
+ hTcBuffer->subframe_nbslots[hTcBuffer->subframes_rendered - 1] = nMaxSlotsPerSubframeNew;
+ move16();
+ }
+ }
+
+ hTcBuffer->tc_buffer_mode = tc_buffer_mode;
+ move16();
+ hTcBuffer->nchan_transport_rend = nchan_transport_rend;
+ move16();
+ hTcBuffer->nchan_transport_internal = nchan_transport_internal;
+ move16();
+ hTcBuffer->nchan_buffer_full = nchan_full;
+ move16();
+ hTcBuffer->n_samples_granularity = n_samples_granularity;
+ move16();
+
+ /* reallocate TC audio buffers */
+
+ ivas_jbm_dec_tc_audio_deallocate_fx( hTcBuffer );
+
+ IF( ( error = ivas_dec_tc_audio_allocate_fx( hTcBuffer, st_ivas->hDecoderConfig->output_Fs, st_ivas->hDecoderConfig->Opt_tsm ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* propagate samples of the TC buffer from the previous frame */
+ FOR( ch_idx = 0; ch_idx < num_tc_buffer_mem; ch_idx++ )
+ {
+ Copy32( tc_buffer_mem[ch_idx], hTcBuffer->tc_buffer_old_fx[ch_idx], n_samples_still_available );
+ }
+
+ return IVAS_ERR_OK;
+}
diff --git a/lib_dec/ivas_jbm_dec_fx.c b/lib_dec/ivas_dec_render_fx.c
similarity index 64%
rename from lib_dec/ivas_jbm_dec_fx.c
rename to lib_dec/ivas_dec_render_fx.c
index 55788b01c7c32969d2a33e9943b1305522d84dd2..5b685edd4de31d1803d2084850d7f231e4bd49a0 100644
--- a/lib_dec/ivas_jbm_dec_fx.c
+++ b/lib_dec/ivas_dec_render_fx.c
@@ -67,814 +67,824 @@ static Word16 ceil_fx16(
return ret;
}
+
+/*--------------------------------------------------------------------------*
+ * ivas_dec_feed_tc_to_renderer()
+ *
+ * Feed decoded transport channels to the IVAS renderer routine
+ * + digest TC channels in ParamISM and ParamMC
+ *--------------------------------------------------------------------------*/
+
+void ivas_dec_feed_tc_to_renderer_fx(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ const Word16 nSamplesForRendering, /* i : number of TC samples available for rendering */
+ Word16 *nSamplesResidual /* o : number of samples not fitting into the renderer grid and buffer for the next call*/
+)
+{
+ Word32 tmp_buf_fx[MAX_JBM_L_FRAME48k];
+ Word32 *p_data_fx[FOA_CHANNELS + MAX_NUM_OBJECTS];
+ Word16 n, n_render_timeslots, n_ch_cldfb;
+ Word16 ch, offset, len_offset;
+ DECODER_TC_BUFFER_HANDLE hTcBuffer;
+
+ hTcBuffer = st_ivas->hTcBuffer;
+ n_ch_cldfb = sub( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full );
+ move16();
+
+ hTcBuffer->q_tc_fx = Q11;
+ move16();
+
+ IF( st_ivas->hDecoderConfig->Opt_tsm )
+ {
+ Word16 n_samples_still_available;
+ Word16 n_ch_full_copy, n_ch_res_copy;
+
+ n_samples_still_available = sub( hTcBuffer->n_samples_buffered, hTcBuffer->n_samples_rendered );
+ hTcBuffer->n_samples_buffered = add( add( n_samples_still_available, nSamplesForRendering ), hTcBuffer->n_samples_discard );
+ hTcBuffer->n_samples_available = i_mult( hTcBuffer->n_samples_granularity, idiv1616( hTcBuffer->n_samples_buffered, hTcBuffer->n_samples_granularity ) );
+ *nSamplesResidual = sub( hTcBuffer->n_samples_buffered, hTcBuffer->n_samples_available );
+ move16();
+ move16();
+ move16();
+ n_ch_full_copy = s_min( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full );
+ n_ch_res_copy = sub( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full );
+
+ /* buffers are shared between 'hTcBuffer->tc[]' and 'p_output_f[]':
+ in case of 'length(hTcBuffer->tc[]) < length(p_output_f[])', reset of TC buffer
+ pointers is needed after ivas_buffer_interleaved_to_deinterleaved() */
+ len_offset = NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS );
+ IF( LT_16( len_offset, L_FRAME48k ) )
+ {
+ offset = 0;
+ move16();
+ FOR( ch = 0; ch < s_max( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full ); ch++ )
+ {
+ hTcBuffer->tc_fx[ch] = &hTcBuffer->tc_buffer_fx[offset];
+ st_ivas->p_output_fx[ch] = hTcBuffer->tc_fx[ch];
+ offset = add( offset, len_offset );
+ }
+ }
+
+ FOR( ch = 0; ch < n_ch_full_copy; ch++ )
+ {
+ Copy32( hTcBuffer->tc_fx[ch], tmp_buf_fx, nSamplesForRendering );
+ set_zero_fx( hTcBuffer->tc_fx[ch], hTcBuffer->n_samples_discard );
+ Copy32( hTcBuffer->tc_buffer_old_fx[ch], hTcBuffer->tc_fx[ch] + hTcBuffer->n_samples_discard, n_samples_still_available );
+ Copy32( tmp_buf_fx, hTcBuffer->tc_fx[ch] + n_samples_still_available + hTcBuffer->n_samples_discard, nSamplesForRendering - *nSamplesResidual );
+ Copy32( tmp_buf_fx + nSamplesForRendering - *nSamplesResidual, hTcBuffer->tc_buffer_old_fx[ch], *nSamplesResidual );
+ }
+
+ IF( n_ch_res_copy > 0 )
+ {
+ FOR( ; ch < hTcBuffer->nchan_transport_rend; ch++ )
+ {
+ p_data_fx[ch] = hTcBuffer->tc_fx[ch];
+ Copy32( hTcBuffer->tc_fx[ch], tmp_buf_fx, nSamplesForRendering );
+ Copy32( hTcBuffer->tc_buffer_old_fx[ch], p_data_fx[ch], n_samples_still_available );
+ Copy32( tmp_buf_fx, p_data_fx[ch] + n_samples_still_available, sub( nSamplesForRendering, *nSamplesResidual ) );
+ Copy32( tmp_buf_fx + nSamplesForRendering - *nSamplesResidual, hTcBuffer->tc_buffer_old_fx[ch], *nSamplesResidual );
+ }
+ }
+
+ n_render_timeslots = idiv1616( st_ivas->hTcBuffer->n_samples_available, st_ivas->hTcBuffer->n_samples_granularity );
+ }
+ ELSE
+ {
+ FOR( n = 0; n < n_ch_cldfb; n++ )
+ {
+ p_data_fx[n] = &st_ivas->p_output_fx[n][0];
+ move16();
+ }
+
+ ch = s_max( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full );
+ FOR( n = 0; n < ch; n++ )
+ {
+ hTcBuffer->tc_fx[n] = st_ivas->p_output_fx[n]; /* note: buffers needed in the TD decorellator */
+ move16();
+ }
+
+ hTcBuffer->n_samples_buffered = nSamplesForRendering;
+ hTcBuffer->n_samples_available = hTcBuffer->n_samples_buffered;
+ *nSamplesResidual = 0;
+ move16();
+ move16();
+ move16();
+
+ n_render_timeslots = DEFAULT_JBM_CLDFB_TIMESLOTS;
+ move16();
+ }
+
+ /* CLDFB analysis for ParamMC/ParamISM */
+ test();
+ test();
+ test();
+ test();
+ test();
+ test();
+ IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) && ( EQ_32( st_ivas->renderer_type, RENDERER_PARAM_ISM ) || EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) )
+ {
+ ivas_param_ism_dec_digest_tc_fx( st_ivas, n_render_timeslots, p_data_fx, Q11 );
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) && EQ_32( hTcBuffer->tc_buffer_mode, TC_BUFFER_MODE_RENDERER ) )
+ {
+ ivas_param_mc_dec_digest_tc_fx( st_ivas, (UWord8) n_render_timeslots, p_data_fx, Q11 );
+ }
+
+ hTcBuffer->n_samples_rendered = 0;
+ move16();
+ hTcBuffer->subframes_rendered = 0;
+ move16();
+
+ return;
+}
+
+
/*--------------------------------------------------------------------------*
- * ivas_dec()
+ * ivas_dec_render()
*
- * Principal IVAS decoder routine, decoding of metadata and transport channels
+ * Principal IVAS internal rendering routine
*--------------------------------------------------------------------------*/
-ivas_error ivas_dec_fx(
- Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
+ivas_error ivas_dec_render_fx(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ const UWord16 nSamplesAsked, /* i : number of samples wanted */
+ UWord16 *nSamplesRendered, /* o : number of samples rendered */
+ UWord16 *nSamplesAvailableNext, /* o : number of samples still available in the rendering pipeline */
+ Word16 *data /* o : output synthesis signal Q0*/
)
{
- Word16 ch, n, output_frame, nchan_out, i, s;
- Decoder_State *st; /* used for bitstream handling */
- Word32 *p_output_fx[MAX_TRANSPORT_CHANNELS]; /* buffer for output synthesis */
+ Word16 n, nchan_out;
+ Word16 nchan_transport_rend;
Word16 nchan_remapped;
- Word16 nb_bits_metadata[MAX_SCE + 1];
- Word32 output_Fs, ivas_total_brate;
+ Word32 output_Fs;
AUDIO_CONFIG output_config;
+ Word16 nSamplesAskedLocal;
ivas_error error;
- Word16 num_md_sub_frames;
- Word32 ism_total_brate;
+ Word32 *p_output_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS];
+ Word32 *p_tc_fx[MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS];
+ Word16 subframe_len, gd_bits, exp, nchan_in, i, j, ch;
+ const Word16 output_q_factor = Q11;
+ move16();
+ Word16 nchan_out_syn_output;
- push_wmops( "ivas_dec" );
+ push_wmops( "ivas_dec_render" );
/*----------------------------------------------------------------*
* Initialization of local vars after struct has been set
*----------------------------------------------------------------*/
output_Fs = st_ivas->hDecoderConfig->output_Fs;
move32();
- nchan_out = st_ivas->hTcBuffer->nchan_transport_rend;
+ nchan_out = st_ivas->hDecoderConfig->nchan_out;
+ move16();
+ nchan_transport_rend = st_ivas->hTcBuffer->nchan_transport_rend;
move16();
output_config = st_ivas->hDecoderConfig->output_config;
- ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
move32();
+ nSamplesAskedLocal = add( nSamplesAsked, st_ivas->hTcBuffer->n_samples_discard );
+ move16();
- output_frame = extract_l( Mult_32_16( output_Fs, INV_FRAME_PER_SEC_Q15 ) ) /* output_Fs / FRAMES_PER_SEC */;
-
- /* set pointers to transport channels audio */
- FOR( n = 0; n < MAX_TRANSPORT_CHANNELS; n++ )
+ FOR( n = 0; n < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; n++ )
{
p_output_fx[n] = st_ivas->p_output_fx[n];
- IF( p_output_fx[n] != NULL )
+ }
+
+ IF( !st_ivas->hDecoderConfig->Opt_tsm )
+ {
+ FOR( n = 0; n < MAX_INTERN_CHANNELS; n++ )
{
- set32_fx( p_output_fx[n], 0, L_FRAME48k );
+ st_ivas->hTcBuffer->tc_fx[n] = st_ivas->p_output_fx[n];
}
}
+ FOR( n = 0; n < st_ivas->hTcBuffer->nchan_buffer_full; n++ )
+ {
+ p_tc_fx[n] = &st_ivas->hTcBuffer->tc_fx[n][st_ivas->hTcBuffer->n_samples_rendered];
+ }
+
/*----------------------------------------------------------------*
- * Decoding + pre-rendering
+ * Update combined orientation access index
*----------------------------------------------------------------*/
- test();
- IF( EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) )
-
+ IF( st_ivas->hCombinedOrientationData != NULL )
{
- st_ivas->hCPE[0]->element_brate = ivas_total_brate;
- move32();
- IF( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, 0 ) ) != IVAS_ERR_OK )
- {
- return error;
- }
+ /* take the discard samples into account here to make sure head rotation stays on the correct 5ms grid */
+ st_ivas->hCombinedOrientationData->cur_subframe_samples_rendered_start = sub( st_ivas->hCombinedOrientationData->cur_subframe_samples_rendered_start, st_ivas->hTcBuffer->n_samples_discard );
+ move16();
- /* HP filtering */
- FOR( n = 0; n < s_min( nchan_out, st_ivas->nchan_transport ); n++ )
- {
- hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs );
- }
+ ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData );
}
- ELSE IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) )
- {
- /* Metadata decoding and configuration */
- test();
- IF( EQ_32( ivas_total_brate, IVAS_SID_5k2 ) || EQ_32( ivas_total_brate, FRAME_NO_DATA ) )
- {
- ivas_ism_dtx_dec_fx( st_ivas, nb_bits_metadata );
- IF( ( error = ivas_sce_dec_fx( st_ivas, st_ivas->hISMDTX.sce_id_dtx, &p_output_fx[st_ivas->hISMDTX.sce_id_dtx], output_frame, nb_bits_metadata[st_ivas->hISMDTX.sce_id_dtx] ) ) != IVAS_ERR_OK )
- {
- return error;
- }
+ /*----------------------------------------------------------------*
+ * Rendering
+ *----------------------------------------------------------------*/
- ivas_ism_dtx_limit_noise_energy_for_near_silence_fx( st_ivas->hSCE, st_ivas->hISMDTX.sce_id_dtx, st_ivas->nchan_transport );
+ *nSamplesRendered = s_min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal );
+ move16();
- ivas_param_ism_dec_dequant_md_fx( st_ivas );
+ test();
+ test();
+ IF( EQ_32( st_ivas->ivas_format, UNDEFINED_FORMAT ) )
+ {
+ assert( 0 );
+ }
+ ELSE IF( EQ_32( st_ivas->hTcBuffer->tc_buffer_mode, TC_BUFFER_MODE_BUFFER ) )
+ {
+ ivas_dec_tc_buffer_playout_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, p_output_fx );
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, MONO_FORMAT ) || EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) )
+ {
+ /* Rendering */
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_MC ) )
+ {
+ ivas_ls_setup_conversion_fx( st_ivas, st_ivas->nchan_transport, *nSamplesRendered, p_tc_fx, p_output_fx );
}
- ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) )
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_NON_DIEGETIC_DOWNMIX ) )
{
- IF( NE_32( ( error = ivas_ism_metadata_dec_fx( ivas_total_brate, st_ivas->nchan_ism, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, st_ivas->hParamIsmDec->hParamIsm, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt, st_ivas->hSCE[0]->hCoreCoder[0] ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- ivas_param_ism_dec_dequant_md_fx( st_ivas );
+ ivas_apply_non_diegetic_panning_fx( p_tc_fx[0], p_output_fx, st_ivas->hDecoderConfig->non_diegetic_pan_gain_fx, *nSamplesRendered );
}
- ELSE /* ISM_MODE_DISC */
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) )
{
- IF( NE_32( ( error = ivas_ism_metadata_dec_fx( ivas_total_brate, st_ivas->nchan_ism, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, NULL, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt, st_ivas->hSCE[0]->hCoreCoder[0] ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
+ ivas_stereo2sba_fx( p_tc_fx, p_output_fx, *nSamplesRendered );
}
-
- FOR( n = 0; n < st_ivas->nchan_transport; n++ )
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) )
+ {
+ /* Rendering */
+ IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) )
{
- /* for DTX frames, dominant object has already been decoded before */
test();
test();
- IF( !( ( EQ_32( ivas_total_brate, IVAS_SID_5k2 ) || EQ_32( ivas_total_brate, FRAME_NO_DATA ) ) && EQ_16( n, st_ivas->hISMDTX.sce_id_dtx ) ) )
+ test();
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) || EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) )
+ {
+ ivas_dirac_dec_binaural_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, st_ivas->nchan_transport, p_output_fx );
+ }
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_PARAM_ISM ) || EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) )
{
- IF( NE_32( ( error = ivas_sce_dec_fx( st_ivas, n, &p_output_fx[n], output_frame, nb_bits_metadata[n] ) ), IVAS_ERR_OK ) )
+ ivas_param_ism_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx );
+
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) )
{
- return error;
+ /* Convert CICP19 -> Ambisonics */
+ ivas_mc2sba_fx( st_ivas->hIntSetup, p_output_fx, p_output_fx, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0 );
}
}
-
- /* HP filtering */
- hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs );
- }
-
- test();
- test();
- test();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) )
- {
- ivas_ism_mono_dmx_fx( st_ivas, p_output_fx, output_frame );
-
- Scale_sig32( p_output_fx[0], output_frame, Q11 - Q8 );
}
- ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) && ( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) || EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) ) )
+ ELSE /* ISM_MODE_DISC */
{
- /* loudness correction */
- ivas_dirac_dec_binaural_sba_gain_fx( p_output_fx, st_ivas->nchan_transport, output_frame ); /*returns Q-1*/
-
- FOR( i = 0; i < st_ivas->nchan_transport; i++ )
+ test();
+ test();
+ /* Loudspeaker or Ambisonics rendering */
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_TD_PANNING ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) )
{
- Scale_sig32( p_output_fx[i], output_frame, 1 ); // Q-1 -> Q
+ /* Convert to CICPxx; used also for ISM->CICP19->binaural_room rendering */
+ ivas_ism_render_sf_fx( st_ivas, st_ivas->renderer_type, p_output_fx, *nSamplesRendered );
}
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) || EQ_32( st_ivas->ivas_format, MASA_FORMAT ) )
- {
- set16_fx( nb_bits_metadata, 0, MAX_SCE );
-
- /* read parameters from the bitstream */
- test();
- IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) && st_ivas->hQMetaData != NULL )
- {
- // st = ( st_ivas->nSCE > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0];
- IF( st_ivas->nSCE > 0 )
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_NON_DIEGETIC_DOWNMIX ) )
{
- st = st_ivas->hSCE[0]->hCoreCoder[0];
+ ivas_apply_non_diegetic_panning_fx( p_tc_fx[0], p_output_fx, st_ivas->hDecoderConfig->non_diegetic_pan_gain_fx, *nSamplesRendered );
}
- ELSE
+#ifdef DEBUGGING
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) )
+#else
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) )
+#endif
{
- st = st_ivas->hCPE[0]->hCoreCoder[0];
+ /* Convert to Ambisonics */
+ FOR( i = 0; i < st_ivas->nchan_transport; i++ )
+ {
+ FOR( j = 0; j < HOA3_CHANNELS; j++ )
+ {
+ st_ivas->hIsmRendererData->gains_fx[i][j] = L_shr( st_ivas->hIsmRendererData->gains_fx[i][j], 1 ); // Q30 -> Q29
+ move32();
+ st_ivas->hIsmRendererData->prev_gains_fx[i][j] = L_shr( st_ivas->hIsmRendererData->prev_gains_fx[i][j], 1 ); // Q30 -> Q29
+ move32();
+ }
+ }
+
+ ivas_ism2sba_sf_fx( p_tc_fx, p_output_fx, st_ivas->hIsmRendererData, st_ivas->nchan_transport, *nSamplesRendered, st_ivas->hTcBuffer->n_samples_rendered, st_ivas->hIntSetup.ambisonics_order );
+
+ Word16 sba_num_chans = imult1616( add( st_ivas->hIntSetup.ambisonics_order, 1 ), add( st_ivas->hIntSetup.ambisonics_order, 1 ) );
+ FOR( j = 0; j < sba_num_chans; j++ )
+ {
+ scale_sig32( p_output_fx[j], *nSamplesRendered, sub( Q11, sub( add( output_q_factor, 29 ), 31 ) ) ); // Q11
+ }
+
+ FOR( i = 0; i < st_ivas->nchan_transport; i++ )
+ {
+ FOR( j = 0; j < 16; j++ )
+ {
+ st_ivas->hIsmRendererData->gains_fx[i][j] = L_shl( st_ivas->hIsmRendererData->gains_fx[i][j], 1 ); // Q29 -> Q30
+ move32();
+ st_ivas->hIsmRendererData->prev_gains_fx[i][j] = L_shl( st_ivas->hIsmRendererData->prev_gains_fx[i][j], 1 ); // Q29 -> Q30
+ move32();
+ }
+ }
}
- IF( NE_32( ( error = ivas_masa_decode_fx( st_ivas, st, &nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
+ /* Binaural rendering */
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) )
{
- return error;
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+ {
+ IF( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_output_fx, *nSamplesRendered ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ ELSE
+ {
+ IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_output_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
}
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) )
- {
- IF( NE_32( ( error = ivas_spar_dec_fx( st_ivas, nb_bits_metadata ) ), IVAS_ERR_OK ) )
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) )
{
- return error;
+ st_ivas->hCrendWrapper->p_io_qfactor = &st_ivas->hCrendWrapper->io_qfactor;
+ subframe_len = imult1616( st_ivas->hTcBuffer->subframe_nbslots[0], st_ivas->hTcBuffer->n_samples_granularity );
+ gd_bits = find_guarded_bits_fx( subframe_len );
+ exp = 13;
+ move16();
+ nchan_in = 12;
+ move16();
+ nchan_out = 2;
+ move16();
+ exp = sub( exp, gd_bits );
+ *st_ivas->hCrendWrapper->p_io_qfactor = exp;
+ move16();
+ FOR( i = 0; i < nchan_in; i++ )
+ {
+ scale_sig32( p_output_fx[i], *nSamplesRendered, negate( sub( 11, *st_ivas->hCrendWrapper->p_io_qfactor ) ) ); // Q11
+ }
+
+ IF( NE_32( ( error = ivas_rend_crendProcessSubframe_fx( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, NULL, NULL, st_ivas->hTcBuffer, p_output_fx, p_output_fx, *nSamplesRendered, output_Fs, 0 ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ FOR( i = 0; i < nchan_out; i++ )
+ {
+ scale_sig32( p_output_fx[i], *nSamplesRendered, sub( 11, *st_ivas->hCrendWrapper->p_io_qfactor ) ); // Q11
+ }
}
}
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) || EQ_32( st_ivas->ivas_format, MASA_FORMAT ) )
+ {
+ nchan_remapped = nchan_transport_rend;
+ move16();
test();
- IF( EQ_16( st_ivas->nchan_transport, CPE_CHANNELS ) && GE_16( st_ivas->nCPE, 1 ) )
- {
- st_ivas->hCPE[0]->brate_surplus = 0;
- move32();
- st_ivas->hCPE[0]->element_brate = ivas_total_brate;
- move32();
- }
-
- /* core-decoding of transport channels */
- IF( EQ_16( st_ivas->nSCE, 1 ) )
+ test();
+ /* Loudspeakers, Ambisonics or Binaural rendering */
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) || EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) )
{
- IF( NE_32( ( error = ivas_sce_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
+ ivas_dirac_dec_binaural_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output_fx );
}
- ELSE IF( EQ_16( st_ivas->nCPE, 1 ) )
+ ELSE IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) )
{
- IF( NE_32( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) )
{
- return error;
+ ivas_dirac_dec_render_fx( st_ivas, nchan_remapped, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx );
}
}
- ELSE IF( GT_16( st_ivas->nCPE, 1 ) )
+ ELSE
{
- IF( NE_32( ( error = ivas_mct_dec_fx( st_ivas, p_output_fx, output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
+ IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) )
{
return error;
}
}
-
- /* TCs remapping */
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
+ {
nchan_remapped = st_ivas->nchan_transport;
move16();
-
test();
test();
test();
- test();
- test();
- IF( st_ivas->sba_dirac_stereo_flag )
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) || EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) )
{
- nchan_remapped = nchan_out;
- move16();
-
- IF( EQ_16( st_ivas->ivas_format, SBA_FORMAT ) )
+ test();
+ IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) )
{
- FOR( i = 0; i < st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport; i++ )
- {
- Scale_sig32( p_output_fx[i], output_frame, Q14 - Q11 ); // Q14
- }
- SPAR_DEC_HANDLE hSpar = st_ivas->hSpar;
- Word16 nchan_transport;
- nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport;
- move16();
- nchan_out = nchan_transport;
- move16();
-
- ivas_agc_dec_process_fx( st_ivas->hSpar->hAgcDec, ( p_output_fx ), ( p_output_fx ), st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, output_frame );
-
- IF( st_ivas->hSpar->hPCA != NULL )
+ IF( NE_32( ( error = ivas_omasa_dirac_td_binaural_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output_fx ) ), IVAS_ERR_OK ) )
{
- ivas_pca_dec_fx( st_ivas->hSpar->hPCA, output_frame, st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, ivas_total_brate, st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, p_output_fx );
+ return error;
}
-
- ivas_spar_dec_gen_umx_mat_fx( st_ivas->hSpar->hMdDec, st_ivas->nchan_transport, IVAS_MAX_NUM_BANDS, st_ivas->bfi, ivas_get_spar_dec_md_num_subframes( st_ivas->sba_order, ivas_total_brate, st_ivas->last_active_ivas_total_brate ) );
}
-
- ivas_sba_dirac_stereo_dec_fx( st_ivas, p_output_fx, output_frame );
+ ELSE
+ {
+ ivas_dirac_dec_binaural_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output_fx );
+ }
}
- ELSE IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) && LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) && ( GT_32( ivas_total_brate, IVAS_SID_5k2 ) || ( LE_32( ivas_total_brate, IVAS_SID_5k2 ) && st_ivas->nCPE > 0 && EQ_16( st_ivas->hCPE[0]->nchan_out, 1 ) ) ) )
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) )
{
- nchan_remapped = 1; /* Only one channel transported */
- move16();
+ ivas_omasa_dirac_rend_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output_fx );
}
-
- /* HP filtering */
- FOR( n = 0; n < nchan_remapped; n++ )
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_OMASA_OBJECT_EXT ) || EQ_32( st_ivas->renderer_type, RENDERER_OMASA_MIX_EXT ) )
{
- hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs );
+ ivas_dec_tc_buffer_playout_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, p_output_fx );
+ ivas_omasa_rearrange_channels_fx( p_output_fx, st_ivas->nchan_ism, *nSamplesRendered );
}
+ }
+ ELSE IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
+ {
+ nchan_remapped = nchan_transport_rend;
+ move16();
- IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) )
+ /* Loudspeakers, Ambisonics or Binaural rendering */
+ IF( EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
{
- nchan_remapped = ivas_sba_remapTCs_fx( p_output_fx, st_ivas, output_frame );
-
test();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
+ test();
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) )
{
- num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( st_ivas->sba_analysis_order, ivas_total_brate, st_ivas->last_active_ivas_total_brate );
-
- SPAR_DEC_HANDLE hSpar = st_ivas->hSpar;
- Word16 Q_p_output = MAX_16, temp_min;
+ SPAR_DEC_HANDLE hSpar;
+ hSpar = st_ivas->hSpar;
+ hSpar->hMdDec->Q_mixer_mat = 30;
move16();
- Word16 nchan_transport;
- nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport;
- move16();
- nchan_out = nchan_transport;
- move16();
- FOR( ch = 0; ch < nchan_transport; ch++ )
+ IF( NE_32( ( error = ivas_osba_dirac_td_binaural_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) )
{
- temp_min = L_norm_arr( p_output_fx[ch], output_frame );
- Q_p_output = s_min( Q_p_output, temp_min );
+ return error;
}
- Q_p_output = sub( Q_p_output, 2 );
- if ( GT_16( Q_p_output, 20 ) )
+ }
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_OSBA_STEREO ) )
+ {
+ test();
+ /* shift SBA channels to avoid overwrite by ISM upmix in 1 object case and non-TSM unified channel memory*/
+ IF( EQ_16( st_ivas->nchan_ism, 1 ) && EQ_16( st_ivas->hDecoderConfig->Opt_tsm, 0 ) )
{
- Q_p_output = 20;
- move16();
+ Copy32( p_tc_fx[2], p_output_fx[3], *nSamplesRendered );
+ Copy32( p_tc_fx[1], p_output_fx[2], *nSamplesRendered );
+ p_tc_fx[1] = p_output_fx[2];
+ p_tc_fx[2] = p_output_fx[3];
+ }
+
+ /* render objects */
+ ivas_ism_render_sf_fx( st_ivas, st_ivas->renderer_type, p_output_fx, *nSamplesRendered );
+
+ /* add already rendered SBA part */
+ ivas_osba_stereo_add_channels_fx( p_tc_fx, p_output_fx, st_ivas->hSbaIsmData->gain_bed_fx, nchan_out, st_ivas->nchan_ism, st_ivas->ism_mode, *nSamplesRendered );
+ }
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_OSBA_AMBI ) || EQ_32( st_ivas->renderer_type, RENDERER_OSBA_LS ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
+ {
+ IF( NE_32( ( error = ivas_osba_render_sf_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) )
+ {
+ return error;
}
- FOR( ch = 0; ch < nchan_transport; ch++ )
+ }
+ ELSE IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) /*EXT output = individual objects + HOA3*/
+ {
+ IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, &p_output_fx[st_ivas->nchan_ism] ) ), IVAS_ERR_OK ) )
{
- Scale_sig32( p_output_fx[ch], output_frame, Q_p_output ); // Q(11+Q_p_output)
+ return error;
}
- ivas_sba_mix_matrix_determiner_fx( st_ivas->hSpar, p_output_fx, st_ivas->bfi, nchan_remapped, output_frame, num_md_sub_frames, Q_p_output );
- FOR( Word16 c = 0; c < nchan_transport; c++ )
+ FOR( n = 0; n < st_ivas->nchan_ism; n++ )
{
- Scale_sig32( p_output_fx[c], output_frame, 11 ); // Q11
+ Copy32( p_tc_fx[n], p_output_fx[n], *nSamplesRendered );
}
}
- ELSE IF( NE_32( st_ivas->renderer_type, RENDERER_DISABLE ) )
+ ELSE
{
- Word16 size = st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport;
- move16();
- if ( EQ_16( st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, 3 ) )
- size = add( size, 1 );
-
- FOR( i = 0; i < size; i++ )
+ IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) )
{
- Scale_sig32( p_output_fx[i], output_frame, Q14 - Q11 ); // Q14
+ return error;
}
-
- ivas_spar_dec_agc_pca_fx( st_ivas, p_output_fx, output_frame );
}
}
-
- test();
- test();
- IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) )
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
{
- Word16 q_shift = 0;
- move16();
-
- ivas_masa_prerender_fx( st_ivas, p_output_fx, &q_shift, output_frame, nchan_remapped );
+ ivas_dirac_dec_binaural_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output_fx );
- FOR( i = 0; i < CPE_CHANNELS; i++ )
+ FOR( n = 0; n < st_ivas->hDecoderConfig->nchan_out; n++ )
+ {
+ scale_sig32( p_output_fx[n], *nSamplesRendered, 1 );
+ }
+ }
+ ELSE
+ {
+ IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) )
{
- Scale_sig32( p_output_fx[i], output_frame, negate( q_shift ) );
+ return error;
}
- test();
- /* external output */
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) && EQ_32( st_ivas->hMasa->config.input_ivas_format, MASA_ISM_FORMAT ) )
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
{
+ FOR( n = st_ivas->hIntSetup.nchan_out_woLFE - 1; n >= 0; n-- )
+ {
+ Copy32( p_output_fx[n], p_output_fx[n + st_ivas->nchan_ism], *nSamplesRendered );
+ }
FOR( n = 0; n < st_ivas->nchan_ism; n++ )
{
- set_zero_fx( p_output_fx[add( st_ivas->nchan_transport, n )], output_frame );
+ set32_fx( p_output_fx[n], 0, *nSamplesRendered );
}
-
- ivas_omasa_rearrange_channels_fx( p_output_fx, st_ivas->nchan_ism, output_frame );
}
- }
- ELSE IF( EQ_16( st_ivas->ivas_format, SBA_FORMAT ) && ( EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_16( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) )
- {
- /* loudness correction */
- ivas_dirac_dec_binaural_sba_gain_fx( p_output_fx, nchan_remapped, output_frame );
-
- FOR( i = 0; i < st_ivas->nchan_transport; i++ )
+ FOR( n = 0; n < st_ivas->hDecoderConfig->nchan_out; n++ )
{
- Scale_sig32( p_output_fx[i], output_frame, 1 ); // Q-1 -> Q
+ scale_sig32( p_output_fx[n], *nSamplesRendered, 1 );
}
}
}
- ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
+ ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) )
{
- Word16 nchan_ism, nchan_transport_ism;
- Word16 dirac_bs_md_write_idx;
-
- set16_fx( nb_bits_metadata, 0, MAX_SCE + 1 );
-
- /* Set the number of objects for the parametric rendering */
- dirac_bs_md_write_idx = 0;
- move16();
- IF( st_ivas->hSpatParamRendCom != NULL )
+ IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCT ) )
{
- st_ivas->hSpatParamRendCom->numIsmDirections = 0;
+ Word16 crendInPlaceRotation = FALSE;
move16();
+
test();
- if ( NE_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && NE_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
+ test();
+ test();
+ IF( NE_32( st_ivas->transport_config, st_ivas->intern_config ) && ( EQ_32( st_ivas->intern_config, IVAS_AUDIO_CONFIG_FOA ) || EQ_32( st_ivas->intern_config, IVAS_AUDIO_CONFIG_HOA2 ) || EQ_32( st_ivas->intern_config, IVAS_AUDIO_CONFIG_HOA3 ) ) )
{
- st_ivas->hSpatParamRendCom->numIsmDirections = st_ivas->nchan_ism;
- move16();
- }
+ IF( LT_16( add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ), add( st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hIntSetup.num_lfe ) ) )
+ {
+ crendInPlaceRotation = TRUE;
+ move16();
- dirac_bs_md_write_idx = st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx; /* Store the write-index for this frame */
- move16();
- }
+ ivas_mc2sba_fx( st_ivas->hTransSetup, p_tc_fx, p_output_fx, *nSamplesRendered, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE_FX );
+ }
+ }
- /* MASA metadata decoding */
- IF( NE_32( ( error = ivas_masa_decode_fx( st_ivas, st_ivas->hCPE[0]->hCoreCoder[0], &nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- /* Configuration of combined-format bit-budget distribution */
- ivas_set_surplus_brate_dec( st_ivas, &ism_total_brate );
-
- st_ivas->hCPE[0]->hCoreCoder[0]->bit_stream = &( st_ivas->bit_stream[( ism_total_brate / FRAMES_PER_SEC )] );
-
- IF( NE_32( ( error = ivas_omasa_ism_metadata_dec_fx( st_ivas, ism_total_brate, &nchan_ism, &nchan_transport_ism, dirac_bs_md_write_idx, &nb_bits_metadata[1] ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- FOR( n = 0; n < nchan_transport_ism; n++ )
- {
- IF( NE_32( ( error = ivas_sce_dec_fx( st_ivas, n, &p_output_fx[st_ivas->nchan_transport + n], output_frame, nb_bits_metadata[1] ) ), IVAS_ERR_OK ) )
+ /* Rendering */
+ test();
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) )
{
- return error;
- }
- }
+ st_ivas->hCrendWrapper->p_io_qfactor = &st_ivas->hCrendWrapper->io_qfactor;
+ subframe_len = imult1616( st_ivas->hTcBuffer->subframe_nbslots[0], st_ivas->hTcBuffer->n_samples_granularity );
+ gd_bits = find_guarded_bits_fx( subframe_len );
+ exp = 13;
+ move16();
+ IF( NE_32( ( error = getAudioConfigNumChannels( st_ivas->intern_config, &nchan_in ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ IF( NE_32( ( error = getAudioConfigNumChannels( st_ivas->hOutSetup.output_config, &nchan_out ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ exp = sub( exp, gd_bits );
+ *st_ivas->hCrendWrapper->p_io_qfactor = exp;
+ move16();
- /* decode MASA channels */
- IF( NE_32( ( error = ivas_cpe_dec_fx( st_ivas, 0, p_output_fx, output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
+ IF( crendInPlaceRotation )
+ {
+ FOR( i = 0; i < nchan_in; i++ )
+ {
+ scale_sig32( p_output_fx[i], *nSamplesRendered, negate( sub( Q11, *st_ivas->hCrendWrapper->p_io_qfactor ) ) ); // Q = *st_ivas->hCrendWrapper->p_io_qfactor
+ }
+ }
+ ELSE
+ {
+ FOR( i = 0; i < nchan_in; i++ )
+ {
+ scale_sig32( p_tc_fx[i], *nSamplesRendered, negate( sub( Q11, *st_ivas->hCrendWrapper->p_io_qfactor ) ) ); // Q = *st_ivas->hCrendWrapper->p_io_qfactor
+ }
+ }
- IF( EQ_16( st_ivas->hCPE[0]->nchan_out, 1 ) )
- {
- Copy32( p_output_fx[0], p_output_fx[1], output_frame ); /* Copy mono signal to stereo output channels */
- }
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+ {
+ IF( ( error = ivas_rend_crendProcessSubframesSplitBin( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData,
+ &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, p_output_fx, p_output_fx, *nSamplesRendered, output_Fs ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ ELSE
+ {
+ IF( NE_32( ( error = ivas_rend_crendProcessSubframe_fx( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData,
+ &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, p_output_fx, p_output_fx, *nSamplesRendered, output_Fs, 0 ) ),
+ IVAS_ERR_OK ) )
+ {
+ return error;
+ }
- FOR( n = 0; n < getNumChanSynthesis( st_ivas ); n++ )
- {
- hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs );
- }
+ ivas_binaural_add_LFE_fx( st_ivas, *nSamplesRendered, p_tc_fx, p_output_fx );
+ }
- Word16 output_q = Q11;
- move16();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) )
- {
- ivas_ism_mono_dmx_fx( st_ivas, p_output_fx, output_frame );
+ IF( crendInPlaceRotation )
+ {
+ n = nchan_in;
+ }
+ ELSE
+ {
+ n = nchan_out;
+ }
+ move16();
- output_q = Q8;
- move16();
- }
- ELSE IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
- {
- IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
- {
- ivas_omasa_rearrange_channels_fx( p_output_fx, nchan_transport_ism, output_frame );
+ FOR( i = 0; i < n; i++ )
+ {
+ scale_sig32( p_output_fx[i], *nSamplesRendered, sub( Q11, *st_ivas->hCrendWrapper->p_io_qfactor ) ); // Q11
+ }
+
+ FOR( i = n; i < nchan_in; i++ )
+ {
+ scale_sig32( p_tc_fx[i], *nSamplesRendered, sub( Q11, *st_ivas->hCrendWrapper->p_io_qfactor ) ); // Q11
+ }
}
- ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_MC ) )
{
- /* Convert separate object to MASA, combine with the original MASA, and output combined MASA + empty objects. */
- ivas_omasa_combine_separate_ism_with_masa_fx( st_ivas, p_output_fx, &output_q, st_ivas->nchan_ism, output_frame );
+ ivas_ls_setup_conversion_fx( st_ivas, st_ivas->nchan_transport, *nSamplesRendered, p_tc_fx, p_output_fx );
}
- ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) )
{
- /* Extract objects from MASA, output MASA + all objects (i.e., extracted and separated objects) */
- ivas_omasa_render_objects_from_mix_fx( st_ivas, p_output_fx, st_ivas->nchan_ism, output_frame, &output_q );
+ ivas_mc2sba_fx( st_ivas->hIntSetup, p_tc_fx, p_output_fx, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0 );
}
- }
-
- IF( NE_16( output_q, Q11 ) )
- {
- FOR( n = 0; n < s_max( getNumChanSynthesis( st_ivas ), nchan_transport_ism + st_ivas->nchan_transport ); n++ )
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) )
{
- Scale_sig32( p_output_fx[n], output_frame, sub( Q11, output_q ) ); // Q11
- }
- st_ivas->hCPE[0]->q_output_mem_fx[0] = output_q;
- st_ivas->hCPE[0]->q_output_mem_fx[1] = output_q;
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
- {
- Word16 nchan_ism, sba_ch_idx;
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+ {
+ IF( NE_32( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_output_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ else
+ {
+ IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_output_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
- set16_fx( nb_bits_metadata, 0, MAX_SCE + 1 );
- nchan_ism = st_ivas->nchan_ism;
- move16();
- IF( EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
- {
- /* set ISM parameters and decode ISM metadata in OSBA format */
- IF( NE_32( ( error = ivas_osba_ism_metadata_dec_fx( st_ivas, ivas_total_brate, &nchan_ism, &nb_bits_metadata[1] ) ), IVAS_ERR_OK ) )
- {
- return error;
+ ivas_binaural_add_LFE_fx( st_ivas, *nSamplesRendered, p_tc_fx, p_output_fx );
+ }
}
- sba_ch_idx = st_ivas->nchan_ism;
- move16();
- }
- ELSE
- {
- nb_bits_metadata[1] = add( nb_bits_metadata[1], NO_BITS_MASA_ISM_NO_OBJ );
- sba_ch_idx = 0;
- move16();
- move16();
- }
-
- /* SBA metadata decoding */
- IF( NE_32( ( error = ivas_spar_dec_fx( st_ivas, nb_bits_metadata ) ), IVAS_ERR_OK ) )
- {
- return error;
}
-
- test();
- IF( EQ_16( st_ivas->nchan_transport, CPE_CHANNELS ) && GE_16( st_ivas->nCPE, 1 ) )
+ ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) )
{
- st_ivas->hCPE[0]->element_brate = ivas_total_brate;
- move32();
- }
+ ivas_mc_paramupmix_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_tc_fx, p_output_fx );
- /* core-decoding of transport channels */
- IF( EQ_16( st_ivas->nSCE, 1 ) )
- {
- IF( NE_32( ( error = ivas_sce_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ), IVAS_ERR_OK ) )
+ /* Rendering */
+ test();
+ test();
+ IF( ( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) && !st_ivas->hDecoderConfig->Opt_Headrotation )
{
- return error;
+ /* handled in CLDFB domain already */
+ IF( NE_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && NE_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+ {
+ ivas_binaural_add_LFE_fx( st_ivas, *nSamplesRendered, p_output_fx, p_output_fx );
+ }
}
- }
- ELSE IF( EQ_16( st_ivas->nCPE, 1 ) )
- {
- IF( NE_32( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, add( nb_bits_metadata[0], nb_bits_metadata[1] ) ) ), IVAS_ERR_OK ) )
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_MC ) )
{
- return error;
+ ivas_ls_setup_conversion_fx( st_ivas, MC_PARAMUPMIX_MAX_INPUT_CHANS, *nSamplesRendered, p_output_fx, p_output_fx );
}
- }
- ELSE IF( GT_16( st_ivas->nCPE, 1 ) )
- {
- IF( NE_32( ( error = ivas_mct_dec_fx( st_ivas, p_output_fx, output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ), IVAS_ERR_OK ) )
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) )
{
- return error;
+ ivas_mc2sba_fx( st_ivas->hIntSetup, p_output_fx, p_output_fx, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0 );
}
}
-
- IF( st_ivas->sba_dirac_stereo_flag )
+ ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) )
{
- FOR( i = 0; i < st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport; i++ )
- {
- Scale_sig32( p_output_fx[i + sba_ch_idx], output_frame, Q14 - Q11 ); // Q14
- }
- SPAR_DEC_HANDLE hSpar = st_ivas->hSpar;
- Word16 nchan_transport;
- nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport;
- move16();
- nchan_out = nchan_transport;
+ Word16 channel_active_fx[MAX_OUTPUT_CHANNELS];
+ Word16 nchan_out_cov;
+ Word16 nchan_out_cldfb = 0;
move16();
- ivas_agc_dec_process_fx( st_ivas->hSpar->hAgcDec, ( p_output_fx + sba_ch_idx ), ( p_output_fx + sba_ch_idx ), st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, output_frame );
- IF( st_ivas->hSpar->hPCA != NULL )
+ set16_fx( channel_active_fx, 0, MAX_LS_CHANNELS );
+ Word16 nchan_transport_tmp = st_ivas->nchan_transport;
+ move16();
+ output_Fs = st_ivas->hDecoderConfig->output_Fs;
+ move32();
+ Word16 nchan_out_transport = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe );
+ test();
+ test();
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
{
- ivas_pca_dec_fx( st_ivas->hSpar->hPCA, output_frame, st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, &p_output_fx[sba_ch_idx] );
+ nchan_out_cldfb = BINAURAL_CHANNELS;
+ move16();
+ set16_fx( channel_active_fx, 1, BINAURAL_CHANNELS );
+ nchan_out_cov = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe );
}
-
- ivas_spar_dec_gen_umx_mat_fx( st_ivas->hSpar->hMdDec, st_ivas->nchan_transport, IVAS_MAX_NUM_BANDS, st_ivas->bfi, ivas_get_spar_dec_md_num_subframes( st_ivas->sba_order, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate ) );
-
- ivas_sba_dirac_stereo_dec_fx( st_ivas, &p_output_fx[sba_ch_idx], output_frame );
- }
-
- /* HP filtering */
- FOR( n = 0; n < getNumChanSynthesis( st_ivas ); n++ )
- {
- hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs );
- }
-
- nchan_remapped = ivas_sba_remapTCs_fx( &p_output_fx[sba_ch_idx], st_ivas, output_frame );
-
- test();
- test();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
- {
- num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate );
- SPAR_DEC_HANDLE hSpar = st_ivas->hSpar;
- Word16 nchan_transport;
- // num_bands_out = hSpar->hFbMixer->pFb->filterbank_num_bands;
- nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport;
- move16();
- nchan_out = nchan_transport;
- move16();
- Word16 Q_p_output;
- Word16 min_norm = 31;
- move16();
-
- FOR( ch = 0; ch < nchan_transport; ++ch )
+ ELSE IF( EQ_32( st_ivas->hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_CLDFB ) )
{
- Word16 norm = L_norm_arr( p_output_fx[sba_ch_idx + ch], output_frame ); // Normalize per channel
- min_norm = s_min( norm, min_norm );
+ nchan_out_cov = nchan_out_transport;
+ move16();
+ nchan_out_cldfb = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe );
}
-
- Q_p_output = s_max( 3, sub( min_norm, 1 ) );
-
- Q_p_output = s_min( Q_p_output, 19 ); // to restrict Q-factor of p_ouptut to Q30
- FOR( ch = 0; ch < nchan_transport; ch++ )
+ ELSE IF( EQ_32( st_ivas->hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_32( st_ivas->hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) )
{
- Scale_sig32( p_output_fx[sba_ch_idx + ch], output_frame, Q_p_output ); // Q_p_output + Q11
+ nchan_out_cov = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe );
+ nchan_out_cldfb = nchan_out_cov;
+ move16();
+ set16_fx( channel_active_fx, 1, nchan_out_cov );
}
- Q_p_output = add( Q11, Q_p_output );
- hSpar->hMdDec->Q_mixer_mat = 31;
- move16();
-
- ivas_sba_mix_matrix_determiner_fx( st_ivas->hSpar, &p_output_fx[sba_ch_idx], st_ivas->bfi, nchan_remapped, output_frame, num_md_sub_frames, sub( Q_p_output, Q11 ) );
- FOR( Word16 c = 0; c < nchan_transport; c++ )
+ ELSE
{
- Scale_sig32( p_output_fx[sba_ch_idx + c], output_frame, Q11 ); // Q11
+ nchan_out_cov = nchan_out_transport;
+ move16();
+ nchan_out_cldfb = nchan_out_transport;
+ move16();
+ set16_fx( channel_active_fx, 1, nchan_out_cov );
}
- }
- ELSE IF( NE_32( st_ivas->renderer_type, RENDERER_DISABLE ) && st_ivas->sba_dirac_stereo_flag == 0 )
- {
- Word16 size = add( st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, sba_ch_idx );
- if ( EQ_16( size, 3 ) )
+ IF( st_ivas->hParamMC->max_band_decorr > 0 )
{
- size = add( size, 1 );
+ Word16 tmp;
+ tmp = L_norm_arr( st_ivas->hParamMC->h_freq_domain_decorr_ap_state->decorr_buffer_fx, st_ivas->hParamMC->h_freq_domain_decorr_ap_state->decorr_buffer_len );
+ scale_sig32( st_ivas->hParamMC->h_freq_domain_decorr_ap_state->decorr_buffer_fx, st_ivas->hParamMC->h_freq_domain_decorr_ap_state->decorr_buffer_len, tmp ); // Q(st_ivas->hParamMC->h_freq_domain_decorr_ap_state->q_decorr_buffer+ tmp)
+ st_ivas->hParamMC->h_freq_domain_decorr_ap_state->q_decorr_buffer = add( st_ivas->hParamMC->h_freq_domain_decorr_ap_state->q_decorr_buffer, tmp );
+ move16();
}
-
- FOR( i = sba_ch_idx; i < size; i++ )
+ /* CLDFB synthesis */
+ FOR( ch = 0; ch < nchan_out_cldfb; ch++ )
{
- Scale_sig32( p_output_fx[i], output_frame, ( Q14 - Q11 ) ); // Q14
+ IF( st_ivas->cldfbSynDec[ch] )
+ {
+ scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, ( Q5 - Q11 ) ); // Q5
+ st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q5;
+ move16();
+ }
}
-
- ivas_spar_dec_agc_pca_fx( st_ivas, &p_output_fx[sba_ch_idx], output_frame );
- }
-
- test();
- test();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
- {
- /* loudness correction */
- ivas_dirac_dec_binaural_sba_gain_fx( &p_output_fx[sba_ch_idx], nchan_remapped, output_frame ); /*returns Q-1*/
-
- FOR( i = 0; i < nchan_remapped; i++ )
+ Word16 tempp;
+ FOR( Word16 param_band_idx = 0; param_band_idx < st_ivas->hParamMC->num_param_bands_synth; param_band_idx++ )
{
- Scale_sig32( p_output_fx[i], output_frame, 1 ); // Q-1 -> Q
+ tempp = getScaleFactor32( st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx[param_band_idx], st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_len );
+ scale_sig32( st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx[param_band_idx], st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_len, tempp ); // Q(31-(st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp[param_band_idx]- tempp))
+ st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp[param_band_idx] = sub( st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp[param_band_idx], tempp );
+ move16();
+
+ IF( LT_16( st_ivas->hParamMC->band_grouping[param_band_idx], st_ivas->hParamMC->h_output_synthesis_params.max_band_decorr ) )
+ {
+ tempp = getScaleFactor32( st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx[param_band_idx], st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_len );
+ scale_sig32( st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx[param_band_idx], st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_len, tempp ); // Q(31- (st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp[param_band_idx] - tempp))
+ st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp[param_band_idx] = sub( st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp[param_band_idx], tempp );
+ move16();
+ }
}
- }
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
- {
- ivas_ism_mono_dmx_fx( st_ivas, p_output_fx, output_frame );
- Scale_sig32( p_output_fx[0], output_frame, Q11 - Q8 ); // Q11
+ ivas_param_mc_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx, channel_active_fx );
- /* add W */
- FOR( n = 0; n < nchan_out; n++ )
- {
- v_add_32( p_output_fx[n], p_output_fx[n + s_max( nchan_out, nchan_ism )], p_output_fx[n], output_frame );
- }
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) )
- {
- IF( st_ivas->nSCE > 0 )
- {
- st = st_ivas->hSCE[0]->hCoreCoder[0];
- }
- ELSE
- {
- st = st_ivas->hCPE[0]->hCoreCoder[0];
- }
-
- IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCT ) )
- {
- /* LFE channel decoder */
- ivas_lfe_dec_fx( st_ivas->hLFE, st, output_frame, st_ivas->bfi, p_output_fx[LFE_CHANNEL] );
-
- Scale_sig32( p_output_fx[LFE_CHANNEL], output_frame, Q11 - Q9 ); // Q11
-
- IF( NE_32( ( error = ivas_mct_dec_fx( st_ivas, p_output_fx, output_frame, 0 ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- /* HP filtering */
- FOR( n = 0; n < st_ivas->nchan_transport; n++ )
- {
- IF( NE_16( n, LFE_CHANNEL ) )
- {
- hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs );
- }
- }
-
- test();
- test();
- test();
- IF( NE_32( st_ivas->transport_config, st_ivas->intern_config ) && ( NE_32( st_ivas->intern_config, IVAS_AUDIO_CONFIG_FOA ) || NE_32( st_ivas->intern_config, IVAS_AUDIO_CONFIG_HOA2 ) || NE_32( st_ivas->intern_config, IVAS_AUDIO_CONFIG_HOA3 ) ) )
+ FOR( ch = 0; ch < nchan_out_cldfb; ch++ )
{
- IF( GE_16( add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ), add( st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hIntSetup.num_lfe ) ) )
+ IF( st_ivas->cldfbSynDec[ch] )
{
- ivas_mc2sba_fx( st_ivas->hTransSetup, p_output_fx, p_output_fx, output_frame, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE_FX );
+ scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, Q11 - Q5 ); // Q11
+ st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11;
+ move16();
}
}
-
- test();
- test();
- IF( ( EQ_32( st_ivas->renderer_type, RENDERER_MC ) || EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) && GE_16( add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ), add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ) ) )
+ IF( EQ_16( st_ivas->hParamMC->slots_rendered, st_ivas->hParamMC->num_slots ) )
{
- IF( EQ_32( st_ivas->renderer_type, RENDERER_MC ) )
+ FOR( Word16 param_band_idx = 0; param_band_idx < st_ivas->hParamMC->hMetadataPMC->nbands_coded; param_band_idx++ )
{
- s = Q16 - Q11;
- move16();
- s = sub( s, find_guarded_bits_fx( st_ivas->nchan_transport ) );
- FOR( i = 0; i < s_max( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_transport ); ++i )
- {
- Scale_sig32( p_output_fx[i], output_frame, s ); // Q(11+s)
- }
- ivas_ls_setup_conversion_fx( st_ivas, st_ivas->nchan_transport, output_frame, p_output_fx, p_output_fx );
- FOR( i = 0; i < s_max( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_transport ); ++i )
+ IF( LT_16( st_ivas->hParamMC->band_grouping[param_band_idx], st_ivas->hParamMC->h_output_synthesis_params.max_band_decorr ) )
{
- Scale_sig32( p_output_fx[i], output_frame, negate( s ) ); // Q11
+ Copy32( st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx[param_band_idx], st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_fx[param_band_idx], imult1616( nchan_transport_tmp, nchan_out_cov ) );
+ st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_exp[param_band_idx] = st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp[param_band_idx];
+ move16();
}
- }
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) )
- {
- ivas_mc2sba_fx( st_ivas->hIntSetup, p_output_fx, p_output_fx, output_frame, st_ivas->hOutSetup.ambisonics_order, 0 );
+ Copy32( st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx[param_band_idx], st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_old_fx[param_band_idx], imult1616( nchan_transport_tmp, nchan_out_cov ) );
+ st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_old_exp[param_band_idx] = st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp[param_band_idx];
+ move16();
}
}
}
- ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) )
+ ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) )
{
- /* LFE channel decoder */
- ivas_lfe_dec_fx( st_ivas->hLFE, st, output_frame, st_ivas->bfi, p_output_fx[LFE_CHANNEL] );
-
- Scale_sig32( p_output_fx[LFE_CHANNEL], output_frame, Q11 - Q9 ); // Q11
-
- ivas_mc_paramupmix_dec_read_BS( st_ivas, st, st_ivas->hMCParamUpmix, &nb_bits_metadata[0] );
-
- IF( NE_32( ( error = ivas_mct_dec_fx( st_ivas, p_output_fx, output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- /* HP filtering */
- FOR( n = 0; n < st_ivas->nchan_transport; n++ )
- {
- IF( NE_16( n, LFE_CHANNEL ) )
- {
- hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs );
- }
- }
+ nchan_remapped = st_ivas->nchan_transport;
+ move16();
- /* Rendering */
test();
test();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_MC ) && ( EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) ) )
+ test();
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) || EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) )
{
- /* Compensate loudness for not doing full upmix */
- FOR( n = 4; n < 8; n++ )
- {
- Scale_sig32( p_output_fx[n], output_frame, 1 );
- }
+ ivas_dirac_dec_binaural_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output_fx );
+ }
+ ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) || EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) /* rendering to CICPxx and Ambisonics */
+ {
+ ivas_dirac_dec_render_fx( st_ivas, nchan_remapped, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx );
test();
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) )
+ test();
+ test();
+ IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) )
{
- s = Q16 - Q11;
- move16();
- Word16 nchan_transport;
- nchan_transport = audioCfg2channels( IVAS_AUDIO_CONFIG_5_1_2 );
- s = sub( s, find_guarded_bits_fx( nchan_transport ) );
- FOR( i = 0; i < s_max( st_ivas->hDecoderConfig->nchan_out, nchan_transport ); ++i )
- {
- Scale_sig32( p_output_fx[i], output_frame, s );
- }
-
- ivas_ls_setup_conversion_fx( st_ivas, nchan_transport, output_frame, p_output_fx, p_output_fx );
-
- FOR( i = 0; i < s_max( st_ivas->hDecoderConfig->nchan_out, nchan_transport ); ++i )
+ /* we still need to copy the separate channel if available */
+ IF( st_ivas->hOutSetup.separateChannelEnabled )
{
- Scale_sig32( p_output_fx[i], output_frame, negate( s ) );
+ Copy32( p_tc_fx[LFE_CHANNEL - 1], p_output_fx[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered );
}
- }
- }
- }
- ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) )
- {
- /* read Parametric MC parameters from the bitstream */
- ivas_param_mc_dec_read_BS_fx( ivas_total_brate, st, st_ivas->hParamMC, &nb_bits_metadata[0] );
- IF( EQ_16( st_ivas->nCPE, 1 ) )
- {
- IF( NE_32( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
- {
- return error;
+ ivas_mc2sba_fx( st_ivas->hIntSetup, p_output_fx, p_output_fx, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0 );
}
- }
- ELSE IF( GT_16( st_ivas->nCPE, 1 ) )
- {
- IF( NE_32( ( error = ivas_mct_dec_fx( st_ivas, p_output_fx, output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
+ ELSE IF( EQ_32( st_ivas->intern_config, IVAS_AUDIO_CONFIG_5_1 ) && ( EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1_2 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1_4 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_7_1 ) ) )
{
- return error;
+ FOR( n = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; n < ( st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ); n++ )
+ {
+ set32_fx( p_output_fx[n], 0, *nSamplesRendered );
+ }
}
}
- /* HP filtering */
- FOR( n = 0; n < st_ivas->nchan_transport; n++ )
- {
- hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs );
- }
-
- /* Rendering */
- test();
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) )
- {
- ivas_ls_setup_conversion_fx( st_ivas, st_ivas->nchan_transport, output_frame, p_output_fx, p_output_fx );
- }
- }
- ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) )
- {
- IF( st_ivas->hOutSetup.separateChannelEnabled )
- {
- st = st_ivas->hCPE[0]->hCoreCoder[0]; /* Metadata is always with CPE in the case of separated channel */
- }
-
- /* read McMASA parameters from the bitstream */
- IF( NE_32( ( error = ivas_masa_decode_fx( st_ivas, st, &nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
+ /* copy discrete C and TD LFE from internal TC to output */
IF( st_ivas->hOutSetup.separateChannelEnabled )
{
- /* Decode the transport audio signals */
- IF( NE_32( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- /* Identify the index of the separated channel, always LFE_CHANNEL-1 here */
- n = LFE_CHANNEL - 1;
- move16();
-
- /* Decode the separated channel to output[n] to be combined with the synthesized channels */
- IF( NE_32( ( error = ivas_sce_dec_fx( st_ivas, 0, &p_output_fx[n], output_frame, 0 ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
test();
test();
test();
@@ -882,2169 +892,761 @@ ivas_error ivas_dec_fx(
test();
test();
test();
- /* Delay the separated channel to sync with CLDFB delay of the DirAC synthesis, and synthesize the LFE signal. */
IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_7_1 ) ||
- EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1_4 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_7_1_4 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1_2 ) || ( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && st_ivas->hOutSetup.num_lfe > 0 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
+ EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1_4 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_7_1_4 ) ||
+ EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1_2 ) || ( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && GT_16( st_ivas->hOutSetup.num_lfe, 0 ) ) )
{
- ivas_lfe_synth_with_filters_fx( st_ivas->hMasa->hMasaLfeSynth, p_output_fx, output_frame, n, LFE_CHANNEL );
+ Copy32( p_tc_fx[LFE_CHANNEL], p_output_fx[LFE_CHANNEL], *nSamplesRendered );
+ Copy32( p_tc_fx[LFE_CHANNEL - 1], p_output_fx[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered );
}
ELSE IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && st_ivas->hOutSetup.num_lfe == 0 )
{
- /* Delay the separated channel to sync with the DirAC rendering */
- delay_signal32_fx( p_output_fx[n], output_frame, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_fx, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_size );
- }
- }
- ELSE
- {
- IF( EQ_16( st_ivas->nSCE, 1 ) )
- {
- IF( NE_32( ( error = ivas_sce_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- ELSE IF( EQ_16( st_ivas->nCPE, 1 ) )
- {
- IF( NE_32( ( error = ivas_cpe_dec_fx( st_ivas, 0, &p_output_fx[0], output_frame, nb_bits_metadata[0] ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
+ Copy32( p_tc_fx[LFE_CHANNEL - 1], p_output_fx[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered );
}
}
-
- IF( st_ivas->sba_dirac_stereo_flag != 0 ) /* use the flag to trigger the DFT upmix */
- {
- ivas_sba_dirac_stereo_dec_fx( st_ivas, p_output_fx, output_frame );
- }
-
- /* HP filtering */
- FOR( n = 0; n < getNumChanSynthesis( st_ivas ); n++ )
- {
- hp20_fx_32_opt( p_output_fx[n], output_frame, st_ivas->mem_hp20_out_fx[n], output_Fs );
- }
-
- IF( EQ_32( st_ivas->renderer_type, RENDERER_MCMASA_MONO_STEREO ) )
- {
- ivas_mono_stereo_downmix_mcmasa_fx( st_ivas, p_output_fx, output_frame );
- }
}
}
/*----------------------------------------------------------------*
- * Common updates
+ * Write IVAS output channels
+ * - compensation for saturation
+ * - float to integer conversion
*----------------------------------------------------------------*/
- IF( !st_ivas->bfi ) /* do not update if first frame(s) are lost or NO_DATA */
+ st_ivas->hTcBuffer->n_samples_available = sub( st_ivas->hTcBuffer->n_samples_available, *nSamplesRendered );
+ st_ivas->hTcBuffer->n_samples_rendered = add( st_ivas->hTcBuffer->n_samples_rendered, *nSamplesRendered );
+ move16();
+ move16();
+
+ /* update global combined orientation start index */
+ ivas_combined_orientation_update_start_index( st_ivas->hCombinedOrientationData, *nSamplesRendered );
+
+ IF( st_ivas->hTcBuffer->n_samples_discard > 0 )
{
- st_ivas->hDecoderConfig->last_ivas_total_brate = ivas_total_brate;
- move32();
- IF( LE_32( ivas_total_brate, IVAS_SID_5k2 ) )
+ FOR( n = 0; n < s_min( MAX_OUTPUT_CHANNELS, ivas_get_nchan_buffers_dec_fx( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ) ); n++ )
{
- st_ivas->last_active_ivas_total_brate = st_ivas->last_active_ivas_total_brate;
- move32();
+ p_output_fx[n] += st_ivas->hTcBuffer->n_samples_discard;
}
- ELSE
+ *nSamplesRendered = sub( (Word16) *nSamplesRendered, st_ivas->hTcBuffer->n_samples_discard );
+ move16();
+ st_ivas->hTcBuffer->n_samples_discard = 0;
+ move16();
+ }
+
+ IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+ {
+ const Word32 *p_output_fx_const[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS];
+
+ nchan_out_syn_output = i_mult( BINAURAL_CHANNELS, st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses );
+
+ /* Save TD signals for pose correction if they are to be used.
+ *
+ * NOTE: Here BASOP differs from the float version. In float, we push samples to TD ring buffer in lib_dec.c function isar_render_poses. */
+ IF( st_ivas->hSplitBinRend->hMultiBinTdData != NULL )
{
- st_ivas->last_active_ivas_total_brate = ivas_total_brate;
- move32();
+ FOR( i = 0; i < nchan_out_syn_output; i++ )
+ {
+ p_output_fx_const[i] = p_output_fx[i];
+ }
+ ivas_TD_RINGBUF_PushChannels( st_ivas->hSplitBinRend->hMultiBinTdData, p_output_fx_const, *nSamplesRendered );
}
- }
- test();
- test();
- if ( LT_16( st_ivas->ini_frame, MAX_FRAME_COUNTER ) && !( st_ivas->bfi && st_ivas->ini_frame == 0 ) ) /* keep "st_ivas->ini_frame = 0" until first good received frame */
+#ifdef TMP_1342_WORKAROUND_DEC_FLUSH_BROKEN_IN_SR
+ if ( st_ivas->flushing )
+ {
+ nchan_out_syn_output = BINAURAL_CHANNELS;
+ move16();
+ }
+#endif
+ }
+ ELSE
{
- st_ivas->ini_frame = add( st_ivas->ini_frame, 1 );
+ nchan_out_syn_output = nchan_out;
move16();
}
- test();
- test();
- if ( LT_16( st_ivas->ini_active_frame, MAX_FRAME_COUNTER ) && !( st_ivas->bfi && st_ivas->ini_frame == 0 ) && GT_32( ivas_total_brate, IVAS_SID_5k2 ) ) /* needed in MASA decoder in case the first active frame is BFI, and there were SID-frames decoded before */
+ IF( is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ) == 0 )
{
- st_ivas->ini_active_frame = add( st_ivas->ini_active_frame, 1 );
- move16();
+ IF( NE_32( st_ivas->ivas_format, MONO_FORMAT ) )
+ {
+#ifndef DISABLE_LIMITER
+ ivas_limiter_dec_fx( st_ivas->hLimiter, p_output_fx, nchan_out, *nSamplesRendered, st_ivas->BER_detect, output_q_factor );
+#endif
+ }
}
- st_ivas->last_ivas_format = st_ivas->ivas_format;
- move32();
- pop_wmops();
+ ivas_syn_output_fx( p_output_fx, output_q_factor, *nSamplesRendered, nchan_out_syn_output, data );
+ *nSamplesAvailableNext = st_ivas->hTcBuffer->n_samples_available;
+ move16();
+
+ pop_wmops();
return IVAS_ERR_OK;
}
/*--------------------------------------------------------------------------*
- * ivas_dec_feed_tc_to_renderer()
+ * ivas_jbm_dec_flush_renderer()
*
- * Feed decoded transport channels to the IVAS renderer routine
- * + digest TC channels in ParamISM and ParamMC
+ * Flush samples if renderer granularity changes on a bitrate change in JBM
*--------------------------------------------------------------------------*/
-void ivas_dec_feed_tc_to_renderer_fx(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
- const Word16 nSamplesForRendering, /* i : number of TC samples available for rendering */
- Word16 *nSamplesResidual /* o : number of samples not fitting into the renderer grid and buffer for the next call*/
+ivas_error ivas_jbm_dec_flush_renderer_fx(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ const Word16 tc_granularity_new, /* i : new renderer granularity */
+ const RENDERER_TYPE renderer_type_old, /* i : old renderer type */
+ const AUDIO_CONFIG intern_config_old, /* i : old internal config */
+ const IVAS_OUTPUT_SETUP_HANDLE hIntSetupOld, /* i : old internal output setup */
+ const MC_MODE mc_mode_old, /* i : old MC mode */
+ const ISM_MODE ism_mode_old, /* i : old ISM mode */
+ UWord16 *nSamplesRendered, /* o : number of samples flushed */
+ Word16 *data /* o : output synthesis signal Q0*/
)
{
- Word32 tmp_buf_fx[MAX_JBM_L_FRAME48k];
- Word32 *p_data_fx[FOA_CHANNELS + MAX_NUM_OBJECTS];
- Word16 n, n_render_timeslots, n_ch_cldfb;
- Word16 ch, offset, len_offset;
+ ivas_error error;
+ Word16 n_samples_still_available;
+ Word16 n_slots_still_available;
+ Word16 n_samples_to_render;
+ Word16 n_samples_granularity;
DECODER_TC_BUFFER_HANDLE hTcBuffer;
+ Word32 *p_output_fx[MAX_LS_CHANNELS + MAX_NUM_OBJECTS];
+ Word16 nchan_in, nchan_out;
+ Word16 ch_idx;
+
+
+ IF( !st_ivas->hDecoderConfig->Opt_tsm )
+ {
+ return IVAS_ERR_OK;
+ }
+
+ FOR( ch_idx = 0; ch_idx < ( MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS ); ch_idx++ )
+ {
+ p_output_fx[ch_idx] = st_ivas->p_output_fx[ch_idx];
+ }
+ *nSamplesRendered = 0;
+ move16();
hTcBuffer = st_ivas->hTcBuffer;
- n_ch_cldfb = sub( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full );
+ n_samples_granularity = hTcBuffer->n_samples_granularity;
move16();
- hTcBuffer->q_tc_fx = Q11;
+ /* get number of possible slots in new granularity */
+ n_samples_still_available = sub( hTcBuffer->n_samples_buffered, hTcBuffer->n_samples_rendered );
+
+ // n_slots_still_available = n_samples_still_available / tc_granularity_new;
+ Word16 tmp, tmp_e;
+ tmp = BASOP_Util_Divide1616_Scale( n_samples_still_available, tc_granularity_new, &tmp_e );
+ n_slots_still_available = shr( tmp, sub( 15, tmp_e ) );
+ *nSamplesRendered = imult1616( n_slots_still_available, tc_granularity_new );
+ n_samples_to_render = *nSamplesRendered;
move16();
+ move16();
+ n_samples_still_available = sub( n_samples_still_available, n_samples_to_render );
+ assert( n_samples_still_available < tc_granularity_new );
- IF( st_ivas->hDecoderConfig->Opt_tsm )
+ /* update combined orientation access index */
+ ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData );
+
+ IF( n_slots_still_available )
{
- Word16 n_samples_still_available;
- Word16 n_ch_full_copy, n_ch_res_copy;
- n_samples_still_available = sub( hTcBuffer->n_samples_buffered, hTcBuffer->n_samples_rendered );
- hTcBuffer->n_samples_buffered = add( add( n_samples_still_available, nSamplesForRendering ), hTcBuffer->n_samples_discard );
- hTcBuffer->n_samples_available = i_mult( hTcBuffer->n_samples_granularity, idiv1616( hTcBuffer->n_samples_buffered, hTcBuffer->n_samples_granularity ) );
- *nSamplesResidual = sub( hTcBuffer->n_samples_buffered, hTcBuffer->n_samples_available );
+ /* render available full slots (with new lower granularity) */
+ FOR( ch_idx = 0; ch_idx < s_max( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full ); ch_idx++ )
+ {
+ /* move it at the beginning of the TC buffer with zero padding */
+ Copy32( hTcBuffer->tc_buffer_old_fx[ch_idx], hTcBuffer->tc_fx[ch_idx], n_samples_to_render );
+ set_zero_fx( hTcBuffer->tc_fx[ch_idx] + n_samples_to_render, sub( hTcBuffer->n_samples_granularity, n_samples_to_render ) );
+ }
+
+ /* simple change of the slot info */
+ hTcBuffer->num_slots = 1;
+ hTcBuffer->nb_subframes = 1;
+ hTcBuffer->subframes_rendered = 0;
+ hTcBuffer->slots_rendered = 0;
+ hTcBuffer->subframe_nbslots[0] = 1;
+ hTcBuffer->n_samples_buffered = add( n_samples_granularity, n_samples_still_available );
+ hTcBuffer->n_samples_available = 0;
+ hTcBuffer->n_samples_flushed = n_samples_to_render;
+ hTcBuffer->n_samples_rendered = 0;
+ move16();
+ move16();
+ move16();
+ move16();
+ move16();
+ move16();
move16();
move16();
move16();
- n_ch_full_copy = s_min( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full );
- n_ch_res_copy = sub( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full );
- /* buffers are shared between 'hTcBuffer->tc[]' and 'p_output_f[]':
- in case of 'length(hTcBuffer->tc[]) < length(p_output_f[])', reset of TC buffer
- pointers is needed after ivas_buffer_interleaved_to_deinterleaved() */
- len_offset = NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS );
- IF( LT_16( len_offset, L_FRAME48k ) )
+
+ test();
+ IF( EQ_16( st_ivas->ivas_format, ISM_FORMAT ) )
{
- offset = 0;
- move16();
- FOR( ch = 0; ch < s_max( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full ); ch++ )
+ IF( EQ_16( ism_mode_old, ISM_MODE_DISC ) )
{
- hTcBuffer->tc_fx[ch] = &hTcBuffer->tc_buffer_fx[offset];
- st_ivas->p_output_fx[ch] = hTcBuffer->tc_fx[ch];
- offset = add( offset, len_offset );
- }
- }
+ /* Binaural rendering */
+ IF( EQ_16( renderer_type_old, RENDERER_BINAURAL_OBJECTS_TD ) )
+ {
+ IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_output_fx, n_samples_granularity ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ ELSE IF( EQ_16( renderer_type_old, RENDERER_BINAURAL_MIXER_CONV_ROOM ) )
+ {
+ /* Convert to CICPxx; used also for ISM->CICP19->binaural_room rendering */
+ set16_fx( st_ivas->hIsmRendererData->interpolator_fx, 32767, n_samples_granularity ); // 32767=1.0f in Q15
- FOR( ch = 0; ch < n_ch_full_copy; ch++ )
- {
- Copy32( hTcBuffer->tc_fx[ch], tmp_buf_fx, nSamplesForRendering );
- set_zero_fx( hTcBuffer->tc_fx[ch], hTcBuffer->n_samples_discard );
- Copy32( hTcBuffer->tc_buffer_old_fx[ch], hTcBuffer->tc_fx[ch] + hTcBuffer->n_samples_discard, n_samples_still_available );
- Copy32( tmp_buf_fx, hTcBuffer->tc_fx[ch] + n_samples_still_available + hTcBuffer->n_samples_discard, nSamplesForRendering - *nSamplesResidual );
- Copy32( tmp_buf_fx + nSamplesForRendering - *nSamplesResidual, hTcBuffer->tc_buffer_old_fx[ch], *nSamplesResidual );
- }
+ ivas_ism_render_sf_fx( st_ivas, renderer_type_old, p_output_fx, n_samples_granularity );
- IF( n_ch_res_copy > 0 )
- {
- FOR( ; ch < hTcBuffer->nchan_transport_rend; ch++ )
+ st_ivas->hCrendWrapper->p_io_qfactor = &st_ivas->hCrendWrapper->io_qfactor;
+ *st_ivas->hCrendWrapper->p_io_qfactor = 11;
+
+ move16();
+ IF( NE_32( ( error = ivas_rend_crendProcessSubframe_fx( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL,
+ NULL, NULL, st_ivas->hTcBuffer, p_output_fx, p_output_fx, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs, 0 ) ),
+ IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+ }
+ }
+ ELSE
{
- p_data_fx[ch] = hTcBuffer->tc_fx[ch];
- Copy32( hTcBuffer->tc_fx[ch], tmp_buf_fx, nSamplesForRendering );
- Copy32( hTcBuffer->tc_buffer_old_fx[ch], p_data_fx[ch], n_samples_still_available );
- Copy32( tmp_buf_fx, p_data_fx[ch] + n_samples_still_available, sub( nSamplesForRendering, *nSamplesResidual ) );
- Copy32( tmp_buf_fx + nSamplesForRendering - *nSamplesResidual, hTcBuffer->tc_buffer_old_fx[ch], *nSamplesResidual );
+ return IVAS_ERROR( IVAS_ERR_WRONG_MODE, "Wrong ISM_MODE in VoIP renderer flushing!" );
}
}
-
- n_render_timeslots = idiv1616( st_ivas->hTcBuffer->n_samples_available, st_ivas->hTcBuffer->n_samples_granularity );
- }
- ELSE
- {
- FOR( n = 0; n < n_ch_cldfb; n++ )
+ ELSE IF( EQ_16( st_ivas->ivas_format, MC_FORMAT ) )
{
- p_data_fx[n] = &st_ivas->p_output_fx[n][0];
- move16();
- }
+ IF( EQ_16( mc_mode_old, MC_MODE_MCT ) )
+ {
+ Word16 crendInPlaceRotation = FALSE;
- ch = s_max( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full );
- FOR( n = 0; n < ch; n++ )
- {
- hTcBuffer->tc_fx[n] = st_ivas->p_output_fx[n]; /* note: buffers needed in the TD decorellator */
- move16();
- }
+ test();
+ test();
+ test();
+ IF( NE_16( st_ivas->transport_config, intern_config_old ) && ( EQ_16( intern_config_old, IVAS_AUDIO_CONFIG_FOA ) || EQ_16( intern_config_old, IVAS_AUDIO_CONFIG_HOA2 ) || EQ_16( intern_config_old, IVAS_AUDIO_CONFIG_HOA3 ) ) )
+ {
+ IF( GT_16( sub( add( hIntSetupOld->nchan_out_woLFE, hIntSetupOld->num_lfe ), add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ) ), 0 ) )
+ {
+ crendInPlaceRotation = TRUE;
+ move16();
+ ivas_mc2sba_fx( st_ivas->hTransSetup, hTcBuffer->tc_fx, p_output_fx, hTcBuffer->n_samples_granularity, hIntSetupOld->ambisonics_order, GAIN_LFE_FX );
+ }
+ }
- hTcBuffer->n_samples_buffered = nSamplesForRendering;
- hTcBuffer->n_samples_available = hTcBuffer->n_samples_buffered;
- *nSamplesResidual = 0;
- move16();
- move16();
- move16();
+ test();
+ IF( EQ_16( renderer_type_old, RENDERER_BINAURAL_MIXER_CONV ) || EQ_16( renderer_type_old, RENDERER_BINAURAL_MIXER_CONV_ROOM ) )
+ {
+ st_ivas->hCrendWrapper->p_io_qfactor = &st_ivas->hCrendWrapper->io_qfactor;
+ IF( NE_32( ( error = getAudioConfigNumChannels( intern_config_old, &nchan_in ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
- n_render_timeslots = DEFAULT_JBM_CLDFB_TIMESLOTS;
- move16();
- }
+ IF( NE_32( ( error = getAudioConfigNumChannels( st_ivas->hOutSetup.output_config, &nchan_out ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
- /* CLDFB analysis for ParamMC/ParamISM */
- test();
- test();
- test();
- test();
- test();
- test();
- IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) && ( EQ_32( st_ivas->renderer_type, RENDERER_PARAM_ISM ) || EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) )
- {
- ivas_param_ism_dec_digest_tc_fx( st_ivas, n_render_timeslots, p_data_fx, Q11 );
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) && EQ_32( hTcBuffer->tc_buffer_mode, TC_BUFFER_MODE_RENDERER ) )
- {
- ivas_param_mc_dec_digest_tc_fx( st_ivas, (UWord8) n_render_timeslots, p_data_fx, Q11 );
- }
+ Word16 subframe_len, gd_bits;
+ subframe_len = imult1616( st_ivas->hTcBuffer->subframe_nbslots[0], n_samples_granularity );
+ gd_bits = find_guarded_bits_fx( subframe_len );
+ *st_ivas->hCrendWrapper->p_io_qfactor = sub( 13, gd_bits );
+ FOR( Word16 i = 0; i < nchan_in; i++ )
+ {
+ scale_sig32( p_output_fx[i], *nSamplesRendered, sub( *st_ivas->hCrendWrapper->p_io_qfactor, Q11 ) ); // Q = *st_ivas->hCrendWrapper->p_io_qfactor
+ }
- hTcBuffer->n_samples_rendered = 0;
- move16();
- hTcBuffer->subframes_rendered = 0;
- move16();
+ IF( NE_32( error = ivas_rend_crendProcessSubframe_fx( st_ivas->hCrendWrapper, intern_config_old, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, hIntSetupOld, st_ivas->hEFAPdata, st_ivas->hTcBuffer, crendInPlaceRotation ? p_output_fx : st_ivas->hTcBuffer->tc_fx, p_output_fx, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs, 0 ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
- return;
-}
+ ivas_binaural_add_LFE_fx( st_ivas, n_samples_granularity, hTcBuffer->tc_fx, p_output_fx );
+ FOR( Word16 i = 0; i < nchan_in; i++ )
+ {
+ scale_sig32( p_output_fx[i], *nSamplesRendered, sub( Q11, *st_ivas->hCrendWrapper->p_io_qfactor ) ); // Q11
+ }
+ }
+ ELSE IF( EQ_16( renderer_type_old, RENDERER_BINAURAL_OBJECTS_TD ) )
+ {
+ IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_output_fx, n_samples_granularity ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
-/*--------------------------------------------------------------------------*
- * ivas_dec_render()
- *
- * Principal IVAS internal rendering routine
- *--------------------------------------------------------------------------*/
+ ivas_binaural_add_LFE_fx( st_ivas, *nSamplesRendered, hTcBuffer->tc_fx, p_output_fx );
+ }
+ ELSE
+ {
+ return IVAS_ERROR( IVAS_ERR_WRONG_MODE, "Wrong renderer in MCT VoIP renderer flushing!" );
+ }
+ }
+ ELSE
+ {
+ return IVAS_ERROR( IVAS_ERR_WRONG_MODE, "Wrong MC_MODE in VoIP renderer flushing!" );
+ }
+ }
+ ELSE IF( EQ_16( st_ivas->ivas_format, MASA_ISM_FORMAT ) || EQ_16( st_ivas->ivas_format, MASA_FORMAT ) )
+ {
+ IF( EQ_16( ism_mode_old, ISM_MASA_MODE_DISC ) )
+ {
+ Word32 *tc_local_fx[MAX_NUM_OBJECTS];
+ Word16 last_dirac_md_idx;
+ UWord16 nSamplesAvailableNext;
+ ISM_MODE ism_mode_orig;
+ RENDERER_TYPE renderer_type_orig;
+ Word32 ivas_total_brate;
-ivas_error ivas_dec_render_fx(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
- const UWord16 nSamplesAsked, /* i : number of samples wanted */
- UWord16 *nSamplesRendered, /* o : number of samples rendered */
- UWord16 *nSamplesAvailableNext, /* o : number of samples still available in the rendering pipeline */
- Word16 *data /* o : output synthesis signal Q0*/
-)
-{
- Word16 n, nchan_out;
- Word16 nchan_transport_rend;
- Word16 nchan_remapped;
- Word32 output_Fs;
- AUDIO_CONFIG output_config;
- Word16 nSamplesAskedLocal;
- ivas_error error;
- Word32 *p_output_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS];
- Word32 *p_tc_fx[MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS];
- Word16 subframe_len, gd_bits, exp, nchan_in, i, j, ch;
- const Word16 output_q_factor = Q11;
- move16();
- Word16 nchan_out_syn_output;
-
- push_wmops( "ivas_dec_render" );
- /*----------------------------------------------------------------*
- * Initialization of local vars after struct has been set
- *----------------------------------------------------------------*/
-
- output_Fs = st_ivas->hDecoderConfig->output_Fs;
- move32();
- nchan_out = st_ivas->hDecoderConfig->nchan_out;
- move16();
- nchan_transport_rend = st_ivas->hTcBuffer->nchan_transport_rend;
- move16();
- output_config = st_ivas->hDecoderConfig->output_config;
- move32();
- nSamplesAskedLocal = add( nSamplesAsked, st_ivas->hTcBuffer->n_samples_discard );
- move16();
-
- FOR( n = 0; n < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; n++ )
- {
- p_output_fx[n] = st_ivas->p_output_fx[n];
- }
-
- IF( !st_ivas->hDecoderConfig->Opt_tsm )
- {
- FOR( n = 0; n < MAX_INTERN_CHANNELS; n++ )
- {
- st_ivas->hTcBuffer->tc_fx[n] = st_ivas->p_output_fx[n];
- }
- }
-
- FOR( n = 0; n < st_ivas->hTcBuffer->nchan_buffer_full; n++ )
- {
- p_tc_fx[n] = &st_ivas->hTcBuffer->tc_fx[n][st_ivas->hTcBuffer->n_samples_rendered];
- }
-
- /*----------------------------------------------------------------*
- * Update combined orientation access index
- *----------------------------------------------------------------*/
-
- IF( st_ivas->hCombinedOrientationData != NULL )
- {
- /* take the discard samples into account here to make sure head rotation stays on the correct 5ms grid */
- st_ivas->hCombinedOrientationData->cur_subframe_samples_rendered_start = sub( st_ivas->hCombinedOrientationData->cur_subframe_samples_rendered_start, st_ivas->hTcBuffer->n_samples_discard );
- move16();
-
- ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData );
- }
-
- /*----------------------------------------------------------------*
- * Rendering
- *----------------------------------------------------------------*/
-
- *nSamplesRendered = s_min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal );
- move16();
-
- test();
- test();
- IF( EQ_32( st_ivas->ivas_format, UNDEFINED_FORMAT ) )
- {
- assert( 0 );
- }
- ELSE IF( EQ_32( st_ivas->hTcBuffer->tc_buffer_mode, TC_BUFFER_MODE_BUFFER ) )
- {
- ivas_dec_tc_buffer_playout_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, p_output_fx );
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, MONO_FORMAT ) || EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) )
- {
- /* Rendering */
- IF( EQ_32( st_ivas->renderer_type, RENDERER_MC ) )
- {
- ivas_ls_setup_conversion_fx( st_ivas, st_ivas->nchan_transport, *nSamplesRendered, p_tc_fx, p_output_fx );
- }
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_NON_DIEGETIC_DOWNMIX ) )
- {
- ivas_apply_non_diegetic_panning_fx( p_tc_fx[0], p_output_fx, st_ivas->hDecoderConfig->non_diegetic_pan_gain_fx, *nSamplesRendered );
- }
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) )
- {
- ivas_stereo2sba_fx( p_tc_fx, p_output_fx, *nSamplesRendered );
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) )
- {
- /* Rendering */
- IF( EQ_32( st_ivas->ism_mode, ISM_MODE_PARAM ) )
- {
- test();
- test();
- test();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) || EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) )
- {
- ivas_dirac_dec_binaural_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, st_ivas->nchan_transport, p_output_fx );
- }
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_PARAM_ISM ) || EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) )
- {
- ivas_param_ism_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx );
-
- IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) )
- {
- /* Convert CICP19 -> Ambisonics */
- ivas_mc2sba_fx( st_ivas->hIntSetup, p_output_fx, p_output_fx, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0 );
- }
- }
- }
- ELSE /* ISM_MODE_DISC */
- {
- test();
- test();
- /* Loudspeaker or Ambisonics rendering */
- IF( EQ_32( st_ivas->renderer_type, RENDERER_TD_PANNING ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) )
- {
- /* Convert to CICPxx; used also for ISM->CICP19->binaural_room rendering */
- ivas_ism_render_sf_fx( st_ivas, st_ivas->renderer_type, p_output_fx, *nSamplesRendered );
- }
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_NON_DIEGETIC_DOWNMIX ) )
- {
- ivas_apply_non_diegetic_panning_fx( p_tc_fx[0], p_output_fx, st_ivas->hDecoderConfig->non_diegetic_pan_gain_fx, *nSamplesRendered );
- }
-#ifdef DEBUGGING
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) )
-#else
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) )
-#endif
- {
- /* Convert to Ambisonics */
- FOR( i = 0; i < st_ivas->nchan_transport; i++ )
- {
- FOR( j = 0; j < HOA3_CHANNELS; j++ )
- {
- st_ivas->hIsmRendererData->gains_fx[i][j] = L_shr( st_ivas->hIsmRendererData->gains_fx[i][j], 1 ); // Q30 -> Q29
- move32();
- st_ivas->hIsmRendererData->prev_gains_fx[i][j] = L_shr( st_ivas->hIsmRendererData->prev_gains_fx[i][j], 1 ); // Q30 -> Q29
- move32();
- }
- }
-
- ivas_ism2sba_sf_fx( p_tc_fx, p_output_fx, st_ivas->hIsmRendererData, st_ivas->nchan_transport, *nSamplesRendered, st_ivas->hTcBuffer->n_samples_rendered, st_ivas->hIntSetup.ambisonics_order );
-
- Word16 sba_num_chans = imult1616( add( st_ivas->hIntSetup.ambisonics_order, 1 ), add( st_ivas->hIntSetup.ambisonics_order, 1 ) );
- FOR( j = 0; j < sba_num_chans; j++ )
- {
- scale_sig32( p_output_fx[j], *nSamplesRendered, sub( Q11, sub( add( output_q_factor, 29 ), 31 ) ) ); // Q11
- }
-
- FOR( i = 0; i < st_ivas->nchan_transport; i++ )
- {
- FOR( j = 0; j < 16; j++ )
- {
- st_ivas->hIsmRendererData->gains_fx[i][j] = L_shl( st_ivas->hIsmRendererData->gains_fx[i][j], 1 ); // Q29 -> Q30
- move32();
- st_ivas->hIsmRendererData->prev_gains_fx[i][j] = L_shl( st_ivas->hIsmRendererData->prev_gains_fx[i][j], 1 ); // Q29 -> Q30
- move32();
- }
- }
- }
-
- /* Binaural rendering */
- IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) )
- {
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
- {
- IF( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_output_fx, *nSamplesRendered ) ) != IVAS_ERR_OK )
- {
- return error;
- }
- }
- ELSE
- {
- IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_output_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- }
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) )
- {
- st_ivas->hCrendWrapper->p_io_qfactor = &st_ivas->hCrendWrapper->io_qfactor;
- subframe_len = imult1616( st_ivas->hTcBuffer->subframe_nbslots[0], st_ivas->hTcBuffer->n_samples_granularity );
- gd_bits = find_guarded_bits_fx( subframe_len );
- exp = 13;
- move16();
- nchan_in = 12;
- move16();
- nchan_out = 2;
- move16();
- exp = sub( exp, gd_bits );
- *st_ivas->hCrendWrapper->p_io_qfactor = exp;
+ /* copy from ISM delay buffer to the correct place in TCs */
move16();
- FOR( i = 0; i < nchan_in; i++ )
+ FOR( ch_idx = 0; ch_idx < st_ivas->nchan_ism; ch_idx++ )
{
- scale_sig32( p_output_fx[i], *nSamplesRendered, negate( sub( 11, *st_ivas->hCrendWrapper->p_io_qfactor ) ) ); // Q11
+ tc_local_fx[ch_idx] = &st_ivas->hTcBuffer->tc_fx[ch_idx + 2][hTcBuffer->n_samples_rendered];
+ Copy32( st_ivas->hMasaIsmData->delayBuffer_fx[ch_idx], tc_local_fx[ch_idx], st_ivas->hMasaIsmData->delayBuffer_size ); /*Q11*/
}
- IF( NE_32( ( error = ivas_rend_crendProcessSubframe_fx( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, NULL, NULL, st_ivas->hTcBuffer, p_output_fx, p_output_fx, *nSamplesRendered, output_Fs, 0 ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
+ /* to render flushed samples, use configuration from the last received frame */
+ ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
+ renderer_type_orig = st_ivas->renderer_type;
+ ism_mode_orig = st_ivas->ism_mode;
+ st_ivas->ism_mode = ism_mode_old;
+ st_ivas->renderer_type = renderer_type_old;
+ st_ivas->hDecoderConfig->ivas_total_brate = st_ivas->hDecoderConfig->last_ivas_total_brate;
+ last_dirac_md_idx = st_ivas->hSpatParamRendCom->render_to_md_map[st_ivas->hSpatParamRendCom->slots_rendered - 1];
- FOR( i = 0; i < nchan_out; i++ )
- {
- scale_sig32( p_output_fx[i], *nSamplesRendered, sub( 11, *st_ivas->hCrendWrapper->p_io_qfactor ) ); // Q11
- }
- }
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) || EQ_32( st_ivas->ivas_format, MASA_FORMAT ) )
- {
- nchan_remapped = nchan_transport_rend;
- move16();
+ /* transfer adapted sf info from hTcBuffer to DirAC */
+ st_ivas->hSpatParamRendCom->nb_subframes = 1;
+ st_ivas->hSpatParamRendCom->subframes_rendered = 0;
+ st_ivas->hSpatParamRendCom->subframe_nbslots[0] = JBM_CLDFB_SLOTS_IN_SUBFRAME;
+ st_ivas->hSpatParamRendCom->slots_rendered = 0;
+ st_ivas->hSpatParamRendCom->num_slots = JBM_CLDFB_SLOTS_IN_SUBFRAME;
+ set16_fx( st_ivas->hSpatParamRendCom->render_to_md_map, last_dirac_md_idx, n_slots_still_available );
- test();
- test();
- /* Loudspeakers, Ambisonics or Binaural rendering */
- IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) || EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) )
- {
- ivas_dirac_dec_binaural_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output_fx );
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) )
- {
- IF( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) )
- {
- ivas_dirac_dec_render_fx( st_ivas, nchan_remapped, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx );
- }
- }
- ELSE
- {
- IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
- {
- nchan_remapped = st_ivas->nchan_transport;
- move16();
- test();
- test();
- test();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) || EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) )
- {
- test();
- IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) )
- {
- IF( NE_32( ( error = ivas_omasa_dirac_td_binaural_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output_fx ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- ELSE
- {
- ivas_dirac_dec_binaural_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output_fx );
- }
- }
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) )
- {
- ivas_omasa_dirac_rend_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output_fx );
- }
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_OMASA_OBJECT_EXT ) || EQ_32( st_ivas->renderer_type, RENDERER_OMASA_MIX_EXT ) )
- {
- ivas_dec_tc_buffer_playout_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, p_output_fx );
- ivas_omasa_rearrange_channels_fx( p_output_fx, st_ivas->nchan_ism, *nSamplesRendered );
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
- {
- nchan_remapped = nchan_transport_rend;
- move16();
-
- /* Loudspeakers, Ambisonics or Binaural rendering */
- IF( EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
- {
- test();
- test();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) )
- {
- SPAR_DEC_HANDLE hSpar;
- hSpar = st_ivas->hSpar;
- hSpar->hMdDec->Q_mixer_mat = 30;
- move16();
-
- IF( NE_32( ( error = ivas_osba_dirac_td_binaural_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_OSBA_STEREO ) )
- {
- test();
- /* shift SBA channels to avoid overwrite by ISM upmix in 1 object case and non-TSM unified channel memory*/
- IF( EQ_16( st_ivas->nchan_ism, 1 ) && EQ_16( st_ivas->hDecoderConfig->Opt_tsm, 0 ) )
- {
- Copy32( p_tc_fx[2], p_output_fx[3], *nSamplesRendered );
- Copy32( p_tc_fx[1], p_output_fx[2], *nSamplesRendered );
- p_tc_fx[1] = p_output_fx[2];
- p_tc_fx[2] = p_output_fx[3];
- }
-
- /* render objects */
- ivas_ism_render_sf_fx( st_ivas, st_ivas->renderer_type, p_output_fx, *nSamplesRendered );
-
- /* add already rendered SBA part */
- ivas_osba_stereo_add_channels_fx( p_tc_fx, p_output_fx, st_ivas->hSbaIsmData->gain_bed_fx, nchan_out, st_ivas->nchan_ism, st_ivas->ism_mode, *nSamplesRendered );
- }
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_OSBA_AMBI ) || EQ_32( st_ivas->renderer_type, RENDERER_OSBA_LS ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
- {
- IF( NE_32( ( error = ivas_osba_render_sf_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- ELSE IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) /*EXT output = individual objects + HOA3*/
- {
- IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, &p_output_fx[st_ivas->nchan_ism] ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- FOR( n = 0; n < st_ivas->nchan_ism; n++ )
- {
- Copy32( p_tc_fx[n], p_output_fx[n], *nSamplesRendered );
- }
- }
- ELSE
- {
- IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- }
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
- {
- ivas_dirac_dec_binaural_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output_fx );
-
- FOR( n = 0; n < st_ivas->hDecoderConfig->nchan_out; n++ )
- {
- scale_sig32( p_output_fx[n], *nSamplesRendered, 1 );
- }
- }
- ELSE
- {
- IF( NE_32( ( error = ivas_sba_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
- {
- FOR( n = st_ivas->hIntSetup.nchan_out_woLFE - 1; n >= 0; n-- )
- {
- Copy32( p_output_fx[n], p_output_fx[n + st_ivas->nchan_ism], *nSamplesRendered );
- }
- FOR( n = 0; n < st_ivas->nchan_ism; n++ )
- {
- set32_fx( p_output_fx[n], 0, *nSamplesRendered );
- }
- }
- FOR( n = 0; n < st_ivas->hDecoderConfig->nchan_out; n++ )
- {
- scale_sig32( p_output_fx[n], *nSamplesRendered, 1 );
- }
- }
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) )
- {
- IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCT ) )
- {
- Word16 crendInPlaceRotation = FALSE;
- move16();
-
- test();
- test();
- test();
- IF( NE_32( st_ivas->transport_config, st_ivas->intern_config ) && ( EQ_32( st_ivas->intern_config, IVAS_AUDIO_CONFIG_FOA ) || EQ_32( st_ivas->intern_config, IVAS_AUDIO_CONFIG_HOA2 ) || EQ_32( st_ivas->intern_config, IVAS_AUDIO_CONFIG_HOA3 ) ) )
- {
- IF( LT_16( add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ), add( st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hIntSetup.num_lfe ) ) )
- {
- crendInPlaceRotation = TRUE;
- move16();
-
- ivas_mc2sba_fx( st_ivas->hTransSetup, p_tc_fx, p_output_fx, *nSamplesRendered, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE_FX );
- }
- }
-
- /* Rendering */
- test();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) )
- {
- st_ivas->hCrendWrapper->p_io_qfactor = &st_ivas->hCrendWrapper->io_qfactor;
- subframe_len = imult1616( st_ivas->hTcBuffer->subframe_nbslots[0], st_ivas->hTcBuffer->n_samples_granularity );
- gd_bits = find_guarded_bits_fx( subframe_len );
- exp = 13;
- move16();
- IF( NE_32( ( error = getAudioConfigNumChannels( st_ivas->intern_config, &nchan_in ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- IF( NE_32( ( error = getAudioConfigNumChannels( st_ivas->hOutSetup.output_config, &nchan_out ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- exp = sub( exp, gd_bits );
- *st_ivas->hCrendWrapper->p_io_qfactor = exp;
- move16();
-
- IF( crendInPlaceRotation )
- {
- FOR( i = 0; i < nchan_in; i++ )
- {
- scale_sig32( p_output_fx[i], *nSamplesRendered, negate( sub( Q11, *st_ivas->hCrendWrapper->p_io_qfactor ) ) ); // Q = *st_ivas->hCrendWrapper->p_io_qfactor
- }
- }
- ELSE
- {
- FOR( i = 0; i < nchan_in; i++ )
- {
- scale_sig32( p_tc_fx[i], *nSamplesRendered, negate( sub( Q11, *st_ivas->hCrendWrapper->p_io_qfactor ) ) ); // Q = *st_ivas->hCrendWrapper->p_io_qfactor
- }
- }
-
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
- {
- IF( ( error = ivas_rend_crendProcessSubframesSplitBin( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData,
- &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, p_output_fx, p_output_fx, *nSamplesRendered, output_Fs ) ) != IVAS_ERR_OK )
- {
- return error;
- }
- }
- ELSE
- {
- IF( NE_32( ( error = ivas_rend_crendProcessSubframe_fx( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData,
- &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, p_output_fx, p_output_fx, *nSamplesRendered, output_Fs, 0 ) ),
- IVAS_ERR_OK ) )
- {
- return error;
- }
-
- ivas_binaural_add_LFE_fx( st_ivas, *nSamplesRendered, p_tc_fx, p_output_fx );
- }
-
- IF( crendInPlaceRotation )
- {
- n = nchan_in;
- }
- ELSE
- {
- n = nchan_out;
- }
- move16();
-
- FOR( i = 0; i < n; i++ )
- {
- scale_sig32( p_output_fx[i], *nSamplesRendered, sub( Q11, *st_ivas->hCrendWrapper->p_io_qfactor ) ); // Q11
- }
-
- FOR( i = n; i < nchan_in; i++ )
- {
- scale_sig32( p_tc_fx[i], *nSamplesRendered, sub( Q11, *st_ivas->hCrendWrapper->p_io_qfactor ) ); // Q11
- }
- }
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_MC ) )
- {
- ivas_ls_setup_conversion_fx( st_ivas, st_ivas->nchan_transport, *nSamplesRendered, p_tc_fx, p_output_fx );
- }
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) )
- {
- ivas_mc2sba_fx( st_ivas->hIntSetup, p_tc_fx, p_output_fx, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0 );
- }
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) )
- {
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
- {
- IF( NE_32( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_output_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- else
+ IF( ( error = ivas_omasa_dirac_td_binaural_fx( st_ivas, (UWord16) hTcBuffer->n_samples_granularity, nSamplesRendered, &nSamplesAvailableNext, CPE_CHANNELS, p_output_fx ) ) != IVAS_ERR_OK )
{
- IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_output_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- ivas_binaural_add_LFE_fx( st_ivas, *nSamplesRendered, p_tc_fx, p_output_fx );
- }
- }
- }
- ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) )
- {
- ivas_mc_paramupmix_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_tc_fx, p_output_fx );
-
- /* Rendering */
- test();
- test();
- IF( ( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) && !st_ivas->hDecoderConfig->Opt_Headrotation )
- {
- /* handled in CLDFB domain already */
- IF( NE_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && NE_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
- {
- ivas_binaural_add_LFE_fx( st_ivas, *nSamplesRendered, p_output_fx, p_output_fx );
- }
- }
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_MC ) )
- {
- ivas_ls_setup_conversion_fx( st_ivas, MC_PARAMUPMIX_MAX_INPUT_CHANS, *nSamplesRendered, p_output_fx, p_output_fx );
- }
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) )
- {
- ivas_mc2sba_fx( st_ivas->hIntSetup, p_output_fx, p_output_fx, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0 );
- }
- }
- ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_PARAMMC ) )
- {
- Word16 channel_active_fx[MAX_OUTPUT_CHANNELS];
- Word16 nchan_out_cov;
- Word16 nchan_out_cldfb = 0;
- move16();
-
- set16_fx( channel_active_fx, 0, MAX_LS_CHANNELS );
- Word16 nchan_transport_tmp = st_ivas->nchan_transport;
- move16();
- output_Fs = st_ivas->hDecoderConfig->output_Fs;
- move32();
- Word16 nchan_out_transport = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe );
- test();
- test();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
- {
- nchan_out_cldfb = BINAURAL_CHANNELS;
- move16();
- set16_fx( channel_active_fx, 1, BINAURAL_CHANNELS );
- nchan_out_cov = add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe );
- }
- ELSE IF( EQ_32( st_ivas->hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_CLDFB ) )
- {
- nchan_out_cov = nchan_out_transport;
- move16();
- nchan_out_cldfb = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe );
- }
- ELSE IF( EQ_32( st_ivas->hParamMC->synthesis_conf, PARAM_MC_SYNTH_LS_CONV_COV ) || EQ_32( st_ivas->hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) )
- {
- nchan_out_cov = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe );
- nchan_out_cldfb = nchan_out_cov;
- move16();
- set16_fx( channel_active_fx, 1, nchan_out_cov );
- }
- ELSE
- {
- nchan_out_cov = nchan_out_transport;
- move16();
- nchan_out_cldfb = nchan_out_transport;
- move16();
- set16_fx( channel_active_fx, 1, nchan_out_cov );
- }
- IF( st_ivas->hParamMC->max_band_decorr > 0 )
- {
- Word16 tmp;
- tmp = L_norm_arr( st_ivas->hParamMC->h_freq_domain_decorr_ap_state->decorr_buffer_fx, st_ivas->hParamMC->h_freq_domain_decorr_ap_state->decorr_buffer_len );
- scale_sig32( st_ivas->hParamMC->h_freq_domain_decorr_ap_state->decorr_buffer_fx, st_ivas->hParamMC->h_freq_domain_decorr_ap_state->decorr_buffer_len, tmp ); // Q(st_ivas->hParamMC->h_freq_domain_decorr_ap_state->q_decorr_buffer+ tmp)
- st_ivas->hParamMC->h_freq_domain_decorr_ap_state->q_decorr_buffer = add( st_ivas->hParamMC->h_freq_domain_decorr_ap_state->q_decorr_buffer, tmp );
- move16();
- }
- /* CLDFB synthesis */
- FOR( ch = 0; ch < nchan_out_cldfb; ch++ )
- {
- IF( st_ivas->cldfbSynDec[ch] )
- {
- scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, ( Q5 - Q11 ) ); // Q5
- st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q5;
- move16();
- }
- }
- Word16 tempp;
- FOR( Word16 param_band_idx = 0; param_band_idx < st_ivas->hParamMC->num_param_bands_synth; param_band_idx++ )
- {
- tempp = getScaleFactor32( st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx[param_band_idx], st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_len );
- scale_sig32( st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx[param_band_idx], st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_len, tempp ); // Q(31-(st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp[param_band_idx]- tempp))
- st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp[param_band_idx] = sub( st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp[param_band_idx], tempp );
- move16();
-
- IF( LT_16( st_ivas->hParamMC->band_grouping[param_band_idx], st_ivas->hParamMC->h_output_synthesis_params.max_band_decorr ) )
- {
- tempp = getScaleFactor32( st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx[param_band_idx], st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_len );
- scale_sig32( st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx[param_band_idx], st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_len, tempp ); // Q(31- (st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp[param_band_idx] - tempp))
- st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp[param_band_idx] = sub( st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp[param_band_idx], tempp );
- move16();
- }
- }
-
- ivas_param_mc_dec_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx, channel_active_fx );
-
- FOR( ch = 0; ch < nchan_out_cldfb; ch++ )
- {
- IF( st_ivas->cldfbSynDec[ch] )
- {
- scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_size, Q11 - Q5 ); // Q11
- st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11;
- move16();
- }
- }
- IF( EQ_16( st_ivas->hParamMC->slots_rendered, st_ivas->hParamMC->num_slots ) )
- {
- FOR( Word16 param_band_idx = 0; param_band_idx < st_ivas->hParamMC->hMetadataPMC->nbands_coded; param_band_idx++ )
- {
- IF( LT_16( st_ivas->hParamMC->band_grouping[param_band_idx], st_ivas->hParamMC->h_output_synthesis_params.max_band_decorr ) )
- {
- Copy32( st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_fx[param_band_idx], st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_fx[param_band_idx], imult1616( nchan_transport_tmp, nchan_out_cov ) );
- st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_old_exp[param_band_idx] = st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_res_exp[param_band_idx];
- move16();
- }
- Copy32( st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_fx[param_band_idx], st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_old_fx[param_band_idx], imult1616( nchan_transport_tmp, nchan_out_cov ) );
- st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_old_exp[param_band_idx] = st_ivas->hParamMC->h_output_synthesis_cov_state.mixing_matrix_exp[param_band_idx];
- move16();
- }
- }
- }
- ELSE IF( EQ_32( st_ivas->mc_mode, MC_MODE_MCMASA ) )
- {
- nchan_remapped = st_ivas->nchan_transport;
- move16();
-
- test();
- test();
- test();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) || EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) )
- {
- ivas_dirac_dec_binaural_render_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output_fx );
- }
- ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) || EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) /* rendering to CICPxx and Ambisonics */
- {
- ivas_dirac_dec_render_fx( st_ivas, nchan_remapped, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output_fx );
-
- test();
- test();
- test();
- IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) )
- {
- /* we still need to copy the separate channel if available */
- IF( st_ivas->hOutSetup.separateChannelEnabled )
- {
- Copy32( p_tc_fx[LFE_CHANNEL - 1], p_output_fx[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered );
- }
-
- ivas_mc2sba_fx( st_ivas->hIntSetup, p_output_fx, p_output_fx, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0 );
- }
- ELSE IF( EQ_32( st_ivas->intern_config, IVAS_AUDIO_CONFIG_5_1 ) && ( EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1_2 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1_4 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_7_1 ) ) )
- {
- FOR( n = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; n < ( st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ); n++ )
- {
- set32_fx( p_output_fx[n], 0, *nSamplesRendered );
- }
- }
- }
-
- /* copy discrete C and TD LFE from internal TC to output */
- IF( st_ivas->hOutSetup.separateChannelEnabled )
- {
- test();
- test();
- test();
- test();
- test();
- test();
- test();
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_7_1 ) ||
- EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1_4 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_7_1_4 ) ||
- EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1_2 ) || ( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && GT_16( st_ivas->hOutSetup.num_lfe, 0 ) ) )
- {
- Copy32( p_tc_fx[LFE_CHANNEL], p_output_fx[LFE_CHANNEL], *nSamplesRendered );
- Copy32( p_tc_fx[LFE_CHANNEL - 1], p_output_fx[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered );
- }
- ELSE IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && st_ivas->hOutSetup.num_lfe == 0 )
- {
- Copy32( p_tc_fx[LFE_CHANNEL - 1], p_output_fx[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered );
- }
- }
- }
- }
-
- /*----------------------------------------------------------------*
- * Write IVAS output channels
- * - compensation for saturation
- * - float to integer conversion
- *----------------------------------------------------------------*/
-
- st_ivas->hTcBuffer->n_samples_available = sub( st_ivas->hTcBuffer->n_samples_available, *nSamplesRendered );
- st_ivas->hTcBuffer->n_samples_rendered = add( st_ivas->hTcBuffer->n_samples_rendered, *nSamplesRendered );
- move16();
- move16();
-
- /* update global combined orientation start index */
- ivas_combined_orientation_update_start_index( st_ivas->hCombinedOrientationData, *nSamplesRendered );
-
- IF( st_ivas->hTcBuffer->n_samples_discard > 0 )
- {
- FOR( n = 0; n < s_min( MAX_OUTPUT_CHANNELS, ivas_get_nchan_buffers_dec_fx( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ) ); n++ )
- {
- p_output_fx[n] += st_ivas->hTcBuffer->n_samples_discard;
- }
- *nSamplesRendered = sub( (Word16) *nSamplesRendered, st_ivas->hTcBuffer->n_samples_discard );
- move16();
- st_ivas->hTcBuffer->n_samples_discard = 0;
- move16();
- }
-
- IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
- {
- const Word32 *p_output_fx_const[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS];
-
- nchan_out_syn_output = i_mult( BINAURAL_CHANNELS, st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses );
-
- /* Save TD signals for pose correction if they are to be used.
- *
- * NOTE: Here BASOP differs from the float version. In float, we push samples to TD ring buffer in lib_dec.c function isar_render_poses. */
- IF( st_ivas->hSplitBinRend->hMultiBinTdData != NULL )
- {
- FOR( i = 0; i < nchan_out_syn_output; i++ )
- {
- p_output_fx_const[i] = p_output_fx[i];
- }
- ivas_TD_RINGBUF_PushChannels( st_ivas->hSplitBinRend->hMultiBinTdData, p_output_fx_const, *nSamplesRendered );
- }
-
-#ifdef TMP_1342_WORKAROUND_DEC_FLUSH_BROKEN_IN_SR
- if ( st_ivas->flushing )
- {
- nchan_out_syn_output = BINAURAL_CHANNELS;
- move16();
- }
-#endif
- }
- ELSE
- {
- nchan_out_syn_output = nchan_out;
- move16();
- }
-
- IF( is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ) == 0 )
- {
- IF( NE_32( st_ivas->ivas_format, MONO_FORMAT ) )
- {
-#ifndef DISABLE_LIMITER
- ivas_limiter_dec_fx( st_ivas->hLimiter, p_output_fx, nchan_out, *nSamplesRendered, st_ivas->BER_detect, output_q_factor );
-#endif
- }
- }
-
- ivas_syn_output_fx( p_output_fx, output_q_factor, *nSamplesRendered, nchan_out_syn_output, data );
-
- *nSamplesAvailableNext = st_ivas->hTcBuffer->n_samples_available;
- move16();
-
- pop_wmops();
- return IVAS_ERR_OK;
-}
-
-/*--------------------------------------------------------------------------*
- * ivas_jbm_dec_flush_renderer()
- *
- * Flush samples if renderer granularity changes on a bitrate change in JBM
- *--------------------------------------------------------------------------*/
-
-ivas_error ivas_jbm_dec_flush_renderer_fx(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
- const Word16 tc_granularity_new, /* i : new renderer granularity */
- const RENDERER_TYPE renderer_type_old, /* i : old renderer type */
- const AUDIO_CONFIG intern_config_old, /* i : old internal config */
- const IVAS_OUTPUT_SETUP_HANDLE hIntSetupOld, /* i : old internal output setup */
- const MC_MODE mc_mode_old, /* i : old MC mode */
- const ISM_MODE ism_mode_old, /* i : old ISM mode */
- UWord16 *nSamplesRendered, /* o : number of samples flushed */
- Word16 *data /* o : output synthesis signal Q0*/
-)
-{
- ivas_error error;
- Word16 n_samples_still_available;
- Word16 n_slots_still_available;
- Word16 n_samples_to_render;
- Word16 n_samples_granularity;
- DECODER_TC_BUFFER_HANDLE hTcBuffer;
- Word32 *p_output_fx[MAX_LS_CHANNELS + MAX_NUM_OBJECTS];
- Word16 nchan_in, nchan_out;
- Word16 ch_idx;
-
-
- IF( !st_ivas->hDecoderConfig->Opt_tsm )
- {
- return IVAS_ERR_OK;
- }
-
- FOR( ch_idx = 0; ch_idx < ( MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS ); ch_idx++ )
- {
- p_output_fx[ch_idx] = st_ivas->p_output_fx[ch_idx];
- }
-
- *nSamplesRendered = 0;
- move16();
- hTcBuffer = st_ivas->hTcBuffer;
- n_samples_granularity = hTcBuffer->n_samples_granularity;
- move16();
-
- /* get number of possible slots in new granularity */
- n_samples_still_available = sub( hTcBuffer->n_samples_buffered, hTcBuffer->n_samples_rendered );
-
- // n_slots_still_available = n_samples_still_available / tc_granularity_new;
- Word16 tmp, tmp_e;
- tmp = BASOP_Util_Divide1616_Scale( n_samples_still_available, tc_granularity_new, &tmp_e );
- n_slots_still_available = shr( tmp, sub( 15, tmp_e ) );
- *nSamplesRendered = imult1616( n_slots_still_available, tc_granularity_new );
- n_samples_to_render = *nSamplesRendered;
- move16();
- move16();
- n_samples_still_available = sub( n_samples_still_available, n_samples_to_render );
- assert( n_samples_still_available < tc_granularity_new );
-
- /* update combined orientation access index */
- ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData );
-
- IF( n_slots_still_available )
- {
-
- /* render available full slots (with new lower granularity) */
- FOR( ch_idx = 0; ch_idx < s_max( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full ); ch_idx++ )
- {
- /* move it at the beginning of the TC buffer with zero padding */
- Copy32( hTcBuffer->tc_buffer_old_fx[ch_idx], hTcBuffer->tc_fx[ch_idx], n_samples_to_render );
- set_zero_fx( hTcBuffer->tc_fx[ch_idx] + n_samples_to_render, sub( hTcBuffer->n_samples_granularity, n_samples_to_render ) );
- }
-
- /* simple change of the slot info */
- hTcBuffer->num_slots = 1;
- hTcBuffer->nb_subframes = 1;
- hTcBuffer->subframes_rendered = 0;
- hTcBuffer->slots_rendered = 0;
- hTcBuffer->subframe_nbslots[0] = 1;
- hTcBuffer->n_samples_buffered = add( n_samples_granularity, n_samples_still_available );
- hTcBuffer->n_samples_available = 0;
- hTcBuffer->n_samples_flushed = n_samples_to_render;
- hTcBuffer->n_samples_rendered = 0;
- move16();
- move16();
- move16();
- move16();
- move16();
- move16();
- move16();
- move16();
- move16();
-
-
- test();
- IF( EQ_16( st_ivas->ivas_format, ISM_FORMAT ) )
- {
- IF( EQ_16( ism_mode_old, ISM_MODE_DISC ) )
- {
- /* Binaural rendering */
- IF( EQ_16( renderer_type_old, RENDERER_BINAURAL_OBJECTS_TD ) )
- {
- IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_output_fx, n_samples_granularity ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- ELSE IF( EQ_16( renderer_type_old, RENDERER_BINAURAL_MIXER_CONV_ROOM ) )
- {
- /* Convert to CICPxx; used also for ISM->CICP19->binaural_room rendering */
- set16_fx( st_ivas->hIsmRendererData->interpolator_fx, 32767, n_samples_granularity ); // 32767=1.0f in Q15
-
- ivas_ism_render_sf_fx( st_ivas, renderer_type_old, p_output_fx, n_samples_granularity );
-
- st_ivas->hCrendWrapper->p_io_qfactor = &st_ivas->hCrendWrapper->io_qfactor;
- *st_ivas->hCrendWrapper->p_io_qfactor = 11;
-
- move16();
- IF( NE_32( ( error = ivas_rend_crendProcessSubframe_fx( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL,
- NULL, NULL, st_ivas->hTcBuffer, p_output_fx, p_output_fx, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs, 0 ) ),
- IVAS_ERR_OK ) )
- {
- return error;
- }
- }
- }
- ELSE
- {
- return IVAS_ERROR( IVAS_ERR_WRONG_MODE, "Wrong ISM_MODE in VoIP renderer flushing!" );
- }
- }
- ELSE IF( EQ_16( st_ivas->ivas_format, MC_FORMAT ) )
- {
- IF( EQ_16( mc_mode_old, MC_MODE_MCT ) )
- {
- Word16 crendInPlaceRotation = FALSE;
-
- test();
- test();
- test();
- IF( NE_16( st_ivas->transport_config, intern_config_old ) && ( EQ_16( intern_config_old, IVAS_AUDIO_CONFIG_FOA ) || EQ_16( intern_config_old, IVAS_AUDIO_CONFIG_HOA2 ) || EQ_16( intern_config_old, IVAS_AUDIO_CONFIG_HOA3 ) ) )
- {
- IF( GT_16( sub( add( hIntSetupOld->nchan_out_woLFE, hIntSetupOld->num_lfe ), add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ) ), 0 ) )
- {
- crendInPlaceRotation = TRUE;
- move16();
- ivas_mc2sba_fx( st_ivas->hTransSetup, hTcBuffer->tc_fx, p_output_fx, hTcBuffer->n_samples_granularity, hIntSetupOld->ambisonics_order, GAIN_LFE_FX );
- }
- }
-
- test();
- IF( EQ_16( renderer_type_old, RENDERER_BINAURAL_MIXER_CONV ) || EQ_16( renderer_type_old, RENDERER_BINAURAL_MIXER_CONV_ROOM ) )
- {
- st_ivas->hCrendWrapper->p_io_qfactor = &st_ivas->hCrendWrapper->io_qfactor;
- IF( NE_32( ( error = getAudioConfigNumChannels( intern_config_old, &nchan_in ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- IF( NE_32( ( error = getAudioConfigNumChannels( st_ivas->hOutSetup.output_config, &nchan_out ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- Word16 subframe_len, gd_bits;
- subframe_len = imult1616( st_ivas->hTcBuffer->subframe_nbslots[0], n_samples_granularity );
- gd_bits = find_guarded_bits_fx( subframe_len );
- *st_ivas->hCrendWrapper->p_io_qfactor = sub( 13, gd_bits );
- FOR( Word16 i = 0; i < nchan_in; i++ )
- {
- scale_sig32( p_output_fx[i], *nSamplesRendered, sub( *st_ivas->hCrendWrapper->p_io_qfactor, Q11 ) ); // Q = *st_ivas->hCrendWrapper->p_io_qfactor
- }
-
- IF( NE_32( error = ivas_rend_crendProcessSubframe_fx( st_ivas->hCrendWrapper, intern_config_old, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, hIntSetupOld, st_ivas->hEFAPdata, st_ivas->hTcBuffer, crendInPlaceRotation ? p_output_fx : st_ivas->hTcBuffer->tc_fx, p_output_fx, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs, 0 ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- ivas_binaural_add_LFE_fx( st_ivas, n_samples_granularity, hTcBuffer->tc_fx, p_output_fx );
-
- FOR( Word16 i = 0; i < nchan_in; i++ )
- {
- scale_sig32( p_output_fx[i], *nSamplesRendered, sub( Q11, *st_ivas->hCrendWrapper->p_io_qfactor ) ); // Q11
- }
- }
- ELSE IF( EQ_16( renderer_type_old, RENDERER_BINAURAL_OBJECTS_TD ) )
- {
- IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_output_fx, n_samples_granularity ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- ivas_binaural_add_LFE_fx( st_ivas, *nSamplesRendered, hTcBuffer->tc_fx, p_output_fx );
- }
- ELSE
- {
- return IVAS_ERROR( IVAS_ERR_WRONG_MODE, "Wrong renderer in MCT VoIP renderer flushing!" );
- }
- }
- ELSE
- {
- return IVAS_ERROR( IVAS_ERR_WRONG_MODE, "Wrong MC_MODE in VoIP renderer flushing!" );
- }
- }
- ELSE IF( EQ_16( st_ivas->ivas_format, MASA_ISM_FORMAT ) || EQ_16( st_ivas->ivas_format, MASA_FORMAT ) )
- {
- IF( EQ_16( ism_mode_old, ISM_MASA_MODE_DISC ) )
- {
- Word32 *tc_local_fx[MAX_NUM_OBJECTS];
- Word16 last_dirac_md_idx;
- UWord16 nSamplesAvailableNext;
- ISM_MODE ism_mode_orig;
- RENDERER_TYPE renderer_type_orig;
- Word32 ivas_total_brate;
-
- /* copy from ISM delay buffer to the correct place in TCs */
- move16();
- FOR( ch_idx = 0; ch_idx < st_ivas->nchan_ism; ch_idx++ )
- {
- tc_local_fx[ch_idx] = &st_ivas->hTcBuffer->tc_fx[ch_idx + 2][hTcBuffer->n_samples_rendered];
- Copy32( st_ivas->hMasaIsmData->delayBuffer_fx[ch_idx], tc_local_fx[ch_idx], st_ivas->hMasaIsmData->delayBuffer_size ); /*Q11*/
- }
-
- /* to render flushed samples, use configuration from the last received frame */
- ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
- renderer_type_orig = st_ivas->renderer_type;
- ism_mode_orig = st_ivas->ism_mode;
- st_ivas->ism_mode = ism_mode_old;
- st_ivas->renderer_type = renderer_type_old;
- st_ivas->hDecoderConfig->ivas_total_brate = st_ivas->hDecoderConfig->last_ivas_total_brate;
- last_dirac_md_idx = st_ivas->hSpatParamRendCom->render_to_md_map[st_ivas->hSpatParamRendCom->slots_rendered - 1];
-
- /* transfer adapted sf info from hTcBuffer to DirAC */
- st_ivas->hSpatParamRendCom->nb_subframes = 1;
- st_ivas->hSpatParamRendCom->subframes_rendered = 0;
- st_ivas->hSpatParamRendCom->subframe_nbslots[0] = JBM_CLDFB_SLOTS_IN_SUBFRAME;
- st_ivas->hSpatParamRendCom->slots_rendered = 0;
- st_ivas->hSpatParamRendCom->num_slots = JBM_CLDFB_SLOTS_IN_SUBFRAME;
- set16_fx( st_ivas->hSpatParamRendCom->render_to_md_map, last_dirac_md_idx, n_slots_still_available );
-
- IF( ( error = ivas_omasa_dirac_td_binaural_fx( st_ivas, (UWord16) hTcBuffer->n_samples_granularity, nSamplesRendered, &nSamplesAvailableNext, CPE_CHANNELS, p_output_fx ) ) != IVAS_ERR_OK )
- {
- return error;
- }
-
- /* restore original configuration */
- st_ivas->ism_mode = ism_mode_orig;
- st_ivas->renderer_type = renderer_type_orig;
- st_ivas->hDecoderConfig->ivas_total_brate = ivas_total_brate;
- }
- }
- ELSE IF( EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
- {
- IF( EQ_32( ism_mode_old, ISM_SBA_MODE_DISC ) )
- {
- Word32 *tc_local_fx[MAX_TRANSPORT_CHANNELS];
- Word16 last_spar_md_idx;
- Word16 last_dirac_md_idx;
- UWord16 nSamplesAvailableNext;
- ISM_MODE ism_mode_orig;
- RENDERER_TYPE renderer_type_orig;
- Word32 ivas_total_brate;
-
- ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
- renderer_type_orig = st_ivas->renderer_type;
- ism_mode_orig = st_ivas->ism_mode;
-
- /* to render flushed samples, use configuration from the last received frame */
- move32();
- st_ivas->ism_mode = ism_mode_old;
- st_ivas->renderer_type = renderer_type_old;
- st_ivas->hDecoderConfig->ivas_total_brate = st_ivas->hDecoderConfig->last_ivas_total_brate;
-
- last_spar_md_idx = st_ivas->hSpar->render_to_md_map[st_ivas->hSpar->slots_rendered - 1];
- last_dirac_md_idx = st_ivas->hSpatParamRendCom->render_to_md_map[st_ivas->hSpatParamRendCom->slots_rendered - 1];
- move16();
- move16();
-
- /* copy from ISM delay buffer to the correct place in TCs */
- FOR( ch_idx = 0; ch_idx < st_ivas->nchan_ism; ch_idx++ )
- {
- tc_local_fx[ch_idx] = &st_ivas->hTcBuffer->tc_fx[ch_idx][hTcBuffer->n_samples_rendered];
- Copy32( st_ivas->hSbaIsmData->delayBuffer_fx[ch_idx], tc_local_fx[ch_idx], st_ivas->hSbaIsmData->delayBuffer_size );
- }
-
- /* transfer adapted sf info from hTcBuffer to SPAR and DirAC */
- st_ivas->hSpar->nb_subframes = 1;
- st_ivas->hSpar->subframes_rendered = 0;
- st_ivas->hSpar->subframe_nbslots[0] = JBM_CLDFB_SLOTS_IN_SUBFRAME;
- st_ivas->hSpar->slots_rendered = 0;
- st_ivas->hSpar->num_slots = JBM_CLDFB_SLOTS_IN_SUBFRAME;
- st_ivas->hSpatParamRendCom->nb_subframes = 1;
- st_ivas->hSpatParamRendCom->subframes_rendered = 0;
- st_ivas->hSpatParamRendCom->subframe_nbslots[0] = JBM_CLDFB_SLOTS_IN_SUBFRAME;
- st_ivas->hSpatParamRendCom->slots_rendered = 0;
- st_ivas->hSpatParamRendCom->num_slots = JBM_CLDFB_SLOTS_IN_SUBFRAME;
- move16();
- move16();
- move16();
- move16();
- move16();
- move16();
- move16();
- move16();
- move16();
- move16();
-
- /* also adapt md maps, just use the last index */
- set16_fx( st_ivas->hSpar->render_to_md_map, last_spar_md_idx, n_slots_still_available );
- set16_fx( st_ivas->hSpatParamRendCom->render_to_md_map, last_dirac_md_idx, n_slots_still_available );
-
- /* render the last subframe */
- IF( NE_32( ( error = ivas_osba_dirac_td_binaural_fx( st_ivas, (UWord16) hTcBuffer->n_samples_granularity, nSamplesRendered, &nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) )
- {
- return error;
- }
-
- /* restore original configuration */
- st_ivas->ism_mode = ism_mode_orig;
- st_ivas->renderer_type = renderer_type_orig;
- st_ivas->hDecoderConfig->ivas_total_brate = ivas_total_brate;
- }
- }
- ELSE
- {
- return IVAS_ERROR( IVAS_ERR_WRONG_MODE, "Wrong IVAS format in VoIP renderer flushing!" );
- }
-
- hTcBuffer->n_samples_rendered = hTcBuffer->n_samples_granularity;
- }
-
- /* update global combined orientation start index */
- ivas_combined_orientation_update_start_index( st_ivas->hCombinedOrientationData, *nSamplesRendered );
-
- *nSamplesRendered = n_samples_to_render;
- move16();
-
- /* Only write out the valid data*/
- IF( is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ) == 0 )
- {
- IF( NE_16( st_ivas->ivas_format, MONO_FORMAT ) )
- {
-#ifndef DISABLE_LIMITER
- Word16 exp = 11;
- move16();
- FOR( ch_idx = 0; ch_idx < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; ch_idx++ )
- {
- p_output_fx[ch_idx] = st_ivas->p_output_fx[ch_idx];
- }
- ivas_limiter_dec_fx( st_ivas->hLimiter, p_output_fx, st_ivas->hDecoderConfig->nchan_out, *nSamplesRendered, st_ivas->BER_detect, exp );
-#endif
- }
- }
-
- ivas_syn_output_fx( p_output_fx, Q11, *nSamplesRendered, st_ivas->hDecoderConfig->nchan_out, data );
-
- return IVAS_ERR_OK;
-}
-
-
-/*--------------------------------------------------------------------------*
- * ivas_jbm_dec_set_discard_samples()
- *
- * Set number of samples to discard in the first subframe
- * if the renderer granularity changes on a bitrate change in JBM processing
- *--------------------------------------------------------------------------*/
-
-ivas_error ivas_jbm_dec_set_discard_samples_fx(
- Decoder_Struct *st_ivas /* i/o: main IVAS decoder structre */
-)
-{
- Word16 nMaxSlotsPerSubframe, nSlotsInFirstSubframe;
- Word16 temp, temp_e;
-
- /* render first frame with front zero padding and discarding those samples */
- /* nMaxSlotsPerSubframe = (Word16)(st_ivas->hDecoderConfig->output_Fs / (FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES)) / st_ivas->hTcBuffer->n_samples_granularity; */
- temp = extract_l( Mpy_32_16_1( st_ivas->hDecoderConfig->output_Fs, ONE_BY_SUBFR_PER_SEC_Q15 ) );
- temp = BASOP_Util_Divide1616_Scale( temp, st_ivas->hTcBuffer->n_samples_granularity, &temp_e );
- nMaxSlotsPerSubframe = shr( temp, sub( 15, temp_e ) ); /* Q0 */
- nSlotsInFirstSubframe = sub( nMaxSlotsPerSubframe, st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->nb_subframes - 1] );
-
- IF( nSlotsInFirstSubframe > 0 )
- {
- st_ivas->hTcBuffer->n_samples_discard = imult1616( sub( nMaxSlotsPerSubframe, nSlotsInFirstSubframe ), st_ivas->hTcBuffer->n_samples_granularity );
- /* set last subframes number to max to ensure correct continuation */
- st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->nb_subframes - 1] = nMaxSlotsPerSubframe;
- move16();
- move16();
- }
-
- return IVAS_ERR_OK;
-}
-
-
-/*--------------------------------------------------------------------------*
- * ivas_dec_get_adapted_linear_interpolator()
- *
- * Get an interpolator that is adapted to (time scale modified) IVAS frame
- *--------------------------------------------------------------------------*/
-
-void ivas_dec_get_adapted_linear_interpolator_fx(
- const Word16 default_interp_length, /* i : default length of the (full-frame) interpolator */
- const Word16 interp_length, /* i : length of the interpolator to be created */
- Word16 *interpolator_fx /* o : the interpolator Q15 */
-)
-{
- Word16 segment_len, idx;
- Word16 dec_fx;
- Word16 dec_e;
-
- segment_len = shr( default_interp_length, 1 );
- dec_fx = divide1616( 1, default_interp_length ); /*32767 / default_interp_length*/
-
- interpolator_fx[interp_length - 1] = 32767; /* (1.0f in Q15) -1 */
- move16();
- interpolator_fx[interp_length - 2] = add( sub( 32767, dec_fx ), 1 ); // Use 32768 to maintain precision
- move16();
- FOR( idx = interp_length - 3; idx >= segment_len; idx-- )
- {
- interpolator_fx[idx] = s_max( 0, sub( interpolator_fx[idx + 1], dec_fx ) );
- move16();
- }
-
- IF( interpolator_fx[idx + 1] > 0 )
- {
- dec_fx = BASOP_Util_Divide1616_Scale( interpolator_fx[idx + 1], add( segment_len, 1 ), &dec_e );
- dec_fx = shr( dec_fx, sub( 15, dec_e ) ); // Q0
- FOR( ; idx >= 0; idx-- )
- {
- interpolator_fx[idx] = sub( interpolator_fx[idx + 1], dec_fx );
- move16();
- }
- }
- ELSE
- {
- set16_fx( interpolator_fx, 0, add( idx, 1 ) );
- }
-
- return;
-}
-
-
-/*--------------------------------------------------------------------------*
- * ivas_dec_get_adapted_subframes()
- *
- * Get an interpolator that is adapted to (time scale modified) IVAS frame
- *--------------------------------------------------------------------------*/
-
-void ivas_dec_get_adapted_subframes_fx(
- const Word16 nCldfbTs, /* i : number of time slots in the current frame */
- Word16 *subframe_nbslots, /* i/o: subframe grid */
- Word16 *nb_subframes /* i/o: number of subframes in the frame */
-)
-{
- UWord16 nSlotsInLastSubframe, nSlotsInFirstSubframe;
- UWord16 nCldfbSlotsLocal = nCldfbTs;
- move16();
- Word16 temp, temp_e;
-
- /* get last subframe size from previous frame, determine how many slots have to be processed
- in the first subframe (i.e. potential leftover of a 5ms subframe) */
- nSlotsInFirstSubframe = ( sub( PARAM_MC_MAX_NSLOTS_IN_SUBFRAME, subframe_nbslots[*nb_subframes - 1] ) );
- *nb_subframes = 0;
- move16();
- IF( nSlotsInFirstSubframe > 0 )
- {
- *nb_subframes = 1;
- move16();
- nCldfbSlotsLocal = sub( nCldfbSlotsLocal, nSlotsInFirstSubframe );
- }
-
- temp = BASOP_Util_Divide3232_Scale( L_add( nCldfbSlotsLocal, PARAM_MC_MAX_NSLOTS_IN_SUBFRAME - 1 ), PARAM_MC_MAX_NSLOTS_IN_SUBFRAME, &temp_e );
- *nb_subframes = add( *nb_subframes, shr( temp, sub( 15, temp_e ) ) ); // Q0
- move16();
- nSlotsInLastSubframe = nCldfbSlotsLocal % PARAM_MC_MAX_NSLOTS_IN_SUBFRAME;
- move16();
-
- set16_fx( subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS );
- set16_fx( subframe_nbslots, PARAM_MC_MAX_NSLOTS_IN_SUBFRAME, *nb_subframes );
-
- IF( nSlotsInFirstSubframe > 0 )
- {
- subframe_nbslots[0] = nSlotsInFirstSubframe;
- move16();
- }
-
- IF( nSlotsInLastSubframe > 0 )
- {
- subframe_nbslots[*nb_subframes - 1] = nSlotsInLastSubframe;
- move16();
- }
-
- return;
-}
-
-
-/*--------------------------------------------------------------------------*
- * ivas_dec_get_md_map()
- *
- * Get an meta data map adapted to a time scale modified IVAS frame
- *--------------------------------------------------------------------------*/
-
-void ivas_dec_get_md_map_fx(
- const Word16 default_len, /* i : default frame length in metadata slots */
- const Word16 len, /* i : length of the modified frames in metadata slots*/
- const Word16 subframe_len, /* i : default length of a subframe */
- const Word16 offset, /* i : current read offset into the MD buffer */
- const Word16 buf_len, /* i : length of the metadata buffer */
- Word16 *map /* o : metadata index map */
-)
-{
- Word16 jbm_segment_len, map_idx, src_idx, src_idx_map;
- Word32 dec_fx, src_idx_fx;
- Word16 temp_e;
- Word16 temp;
- jbm_segment_len = shr( default_len, 1 );
-
- FOR( ( map_idx = len - 1, src_idx = default_len - 1 ); map_idx >= jbm_segment_len; ( map_idx--, src_idx-- ) )
- {
- temp = BASOP_Util_Divide1616_Scale( src_idx, subframe_len, &temp_e );
- temp = shr( temp, sub( 15, temp_e ) ); // Q0
- src_idx_map = s_max( 0, temp );
- map[map_idx] = add( offset, src_idx_map ) % buf_len;
- move16();
- }
-
- /* changed part (first segment), interpolate index to parameters
- (we do not want to interpolate and smooth acutal direction/diffuseness values even more) */
- IF( src_idx >= 0 )
- {
- dec_fx = BASOP_Util_Divide3232_Scale( L_shl( add( src_idx, 1 ), 16 ), jbm_segment_len, &temp_e );
- dec_fx = L_shr( dec_fx, sub( 15, temp_e ) );
- src_idx_fx = L_sub( L_shl( add( src_idx, 1 ), 16 ), dec_fx );
- FOR( ; map_idx >= 0; map_idx-- )
- {
- temp = BASOP_Util_Divide1616_Scale( round_fx( src_idx_fx ), subframe_len, &temp_e );
- temp = shr( temp, sub( 15, temp_e ) ); // Q0
- src_idx = s_max( 0, temp );
- map[map_idx] = add( offset, src_idx ) % buf_len;
- src_idx_fx = L_sub( src_idx_fx, dec_fx );
- }
- }
- ELSE
- {
- set16_fx( map, offset, add( map_idx, 1 ) );
- }
-
- return;
-}
-
-
-/*--------------------------------------------------------------------------*
- * ivas_dec_get_md_map_even_spacing()
- *
- * Get an meta data map adapted to (time scale modified) IVAS frame.
- * Distribute slots evenly across the (modified) frame.
- *--------------------------------------------------------------------------*/
-
-void ivas_dec_get_md_map_even_spacing_fx(
- const Word16 len, /* i : length of the modified frames in metadata slots*/
- const Word16 subframe_len, /* i : default length of a subframe */
- const Word16 offset, /* i : current read offset into the MD buffer */
- const Word16 buf_len, /* i : length of the metadata buffer */
- Word16 *map /* o : metadata index map */
-)
-{
- Word16 map_idx, sf_idx, sf_length, increment, subframes_written;
- Word32 decimal_fx, decimal_sum_fx, eps_fx; // q = 16
- Word16 subframe_map_length[MAX_PARAM_SPATIAL_SUBFRAMES];
-
- /* subframe map length */
- sf_length = idiv1616( len, subframe_len );
- IF( len % subframe_len == 0 )
- {
- /* even subframes */
- FOR( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ )
- {
- subframe_map_length[sf_idx] = sf_length;
- move16();
- }
- }
- ELSE
- {
- /* uneven subframes */
- Word32 temp;
- Word16 temp_e;
- temp = BASOP_Util_Divide3232_Scale( L_shl( len, 16 ), subframe_len, &temp_e );
- temp = L_shr( temp, sub( 15, temp_e ) ); // Q16
- decimal_fx = L_sub( temp, L_shl( sf_length, 16 ) ); // Q16
- decimal_sum_fx = decimal_fx;
-
- eps_fx = 65;
- move32();
- move32();
- FOR( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ )
- {
- increment = extract_l( L_shr( L_add( decimal_sum_fx, eps_fx ), 16 ) );
- subframe_map_length[sf_idx] = add( sf_length, increment );
- move16();
- IF( increment > 0 )
- {
- decimal_sum_fx = L_sub( decimal_sum_fx, ONE_IN_Q16 );
- }
- decimal_sum_fx = L_add( decimal_sum_fx, decimal_fx );
- }
- }
-
- /* map slots to subframes */
- sf_idx = 0;
- subframes_written = 0;
- move16();
- move16();
- FOR( map_idx = 0; map_idx < len; map_idx++ )
- {
- map[map_idx] = add( offset, sf_idx ) % buf_len;
- move16();
- IF( GE_16( sub( map_idx, subframes_written ), sub( subframe_map_length[sf_idx], 1 ) ) )
- {
- subframes_written = add( subframes_written, subframe_map_length[sf_idx] );
- sf_idx = add( sf_idx, 1 );
- }
- }
-
- return;
-}
-
-
-/*--------------------------------------------------------------------------*
- * ivas_dec_get_num_tc_channels()
- *
- * Get the number of transport channels provided to the renderer
- *--------------------------------------------------------------------------*/
-
-Word16 ivas_dec_get_num_tc_channels_fx(
- Decoder_Struct *st_ivas /* i : IVAS decoder handle */
-)
-{
- Word16 num_tc;
- Word32 ivas_total_brate;
- AUDIO_CONFIG output_config;
-
- IF( EQ_16( st_ivas->renderer_type, RENDERER_DISABLE ) )
- {
- num_tc = st_ivas->hDecoderConfig->nchan_out;
- move16();
- }
- ELSE
- {
- num_tc = st_ivas->nchan_transport;
- move16();
- }
- output_config = st_ivas->hDecoderConfig->output_config;
- move16();
-
- ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
- move32();
-
- test();
- test();
- test();
- test();
- IF( EQ_32( st_ivas->ivas_format, MONO_FORMAT ) )
- {
- num_tc = 1;
- move16();
- }
- ELSE IF( EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) && EQ_16( st_ivas->hDecoderConfig->nchan_out, 1 ) )
- {
- num_tc = 1;
- move16();
- }
- ELSE IF( EQ_16( st_ivas->ivas_format, ISM_FORMAT ) )
- {
- if ( EQ_16( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) )
- {
- num_tc = 1;
- move16();
- }
- }
- ELSE IF( EQ_16( st_ivas->ivas_format, SBA_FORMAT ) || EQ_16( st_ivas->ivas_format, MASA_FORMAT ) )
- {
- test();
- test();
- test();
- test();
- test();
- test();
- IF( st_ivas->sba_dirac_stereo_flag )
- {
- num_tc = CPE_CHANNELS;
- move16();
- }
- ELSE IF( EQ_16( st_ivas->ivas_format, MASA_FORMAT ) && LT_32( ivas_total_brate, MASA_STEREO_MIN_BITRATE ) && ( GT_32( ivas_total_brate, IVAS_SID_5k2 ) || ( LE_32( ivas_total_brate, IVAS_SID_5k2 ) && GT_16( st_ivas->nCPE, 0 ) && st_ivas->hCPE[0] != NULL && EQ_16( st_ivas->hCPE[0]->nchan_out, 1 ) ) ) )
- {
- num_tc = 1; /* Only one channel transported */
- move16();
- }
-
- test();
- test();
- test();
- test();
- IF( EQ_16( st_ivas->ivas_format, MASA_FORMAT ) && EQ_16( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) && EQ_16( st_ivas->nchan_transport, 2 ) && LT_32( st_ivas->hDecoderConfig->ivas_total_brate, MASA_STEREO_MIN_BITRATE ) && GT_32( st_ivas->hDecoderConfig->ivas_total_brate, IVAS_SID_5k2 ) )
- {
- num_tc = CPE_CHANNELS;
- move16();
- }
- IF( EQ_16( st_ivas->ivas_format, SBA_FORMAT ) )
- {
- if ( EQ_16( num_tc, 3 ) )
- {
- num_tc = add( num_tc, 1 );
- }
- }
- }
- ELSE IF( EQ_16( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
- {
- IF( NE_16( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
- {
- test();
- IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
- {
- num_tc = add( num_tc, 1 );
- }
- ELSE IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
- {
- num_tc = add( num_tc, st_ivas->nchan_ism );
- }
- }
- }
- ELSE IF( EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
- {
- if ( st_ivas->sba_dirac_stereo_flag )
- {
- num_tc = CPE_CHANNELS;
- move16();
- }
-
- if ( EQ_16( num_tc, 3 ) )
- {
- num_tc = add( num_tc, 1 );
- }
- if ( EQ_16( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
- {
- num_tc = add( num_tc, st_ivas->nchan_ism );
- }
- }
- ELSE IF( EQ_16( st_ivas->ivas_format, MC_FORMAT ) )
- {
- IF( EQ_16( output_config, IVAS_AUDIO_CONFIG_MONO ) )
- {
- num_tc = 1;
- move16();
- }
- ELSE IF( EQ_16( output_config, IVAS_AUDIO_CONFIG_STEREO ) )
- {
- num_tc = 2;
- move16();
+ return error;
+ }
+
+ /* restore original configuration */
+ st_ivas->ism_mode = ism_mode_orig;
+ st_ivas->renderer_type = renderer_type_orig;
+ st_ivas->hDecoderConfig->ivas_total_brate = ivas_total_brate;
+ }
}
- ELSE IF( EQ_16( st_ivas->mc_mode, MC_MODE_MCT ) )
+ ELSE IF( EQ_16( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
{
- /* do all static dmx already in the TC decoder if less channels than transported... */
- test();
- test();
- test();
- test();
- test();
- IF( NE_16( st_ivas->transport_config, st_ivas->intern_config ) && ( EQ_16( st_ivas->intern_config, IVAS_AUDIO_CONFIG_FOA ) || EQ_16( st_ivas->intern_config, IVAS_AUDIO_CONFIG_HOA2 ) || EQ_16( st_ivas->intern_config, IVAS_AUDIO_CONFIG_HOA3 ) ) )
+ IF( EQ_32( ism_mode_old, ISM_SBA_MODE_DISC ) )
{
- if ( GE_16( add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ), add( st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hIntSetup.num_lfe ) ) )
+ Word32 *tc_local_fx[MAX_TRANSPORT_CHANNELS];
+ Word16 last_spar_md_idx;
+ Word16 last_dirac_md_idx;
+ UWord16 nSamplesAvailableNext;
+ ISM_MODE ism_mode_orig;
+ RENDERER_TYPE renderer_type_orig;
+ Word32 ivas_total_brate;
+
+ ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
+ renderer_type_orig = st_ivas->renderer_type;
+ ism_mode_orig = st_ivas->ism_mode;
+
+ /* to render flushed samples, use configuration from the last received frame */
+ move32();
+ st_ivas->ism_mode = ism_mode_old;
+ st_ivas->renderer_type = renderer_type_old;
+ st_ivas->hDecoderConfig->ivas_total_brate = st_ivas->hDecoderConfig->last_ivas_total_brate;
+
+ last_spar_md_idx = st_ivas->hSpar->render_to_md_map[st_ivas->hSpar->slots_rendered - 1];
+ last_dirac_md_idx = st_ivas->hSpatParamRendCom->render_to_md_map[st_ivas->hSpatParamRendCom->slots_rendered - 1];
+ move16();
+ move16();
+
+ /* copy from ISM delay buffer to the correct place in TCs */
+ FOR( ch_idx = 0; ch_idx < st_ivas->nchan_ism; ch_idx++ )
{
- num_tc = add( st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hIntSetup.num_lfe );
+ tc_local_fx[ch_idx] = &st_ivas->hTcBuffer->tc_fx[ch_idx][hTcBuffer->n_samples_rendered];
+ Copy32( st_ivas->hSbaIsmData->delayBuffer_fx[ch_idx], tc_local_fx[ch_idx], st_ivas->hSbaIsmData->delayBuffer_size );
}
- }
- ELSE IF( ( EQ_16( st_ivas->renderer_type, RENDERER_MC ) || EQ_16( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) && GE_16( add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ), add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ) ) )
- {
- num_tc = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe );
+
+ /* transfer adapted sf info from hTcBuffer to SPAR and DirAC */
+ st_ivas->hSpar->nb_subframes = 1;
+ st_ivas->hSpar->subframes_rendered = 0;
+ st_ivas->hSpar->subframe_nbslots[0] = JBM_CLDFB_SLOTS_IN_SUBFRAME;
+ st_ivas->hSpar->slots_rendered = 0;
+ st_ivas->hSpar->num_slots = JBM_CLDFB_SLOTS_IN_SUBFRAME;
+ st_ivas->hSpatParamRendCom->nb_subframes = 1;
+ st_ivas->hSpatParamRendCom->subframes_rendered = 0;
+ st_ivas->hSpatParamRendCom->subframe_nbslots[0] = JBM_CLDFB_SLOTS_IN_SUBFRAME;
+ st_ivas->hSpatParamRendCom->slots_rendered = 0;
+ st_ivas->hSpatParamRendCom->num_slots = JBM_CLDFB_SLOTS_IN_SUBFRAME;
+ move16();
+ move16();
+ move16();
+ move16();
+ move16();
+ move16();
+ move16();
+ move16();
+ move16();
+ move16();
+
+ /* also adapt md maps, just use the last index */
+ set16_fx( st_ivas->hSpar->render_to_md_map, last_spar_md_idx, n_slots_still_available );
+ set16_fx( st_ivas->hSpatParamRendCom->render_to_md_map, last_dirac_md_idx, n_slots_still_available );
+
+ /* render the last subframe */
+ IF( NE_32( ( error = ivas_osba_dirac_td_binaural_fx( st_ivas, (UWord16) hTcBuffer->n_samples_granularity, nSamplesRendered, &nSamplesAvailableNext, p_output_fx ) ), IVAS_ERR_OK ) )
+ {
+ return error;
+ }
+
+ /* restore original configuration */
+ st_ivas->ism_mode = ism_mode_orig;
+ st_ivas->renderer_type = renderer_type_orig;
+ st_ivas->hDecoderConfig->ivas_total_brate = ivas_total_brate;
}
}
- ELSE IF( EQ_16( st_ivas->mc_mode, MC_MODE_PARAMUPMIX ) )
+ ELSE
{
- num_tc = MC_PARAMUPMIX_MAX_TRANSPORT_CHANS;
- move16();
+ return IVAS_ERROR( IVAS_ERR_WRONG_MODE, "Wrong IVAS format in VoIP renderer flushing!" );
}
- ELSE IF( EQ_16( st_ivas->mc_mode, MC_MODE_MCMASA ) )
- {
- if ( st_ivas->hOutSetup.separateChannelEnabled )
- {
- num_tc = add( num_tc, 1 );
- }
- test();
- test();
- test();
- test();
- test();
- test();
- test();
- if ( st_ivas->hOutSetup.separateChannelEnabled && ( EQ_16( output_config, IVAS_AUDIO_CONFIG_5_1 ) || EQ_16( output_config, IVAS_AUDIO_CONFIG_7_1 ) ||
- EQ_16( output_config, IVAS_AUDIO_CONFIG_5_1_4 ) || EQ_16( output_config, IVAS_AUDIO_CONFIG_7_1_4 ) ||
- EQ_16( output_config, IVAS_AUDIO_CONFIG_5_1_2 ) || ( EQ_16( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) && st_ivas->hOutSetup.num_lfe > 0 ) ) )
+ hTcBuffer->n_samples_rendered = hTcBuffer->n_samples_granularity;
+ }
+
+ /* update global combined orientation start index */
+ ivas_combined_orientation_update_start_index( st_ivas->hCombinedOrientationData, *nSamplesRendered );
+
+ *nSamplesRendered = n_samples_to_render;
+ move16();
+
+ /* Only write out the valid data*/
+ IF( is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ) == 0 )
+ {
+ IF( NE_16( st_ivas->ivas_format, MONO_FORMAT ) )
+ {
+#ifndef DISABLE_LIMITER
+ Word16 exp = 11;
+ move16();
+ FOR( ch_idx = 0; ch_idx < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; ch_idx++ )
{
- /* LFE is synthesized in TD with the TCs*/
- num_tc = add( num_tc, 1 );
+ p_output_fx[ch_idx] = st_ivas->p_output_fx[ch_idx];
}
+ ivas_limiter_dec_fx( st_ivas->hLimiter, p_output_fx, st_ivas->hDecoderConfig->nchan_out, *nSamplesRendered, st_ivas->BER_detect, exp );
+#endif
}
}
- return num_tc;
+ ivas_syn_output_fx( p_output_fx, Q11, *nSamplesRendered, st_ivas->hDecoderConfig->nchan_out, data );
+
+ return IVAS_ERR_OK;
}
/*--------------------------------------------------------------------------*
- * ivas_dec_get_render_granularity()
+ * ivas_jbm_dec_set_discard_samples()
*
- * Get renderer granularity
+ * Set number of samples to discard in the first subframe
+ * if the renderer granularity changes on a bitrate change in JBM processing
*--------------------------------------------------------------------------*/
-/*! r: render granularity */
-Word16 ivas_dec_get_render_granularity_fx(
- const RENDERER_TYPE renderer_type, /* i : renderer type */
- const RENDERER_TYPE renderer_type_sec, /* i : secondary renderer type */
- const Word32 output_Fs /* i : sampling rate */
+ivas_error ivas_jbm_dec_set_discard_samples_fx(
+ Decoder_Struct *st_ivas /* i/o: main IVAS decoder structre */
)
{
- Word16 render_granularity;
+ Word16 nMaxSlotsPerSubframe, nSlotsInFirstSubframe;
+ Word16 temp, temp_e;
- test();
- test();
- test();
- IF( EQ_32( renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) || /* TD renderer */
- EQ_32( renderer_type, RENDERER_BINAURAL_MIXER_CONV ) || EQ_32( renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) || /* Crend */
- EQ_32( renderer_type_sec, RENDERER_BINAURAL_OBJECTS_TD ) /* TD rend as a secondary renderer -> set the common granularity for both renderers */
- )
+ /* render first frame with front zero padding and discarding those samples */
+ /* nMaxSlotsPerSubframe = (Word16)(st_ivas->hDecoderConfig->output_Fs / (FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES)) / st_ivas->hTcBuffer->n_samples_granularity; */
+ temp = extract_l( Mpy_32_16_1( st_ivas->hDecoderConfig->output_Fs, ONE_BY_SUBFR_PER_SEC_Q15 ) );
+ temp = BASOP_Util_Divide1616_Scale( temp, st_ivas->hTcBuffer->n_samples_granularity, &temp_e );
+ nMaxSlotsPerSubframe = shr( temp, sub( 15, temp_e ) ); /* Q0 */
+ nSlotsInFirstSubframe = sub( nMaxSlotsPerSubframe, st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->nb_subframes - 1] );
+
+ IF( nSlotsInFirstSubframe > 0 )
{
- /* 5 ms granularity */
- render_granularity = NS2SA_FX2( output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES );
+ st_ivas->hTcBuffer->n_samples_discard = imult1616( sub( nMaxSlotsPerSubframe, nSlotsInFirstSubframe ), st_ivas->hTcBuffer->n_samples_granularity );
+ /* set last subframes number to max to ensure correct continuation */
+ st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->nb_subframes - 1] = nMaxSlotsPerSubframe;
move16();
- }
- ELSE
- {
- /* 1.25 ms granularity */
- render_granularity = NS2SA_FX2( output_Fs, CLDFB_SLOT_NS );
move16();
}
- return render_granularity;
+ return IVAS_ERR_OK;
}
/*--------------------------------------------------------------------------*
- * ivas_dec_tc_audio_allocate()
+ * ivas_dec_get_adapted_linear_interpolator()
*
- * allocate and initialize TC audio buffer
+ * Get an interpolator that is adapted to (time scale modified) IVAS frame
*--------------------------------------------------------------------------*/
-static ivas_error ivas_dec_tc_audio_allocate_fx(
- DECODER_TC_BUFFER_HANDLE hTcBuffer, /* i/o: TC buffer handle */
- const Word32 output_Fs, /* i : output sampling rate */
- const Word16 Opt_tsm /* i : TSM option flag */
+void ivas_dec_get_adapted_linear_interpolator_fx(
+ const Word16 default_interp_length, /* i : default length of the (full-frame) interpolator */
+ const Word16 interp_length, /* i : length of the interpolator to be created */
+ Word16 *interpolator_fx /* o : the interpolator Q15 */
)
{
- Word16 nsamp_to_allocate;
- Word16 ch_idx, n_samp_full, n_samp_residual, offset;
+ Word16 segment_len, idx;
+ Word16 dec_fx;
+ Word16 dec_e;
- IF( Opt_tsm )
- {
- n_samp_full = NS2SA_FX2( output_Fs, MAX_JBM_L_FRAME_NS );
- n_samp_full = s_max( n_samp_full, L_FRAME48k ); /* buffers are shared between 'hTcBuffer->tc[]' and 'p_output_f[]': ensure minimal length */
- n_samp_residual = sub( hTcBuffer->n_samples_granularity, 1 );
- }
- ELSE
+ segment_len = shr( default_interp_length, 1 );
+ dec_fx = divide1616( 1, default_interp_length ); /*32767 / default_interp_length*/
+
+ interpolator_fx[interp_length - 1] = 32767; /* (1.0f in Q15) -1 */
+ move16();
+ interpolator_fx[interp_length - 2] = add( sub( 32767, dec_fx ), 1 ); // Use 32768 to maintain precision
+ move16();
+ FOR( idx = interp_length - 3; idx >= segment_len; idx-- )
{
- n_samp_full = extract_l( Mpy_32_32( output_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) );
- n_samp_residual = 0;
+ interpolator_fx[idx] = s_max( 0, sub( interpolator_fx[idx + 1], dec_fx ) );
move16();
}
- nsamp_to_allocate = imult1616( s_max( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full ), n_samp_full );
-
- IF( Opt_tsm )
+ IF( interpolator_fx[idx + 1] > 0 )
{
- /* note: this is stack memory buffer for TC decoded and also time-scale modified audio signals */
- IF( ( hTcBuffer->tc_buffer_fx = (Word32 *) malloc( nsamp_to_allocate * sizeof( Word32 ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TC Buffer\n" ) );
- }
- set_zero_fx( hTcBuffer->tc_buffer_fx, nsamp_to_allocate );
-
- offset = 0;
- move16();
- FOR( ch_idx = 0; ch_idx < s_max( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full ); ch_idx++ )
- {
- hTcBuffer->tc_fx[ch_idx] = &hTcBuffer->tc_buffer_fx[offset];
- offset = add( offset, n_samp_full );
- }
- FOR( ; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
- {
- hTcBuffer->tc_fx[ch_idx] = NULL;
- }
-
- /* memory buffer for TC audio samples not rendered in the previous frame */
- FOR( ch_idx = 0; ch_idx < hTcBuffer->nchan_transport_internal; ch_idx++ )
- {
- IF( ( hTcBuffer->tc_buffer_old_fx[ch_idx] = (Word32 *) malloc( n_samp_residual * sizeof( Word32 ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TC Buffer\n" ) );
- }
- set_zero_fx( hTcBuffer->tc_buffer_old_fx[ch_idx], n_samp_residual );
- }
- FOR( ; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
+ dec_fx = BASOP_Util_Divide1616_Scale( interpolator_fx[idx + 1], add( segment_len, 1 ), &dec_e );
+ dec_fx = shr( dec_fx, sub( 15, dec_e ) ); // Q0
+ FOR( ; idx >= 0; idx-- )
{
- hTcBuffer->tc_buffer_old_fx[ch_idx] = NULL;
+ interpolator_fx[idx] = sub( interpolator_fx[idx + 1], dec_fx );
+ move16();
}
}
- else
+ ELSE
{
- hTcBuffer->tc_buffer_fx = NULL;
-
- FOR( ch_idx = 0; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
- {
- hTcBuffer->tc_fx[ch_idx] = NULL;
- }
-
- FOR( ch_idx = 0; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
- {
- hTcBuffer->tc_buffer_old_fx[ch_idx] = NULL;
- }
+ set16_fx( interpolator_fx, 0, add( idx, 1 ) );
}
- hTcBuffer->tc_buffer2_fx = NULL;
-
- return IVAS_ERR_OK;
+ return;
}
/*--------------------------------------------------------------------------*
- * ivas_jbm_dec_tc_audio_deallocate()
+ * ivas_dec_get_adapted_subframes()
*
- * deallocate TC audio buffer
+ * Get an interpolator that is adapted to (time scale modified) IVAS frame
*--------------------------------------------------------------------------*/
-static void ivas_jbm_dec_tc_audio_deallocate_fx(
- DECODER_TC_BUFFER_HANDLE hTcBuffer /* i/o: JBM TSM buffer handle */
+void ivas_dec_get_adapted_subframes_fx(
+ const Word16 nCldfbTs, /* i : number of time slots in the current frame */
+ Word16 *subframe_nbslots, /* i/o: subframe grid */
+ Word16 *nb_subframes /* i/o: number of subframes in the frame */
)
{
- Word16 ch_idx;
+ UWord16 nSlotsInLastSubframe, nSlotsInFirstSubframe;
+ UWord16 nCldfbSlotsLocal = nCldfbTs;
+ move16();
+ Word16 temp, temp_e;
- IF( hTcBuffer != NULL )
+ /* get last subframe size from previous frame, determine how many slots have to be processed
+ in the first subframe (i.e. potential leftover of a 5ms subframe) */
+ nSlotsInFirstSubframe = ( sub( PARAM_MC_MAX_NSLOTS_IN_SUBFRAME, subframe_nbslots[*nb_subframes - 1] ) );
+ *nb_subframes = 0;
+ move16();
+ IF( nSlotsInFirstSubframe > 0 )
{
- IF( hTcBuffer->tc_buffer_fx != NULL )
- {
- FOR( ch_idx = 0; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
- {
- hTcBuffer->tc_fx[ch_idx] = NULL;
- }
+ *nb_subframes = 1;
+ move16();
+ nCldfbSlotsLocal = sub( nCldfbSlotsLocal, nSlotsInFirstSubframe );
+ }
- free( hTcBuffer->tc_buffer_fx );
- hTcBuffer->tc_buffer_fx = NULL;
- }
+ temp = BASOP_Util_Divide3232_Scale( L_add( nCldfbSlotsLocal, PARAM_MC_MAX_NSLOTS_IN_SUBFRAME - 1 ), PARAM_MC_MAX_NSLOTS_IN_SUBFRAME, &temp_e );
+ *nb_subframes = add( *nb_subframes, shr( temp, sub( 15, temp_e ) ) ); // Q0
+ move16();
+ nSlotsInLastSubframe = nCldfbSlotsLocal % PARAM_MC_MAX_NSLOTS_IN_SUBFRAME;
+ move16();
- FOR( ch_idx = 0; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
- {
- IF( hTcBuffer->tc_buffer_old_fx[ch_idx] != NULL )
- {
- free( hTcBuffer->tc_buffer_old_fx[ch_idx] );
- hTcBuffer->tc_buffer_old_fx[ch_idx] = NULL;
- }
- }
+ set16_fx( subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS );
+ set16_fx( subframe_nbslots, PARAM_MC_MAX_NSLOTS_IN_SUBFRAME, *nb_subframes );
+
+ IF( nSlotsInFirstSubframe > 0 )
+ {
+ subframe_nbslots[0] = nSlotsInFirstSubframe;
+ move16();
+ }
- IF( hTcBuffer->tc_buffer2_fx != NULL )
- {
- free( hTcBuffer->tc_buffer2_fx );
- hTcBuffer->tc_buffer2_fx = NULL;
- }
+ IF( nSlotsInLastSubframe > 0 )
+ {
+ subframe_nbslots[*nb_subframes - 1] = nSlotsInLastSubframe;
+ move16();
}
return;
}
+
/*--------------------------------------------------------------------------*
- * ivas_dec_tc_buffer_open()
+ * ivas_dec_get_md_map()
*
- * Open and initialize transport channel buffer handle
+ * Get an meta data map adapted to a time scale modified IVAS frame
*--------------------------------------------------------------------------*/
-ivas_error ivas_dec_tc_buffer_open_fx(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
- const TC_BUFFER_MODE tc_buffer_mode, /* i : buffer mode */
- const Word16 nchan_transport_rend, /* i : number of TCs for rendering */
- const Word16 nchan_transport_internal, /* i : number of totally buffered channels */
- const Word16 nchan_full, /* i : number of channels to fully store */
- const Word16 n_samples_granularity /* i : granularity of the renderer/buffer */
+void ivas_dec_get_md_map_fx(
+ const Word16 default_len, /* i : default frame length in metadata slots */
+ const Word16 len, /* i : length of the modified frames in metadata slots*/
+ const Word16 subframe_len, /* i : default length of a subframe */
+ const Word16 offset, /* i : current read offset into the MD buffer */
+ const Word16 buf_len, /* i : length of the metadata buffer */
+ Word16 *map /* o : metadata index map */
)
{
- DECODER_TC_BUFFER_HANDLE hTcBuffer;
- Word16 nMaxSlotsPerSubframe;
- ivas_error error;
- Word16 tmp, tmp_e;
-
- /*-----------------------------------------------------------------*
- * prepare library opening
- *-----------------------------------------------------------------*/
+ Word16 jbm_segment_len, map_idx, src_idx, src_idx_map;
+ Word32 dec_fx, src_idx_fx;
+ Word16 temp_e;
+ Word16 temp;
+ jbm_segment_len = shr( default_len, 1 );
- IF( ( hTcBuffer = (DECODER_TC_BUFFER_HANDLE) malloc( sizeof( DECODER_TC_BUFFER ) ) ) == NULL )
+ FOR( ( map_idx = len - 1, src_idx = default_len - 1 ); map_idx >= jbm_segment_len; ( map_idx--, src_idx-- ) )
{
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TC Buffer\n" ) );
+ temp = BASOP_Util_Divide1616_Scale( src_idx, subframe_len, &temp_e );
+ temp = shr( temp, sub( 15, temp_e ) ); // Q0
+ src_idx_map = s_max( 0, temp );
+ map[map_idx] = add( offset, src_idx_map ) % buf_len;
+ move16();
}
- hTcBuffer->tc_buffer_mode = tc_buffer_mode;
- move16();
- hTcBuffer->nchan_transport_rend = nchan_transport_rend;
- move16();
- hTcBuffer->nchan_transport_internal = nchan_transport_internal;
- move16();
- hTcBuffer->nchan_buffer_full = nchan_full;
- move16();
- hTcBuffer->n_samples_granularity = n_samples_granularity;
- move16();
- hTcBuffer->n_samples_available = 0;
- move16();
- hTcBuffer->n_samples_buffered = 0;
- move16();
- hTcBuffer->n_samples_rendered = 0;
- move16();
- hTcBuffer->slots_rendered = 0;
- move16();
- hTcBuffer->subframes_rendered = 0;
- move16();
- hTcBuffer->n_samples_discard = 0;
- move16();
- hTcBuffer->n_samples_flushed = 0;
- move16();
- hTcBuffer->nb_subframes = MAX_PARAM_SPATIAL_SUBFRAMES;
- move16();
-
- /* nMaxSlotsPerSubframe = (Word16)(st_ivas->hDecoderConfig->output_Fs / (FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES)) / st_ivas->hTcBuffer->n_samples_granularity; */
- tmp = extract_l( Mpy_32_16_1( st_ivas->hDecoderConfig->output_Fs, ONE_BY_SUBFR_PER_SEC_Q15 ) );
- tmp = BASOP_Util_Divide1616_Scale( tmp, hTcBuffer->n_samples_granularity, &tmp_e );
- nMaxSlotsPerSubframe = shr( tmp, sub( 15, tmp_e ) ); /* Q0 */
-
- hTcBuffer->num_slots = mult0( nMaxSlotsPerSubframe, MAX_PARAM_SPATIAL_SUBFRAMES );
- move16();
-
- set16_fx( hTcBuffer->subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS );
- set16_fx( hTcBuffer->subframe_nbslots, nMaxSlotsPerSubframe, MAX_PARAM_SPATIAL_SUBFRAMES );
-
- IF( ( error = ivas_dec_tc_audio_allocate_fx( hTcBuffer, st_ivas->hDecoderConfig->output_Fs, st_ivas->hDecoderConfig->Opt_tsm ) ) != IVAS_ERR_OK )
+ /* changed part (first segment), interpolate index to parameters
+ (we do not want to interpolate and smooth acutal direction/diffuseness values even more) */
+ IF( src_idx >= 0 )
+ {
+ dec_fx = BASOP_Util_Divide3232_Scale( L_shl( add( src_idx, 1 ), 16 ), jbm_segment_len, &temp_e );
+ dec_fx = L_shr( dec_fx, sub( 15, temp_e ) );
+ src_idx_fx = L_sub( L_shl( add( src_idx, 1 ), 16 ), dec_fx );
+ FOR( ; map_idx >= 0; map_idx-- )
+ {
+ temp = BASOP_Util_Divide1616_Scale( round_fx( src_idx_fx ), subframe_len, &temp_e );
+ temp = shr( temp, sub( 15, temp_e ) ); // Q0
+ src_idx = s_max( 0, temp );
+ map[map_idx] = add( offset, src_idx ) % buf_len;
+ src_idx_fx = L_sub( src_idx_fx, dec_fx );
+ }
+ }
+ ELSE
{
- return error;
+ set16_fx( map, offset, add( map_idx, 1 ) );
}
- st_ivas->hTcBuffer = hTcBuffer;
-
- return IVAS_ERR_OK;
+ return;
}
/*--------------------------------------------------------------------------*
- * ivas_dec_tc_buffer_reconfigure()
+ * ivas_dec_get_md_map_even_spacing()
*
- * Reconfigure transport channel buffer handle
+ * Get an meta data map adapted to (time scale modified) IVAS frame.
+ * Distribute slots evenly across the (modified) frame.
*--------------------------------------------------------------------------*/
-ivas_error ivas_dec_tc_buffer_reconfigure_fx(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
- const TC_BUFFER_MODE tc_buffer_mode, /* i : new buffer mode */
- const Word16 nchan_transport_rend, /* i : new number of TCs for rendering */
- const Word16 nchan_transport_internal, /* i : new number of totally buffered channels */
- const Word16 nchan_full, /* i : new number of channels to fully store */
- const Word16 n_samples_granularity /* i : new granularity of the renderer/buffer */
+void ivas_dec_get_md_map_even_spacing_fx(
+ const Word16 len, /* i : length of the modified frames in metadata slots*/
+ const Word16 subframe_len, /* i : default length of a subframe */
+ const Word16 offset, /* i : current read offset into the MD buffer */
+ const Word16 buf_len, /* i : length of the metadata buffer */
+ Word16 *map /* o : metadata index map */
)
{
- Word16 ch_idx, num_tc_buffer_mem, n_samples_still_available;
- Word32 tc_buffer_mem[MAX_INTERN_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES - 1];
- ivas_error error;
- DECODER_TC_BUFFER_HANDLE hTcBuffer;
-
- hTcBuffer = st_ivas->hTcBuffer;
- move16();
-
- num_tc_buffer_mem = 0;
- move16();
- n_samples_still_available = 0;
- move16();
+ Word16 map_idx, sf_idx, sf_length, increment, subframes_written;
+ Word32 decimal_fx, decimal_sum_fx, eps_fx; // q = 16
+ Word16 subframe_map_length[MAX_PARAM_SPATIAL_SUBFRAMES];
- IF( st_ivas->hDecoderConfig->Opt_tsm )
+ /* subframe map length */
+ sf_length = idiv1616( len, subframe_len );
+ IF( len % subframe_len == 0 )
{
- /* save samples of the TC buffer from the previous frame */
- num_tc_buffer_mem = s_min( hTcBuffer->nchan_transport_internal, nchan_transport_internal );
- n_samples_still_available = sub( hTcBuffer->n_samples_buffered, hTcBuffer->n_samples_rendered );
-
- /* what is remaining from last frame needs always be smaller than the new granularity */
- assert( n_samples_still_available < n_samples_granularity );
-
- FOR( ch_idx = 0; ch_idx < num_tc_buffer_mem; ch_idx++ )
+ /* even subframes */
+ FOR( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ )
{
- Copy32( hTcBuffer->tc_buffer_old_fx[ch_idx] + hTcBuffer->n_samples_flushed, tc_buffer_mem[ch_idx], n_samples_still_available );
+ subframe_map_length[sf_idx] = sf_length;
+ move16();
}
}
-
- /* if granularity changes, adapt subframe_nb_slots */
- IF( NE_16( n_samples_granularity, hTcBuffer->n_samples_granularity ) )
+ ELSE
{
- Word16 nMaxSlotsPerSubframeNew;
- Word16 tmp, tmp_e;
-
- /* nMaxSlotsPerSubframeNew = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ) / n_samples_granularity; */
- tmp = extract_l( Mpy_32_16_1( st_ivas->hDecoderConfig->output_Fs, ONE_BY_SUBFR_PER_SEC_Q15 ) );
- tmp = BASOP_Util_Divide1616_Scale( tmp, n_samples_granularity, &tmp_e );
- nMaxSlotsPerSubframeNew = shr( tmp, sub( 15, tmp_e ) ); /* Q0 */
+ /* uneven subframes */
+ Word32 temp;
+ Word16 temp_e;
+ temp = BASOP_Util_Divide3232_Scale( L_shl( len, 16 ), subframe_len, &temp_e );
+ temp = L_shr( temp, sub( 15, temp_e ) ); // Q16
+ decimal_fx = L_sub( temp, L_shl( sf_length, 16 ) ); // Q16
+ decimal_sum_fx = decimal_fx;
- /* if samples were flushed, take that into account here */
- test();
- IF( LT_16( n_samples_granularity, hTcBuffer->n_samples_granularity ) && hTcBuffer->n_samples_flushed > 0 )
- {
- hTcBuffer->subframe_nbslots[hTcBuffer->subframes_rendered - 1] = idiv1616( hTcBuffer->n_samples_flushed, n_samples_granularity );
- hTcBuffer->n_samples_flushed = 0;
- move16();
- move16();
- }
- ELSE
+ eps_fx = 65;
+ move32();
+ move32();
+ FOR( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ )
{
- hTcBuffer->subframe_nbslots[hTcBuffer->subframes_rendered - 1] = nMaxSlotsPerSubframeNew;
+ increment = extract_l( L_shr( L_add( decimal_sum_fx, eps_fx ), 16 ) );
+ subframe_map_length[sf_idx] = add( sf_length, increment );
move16();
+ IF( increment > 0 )
+ {
+ decimal_sum_fx = L_sub( decimal_sum_fx, ONE_IN_Q16 );
+ }
+ decimal_sum_fx = L_add( decimal_sum_fx, decimal_fx );
}
}
- hTcBuffer->tc_buffer_mode = tc_buffer_mode;
- move16();
- hTcBuffer->nchan_transport_rend = nchan_transport_rend;
- move16();
- hTcBuffer->nchan_transport_internal = nchan_transport_internal;
- move16();
- hTcBuffer->nchan_buffer_full = nchan_full;
+ /* map slots to subframes */
+ sf_idx = 0;
+ subframes_written = 0;
move16();
- hTcBuffer->n_samples_granularity = n_samples_granularity;
move16();
+ FOR( map_idx = 0; map_idx < len; map_idx++ )
+ {
+ map[map_idx] = add( offset, sf_idx ) % buf_len;
+ move16();
+ IF( GE_16( sub( map_idx, subframes_written ), sub( subframe_map_length[sf_idx], 1 ) ) )
+ {
+ subframes_written = add( subframes_written, subframe_map_length[sf_idx] );
+ sf_idx = add( sf_idx, 1 );
+ }
+ }
+
+ return;
+}
- /* reallocate TC audio buffers */
- ivas_jbm_dec_tc_audio_deallocate_fx( hTcBuffer );
+/*--------------------------------------------------------------------------*
+ * ivas_dec_get_render_granularity()
+ *
+ * Get renderer granularity
+ *--------------------------------------------------------------------------*/
+
+/*! r: render granularity */
+Word16 ivas_dec_get_render_granularity_fx(
+ const RENDERER_TYPE renderer_type, /* i : renderer type */
+ const RENDERER_TYPE renderer_type_sec, /* i : secondary renderer type */
+ const Word32 output_Fs /* i : sampling rate */
+)
+{
+ Word16 render_granularity;
- IF( ( error = ivas_dec_tc_audio_allocate_fx( hTcBuffer, st_ivas->hDecoderConfig->output_Fs, st_ivas->hDecoderConfig->Opt_tsm ) ) != IVAS_ERR_OK )
+ test();
+ test();
+ test();
+ IF( EQ_32( renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) || /* TD renderer */
+ EQ_32( renderer_type, RENDERER_BINAURAL_MIXER_CONV ) || EQ_32( renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) || /* Crend */
+ EQ_32( renderer_type_sec, RENDERER_BINAURAL_OBJECTS_TD ) /* TD rend as a secondary renderer -> set the common granularity for both renderers */
+ )
{
- return error;
+ /* 5 ms granularity */
+ render_granularity = NS2SA_FX2( output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES );
+ move16();
}
-
- /* propagate samples of the TC buffer from the previous frame */
- FOR( ch_idx = 0; ch_idx < num_tc_buffer_mem; ch_idx++ )
+ ELSE
{
- Copy32( tc_buffer_mem[ch_idx], hTcBuffer->tc_buffer_old_fx[ch_idx], n_samples_still_available );
+ /* 1.25 ms granularity */
+ render_granularity = NS2SA_FX2( output_Fs, CLDFB_SLOT_NS );
+ move16();
}
- return IVAS_ERR_OK;
+ return render_granularity;
}
@@ -3103,28 +1705,6 @@ static void ivas_dec_tc_buffer_playout_fx(
}
-/*--------------------------------------------------------------------------*
- * ivas_dec_tc_buffer_close()
- *
- * Close transport channel buffer handle
- *--------------------------------------------------------------------------*/
-
-void ivas_dec_tc_buffer_close_fx(
- DECODER_TC_BUFFER_HANDLE *phTcBuffer /* i/o: TC buffer handle */
-)
-{
- IF( *phTcBuffer != NULL )
- {
- ivas_jbm_dec_tc_audio_deallocate_fx( *phTcBuffer );
-
- free( *phTcBuffer );
- *phTcBuffer = NULL;
- }
-
- return;
-}
-
-
/*--------------------------------------------------------------------------*
* ivas_dec_td_renderers_adapt_subframes()
*
@@ -3202,105 +1782,6 @@ void ivas_dec_td_renderers_adapt_subframes_fx(
}
-/*--------------------------------------------------------------------------*
- * ivas_dec_get_tc_buffer_mode()
- *
- *
- *--------------------------------------------------------------------------*/
-
-TC_BUFFER_MODE ivas_dec_get_tc_buffer_mode_fx(
- Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
-)
-{
- TC_BUFFER_MODE buffer_mode;
-
- buffer_mode = TC_BUFFER_MODE_BUFFER;
- move16();
-
- SWITCH( st_ivas->renderer_type )
- {
- /* all renderers where we are done after TC decoding (might include DMX to mono/stereo */
- case RENDERER_DISABLE:
- case RENDERER_MCMASA_MONO_STEREO:
- case RENDERER_OSBA_STEREO:
- case RENDERER_MONO_DOWNMIX:
- buffer_mode = TC_BUFFER_MODE_BUFFER;
- move16();
- BREAK;
- case RENDERER_NON_DIEGETIC_DOWNMIX:
- case RENDERER_TD_PANNING:
- case RENDERER_BINAURAL_OBJECTS_TD:
- case RENDERER_BINAURAL_FASTCONV:
- case RENDERER_BINAURAL_FASTCONV_ROOM:
- case RENDERER_BINAURAL_PARAMETRIC:
- case RENDERER_BINAURAL_PARAMETRIC_ROOM:
- case RENDERER_STEREO_PARAMETRIC:
- case RENDERER_DIRAC:
- case RENDERER_PARAM_ISM:
- case RENDERER_BINAURAL_MIXER_CONV:
- case RENDERER_BINAURAL_MIXER_CONV_ROOM:
- case RENDERER_OMASA_OBJECT_EXT:
- case RENDERER_OMASA_MIX_EXT:
- case RENDERER_OSBA_AMBI:
- case RENDERER_OSBA_LS:
- buffer_mode = TC_BUFFER_MODE_RENDERER;
- move16();
- BREAK;
- case RENDERER_MC_PARAMMC:
- IF( EQ_32( st_ivas->hParamMC->synthesis_conf, PARAM_MC_SYNTH_MONO_STEREO ) )
- {
- buffer_mode = TC_BUFFER_MODE_BUFFER; /* TCs are already the DMX to mono or stereo */
- move16();
- }
- ELSE
- {
- buffer_mode = TC_BUFFER_MODE_RENDERER;
- move16();
- }
- BREAK;
- case RENDERER_MC:
- if ( NE_16( ivas_dec_get_num_tc_channels_fx( st_ivas ), st_ivas->hDecoderConfig->nchan_out ) )
- {
- buffer_mode = TC_BUFFER_MODE_RENDERER;
- move16();
- }
- BREAK;
- case RENDERER_SBA_LINEAR_ENC:
- test();
- test();
- test();
- test();
- IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && EQ_32( st_ivas->mc_mode, MC_MODE_MCT ) && ( EQ_32( st_ivas->renderer_type, RENDERER_MC ) || EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ) && GE_16( ( add( st_ivas->hTransSetup.nchan_out_woLFE, st_ivas->hTransSetup.num_lfe ) ), ( add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ) ) ) )
- {
- buffer_mode = TC_BUFFER_MODE_BUFFER;
- move16();
- }
- ELSE
- {
- buffer_mode = TC_BUFFER_MODE_RENDERER;
- move16();
- }
- BREAK;
- case RENDERER_SBA_LINEAR_DEC:
- test();
- test();
- IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) && ( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) ) )
- {
- buffer_mode = TC_BUFFER_MODE_BUFFER;
- move16();
- }
- ELSE
- {
- buffer_mode = TC_BUFFER_MODE_RENDERER;
- move16();
- }
- BREAK;
- }
-
- return buffer_mode;
-}
-
-
/*--------------------------------------------------------------------------*
* ivas_jbm_dec_masa_metadata_open()
*