diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj
index 57b0ff748e7ffcdeced3fabcbcd323e4bb0c1a47..cc2f5b5b40c012651e340043296dd839aa9db577 100644
--- a/Workspace_msvc/lib_dec.vcxproj
+++ b/Workspace_msvc/lib_dec.vcxproj
@@ -210,6 +210,7 @@
+
@@ -219,7 +220,6 @@
-
diff --git a/Workspace_msvc/lib_dec.vcxproj.filters b/Workspace_msvc/lib_dec.vcxproj.filters
index 8eddbb60a098e2b807e849b7bc72e1fe003e8a53..9ca8447fb5d6e9be282bc4540f819572758cf7e5 100644
--- a/Workspace_msvc/lib_dec.vcxproj.filters
+++ b/Workspace_msvc/lib_dec.vcxproj.filters
@@ -4,9 +4,6 @@
decoder_ivas_c
-
- decoder_ivas_c
-
decoder_ivas_c
@@ -49,9 +46,6 @@
decoder_ivas_c
-
- decoder_ivas_c
-
decoder_ivas_c
@@ -515,6 +509,9 @@
decoder_all_c
+
+ decoder_ivas_c
+
diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c
index 4f49e0da13e79010e9eda33e997c53cb00b090e3..bebc8a6a420c0d8150ee24176f427b290f60969a 100644
--- a/lib_dec/ivas_dec.c
+++ b/lib_dec/ivas_dec.c
@@ -48,17 +48,1212 @@
/*--------------------------------------------------------------------------*
* ivas_dec()
*
- * Principal IVAS decoder routine
+ * Principal IVAS decoder routine, decoding of metadata and transport channels
*--------------------------------------------------------------------------*/
-ivas_error ivas_dec_tmp( // this will be removed in the following step
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
- int16_t *data /* o : output synthesis signal */
+ivas_error ivas_dec(
+ Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
)
{
- // TODO: move here function ivas_dec()
- st_ivas->ivas_format = UNDEFINED_FORMAT; // temp. to avoid compilation warnings
- data[0] = 0; // temp. to avoid compilation warnings
+ int16_t n, output_frame, nchan_out;
+ Decoder_State *st; /* used for bitstream handling */
+ float *p_output[MAX_TRANSPORT_CHANNELS]; /* 'float' buffer for output synthesis */
+ int16_t nchan_remapped;
+ int16_t nb_bits_metadata[MAX_SCE + 1];
+ int32_t output_Fs, ivas_total_brate;
+ AUDIO_CONFIG output_config;
+ ivas_error error;
+ int16_t num_md_sub_frames;
+ int32_t ism_total_brate;
+
+ push_wmops( "ivas_dec" );
+
+ /*----------------------------------------------------------------*
+ * Initialization of local vars after struct has been set
+ *----------------------------------------------------------------*/
+
+ output_Fs = st_ivas->hDecoderConfig->output_Fs;
+ nchan_out = st_ivas->hTcBuffer->nchan_transport_rend;
+ output_config = st_ivas->hDecoderConfig->output_config;
+ ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
+
+ output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC );
+
+ /* set pointers to transport channels audio */
+ for ( n = 0; n < MAX_TRANSPORT_CHANNELS; n++ )
+ {
+ p_output[n] = st_ivas->p_output_f[n];
+ if ( p_output[n] != NULL )
+ {
+ set_zero( p_output[n], L_FRAME48k );
+ }
+ }
+
+ /*----------------------------------------------------------------*
+ * Decoding + pre-rendering
+ *----------------------------------------------------------------*/
+
+ if ( st_ivas->ivas_format == STEREO_FORMAT )
+ {
+ st_ivas->hCPE[0]->element_brate = ivas_total_brate;
+ if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, 0 ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* HP filtering */
+ for ( n = 0; n < min( nchan_out, st_ivas->nchan_transport ); n++ )
+ {
+ hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs );
+ }
+ }
+ else if ( st_ivas->ivas_format == ISM_FORMAT )
+ {
+ /* Metadata decoding and configuration */
+ if ( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA )
+ {
+ ivas_ism_dtx_dec( st_ivas, nb_bits_metadata );
+
+ /* decode dominant object first so the noise energy of the other objects can be limited */
+ if ( ( error = ivas_sce_dec( st_ivas, st_ivas->hISMDTX.sce_id_dtx, &p_output[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( st_ivas->hSCE, st_ivas->hISMDTX.sce_id_dtx, st_ivas->nchan_transport );
+
+ ivas_param_ism_dec_dequant_md( st_ivas );
+ }
+ else if ( st_ivas->ism_mode == ISM_MODE_PARAM )
+ {
+ if ( ( error = ivas_ism_metadata_dec( 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( st_ivas );
+ }
+ else /* ISM_MODE_DISC */
+ {
+ if ( ( error = ivas_ism_metadata_dec( 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 */
+ if ( !( ( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) && n == st_ivas->hISMDTX.sce_id_dtx ) )
+ {
+ if ( ( error = ivas_sce_dec( st_ivas, n, &p_output[n], output_frame, nb_bits_metadata[n] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ /* HP filtering */
+ hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs );
+ }
+
+ if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX )
+ {
+ ivas_ism_mono_dmx( st_ivas, p_output, output_frame );
+ }
+ else if ( st_ivas->ism_mode == ISM_MODE_PARAM && ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) )
+ {
+ /* loudness correction */
+ ivas_dirac_dec_binaural_sba_gain( p_output, st_ivas->nchan_transport, output_frame );
+ }
+ }
+ else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT )
+ {
+ set_s( nb_bits_metadata, 0, MAX_SCE );
+
+ /* read parameters from the bitstream */
+ if ( 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 ( ( error = ivas_masa_decode( st_ivas, st, &nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else if ( st_ivas->ivas_format == SBA_FORMAT )
+ {
+ if ( ( error = ivas_spar_dec( st_ivas, nb_bits_metadata ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ if ( st_ivas->nchan_transport == CPE_CHANNELS && st_ivas->nCPE >= 1 )
+ {
+ st_ivas->hCPE[0]->brate_surplus = 0;
+ st_ivas->hCPE[0]->element_brate = ivas_total_brate;
+ }
+
+ /* core-decoding of transport channels */
+ if ( st_ivas->nSCE == 1 )
+ {
+ if ( ( error = ivas_sce_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else if ( st_ivas->nCPE == 1 )
+ {
+ if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else if ( st_ivas->nCPE > 1 )
+ {
+ if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+#ifdef DEBUG_SBA_AUDIO_DUMP
+ /* Dump audio signal after core-decoding */
+ ivas_spar_dump_signal_wav( output_frame, NULL, output, st_ivas->nchan_transport, spar_foa_dec_wav[0], "core-decoding" );
+#endif
+ /* TCs remapping */
+ nchan_remapped = st_ivas->nchan_transport;
+ if ( st_ivas->sba_dirac_stereo_flag )
+ {
+ nchan_remapped = nchan_out;
+
+ if ( st_ivas->ivas_format == SBA_FORMAT )
+ {
+ ivas_agc_dec_process( st_ivas->hSpar->hAgcDec, p_output, p_output, st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, output_frame );
+
+ if ( st_ivas->hSpar->hPCA != NULL )
+ {
+ ivas_pca_dec( 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 );
+ }
+
+ ivas_spar_dec_gen_umx_mat( 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( st_ivas, p_output, output_frame );
+ }
+ else if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && ( ivas_total_brate > IVAS_SID_5k2 || ( ivas_total_brate <= IVAS_SID_5k2 && st_ivas->nCPE > 0 && st_ivas->hCPE[0]->nchan_out == 1 ) ) )
+ {
+ nchan_remapped = 1; /* Only one channel transported */
+ }
+
+ /* HP filtering */
+#ifndef DEBUG_SPAR_BYPASS_EVS_CODEC
+ for ( n = 0; n < nchan_remapped; n++ )
+ {
+ hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs );
+ }
+#endif
+
+ if ( st_ivas->ivas_format == SBA_FORMAT )
+ {
+ nchan_remapped = ivas_sba_remapTCs( p_output, st_ivas, output_frame );
+
+ if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || 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 );
+ ivas_sba_mix_matrix_determiner( st_ivas->hSpar, p_output, st_ivas->bfi, nchan_remapped, output_frame, num_md_sub_frames );
+ }
+ else if ( st_ivas->renderer_type != RENDERER_DISABLE )
+ {
+ ivas_spar_dec_agc_pca( st_ivas, p_output, output_frame );
+ }
+ }
+
+ if ( st_ivas->ivas_format == MASA_FORMAT )
+ {
+ ivas_masa_prerender( st_ivas, p_output, output_frame, nchan_remapped );
+
+ /* external output */
+ if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL && st_ivas->hMasa->config.input_ivas_format == MASA_ISM_FORMAT )
+ {
+ for ( n = 0; n < st_ivas->nchan_ism; n++ )
+ {
+ set_zero( p_output[st_ivas->nchan_transport + n], output_frame );
+ }
+
+ ivas_omasa_rearrange_channels( p_output, st_ivas->nchan_ism, output_frame );
+ }
+ }
+ else if ( st_ivas->ivas_format == SBA_FORMAT && ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
+ {
+ /* loudness correction */
+ ivas_dirac_dec_binaural_sba_gain( p_output, nchan_remapped, output_frame );
+ }
+ }
+ else if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ int16_t nchan_ism, nchan_transport_ism;
+ int16_t dirac_bs_md_write_idx;
+
+ set_s( nb_bits_metadata, 0, MAX_SCE + 1 );
+
+ /* Set the number of objects for the parametric rendering */
+ dirac_bs_md_write_idx = 0;
+ if ( st_ivas->hSpatParamRendCom != NULL )
+ {
+ st_ivas->hSpatParamRendCom->numIsmDirections = 0;
+ if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ st_ivas->hSpatParamRendCom->numIsmDirections = st_ivas->nchan_ism;
+ }
+
+ dirac_bs_md_write_idx = st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx; /* Store the write-index for this frame */
+ }
+
+ /* MASA metadata decoding */
+ if ( ( error = ivas_masa_decode( 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 )] );
+
+ /* set ISM parameters and decode ISM metadata in OMASA format */
+ if ( ( error = ivas_omasa_ism_metadata_dec( st_ivas, ism_total_brate, &nchan_ism, &nchan_transport_ism, dirac_bs_md_write_idx, &nb_bits_metadata[1] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* decode ISM channels */
+ for ( n = 0; n < nchan_transport_ism; n++ )
+ {
+ if ( ( error = ivas_sce_dec( st_ivas, n, &p_output[st_ivas->nchan_transport + n], output_frame, nb_bits_metadata[1] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ /* decode MASA channels */
+ if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ if ( st_ivas->hCPE[0]->nchan_out == 1 )
+ {
+ mvr2r( p_output[0], p_output[1], output_frame ); /* Copy mono signal to stereo output channels */
+ }
+
+ /* HP filtering */
+ for ( n = 0; n < getNumChanSynthesis( st_ivas ); n++ )
+ {
+ hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs );
+ }
+
+ if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX )
+ {
+ ivas_ism_mono_dmx( st_ivas, p_output, output_frame );
+ }
+ else if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL )
+ {
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ ivas_omasa_rearrange_channels( p_output, nchan_transport_ism, output_frame );
+ }
+ else if ( 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( st_ivas, p_output, st_ivas->nchan_ism, output_frame );
+ }
+ else if ( 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( st_ivas, p_output, st_ivas->nchan_ism, output_frame );
+ }
+ }
+ }
+ else if ( st_ivas->ivas_format == SBA_ISM_FORMAT )
+ {
+ int16_t nchan_ism, sba_ch_idx;
+
+ set_s( nb_bits_metadata, 0, MAX_SCE + 1 );
+ nchan_ism = st_ivas->nchan_ism;
+ if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC )
+ {
+ /* set ISM parameters and decode ISM metadata in OSBA format */
+ if ( ( error = ivas_osba_ism_metadata_dec( st_ivas, ivas_total_brate, &nchan_ism, &nb_bits_metadata[1] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ sba_ch_idx = st_ivas->nchan_ism;
+ }
+ else
+ {
+ nb_bits_metadata[1] += NO_BITS_MASA_ISM_NO_OBJ;
+ sba_ch_idx = 0;
+ }
+
+ /* SBA metadata decoding */
+ if ( ( error = ivas_spar_dec( st_ivas, nb_bits_metadata ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ if ( st_ivas->nchan_transport == CPE_CHANNELS && st_ivas->nCPE >= 1 )
+ {
+ st_ivas->hCPE[0]->element_brate = ivas_total_brate;
+ }
+
+ /* core-decoding of transport channels */
+ if ( st_ivas->nSCE == 1 )
+ {
+ if ( ( error = ivas_sce_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else if ( st_ivas->nCPE == 1 )
+ {
+ if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else if ( st_ivas->nCPE > 1 )
+ {
+ if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ if ( st_ivas->sba_dirac_stereo_flag )
+ {
+ ivas_agc_dec_process( st_ivas->hSpar->hAgcDec, &p_output[sba_ch_idx], &p_output[sba_ch_idx], st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, output_frame );
+
+ if ( st_ivas->hSpar->hPCA != NULL )
+ {
+ ivas_pca_dec( 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[sba_ch_idx] );
+ }
+
+ ivas_spar_dec_gen_umx_mat( 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( st_ivas, &p_output[sba_ch_idx], output_frame );
+ }
+
+ /* HP filtering */
+ for ( n = 0; n < getNumChanSynthesis( st_ivas ); n++ )
+ {
+ hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs );
+ }
+
+ nchan_remapped = ivas_sba_remapTCs( &p_output[sba_ch_idx], st_ivas, output_frame );
+
+#ifdef DEBUG_OSBA
+ if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC )
+ {
+ int16_t nchan = st_ivas->nchan_transport + st_ivas->nchan_ism;
+ for ( int16_t t = 0; t < output_frame; t++ )
+ {
+ for ( int16_t c = 0; c < nchan; c++ )
+ {
+ int16_t val = (int16_t) ( output[c][t] + 0.5f );
+ dbgwrite( &val, sizeof( int16_t ), 1, 1, "./res/TC_dec_core_out.raw" );
+ }
+ }
+ }
+#endif
+ if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || 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 );
+
+ ivas_sba_mix_matrix_determiner( st_ivas->hSpar, &p_output[sba_ch_idx], st_ivas->bfi, nchan_remapped, output_frame, num_md_sub_frames );
+ }
+ else if ( st_ivas->renderer_type != RENDERER_DISABLE && !st_ivas->sba_dirac_stereo_flag )
+ {
+ ivas_spar_dec_agc_pca( st_ivas, &p_output[sba_ch_idx], output_frame );
+ }
+
+ if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM )
+ {
+ /* loudness correction */
+ ivas_dirac_dec_binaural_sba_gain( &p_output[sba_ch_idx], nchan_remapped, output_frame );
+ }
+ else if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX && st_ivas->ism_mode == ISM_SBA_MODE_DISC )
+ {
+ ivas_ism_mono_dmx( st_ivas, p_output, output_frame );
+
+ /* add W */
+ for ( n = 0; n < nchan_out; n++ )
+ {
+ v_add( p_output[n], p_output[n + max( nchan_out, nchan_ism )], p_output[n], output_frame );
+ }
+ }
+ }
+ else if ( st_ivas->ivas_format == MC_FORMAT )
+ {
+ st = ( st_ivas->nSCE > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0];
+
+ if ( st_ivas->mc_mode == MC_MODE_MCT )
+ {
+ /* LFE channel decoder */
+ ivas_lfe_dec( st_ivas->hLFE, st, output_frame, st_ivas->bfi, p_output[LFE_CHANNEL] );
+
+ if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, 0 ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* HP filtering */
+ for ( n = 0; n < st_ivas->nchan_transport; n++ )
+ {
+ if ( n != LFE_CHANNEL )
+ {
+ hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs );
+ }
+ }
+
+ if ( st_ivas->transport_config != st_ivas->intern_config && ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_FOA || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA2 || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA3 ) )
+ {
+ if ( ( st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe ) >= ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ) )
+ {
+ ivas_mc2sba( st_ivas->hTransSetup, p_output, p_output, output_frame, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE );
+ }
+ }
+
+ if ( ( st_ivas->renderer_type == RENDERER_MC || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) && ( st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe ) >= ( st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ) )
+ {
+ if ( st_ivas->renderer_type == RENDERER_MC )
+ {
+ ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, output_frame, p_output, p_output );
+ }
+ else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC )
+ {
+ ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, output_frame, st_ivas->hOutSetup.ambisonics_order, 0.f );
+ }
+ }
+ }
+ else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX )
+ {
+ /* LFE channel decoder */
+ ivas_lfe_dec( st_ivas->hLFE, st, output_frame, st_ivas->bfi, p_output[LFE_CHANNEL] );
+
+ ivas_mc_paramupmix_dec_read_BS( st_ivas, st, st_ivas->hMCParamUpmix, &nb_bits_metadata[0] );
+
+ if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* HP filtering */
+ for ( n = 0; n < st_ivas->nchan_transport; n++ )
+ {
+ if ( n != LFE_CHANNEL )
+ {
+ hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs );
+ }
+ }
+
+ /* Rendering */
+ if ( st_ivas->renderer_type == RENDERER_MC && ( output_config == IVAS_AUDIO_CONFIG_MONO || output_config == IVAS_AUDIO_CONFIG_STEREO ) )
+ {
+ /* Compensate loudness for not doing full upmix */
+ for ( n = 4; n < 8; n++ )
+ {
+ v_multc( p_output[n], 2.0f, p_output[n], output_frame );
+ }
+
+ if ( output_config == IVAS_AUDIO_CONFIG_MONO || output_config == IVAS_AUDIO_CONFIG_STEREO )
+ {
+ ivas_ls_setup_conversion( st_ivas, audioCfg2channels( IVAS_AUDIO_CONFIG_5_1_2 ), output_frame, p_output, p_output );
+ }
+ }
+ }
+ else if ( st_ivas->mc_mode == MC_MODE_PARAMMC )
+ {
+ /* read Parametric MC parameters from the bitstream */
+ ivas_param_mc_dec_read_BS( ivas_total_brate, st, st_ivas->hParamMC, &nb_bits_metadata[0] );
+
+ if ( st_ivas->nCPE == 1 )
+ {
+ if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else if ( st_ivas->nCPE > 1 )
+ {
+ if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ /* HP filtering */
+ for ( n = 0; n < st_ivas->nchan_transport; n++ )
+ {
+ hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs );
+ }
+
+ /* Rendering */
+ if ( output_config == IVAS_AUDIO_CONFIG_MONO || output_config == IVAS_AUDIO_CONFIG_STEREO )
+ {
+ ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, output_frame, p_output, p_output );
+ }
+ }
+ else if ( 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 ( ( error = ivas_masa_decode( st_ivas, st, &nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ if ( st_ivas->hOutSetup.separateChannelEnabled )
+ {
+ /* Decode the transport audio signals */
+ if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, 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;
+
+ /* Decode the separated channel to output[n] to be combined with the synthesized channels */
+ if ( ( error = ivas_sce_dec( st_ivas, 0, &p_output[n], output_frame, 0 ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* Delay the separated channel to sync with CLDFB delay of the DirAC synthesis, and synthesize the LFE signal. */
+ if ( output_config == IVAS_AUDIO_CONFIG_5_1 || output_config == IVAS_AUDIO_CONFIG_7_1 ||
+ output_config == IVAS_AUDIO_CONFIG_5_1_4 || output_config == IVAS_AUDIO_CONFIG_7_1_4 ||
+ output_config == IVAS_AUDIO_CONFIG_5_1_2 || ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe > 0 ) || output_config == IVAS_AUDIO_CONFIG_EXTERNAL )
+ {
+ ivas_lfe_synth_with_filters( st_ivas->hMasa->hMasaLfeSynth, p_output, output_frame, n, LFE_CHANNEL );
+ }
+ else if ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe == 0 )
+ {
+ /* Delay the separated channel to sync with the DirAC rendering */
+ delay_signal( p_output[n], output_frame, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_size );
+ }
+ }
+ else
+ {
+ if ( st_ivas->nSCE == 1 )
+ {
+ if ( ( error = ivas_sce_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else if ( st_ivas->nCPE == 1 )
+ {
+ if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ }
+
+ if ( st_ivas->sba_dirac_stereo_flag ) /* use the flag to trigger the DFT upmix */
+ {
+ ivas_sba_dirac_stereo_dec( st_ivas, p_output, output_frame );
+ }
+
+ /* HP filtering */
+ for ( n = 0; n < getNumChanSynthesis( st_ivas ); n++ )
+ {
+ hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs );
+ }
+
+ if ( st_ivas->renderer_type == RENDERER_MCMASA_MONO_STEREO )
+ {
+ ivas_mono_stereo_downmix_mcmasa( st_ivas, p_output, 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;
+ st_ivas->last_active_ivas_total_brate = ( ivas_total_brate <= IVAS_SID_5k2 ) ? st_ivas->last_active_ivas_total_brate : ivas_total_brate;
+ }
+
+ if ( 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++;
+ }
+
+ if ( st_ivas->ini_active_frame < MAX_FRAME_COUNTER && !( st_ivas->bfi && st_ivas->ini_frame == 0 ) && 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++;
+ }
+
+ st_ivas->last_ivas_format = st_ivas->ivas_format;
+
+#ifdef DEBUG_MODE_INFO
+ dbgwrite( &st_ivas->bfi, sizeof( int16_t ), 1, output_frame, "res/bfi" );
+ dbgwrite( &st_ivas->BER_detect, sizeof( int16_t ), 1, output_frame, "res/BER_detect" );
+ {
+ float tmpF = ivas_total_brate / 1000.0f;
+ dbgwrite( &tmpF, sizeof( float ), 1, output_frame, "res/ivas_total_brate.dec" );
+ }
+#endif
+
+ pop_wmops();
+ return IVAS_ERR_OK;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_dec_get_num_tc_channels()
+ *
+ * Get the number of channels provided to the renderer
+ *--------------------------------------------------------------------------*/
+
+int16_t ivas_dec_get_num_tc_channels(
+ Decoder_Struct *st_ivas /* i : IVAS decoder handle */
+)
+{
+ int16_t num_tc;
+ int32_t ivas_total_brate;
+ AUDIO_CONFIG output_config;
+
+ if ( st_ivas->renderer_type == RENDERER_DISABLE )
+ {
+ num_tc = st_ivas->hDecoderConfig->nchan_out;
+ }
+ else
+ {
+ num_tc = st_ivas->nchan_transport;
+ }
+
+ output_config = st_ivas->hDecoderConfig->output_config;
+
+ ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
+
+ if ( st_ivas->ivas_format == MONO_FORMAT )
+ {
+ num_tc = 1;
+ }
+ else if ( st_ivas->ivas_format == STEREO_FORMAT && st_ivas->hDecoderConfig->nchan_out == 1 )
+ {
+ num_tc = 1;
+ }
+ else if ( st_ivas->ivas_format == ISM_FORMAT )
+ {
+ if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX )
+ {
+ num_tc = 1;
+ }
+ }
+ else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT )
+ {
+ if ( st_ivas->sba_dirac_stereo_flag )
+ {
+ num_tc = CPE_CHANNELS;
+ }
+ else if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && ( ivas_total_brate > IVAS_SID_5k2 || ( ivas_total_brate <= IVAS_SID_5k2 && st_ivas->nCPE > 0 && st_ivas->hCPE[0] != NULL && st_ivas->hCPE[0]->nchan_out == 1 ) ) )
+ {
+ num_tc = 1; /* Only one channel transported */
+ }
+
+ if ( st_ivas->ivas_format == MASA_FORMAT && output_config == IVAS_AUDIO_CONFIG_EXTERNAL && st_ivas->nchan_transport == 2 && ivas_total_brate < MASA_STEREO_MIN_BITRATE && ivas_total_brate > IVAS_SID_5k2 )
+ {
+ num_tc = CPE_CHANNELS;
+ }
+
+ if ( st_ivas->ivas_format == SBA_FORMAT )
+ {
+ if ( num_tc == 3 )
+ {
+ num_tc++;
+ }
+ }
+ }
+ else if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ if ( output_config != IVAS_AUDIO_CONFIG_EXTERNAL )
+ {
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
+ {
+ num_tc++;
+ }
+ else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ num_tc += st_ivas->nchan_ism;
+ }
+ }
+ }
+ else if ( st_ivas->ivas_format == SBA_ISM_FORMAT )
+ {
+ if ( st_ivas->sba_dirac_stereo_flag )
+ {
+ num_tc = CPE_CHANNELS;
+ }
+ if ( num_tc == 3 )
+ {
+ num_tc++;
+ }
+ if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC )
+ {
+ num_tc += st_ivas->nchan_ism;
+ }
+ }
+ else if ( st_ivas->ivas_format == MC_FORMAT )
+ {
+ if ( output_config == IVAS_AUDIO_CONFIG_MONO )
+ {
+ num_tc = 1;
+ }
+ else if ( output_config == IVAS_AUDIO_CONFIG_STEREO )
+ {
+ num_tc = 2;
+ }
+ else if ( st_ivas->mc_mode == MC_MODE_MCT )
+ {
+ /* do all static dmx already in the TC decoder if less channels than transported... */
+ if ( st_ivas->transport_config != st_ivas->intern_config && ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_FOA || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA2 || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA3 ) )
+ {
+ if ( ( st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe ) >= ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ) )
+ {
+ num_tc = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe;
+ }
+ }
+ else if ( ( st_ivas->renderer_type == RENDERER_MC || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) && ( st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe ) >= ( st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ) )
+ {
+ num_tc = st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe;
+ }
+ }
+ else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX )
+ {
+ num_tc = MC_PARAMUPMIX_MAX_TRANSPORT_CHANS;
+ }
+ else if ( st_ivas->mc_mode == MC_MODE_MCMASA )
+ {
+ if ( st_ivas->hOutSetup.separateChannelEnabled )
+ {
+ num_tc++;
+ }
+
+ if ( st_ivas->hOutSetup.separateChannelEnabled && ( output_config == IVAS_AUDIO_CONFIG_5_1 || output_config == IVAS_AUDIO_CONFIG_7_1 ||
+ output_config == IVAS_AUDIO_CONFIG_5_1_4 || output_config == IVAS_AUDIO_CONFIG_7_1_4 ||
+ output_config == IVAS_AUDIO_CONFIG_5_1_2 || ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe > 0 ) ) )
+ {
+ /* LFE is synthesized in TD with the TCs */
+ num_tc++;
+ }
+ }
+ }
+
+ return num_tc;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_dec_get_tc_buffer_mode()
+ *
+ *
+ *--------------------------------------------------------------------------*/
+
+TC_BUFFER_MODE ivas_dec_get_tc_buffer_mode(
+ Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
+)
+{
+ TC_BUFFER_MODE buffer_mode;
+
+ buffer_mode = TC_BUFFER_MODE_BUFFER;
+
+ 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;
+ 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;
+ break;
+ break;
+ case RENDERER_MC_PARAMMC:
+ if ( 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 */
+ }
+ else
+ {
+ buffer_mode = TC_BUFFER_MODE_RENDERER;
+ }
+ break;
+ case RENDERER_MC:
+ if ( ivas_dec_get_num_tc_channels( st_ivas ) != st_ivas->hDecoderConfig->nchan_out )
+ {
+ buffer_mode = TC_BUFFER_MODE_RENDERER;
+ }
+ break;
+ case RENDERER_SBA_LINEAR_ENC:
+ if ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCT && ( st_ivas->renderer_type == RENDERER_MC || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) && ( st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe ) >= ( st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ) )
+ {
+ buffer_mode = TC_BUFFER_MODE_BUFFER;
+ }
+ else
+ {
+ buffer_mode = TC_BUFFER_MODE_RENDERER;
+ }
+ break;
+ case RENDERER_SBA_LINEAR_DEC:
+ if ( st_ivas->ivas_format == SBA_FORMAT && ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_MONO || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO ) )
+ {
+ buffer_mode = TC_BUFFER_MODE_BUFFER;
+ }
+ else
+ {
+ buffer_mode = TC_BUFFER_MODE_RENDERER;
+ }
+ break;
+#ifdef DEBUGGING
+ default:
+ assert( 0 );
+#endif
+ }
+
+ return buffer_mode;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_dec_tc_audio_allocate()
+ *
+ * allocate and initialize TC audio buffer
+ *--------------------------------------------------------------------------*/
+
+static ivas_error ivas_dec_tc_audio_allocate(
+ DECODER_TC_BUFFER_HANDLE hTcBuffer, /* i/o: TC buffer handle */
+ const int32_t output_Fs, /* i : output sampling rate */
+ const int16_t Opt_tsm /* i : TSM option flag */
+)
+{
+ int16_t nsamp_to_allocate;
+ int16_t ch_idx, n_samp_full, n_samp_residual, offset;
+
+ if ( Opt_tsm )
+ {
+ n_samp_full = ( NS2SA( output_Fs, MAX_JBM_L_FRAME_NS ) );
+ n_samp_full = max( n_samp_full, L_FRAME48k ); /* buffers are shared between 'hTcBuffer->tc[]' and 'p_output_f[]': ensure minimal length */
+ n_samp_residual = hTcBuffer->n_samples_granularity - 1;
+ }
+ else
+ {
+ n_samp_full = (int16_t) ( output_Fs / FRAMES_PER_SEC );
+ n_samp_residual = 0;
+ }
+
+ nsamp_to_allocate = 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 = (float *) malloc( nsamp_to_allocate * sizeof( float ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TC Buffer\n" ) );
+ }
+ set_zero( hTcBuffer->tc_buffer, nsamp_to_allocate );
+
+ offset = 0;
+ for ( ch_idx = 0; ch_idx < max( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full ); ch_idx++ )
+ {
+ hTcBuffer->tc[ch_idx] = &hTcBuffer->tc_buffer[offset];
+ offset += n_samp_full;
+ }
+ for ( ; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
+ {
+ hTcBuffer->tc[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[ch_idx] = (float *) malloc( n_samp_residual * sizeof( float ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TC Buffer\n" ) );
+ }
+ set_zero( hTcBuffer->tc_buffer_old[ch_idx], n_samp_residual );
+ }
+ for ( ; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
+ {
+ hTcBuffer->tc_buffer_old[ch_idx] = NULL;
+ }
+ }
+ else
+ {
+ hTcBuffer->tc_buffer = NULL;
+
+ for ( ch_idx = 0; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
+ {
+ hTcBuffer->tc[ch_idx] = NULL;
+ }
+
+ for ( ch_idx = 0; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
+ {
+ hTcBuffer->tc_buffer_old[ch_idx] = NULL;
+ }
+ }
+
+ hTcBuffer->tc_buffer2 = NULL;
+
+ return IVAS_ERR_OK;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_dec_tc_buffer_open()
+ *
+ * Open and initialize transport channel buffer handle
+ *--------------------------------------------------------------------------*/
+
+ivas_error ivas_dec_tc_buffer_open(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ const TC_BUFFER_MODE tc_buffer_mode, /* i : buffer mode */
+ const int16_t nchan_transport_rend, /* i : number of TCs for rendering */
+ const int16_t nchan_transport_internal, /* i : number of totally buffered channels */
+ const int16_t nchan_full, /* i : number of channels to fully store */
+ const int16_t n_samples_granularity /* i : granularity of the renderer/buffer */
+)
+{
+ DECODER_TC_BUFFER_HANDLE hTcBuffer;
+ int16_t nMaxSlotsPerSubframe;
+ ivas_error error;
+
+ /*-----------------------------------------------------------------*
+ * 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;
+ hTcBuffer->nchan_transport_rend = nchan_transport_rend;
+ hTcBuffer->nchan_transport_internal = nchan_transport_internal;
+ hTcBuffer->nchan_buffer_full = nchan_full;
+ hTcBuffer->n_samples_granularity = n_samples_granularity;
+ hTcBuffer->n_samples_available = 0;
+ hTcBuffer->n_samples_buffered = 0;
+ hTcBuffer->n_samples_rendered = 0;
+ hTcBuffer->slots_rendered = 0;
+ hTcBuffer->subframes_rendered = 0;
+ hTcBuffer->n_samples_discard = 0;
+ hTcBuffer->n_samples_flushed = 0;
+ hTcBuffer->nb_subframes = MAX_PARAM_SPATIAL_SUBFRAMES;
+
+ nMaxSlotsPerSubframe = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ) / hTcBuffer->n_samples_granularity;
+ hTcBuffer->num_slots = nMaxSlotsPerSubframe * MAX_PARAM_SPATIAL_SUBFRAMES;
+ set_s( hTcBuffer->subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS );
+ set_s( hTcBuffer->subframe_nbslots, nMaxSlotsPerSubframe, MAX_PARAM_SPATIAL_SUBFRAMES );
+
+ if ( ( error = ivas_dec_tc_audio_allocate( 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_dec_tc_audio_deallocate()
+ *
+ * deallocate TC audio buffer
+ *--------------------------------------------------------------------------*/
+
+static void ivas_dec_tc_audio_deallocate(
+ DECODER_TC_BUFFER_HANDLE hTcBuffer /* i/o: TC buffer handle */
+)
+{
+ int16_t ch_idx;
+
+ if ( hTcBuffer != NULL )
+ {
+ if ( hTcBuffer->tc_buffer != NULL )
+ {
+ for ( ch_idx = 0; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
+ {
+ hTcBuffer->tc[ch_idx] = NULL;
+ }
+
+ free( hTcBuffer->tc_buffer );
+ hTcBuffer->tc_buffer = NULL;
+ }
+
+ for ( ch_idx = 0; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
+ {
+ if ( hTcBuffer->tc_buffer_old[ch_idx] != NULL )
+ {
+ free( hTcBuffer->tc_buffer_old[ch_idx] );
+ hTcBuffer->tc_buffer_old[ch_idx] = NULL;
+ }
+ }
+
+ if ( hTcBuffer->tc_buffer2 != NULL )
+ {
+ free( hTcBuffer->tc_buffer2 );
+ hTcBuffer->tc_buffer2 = NULL;
+ }
+ }
+
+ return;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_dec_tc_buffer_close()
+ *
+ * Close transport channel buffer handle
+ *--------------------------------------------------------------------------*/
+
+void ivas_dec_tc_buffer_close(
+ DECODER_TC_BUFFER_HANDLE *phTcBuffer /* i/o: TC buffer handle */
+)
+{
+ if ( *phTcBuffer != NULL )
+ {
+ ivas_dec_tc_audio_deallocate( *phTcBuffer );
+
+ free( *phTcBuffer );
+ *phTcBuffer = NULL;
+ }
+
+ return;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_dec_tc_buffer_reconfigure()
+ *
+ * Reconfigure transport channel buffer handle
+ *--------------------------------------------------------------------------*/
+
+ivas_error ivas_dec_tc_buffer_reconfigure(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ const TC_BUFFER_MODE tc_buffer_mode, /* i : new buffer mode */
+ const int16_t nchan_transport_rend, /* i : new number of TCs for rendering */
+ const int16_t nchan_transport_internal, /* i : new number of totally buffered channels */
+ const int16_t nchan_full, /* i : new number of channels to fully store */
+ const int16_t n_samples_granularity /* i : new granularity of the renderer/buffer */
+)
+{
+ int16_t ch_idx, num_tc_buffer_mem, n_samples_still_available;
+ float 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;
+
+ num_tc_buffer_mem = 0;
+ n_samples_still_available = 0;
+
+ if ( st_ivas->hDecoderConfig->Opt_tsm )
+ {
+ /* save samples of the TC buffer from the previous frame */
+ num_tc_buffer_mem = min( hTcBuffer->nchan_transport_internal, nchan_transport_internal );
+ n_samples_still_available = 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++ )
+ {
+ mvr2r( hTcBuffer->tc_buffer_old[ch_idx] + hTcBuffer->n_samples_flushed, tc_buffer_mem[ch_idx], n_samples_still_available );
+ }
+ }
+
+ /* if granularity changes, adapt subframe_nb_slots */
+ if ( n_samples_granularity != hTcBuffer->n_samples_granularity )
+ {
+#ifdef DEBUGGING
+ int16_t nMaxSlotsPerSubframeOld;
+#endif
+ int16_t nMaxSlotsPerSubframeNew;
+
+ nMaxSlotsPerSubframeNew = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ) / n_samples_granularity;
+#ifdef DEBUGGING
+ nMaxSlotsPerSubframeOld = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ) / st_ivas->hTcBuffer->n_samples_granularity;
+ assert( hTcBuffer->subframe_nbslots[hTcBuffer->subframes_rendered - 1] == nMaxSlotsPerSubframeOld );
+ if ( n_samples_granularity < hTcBuffer->n_samples_granularity )
+ {
+ assert( ( hTcBuffer->n_samples_granularity % n_samples_granularity ) == 0 );
+ }
+ else
+ {
+ assert( ( n_samples_granularity % hTcBuffer->n_samples_granularity ) == 0 );
+ }
+#endif
+ /* if samples were flushed, take that into account here */
+ if ( n_samples_granularity < hTcBuffer->n_samples_granularity && hTcBuffer->n_samples_flushed > 0 )
+ {
+ hTcBuffer->subframe_nbslots[hTcBuffer->subframes_rendered - 1] = hTcBuffer->n_samples_flushed / n_samples_granularity;
+ hTcBuffer->n_samples_flushed = 0;
+ }
+ else
+ {
+ hTcBuffer->subframe_nbslots[hTcBuffer->subframes_rendered - 1] = nMaxSlotsPerSubframeNew;
+ }
+ }
+
+ hTcBuffer->tc_buffer_mode = tc_buffer_mode;
+ hTcBuffer->nchan_transport_rend = nchan_transport_rend;
+ hTcBuffer->nchan_transport_internal = nchan_transport_internal;
+ hTcBuffer->nchan_buffer_full = nchan_full;
+ hTcBuffer->n_samples_granularity = n_samples_granularity;
+
+ /* reallocate TC audio buffers */
+
+ ivas_dec_tc_audio_deallocate( hTcBuffer );
+
+ if ( ( error = ivas_dec_tc_audio_allocate( 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++ )
+ {
+ mvr2r( tc_buffer_mem[ch_idx], hTcBuffer->tc_buffer_old[ch_idx], n_samples_still_available );
+ }
return IVAS_ERR_OK;
}
diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_dec_render.c
similarity index 61%
rename from lib_dec/ivas_jbm_dec.c
rename to lib_dec/ivas_dec_render.c
index 7daf20ab32d05c1e4e615e0e13d0bbecf59912c6..6806700255b60cfcecb539bc0788058d39bfb8ac 100644
--- a/lib_dec/ivas_jbm_dec.c
+++ b/lib_dec/ivas_dec_render.c
@@ -59,673 +59,631 @@ static void ivas_jbm_masa_sf_to_slot_map( Decoder_Struct *st_ivas, const int16_t
/*--------------------------------------------------------------------------*
- * ivas_dec()
+ * 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(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ const int16_t nSamplesForRendering, /* i : number of TC samples available for rendering */
+ int16_t *nSamplesResidual /* o : number of samples not fitting into the renderer grid and buffer for the next call*/
+)
+{
+ float tmp_buf[MAX_JBM_L_FRAME48k];
+ float *p_data_f[FOA_CHANNELS + MAX_NUM_OBJECTS];
+ int16_t n, n_render_timeslots, n_ch_cldfb;
+ int16_t ch, offset, len_offset;
+ DECODER_TC_BUFFER_HANDLE hTcBuffer;
+
+ hTcBuffer = st_ivas->hTcBuffer;
+ n_ch_cldfb = hTcBuffer->nchan_transport_rend - hTcBuffer->nchan_buffer_full;
+
+ if ( st_ivas->hDecoderConfig->Opt_tsm )
+ {
+ int16_t n_samples_still_available;
+ int16_t n_ch_full_copy, n_ch_res_copy;
+
+ n_samples_still_available = hTcBuffer->n_samples_buffered - hTcBuffer->n_samples_rendered;
+ hTcBuffer->n_samples_buffered = n_samples_still_available + nSamplesForRendering + hTcBuffer->n_samples_discard;
+ hTcBuffer->n_samples_available = hTcBuffer->n_samples_granularity * ( hTcBuffer->n_samples_buffered / hTcBuffer->n_samples_granularity );
+ *nSamplesResidual = hTcBuffer->n_samples_buffered - hTcBuffer->n_samples_available;
+ n_ch_full_copy = min( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full );
+ n_ch_res_copy = 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( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS );
+ if ( len_offset < L_FRAME48k )
+ {
+ offset = 0;
+ for ( ch = 0; ch < max( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full ); ch++ )
+ {
+ hTcBuffer->tc[ch] = &hTcBuffer->tc_buffer[offset];
+ st_ivas->p_output_f[ch] = hTcBuffer->tc[ch];
+ offset += len_offset;
+ }
+ }
+
+ for ( ch = 0; ch < n_ch_full_copy; ch++ )
+ {
+ mvr2r( hTcBuffer->tc[ch], tmp_buf, nSamplesForRendering );
+ set_zero( hTcBuffer->tc[ch], hTcBuffer->n_samples_discard );
+ mvr2r( hTcBuffer->tc_buffer_old[ch], hTcBuffer->tc[ch] + hTcBuffer->n_samples_discard, n_samples_still_available );
+ mvr2r( tmp_buf, hTcBuffer->tc[ch] + n_samples_still_available + hTcBuffer->n_samples_discard, nSamplesForRendering - *nSamplesResidual );
+ mvr2r( tmp_buf + nSamplesForRendering - *nSamplesResidual, hTcBuffer->tc_buffer_old[ch], *nSamplesResidual );
+ }
+
+ if ( n_ch_res_copy > 0 )
+ {
+ for ( ; ch < hTcBuffer->nchan_transport_rend; ch++ )
+ {
+ p_data_f[ch] = hTcBuffer->tc[ch];
+ mvr2r( hTcBuffer->tc[ch], tmp_buf, nSamplesForRendering );
+ mvr2r( hTcBuffer->tc_buffer_old[ch], p_data_f[ch], n_samples_still_available );
+ mvr2r( tmp_buf, p_data_f[ch] + n_samples_still_available, nSamplesForRendering - *nSamplesResidual );
+ mvr2r( tmp_buf + nSamplesForRendering - *nSamplesResidual, hTcBuffer->tc_buffer_old[ch], *nSamplesResidual );
+ }
+ }
+
+ n_render_timeslots = hTcBuffer->n_samples_available / hTcBuffer->n_samples_granularity;
+ }
+ else
+ {
+ for ( n = 0; n < n_ch_cldfb; n++ )
+ {
+ p_data_f[n] = &st_ivas->p_output_f[n][0];
+ }
+
+ ch = max( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full );
+ for ( n = 0; n < ch; n++ )
+ {
+ hTcBuffer->tc[n] = st_ivas->p_output_f[n]; /* note: buffers needed in the TD decorellator */
+ }
+
+ hTcBuffer->n_samples_buffered = nSamplesForRendering;
+ hTcBuffer->n_samples_available = hTcBuffer->n_samples_buffered;
+ *nSamplesResidual = 0;
+
+ n_render_timeslots = DEFAULT_JBM_CLDFB_TIMESLOTS;
+ }
+
+ /* CLDFB analysis for ParamMC/ParamISM */
+ if ( st_ivas->ivas_format == ISM_FORMAT && st_ivas->ism_mode == ISM_MODE_PARAM && ( st_ivas->renderer_type == RENDERER_PARAM_ISM || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) )
+ {
+ ivas_param_ism_dec_digest_tc( st_ivas, n_render_timeslots, p_data_f );
+ }
+ else if ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_PARAMMC && hTcBuffer->tc_buffer_mode == TC_BUFFER_MODE_RENDERER )
+ {
+ ivas_param_mc_dec_digest_tc( st_ivas, (uint8_t) n_render_timeslots, p_data_f );
+ }
+
+ hTcBuffer->n_samples_rendered = 0;
+ hTcBuffer->subframes_rendered = 0;
+
+ return;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_dec_render()
*
- * Principal IVAS decoder routine, decoding of metadata and transport channels
+ * Principal IVAS internal rendering routine
*--------------------------------------------------------------------------*/
-ivas_error ivas_dec(
- Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
+ivas_error ivas_dec_render(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ const uint16_t nSamplesAsked, /* i : number of samples wanted */
+ uint16_t *nSamplesRendered, /* o : number of samples rendered */
+ uint16_t *nSamplesAvailableNext, /* o : number of samples still available in the rendering pipeline */
+ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */
+ void *data /* o : output synthesis signal */
)
{
- int16_t n, output_frame, nchan_out;
- Decoder_State *st; /* used for bitstream handling */
- float *p_output[MAX_TRANSPORT_CHANNELS]; /* 'float' buffer for output synthesis */
+ int16_t n, nchan_out;
+ int16_t nchan_transport_rend;
int16_t nchan_remapped;
- int16_t nb_bits_metadata[MAX_SCE + 1];
- int32_t output_Fs, ivas_total_brate;
+ int32_t output_Fs;
AUDIO_CONFIG output_config;
+ int16_t nSamplesAskedLocal;
ivas_error error;
- int16_t num_md_sub_frames;
- int32_t ism_total_brate;
-
- push_wmops( "ivas_dec" );
+ float *p_output[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS];
+ float *p_tc[MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS];
+ int16_t 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;
- nchan_out = st_ivas->hTcBuffer->nchan_transport_rend;
+ nchan_out = st_ivas->hDecoderConfig->nchan_out;
+ nchan_transport_rend = st_ivas->hTcBuffer->nchan_transport_rend;
output_config = st_ivas->hDecoderConfig->output_config;
- ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
-
- output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC );
+ nSamplesAskedLocal = nSamplesAsked + st_ivas->hTcBuffer->n_samples_discard;
- /* 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[n] = st_ivas->p_output_f[n];
- if ( p_output[n] != NULL )
+ }
+
+ if ( !st_ivas->hDecoderConfig->Opt_tsm )
+ {
+ for ( n = 0; n < MAX_INTERN_CHANNELS; n++ )
{
- set_zero( p_output[n], L_FRAME48k );
+ st_ivas->hTcBuffer->tc[n] = p_output[n];
}
}
+ for ( n = 0; n < st_ivas->hTcBuffer->nchan_buffer_full; n++ )
+ {
+ p_tc[n] = &st_ivas->hTcBuffer->tc[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 -= st_ivas->hTcBuffer->n_samples_discard;
+
+ ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData );
+ }
+
/*----------------------------------------------------------------*
- * Decoding + pre-rendering
+ * Rendering
*----------------------------------------------------------------*/
- if ( st_ivas->ivas_format == STEREO_FORMAT )
+ *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal );
+
+ if ( st_ivas->ivas_format == UNDEFINED_FORMAT )
+ {
+ assert( 0 );
+ }
+ else if ( st_ivas->hTcBuffer->tc_buffer_mode == TC_BUFFER_MODE_BUFFER )
+ {
+ ivas_dec_tc_buffer_playout( st_ivas, nSamplesAskedLocal, nSamplesRendered, p_output );
+ }
+ else if ( st_ivas->ivas_format == MONO_FORMAT || st_ivas->ivas_format == STEREO_FORMAT )
{
- st_ivas->hCPE[0]->element_brate = ivas_total_brate;
- if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, 0 ) ) != IVAS_ERR_OK )
+ /* Rendering */
+ if ( st_ivas->renderer_type == RENDERER_MC )
{
- return error;
+ ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, *nSamplesRendered, p_tc, p_output );
}
-
- /* HP filtering */
- for ( n = 0; n < min( nchan_out, st_ivas->nchan_transport ); n++ )
+ else if ( st_ivas->renderer_type == RENDERER_NON_DIEGETIC_DOWNMIX )
+ {
+ ivas_apply_non_diegetic_panning( p_tc[0], p_output, st_ivas->hDecoderConfig->non_diegetic_pan_gain, *nSamplesRendered );
+ }
+ else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC )
{
- hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs );
+ ivas_stereo2sba( p_tc, p_output, *nSamplesRendered );
}
}
else if ( st_ivas->ivas_format == ISM_FORMAT )
{
- /* Metadata decoding and configuration */
- if ( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA )
+ /* Rendering */
+ if ( st_ivas->ism_mode == ISM_MODE_PARAM )
{
- ivas_ism_dtx_dec( st_ivas, nb_bits_metadata );
-
- /* decode dominant object first so the noise energy of the other objects can be limited */
- if ( ( error = ivas_sce_dec( st_ivas, st_ivas->hISMDTX.sce_id_dtx, &p_output[st_ivas->hISMDTX.sce_id_dtx], output_frame, nb_bits_metadata[st_ivas->hISMDTX.sce_id_dtx] ) ) != IVAS_ERR_OK )
+ if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC )
{
- return error;
+ ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, st_ivas->nchan_transport, p_output );
}
-
- ivas_ism_dtx_limit_noise_energy_for_near_silence( st_ivas->hSCE, st_ivas->hISMDTX.sce_id_dtx, st_ivas->nchan_transport );
-
- ivas_param_ism_dec_dequant_md( st_ivas );
- }
- else if ( st_ivas->ism_mode == ISM_MODE_PARAM )
- {
- if ( ( error = ivas_ism_metadata_dec( 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 )
+ else if ( st_ivas->renderer_type == RENDERER_PARAM_ISM || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC )
{
- return error;
- }
+ ivas_param_ism_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output );
- ivas_param_ism_dec_dequant_md( st_ivas );
+ if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC )
+ {
+ /* Convert CICP19 -> Ambisonics */
+ ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f );
+ }
+ }
}
else /* ISM_MODE_DISC */
{
- if ( ( error = ivas_ism_metadata_dec( 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 )
+ /* Loudspeaker or Ambisonics rendering */
+ if ( st_ivas->renderer_type == RENDERER_TD_PANNING || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM )
{
- return error;
+ /* Convert to CICPxx; used also for ISM->CICP19->binaural_room rendering */
+ ivas_ism_render_sf( st_ivas, st_ivas->renderer_type, p_output, *nSamplesRendered );
+ }
+ else if ( st_ivas->renderer_type == RENDERER_NON_DIEGETIC_DOWNMIX )
+ {
+ ivas_apply_non_diegetic_panning( p_tc[0], p_output, st_ivas->hDecoderConfig->non_diegetic_pan_gain, *nSamplesRendered );
+ }
+#ifdef DEBUGGING
+ else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV )
+#else
+ else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC )
+#endif
+ {
+ /* Convert to Ambisonics */
+ ivas_ism2sba_sf( p_tc, p_output, st_ivas->hIsmRendererData, st_ivas->nchan_transport, *nSamplesRendered, st_ivas->hTcBuffer->n_samples_rendered, st_ivas->hIntSetup.ambisonics_order );
}
- }
- for ( n = 0; n < st_ivas->nchan_transport; n++ )
- {
- /* for DTX frames, dominant object has already been decoded before */
- if ( !( ( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) && n == st_ivas->hISMDTX.sce_id_dtx ) )
+ /* Binaural rendering */
+ if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD )
+ {
+ if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+ {
+ if ( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else
+ {
+ if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ }
+ else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM )
{
- if ( ( error = ivas_sce_dec( st_ivas, n, &p_output[n], output_frame, nb_bits_metadata[n] ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_rend_crendProcessSubframe( 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, p_output, *nSamplesRendered, output_Fs, 0 ) ) != IVAS_ERR_OK )
{
return error;
}
}
-
- /* HP filtering */
- hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs );
- }
-
- if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX )
- {
- ivas_ism_mono_dmx( st_ivas, p_output, output_frame );
- }
- else if ( st_ivas->ism_mode == ISM_MODE_PARAM && ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) )
- {
- /* loudness correction */
- ivas_dirac_dec_binaural_sba_gain( p_output, st_ivas->nchan_transport, output_frame );
}
}
else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT )
{
- set_s( nb_bits_metadata, 0, MAX_SCE );
+ nchan_remapped = nchan_transport_rend;
- /* read parameters from the bitstream */
- if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hQMetaData != NULL )
+ /* Loudspeakers, Ambisonics or Binaural rendering */
+ if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC )
{
- st = ( st_ivas->nSCE > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0];
-
- if ( ( error = ivas_masa_decode( st_ivas, st, &nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
- {
- return error;
- }
+ ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output );
}
- else if ( st_ivas->ivas_format == SBA_FORMAT )
+ else if ( st_ivas->ivas_format == MASA_FORMAT )
{
- if ( ( error = ivas_spar_dec( st_ivas, nb_bits_metadata ) ) != IVAS_ERR_OK )
+ if ( st_ivas->renderer_type == RENDERER_DIRAC )
{
- return error;
+ ivas_dirac_dec_render( st_ivas, nchan_remapped, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output );
}
}
-
- if ( st_ivas->nchan_transport == CPE_CHANNELS && st_ivas->nCPE >= 1 )
- {
- st_ivas->hCPE[0]->brate_surplus = 0;
- st_ivas->hCPE[0]->element_brate = ivas_total_brate;
- }
-
- /* core-decoding of transport channels */
- if ( st_ivas->nSCE == 1 )
- {
- if ( ( error = ivas_sce_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
- {
- return error;
- }
- }
- else if ( st_ivas->nCPE == 1 )
- {
- if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
- {
- return error;
- }
- }
- else if ( st_ivas->nCPE > 1 )
+ else
{
- if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ) ) != IVAS_ERR_OK )
{
return error;
}
}
-
-#ifdef DEBUG_SBA_AUDIO_DUMP
- /* Dump audio signal after core-decoding */
- ivas_spar_dump_signal_wav( output_frame, NULL, output, st_ivas->nchan_transport, spar_foa_dec_wav[0], "core-decoding" );
-#endif
- /* TCs remapping */
+ }
+ else if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
nchan_remapped = st_ivas->nchan_transport;
- if ( st_ivas->sba_dirac_stereo_flag )
- {
- nchan_remapped = nchan_out;
- if ( st_ivas->ivas_format == SBA_FORMAT )
+ if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC )
+ {
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC && st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC )
{
- ivas_agc_dec_process( st_ivas->hSpar->hAgcDec, p_output, p_output, st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, output_frame );
-
- if ( st_ivas->hSpar->hPCA != NULL )
+ if ( ( error = ivas_omasa_dirac_td_binaural( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output ) ) != IVAS_ERR_OK )
{
- ivas_pca_dec( 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 );
+ return error;
}
-
- ivas_spar_dec_gen_umx_mat( 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( st_ivas, p_output, output_frame );
- }
- else if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && ( ivas_total_brate > IVAS_SID_5k2 || ( ivas_total_brate <= IVAS_SID_5k2 && st_ivas->nCPE > 0 && st_ivas->hCPE[0]->nchan_out == 1 ) ) )
- {
- nchan_remapped = 1; /* Only one channel transported */
- }
-
- /* HP filtering */
-#ifndef DEBUG_SPAR_BYPASS_EVS_CODEC
- for ( n = 0; n < nchan_remapped; n++ )
- {
- hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs );
- }
-#endif
-
- if ( st_ivas->ivas_format == SBA_FORMAT )
- {
- nchan_remapped = ivas_sba_remapTCs( p_output, st_ivas, output_frame );
-
- if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || 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 );
- ivas_sba_mix_matrix_determiner( st_ivas->hSpar, p_output, st_ivas->bfi, nchan_remapped, output_frame, num_md_sub_frames );
}
- else if ( st_ivas->renderer_type != RENDERER_DISABLE )
+ else
{
- ivas_spar_dec_agc_pca( st_ivas, p_output, output_frame );
+ ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output );
}
}
-
- if ( st_ivas->ivas_format == MASA_FORMAT )
+ else if ( st_ivas->renderer_type == RENDERER_DIRAC )
{
- ivas_masa_prerender( st_ivas, p_output, output_frame, nchan_remapped );
-
- /* external output */
- if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL && st_ivas->hMasa->config.input_ivas_format == MASA_ISM_FORMAT )
- {
- for ( n = 0; n < st_ivas->nchan_ism; n++ )
- {
- set_zero( p_output[st_ivas->nchan_transport + n], output_frame );
- }
-
- ivas_omasa_rearrange_channels( p_output, st_ivas->nchan_ism, output_frame );
- }
+ ivas_omasa_dirac_rend( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output );
}
- else if ( st_ivas->ivas_format == SBA_FORMAT && ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
+ else if ( st_ivas->renderer_type == RENDERER_OMASA_OBJECT_EXT || st_ivas->renderer_type == RENDERER_OMASA_MIX_EXT )
{
- /* loudness correction */
- ivas_dirac_dec_binaural_sba_gain( p_output, nchan_remapped, output_frame );
+ ivas_dec_tc_buffer_playout( st_ivas, nSamplesAskedLocal, nSamplesRendered, p_output );
+ ivas_omasa_rearrange_channels( p_output, st_ivas->nchan_ism, *nSamplesRendered );
}
}
- else if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ else if ( st_ivas->ivas_format == SBA_ISM_FORMAT )
{
- int16_t nchan_ism, nchan_transport_ism;
- int16_t dirac_bs_md_write_idx;
-
- set_s( nb_bits_metadata, 0, MAX_SCE + 1 );
+ nchan_remapped = nchan_transport_rend;
- /* Set the number of objects for the parametric rendering */
- dirac_bs_md_write_idx = 0;
- if ( st_ivas->hSpatParamRendCom != NULL )
+ /* Loudspeakers, Ambisonics or Binaural rendering */
+ if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC )
{
- st_ivas->hSpatParamRendCom->numIsmDirections = 0;
- if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ )
+ if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV )
{
- st_ivas->hSpatParamRendCom->numIsmDirections = st_ivas->nchan_ism;
+ if ( ( error = ivas_osba_dirac_td_binaural( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
}
-
- dirac_bs_md_write_idx = st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx; /* Store the write-index for this frame */
- }
-
- /* MASA metadata decoding */
- if ( ( error = ivas_masa_decode( 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 )] );
-
- /* set ISM parameters and decode ISM metadata in OMASA format */
- if ( ( error = ivas_omasa_ism_metadata_dec( st_ivas, ism_total_brate, &nchan_ism, &nchan_transport_ism, dirac_bs_md_write_idx, &nb_bits_metadata[1] ) ) != IVAS_ERR_OK )
- {
- return error;
- }
-
- /* decode ISM channels */
- for ( n = 0; n < nchan_transport_ism; n++ )
- {
- if ( ( error = ivas_sce_dec( st_ivas, n, &p_output[st_ivas->nchan_transport + n], output_frame, nb_bits_metadata[1] ) ) != IVAS_ERR_OK )
+ else if ( st_ivas->renderer_type == RENDERER_OSBA_STEREO )
{
- return error;
- }
- }
-
- /* decode MASA channels */
- if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
- {
- return error;
- }
-
- if ( st_ivas->hCPE[0]->nchan_out == 1 )
- {
- mvr2r( p_output[0], p_output[1], output_frame ); /* Copy mono signal to stereo output channels */
- }
+ /* shift SBA channels to avoid overwrite by ISM upmix in 1 object case and non-TSM unified channel memory*/
+ if ( st_ivas->nchan_ism == 1 && st_ivas->hDecoderConfig->Opt_tsm == 0 )
+ {
+ mvr2r( p_tc[2], p_output[3], *nSamplesRendered );
+ mvr2r( p_tc[1], p_output[2], *nSamplesRendered );
+ p_tc[1] = p_output[2];
+ p_tc[2] = p_output[3];
+ }
- /* HP filtering */
- for ( n = 0; n < getNumChanSynthesis( st_ivas ); n++ )
- {
- hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs );
- }
+ /* render objects */
+ ivas_ism_render_sf( st_ivas, st_ivas->renderer_type, p_output, *nSamplesRendered );
- if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX )
- {
- ivas_ism_mono_dmx( st_ivas, p_output, output_frame );
- }
- else if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL )
- {
- if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
- {
- ivas_omasa_rearrange_channels( p_output, nchan_transport_ism, output_frame );
+ /* add already rendered SBA part */
+ ivas_osba_stereo_add_channels( p_tc, p_output, st_ivas->hSbaIsmData->gain_bed, nchan_out, st_ivas->nchan_ism, *nSamplesRendered );
}
- else if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ else if ( st_ivas->renderer_type == RENDERER_OSBA_AMBI || st_ivas->renderer_type == RENDERER_OSBA_LS || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM )
{
- /* Convert separate object to MASA, combine with the original MASA, and output combined MASA + empty objects. */
- ivas_omasa_combine_separate_ism_with_masa( st_ivas, p_output, st_ivas->nchan_ism, output_frame );
+ if ( ( error = ivas_osba_render_sf( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
}
- else if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
+ else if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) /*EXT output = individual objects + HOA3*/
{
- /* Extract objects from MASA, output MASA + all objects (i.e., extracted and separated objects) */
- ivas_omasa_render_objects_from_mix( st_ivas, p_output, st_ivas->nchan_ism, output_frame );
- }
- }
- }
- else if ( st_ivas->ivas_format == SBA_ISM_FORMAT )
- {
- int16_t nchan_ism, sba_ch_idx;
+ if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, &p_output[st_ivas->nchan_ism] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
- set_s( nb_bits_metadata, 0, MAX_SCE + 1 );
- nchan_ism = st_ivas->nchan_ism;
- if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC )
- {
- /* set ISM parameters and decode ISM metadata in OSBA format */
- if ( ( error = ivas_osba_ism_metadata_dec( st_ivas, ivas_total_brate, &nchan_ism, &nb_bits_metadata[1] ) ) != IVAS_ERR_OK )
- {
- return error;
+ for ( n = 0; n < st_ivas->nchan_ism; n++ )
+ {
+ mvr2r( p_tc[n], p_output[n], *nSamplesRendered );
+ }
}
- sba_ch_idx = st_ivas->nchan_ism;
- }
- else
- {
- nb_bits_metadata[1] += NO_BITS_MASA_ISM_NO_OBJ;
- sba_ch_idx = 0;
- }
-
- /* SBA metadata decoding */
- if ( ( error = ivas_spar_dec( st_ivas, nb_bits_metadata ) ) != IVAS_ERR_OK )
- {
- return error;
- }
-
- if ( st_ivas->nchan_transport == CPE_CHANNELS && st_ivas->nCPE >= 1 )
- {
- st_ivas->hCPE[0]->element_brate = ivas_total_brate;
- }
-
- /* core-decoding of transport channels */
- if ( st_ivas->nSCE == 1 )
- {
- if ( ( error = ivas_sce_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ) != IVAS_ERR_OK )
+ else
{
- return error;
+ if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
}
}
- else if ( st_ivas->nCPE == 1 )
+ else if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM )
{
- if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ) != IVAS_ERR_OK )
+ ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output );
+ for ( n = 0; n < st_ivas->hDecoderConfig->nchan_out; n++ )
{
- return error;
+ v_multc( p_output[n], 2.0f, p_output[n], *nSamplesRendered );
}
}
- else if ( st_ivas->nCPE > 1 )
+ else
{
- if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ) ) != IVAS_ERR_OK )
{
return error;
}
- }
-
- if ( st_ivas->sba_dirac_stereo_flag )
- {
- ivas_agc_dec_process( st_ivas->hSpar->hAgcDec, &p_output[sba_ch_idx], &p_output[sba_ch_idx], st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, output_frame );
-
- if ( st_ivas->hSpar->hPCA != NULL )
- {
- ivas_pca_dec( 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[sba_ch_idx] );
- }
-
- ivas_spar_dec_gen_umx_mat( 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( st_ivas, &p_output[sba_ch_idx], output_frame );
- }
-
- /* HP filtering */
- for ( n = 0; n < getNumChanSynthesis( st_ivas ); n++ )
- {
- hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs );
- }
-
- nchan_remapped = ivas_sba_remapTCs( &p_output[sba_ch_idx], st_ivas, output_frame );
-#ifdef DEBUG_OSBA
- if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC )
- {
- int16_t nchan = st_ivas->nchan_transport + st_ivas->nchan_ism;
- for ( int16_t t = 0; t < output_frame; t++ )
+ if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL )
{
- for ( int16_t c = 0; c < nchan; c++ )
+#ifdef DEBUGGING
+ assert( st_ivas->ism_mode == ISM_MODE_NONE );
+#endif
+ for ( n = st_ivas->hIntSetup.nchan_out_woLFE - 1; n >= 0; n-- )
+ {
+ mvr2r( p_output[n], p_output[n + st_ivas->nchan_ism], *nSamplesRendered );
+ }
+ for ( n = 0; n < st_ivas->nchan_ism; n++ )
{
- int16_t val = (int16_t) ( output[c][t] + 0.5f );
- dbgwrite( &val, sizeof( int16_t ), 1, 1, "./res/TC_dec_core_out.raw" );
+ set_zero( p_output[n], *nSamplesRendered );
}
}
- }
-#endif
- if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || 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 );
-
- ivas_sba_mix_matrix_determiner( st_ivas->hSpar, &p_output[sba_ch_idx], st_ivas->bfi, nchan_remapped, output_frame, num_md_sub_frames );
- }
- else if ( st_ivas->renderer_type != RENDERER_DISABLE && !st_ivas->sba_dirac_stereo_flag )
- {
- ivas_spar_dec_agc_pca( st_ivas, &p_output[sba_ch_idx], output_frame );
- }
-
- if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM )
- {
- /* loudness correction */
- ivas_dirac_dec_binaural_sba_gain( &p_output[sba_ch_idx], nchan_remapped, output_frame );
- }
- else if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX && st_ivas->ism_mode == ISM_SBA_MODE_DISC )
- {
- ivas_ism_mono_dmx( st_ivas, p_output, output_frame );
-
- /* add W */
- for ( n = 0; n < nchan_out; n++ )
+ for ( n = 0; n < st_ivas->hDecoderConfig->nchan_out; n++ )
{
- v_add( p_output[n], p_output[n + max( nchan_out, nchan_ism )], p_output[n], output_frame );
+ v_multc( p_output[n], 2.0f, p_output[n], *nSamplesRendered );
}
}
}
else if ( st_ivas->ivas_format == MC_FORMAT )
{
- st = ( st_ivas->nSCE > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0];
-
if ( st_ivas->mc_mode == MC_MODE_MCT )
{
- /* LFE channel decoder */
- ivas_lfe_dec( st_ivas->hLFE, st, output_frame, st_ivas->bfi, p_output[LFE_CHANNEL] );
-
- if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, 0 ) ) != IVAS_ERR_OK )
- {
- return error;
- }
-
- /* HP filtering */
- for ( n = 0; n < st_ivas->nchan_transport; n++ )
- {
- if ( n != LFE_CHANNEL )
- {
- hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs );
- }
- }
+ int16_t crendInPlaceRotation = FALSE;
if ( st_ivas->transport_config != st_ivas->intern_config && ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_FOA || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA2 || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA3 ) )
{
- if ( ( st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe ) >= ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ) )
+ if ( ( st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe ) < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ) )
{
- ivas_mc2sba( st_ivas->hTransSetup, p_output, p_output, output_frame, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE );
+ crendInPlaceRotation = TRUE;
+ ivas_mc2sba( st_ivas->hTransSetup, p_tc, p_output, *nSamplesRendered, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE );
}
}
- if ( ( st_ivas->renderer_type == RENDERER_MC || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) && ( st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe ) >= ( st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ) )
+ /* Rendering */
+ if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM )
{
- if ( st_ivas->renderer_type == RENDERER_MC )
+ if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
{
- ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, output_frame, p_output, p_output );
+ 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, crendInPlaceRotation ? p_output : p_tc, p_output, *nSamplesRendered, output_Fs ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
}
- else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC )
+ else
{
- ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, output_frame, st_ivas->hOutSetup.ambisonics_order, 0.f );
+ if ( ( error = ivas_rend_crendProcessSubframe( 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, crendInPlaceRotation ? p_output : p_tc, p_output, *nSamplesRendered, output_Fs, 0 ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_tc, p_output );
}
}
- }
- else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX )
- {
- /* LFE channel decoder */
- ivas_lfe_dec( st_ivas->hLFE, st, output_frame, st_ivas->bfi, p_output[LFE_CHANNEL] );
-
- ivas_mc_paramupmix_dec_read_BS( st_ivas, st, st_ivas->hMCParamUpmix, &nb_bits_metadata[0] );
-
- if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
+ else if ( st_ivas->renderer_type == RENDERER_MC )
{
- return error;
+ ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, *nSamplesRendered, p_tc, p_output );
}
-
- /* HP filtering */
- for ( n = 0; n < st_ivas->nchan_transport; n++ )
+ else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC )
{
- if ( n != LFE_CHANNEL )
- {
- hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs );
- }
+ ivas_mc2sba( st_ivas->hIntSetup, p_tc, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f );
}
-
- /* Rendering */
- if ( st_ivas->renderer_type == RENDERER_MC && ( output_config == IVAS_AUDIO_CONFIG_MONO || output_config == IVAS_AUDIO_CONFIG_STEREO ) )
+ else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD )
{
- /* Compensate loudness for not doing full upmix */
- for ( n = 4; n < 8; n++ )
+ if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
{
- v_multc( p_output[n], 2.0f, p_output[n], output_frame );
+ if ( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
}
-
- if ( output_config == IVAS_AUDIO_CONFIG_MONO || output_config == IVAS_AUDIO_CONFIG_STEREO )
+ else
{
- ivas_ls_setup_conversion( st_ivas, audioCfg2channels( IVAS_AUDIO_CONFIG_5_1_2 ), output_frame, p_output, p_output );
+ if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_tc, p_output );
}
}
}
- else if ( st_ivas->mc_mode == MC_MODE_PARAMMC )
+ else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX )
{
- /* read Parametric MC parameters from the bitstream */
- ivas_param_mc_dec_read_BS( ivas_total_brate, st, st_ivas->hParamMC, &nb_bits_metadata[0] );
+ ivas_mc_paramupmix_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_tc, p_output );
- if ( st_ivas->nCPE == 1 )
- {
- if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
- {
- return error;
- }
- }
- else if ( st_ivas->nCPE > 1 )
+ /* Rendering */
+ if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) && !st_ivas->hDecoderConfig->Opt_Headrotation )
{
- if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
+ /* handled in CLDFB domain already */
+ if ( output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
{
- return error;
+ ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_output, p_output );
}
}
-
- /* HP filtering */
- for ( n = 0; n < st_ivas->nchan_transport; n++ )
+ else if ( st_ivas->renderer_type == RENDERER_MC )
{
- hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs );
+ ivas_ls_setup_conversion( st_ivas, MC_PARAMUPMIX_MAX_INPUT_CHANS, *nSamplesRendered, p_output, p_output );
}
-
- /* Rendering */
- if ( output_config == IVAS_AUDIO_CONFIG_MONO || output_config == IVAS_AUDIO_CONFIG_STEREO )
+ else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC )
{
- ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, output_frame, p_output, p_output );
+ ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f );
}
}
+ else if ( st_ivas->mc_mode == MC_MODE_PARAMMC )
+ {
+ ivas_param_mc_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output );
+ }
else if ( 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 */
- }
+ nchan_remapped = st_ivas->nchan_transport;
- /* read McMASA parameters from the bitstream */
- if ( ( error = ivas_masa_decode( st_ivas, st, &nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
+ if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC )
{
- return error;
+ ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output );
}
-
- if ( st_ivas->hOutSetup.separateChannelEnabled )
+ else if ( st_ivas->renderer_type == RENDERER_DIRAC || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) /* rendering to CICPxx and Ambisonics */
{
- /* Decode the transport audio signals */
- if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, 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;
-
- /* Decode the separated channel to output[n] to be combined with the synthesized channels */
- if ( ( error = ivas_sce_dec( st_ivas, 0, &p_output[n], output_frame, 0 ) ) != IVAS_ERR_OK )
- {
- return error;
- }
+ ivas_dirac_dec_render( st_ivas, nchan_remapped, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output );
- /* Delay the separated channel to sync with CLDFB delay of the DirAC synthesis, and synthesize the LFE signal. */
- if ( output_config == IVAS_AUDIO_CONFIG_5_1 || output_config == IVAS_AUDIO_CONFIG_7_1 ||
- output_config == IVAS_AUDIO_CONFIG_5_1_4 || output_config == IVAS_AUDIO_CONFIG_7_1_4 ||
- output_config == IVAS_AUDIO_CONFIG_5_1_2 || ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe > 0 ) || output_config == IVAS_AUDIO_CONFIG_EXTERNAL )
- {
- ivas_lfe_synth_with_filters( st_ivas->hMasa->hMasaLfeSynth, p_output, output_frame, n, LFE_CHANNEL );
- }
- else if ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe == 0 )
- {
- /* Delay the separated channel to sync with the DirAC rendering */
- delay_signal( p_output[n], output_frame, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_size );
- }
- }
- else
- {
- if ( st_ivas->nSCE == 1 )
+ if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC )
{
- if ( ( error = ivas_sce_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
+ /* we still need to copy the separate channel if available */
+ if ( st_ivas->hOutSetup.separateChannelEnabled )
{
- return error;
+ mvr2r( p_tc[LFE_CHANNEL - 1], p_output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered );
}
+
+ ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f );
}
- else if ( st_ivas->nCPE == 1 )
+ else if ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_5_1 && ( output_config == IVAS_AUDIO_CONFIG_5_1_2 || output_config == IVAS_AUDIO_CONFIG_5_1_4 || output_config == IVAS_AUDIO_CONFIG_7_1 ) )
{
- if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
+ 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++ )
{
- return error;
+ set_zero( p_output[n], *nSamplesRendered );
}
}
}
- if ( st_ivas->sba_dirac_stereo_flag ) /* use the flag to trigger the DFT upmix */
- {
- ivas_sba_dirac_stereo_dec( st_ivas, p_output, output_frame );
- }
-
- /* HP filtering */
- for ( n = 0; n < getNumChanSynthesis( st_ivas ); n++ )
- {
- hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs );
- }
-
- if ( st_ivas->renderer_type == RENDERER_MCMASA_MONO_STEREO )
+ /* copy discrete C and TD LFE from internal TC to output */
+ if ( st_ivas->hOutSetup.separateChannelEnabled )
{
- ivas_mono_stereo_downmix_mcmasa( st_ivas, p_output, output_frame );
+ if ( output_config == IVAS_AUDIO_CONFIG_5_1 || output_config == IVAS_AUDIO_CONFIG_7_1 ||
+ output_config == IVAS_AUDIO_CONFIG_5_1_4 || output_config == IVAS_AUDIO_CONFIG_7_1_4 ||
+ output_config == IVAS_AUDIO_CONFIG_5_1_2 || ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe > 0 ) )
+ {
+ mvr2r( p_tc[LFE_CHANNEL], p_output[LFE_CHANNEL], *nSamplesRendered );
+ mvr2r( p_tc[LFE_CHANNEL - 1], p_output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered );
+ }
+ else if ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe == 0 )
+ {
+ mvr2r( p_tc[LFE_CHANNEL - 1], p_output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered );
+ }
}
}
}
/*----------------------------------------------------------------*
- * 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 -= *nSamplesRendered;
+ st_ivas->hTcBuffer->n_samples_rendered += *nSamplesRendered;
+
+ /* 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;
- st_ivas->last_active_ivas_total_brate = ( ivas_total_brate <= IVAS_SID_5k2 ) ? st_ivas->last_active_ivas_total_brate : ivas_total_brate;
+ for ( n = 0; n < min( MAX_OUTPUT_CHANNELS, ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ) ); n++ )
+ {
+ p_output[n] += st_ivas->hTcBuffer->n_samples_discard;
+ }
+ *nSamplesRendered -= st_ivas->hTcBuffer->n_samples_discard;
+ st_ivas->hTcBuffer->n_samples_discard = 0;
}
- if ( 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 */
+ if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
{
- st_ivas->ini_frame++;
+ nchan_out_syn_output = BINAURAL_CHANNELS * st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses;
+#ifdef TMP_1342_WORKAROUND_DEC_FLUSH_BROKEN_IN_SR
+ if ( st_ivas->flushing )
+ {
+ nchan_out_syn_output = BINAURAL_CHANNELS;
+ }
+#endif
}
-
- if ( st_ivas->ini_active_frame < MAX_FRAME_COUNTER && !( st_ivas->bfi && st_ivas->ini_frame == 0 ) && 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 */
+ else
{
- st_ivas->ini_active_frame++;
+ nchan_out_syn_output = nchan_out;
}
- st_ivas->last_ivas_format = st_ivas->ivas_format;
-
-#ifdef DEBUG_MODE_INFO
- dbgwrite( &st_ivas->bfi, sizeof( int16_t ), 1, output_frame, "res/bfi" );
- dbgwrite( &st_ivas->BER_detect, sizeof( int16_t ), 1, output_frame, "res/BER_detect" );
+ if ( is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ) == 0 )
{
- float tmpF = ivas_total_brate / 1000.0f;
- dbgwrite( &tmpF, sizeof( float ), 1, output_frame, "res/ivas_total_brate.dec" );
+ if ( st_ivas->ivas_format != MONO_FORMAT )
+ {
+#ifndef DISABLE_LIMITER
+ ivas_limiter_dec( st_ivas->hLimiter, p_output, nchan_out, *nSamplesRendered, st_ivas->BER_detect );
+#endif
+ }
}
+
+ switch ( pcm_resolution )
+ {
+ case PCM_INT16:
+#ifdef DEBUGGING
+ st_ivas->noClipping +=
#endif
+ ivas_syn_output( p_output, *nSamplesRendered, nchan_out_syn_output, (int16_t *) data );
+
+ break;
+ case PCM_FLOAT32:
+ ivas_buffer_deinterleaved_to_interleaved( p_output, nchan_out_syn_output, *nSamplesRendered, (float *) data );
+ break;
+ default:
+ error = IVAS_ERR_UNKNOWN;
+ break;
+ }
+
+ *nSamplesAvailableNext = st_ivas->hTcBuffer->n_samples_available;
pop_wmops();
return IVAS_ERR_OK;
@@ -733,1470 +691,415 @@ ivas_error ivas_dec(
/*--------------------------------------------------------------------------*
- * 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(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
- const int16_t nSamplesForRendering, /* i : number of TC samples available for rendering */
- int16_t *nSamplesResidual /* o : number of samples not fitting into the renderer grid and buffer for the next call*/
+ivas_error ivas_jbm_dec_flush_renderer(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ const int16_t 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 */
+ uint16_t *nSamplesRendered, /* o : number of samples flushed */
+ const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */
+ void *data /* o : output synthesis signal */
)
{
- float tmp_buf[MAX_JBM_L_FRAME48k];
- float *p_data_f[FOA_CHANNELS + MAX_NUM_OBJECTS];
- int16_t n, n_render_timeslots, n_ch_cldfb;
- int16_t ch, offset, len_offset;
+ ivas_error error;
+ int16_t n_samples_still_available;
+ int16_t n_slots_still_available;
+ int16_t n_samples_to_render;
+ int16_t ch_idx;
+ int16_t n_samples_granularity;
DECODER_TC_BUFFER_HANDLE hTcBuffer;
+ float *p_output[MAX_LS_CHANNELS + MAX_NUM_OBJECTS];
- hTcBuffer = st_ivas->hTcBuffer;
- n_ch_cldfb = hTcBuffer->nchan_transport_rend - hTcBuffer->nchan_buffer_full;
-
- if ( st_ivas->hDecoderConfig->Opt_tsm )
+ if ( !st_ivas->hDecoderConfig->Opt_tsm )
{
- int16_t n_samples_still_available;
- int16_t n_ch_full_copy, n_ch_res_copy;
+ return IVAS_ERR_OK;
+ }
- n_samples_still_available = hTcBuffer->n_samples_buffered - hTcBuffer->n_samples_rendered;
- hTcBuffer->n_samples_buffered = n_samples_still_available + nSamplesForRendering + hTcBuffer->n_samples_discard;
- hTcBuffer->n_samples_available = hTcBuffer->n_samples_granularity * ( hTcBuffer->n_samples_buffered / hTcBuffer->n_samples_granularity );
- *nSamplesResidual = hTcBuffer->n_samples_buffered - hTcBuffer->n_samples_available;
- n_ch_full_copy = min( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full );
- n_ch_res_copy = hTcBuffer->nchan_transport_rend - hTcBuffer->nchan_buffer_full;
+ for ( ch_idx = 0; ch_idx < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; ch_idx++ )
+ {
+ p_output[ch_idx] = st_ivas->p_output_f[ch_idx];
+ }
- /* 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( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS );
- if ( len_offset < L_FRAME48k )
- {
- offset = 0;
- for ( ch = 0; ch < max( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full ); ch++ )
- {
- hTcBuffer->tc[ch] = &hTcBuffer->tc_buffer[offset];
- st_ivas->p_output_f[ch] = hTcBuffer->tc[ch];
- offset += len_offset;
- }
- }
+ *nSamplesRendered = 0;
+ hTcBuffer = st_ivas->hTcBuffer;
+ n_samples_granularity = hTcBuffer->n_samples_granularity;
- for ( ch = 0; ch < n_ch_full_copy; ch++ )
- {
- mvr2r( hTcBuffer->tc[ch], tmp_buf, nSamplesForRendering );
- set_zero( hTcBuffer->tc[ch], hTcBuffer->n_samples_discard );
- mvr2r( hTcBuffer->tc_buffer_old[ch], hTcBuffer->tc[ch] + hTcBuffer->n_samples_discard, n_samples_still_available );
- mvr2r( tmp_buf, hTcBuffer->tc[ch] + n_samples_still_available + hTcBuffer->n_samples_discard, nSamplesForRendering - *nSamplesResidual );
- mvr2r( tmp_buf + nSamplesForRendering - *nSamplesResidual, hTcBuffer->tc_buffer_old[ch], *nSamplesResidual );
- }
+ /* get number of possible slots in new granularity */
+ n_samples_still_available = hTcBuffer->n_samples_buffered - hTcBuffer->n_samples_rendered;
+ n_slots_still_available = n_samples_still_available / tc_granularity_new;
+ *nSamplesRendered = n_slots_still_available * tc_granularity_new;
+ n_samples_to_render = *nSamplesRendered;
+ n_samples_still_available -= n_samples_to_render;
+ assert( n_samples_still_available < tc_granularity_new );
- if ( n_ch_res_copy > 0 )
- {
- for ( ; ch < hTcBuffer->nchan_transport_rend; ch++ )
- {
- p_data_f[ch] = hTcBuffer->tc[ch];
- mvr2r( hTcBuffer->tc[ch], tmp_buf, nSamplesForRendering );
- mvr2r( hTcBuffer->tc_buffer_old[ch], p_data_f[ch], n_samples_still_available );
- mvr2r( tmp_buf, p_data_f[ch] + n_samples_still_available, nSamplesForRendering - *nSamplesResidual );
- mvr2r( tmp_buf + nSamplesForRendering - *nSamplesResidual, hTcBuffer->tc_buffer_old[ch], *nSamplesResidual );
- }
- }
+ /* update combined orientation access index */
+ ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData );
- n_render_timeslots = hTcBuffer->n_samples_available / hTcBuffer->n_samples_granularity;
- }
- else
+ if ( n_slots_still_available )
{
- for ( n = 0; n < n_ch_cldfb; n++ )
- {
- p_data_f[n] = &st_ivas->p_output_f[n][0];
- }
-
- ch = max( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full );
- for ( n = 0; n < ch; n++ )
+ /* render available full slots (with new lower granularity) */
+ for ( ch_idx = 0; ch_idx < max( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full ); ch_idx++ )
{
- hTcBuffer->tc[n] = st_ivas->p_output_f[n]; /* note: buffers needed in the TD decorellator */
+ /* move it at the beginning of the TC buffer with zero padding */
+ mvr2r( hTcBuffer->tc_buffer_old[ch_idx], hTcBuffer->tc[ch_idx], n_samples_to_render );
+ set_zero( hTcBuffer->tc[ch_idx] + n_samples_to_render, hTcBuffer->n_samples_granularity - n_samples_to_render );
}
- hTcBuffer->n_samples_buffered = nSamplesForRendering;
- hTcBuffer->n_samples_available = hTcBuffer->n_samples_buffered;
- *nSamplesResidual = 0;
-
- n_render_timeslots = DEFAULT_JBM_CLDFB_TIMESLOTS;
- }
-
- /* CLDFB analysis for ParamMC/ParamISM */
- if ( st_ivas->ivas_format == ISM_FORMAT && st_ivas->ism_mode == ISM_MODE_PARAM && ( st_ivas->renderer_type == RENDERER_PARAM_ISM || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) )
- {
- ivas_param_ism_dec_digest_tc( st_ivas, n_render_timeslots, p_data_f );
- }
- else if ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_PARAMMC && hTcBuffer->tc_buffer_mode == TC_BUFFER_MODE_RENDERER )
- {
- ivas_param_mc_dec_digest_tc( st_ivas, (uint8_t) n_render_timeslots, p_data_f );
- }
-
- hTcBuffer->n_samples_rendered = 0;
- hTcBuffer->subframes_rendered = 0;
-
- return;
-}
-
-
-/*--------------------------------------------------------------------------*
- * ivas_dec_render()
- *
- * Principal IVAS internal rendering routine
- *--------------------------------------------------------------------------*/
-
-ivas_error ivas_dec_render(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
- const uint16_t nSamplesAsked, /* i : number of samples wanted */
- uint16_t *nSamplesRendered, /* o : number of samples rendered */
- uint16_t *nSamplesAvailableNext, /* o : number of samples still available in the rendering pipeline */
- const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */
- void *data /* o : output synthesis signal */
-)
-{
- int16_t n, nchan_out;
- int16_t nchan_transport_rend;
- int16_t nchan_remapped;
- int32_t output_Fs;
- AUDIO_CONFIG output_config;
- int16_t nSamplesAskedLocal;
- ivas_error error;
- float *p_output[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS];
- float *p_tc[MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS];
- int16_t 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;
- nchan_out = st_ivas->hDecoderConfig->nchan_out;
- nchan_transport_rend = st_ivas->hTcBuffer->nchan_transport_rend;
- output_config = st_ivas->hDecoderConfig->output_config;
- nSamplesAskedLocal = nSamplesAsked + st_ivas->hTcBuffer->n_samples_discard;
+ /* 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 = 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;
- for ( n = 0; n < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; n++ )
- {
- p_output[n] = st_ivas->p_output_f[n];
- }
- if ( !st_ivas->hDecoderConfig->Opt_tsm )
- {
- for ( n = 0; n < MAX_INTERN_CHANNELS; n++ )
+ if ( st_ivas->ivas_format == ISM_FORMAT )
{
- st_ivas->hTcBuffer->tc[n] = p_output[n];
- }
- }
-
- for ( n = 0; n < st_ivas->hTcBuffer->nchan_buffer_full; n++ )
- {
- p_tc[n] = &st_ivas->hTcBuffer->tc[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 -= st_ivas->hTcBuffer->n_samples_discard;
-
- ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData );
- }
-
- /*----------------------------------------------------------------*
- * Rendering
- *----------------------------------------------------------------*/
+ if ( ism_mode_old == ISM_MODE_DISC )
+ {
+ /* Binaural rendering */
+ if ( renderer_type_old == RENDERER_BINAURAL_OBJECTS_TD )
+ {
+ if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_output, n_samples_granularity ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else if ( renderer_type_old == RENDERER_BINAURAL_MIXER_CONV_ROOM )
+ {
+ /* Convert to CICPxx; used also for ISM->CICP19->binaural_room rendering */
+ set_f( st_ivas->hIsmRendererData->interpolator, 1.0f, n_samples_granularity );
- *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal );
+ ivas_ism_render_sf( st_ivas, renderer_type_old, p_output, n_samples_granularity );
- if ( st_ivas->ivas_format == UNDEFINED_FORMAT )
- {
- assert( 0 );
- }
- else if ( st_ivas->hTcBuffer->tc_buffer_mode == TC_BUFFER_MODE_BUFFER )
- {
- ivas_dec_tc_buffer_playout( st_ivas, nSamplesAskedLocal, nSamplesRendered, p_output );
- }
- else if ( st_ivas->ivas_format == MONO_FORMAT || st_ivas->ivas_format == STEREO_FORMAT )
- {
- /* Rendering */
- if ( st_ivas->renderer_type == RENDERER_MC )
- {
- ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, *nSamplesRendered, p_tc, p_output );
- }
- else if ( st_ivas->renderer_type == RENDERER_NON_DIEGETIC_DOWNMIX )
- {
- ivas_apply_non_diegetic_panning( p_tc[0], p_output, st_ivas->hDecoderConfig->non_diegetic_pan_gain, *nSamplesRendered );
- }
- else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC )
- {
- ivas_stereo2sba( p_tc, p_output, *nSamplesRendered );
- }
- }
- else if ( st_ivas->ivas_format == ISM_FORMAT )
- {
- /* Rendering */
- if ( st_ivas->ism_mode == ISM_MODE_PARAM )
- {
- if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC )
- {
- ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, st_ivas->nchan_transport, p_output );
+ if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL,
+ NULL, NULL, hTcBuffer, p_output, p_output, n_samples_granularity, st_ivas->hDecoderConfig->output_Fs, 0 ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
}
- else if ( st_ivas->renderer_type == RENDERER_PARAM_ISM || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC )
+ else
{
- ivas_param_ism_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output );
-
- if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC )
- {
- /* Convert CICP19 -> Ambisonics */
- ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f );
- }
+ return IVAS_ERROR( IVAS_ERR_WRONG_MODE, "Wrong ISM_MODE in VoIP renderer flushing!" );
}
}
- else /* ISM_MODE_DISC */
+ else if ( st_ivas->ivas_format == MC_FORMAT )
{
- /* Loudspeaker or Ambisonics rendering */
- if ( st_ivas->renderer_type == RENDERER_TD_PANNING || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM )
- {
- /* Convert to CICPxx; used also for ISM->CICP19->binaural_room rendering */
- ivas_ism_render_sf( st_ivas, st_ivas->renderer_type, p_output, *nSamplesRendered );
- }
- else if ( st_ivas->renderer_type == RENDERER_NON_DIEGETIC_DOWNMIX )
- {
- ivas_apply_non_diegetic_panning( p_tc[0], p_output, st_ivas->hDecoderConfig->non_diegetic_pan_gain, *nSamplesRendered );
- }
-#ifdef DEBUGGING
- else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV )
-#else
- else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC )
-#endif
+ if ( mc_mode_old == MC_MODE_MCT )
{
- /* Convert to Ambisonics */
- ivas_ism2sba_sf( p_tc, p_output, st_ivas->hIsmRendererData, st_ivas->nchan_transport, *nSamplesRendered, st_ivas->hTcBuffer->n_samples_rendered, st_ivas->hIntSetup.ambisonics_order );
- }
+ int16_t crendInPlaceRotation = FALSE;
- /* Binaural rendering */
- if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD )
- {
- if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
+ if ( st_ivas->transport_config != intern_config_old && ( intern_config_old == IVAS_AUDIO_CONFIG_FOA || intern_config_old == IVAS_AUDIO_CONFIG_HOA2 || intern_config_old == IVAS_AUDIO_CONFIG_HOA3 ) )
{
- if ( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK )
+ if ( ( st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe ) < ( hIntSetupOld->nchan_out_woLFE + hIntSetupOld->num_lfe ) )
{
- return error;
+ crendInPlaceRotation = TRUE;
+ ivas_mc2sba( st_ivas->hTransSetup, hTcBuffer->tc, p_output, n_samples_granularity, hIntSetupOld->ambisonics_order, GAIN_LFE );
}
}
- else
+ if ( renderer_type_old == RENDERER_BINAURAL_MIXER_CONV || renderer_type_old == RENDERER_BINAURAL_MIXER_CONV_ROOM )
{
- if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, intern_config_old, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData,
+ hIntSetupOld, st_ivas->hEFAPdata, hTcBuffer, crendInPlaceRotation ? p_output : hTcBuffer->tc, p_output, n_samples_granularity, st_ivas->hDecoderConfig->output_Fs, 0 ) ) != IVAS_ERR_OK )
{
return error;
}
+
+ ivas_binaural_add_LFE( st_ivas, n_samples_granularity, hTcBuffer->tc, p_output );
}
- }
- else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM )
- {
- if ( ( error = ivas_rend_crendProcessSubframe( 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, p_output, *nSamplesRendered, output_Fs, 0 ) ) != IVAS_ERR_OK )
+ else if ( renderer_type_old == RENDERER_BINAURAL_OBJECTS_TD )
{
- return error;
- }
- }
- }
- }
- else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT )
- {
- nchan_remapped = nchan_transport_rend;
-
- /* Loudspeakers, Ambisonics or Binaural rendering */
- if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC )
- {
- ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output );
- }
- else if ( st_ivas->ivas_format == MASA_FORMAT )
- {
- if ( st_ivas->renderer_type == RENDERER_DIRAC )
- {
- ivas_dirac_dec_render( st_ivas, nchan_remapped, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output );
- }
- }
- else
- {
- if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ) ) != IVAS_ERR_OK )
- {
- return error;
- }
- }
- }
- else if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
- {
- nchan_remapped = st_ivas->nchan_transport;
+ if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_output, n_samples_granularity ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
- if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC )
- {
- if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC && st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC )
- {
- if ( ( error = ivas_omasa_dirac_td_binaural( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output ) ) != IVAS_ERR_OK )
+ ivas_binaural_add_LFE( st_ivas, n_samples_granularity, hTcBuffer->tc, p_output );
+ }
+ else
{
- return error;
+ return IVAS_ERROR( IVAS_ERR_WRONG_MODE, "Wrong renderer in MCT VoIP renderer flushing!" );
}
}
else
{
- ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output );
+ return IVAS_ERROR( IVAS_ERR_WRONG_MODE, "Wrong MC_MODE in VoIP renderer flushing!" );
}
}
- else if ( st_ivas->renderer_type == RENDERER_DIRAC )
+ else if ( st_ivas->ivas_format == MASA_ISM_FORMAT || st_ivas->ivas_format == MASA_FORMAT )
{
- ivas_omasa_dirac_rend( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output );
- }
- else if ( st_ivas->renderer_type == RENDERER_OMASA_OBJECT_EXT || st_ivas->renderer_type == RENDERER_OMASA_MIX_EXT )
- {
- ivas_dec_tc_buffer_playout( st_ivas, nSamplesAskedLocal, nSamplesRendered, p_output );
- ivas_omasa_rearrange_channels( p_output, st_ivas->nchan_ism, *nSamplesRendered );
- }
- }
- else if ( st_ivas->ivas_format == SBA_ISM_FORMAT )
- {
- nchan_remapped = nchan_transport_rend;
-
- /* Loudspeakers, Ambisonics or Binaural rendering */
- if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC )
- {
- if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV )
- {
- if ( ( error = ivas_osba_dirac_td_binaural( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ) ) != IVAS_ERR_OK )
- {
- return error;
- }
- }
- else if ( st_ivas->renderer_type == RENDERER_OSBA_STEREO )
- {
- /* shift SBA channels to avoid overwrite by ISM upmix in 1 object case and non-TSM unified channel memory*/
- if ( st_ivas->nchan_ism == 1 && st_ivas->hDecoderConfig->Opt_tsm == 0 )
- {
- mvr2r( p_tc[2], p_output[3], *nSamplesRendered );
- mvr2r( p_tc[1], p_output[2], *nSamplesRendered );
- p_tc[1] = p_output[2];
- p_tc[2] = p_output[3];
- }
-
- /* render objects */
- ivas_ism_render_sf( st_ivas, st_ivas->renderer_type, p_output, *nSamplesRendered );
-
- /* add already rendered SBA part */
- ivas_osba_stereo_add_channels( p_tc, p_output, st_ivas->hSbaIsmData->gain_bed, nchan_out, st_ivas->nchan_ism, *nSamplesRendered );
- }
- else if ( st_ivas->renderer_type == RENDERER_OSBA_AMBI || st_ivas->renderer_type == RENDERER_OSBA_LS || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM )
- {
- if ( ( error = ivas_osba_render_sf( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ) ) != IVAS_ERR_OK )
- {
- return error;
- }
- }
- else if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) /*EXT output = individual objects + HOA3*/
- {
- if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, &p_output[st_ivas->nchan_ism] ) ) != IVAS_ERR_OK )
- {
- return error;
- }
-
- for ( n = 0; n < st_ivas->nchan_ism; n++ )
- {
- mvr2r( p_tc[n], p_output[n], *nSamplesRendered );
- }
- }
- else
- {
- if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ) ) != IVAS_ERR_OK )
- {
- return error;
- }
- }
- }
- else if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM )
- {
- ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output );
- for ( n = 0; n < st_ivas->hDecoderConfig->nchan_out; n++ )
- {
- v_multc( p_output[n], 2.0f, p_output[n], *nSamplesRendered );
- }
- }
- else
- {
- if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ) ) != IVAS_ERR_OK )
- {
- return error;
- }
-
- if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL )
- {
-#ifdef DEBUGGING
- assert( st_ivas->ism_mode == ISM_MODE_NONE );
-#endif
- for ( n = st_ivas->hIntSetup.nchan_out_woLFE - 1; n >= 0; n-- )
- {
- mvr2r( p_output[n], p_output[n + st_ivas->nchan_ism], *nSamplesRendered );
- }
- for ( n = 0; n < st_ivas->nchan_ism; n++ )
- {
- set_zero( p_output[n], *nSamplesRendered );
- }
- }
- for ( n = 0; n < st_ivas->hDecoderConfig->nchan_out; n++ )
- {
- v_multc( p_output[n], 2.0f, p_output[n], *nSamplesRendered );
- }
- }
- }
- else if ( st_ivas->ivas_format == MC_FORMAT )
- {
- if ( st_ivas->mc_mode == MC_MODE_MCT )
- {
- int16_t crendInPlaceRotation = FALSE;
-
- if ( st_ivas->transport_config != st_ivas->intern_config && ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_FOA || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA2 || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA3 ) )
- {
- if ( ( st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe ) < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ) )
- {
- crendInPlaceRotation = TRUE;
- ivas_mc2sba( st_ivas->hTransSetup, p_tc, p_output, *nSamplesRendered, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE );
- }
- }
-
- /* Rendering */
- if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM )
- {
- if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || 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, crendInPlaceRotation ? p_output : p_tc, p_output, *nSamplesRendered, output_Fs ) ) != IVAS_ERR_OK )
- {
- return error;
- }
- }
- else
- {
- if ( ( error = ivas_rend_crendProcessSubframe( 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, crendInPlaceRotation ? p_output : p_tc, p_output, *nSamplesRendered, output_Fs, 0 ) ) != IVAS_ERR_OK )
- {
- return error;
- }
-
- ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_tc, p_output );
- }
- }
- else if ( st_ivas->renderer_type == RENDERER_MC )
- {
- ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, *nSamplesRendered, p_tc, p_output );
- }
- else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC )
- {
- ivas_mc2sba( st_ivas->hIntSetup, p_tc, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f );
- }
- else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD )
- {
- if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
- {
- if ( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK )
- {
- return error;
- }
- }
- else
- {
- if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK )
- {
- return error;
- }
-
- ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_tc, p_output );
- }
- }
- }
- else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX )
- {
- ivas_mc_paramupmix_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_tc, p_output );
-
- /* Rendering */
- if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) && !st_ivas->hDecoderConfig->Opt_Headrotation )
- {
- /* handled in CLDFB domain already */
- if ( output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
- {
- ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_output, p_output );
- }
- }
- else if ( st_ivas->renderer_type == RENDERER_MC )
- {
- ivas_ls_setup_conversion( st_ivas, MC_PARAMUPMIX_MAX_INPUT_CHANS, *nSamplesRendered, p_output, p_output );
- }
- else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC )
- {
- ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f );
- }
- }
- else if ( st_ivas->mc_mode == MC_MODE_PARAMMC )
- {
- ivas_param_mc_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output );
- }
- else if ( st_ivas->mc_mode == MC_MODE_MCMASA )
- {
- nchan_remapped = st_ivas->nchan_transport;
-
- if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC )
- {
- ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output );
- }
- else if ( st_ivas->renderer_type == RENDERER_DIRAC || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) /* rendering to CICPxx and Ambisonics */
- {
- ivas_dirac_dec_render( st_ivas, nchan_remapped, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output );
-
- if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC )
- {
- /* we still need to copy the separate channel if available */
- if ( st_ivas->hOutSetup.separateChannelEnabled )
- {
- mvr2r( p_tc[LFE_CHANNEL - 1], p_output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered );
- }
-
- ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f );
- }
- else if ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_5_1 && ( output_config == IVAS_AUDIO_CONFIG_5_1_2 || output_config == IVAS_AUDIO_CONFIG_5_1_4 || 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++ )
- {
- set_zero( p_output[n], *nSamplesRendered );
- }
- }
- }
-
- /* copy discrete C and TD LFE from internal TC to output */
- if ( st_ivas->hOutSetup.separateChannelEnabled )
- {
- if ( output_config == IVAS_AUDIO_CONFIG_5_1 || output_config == IVAS_AUDIO_CONFIG_7_1 ||
- output_config == IVAS_AUDIO_CONFIG_5_1_4 || output_config == IVAS_AUDIO_CONFIG_7_1_4 ||
- output_config == IVAS_AUDIO_CONFIG_5_1_2 || ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe > 0 ) )
- {
- mvr2r( p_tc[LFE_CHANNEL], p_output[LFE_CHANNEL], *nSamplesRendered );
- mvr2r( p_tc[LFE_CHANNEL - 1], p_output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered );
- }
- else if ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe == 0 )
- {
- mvr2r( p_tc[LFE_CHANNEL - 1], p_output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered );
- }
- }
- }
- }
-
- /*----------------------------------------------------------------*
- * Write IVAS output channels
- * - compensation for saturation
- * - float to integer conversion
- *----------------------------------------------------------------*/
-
- st_ivas->hTcBuffer->n_samples_available -= *nSamplesRendered;
- st_ivas->hTcBuffer->n_samples_rendered += *nSamplesRendered;
-
- /* 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 < min( MAX_OUTPUT_CHANNELS, ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ) ); n++ )
- {
- p_output[n] += st_ivas->hTcBuffer->n_samples_discard;
- }
- *nSamplesRendered -= st_ivas->hTcBuffer->n_samples_discard;
- st_ivas->hTcBuffer->n_samples_discard = 0;
- }
-
- if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
- {
- nchan_out_syn_output = BINAURAL_CHANNELS * st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses;
-#ifdef TMP_1342_WORKAROUND_DEC_FLUSH_BROKEN_IN_SR
- if ( st_ivas->flushing )
- {
- nchan_out_syn_output = BINAURAL_CHANNELS;
- }
-#endif
- }
- else
- {
- nchan_out_syn_output = nchan_out;
- }
-
- if ( is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ) == 0 )
- {
- if ( st_ivas->ivas_format != MONO_FORMAT )
- {
-#ifndef DISABLE_LIMITER
- ivas_limiter_dec( st_ivas->hLimiter, p_output, nchan_out, *nSamplesRendered, st_ivas->BER_detect );
-#endif
- }
- }
-
- switch ( pcm_resolution )
- {
- case PCM_INT16:
-#ifdef DEBUGGING
- st_ivas->noClipping +=
-#endif
- ivas_syn_output( p_output, *nSamplesRendered, nchan_out_syn_output, (int16_t *) data );
-
- break;
- case PCM_FLOAT32:
- ivas_buffer_deinterleaved_to_interleaved( p_output, nchan_out_syn_output, *nSamplesRendered, (float *) data );
- break;
- default:
- error = IVAS_ERR_UNKNOWN;
- break;
- }
-
- *nSamplesAvailableNext = st_ivas->hTcBuffer->n_samples_available;
-
- 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(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
- const int16_t 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 */
- uint16_t *nSamplesRendered, /* o : number of samples flushed */
- const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */
- void *data /* o : output synthesis signal */
-)
-{
- ivas_error error;
- int16_t n_samples_still_available;
- int16_t n_slots_still_available;
- int16_t n_samples_to_render;
- int16_t ch_idx;
- int16_t n_samples_granularity;
- DECODER_TC_BUFFER_HANDLE hTcBuffer;
- float *p_output[MAX_LS_CHANNELS + MAX_NUM_OBJECTS];
-
- 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[ch_idx] = st_ivas->p_output_f[ch_idx];
- }
-
- *nSamplesRendered = 0;
- hTcBuffer = st_ivas->hTcBuffer;
- n_samples_granularity = hTcBuffer->n_samples_granularity;
-
- /* get number of possible slots in new granularity */
- n_samples_still_available = hTcBuffer->n_samples_buffered - hTcBuffer->n_samples_rendered;
- n_slots_still_available = n_samples_still_available / tc_granularity_new;
- *nSamplesRendered = n_slots_still_available * tc_granularity_new;
- n_samples_to_render = *nSamplesRendered;
- 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 < max( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full ); ch_idx++ )
- {
- /* move it at the beginning of the TC buffer with zero padding */
- mvr2r( hTcBuffer->tc_buffer_old[ch_idx], hTcBuffer->tc[ch_idx], n_samples_to_render );
- set_zero( hTcBuffer->tc[ch_idx] + n_samples_to_render, 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 = 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;
-
-
- if ( st_ivas->ivas_format == ISM_FORMAT )
- {
- if ( ism_mode_old == ISM_MODE_DISC )
- {
- /* Binaural rendering */
- if ( renderer_type_old == RENDERER_BINAURAL_OBJECTS_TD )
- {
- if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_output, n_samples_granularity ) ) != IVAS_ERR_OK )
- {
- return error;
- }
- }
- else if ( renderer_type_old == RENDERER_BINAURAL_MIXER_CONV_ROOM )
- {
- /* Convert to CICPxx; used also for ISM->CICP19->binaural_room rendering */
- set_f( st_ivas->hIsmRendererData->interpolator, 1.0f, n_samples_granularity );
-
- ivas_ism_render_sf( st_ivas, renderer_type_old, p_output, n_samples_granularity );
-
- if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL,
- NULL, NULL, hTcBuffer, p_output, p_output, 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 ( st_ivas->ivas_format == MC_FORMAT )
- {
- if ( mc_mode_old == MC_MODE_MCT )
- {
- int16_t crendInPlaceRotation = FALSE;
-
- if ( st_ivas->transport_config != intern_config_old && ( intern_config_old == IVAS_AUDIO_CONFIG_FOA || intern_config_old == IVAS_AUDIO_CONFIG_HOA2 || intern_config_old == IVAS_AUDIO_CONFIG_HOA3 ) )
- {
- if ( ( st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe ) < ( hIntSetupOld->nchan_out_woLFE + hIntSetupOld->num_lfe ) )
- {
- crendInPlaceRotation = TRUE;
- ivas_mc2sba( st_ivas->hTransSetup, hTcBuffer->tc, p_output, n_samples_granularity, hIntSetupOld->ambisonics_order, GAIN_LFE );
- }
- }
- if ( renderer_type_old == RENDERER_BINAURAL_MIXER_CONV || renderer_type_old == RENDERER_BINAURAL_MIXER_CONV_ROOM )
- {
- if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, intern_config_old, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData,
- hIntSetupOld, st_ivas->hEFAPdata, hTcBuffer, crendInPlaceRotation ? p_output : hTcBuffer->tc, p_output, n_samples_granularity, st_ivas->hDecoderConfig->output_Fs, 0 ) ) != IVAS_ERR_OK )
- {
- return error;
- }
-
- ivas_binaural_add_LFE( st_ivas, n_samples_granularity, hTcBuffer->tc, p_output );
- }
- else if ( renderer_type_old == RENDERER_BINAURAL_OBJECTS_TD )
- {
- if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_output, n_samples_granularity ) ) != IVAS_ERR_OK )
- {
- return error;
- }
-
- ivas_binaural_add_LFE( st_ivas, n_samples_granularity, hTcBuffer->tc, p_output );
- }
- 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 ( st_ivas->ivas_format == MASA_ISM_FORMAT || st_ivas->ivas_format == MASA_FORMAT )
- {
- if ( ism_mode_old == ISM_MASA_MODE_DISC )
- {
- float *tc_local[MAX_NUM_OBJECTS];
- int16_t last_dirac_md_idx;
- uint16_t nSamplesAvailableNext;
- ISM_MODE ism_mode_orig;
- RENDERER_TYPE renderer_type_orig;
- int32_t ivas_total_brate;
-
- /* 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[ch_idx] = &hTcBuffer->tc[ch_idx + 2][hTcBuffer->n_samples_rendered];
- mvr2r( st_ivas->hMasaIsmData->delayBuffer[ch_idx], tc_local[ch_idx], st_ivas->hMasaIsmData->delayBuffer_size );
- }
-
- /* 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;
- set_s( st_ivas->hSpatParamRendCom->render_to_md_map, last_dirac_md_idx, n_slots_still_available );
-
- if ( ( error = ivas_omasa_dirac_td_binaural( st_ivas, (uint16_t) hTcBuffer->n_samples_granularity, nSamplesRendered, &nSamplesAvailableNext, CPE_CHANNELS, p_output ) ) != 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 ( st_ivas->ivas_format == SBA_ISM_FORMAT )
- {
- if ( ism_mode_old == ISM_SBA_MODE_DISC )
- {
- float *tc_local[MAX_TRANSPORT_CHANNELS];
- int16_t last_spar_md_idx;
- int16_t last_dirac_md_idx;
- uint16_t nSamplesAvailableNext;
- ISM_MODE ism_mode_orig;
- RENDERER_TYPE renderer_type_orig;
- int32_t ivas_total_brate;
-
- /* 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_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];
-#ifdef DEBUGGING
- assert( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV );
-#endif
-
- /* 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[ch_idx] = &st_ivas->hTcBuffer->tc[ch_idx][hTcBuffer->n_samples_rendered];
- mvr2r( st_ivas->hSbaIsmData->delayBuffer[ch_idx], tc_local[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;
-
- /* also adapt md maps, just use the last index */
- set_s( st_ivas->hSpar->render_to_md_map, last_spar_md_idx, n_slots_still_available );
- set_s( st_ivas->hSpatParamRendCom->render_to_md_map, last_dirac_md_idx, n_slots_still_available );
-
- /* render the last subframe */
- if ( ( error = ivas_osba_dirac_td_binaural( st_ivas, (uint16_t) n_samples_granularity, nSamplesRendered, &nSamplesAvailableNext, p_output ) ) != 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;
-
- /* Only write out the valid data*/
- if ( is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ) == 0 )
- {
- if ( st_ivas->ivas_format != MONO_FORMAT )
- {
-#ifndef DISABLE_LIMITER
- ivas_limiter_dec( st_ivas->hLimiter, p_output, st_ivas->hDecoderConfig->nchan_out, *nSamplesRendered, st_ivas->BER_detect );
-#endif
- }
- }
-
- switch ( pcm_resolution )
- {
- case PCM_INT16:
-#ifdef DEBUGGING
- st_ivas->noClipping +=
-#endif
- ivas_syn_output( p_output, *nSamplesRendered, st_ivas->hDecoderConfig->nchan_out, (int16_t *) data );
- break;
- case PCM_FLOAT32:
- ivas_buffer_deinterleaved_to_interleaved( p_output, st_ivas->hDecoderConfig->nchan_out, *nSamplesRendered, (float *) data );
- break;
- default:
- error = IVAS_ERR_UNKNOWN;
- break;
- }
-
- 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(
- Decoder_Struct *st_ivas /* i/o: main IVAS decoder structre */
-)
-{
- int16_t nMaxSlotsPerSubframe, nSlotsInFirstSubframe;
-
- /* render first frame with front zero padding and discarding those samples */
- nMaxSlotsPerSubframe = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ) / st_ivas->hTcBuffer->n_samples_granularity;
- nSlotsInFirstSubframe = nMaxSlotsPerSubframe - st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->nb_subframes - 1];
-
- if ( nSlotsInFirstSubframe > 0 )
- {
- st_ivas->hTcBuffer->n_samples_discard = ( 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;
- }
-
- 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(
- const int16_t default_interp_length, /* i : default length of the (full-frame) interpolator */
- const int16_t interp_length, /* i : length of the interpolator to be created */
- float *interpolator /* o : the interpolator */
-)
-{
- int16_t segment_len, idx;
- float dec;
-#ifdef DEBUGGING
- assert( default_interp_length % 2 == 0 );
-#endif
-
- segment_len = ( default_interp_length >> 1 );
- dec = 1.0f / default_interp_length;
-
- interpolator[interp_length - 1] = 1.0f;
- for ( idx = interp_length - 2; idx >= segment_len; idx-- )
- {
- interpolator[idx] = max( 0.0f, interpolator[idx + 1] - dec );
- }
-
- if ( interpolator[idx + 1] > 0.0f )
- {
- dec = interpolator[idx + 1] / ( segment_len + 1 );
- for ( ; idx >= 0; idx-- )
- {
- interpolator[idx] = interpolator[idx + 1] - dec;
- }
- }
- else
- {
- set_f( interpolator, 0.0f, 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(
- const int16_t nCldfbTs, /* i : number of time slots in the current frame */
- int16_t *subframe_nbslots, /* i/o: subframe grid */
- int16_t *nb_subframes /* i/o: number of subframes in the frame */
-)
-{
- uint16_t nSlotsInLastSubframe, nSlotsInFirstSubframe;
- uint16_t nCldfbSlotsLocal = nCldfbTs;
-
- /* 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 = ( PARAM_MC_MAX_NSLOTS_IN_SUBFRAME - subframe_nbslots[*nb_subframes - 1] );
- *nb_subframes = 0;
- if ( nSlotsInFirstSubframe > 0 )
- {
- *nb_subframes = 1;
- nCldfbSlotsLocal -= nSlotsInFirstSubframe;
- }
-
- *nb_subframes += (int16_t) ceilf( (float) nCldfbSlotsLocal / (float) PARAM_MC_MAX_NSLOTS_IN_SUBFRAME );
- nSlotsInLastSubframe = nCldfbSlotsLocal % PARAM_MC_MAX_NSLOTS_IN_SUBFRAME;
-
- set_s( subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS );
- set_s( subframe_nbslots, PARAM_MC_MAX_NSLOTS_IN_SUBFRAME, *nb_subframes );
-
- if ( nSlotsInFirstSubframe > 0 )
- {
- subframe_nbslots[0] = nSlotsInFirstSubframe;
- }
-
- if ( nSlotsInLastSubframe > 0 )
- {
- subframe_nbslots[*nb_subframes - 1] = nSlotsInLastSubframe;
- }
-
- return;
-}
-
-
-/*--------------------------------------------------------------------------*
- * ivas_dec_get_md_map()
- *
- * Get an meta data map adapted to (time scale modified) IVAS frame
- *--------------------------------------------------------------------------*/
-
-void ivas_dec_get_md_map(
- const int16_t default_len, /* i : default frame length in metadata slots */
- const int16_t len, /* i : length of the modified frames in metadata slots */
- const int16_t subframe_len, /* i : default length of a subframe */
- const int16_t offset, /* i : current read offset into the MD buffer */
- const int16_t buf_len, /* i : length of the metadata buffer */
- int16_t *map /* o : metadata index map */
-)
-{
- int16_t jbm_segment_len, map_idx, src_idx, src_idx_map;
- float dec, src_idx_f;
-
-#ifdef DEBUGGING
- assert( default_len % 2 == 0 );
-#endif
- jbm_segment_len = ( default_len >> 1 );
- dec = 1.0f / default_len;
-
- for ( map_idx = len - 1, src_idx = default_len - 1; map_idx >= jbm_segment_len; map_idx--, src_idx-- )
- {
- src_idx_map = max( 0, src_idx / subframe_len );
- map[map_idx] = ( offset + src_idx_map ) % buf_len;
- }
-
- /* 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 = ( (float) ( src_idx + 1 ) ) / ( (float) jbm_segment_len );
- src_idx_f = (float) ( src_idx + 1 ) - dec;
- for ( ; map_idx >= 0; map_idx-- )
- {
- src_idx = max( 0, ( (int16_t) round_f( src_idx_f ) ) / subframe_len );
- map[map_idx] = ( offset + src_idx ) % buf_len;
- src_idx_f -= dec;
- }
- }
- else
- {
- set_s( map, offset, 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(
- const int16_t len, /* i : length of the modified frames in metadata slots */
- const int16_t subframe_len, /* i : default length of a subframe */
- const int16_t offset, /* i : current read offset into the MD buffer */
- const int16_t buf_len, /* i : length of the metadata buffer */
- int16_t *map /* o : metadata index map */
-)
-{
- int16_t map_idx, sf_idx, sf_length, increment, subframes_written;
- float decimal, decimal_sum, eps;
- int16_t subframe_map_length[MAX_PARAM_SPATIAL_SUBFRAMES];
-
- /* subframe map length */
- sf_length = 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;
- }
- }
- else
- {
- /* uneven subframes */
- decimal = ( (float) len / (float) subframe_len ) - (float) sf_length;
- decimal_sum = decimal;
- eps = 0.001f;
- for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ )
- {
- increment = (int16_t) floorf( decimal_sum + eps );
- subframe_map_length[sf_idx] = sf_length + increment;
- if ( increment > 0 )
+ if ( ism_mode_old == ISM_MASA_MODE_DISC )
{
- decimal_sum -= 1.0f;
- }
- decimal_sum += decimal;
- }
- }
-
- /* map slots to subframes */
- sf_idx = 0;
- subframes_written = 0;
- for ( map_idx = 0; map_idx < len; map_idx++ )
- {
- map[map_idx] = ( offset + sf_idx ) % buf_len;
- if ( map_idx - subframes_written >= subframe_map_length[sf_idx] - 1 )
- {
- subframes_written += subframe_map_length[sf_idx];
- ++sf_idx;
- }
- }
+ float *tc_local[MAX_NUM_OBJECTS];
+ int16_t last_dirac_md_idx;
+ uint16_t nSamplesAvailableNext;
+ ISM_MODE ism_mode_orig;
+ RENDERER_TYPE renderer_type_orig;
+ int32_t ivas_total_brate;
- return;
-}
+ /* 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[ch_idx] = &hTcBuffer->tc[ch_idx + 2][hTcBuffer->n_samples_rendered];
+ mvr2r( st_ivas->hMasaIsmData->delayBuffer[ch_idx], tc_local[ch_idx], st_ivas->hMasaIsmData->delayBuffer_size );
+ }
+ /* 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];
-/*--------------------------------------------------------------------------*
- * ivas_dec_get_num_tc_channels()
- *
- * Get the number of channels provided to the renderer
- *--------------------------------------------------------------------------*/
+ /* 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;
+ set_s( st_ivas->hSpatParamRendCom->render_to_md_map, last_dirac_md_idx, n_slots_still_available );
-int16_t ivas_dec_get_num_tc_channels(
- Decoder_Struct *st_ivas /* i : IVAS decoder handle */
-)
-{
- int16_t num_tc;
- int32_t ivas_total_brate;
- AUDIO_CONFIG output_config;
+ if ( ( error = ivas_omasa_dirac_td_binaural( st_ivas, (uint16_t) hTcBuffer->n_samples_granularity, nSamplesRendered, &nSamplesAvailableNext, CPE_CHANNELS, p_output ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
- if ( st_ivas->renderer_type == RENDERER_DISABLE )
- {
- num_tc = st_ivas->hDecoderConfig->nchan_out;
- }
- else
- {
- num_tc = st_ivas->nchan_transport;
- }
+ /* 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 ( st_ivas->ivas_format == SBA_ISM_FORMAT )
+ {
+ if ( ism_mode_old == ISM_SBA_MODE_DISC )
+ {
+ float *tc_local[MAX_TRANSPORT_CHANNELS];
+ int16_t last_spar_md_idx;
+ int16_t last_dirac_md_idx;
+ uint16_t nSamplesAvailableNext;
+ ISM_MODE ism_mode_orig;
+ RENDERER_TYPE renderer_type_orig;
+ int32_t ivas_total_brate;
- output_config = st_ivas->hDecoderConfig->output_config;
+ /* 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_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];
+#ifdef DEBUGGING
+ assert( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV );
+#endif
- ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
+ /* 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[ch_idx] = &st_ivas->hTcBuffer->tc[ch_idx][hTcBuffer->n_samples_rendered];
+ mvr2r( st_ivas->hSbaIsmData->delayBuffer[ch_idx], tc_local[ch_idx], st_ivas->hSbaIsmData->delayBuffer_size );
+ }
- if ( st_ivas->ivas_format == MONO_FORMAT )
- {
- num_tc = 1;
- }
- else if ( st_ivas->ivas_format == STEREO_FORMAT && st_ivas->hDecoderConfig->nchan_out == 1 )
- {
- num_tc = 1;
- }
- else if ( st_ivas->ivas_format == ISM_FORMAT )
- {
- if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX )
- {
- num_tc = 1;
- }
- }
- else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT )
- {
- if ( st_ivas->sba_dirac_stereo_flag )
- {
- num_tc = CPE_CHANNELS;
- }
- else if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && ( ivas_total_brate > IVAS_SID_5k2 || ( ivas_total_brate <= IVAS_SID_5k2 && st_ivas->nCPE > 0 && st_ivas->hCPE[0] != NULL && st_ivas->hCPE[0]->nchan_out == 1 ) ) )
- {
- num_tc = 1; /* Only one channel transported */
- }
+ /* 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;
- if ( st_ivas->ivas_format == MASA_FORMAT && output_config == IVAS_AUDIO_CONFIG_EXTERNAL && st_ivas->nchan_transport == 2 && ivas_total_brate < MASA_STEREO_MIN_BITRATE && ivas_total_brate > IVAS_SID_5k2 )
- {
- num_tc = CPE_CHANNELS;
- }
+ /* also adapt md maps, just use the last index */
+ set_s( st_ivas->hSpar->render_to_md_map, last_spar_md_idx, n_slots_still_available );
+ set_s( st_ivas->hSpatParamRendCom->render_to_md_map, last_dirac_md_idx, n_slots_still_available );
- if ( st_ivas->ivas_format == SBA_FORMAT )
- {
- if ( num_tc == 3 )
- {
- num_tc++;
+ /* render the last subframe */
+ if ( ( error = ivas_osba_dirac_td_binaural( st_ivas, (uint16_t) n_samples_granularity, nSamplesRendered, &nSamplesAvailableNext, p_output ) ) != 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 ( st_ivas->ivas_format == MASA_ISM_FORMAT )
- {
- if ( output_config != IVAS_AUDIO_CONFIG_EXTERNAL )
+ else
{
- if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
- {
- num_tc++;
- }
- else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
- {
- num_tc += st_ivas->nchan_ism;
- }
+ return IVAS_ERROR( IVAS_ERR_WRONG_MODE, "Wrong IVAS format in VoIP renderer flushing!" );
}
+
+ hTcBuffer->n_samples_rendered = hTcBuffer->n_samples_granularity;
}
- else if ( st_ivas->ivas_format == SBA_ISM_FORMAT )
+
+ /* update global combined orientation start index */
+ ivas_combined_orientation_update_start_index( st_ivas->hCombinedOrientationData, *nSamplesRendered );
+
+ *nSamplesRendered = n_samples_to_render;
+
+ /* Only write out the valid data*/
+ if ( is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ) == 0 )
{
- if ( st_ivas->sba_dirac_stereo_flag )
- {
- num_tc = CPE_CHANNELS;
- }
- if ( num_tc == 3 )
- {
- num_tc++;
- }
- if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC )
+ if ( st_ivas->ivas_format != MONO_FORMAT )
{
- num_tc += st_ivas->nchan_ism;
+#ifndef DISABLE_LIMITER
+ ivas_limiter_dec( st_ivas->hLimiter, p_output, st_ivas->hDecoderConfig->nchan_out, *nSamplesRendered, st_ivas->BER_detect );
+#endif
}
}
- else if ( st_ivas->ivas_format == MC_FORMAT )
- {
- if ( output_config == IVAS_AUDIO_CONFIG_MONO )
- {
- num_tc = 1;
- }
- else if ( output_config == IVAS_AUDIO_CONFIG_STEREO )
- {
- num_tc = 2;
- }
- else if ( st_ivas->mc_mode == MC_MODE_MCT )
- {
- /* do all static dmx already in the TC decoder if less channels than transported... */
- if ( st_ivas->transport_config != st_ivas->intern_config && ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_FOA || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA2 || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA3 ) )
- {
- if ( ( st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe ) >= ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ) )
- {
- num_tc = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe;
- }
- }
- else if ( ( st_ivas->renderer_type == RENDERER_MC || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) && ( st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe ) >= ( st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ) )
- {
- num_tc = st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe;
- }
- }
- else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX )
- {
- num_tc = MC_PARAMUPMIX_MAX_TRANSPORT_CHANS;
- }
- else if ( st_ivas->mc_mode == MC_MODE_MCMASA )
- {
- if ( st_ivas->hOutSetup.separateChannelEnabled )
- {
- num_tc++;
- }
- if ( st_ivas->hOutSetup.separateChannelEnabled && ( output_config == IVAS_AUDIO_CONFIG_5_1 || output_config == IVAS_AUDIO_CONFIG_7_1 ||
- output_config == IVAS_AUDIO_CONFIG_5_1_4 || output_config == IVAS_AUDIO_CONFIG_7_1_4 ||
- output_config == IVAS_AUDIO_CONFIG_5_1_2 || ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe > 0 ) ) )
- {
- /* LFE is synthesized in TD with the TCs */
- num_tc++;
- }
- }
+ switch ( pcm_resolution )
+ {
+ case PCM_INT16:
+#ifdef DEBUGGING
+ st_ivas->noClipping +=
+#endif
+ ivas_syn_output( p_output, *nSamplesRendered, st_ivas->hDecoderConfig->nchan_out, (int16_t *) data );
+ break;
+ case PCM_FLOAT32:
+ ivas_buffer_deinterleaved_to_interleaved( p_output, st_ivas->hDecoderConfig->nchan_out, *nSamplesRendered, (float *) data );
+ break;
+ default:
+ error = IVAS_ERR_UNKNOWN;
+ break;
}
- return num_tc;
+ 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 */
-int16_t ivas_dec_get_render_granularity(
- const RENDERER_TYPE renderer_type, /* i : renderer type */
- const RENDERER_TYPE renderer_type_sec, /* i : secondary renderer type */
- const int32_t output_Fs /* i : sampling rate */
+ivas_error ivas_jbm_dec_set_discard_samples(
+ Decoder_Struct *st_ivas /* i/o: main IVAS decoder structre */
)
{
- int16_t render_granularity;
+ int16_t nMaxSlotsPerSubframe, nSlotsInFirstSubframe;
- if ( renderer_type == RENDERER_BINAURAL_OBJECTS_TD || /* TD renderer */
- renderer_type == RENDERER_BINAURAL_MIXER_CONV || renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM || /* Crend */
- renderer_type_sec == RENDERER_BINAURAL_OBJECTS_TD /* TD rend as a secondary renderer -> set the common granularity for both renderers */
- )
- {
- /* 5 ms granularity */
- render_granularity = NS2SA( output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES );
- }
- else
+ /* render first frame with front zero padding and discarding those samples */
+ nMaxSlotsPerSubframe = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ) / st_ivas->hTcBuffer->n_samples_granularity;
+ nSlotsInFirstSubframe = nMaxSlotsPerSubframe - st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->nb_subframes - 1];
+
+ if ( nSlotsInFirstSubframe > 0 )
{
- /* 1.25 ms granularity */
- render_granularity = NS2SA( output_Fs, CLDFB_SLOT_NS );
+ st_ivas->hTcBuffer->n_samples_discard = ( 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;
}
- 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(
- DECODER_TC_BUFFER_HANDLE hTcBuffer, /* i/o: TC buffer handle */
- const int32_t output_Fs, /* i : output sampling rate */
- const int16_t Opt_tsm /* i : TSM option flag */
+void ivas_dec_get_adapted_linear_interpolator(
+ const int16_t default_interp_length, /* i : default length of the (full-frame) interpolator */
+ const int16_t interp_length, /* i : length of the interpolator to be created */
+ float *interpolator /* o : the interpolator */
)
{
- int16_t nsamp_to_allocate;
- int16_t ch_idx, n_samp_full, n_samp_residual, offset;
-
- if ( Opt_tsm )
- {
- n_samp_full = ( NS2SA( output_Fs, MAX_JBM_L_FRAME_NS ) );
- n_samp_full = max( n_samp_full, L_FRAME48k ); /* buffers are shared between 'hTcBuffer->tc[]' and 'p_output_f[]': ensure minimal length */
- n_samp_residual = hTcBuffer->n_samples_granularity - 1;
- }
- else
- {
- n_samp_full = (int16_t) ( output_Fs / FRAMES_PER_SEC );
- n_samp_residual = 0;
- }
-
- nsamp_to_allocate = max( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full ) * n_samp_full;
+ int16_t segment_len, idx;
+ float dec;
+#ifdef DEBUGGING
+ assert( default_interp_length % 2 == 0 );
+#endif
- if ( Opt_tsm )
- {
- /* note: this is stack memory buffer for TC decoded and also time-scale modified audio signals */
- if ( ( hTcBuffer->tc_buffer = (float *) malloc( nsamp_to_allocate * sizeof( float ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TC Buffer\n" ) );
- }
- set_zero( hTcBuffer->tc_buffer, nsamp_to_allocate );
+ segment_len = ( default_interp_length >> 1 );
+ dec = 1.0f / default_interp_length;
- offset = 0;
- for ( ch_idx = 0; ch_idx < max( hTcBuffer->nchan_transport_rend, hTcBuffer->nchan_buffer_full ); ch_idx++ )
- {
- hTcBuffer->tc[ch_idx] = &hTcBuffer->tc_buffer[offset];
- offset += n_samp_full;
- }
- for ( ; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
- {
- hTcBuffer->tc[ch_idx] = NULL;
- }
+ interpolator[interp_length - 1] = 1.0f;
+ for ( idx = interp_length - 2; idx >= segment_len; idx-- )
+ {
+ interpolator[idx] = max( 0.0f, interpolator[idx + 1] - dec );
+ }
- /* 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[ch_idx] = (float *) malloc( n_samp_residual * sizeof( float ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TC Buffer\n" ) );
- }
- set_zero( hTcBuffer->tc_buffer_old[ch_idx], n_samp_residual );
- }
- for ( ; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
+ if ( interpolator[idx + 1] > 0.0f )
+ {
+ dec = interpolator[idx + 1] / ( segment_len + 1 );
+ for ( ; idx >= 0; idx-- )
{
- hTcBuffer->tc_buffer_old[ch_idx] = NULL;
+ interpolator[idx] = interpolator[idx + 1] - dec;
}
}
else
{
- hTcBuffer->tc_buffer = NULL;
-
- for ( ch_idx = 0; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
- {
- hTcBuffer->tc[ch_idx] = NULL;
- }
-
- for ( ch_idx = 0; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
- {
- hTcBuffer->tc_buffer_old[ch_idx] = NULL;
- }
+ set_f( interpolator, 0.0f, idx + 1 );
}
- hTcBuffer->tc_buffer2 = NULL;
-
- return IVAS_ERR_OK;
+ return;
}
/*--------------------------------------------------------------------------*
- * ivas_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_dec_tc_audio_deallocate(
- DECODER_TC_BUFFER_HANDLE hTcBuffer /* i/o: TC buffer handle */
+void ivas_dec_get_adapted_subframes(
+ const int16_t nCldfbTs, /* i : number of time slots in the current frame */
+ int16_t *subframe_nbslots, /* i/o: subframe grid */
+ int16_t *nb_subframes /* i/o: number of subframes in the frame */
)
{
- int16_t ch_idx;
+ uint16_t nSlotsInLastSubframe, nSlotsInFirstSubframe;
+ uint16_t nCldfbSlotsLocal = nCldfbTs;
- 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 = ( PARAM_MC_MAX_NSLOTS_IN_SUBFRAME - subframe_nbslots[*nb_subframes - 1] );
+ *nb_subframes = 0;
+ if ( nSlotsInFirstSubframe > 0 )
{
- if ( hTcBuffer->tc_buffer != NULL )
- {
- for ( ch_idx = 0; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
- {
- hTcBuffer->tc[ch_idx] = NULL;
- }
+ *nb_subframes = 1;
+ nCldfbSlotsLocal -= nSlotsInFirstSubframe;
+ }
- free( hTcBuffer->tc_buffer );
- hTcBuffer->tc_buffer = NULL;
- }
+ *nb_subframes += (int16_t) ceilf( (float) nCldfbSlotsLocal / (float) PARAM_MC_MAX_NSLOTS_IN_SUBFRAME );
+ nSlotsInLastSubframe = nCldfbSlotsLocal % PARAM_MC_MAX_NSLOTS_IN_SUBFRAME;
- for ( ch_idx = 0; ch_idx < MAX_INTERN_CHANNELS; ch_idx++ )
- {
- if ( hTcBuffer->tc_buffer_old[ch_idx] != NULL )
- {
- free( hTcBuffer->tc_buffer_old[ch_idx] );
- hTcBuffer->tc_buffer_old[ch_idx] = NULL;
- }
- }
+ set_s( subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS );
+ set_s( subframe_nbslots, PARAM_MC_MAX_NSLOTS_IN_SUBFRAME, *nb_subframes );
- if ( hTcBuffer->tc_buffer2 != NULL )
- {
- free( hTcBuffer->tc_buffer2 );
- hTcBuffer->tc_buffer2 = NULL;
- }
+ if ( nSlotsInFirstSubframe > 0 )
+ {
+ subframe_nbslots[0] = nSlotsInFirstSubframe;
+ }
+
+ if ( nSlotsInLastSubframe > 0 )
+ {
+ subframe_nbslots[*nb_subframes - 1] = nSlotsInLastSubframe;
}
return;
@@ -2204,158 +1107,151 @@ static void ivas_dec_tc_audio_deallocate(
/*--------------------------------------------------------------------------*
- * ivas_dec_tc_buffer_open()
+ * ivas_dec_get_md_map()
*
- * Open and initialize transport channel buffer handle
+ * Get an meta data map adapted to (time scale modified) IVAS frame
*--------------------------------------------------------------------------*/
-ivas_error ivas_dec_tc_buffer_open(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
- const TC_BUFFER_MODE tc_buffer_mode, /* i : buffer mode */
- const int16_t nchan_transport_rend, /* i : number of TCs for rendering */
- const int16_t nchan_transport_internal, /* i : number of totally buffered channels */
- const int16_t nchan_full, /* i : number of channels to fully store */
- const int16_t n_samples_granularity /* i : granularity of the renderer/buffer */
+void ivas_dec_get_md_map(
+ const int16_t default_len, /* i : default frame length in metadata slots */
+ const int16_t len, /* i : length of the modified frames in metadata slots */
+ const int16_t subframe_len, /* i : default length of a subframe */
+ const int16_t offset, /* i : current read offset into the MD buffer */
+ const int16_t buf_len, /* i : length of the metadata buffer */
+ int16_t *map /* o : metadata index map */
)
{
- DECODER_TC_BUFFER_HANDLE hTcBuffer;
- int16_t nMaxSlotsPerSubframe;
- ivas_error error;
+ int16_t jbm_segment_len, map_idx, src_idx, src_idx_map;
+ float dec, src_idx_f;
- /*-----------------------------------------------------------------*
- * prepare library opening
- *-----------------------------------------------------------------*/
+#ifdef DEBUGGING
+ assert( default_len % 2 == 0 );
+#endif
+ jbm_segment_len = ( default_len >> 1 );
+ dec = 1.0f / default_len;
- 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" ) );
+ src_idx_map = max( 0, src_idx / subframe_len );
+ map[map_idx] = ( offset + src_idx_map ) % buf_len;
}
- hTcBuffer->tc_buffer_mode = tc_buffer_mode;
- hTcBuffer->nchan_transport_rend = nchan_transport_rend;
- hTcBuffer->nchan_transport_internal = nchan_transport_internal;
- hTcBuffer->nchan_buffer_full = nchan_full;
- hTcBuffer->n_samples_granularity = n_samples_granularity;
- hTcBuffer->n_samples_available = 0;
- hTcBuffer->n_samples_buffered = 0;
- hTcBuffer->n_samples_rendered = 0;
- hTcBuffer->slots_rendered = 0;
- hTcBuffer->subframes_rendered = 0;
- hTcBuffer->n_samples_discard = 0;
- hTcBuffer->n_samples_flushed = 0;
- hTcBuffer->nb_subframes = MAX_PARAM_SPATIAL_SUBFRAMES;
-
- nMaxSlotsPerSubframe = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ) / hTcBuffer->n_samples_granularity;
- hTcBuffer->num_slots = nMaxSlotsPerSubframe * MAX_PARAM_SPATIAL_SUBFRAMES;
- set_s( hTcBuffer->subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS );
- set_s( hTcBuffer->subframe_nbslots, nMaxSlotsPerSubframe, MAX_PARAM_SPATIAL_SUBFRAMES );
-
- if ( ( error = ivas_dec_tc_audio_allocate( 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 = ( (float) ( src_idx + 1 ) ) / ( (float) jbm_segment_len );
+ src_idx_f = (float) ( src_idx + 1 ) - dec;
+ for ( ; map_idx >= 0; map_idx-- )
+ {
+ src_idx = max( 0, ( (int16_t) round_f( src_idx_f ) ) / subframe_len );
+ map[map_idx] = ( offset + src_idx ) % buf_len;
+ src_idx_f -= dec;
+ }
+ }
+ else
{
- return error;
+ set_s( map, offset, 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(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
- const TC_BUFFER_MODE tc_buffer_mode, /* i : new buffer mode */
- const int16_t nchan_transport_rend, /* i : new number of TCs for rendering */
- const int16_t nchan_transport_internal, /* i : new number of totally buffered channels */
- const int16_t nchan_full, /* i : new number of channels to fully store */
- const int16_t n_samples_granularity /* i : new granularity of the renderer/buffer */
+void ivas_dec_get_md_map_even_spacing(
+ const int16_t len, /* i : length of the modified frames in metadata slots */
+ const int16_t subframe_len, /* i : default length of a subframe */
+ const int16_t offset, /* i : current read offset into the MD buffer */
+ const int16_t buf_len, /* i : length of the metadata buffer */
+ int16_t *map /* o : metadata index map */
)
{
- int16_t ch_idx, num_tc_buffer_mem, n_samples_still_available;
- float 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;
-
- num_tc_buffer_mem = 0;
- n_samples_still_available = 0;
+ int16_t map_idx, sf_idx, sf_length, increment, subframes_written;
+ float decimal, decimal_sum, eps;
+ int16_t subframe_map_length[MAX_PARAM_SPATIAL_SUBFRAMES];
- if ( st_ivas->hDecoderConfig->Opt_tsm )
+ /* subframe map length */
+ sf_length = len / subframe_len;
+ if ( len % subframe_len == 0 )
{
- /* save samples of the TC buffer from the previous frame */
- num_tc_buffer_mem = min( hTcBuffer->nchan_transport_internal, nchan_transport_internal );
- n_samples_still_available = 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++ )
{
- mvr2r( hTcBuffer->tc_buffer_old[ch_idx] + hTcBuffer->n_samples_flushed, tc_buffer_mem[ch_idx], n_samples_still_available );
+ subframe_map_length[sf_idx] = sf_length;
}
}
-
- /* if granularity changes, adapt subframe_nb_slots */
- if ( n_samples_granularity != hTcBuffer->n_samples_granularity )
+ else
{
-#ifdef DEBUGGING
- int16_t nMaxSlotsPerSubframeOld;
-#endif
- int16_t nMaxSlotsPerSubframeNew;
-
- nMaxSlotsPerSubframeNew = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ) / n_samples_granularity;
-#ifdef DEBUGGING
- nMaxSlotsPerSubframeOld = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ) / st_ivas->hTcBuffer->n_samples_granularity;
- assert( hTcBuffer->subframe_nbslots[hTcBuffer->subframes_rendered - 1] == nMaxSlotsPerSubframeOld );
- if ( n_samples_granularity < hTcBuffer->n_samples_granularity )
- {
- assert( ( hTcBuffer->n_samples_granularity % n_samples_granularity ) == 0 );
- }
- else
- {
- assert( ( n_samples_granularity % hTcBuffer->n_samples_granularity ) == 0 );
- }
-#endif
- /* if samples were flushed, take that into account here */
- if ( n_samples_granularity < hTcBuffer->n_samples_granularity && hTcBuffer->n_samples_flushed > 0 )
+ /* uneven subframes */
+ decimal = ( (float) len / (float) subframe_len ) - (float) sf_length;
+ decimal_sum = decimal;
+ eps = 0.001f;
+ for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ )
{
- hTcBuffer->subframe_nbslots[hTcBuffer->subframes_rendered - 1] = hTcBuffer->n_samples_flushed / n_samples_granularity;
- hTcBuffer->n_samples_flushed = 0;
+ increment = (int16_t) floorf( decimal_sum + eps );
+ subframe_map_length[sf_idx] = sf_length + increment;
+ if ( increment > 0 )
+ {
+ decimal_sum -= 1.0f;
+ }
+ decimal_sum += decimal;
}
- else
+ }
+
+ /* map slots to subframes */
+ sf_idx = 0;
+ subframes_written = 0;
+ for ( map_idx = 0; map_idx < len; map_idx++ )
+ {
+ map[map_idx] = ( offset + sf_idx ) % buf_len;
+ if ( map_idx - subframes_written >= subframe_map_length[sf_idx] - 1 )
{
- hTcBuffer->subframe_nbslots[hTcBuffer->subframes_rendered - 1] = nMaxSlotsPerSubframeNew;
+ subframes_written += subframe_map_length[sf_idx];
+ ++sf_idx;
}
}
- hTcBuffer->tc_buffer_mode = tc_buffer_mode;
- hTcBuffer->nchan_transport_rend = nchan_transport_rend;
- hTcBuffer->nchan_transport_internal = nchan_transport_internal;
- hTcBuffer->nchan_buffer_full = nchan_full;
- hTcBuffer->n_samples_granularity = n_samples_granularity;
+ return;
+}
+
- /* reallocate TC audio buffers */
+/*--------------------------------------------------------------------------*
+ * ivas_dec_get_render_granularity()
+ *
+ * Get renderer granularity
+ *--------------------------------------------------------------------------*/
- ivas_dec_tc_audio_deallocate( hTcBuffer );
+/*! r: render granularity */
+int16_t ivas_dec_get_render_granularity(
+ const RENDERER_TYPE renderer_type, /* i : renderer type */
+ const RENDERER_TYPE renderer_type_sec, /* i : secondary renderer type */
+ const int32_t output_Fs /* i : sampling rate */
+)
+{
+ int16_t render_granularity;
- if ( ( error = ivas_dec_tc_audio_allocate( hTcBuffer, st_ivas->hDecoderConfig->output_Fs, st_ivas->hDecoderConfig->Opt_tsm ) ) != IVAS_ERR_OK )
+ if ( renderer_type == RENDERER_BINAURAL_OBJECTS_TD || /* TD renderer */
+ renderer_type == RENDERER_BINAURAL_MIXER_CONV || renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM || /* Crend */
+ 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( output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES );
}
-
- /* propagate samples of the TC buffer from the previous frame */
- for ( ch_idx = 0; ch_idx < num_tc_buffer_mem; ch_idx++ )
+ else
{
- mvr2r( tc_buffer_mem[ch_idx], hTcBuffer->tc_buffer_old[ch_idx], n_samples_still_available );
+ /* 1.25 ms granularity */
+ render_granularity = NS2SA( output_Fs, CLDFB_SLOT_NS );
}
- return IVAS_ERR_OK;
+ return render_granularity;
}
@@ -2404,28 +1300,6 @@ static void ivas_dec_tc_buffer_playout(
}
-/*--------------------------------------------------------------------------*
- * ivas_dec_tc_buffer_close()
- *
- * Close transport channel buffer handle
- *--------------------------------------------------------------------------*/
-
-void ivas_dec_tc_buffer_close(
- DECODER_TC_BUFFER_HANDLE *phTcBuffer /* i/o: TC buffer handle */
-)
-{
- if ( *phTcBuffer != NULL )
- {
- ivas_dec_tc_audio_deallocate( *phTcBuffer );
-
- free( *phTcBuffer );
- *phTcBuffer = NULL;
- }
-
- return;
-}
-
-
/*--------------------------------------------------------------------------*
* ivas_dec_td_renderers_adapt_subframes()
*
@@ -2476,94 +1350,6 @@ void ivas_dec_td_renderers_adapt_subframes(
}
-/*--------------------------------------------------------------------------*
- * ivas_dec_get_tc_buffer_mode()
- *
- *
- *--------------------------------------------------------------------------*/
-
-TC_BUFFER_MODE ivas_dec_get_tc_buffer_mode(
- Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
-)
-{
- TC_BUFFER_MODE buffer_mode;
-
- buffer_mode = TC_BUFFER_MODE_BUFFER;
-
- 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;
- 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;
- break;
- break;
- case RENDERER_MC_PARAMMC:
- if ( 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 */
- }
- else
- {
- buffer_mode = TC_BUFFER_MODE_RENDERER;
- }
- break;
- case RENDERER_MC:
- if ( ivas_dec_get_num_tc_channels( st_ivas ) != st_ivas->hDecoderConfig->nchan_out )
- {
- buffer_mode = TC_BUFFER_MODE_RENDERER;
- }
- break;
- case RENDERER_SBA_LINEAR_ENC:
- if ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCT && ( st_ivas->renderer_type == RENDERER_MC || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) && ( st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe ) >= ( st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ) )
- {
- buffer_mode = TC_BUFFER_MODE_BUFFER;
- }
- else
- {
- buffer_mode = TC_BUFFER_MODE_RENDERER;
- }
- break;
- case RENDERER_SBA_LINEAR_DEC:
- if ( st_ivas->ivas_format == SBA_FORMAT && ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_MONO || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO ) )
- {
- buffer_mode = TC_BUFFER_MODE_BUFFER;
- }
- else
- {
- buffer_mode = TC_BUFFER_MODE_RENDERER;
- }
- break;
-#ifdef DEBUGGING
- default:
- assert( 0 );
-#endif
- }
-
- return buffer_mode;
-}
-
-
/*--------------------------------------------------------------------------*
* ivas_jbm_dec_masa_metadata_open()
*