From 1db032e42c387433ff2edbf6550e3a125d77db2b Mon Sep 17 00:00:00 2001 From: vaclav Date: Fri, 13 Mar 2026 10:26:41 +0100 Subject: [PATCH 1/9] FIX_FMSW_DEC --- apps/decoder.c | 7 +- lib_com/options.h | 1 + lib_dec/ivas_init_dec.c | 28 + lib_dec/lib_dec.c | 8448 ++++++++++++++++++++------------------- 4 files changed, 4276 insertions(+), 4208 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 44af4ba1e..b1d050c0a 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -4345,6 +4345,9 @@ static ivas_error restartDecoder( IVAS_AUDIO_CONFIG outputConfig = ( decMode == IVAS_DEC_MODE_IVAS ) ? arg->outputConfig : IVAS_AUDIO_CONFIG_MONO; +#ifdef FIX_FMSW_DEC + // the calling of following 3 functions could be avoided as well +#endif if ( ( error = IVAS_DEC_Configure( hIvasDec, arg->output_Fs, outputConfig, arg->render_num_subframes, arg->customLsOutputEnabled, arg->hrtfReaderEnabled, arg->enableHeadRotation, arg->enableExternalOrientation, arg->orientation_tracking, arg->renderConfigEnabled, arg->roomSize, arg->non_diegetic_pan_enabled, arg->non_diegetic_pan_gain, arg->dpidEnabled, aeID, arg->objEditEnabled, arg->delayCompensationEnabled ) ) != IVAS_ERR_OK ) @@ -4368,7 +4371,7 @@ static ivas_error restartDecoder( goto cleanup; } - if ( arg->voipMode ) +#ifndef FIX_FMSW_DEC { if ( ( error = IVAS_DEC_EnableVoIP( hIvasDec, 60, arg->inputFormat ) ) != IVAS_ERR_OK ) { @@ -4376,7 +4379,7 @@ static ivas_error restartDecoder( goto cleanup; } } - +#endif if ( ( error = IVAS_DEC_PrintConfig( hIvasDec, 1, arg->voipMode ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_PrintConfig failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); diff --git a/lib_com/options.h b/lib_com/options.h index a7fe3da41..5628b5fb1 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -171,6 +171,7 @@ #define FIX_FLOAT_1493_MASA_ENCODE_STABILITY_IMPROVE /* Nokia: float issue 1493: Improves float decision stability in MASA encoding by adjusting reduction code */ #define FIX_BASOP_2436_REUSED_CLDFB_IN_OMASA_SR /* FhG: basop issue 2436 (related to basop 2283): fix garbage output for >1 object OMASA with extrend as ISAR prerenderer */ #define FIX_FLOAT_1528_5MS_REND_ISM_META_DELAY_COMPENSATION /* Nokia: float issue 1528: Fixes incorrect compensation for ISM metadata delay in 5ms TD rendering */ +#define FIX_FMSW_DEC /* float issue 1542: fix JBM issue in format switching */ /* ##################### End NON-BE switches ########################### */ diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index b16a31604..a6f0bd3e6 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -2739,9 +2739,16 @@ void ivas_initialize_handles_dec( st_ivas->hCPE[i] = NULL; } +#ifdef FIX_FMSW_DEC + if ( st_ivas->restartNeeded == 0 ) + { +#endif st_ivas->bit_stream = NULL; st_ivas->mem_hp20_out = NULL; st_ivas->hLimiter = NULL; +#ifdef FIX_FMSW_DEC + } +#endif /* ISM metadata handles */ for ( i = 0; i < MAX_NUM_OBJECTS; i++ ) @@ -2867,6 +2874,10 @@ void ivas_destroy_dec( } } +#ifdef FIX_FMSW_DEC + if ( st_ivas->restartNeeded == 0 ) + { +#endif /* HP20 filter handles */ if ( st_ivas->mem_hp20_out != NULL ) { @@ -2878,6 +2889,9 @@ void ivas_destroy_dec( free( st_ivas->mem_hp20_out ); st_ivas->mem_hp20_out = NULL; } +#ifdef FIX_FMSW_DEC + } +#endif /* ISM metadata handles */ ivas_ism_metadata_close( st_ivas->hIsmMetaData, 0 ); @@ -3004,6 +3018,10 @@ void ivas_destroy_dec( st_ivas->pAcousticEnvironments = NULL; } +#ifdef FIX_FMSW_DEC + if ( st_ivas->restartNeeded == 0 ) + { +#endif /* Limiter struct */ ivas_limiter_close( &( st_ivas->hLimiter ) ); @@ -3013,6 +3031,9 @@ void ivas_destroy_dec( free( st_ivas->hDecoderConfig ); st_ivas->hDecoderConfig = NULL; } +#ifdef FIX_FMSW_DEC + } +#endif /* TC buffer structure */ ivas_dec_tc_buffer_close( &st_ivas->hTcBuffer ); @@ -3030,7 +3051,14 @@ void ivas_destroy_dec( } /* main IVAS handle */ +#ifdef FIX_FMSW_DEC + if ( st_ivas->restartNeeded == 0 ) + { +#endif free( st_ivas ); +#ifdef FIX_FMSW_DEC + } +#endif return; } diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 0afec7310..078ea6db2 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -150,59 +150,70 @@ ivas_error IVAS_DEC_Open( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - /*-----------------------------------------------------------------* - * Allocate and initialize IVAS application decoder handle - *-----------------------------------------------------------------*/ - - if ( ( *phIvasDec = (IVAS_DEC_HANDLE) malloc( sizeof( struct IVAS_DEC ) ) ) == NULL ) +#ifdef FIX_FMSW_DEC + if ( ( *phIvasDec ) != NULL && ( *phIvasDec )->st_ivas != NULL && ( *phIvasDec )->st_ivas->restartNeeded != 0 ) { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS decoder handle" ); + hIvasDec = *phIvasDec; } + else + { +#endif + /*-----------------------------------------------------------------* + * Allocate and initialize IVAS application decoder handle + *-----------------------------------------------------------------*/ + + if ( ( *phIvasDec = (IVAS_DEC_HANDLE) malloc( sizeof( struct IVAS_DEC ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS decoder handle" ); + } + + hIvasDec = *phIvasDec; + hIvasDec->hVoIP = NULL; + hIvasDec->hTimeScaler = NULL; + hIvasDec->tsm_scale = 100; + hIvasDec->tsm_max_scaling = 0; + hIvasDec->tsm_quality = 1.0f; + hIvasDec->timeScalingDone = 0; + hIvasDec->needNewFrame = false; + hIvasDec->nTransportChannelsOld = 0; + hIvasDec->nSamplesAvailableNext = 0; + hIvasDec->nSamplesFrame = 0; + hIvasDec->hasBeenFedFrame = false; + hIvasDec->hasBeenFedFirstGoodFrame = false; + hIvasDec->hasDecodedFirstGoodFrame = false; + hIvasDec->isInitialized = false; + hIvasDec->updateOrientation = false; + hIvasDec->flushbuffer = NULL; + hIvasDec->pcmType = IVAS_DEC_PCM_INVALID; + hIvasDec->nSamplesFlushed = 0; + hIvasDec->hasBeenPreparedRendering = false; + + hIvasDec->mode = mode; - hIvasDec = *phIvasDec; - hIvasDec->hVoIP = NULL; - hIvasDec->hTimeScaler = NULL; - hIvasDec->tsm_scale = 100; - hIvasDec->tsm_max_scaling = 0; - hIvasDec->tsm_quality = 1.0f; - hIvasDec->timeScalingDone = 0; - hIvasDec->needNewFrame = false; - hIvasDec->nTransportChannelsOld = 0; - hIvasDec->nSamplesAvailableNext = 0; - hIvasDec->nSamplesFrame = 0; - hIvasDec->hasBeenFedFrame = false; - hIvasDec->hasBeenFedFirstGoodFrame = false; - hIvasDec->hasDecodedFirstGoodFrame = false; - hIvasDec->isInitialized = false; - hIvasDec->updateOrientation = false; - hIvasDec->flushbuffer = NULL; - hIvasDec->pcmType = IVAS_DEC_PCM_INVALID; - hIvasDec->nSamplesFlushed = 0; - hIvasDec->hasBeenPreparedRendering = false; - - hIvasDec->mode = mode; - - hIvasDec->bitstreamformat = G192; + hIvasDec->bitstreamformat = G192; #ifdef DEBUGGING - hIvasDec->Opt_VOIP = 0; + hIvasDec->Opt_VOIP = 0; #endif - hIvasDec->amrwb_rfc4867_flag = -1; - hIvasDec->prev_ft_speech = 1; /* RXDTX handler previous frametype flag for G.192 format AMRWB SID_FIRST detection */ - hIvasDec->CNG = 0; /* RXDTX handler CNG = 1, no CNG = 0*/ + hIvasDec->amrwb_rfc4867_flag = -1; + hIvasDec->prev_ft_speech = 1; /* RXDTX handler previous frametype flag for G.192 format AMRWB SID_FIRST detection */ + hIvasDec->CNG = 0; /* RXDTX handler CNG = 1, no CNG = 0*/ - /*-----------------------------------------------------------------* - * Initialize IVAS-codec decoder state - *-----------------------------------------------------------------*/ + /*-----------------------------------------------------------------* + * Initialize IVAS-codec decoder state + *-----------------------------------------------------------------*/ - if ( ( hIvasDec->st_ivas = (Decoder_Struct *) malloc( sizeof( Decoder_Struct ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS decoder structure" ); - } + if ( ( hIvasDec->st_ivas = (Decoder_Struct *) malloc( sizeof( Decoder_Struct ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS decoder structure" ); + } - if ( ( hIvasDec->st_ivas->hDecoderConfig = (DECODER_CONFIG_HANDLE) malloc( sizeof( DECODER_CONFIG ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for Decoder config structure" ); + if ( ( hIvasDec->st_ivas->hDecoderConfig = (DECODER_CONFIG_HANDLE) malloc( sizeof( DECODER_CONFIG ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for Decoder config structure" ); + } +#ifdef FIX_FMSW_DEC } +#endif /*-----------------------------------------------------------------* * Initialize IVAS-codec decoder state @@ -211,3488 +222,3490 @@ ivas_error IVAS_DEC_Open( st_ivas = hIvasDec->st_ivas; /* initialize Decoder Config. handle */ - init_decoder_config( hIvasDec->st_ivas->hDecoderConfig ); +#ifdef FIX_FMSW_DEC + if ( st_ivas->restartNeeded == 0 ) + { +#endif + init_decoder_config( hIvasDec->st_ivas->hDecoderConfig ); +#ifdef FIX_FMSW_DEC + } +#endif - /* initialize pointers to handles to NULL */ - ivas_initialize_handles_dec( st_ivas ); + /* initialize pointers to handles to NULL */ + ivas_initialize_handles_dec( st_ivas ); - st_ivas->restartNeeded = 0; + st_ivas->restartNeeded = 0; - /* set high-level parameters */ + /* set high-level parameters */ - st_ivas->codec_mode = 0; /* unknown before first frame */ - st_ivas->transport_config = IVAS_AUDIO_CONFIG_INVALID; - st_ivas->intern_config = IVAS_AUDIO_CONFIG_INVALID; - st_ivas->writeFECoffset = 0; - st_ivas->sba_analysis_order = 0; /* not really used in EVS mode, but initialize here to fix MSAN complaint */ + st_ivas->codec_mode = 0; /* unknown before first frame */ + st_ivas->transport_config = IVAS_AUDIO_CONFIG_INVALID; + st_ivas->intern_config = IVAS_AUDIO_CONFIG_INVALID; + st_ivas->writeFECoffset = 0; + st_ivas->sba_analysis_order = 0; /* not really used in EVS mode, but initialize here to fix MSAN complaint */ - if ( mode == IVAS_DEC_MODE_EVS ) - { - st_ivas->element_mode_init = EVS_MONO; - st_ivas->ivas_format = MONO_FORMAT; - hIvasDec->hasDecodedFirstGoodFrame = true; /* Functionality to suppress output for initial lost frames is disabled in EVS operation */ + if ( mode == IVAS_DEC_MODE_EVS ) + { + st_ivas->element_mode_init = EVS_MONO; + st_ivas->ivas_format = MONO_FORMAT; + hIvasDec->hasDecodedFirstGoodFrame = true; /* Functionality to suppress output for initial lost frames is disabled in EVS operation */ - return IVAS_ERR_OK; - } - else if ( mode == IVAS_DEC_MODE_IVAS ) - { - st_ivas->element_mode_init = -1; - st_ivas->ivas_format = UNDEFINED_FORMAT; - st_ivas->renderer_type = RENDERER_DISABLE; - st_ivas->ini_frame = 0; - st_ivas->ini_active_frame = 0; + return IVAS_ERR_OK; + } + else if ( mode == IVAS_DEC_MODE_IVAS ) + { + st_ivas->element_mode_init = -1; + st_ivas->ivas_format = UNDEFINED_FORMAT; + st_ivas->renderer_type = RENDERER_DISABLE; + st_ivas->ini_frame = 0; + st_ivas->ini_active_frame = 0; - st_ivas->ism_mode = ISM_MODE_NONE; - st_ivas->mc_mode = MC_MODE_NONE; + st_ivas->ism_mode = ISM_MODE_NONE; + st_ivas->mc_mode = MC_MODE_NONE; - st_ivas->sba_order = 0; - st_ivas->sba_planar = 0; + st_ivas->sba_order = 0; + st_ivas->sba_planar = 0; - return IVAS_ERR_OK; + return IVAS_ERR_OK; + } + + return IVAS_ERR_WRONG_PARAMS; } - return IVAS_ERR_WRONG_PARAMS; -} + /*-------------------------------------------------------------------------* + * isar_set_split_rend_setup() + * + * Setup IVAS split rendering + *-------------------------------------------------------------------------*/ -/*-------------------------------------------------------------------------* - * isar_set_split_rend_setup() - * - * Setup IVAS split rendering - *-------------------------------------------------------------------------*/ - -static ivas_error isar_set_split_rend_setup( - ISAR_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, - const ISAR_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, - const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, - ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ -) -{ - splitRendBits->bits_read = 0; - splitRendBits->bits_written = 0; - splitRendBits->buf_len = ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES; - splitRendBits->codec = ISAR_SPLIT_REND_CODEC_DEFAULT; - splitRendBits->pose_correction = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; - splitRendBits->codec_frame_size_ms = 0; - splitRendBits->isar_frame_size_ms = 0; - splitRendBits->lc3plus_highres = 0; - - ISAR_PRE_REND_GetMultiBinPoseData( hSplitBinConfig, &hSplitBinRend->splitrend.multiBinPoseData, ( hCombinedOrientationData != NULL ) ? hCombinedOrientationData->sr_pose_pred_axis : DEFAULT_AXIS ); - - if ( hCombinedOrientationData != NULL ) + static ivas_error isar_set_split_rend_setup( + ISAR_DEC_SPLIT_REND_WRAPPER * hSplitBinRend, + const ISAR_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, + const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, + ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ + ) { - isar_set_split_rend_ht_setup( &hSplitBinRend->splitrend, hCombinedOrientationData->Quaternions, hCombinedOrientationData->Rmat ); - } + splitRendBits->bits_read = 0; + splitRendBits->bits_written = 0; + splitRendBits->buf_len = ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES; + splitRendBits->codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + splitRendBits->pose_correction = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + splitRendBits->codec_frame_size_ms = 0; + splitRendBits->isar_frame_size_ms = 0; + splitRendBits->lc3plus_highres = 0; - return IVAS_ERR_OK; -} - -/*---------------------------------------------------------------------* - * init_decoder_config() - * - * Initialize Decoder Config. handle - *---------------------------------------------------------------------*/ + ISAR_PRE_REND_GetMultiBinPoseData( hSplitBinConfig, &hSplitBinRend->splitrend.multiBinPoseData, ( hCombinedOrientationData != NULL ) ? hCombinedOrientationData->sr_pose_pred_axis : DEFAULT_AXIS ); -static void init_decoder_config( - DECODER_CONFIG_HANDLE hDecoderConfig /* i/o: configuration structure */ -) -{ - hDecoderConfig->Opt_AMR_WB = 0; - hDecoderConfig->output_Fs = -1; - hDecoderConfig->nchan_out = 1; - hDecoderConfig->output_config = IVAS_AUDIO_CONFIG_INVALID; - hDecoderConfig->Opt_LsCustom = 0; - hDecoderConfig->Opt_HRTF_binary = 0; - hDecoderConfig->Opt_Headrotation = 0; - hDecoderConfig->Opt_RendConfigCustom = 0; - hDecoderConfig->room_size = IVAS_ROOM_SIZE_AUTO; - hDecoderConfig->orientation_tracking = IVAS_HEAD_ORIENT_TRK_NONE; - hDecoderConfig->Opt_non_diegetic_pan = 0; - hDecoderConfig->non_diegetic_pan_gain = 0; - hDecoderConfig->Opt_tsm = 0; - hDecoderConfig->Opt_delay_comp = 0; - hDecoderConfig->Opt_ExternalOrientation = 0; - hDecoderConfig->Opt_dpid_on = 0; - hDecoderConfig->Opt_aeid_on = 0; - hDecoderConfig->Opt_ObjEdit_on = 0; - - return; -} + if ( hCombinedOrientationData != NULL ) + { + isar_set_split_rend_ht_setup( &hSplitBinRend->splitrend, hCombinedOrientationData->Quaternions, hCombinedOrientationData->Rmat ); + } + return IVAS_ERR_OK; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_Close( ) - * - * Deallocate IVAS decoder memory handles - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * init_decoder_config() + * + * Initialize Decoder Config. handle + *---------------------------------------------------------------------*/ -void IVAS_DEC_Close( - IVAS_DEC_HANDLE *phIvasDec /* i/o: pointer to IVAS decoder handle */ -) -{ - /* Free all memory */ - if ( phIvasDec == NULL || *phIvasDec == NULL ) + static void init_decoder_config( + DECODER_CONFIG_HANDLE hDecoderConfig /* i/o: configuration structure */ + ) { + hDecoderConfig->Opt_AMR_WB = 0; + hDecoderConfig->output_Fs = -1; + hDecoderConfig->nchan_out = 1; + hDecoderConfig->output_config = IVAS_AUDIO_CONFIG_INVALID; + hDecoderConfig->Opt_LsCustom = 0; + hDecoderConfig->Opt_HRTF_binary = 0; + hDecoderConfig->Opt_Headrotation = 0; + hDecoderConfig->Opt_RendConfigCustom = 0; + hDecoderConfig->room_size = IVAS_ROOM_SIZE_AUTO; + hDecoderConfig->orientation_tracking = IVAS_HEAD_ORIENT_TRK_NONE; + hDecoderConfig->Opt_non_diegetic_pan = 0; + hDecoderConfig->non_diegetic_pan_gain = 0; + hDecoderConfig->Opt_tsm = 0; + hDecoderConfig->Opt_delay_comp = 0; + hDecoderConfig->Opt_ExternalOrientation = 0; + hDecoderConfig->Opt_dpid_on = 0; + hDecoderConfig->Opt_aeid_on = 0; + hDecoderConfig->Opt_ObjEdit_on = 0; + return; } - if ( ( *phIvasDec )->hVoIP ) - { - ivas_destroy_handle_VoIP( ( *phIvasDec )->hVoIP ); - ( *phIvasDec )->hVoIP = NULL; - } - if ( ( *phIvasDec )->st_ivas ) - { - /* destroy Split binaural renderer (ISAR) handle */ - ivas_destroy_handle_isar( &( *phIvasDec )->st_ivas->hSplitBinRend ); + /*---------------------------------------------------------------------* + * IVAS_DEC_Close( ) + * + * Deallocate IVAS decoder memory handles + *---------------------------------------------------------------------*/ - /* destroy IVAS decoder handles */ - ivas_destroy_dec( ( *phIvasDec )->st_ivas ); - ( *phIvasDec )->st_ivas = NULL; - } + void IVAS_DEC_Close( + IVAS_DEC_HANDLE * phIvasDec /* i/o: pointer to IVAS decoder handle */ + ) + { + /* Free all memory */ + if ( phIvasDec == NULL || *phIvasDec == NULL ) + { + return; + } - apa_exit( &( *phIvasDec )->hTimeScaler ); +#ifdef FIX_FMSW_DEC + if ( ( *phIvasDec )->st_ivas->restartNeeded == 0 && ( *phIvasDec )->hVoIP ) +#else + if ( ( *phIvasDec )->hVoIP ) +#endif + { + ivas_destroy_handle_VoIP( ( *phIvasDec )->hVoIP ); + ( *phIvasDec )->hVoIP = NULL; + } - if ( ( *phIvasDec )->flushbuffer != NULL ) - { - free( ( *phIvasDec )->flushbuffer ); - } + if ( ( *phIvasDec )->st_ivas ) + { + /* destroy Split binaural renderer (ISAR) handle */ + ivas_destroy_handle_isar( &( *phIvasDec )->st_ivas->hSplitBinRend ); - free( *phIvasDec ); - *phIvasDec = NULL; - phIvasDec = NULL; + /* destroy IVAS decoder handles */ + ivas_destroy_dec( ( *phIvasDec )->st_ivas ); +#ifdef FIX_FMSW_DEC + if ( ( *phIvasDec )->st_ivas->restartNeeded == 0 ) + { +#endif + ( *phIvasDec )->st_ivas = NULL; +#ifdef FIX_FMSW_DEC + } +#endif + } - return; -} +#ifdef FIX_FMSW_DEC + if ( ( *phIvasDec )->st_ivas->restartNeeded == 0 ) + { +#endif + apa_exit( &( *phIvasDec )->hTimeScaler ); + if ( ( *phIvasDec )->flushbuffer != NULL ) + { + free( ( *phIvasDec )->flushbuffer ); + } -/*---------------------------------------------------------------------* - * mapIvasFormat( ) - * - * - *---------------------------------------------------------------------*/ + free( *phIvasDec ); + *phIvasDec = NULL; + phIvasDec = NULL; +#ifdef FIX_FMSW_DEC + } +#endif -static IVAS_DEC_BS_FORMAT mapIvasFormat( - const IVAS_FORMAT ivas_format ) -{ - switch ( ivas_format ) - { - case MONO_FORMAT: - return IVAS_DEC_BS_MONO; - case STEREO_FORMAT: - return IVAS_DEC_BS_STEREO; - case ISM_FORMAT: - return IVAS_DEC_BS_OBJ; - case MC_FORMAT: - return IVAS_DEC_BS_MC; - case SBA_FORMAT: - return IVAS_DEC_BS_SBA; - case SBA_ISM_FORMAT: - return IVAS_DEC_BS_SBA_ISM; - case MASA_FORMAT: - return IVAS_DEC_BS_MASA; - case MASA_ISM_FORMAT: - return IVAS_DEC_BS_MASA_ISM; - default: - break; + return; } - return IVAS_DEC_BS_UNKOWN; -} - -/*---------------------------------------------------------------------* - * create_flush_buffer() - * - * Create flush buffer - needed for binaural outputs with TSM or in VoIP mode - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * mapIvasFormat( ) + * + * + *---------------------------------------------------------------------*/ + + static IVAS_DEC_BS_FORMAT mapIvasFormat( + const IVAS_FORMAT ivas_format ) + { + switch ( ivas_format ) + { + case MONO_FORMAT: + return IVAS_DEC_BS_MONO; + case STEREO_FORMAT: + return IVAS_DEC_BS_STEREO; + case ISM_FORMAT: + return IVAS_DEC_BS_OBJ; + case MC_FORMAT: + return IVAS_DEC_BS_MC; + case SBA_FORMAT: + return IVAS_DEC_BS_SBA; + case SBA_ISM_FORMAT: + return IVAS_DEC_BS_SBA_ISM; + case MASA_FORMAT: + return IVAS_DEC_BS_MASA; + case MASA_ISM_FORMAT: + return IVAS_DEC_BS_MASA_ISM; + default: + break; + } -static ivas_error create_flush_buffer( - IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ -) -{ - hIvasDec->flushbuffer = (void *) malloc( CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( int16_t ) ); - if ( hIvasDec->flushbuffer == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate JBM flush buffer" ); + return IVAS_DEC_BS_UNKOWN; } - hIvasDec->pcmType = IVAS_DEC_PCM_INT16; - set_s( (int16_t *) hIvasDec->flushbuffer, 0, CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ); - return IVAS_ERR_OK; -} + /*---------------------------------------------------------------------* + * create_flush_buffer() + * + * Create flush buffer - needed for binaural outputs with TSM or in VoIP mode + *---------------------------------------------------------------------*/ + static ivas_error create_flush_buffer( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ + ) + { + hIvasDec->flushbuffer = (void *) malloc( CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( int16_t ) ); + if ( hIvasDec->flushbuffer == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate JBM flush buffer" ); + } -/*---------------------------------------------------------------------* - * IVAS_DEC_Configure( ) - * - * Decoder configuration - * legacy behavior: if no output format set, then it's EVS mono - *---------------------------------------------------------------------*/ - -ivas_error IVAS_DEC_Configure( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const uint32_t sampleRate, /* i : output sampling frequency */ - const AUDIO_CONFIG outputConfig, /* i : output configuration */ - const IVAS_RENDER_NUM_SUBFR render_num_subframes, /* i : rendering number of subframes */ - const bool customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ - const bool hrtfReaderEnabled, /* i : enable HRTF binary file input */ - const bool enableHeadRotation, /* i : enable head rotation for binaural output */ - const bool enableExternalOrientation, /* i : enable external orientations */ - const IVAS_HEAD_ORIENT_TRK_T orientation_tracking, /* i : head orientation tracking type */ - const bool renderConfigEnabled, /* i : enable Renderer config. file for binaural output */ - const IVAS_ROOM_SIZE_T roomSize, /* i : room size selector for reverb */ - const bool non_diegetic_pan_enabled, /* i : enabled diegetic panning */ - const float non_diegetic_pan_gain, /* i : non diegetic panning gain */ - const bool dpidEnabled, /* i : enable directivity pattern option */ - const uint16_t acousticEnvironmentId, /* i : Acoustic environment ID */ - const bool objEditEnabled, /* i : enable object editing */ - const bool delayCompensationEnabled /* i : enable delay compensation */ -) -{ - Decoder_Struct *st_ivas; - DECODER_CONFIG_HANDLE hDecoderConfig; - ivas_error error; + hIvasDec->pcmType = IVAS_DEC_PCM_INT16; + set_s( (int16_t *) hIvasDec->flushbuffer, 0, CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ); - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + return IVAS_ERR_OK; } - if ( sampleRate != 8000 && sampleRate != 16000 && sampleRate != 32000 && sampleRate != 48000 ) - { - return IVAS_ERR_WRONG_PARAMS; - } - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS && - ( outputConfig == IVAS_AUDIO_CONFIG_INVALID || - outputConfig == IVAS_AUDIO_CONFIG_ISM1 || - outputConfig == IVAS_AUDIO_CONFIG_ISM2 || - outputConfig == IVAS_AUDIO_CONFIG_ISM3 || - outputConfig == IVAS_AUDIO_CONFIG_ISM4 || - outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || - outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || - outputConfig == IVAS_AUDIO_CONFIG_MASA1 || - outputConfig == IVAS_AUDIO_CONFIG_MASA2 ) ) + /*---------------------------------------------------------------------* + * IVAS_DEC_Configure( ) + * + * Decoder configuration + * legacy behavior: if no output format set, then it's EVS mono + *---------------------------------------------------------------------*/ + + ivas_error IVAS_DEC_Configure( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const uint32_t sampleRate, /* i : output sampling frequency */ + const AUDIO_CONFIG outputConfig, /* i : output configuration */ + const IVAS_RENDER_NUM_SUBFR render_num_subframes, /* i : rendering number of subframes */ + const bool customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ + const bool hrtfReaderEnabled, /* i : enable HRTF binary file input */ + const bool enableHeadRotation, /* i : enable head rotation for binaural output */ + const bool enableExternalOrientation, /* i : enable external orientations */ + const IVAS_HEAD_ORIENT_TRK_T orientation_tracking, /* i : head orientation tracking type */ + const bool renderConfigEnabled, /* i : enable Renderer config. file for binaural output */ + const IVAS_ROOM_SIZE_T roomSize, /* i : room size selector for reverb */ + const bool non_diegetic_pan_enabled, /* i : enabled diegetic panning */ + const float non_diegetic_pan_gain, /* i : non diegetic panning gain */ + const bool dpidEnabled, /* i : enable directivity pattern option */ + const uint16_t acousticEnvironmentId, /* i : Acoustic environment ID */ + const bool objEditEnabled, /* i : enable object editing */ + const bool delayCompensationEnabled /* i : enable delay compensation */ + ) { - return IVAS_ERR_WRONG_MODE; - } + Decoder_Struct *st_ivas; + DECODER_CONFIG_HANDLE hDecoderConfig; + ivas_error error; - st_ivas = hIvasDec->st_ivas; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - hDecoderConfig = st_ivas->hDecoderConfig; + if ( sampleRate != 8000 && sampleRate != 16000 && sampleRate != 32000 && sampleRate != 48000 ) + { + return IVAS_ERR_WRONG_PARAMS; + } - hDecoderConfig->output_config = outputConfig; - if ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_INVALID ) - { - return IVAS_ERR_WRONG_PARAMS; - } + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS && + ( outputConfig == IVAS_AUDIO_CONFIG_INVALID || + outputConfig == IVAS_AUDIO_CONFIG_ISM1 || + outputConfig == IVAS_AUDIO_CONFIG_ISM2 || + outputConfig == IVAS_AUDIO_CONFIG_ISM3 || + outputConfig == IVAS_AUDIO_CONFIG_ISM4 || + outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || + outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || + outputConfig == IVAS_AUDIO_CONFIG_MASA1 || + outputConfig == IVAS_AUDIO_CONFIG_MASA2 ) ) + { + return IVAS_ERR_WRONG_MODE; + } - hDecoderConfig->output_Fs = sampleRate; + st_ivas = hIvasDec->st_ivas; - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) - { - st_ivas->element_mode_init = EVS_MONO; - hDecoderConfig->nchan_out = 1; - } + hDecoderConfig = st_ivas->hDecoderConfig; - if ( outputConfig != IVAS_AUDIO_CONFIG_EXTERNAL && outputConfig != IVAS_AUDIO_CONFIG_LS_CUSTOM ) - { - hDecoderConfig->nchan_out = audioCfg2channels( hDecoderConfig->output_config ); - } + hDecoderConfig->output_config = outputConfig; + if ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_INVALID ) + { + return IVAS_ERR_WRONG_PARAMS; + } - hDecoderConfig->Opt_LsCustom = (int16_t) customLsOutputEnabled; - hDecoderConfig->Opt_Headrotation = (int16_t) enableHeadRotation; - hDecoderConfig->orientation_tracking = orientation_tracking; - hDecoderConfig->Opt_HRTF_binary = (int16_t) hrtfReaderEnabled; - hDecoderConfig->Opt_RendConfigCustom = (int16_t) renderConfigEnabled; - hDecoderConfig->room_size = roomSize; - hDecoderConfig->Opt_non_diegetic_pan = (int16_t) non_diegetic_pan_enabled; - hDecoderConfig->non_diegetic_pan_gain = non_diegetic_pan_gain; - hDecoderConfig->Opt_delay_comp = (int16_t) delayCompensationEnabled; - hDecoderConfig->Opt_ExternalOrientation = enableExternalOrientation; - hDecoderConfig->Opt_dpid_on = (int16_t) dpidEnabled; - hDecoderConfig->Opt_aeid_on = acousticEnvironmentId != 65535 ? TRUE : FALSE; - hDecoderConfig->Opt_ObjEdit_on = (int16_t) objEditEnabled; - - if ( outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - hDecoderConfig->Opt_Headrotation = 1; - } + hDecoderConfig->output_Fs = sampleRate; - if ( render_num_subframes == IVAS_RENDER_NUM_SUBFR_UNKNOWN ) - { - return IVAS_ERR_WRONG_PARAMS; - } + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + { + st_ivas->element_mode_init = EVS_MONO; + hDecoderConfig->nchan_out = 1; + } - if ( outputConfig == IVAS_AUDIO_CONFIG_EXTERNAL ) - { - hDecoderConfig->render_num_subframes = IVAS_RENDER_NUM_SUBFR_20MS; - } - else - { - hDecoderConfig->render_num_subframes = render_num_subframes; - } + if ( outputConfig != IVAS_AUDIO_CONFIG_EXTERNAL && outputConfig != IVAS_AUDIO_CONFIG_LS_CUSTOM ) + { + hDecoderConfig->nchan_out = audioCfg2channels( hDecoderConfig->output_config ); + } - /* Set decoder parameters to initial values */ - if ( ( error = ivas_init_decoder_front( st_ivas ) ) != IVAS_ERR_OK ) - { - return error; - } + hDecoderConfig->Opt_LsCustom = (int16_t) customLsOutputEnabled; + hDecoderConfig->Opt_Headrotation = (int16_t) enableHeadRotation; + hDecoderConfig->orientation_tracking = orientation_tracking; + hDecoderConfig->Opt_HRTF_binary = (int16_t) hrtfReaderEnabled; + hDecoderConfig->Opt_RendConfigCustom = (int16_t) renderConfigEnabled; + hDecoderConfig->room_size = roomSize; + hDecoderConfig->Opt_non_diegetic_pan = (int16_t) non_diegetic_pan_enabled; + hDecoderConfig->non_diegetic_pan_gain = non_diegetic_pan_gain; + hDecoderConfig->Opt_delay_comp = (int16_t) delayCompensationEnabled; + hDecoderConfig->Opt_ExternalOrientation = enableExternalOrientation; + hDecoderConfig->Opt_dpid_on = (int16_t) dpidEnabled; + hDecoderConfig->Opt_aeid_on = acousticEnvironmentId != 65535 ? TRUE : FALSE; + hDecoderConfig->Opt_ObjEdit_on = (int16_t) objEditEnabled; - /* create ISAR handle */ - if ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - if ( ( error = ivas_create_handle_isar( &st_ivas->hSplitBinRend ) ) != IVAS_ERR_OK ) + if ( outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for ISAR handle" ); + hDecoderConfig->Opt_Headrotation = 1; } - } - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) - { - hIvasDec->st_ivas->ivas_format = MONO_FORMAT; - } + if ( render_num_subframes == IVAS_RENDER_NUM_SUBFR_UNKNOWN ) + { + return IVAS_ERR_WRONG_PARAMS; + } - hIvasDec->nSamplesFrame = (uint16_t) ( hDecoderConfig->output_Fs / FRAMES_PER_SEC ); + if ( outputConfig == IVAS_AUDIO_CONFIG_EXTERNAL ) + { + hDecoderConfig->render_num_subframes = IVAS_RENDER_NUM_SUBFR_20MS; + } + else + { + hDecoderConfig->render_num_subframes = render_num_subframes; + } - return IVAS_ERR_OK; -} + /* Set decoder parameters to initial values */ + if ( ( error = ivas_init_decoder_front( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + /* create ISAR handle */ + if ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( ( error = ivas_create_handle_isar( &st_ivas->hSplitBinRend ) ) != IVAS_ERR_OK ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for ISAR handle" ); + } + } -/*---------------------------------------------------------------------* - * IVAS_DEC_EnableSplitRendering( ) - * - * Update IVAS decoder config. if Split rendering is enabled - *---------------------------------------------------------------------*/ + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + { + hIvasDec->st_ivas->ivas_format = MONO_FORMAT; + } -ivas_error IVAS_DEC_EnableSplitRendering( - IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ -) -{ - DECODER_CONFIG_HANDLE hDecoderConfig; + hIvasDec->nSamplesFrame = (uint16_t) ( hDecoderConfig->output_Fs / FRAMES_PER_SEC ); - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + return IVAS_ERR_OK; } - hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; - hDecoderConfig->Opt_Headrotation = 1; - hDecoderConfig->render_num_subframes = IVAS_RENDER_NUM_SUBFR_20MS; + /*---------------------------------------------------------------------* + * IVAS_DEC_EnableSplitRendering( ) + * + * Update IVAS decoder config. if Split rendering is enabled + *---------------------------------------------------------------------*/ - return IVAS_ERR_OK; -} + ivas_error IVAS_DEC_EnableSplitRendering( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ + ) + { + DECODER_CONFIG_HANDLE hDecoderConfig; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } -/*---------------------------------------------------------------------* - * get_render_framesize_ms( ) - * - * Get render framesize in ms - *---------------------------------------------------------------------*/ + hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; -/*! r: render framesize in ms */ -static int16_t get_render_frame_size_ms( - const IVAS_RENDER_NUM_SUBFR render_num_subframes ) -{ - return (int16_t) ( render_num_subframes * ( 1000 / ( FRAMES_PER_SEC * IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ) ) ); -} + hDecoderConfig->Opt_Headrotation = 1; + hDecoderConfig->render_num_subframes = IVAS_RENDER_NUM_SUBFR_20MS; + return IVAS_ERR_OK; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_SetRenderNumSubfr( ) - * - * Set number of rendering subrames - *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_SetRenderNumSubfr( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const IVAS_RENDER_NUM_SUBFR render_num_subframes /* i : renderer number of subframes */ -) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hDecoderConfig == NULL ) + /*---------------------------------------------------------------------* + * get_render_framesize_ms( ) + * + * Get render framesize in ms + *---------------------------------------------------------------------*/ + + /*! r: render framesize in ms */ + static int16_t get_render_frame_size_ms( + const IVAS_RENDER_NUM_SUBFR render_num_subframes ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + return (int16_t) ( render_num_subframes * ( 1000 / ( FRAMES_PER_SEC * IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ) ) ); } - hIvasDec->st_ivas->hDecoderConfig->render_num_subframes = render_num_subframes; - if ( hIvasDec->st_ivas->hExtOrientationData != NULL ) - { - hIvasDec->st_ivas->hExtOrientationData->num_subframes = (int16_t) render_num_subframes; - } + /*---------------------------------------------------------------------* + * IVAS_DEC_SetRenderNumSubfr( ) + * + * Set number of rendering subrames + *---------------------------------------------------------------------*/ - if ( hIvasDec->st_ivas->hCombinedOrientationData != NULL ) + ivas_error IVAS_DEC_SetRenderNumSubfr( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_RENDER_NUM_SUBFR render_num_subframes /* i : renderer number of subframes */ + ) { - hIvasDec->st_ivas->hCombinedOrientationData->num_subframes = (int16_t) render_num_subframes; - } + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hDecoderConfig == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - return IVAS_ERR_OK; -} + hIvasDec->st_ivas->hDecoderConfig->render_num_subframes = render_num_subframes; + if ( hIvasDec->st_ivas->hExtOrientationData != NULL ) + { + hIvasDec->st_ivas->hExtOrientationData->num_subframes = (int16_t) render_num_subframes; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_GetRenderNumSubfr( ) - * - * Get number of rendering subframes - *---------------------------------------------------------------------*/ + if ( hIvasDec->st_ivas->hCombinedOrientationData != NULL ) + { + hIvasDec->st_ivas->hCombinedOrientationData->num_subframes = (int16_t) render_num_subframes; + } -ivas_error IVAS_DEC_GetRenderNumSubfr( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_RENDER_NUM_SUBFR *render_num_subframes /* o : rendering number of subframes */ -) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || render_num_subframes == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + return IVAS_ERR_OK; } - *render_num_subframes = hIvasDec->st_ivas->hDecoderConfig->render_num_subframes; - return IVAS_ERR_OK; -} + /*---------------------------------------------------------------------* + * IVAS_DEC_GetRenderNumSubfr( ) + * + * Get number of rendering subframes + *---------------------------------------------------------------------*/ + ivas_error IVAS_DEC_GetRenderNumSubfr( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_RENDER_NUM_SUBFR * render_num_subframes /* o : rendering number of subframes */ + ) + { + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || render_num_subframes == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } -/*---------------------------------------------------------------------* - * get_render_frame_size_samples( ) - * - * - *---------------------------------------------------------------------*/ + *render_num_subframes = hIvasDec->st_ivas->hDecoderConfig->render_num_subframes; -static int16_t get_render_frame_size_samples( - const DECODER_CONFIG_HANDLE hDecoderConfig /* i : configuration structure */ -) -{ - return (int16_t) ( hDecoderConfig->output_Fs * hDecoderConfig->render_num_subframes / ( FRAMES_PER_SEC * IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ) ); -} + return IVAS_ERR_OK; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_etRenderFramesizeSamples( ) - * - * Get render framesize in samples - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * get_render_frame_size_samples( ) + * + * + *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_GetRenderFramesizeSamples( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t *render_framesize /* o : render framesize in samples */ -) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || render_framesize == NULL ) + static int16_t get_render_frame_size_samples( + const DECODER_CONFIG_HANDLE hDecoderConfig /* i : configuration structure */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + return (int16_t) ( hDecoderConfig->output_Fs * hDecoderConfig->render_num_subframes / ( FRAMES_PER_SEC * IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ) ); } - *render_framesize = get_render_frame_size_samples( hIvasDec->st_ivas->hDecoderConfig ); - return IVAS_ERR_OK; -} + /*---------------------------------------------------------------------* + * IVAS_DEC_etRenderFramesizeSamples( ) + * + * Get render framesize in samples + *---------------------------------------------------------------------*/ + ivas_error IVAS_DEC_GetRenderFramesizeSamples( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t * render_framesize /* o : render framesize in samples */ + ) + { + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || render_framesize == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_GetRenderFramesizeMs( ) - * - * Get render framesize in milliseconds - *---------------------------------------------------------------------*/ + *render_framesize = get_render_frame_size_samples( hIvasDec->st_ivas->hDecoderConfig ); -ivas_error IVAS_DEC_GetRenderFramesizeMs( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint32_t *render_framesize_ms /* o : render framesize in ms */ -) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || render_framesize_ms == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + return IVAS_ERR_OK; } - *render_framesize_ms = get_render_frame_size_ms( hIvasDec->st_ivas->hDecoderConfig->render_num_subframes ); - return IVAS_ERR_OK; -} + /*---------------------------------------------------------------------* + * IVAS_DEC_GetRenderFramesizeMs( ) + * + * Get render framesize in milliseconds + *---------------------------------------------------------------------*/ + ivas_error IVAS_DEC_GetRenderFramesizeMs( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint32_t * render_framesize_ms /* o : render framesize in ms */ + ) + { + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || render_framesize_ms == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_GetReferencesUpdateFrequency( ) - * - * Get update frequency of the reference vector/orientation - *---------------------------------------------------------------------*/ + *render_framesize_ms = get_render_frame_size_ms( hIvasDec->st_ivas->hDecoderConfig->render_num_subframes ); -ivas_error IVAS_DEC_GetReferencesUpdateFrequency( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t *update_frequency /* o : update frequency */ -) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || update_frequency == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + return IVAS_ERR_OK; } - *update_frequency = (int16_t) ( IVAS_MAX_PARAM_SPATIAL_SUBFRAMES / hIvasDec->st_ivas->hDecoderConfig->render_num_subframes ); - return IVAS_ERR_OK; -} + /*---------------------------------------------------------------------* + * IVAS_DEC_GetReferencesUpdateFrequency( ) + * + * Get update frequency of the reference vector/orientation + *---------------------------------------------------------------------*/ + ivas_error IVAS_DEC_GetReferencesUpdateFrequency( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t * update_frequency /* o : update frequency */ + ) + { + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || update_frequency == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_EnableVoIP( ) - * - * Intitialize JBM - * jbmSafetyMargin: allowed delay reserve in addition to network jitter - * to reduce late-loss, default: 60 [milliseconds] - *---------------------------------------------------------------------*/ + *update_frequency = (int16_t) ( IVAS_MAX_PARAM_SPATIAL_SUBFRAMES / hIvasDec->st_ivas->hDecoderConfig->render_num_subframes ); + + return IVAS_ERR_OK; + } -ivas_error IVAS_DEC_EnableVoIP( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const int16_t jbmSafetyMargin, /* i : allowed delay reserve for JBM, in milliseconds */ - const IVAS_DEC_INPUT_FORMAT inputFormat /* i : format of the input bitstream */ -) -{ - DECODER_CONFIG_HANDLE hDecoderConfig; - ivas_error error; - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + /*---------------------------------------------------------------------* + * IVAS_DEC_EnableVoIP( ) + * + * Intitialize JBM + * jbmSafetyMargin: allowed delay reserve in addition to network jitter + * to reduce late-loss, default: 60 [milliseconds] + *---------------------------------------------------------------------*/ + + ivas_error IVAS_DEC_EnableVoIP( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t jbmSafetyMargin, /* i : allowed delay reserve for JBM, in milliseconds */ + const IVAS_DEC_INPUT_FORMAT inputFormat /* i : format of the input bitstream */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + DECODER_CONFIG_HANDLE hDecoderConfig; + ivas_error error; - hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; #ifdef DEBUGGING - hIvasDec->Opt_VOIP = 1; + hIvasDec->Opt_VOIP = 1; #endif - hDecoderConfig->Opt_tsm = 1; + hDecoderConfig->Opt_tsm = 1; - if ( hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) - { - hDecoderConfig->nchan_out = audioCfg2channels( hDecoderConfig->output_config ); - } + if ( hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) + { + hDecoderConfig->nchan_out = audioCfg2channels( hDecoderConfig->output_config ); + } #ifdef VARIABLE_SPEED_DECODING - else - { - hDecoderConfig->nchan_out = 1; - } + else + { + hDecoderConfig->nchan_out = 1; + } #endif - if ( ( error = input_format_API_to_internal( inputFormat, &hIvasDec->bitstreamformat, &hIvasDec->sdp_hf_only, true ) ) != IVAS_ERR_OK ) - { - return error; - } + if ( ( error = input_format_API_to_internal( inputFormat, &hIvasDec->bitstreamformat, &hIvasDec->sdp_hf_only, true ) ) != IVAS_ERR_OK ) + { + return error; + } - if ( ( hIvasDec->hVoIP = malloc( sizeof( IVAS_DEC_VOIP ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); - } + if ( ( hIvasDec->hVoIP = malloc( sizeof( IVAS_DEC_VOIP ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); + } - hIvasDec->hVoIP->lastDecodedWasActive = 0; - hIvasDec->hVoIP->hCurrentDataUnit = NULL; - hIvasDec->hVoIP->nSamplesRendered20ms = 0; + hIvasDec->hVoIP->lastDecodedWasActive = 0; + hIvasDec->hVoIP->hCurrentDataUnit = NULL; + hIvasDec->hVoIP->nSamplesRendered20ms = 0; #define WMC_TOOL_SKIP - /* Bitstream conversion is not counted towards complexity and memory usage */ - hIvasDec->hVoIP->bs_conversion_buf = malloc( sizeof( uint16_t ) * ( MAX_BITS_PER_FRAME + 4 * 8 ) ); + /* Bitstream conversion is not counted towards complexity and memory usage */ + hIvasDec->hVoIP->bs_conversion_buf = malloc( sizeof( uint16_t ) * ( MAX_BITS_PER_FRAME + 4 * 8 ) ); #undef WMC_TOOL_SKIP - if ( hIvasDec->hVoIP->bs_conversion_buf == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); - } + if ( hIvasDec->hVoIP->bs_conversion_buf == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); + } - /* initialize JBM */ - if ( ( error = JB4_Create( &hIvasDec->hVoIP->hJBM ) != IVAS_ERR_OK ) != IVAS_ERR_OK ) - { - return error; - } + /* initialize JBM */ + if ( ( error = JB4_Create( &hIvasDec->hVoIP->hJBM ) != IVAS_ERR_OK ) != IVAS_ERR_OK ) + { + return error; + } - if ( JB4_Init( hIvasDec->hVoIP->hJBM, jbmSafetyMargin ) != 0 ) - { - return IVAS_ERR_FAILED_ALLOC; - } + if ( JB4_Init( hIvasDec->hVoIP->hJBM, jbmSafetyMargin ) != 0 ) + { + return IVAS_ERR_FAILED_ALLOC; + } #ifdef NONBE_1122_KEEP_EVS_MODE_UNCHANGED - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) - { - JB4_TMP_SetEvsCompatFlag( hIvasDec->hVoIP->hJBM ); - } + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + { + JB4_TMP_SetEvsCompatFlag( hIvasDec->hVoIP->hJBM ); + } #endif - /* init flush buffer (needed for binaural outputs) */ - if ( ( error = create_flush_buffer( hIvasDec ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError in create_flush_buffer , code: %d\n", error ); - return error; - } - - return IVAS_ERR_OK; -} + /* init flush buffer (needed for binaural outputs) */ + if ( ( error = create_flush_buffer( hIvasDec ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in create_flush_buffer , code: %d\n", error ); + return error; + } + return IVAS_ERR_OK; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_FeedFrame_Serial( ) - * - * - *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_FeedFrame_Serial( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint16_t *serial, /* i : buffer containing serial input bitstream. Each bit should be stored as a single uint16_t value */ - const uint16_t num_bits, /* i : number of bits in input bitstream */ - int16_t bfi /* i : bad frame indicator flag */ -) -{ - ivas_error error; + /*---------------------------------------------------------------------* + * IVAS_DEC_FeedFrame_Serial( ) + * + * + *---------------------------------------------------------------------*/ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + ivas_error IVAS_DEC_FeedFrame_Serial( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint16_t * serial, /* i : buffer containing serial input bitstream. Each bit should be stored as a single uint16_t value */ + const uint16_t num_bits, /* i : number of bits in input bitstream */ + int16_t bfi /* i : bad frame indicator flag */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + ivas_error error; - if ( !hIvasDec->isInitialized ) - { - /* Once first frame is fed, finish initialization in EVS Mono. - * In IVAS mode, initialization is done in ivas_dec(). */ - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - hIvasDec->st_ivas->hDecoderConfig->ivas_total_brate = ACELP_8k00; - hIvasDec->st_ivas->transport_config = IVAS_AUDIO_CONFIG_MONO; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( ( error = ivas_init_decoder( hIvasDec->st_ivas ) ) != IVAS_ERR_OK ) + if ( !hIvasDec->isInitialized ) + { + /* Once first frame is fed, finish initialization in EVS Mono. + * In IVAS mode, initialization is done in ivas_dec(). */ + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) { - return error; - } + hIvasDec->st_ivas->hDecoderConfig->ivas_total_brate = ACELP_8k00; + hIvasDec->st_ivas->transport_config = IVAS_AUDIO_CONFIG_MONO; - if ( hIvasDec->hVoIP != NULL && hIvasDec->hVoIP->hCurrentDataUnit != NULL ) - { - DEC_CORE_HANDLE st = hIvasDec->st_ivas->hSCE[0]->hCoreCoder[0]; - st->ini_frame = 0; - st->prev_use_partial_copy = 0; - hIvasDec->st_ivas->hDecoderConfig->ivas_total_brate = hIvasDec->hVoIP->hCurrentDataUnit->dataSize * FRAMES_PER_SEC; + if ( ( error = ivas_init_decoder( hIvasDec->st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( hIvasDec->hVoIP != NULL && hIvasDec->hVoIP->hCurrentDataUnit != NULL ) + { + DEC_CORE_HANDLE st = hIvasDec->st_ivas->hSCE[0]->hCoreCoder[0]; + st->ini_frame = 0; + st->prev_use_partial_copy = 0; + hIvasDec->st_ivas->hDecoderConfig->ivas_total_brate = hIvasDec->hVoIP->hCurrentDataUnit->dataSize * FRAMES_PER_SEC; + } + + hIvasDec->isInitialized = true; } + } - hIvasDec->isInitialized = true; + if ( !bfi ) /* TODO(mcjbm): Is this ok for bfi == 2 (partial frame)? Is there enough info to fully configure decoder? */ + { + hIvasDec->hasBeenFedFirstGoodFrame = true; } - } - if ( !bfi ) /* TODO(mcjbm): Is this ok for bfi == 2 (partial frame)? Is there enough info to fully configure decoder? */ - { - hIvasDec->hasBeenFedFirstGoodFrame = true; - } + /* Update redundant frame information in EVS (pre- read indices) */ + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS && hIvasDec->hVoIP != NULL && hIvasDec->hVoIP->hCurrentDataUnit != NULL ) + { + DEC_CORE_HANDLE st = hIvasDec->st_ivas->hSCE[0]->hCoreCoder[0]; + st->bit_stream = serial; - /* Update redundant frame information in EVS (pre- read indices) */ - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS && hIvasDec->hVoIP != NULL && hIvasDec->hVoIP->hCurrentDataUnit != NULL ) - { - DEC_CORE_HANDLE st = hIvasDec->st_ivas->hSCE[0]->hCoreCoder[0]; - st->bit_stream = serial; + if ( hIvasDec->hVoIP->hCurrentDataUnit->partial_frame || st->prev_use_partial_copy ) + { + st->next_coder_type = hIvasDec->hVoIP->hCurrentDataUnit->nextCoderType; + } + else + { + st->next_coder_type = INACTIVE; + } - if ( hIvasDec->hVoIP->hCurrentDataUnit->partial_frame || st->prev_use_partial_copy ) - { - st->next_coder_type = hIvasDec->hVoIP->hCurrentDataUnit->nextCoderType; + if ( hIvasDec->hVoIP->hCurrentDataUnit->partial_frame == 1 && bfi != 1 ) + { + bfi = 2; + } } - else + + if ( ( error = read_indices( hIvasDec->st_ivas, serial, num_bits, &hIvasDec->prev_ft_speech, &hIvasDec->CNG, bfi ) ) != IVAS_ERR_OK ) { - st->next_coder_type = INACTIVE; + return error; } - if ( hIvasDec->hVoIP->hCurrentDataUnit->partial_frame == 1 && bfi != 1 ) + /* Update redundant frame information in EVS (post- read indices) */ + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS && + hIvasDec->hVoIP != NULL && + hIvasDec->hVoIP->hCurrentDataUnit != NULL && + hIvasDec->hVoIP->hCurrentDataUnit->partial_frame != 0 ) { - bfi = 2; + DEC_CORE_HANDLE st = hIvasDec->st_ivas->hSCE[0]->hCoreCoder[0]; + st->codec_mode = MODE2; + st->use_partial_copy = 1; } - } - if ( ( error = read_indices( hIvasDec->st_ivas, serial, num_bits, &hIvasDec->prev_ft_speech, &hIvasDec->CNG, bfi ) ) != IVAS_ERR_OK ) - { - return error; - } + hIvasDec->needNewFrame = false; + hIvasDec->hasBeenFedFrame = true; + hIvasDec->nSamplesAvailableNext = hIvasDec->nSamplesFrame; - /* Update redundant frame information in EVS (post- read indices) */ - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS && - hIvasDec->hVoIP != NULL && - hIvasDec->hVoIP->hCurrentDataUnit != NULL && - hIvasDec->hVoIP->hCurrentDataUnit->partial_frame != 0 ) - { - DEC_CORE_HANDLE st = hIvasDec->st_ivas->hSCE[0]->hCoreCoder[0]; - st->codec_mode = MODE2; - st->use_partial_copy = 1; + return IVAS_ERR_OK; } - hIvasDec->needNewFrame = false; - hIvasDec->hasBeenFedFrame = true; - hIvasDec->nSamplesAvailableNext = hIvasDec->nSamplesFrame; - - return IVAS_ERR_OK; -} - -/*---------------------------------------------------------------------* - * renderer_type_to_mode() - * - * Convert (codec library) renderer type to (API public) binaural renderer mode - *---------------------------------------------------------------------*/ - -/*! r: binaural renderer mode (API type) */ -static IVAS_BIN_RENDERER_TYPE renderer_type_to_mode( - const RENDERER_TYPE renderer_type /* i : renderer type (codec library type) */ -) -{ - IVAS_BIN_RENDERER_TYPE binaural_renderer; + /*---------------------------------------------------------------------* + * renderer_type_to_mode() + * + * Convert (codec library) renderer type to (API public) binaural renderer mode + *---------------------------------------------------------------------*/ + + /*! r: binaural renderer mode (API type) */ + static IVAS_BIN_RENDERER_TYPE renderer_type_to_mode( + const RENDERER_TYPE renderer_type /* i : renderer type (codec library type) */ + ) + { + IVAS_BIN_RENDERER_TYPE binaural_renderer; + + switch ( renderer_type ) + { + case RENDERER_BINAURAL_OBJECTS_TD: + binaural_renderer = IVAS_BIN_RENDERER_TYPE_TDREND; + break; + case RENDERER_BINAURAL_MIXER_CONV: + case RENDERER_BINAURAL_MIXER_CONV_ROOM: + binaural_renderer = IVAS_BIN_RENDERER_TYPE_CREND; + break; + case RENDERER_BINAURAL_FASTCONV: + binaural_renderer = IVAS_BIN_RENDERER_TYPE_FASTCONV; + break; + case RENDERER_BINAURAL_FASTCONV_ROOM: + binaural_renderer = IVAS_BIN_RENDERER_TYPE_FASTCONV; + break; + case RENDERER_BINAURAL_PARAMETRIC: + case RENDERER_BINAURAL_PARAMETRIC_ROOM: + binaural_renderer = IVAS_BIN_RENDERER_TYPE_PARAMBIN; + break; + default: + binaural_renderer = IVAS_BIN_RENDERER_TYPE_NONE; + break; + } - switch ( renderer_type ) - { - case RENDERER_BINAURAL_OBJECTS_TD: - binaural_renderer = IVAS_BIN_RENDERER_TYPE_TDREND; - break; - case RENDERER_BINAURAL_MIXER_CONV: - case RENDERER_BINAURAL_MIXER_CONV_ROOM: - binaural_renderer = IVAS_BIN_RENDERER_TYPE_CREND; - break; - case RENDERER_BINAURAL_FASTCONV: - binaural_renderer = IVAS_BIN_RENDERER_TYPE_FASTCONV; - break; - case RENDERER_BINAURAL_FASTCONV_ROOM: - binaural_renderer = IVAS_BIN_RENDERER_TYPE_FASTCONV; - break; - case RENDERER_BINAURAL_PARAMETRIC: - case RENDERER_BINAURAL_PARAMETRIC_ROOM: - binaural_renderer = IVAS_BIN_RENDERER_TYPE_PARAMBIN; - break; - default: - binaural_renderer = IVAS_BIN_RENDERER_TYPE_NONE; - break; + return binaural_renderer; } - return binaural_renderer; -} - -/*---------------------------------------------------------------------* - * IVAS_DEC_ReadFormat( ) - * - * Read main parameters from the bitstream to set-up the decoder: - * - IVAS format - * - IVAS format specific signaling - * - compensate for renderer granularity change in JBM - *---------------------------------------------------------------------*/ - -ivas_error IVAS_DEC_ReadFormat( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_BIN_RENDERER_TYPE *binaural_renderer, /* o : binaural renderer type */ - IVAS_BIN_RENDERER_TYPE *binaural_renderer_sec, /* o : secondary binaural renderer type */ - IVAS_AUDIO_CONFIG *hrtf_set_audio_cfg /* o : HRTF set audio config. */ -) -{ - ivas_error error; - Decoder_Struct *st_ivas; - ISM_MODE ism_mode_old; - MC_MODE mc_mode_old; - int16_t nchan_transport_old; - AUDIO_CONFIG intern_config_old, transport_config_old, output_config; - RENDERER_TYPE renderer_type_old, renderer_type_sec_new, renderer_type_sec_old; + /*---------------------------------------------------------------------* + * IVAS_DEC_ReadFormat( ) + * + * Read main parameters from the bitstream to set-up the decoder: + * - IVAS format + * - IVAS format specific signaling + * - compensate for renderer granularity change in JBM + *---------------------------------------------------------------------*/ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + ivas_error IVAS_DEC_ReadFormat( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_BIN_RENDERER_TYPE * binaural_renderer, /* o : binaural renderer type */ + IVAS_BIN_RENDERER_TYPE * binaural_renderer_sec, /* o : secondary binaural renderer type */ + IVAS_AUDIO_CONFIG * hrtf_set_audio_cfg /* o : HRTF set audio config. */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + ivas_error error; + Decoder_Struct *st_ivas; + ISM_MODE ism_mode_old; + MC_MODE mc_mode_old; + int16_t nchan_transport_old; + AUDIO_CONFIG intern_config_old, transport_config_old, output_config; + RENDERER_TYPE renderer_type_old, renderer_type_sec_new, renderer_type_sec_old; - st_ivas = hIvasDec->st_ivas; - ism_mode_old = st_ivas->ism_mode; - mc_mode_old = st_ivas->mc_mode; - nchan_transport_old = st_ivas->nchan_transport; - intern_config_old = st_ivas->intern_config; - transport_config_old = st_ivas->transport_config; - renderer_type_old = st_ivas->renderer_type; - renderer_type_sec_old = ivas_renderer_secondary_select( st_ivas ); + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - output_config = st_ivas->hDecoderConfig->output_config; + st_ivas = hIvasDec->st_ivas; + ism_mode_old = st_ivas->ism_mode; + mc_mode_old = st_ivas->mc_mode; + nchan_transport_old = st_ivas->nchan_transport; + intern_config_old = st_ivas->intern_config; + transport_config_old = st_ivas->transport_config; + renderer_type_old = st_ivas->renderer_type; + renderer_type_sec_old = ivas_renderer_secondary_select( st_ivas ); - if ( st_ivas->ivas_format == MONO_FORMAT ) - { - return IVAS_ERR_OK; - } + output_config = st_ivas->hDecoderConfig->output_config; - if ( st_ivas->bfi == 0 ) - { - if ( ( error = ivas_dec_get_format( st_ivas ) ) != IVAS_ERR_OK ) + if ( st_ivas->ivas_format == MONO_FORMAT ) { - return error; + return IVAS_ERR_OK; } - if ( st_ivas->restartNeeded == 1 ) + if ( st_ivas->bfi == 0 ) { - return IVAS_ERR_OK; - } + if ( ( error = ivas_dec_get_format( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( st_ivas->restartNeeded == 1 ) + { + return IVAS_ERR_OK; + } - /* Select binaural renderer */ - ivas_renderer_select( st_ivas ); - *binaural_renderer = renderer_type_to_mode( st_ivas->renderer_type ); + /* Select binaural renderer */ + ivas_renderer_select( st_ivas ); + *binaural_renderer = renderer_type_to_mode( st_ivas->renderer_type ); - /* Select secondary binaural renderer (used in combined formats) */ - renderer_type_sec_new = ivas_renderer_secondary_select( st_ivas ); - *binaural_renderer_sec = renderer_type_to_mode( renderer_type_sec_new ); + /* Select secondary binaural renderer (used in combined formats) */ + renderer_type_sec_new = ivas_renderer_secondary_select( st_ivas ); + *binaural_renderer_sec = renderer_type_to_mode( renderer_type_sec_new ); - /* select HRTF audio configuration to load the right HRTF set for the external binary file */ - *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_INVALID; - if ( *binaural_renderer == IVAS_BIN_RENDERER_TYPE_FASTCONV ) - { - if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) + /* select HRTF audio configuration to load the right HRTF set for the external binary file */ + *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_INVALID; + if ( *binaural_renderer == IVAS_BIN_RENDERER_TYPE_FASTCONV ) { - /* SHD HRIRs */ - *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_HOA3; + if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) + { + /* SHD HRIRs */ + *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_HOA3; - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) + { + /* BRIRs */ + *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_7_1_4; + } + } + else if ( st_ivas->ivas_format == MC_FORMAT ) { - /* BRIRs */ + /* HRIRs */ *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_7_1_4; + + if ( ( st_ivas->hDecoderConfig->Opt_Headrotation ) && + !( st_ivas->mc_mode == MC_MODE_PARAMUPMIX && output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) ) + { + /* SHD HRIRs for low complexity rotation */ + *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_HOA3; + } } } - else if ( st_ivas->ivas_format == MC_FORMAT ) + else if ( *binaural_renderer == IVAS_BIN_RENDERER_TYPE_CREND ) { - /* HRIRs */ - *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_7_1_4; - - if ( ( st_ivas->hDecoderConfig->Opt_Headrotation ) && - !( st_ivas->mc_mode == MC_MODE_PARAMUPMIX && output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) ) + if ( st_ivas->ivas_format == ISM_FORMAT ) { - /* SHD HRIRs for low complexity rotation */ - *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_HOA3; + /* BRIRs */ + *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_7_1_4; } - } - } - else if ( *binaural_renderer == IVAS_BIN_RENDERER_TYPE_CREND ) - { - if ( st_ivas->ivas_format == ISM_FORMAT ) - { - /* BRIRs */ - *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_7_1_4; - } - else if ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCT ) - { - /* BRIRs */ - *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_7_1_4; - - if ( st_ivas->hDecoderConfig->Opt_Headrotation && ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) + else if ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCT ) { - /* SHD HRIRs for low complexity rotation */ - *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_HOA3; + /* BRIRs */ + *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_7_1_4; + + if ( st_ivas->hDecoderConfig->Opt_Headrotation && ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) + { + /* SHD HRIRs for low complexity rotation */ + *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_HOA3; + } } } - } - /* JBM: compensate when binaural renderer granularity changes (happens in bitrate switching) */ - if ( st_ivas->ini_active_frame > 0 && st_ivas->hDecoderConfig->Opt_tsm && - ( ( renderer_type_old != st_ivas->renderer_type ) || - ( renderer_type_sec_old != renderer_type_sec_new ) ) ) - { - int16_t tc_granularity_new = ivas_dec_get_render_granularity( st_ivas->renderer_type, renderer_type_sec_new, st_ivas->hDecoderConfig->output_Fs ); + /* JBM: compensate when binaural renderer granularity changes (happens in bitrate switching) */ + if ( st_ivas->ini_active_frame > 0 && st_ivas->hDecoderConfig->Opt_tsm && + ( ( renderer_type_old != st_ivas->renderer_type ) || + ( renderer_type_sec_old != renderer_type_sec_new ) ) ) + { + int16_t tc_granularity_new = ivas_dec_get_render_granularity( st_ivas->renderer_type, renderer_type_sec_new, st_ivas->hDecoderConfig->output_Fs ); - st_ivas->nchan_transport = nchan_transport_old; + st_ivas->nchan_transport = nchan_transport_old; - if ( st_ivas->hTcBuffer == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + if ( st_ivas->hTcBuffer == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - /* when granularity goes down, render what still fits in the new granularity */ - if ( tc_granularity_new < st_ivas->hTcBuffer->n_samples_granularity ) - { - if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, tc_granularity_new, renderer_type_old, intern_config_old, &st_ivas->hIntSetup, mc_mode_old, ism_mode_old, &hIvasDec->nSamplesFlushed, pcm_type_API_to_internal( hIvasDec->pcmType ), hIvasDec->flushbuffer ) ) != IVAS_ERR_OK ) + /* when granularity goes down, render what still fits in the new granularity */ + if ( tc_granularity_new < st_ivas->hTcBuffer->n_samples_granularity ) { - return error; + if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, tc_granularity_new, renderer_type_old, intern_config_old, &st_ivas->hIntSetup, mc_mode_old, ism_mode_old, &hIvasDec->nSamplesFlushed, pcm_type_API_to_internal( hIvasDec->pcmType ), hIvasDec->flushbuffer ) ) != IVAS_ERR_OK ) + { + return error; + } } } } - } - - st_ivas->ism_mode = ism_mode_old; - st_ivas->mc_mode = mc_mode_old; - st_ivas->nchan_transport = nchan_transport_old; - st_ivas->intern_config = intern_config_old; - st_ivas->transport_config = transport_config_old; - st_ivas->renderer_type = renderer_type_old; - return IVAS_ERR_OK; -} + st_ivas->ism_mode = ism_mode_old; + st_ivas->mc_mode = mc_mode_old; + st_ivas->nchan_transport = nchan_transport_old; + st_ivas->intern_config = intern_config_old; + st_ivas->transport_config = transport_config_old; + st_ivas->renderer_type = renderer_type_old; - -/*---------------------------------------------------------------------* - * IVAS_DEC_GetSamplesDecoder( ) - * - * Main function to run setup, decode transport channels, do TSM and feed to renderer. - *---------------------------------------------------------------------*/ - -ivas_error IVAS_DEC_GetSamplesDecoder( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ -) -{ - ivas_error error; - Decoder_Struct *st_ivas; - uint16_t nTimeScalerOutSamples; - uint8_t nTransportChannels; - int16_t nResidualSamples, nSamplesTcsScaled; - bool isInitialized_voip; - - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - if ( !hIvasDec->hasBeenFedFirstGoodFrame && !hIvasDec->isInitialized ) /* note: 'isInitialized' is related to EVS decoder */ - { return IVAS_ERR_OK; } - st_ivas = hIvasDec->st_ivas; - isInitialized_voip = hIvasDec->hTimeScaler != NULL; + /*---------------------------------------------------------------------* + * IVAS_DEC_GetSamplesDecoder( ) + * + * Main function to run setup, decode transport channels, do TSM and feed to renderer. + *---------------------------------------------------------------------*/ - if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) /* wait for the first good frame */ + ivas_error IVAS_DEC_GetSamplesDecoder( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + ISAR_SPLIT_REND_BITS_DATA * splitRendBits /* o : output split rendering bits */ + ) { - /*-----------------------------------------------------------------* - * Setup all decoder parts (IVAS decoder, ISAR) - *-----------------------------------------------------------------*/ + ivas_error error; + Decoder_Struct *st_ivas; + uint16_t nTimeScalerOutSamples; + uint8_t nTransportChannels; + int16_t nResidualSamples, nSamplesTcsScaled; + bool isInitialized_voip; - if ( ( error = ivas_dec_setup_all( hIvasDec, &nTransportChannels, splitRendBits ) ) != IVAS_ERR_OK ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - return error; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - /*-----------------------------------------------------------------* - * IVAS decoder: decode transport channels and metadata - *-----------------------------------------------------------------*/ - - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + if ( !hIvasDec->hasBeenFedFirstGoodFrame && !hIvasDec->isInitialized ) /* note: 'isInitialized' is related to EVS decoder */ { - if ( ( error = evs_dec_main( st_ivas ) ) != IVAS_ERR_OK ) - { - return error; - } + return IVAS_ERR_OK; } - else if ( hIvasDec->mode == IVAS_DEC_MODE_IVAS ) + + st_ivas = hIvasDec->st_ivas; + + isInitialized_voip = hIvasDec->hTimeScaler != NULL; + + if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) /* wait for the first good frame */ { - if ( ( error = ivas_dec( st_ivas ) ) != IVAS_ERR_OK ) + /*-----------------------------------------------------------------* + * Setup all decoder parts (IVAS decoder, ISAR) + *-----------------------------------------------------------------*/ + + if ( ( error = ivas_dec_setup_all( hIvasDec, &nTransportChannels, splitRendBits ) ) != IVAS_ERR_OK ) { return error; } - hIvasDec->isInitialized = true; /* Initialization done in ivas_dec() */ - } - - if ( hIvasDec->hasBeenFedFirstGoodFrame ) - { - hIvasDec->hasDecodedFirstGoodFrame = true; - } + /*-----------------------------------------------------------------* + * IVAS decoder: decode transport channels and metadata + *-----------------------------------------------------------------*/ - /*-----------------------------------------------------------------* - * JBM - *-----------------------------------------------------------------*/ - - if ( st_ivas->hDecoderConfig->Opt_tsm ) - { - if ( nTransportChannels != hIvasDec->nTransportChannelsOld ) + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + { + if ( ( error = evs_dec_main( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else if ( hIvasDec->mode == IVAS_DEC_MODE_IVAS ) { - if ( ( error = apa_setup( hIvasDec, isInitialized_voip, nTransportChannels ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_dec( st_ivas ) ) != IVAS_ERR_OK ) { return error; } + + hIvasDec->isInitialized = true; /* Initialization done in ivas_dec() */ } - if ( apa_set_scale( hIvasDec->hTimeScaler, hIvasDec->tsm_scale ) != 0 ) + if ( hIvasDec->hasBeenFedFirstGoodFrame ) { - return IVAS_ERR_UNKNOWN; + hIvasDec->hasDecodedFirstGoodFrame = true; } - /* convert deinterleaved decoded TC audio channels buffer to an interleaved one */ - ivas_buffer_deinterleaved_to_interleaved( st_ivas->p_output_f, st_ivas->hTcBuffer->tc_buffer, nTransportChannels, hIvasDec->nSamplesFrame ); + /*-----------------------------------------------------------------* + * JBM + *-----------------------------------------------------------------*/ - /* time-scale modification */ - if ( apa_exec( hIvasDec->hTimeScaler, st_ivas->hTcBuffer->tc_buffer, hIvasDec->nSamplesFrame * nTransportChannels, (uint16_t) hIvasDec->tsm_max_scaling, st_ivas->hTcBuffer->tc_buffer, &nTimeScalerOutSamples ) != 0 ) + if ( st_ivas->hDecoderConfig->Opt_tsm ) { - return IVAS_ERR_UNKNOWN; - } + if ( nTransportChannels != hIvasDec->nTransportChannelsOld ) + { + if ( ( error = apa_setup( hIvasDec, isInitialized_voip, nTransportChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + } - assert( nTimeScalerOutSamples <= APA_BUF ); - nSamplesTcsScaled = nTimeScalerOutSamples / nTransportChannels; - hIvasDec->timeScalingDone = 1; + if ( apa_set_scale( hIvasDec->hTimeScaler, hIvasDec->tsm_scale ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } - /* convert interleaved time-scaled TC audio channels buffer to deinterleaved one */ - ivas_buffer_interleaved_to_deinterleaved( st_ivas->hTcBuffer->tc_buffer, st_ivas->p_output_f, nTransportChannels, nSamplesTcsScaled ); - } - else - { - nSamplesTcsScaled = hIvasDec->nSamplesFrame; - } + /* convert deinterleaved decoded TC audio channels buffer to an interleaved one */ + ivas_buffer_deinterleaved_to_interleaved( st_ivas->p_output_f, st_ivas->hTcBuffer->tc_buffer, nTransportChannels, hIvasDec->nSamplesFrame ); - /*-----------------------------------------------------------------* - * Feed decoded transport channels samples to the renderer - *-----------------------------------------------------------------*/ + /* time-scale modification */ + if ( apa_exec( hIvasDec->hTimeScaler, st_ivas->hTcBuffer->tc_buffer, hIvasDec->nSamplesFrame * nTransportChannels, (uint16_t) hIvasDec->tsm_max_scaling, st_ivas->hTcBuffer->tc_buffer, &nTimeScalerOutSamples ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } - ivas_dec_feed_tc_to_renderer( st_ivas, nSamplesTcsScaled, &nResidualSamples ); + assert( nTimeScalerOutSamples <= APA_BUF ); + nSamplesTcsScaled = nTimeScalerOutSamples / nTransportChannels; + hIvasDec->timeScalingDone = 1; - if ( st_ivas->hDecoderConfig->Opt_tsm ) - { - /* feed residual samples to TSM for the next call */ - if ( apa_set_renderer_residual_samples( hIvasDec->hTimeScaler, (uint16_t) nResidualSamples ) != 0 ) + /* convert interleaved time-scaled TC audio channels buffer to deinterleaved one */ + ivas_buffer_interleaved_to_deinterleaved( st_ivas->hTcBuffer->tc_buffer, st_ivas->p_output_f, nTransportChannels, nSamplesTcsScaled ); + } + else { - return IVAS_ERR_UNKNOWN; + nSamplesTcsScaled = hIvasDec->nSamplesFrame; } - } - - hIvasDec->hasBeenFedFrame = false; - } - hIvasDec->hasBeenPreparedRendering = false; + /*-----------------------------------------------------------------* + * Feed decoded transport channels samples to the renderer + *-----------------------------------------------------------------*/ - /*-----------------------------------------------------------------* - * Set editable metadata - *-----------------------------------------------------------------*/ + ivas_dec_feed_tc_to_renderer( st_ivas, nSamplesTcsScaled, &nResidualSamples ); - if ( st_ivas->hIsmMetaData[0] ) - { - if ( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) - { - if ( st_ivas->ism_mode == ISM_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + if ( st_ivas->hDecoderConfig->Opt_tsm ) { - int16_t obj; - ISM_METADATA_HANDLE *hIsmMetaData = st_ivas->hIsmMetaData; - for ( obj = 0; obj < st_ivas->nchan_ism; obj++ ) + /* feed residual samples to TSM for the next call */ + if ( apa_set_renderer_residual_samples( hIvasDec->hTimeScaler, (uint16_t) nResidualSamples ) != 0 ) { - hIsmMetaData[obj]->edited_azimuth = hIsmMetaData[obj]->azimuth; - hIsmMetaData[obj]->edited_elevation = hIsmMetaData[obj]->elevation; - hIsmMetaData[obj]->edited_yaw = hIsmMetaData[obj]->yaw; - hIsmMetaData[obj]->edited_pitch = hIsmMetaData[obj]->pitch; - hIsmMetaData[obj]->edited_radius = hIsmMetaData[obj]->radius; - hIsmMetaData[obj]->edited_gain = 1.0f; + return IVAS_ERR_UNKNOWN; } + } + + hIvasDec->hasBeenFedFrame = false; + } + + hIvasDec->hasBeenPreparedRendering = false; + + /*-----------------------------------------------------------------* + * Set editable metadata + *-----------------------------------------------------------------*/ - if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + if ( st_ivas->hIsmMetaData[0] ) + { + if ( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) + { + if ( st_ivas->ism_mode == ISM_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { - st_ivas->hSbaIsmData->gain_bed = 1.0f; + int16_t obj; + ISM_METADATA_HANDLE *hIsmMetaData = st_ivas->hIsmMetaData; + for ( obj = 0; obj < st_ivas->nchan_ism; obj++ ) + { + hIsmMetaData[obj]->edited_azimuth = hIsmMetaData[obj]->azimuth; + hIsmMetaData[obj]->edited_elevation = hIsmMetaData[obj]->elevation; + hIsmMetaData[obj]->edited_yaw = hIsmMetaData[obj]->yaw; + hIsmMetaData[obj]->edited_pitch = hIsmMetaData[obj]->pitch; + hIsmMetaData[obj]->edited_radius = hIsmMetaData[obj]->radius; + hIsmMetaData[obj]->edited_gain = 1.0f; + } + + if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + st_ivas->hSbaIsmData->gain_bed = 1.0f; + } } } } - } - if ( st_ivas->hParamIsmDec != NULL ) - { - if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + if ( st_ivas->hParamIsmDec != NULL ) { - int16_t obj = 0; - PARAM_ISM_DEC_HANDLE hParamIsmDec = st_ivas->hParamIsmDec; - for ( obj = 0; obj < st_ivas->nchan_ism; obj++ ) + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { - hParamIsmDec->edited_azimuth_values[obj] = hParamIsmDec->azimuth_values[obj]; - hParamIsmDec->edited_elevation_values[obj] = hParamIsmDec->elevation_values[obj]; + int16_t obj = 0; + PARAM_ISM_DEC_HANDLE hParamIsmDec = st_ivas->hParamIsmDec; + for ( obj = 0; obj < st_ivas->nchan_ism; obj++ ) + { + hParamIsmDec->edited_azimuth_values[obj] = hParamIsmDec->azimuth_values[obj]; + hParamIsmDec->edited_elevation_values[obj] = hParamIsmDec->elevation_values[obj]; + } } } - } - - return IVAS_ERR_OK; -} + return IVAS_ERR_OK; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_GetEditableParameters( ) - * - * Get editable metadata parameters - *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_GetEditableParameters( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_EDITABLE_PARAMETERS *hIvasEditableParameters /* o : object editing parameters handle */ -) -{ - int16_t dirac_read_idx, obj; - Decoder_Struct *st_ivas; - ISM_MODE ism_mode; + /*---------------------------------------------------------------------* + * IVAS_DEC_GetEditableParameters( ) + * + * Get editable metadata parameters + *---------------------------------------------------------------------*/ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasEditableParameters == NULL ) + ivas_error IVAS_DEC_GetEditableParameters( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_EDITABLE_PARAMETERS * hIvasEditableParameters /* o : object editing parameters handle */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + int16_t dirac_read_idx, obj; + Decoder_Struct *st_ivas; + ISM_MODE ism_mode; - if ( !hIvasDec->hasBeenFedFirstGoodFrame ) - { - hIvasEditableParameters->num_obj = 0; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasEditableParameters == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - return IVAS_ERR_OK; - } + if ( !hIvasDec->hasBeenFedFirstGoodFrame ) + { + hIvasEditableParameters->num_obj = 0; - st_ivas = hIvasDec->st_ivas; - ism_mode = st_ivas->ism_mode; + return IVAS_ERR_OK; + } - if ( !( st_ivas->ivas_format == ISM_FORMAT || - st_ivas->ivas_format == SBA_ISM_FORMAT || - st_ivas->ivas_format == MASA_ISM_FORMAT || - ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nchan_ism > 0 ) ) ) - { - return IVAS_ERROR( IVAS_ERR_OBJECTS_EDITING_NOT_SUPPORTED, "Object editing is not supported in this operation mode." ); - } + st_ivas = hIvasDec->st_ivas; + ism_mode = st_ivas->ism_mode; - hIvasEditableParameters->gain_bed = 1.0f; - hIvasEditableParameters->num_obj = st_ivas->nchan_ism; - if ( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) - { - if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) + if ( !( st_ivas->ivas_format == ISM_FORMAT || + st_ivas->ivas_format == SBA_ISM_FORMAT || + st_ivas->ivas_format == MASA_ISM_FORMAT || + ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nchan_ism > 0 ) ) ) + { + return IVAS_ERROR( IVAS_ERR_OBJECTS_EDITING_NOT_SUPPORTED, "Object editing is not supported in this operation mode." ); + } + + hIvasEditableParameters->gain_bed = 1.0f; + hIvasEditableParameters->num_obj = st_ivas->nchan_ism; + if ( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) { - for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) { - hIvasEditableParameters->ism_metadata[obj].azimuth = st_ivas->hIsmMetaData[obj]->azimuth; - hIvasEditableParameters->ism_metadata[obj].elevation = st_ivas->hIsmMetaData[obj]->elevation; - hIvasEditableParameters->ism_metadata[obj].yaw = st_ivas->hIsmMetaData[obj]->yaw; - hIvasEditableParameters->ism_metadata[obj].pitch = st_ivas->hIsmMetaData[obj]->pitch; - hIvasEditableParameters->ism_metadata[obj].radius = st_ivas->hIsmMetaData[obj]->radius; - hIvasEditableParameters->ism_metadata[obj].gain = st_ivas->hIsmMetaData[obj]->edited_gain; - hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = st_ivas->hIsmMetaData[obj]->non_diegetic_flag; - } + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + { + hIvasEditableParameters->ism_metadata[obj].azimuth = st_ivas->hIsmMetaData[obj]->azimuth; + hIvasEditableParameters->ism_metadata[obj].elevation = st_ivas->hIsmMetaData[obj]->elevation; + hIvasEditableParameters->ism_metadata[obj].yaw = st_ivas->hIsmMetaData[obj]->yaw; + hIvasEditableParameters->ism_metadata[obj].pitch = st_ivas->hIsmMetaData[obj]->pitch; + hIvasEditableParameters->ism_metadata[obj].radius = st_ivas->hIsmMetaData[obj]->radius; + hIvasEditableParameters->ism_metadata[obj].gain = st_ivas->hIsmMetaData[obj]->edited_gain; + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = st_ivas->hIsmMetaData[obj]->non_diegetic_flag; + } - if ( ism_mode == ISM_SBA_MODE_DISC ) + if ( ism_mode == ISM_SBA_MODE_DISC ) + { + hIvasEditableParameters->gain_bed = 1.0f; + } + } + else if ( ism_mode == ISM_MODE_PARAM ) { - hIvasEditableParameters->gain_bed = 1.0f; + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + { + hIvasEditableParameters->ism_metadata[obj].azimuth = st_ivas->hParamIsmDec->azimuth_values[obj]; + hIvasEditableParameters->ism_metadata[obj].elevation = st_ivas->hParamIsmDec->elevation_values[obj]; + hIvasEditableParameters->ism_metadata[obj].yaw = 0.0f; + hIvasEditableParameters->ism_metadata[obj].pitch = 0.0f; + hIvasEditableParameters->ism_metadata[obj].radius = 0.0f; + hIvasEditableParameters->ism_metadata[obj].gain = 1.0f; + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = 0; + } } - } - else if ( ism_mode == ISM_MODE_PARAM ) - { - for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + else if ( ism_mode == ISM_MODE_NONE ) { - hIvasEditableParameters->ism_metadata[obj].azimuth = st_ivas->hParamIsmDec->azimuth_values[obj]; - hIvasEditableParameters->ism_metadata[obj].elevation = st_ivas->hParamIsmDec->elevation_values[obj]; - hIvasEditableParameters->ism_metadata[obj].yaw = 0.0f; - hIvasEditableParameters->ism_metadata[obj].pitch = 0.0f; - hIvasEditableParameters->ism_metadata[obj].radius = 0.0f; - hIvasEditableParameters->ism_metadata[obj].gain = 1.0f; - hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = 0; + hIvasEditableParameters->num_obj = 0; } - } - else if ( ism_mode == ISM_MODE_NONE ) - { - hIvasEditableParameters->num_obj = 0; - } #ifdef DEBUGGING - else - { - assert( 0 && "This should never happen!" ); - } -#endif - } - else if ( st_ivas->ivas_format == MASA_ISM_FORMAT || ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nchan_ism > 0 ) ) - { - /* object editing possible only in two highest OMASA modes */ - if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) - { - for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + else { - hIvasEditableParameters->ism_metadata[obj].azimuth = st_ivas->hIsmMetaData[obj]->azimuth; - hIvasEditableParameters->ism_metadata[obj].elevation = st_ivas->hIsmMetaData[obj]->elevation; - hIvasEditableParameters->ism_metadata[obj].yaw = st_ivas->hIsmMetaData[obj]->yaw; - hIvasEditableParameters->ism_metadata[obj].pitch = st_ivas->hIsmMetaData[obj]->pitch; - hIvasEditableParameters->ism_metadata[obj].radius = st_ivas->hIsmMetaData[obj]->radius; - - /* reset the otherwise unused "gain" field for the object */ - st_ivas->hIsmMetaData[obj]->edited_gain = 1.0f; - hIvasEditableParameters->ism_metadata[obj].gain = st_ivas->hIsmMetaData[obj]->edited_gain; - hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = st_ivas->hIsmMetaData[obj]->non_diegetic_flag; + assert( 0 && "This should never happen!" ); } +#endif } - else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + else if ( st_ivas->ivas_format == MASA_ISM_FORMAT || ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nchan_ism > 0 ) ) { - /* Handle MONO output */ - if ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX ) + /* object editing possible only in two highest OMASA modes */ + if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) { - dirac_read_idx = st_ivas->hSpatParamRendCom->render_to_md_map[st_ivas->hSpatParamRendCom->subframes_rendered]; + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + { + hIvasEditableParameters->ism_metadata[obj].azimuth = st_ivas->hIsmMetaData[obj]->azimuth; + hIvasEditableParameters->ism_metadata[obj].elevation = st_ivas->hIsmMetaData[obj]->elevation; + hIvasEditableParameters->ism_metadata[obj].yaw = st_ivas->hIsmMetaData[obj]->yaw; + hIvasEditableParameters->ism_metadata[obj].pitch = st_ivas->hIsmMetaData[obj]->pitch; + hIvasEditableParameters->ism_metadata[obj].radius = st_ivas->hIsmMetaData[obj]->radius; + + /* reset the otherwise unused "gain" field for the object */ + st_ivas->hIsmMetaData[obj]->edited_gain = 1.0f; + hIvasEditableParameters->ism_metadata[obj].gain = st_ivas->hIsmMetaData[obj]->edited_gain; + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = st_ivas->hIsmMetaData[obj]->non_diegetic_flag; + } } - else + else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) { - dirac_read_idx = 0; - } + /* Handle MONO output */ + if ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX ) + { + dirac_read_idx = st_ivas->hSpatParamRendCom->render_to_md_map[st_ivas->hSpatParamRendCom->subframes_rendered]; + } + else + { + dirac_read_idx = 0; + } - for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) - { - hIvasEditableParameters->ism_metadata[obj].azimuth = st_ivas->hMasaIsmData->azimuth_ism[obj][dirac_read_idx]; - hIvasEditableParameters->ism_metadata[obj].elevation = st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx]; + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + { + hIvasEditableParameters->ism_metadata[obj].azimuth = st_ivas->hMasaIsmData->azimuth_ism[obj][dirac_read_idx]; + hIvasEditableParameters->ism_metadata[obj].elevation = st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx]; - hIvasEditableParameters->ism_metadata[obj].yaw = st_ivas->hIsmMetaData[obj]->yaw; - hIvasEditableParameters->ism_metadata[obj].pitch = st_ivas->hIsmMetaData[obj]->pitch; - hIvasEditableParameters->ism_metadata[obj].radius = st_ivas->hIsmMetaData[obj]->radius; + hIvasEditableParameters->ism_metadata[obj].yaw = st_ivas->hIsmMetaData[obj]->yaw; + hIvasEditableParameters->ism_metadata[obj].pitch = st_ivas->hIsmMetaData[obj]->pitch; + hIvasEditableParameters->ism_metadata[obj].radius = st_ivas->hIsmMetaData[obj]->radius; - /* reset the otherwise unused "gain" field for the object */ - st_ivas->hIsmMetaData[obj]->edited_gain = 1.0f; - hIvasEditableParameters->ism_metadata[obj].gain = st_ivas->hIsmMetaData[obj]->edited_gain; - hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = st_ivas->hIsmMetaData[obj]->non_diegetic_flag; + /* reset the otherwise unused "gain" field for the object */ + st_ivas->hIsmMetaData[obj]->edited_gain = 1.0f; + hIvasEditableParameters->ism_metadata[obj].gain = st_ivas->hIsmMetaData[obj]->edited_gain; + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = st_ivas->hIsmMetaData[obj]->non_diegetic_flag; + } + } + else if ( ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || ism_mode == ISM_MODE_NONE ) + { + hIvasEditableParameters->num_obj = 0; } - } - else if ( ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || ism_mode == ISM_MODE_NONE ) - { - hIvasEditableParameters->num_obj = 0; - } #ifdef DEBUGGING - else - { - assert( 0 && "This should never happen!" ); - } + else + { + assert( 0 && "This should never happen!" ); + } #endif - } - - return IVAS_ERR_OK; -} + } + return IVAS_ERR_OK; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_SetEditableParameters( ) - * - * Set editable metadata parameters - *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_SetEditableParameters( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_EDITABLE_PARAMETERS hIvasEditableParameters /* i : object editing parameters handle */ -) -{ - int16_t dirac_read_idx, obj; - Decoder_Struct *st_ivas; - ISM_MODE ism_mode; + /*---------------------------------------------------------------------* + * IVAS_DEC_SetEditableParameters( ) + * + * Set editable metadata parameters + *---------------------------------------------------------------------*/ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + ivas_error IVAS_DEC_SetEditableParameters( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_EDITABLE_PARAMETERS hIvasEditableParameters /* i : object editing parameters handle */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + int16_t dirac_read_idx, obj; + Decoder_Struct *st_ivas; + ISM_MODE ism_mode; - if ( !hIvasDec->hasBeenFedFirstGoodFrame ) - { - return IVAS_ERR_OK; - } + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - st_ivas = hIvasDec->st_ivas; - ism_mode = st_ivas->ism_mode; + if ( !hIvasDec->hasBeenFedFirstGoodFrame ) + { + return IVAS_ERR_OK; + } - if ( !( st_ivas->ivas_format == ISM_FORMAT || - st_ivas->ivas_format == SBA_ISM_FORMAT || - st_ivas->ivas_format == MASA_ISM_FORMAT || - ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nchan_ism > 0 ) ) ) - { - return IVAS_ERROR( IVAS_ERR_OBJECTS_EDITING_NOT_SUPPORTED, "Object editing no supported in this operation mode." ); - } + st_ivas = hIvasDec->st_ivas; + ism_mode = st_ivas->ism_mode; - if ( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) - { - if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) + if ( !( st_ivas->ivas_format == ISM_FORMAT || + st_ivas->ivas_format == SBA_ISM_FORMAT || + st_ivas->ivas_format == MASA_ISM_FORMAT || + ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nchan_ism > 0 ) ) ) + { + return IVAS_ERROR( IVAS_ERR_OBJECTS_EDITING_NOT_SUPPORTED, "Object editing no supported in this operation mode." ); + } + + if ( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) { + if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) + { #ifdef DEBUGGING - assert( hIvasEditableParameters.num_obj == st_ivas->nchan_ism ); + assert( hIvasEditableParameters.num_obj == st_ivas->nchan_ism ); #endif - for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) - { - st_ivas->hIsmMetaData[obj]->edited_azimuth = hIvasEditableParameters.ism_metadata[obj].azimuth; - st_ivas->hIsmMetaData[obj]->edited_elevation = hIvasEditableParameters.ism_metadata[obj].elevation; - st_ivas->hIsmMetaData[obj]->edited_radius = hIvasEditableParameters.ism_metadata[obj].radius; - st_ivas->hIsmMetaData[obj]->edited_yaw = hIvasEditableParameters.ism_metadata[obj].yaw; - st_ivas->hIsmMetaData[obj]->edited_pitch = hIvasEditableParameters.ism_metadata[obj].pitch; - if ( hIvasEditableParameters.ism_metadata[obj].gain > EDIT_GAIN_MAX ) + for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) { - st_ivas->hIsmMetaData[obj]->edited_gain = EDIT_GAIN_MAX; + st_ivas->hIsmMetaData[obj]->edited_azimuth = hIvasEditableParameters.ism_metadata[obj].azimuth; + st_ivas->hIsmMetaData[obj]->edited_elevation = hIvasEditableParameters.ism_metadata[obj].elevation; + st_ivas->hIsmMetaData[obj]->edited_radius = hIvasEditableParameters.ism_metadata[obj].radius; + st_ivas->hIsmMetaData[obj]->edited_yaw = hIvasEditableParameters.ism_metadata[obj].yaw; + st_ivas->hIsmMetaData[obj]->edited_pitch = hIvasEditableParameters.ism_metadata[obj].pitch; + if ( hIvasEditableParameters.ism_metadata[obj].gain > EDIT_GAIN_MAX ) + { + st_ivas->hIsmMetaData[obj]->edited_gain = EDIT_GAIN_MAX; + } + else + { + st_ivas->hIsmMetaData[obj]->edited_gain = hIvasEditableParameters.ism_metadata[obj].gain; + } + st_ivas->hIsmMetaData[obj]->non_diegetic_flag = hIvasEditableParameters.ism_metadata[obj].non_diegetic_flag; } - else + + if ( ism_mode == ISM_SBA_MODE_DISC ) { - st_ivas->hIsmMetaData[obj]->edited_gain = hIvasEditableParameters.ism_metadata[obj].gain; + if ( hIvasEditableParameters.gain_bed > EDIT_GAIN_MAX ) + { + st_ivas->hSbaIsmData->gain_bed = EDIT_GAIN_MAX; + } + else + { + st_ivas->hSbaIsmData->gain_bed = hIvasEditableParameters.gain_bed; + } } - st_ivas->hIsmMetaData[obj]->non_diegetic_flag = hIvasEditableParameters.ism_metadata[obj].non_diegetic_flag; } - - if ( ism_mode == ISM_SBA_MODE_DISC ) + else if ( ism_mode == ISM_MODE_PARAM ) { - if ( hIvasEditableParameters.gain_bed > EDIT_GAIN_MAX ) +#ifdef DEBUGGING + assert( hIvasEditableParameters.num_obj == st_ivas->nchan_ism ); +#endif + for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) { - st_ivas->hSbaIsmData->gain_bed = EDIT_GAIN_MAX; + st_ivas->hParamIsmDec->edited_azimuth_values[obj] = hIvasEditableParameters.ism_metadata[obj].azimuth; + st_ivas->hParamIsmDec->edited_elevation_values[obj] = hIvasEditableParameters.ism_metadata[obj].elevation; + + if ( st_ivas->hMasaIsmData != NULL ) + { + /* Limit gain edit to a range of +12dB to -24dB with parametric ISM mode */ + if ( hIvasEditableParameters.ism_metadata[obj].gain > EDIT_GAIN_MAX ) + { + st_ivas->hMasaIsmData->gain_ism_edited[obj] = EDIT_GAIN_MAX; + } + else if ( hIvasEditableParameters.ism_metadata[obj].gain < EDIT_GAIN_MIN ) + { + st_ivas->hMasaIsmData->gain_ism_edited[obj] = EDIT_GAIN_MIN; + } + else + { + st_ivas->hMasaIsmData->gain_ism_edited[obj] = hIvasEditableParameters.ism_metadata[obj].gain; + } + + /* Detect direction editing in Param-ISM mode */ + if ( fabsf( st_ivas->hParamIsmDec->azimuth_values[obj] - hIvasEditableParameters.ism_metadata[obj].azimuth ) > OMASA_AZI_EDIT_THR || + fabsf( st_ivas->hParamIsmDec->elevation_values[obj] - hIvasEditableParameters.ism_metadata[obj].elevation ) > OMASA_ELE_EDIT_THR ) + { + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; + } + else + { + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 0u; + } + + /* Detect gain editing in Param-ISM mode */ + if ( fabsf( 1.0f - hIvasEditableParameters.ism_metadata[obj].gain ) > OMASA_GAIN_EDIT_THR ) + { + st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 1u; + } + else + { + st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 0u; + } + } } - else + + if ( st_ivas->hMasaIsmData != NULL ) + { + /* MASA is not present with the ISM format */ + st_ivas->hMasaIsmData->masa_gain_is_edited = 0u; + } + } + else if ( ism_mode == ISM_MODE_NONE ) + { + if ( hIvasEditableParameters.num_obj != 0 ) { - st_ivas->hSbaIsmData->gain_bed = hIvasEditableParameters.gain_bed; + return IVAS_ERR_OBJECTS_EDITING_NOT_SUPPORTED; } } +#ifdef DEBUGGING + else + { + assert( 0 && "This should never happen!" ); + } +#endif } - else if ( ism_mode == ISM_MODE_PARAM ) + else if ( st_ivas->ivas_format == MASA_ISM_FORMAT && ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || ism_mode == ISM_MASA_MODE_DISC ) ) { + int16_t id_th; + float threshold_azi, threshold_ele; + #ifdef DEBUGGING assert( hIvasEditableParameters.num_obj == st_ivas->nchan_ism ); #endif for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) { - st_ivas->hParamIsmDec->edited_azimuth_values[obj] = hIvasEditableParameters.ism_metadata[obj].azimuth; - st_ivas->hParamIsmDec->edited_elevation_values[obj] = hIvasEditableParameters.ism_metadata[obj].elevation; - if ( st_ivas->hMasaIsmData != NULL ) { - /* Limit gain edit to a range of +12dB to -24dB with parametric ISM mode */ - if ( hIvasEditableParameters.ism_metadata[obj].gain > EDIT_GAIN_MAX ) + /* copy relevant fields also to OMASA structs, but only if the value has been changed. original values are in st_ivas->hIsmMetaData */ + /* first, need to convert float values to ints used internally */ + int16_t new_azi, new_ele; + if ( hIvasEditableParameters.ism_metadata[obj].azimuth > 0.0f ) + { + new_azi = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].azimuth + 0.5f ); + } + else { - st_ivas->hMasaIsmData->gain_ism_edited[obj] = EDIT_GAIN_MAX; + new_azi = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].azimuth - 0.5f ); } - else if ( hIvasEditableParameters.ism_metadata[obj].gain < EDIT_GAIN_MIN ) + + if ( hIvasEditableParameters.ism_metadata[obj].elevation > 0.0f ) { - st_ivas->hMasaIsmData->gain_ism_edited[obj] = EDIT_GAIN_MIN; + new_ele = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].elevation + 0.5f ); } else { - st_ivas->hMasaIsmData->gain_ism_edited[obj] = hIvasEditableParameters.ism_metadata[obj].gain; + new_ele = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].elevation - 0.5f ); } - /* Detect direction editing in Param-ISM mode */ - if ( fabsf( st_ivas->hParamIsmDec->azimuth_values[obj] - hIvasEditableParameters.ism_metadata[obj].azimuth ) > OMASA_AZI_EDIT_THR || - fabsf( st_ivas->hParamIsmDec->elevation_values[obj] - hIvasEditableParameters.ism_metadata[obj].elevation ) > OMASA_ELE_EDIT_THR ) + if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) { - st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; + /* Handle MONO output */ + if ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX ) + { + dirac_read_idx = st_ivas->hSpatParamRendCom->render_to_md_map[st_ivas->hSpatParamRendCom->subframes_rendered]; + } + else + { + dirac_read_idx = 0; + } + + /* determine thresholds for detecting object metadata edit for direction based on quantization resolution of the spatial direction parameters. + * these depend from the number of bits used to transmit the directions, + * which in turn depends from the object priority and importance: + * importance -> priority -> number of bits -> elevation resolution -> elevation ring index -> azimuth resolution. + * leading to elevation_resolution -> elevation threshold and azimuth resolution -> azimuth threshold */ + id_th = (int16_t) ( fabsf( (float) st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx] ) / delta_theta_masa[st_ivas->hMasaIsmData->bits_ism[obj] - 3] + 0.5f ); + threshold_azi = 360.0f / (float) no_phi_masa[st_ivas->hMasaIsmData->bits_ism[obj] - 1][id_th]; + threshold_ele = delta_theta_masa[st_ivas->hMasaIsmData->bits_ism[obj] - 3]; + + if ( ( (float) abs( new_azi - st_ivas->hMasaIsmData->azimuth_ism[obj][dirac_read_idx] ) > threshold_azi ) || + ( (float) abs( new_ele - st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx] ) > threshold_ele ) ) + { + /* at least one of the threshold is exceeded, so use new direction value and set editing detection flag */ + st_ivas->hMasaIsmData->azimuth_ism_edited[obj] = new_azi; + st_ivas->hMasaIsmData->elevation_ism_edited[obj] = new_ele; + + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; + } + else + { + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 0u; + } } else { - st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 0u; + /* detect editing in ISM_MASA_MODE_DISC mode */ + if ( fabsf( st_ivas->hIsmMetaData[obj]->azimuth - hIvasEditableParameters.ism_metadata[obj].azimuth ) > OMASA_AZI_EDIT_THR || + fabsf( st_ivas->hIsmMetaData[obj]->elevation - hIvasEditableParameters.ism_metadata[obj].elevation ) > OMASA_ELE_EDIT_THR ) + { + st_ivas->hMasaIsmData->azimuth_ism_edited[obj] = new_azi; + st_ivas->hMasaIsmData->elevation_ism_edited[obj] = new_ele; + + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; + } + else + { + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 0u; + } } - /* Detect gain editing in Param-ISM mode */ - if ( fabsf( 1.0f - hIvasEditableParameters.ism_metadata[obj].gain ) > OMASA_GAIN_EDIT_THR ) + /* compare pre-edit gain and the edited one to detect editing */ + if ( fabsf( st_ivas->hIsmMetaData[obj]->edited_gain - hIvasEditableParameters.ism_metadata[obj].gain ) > OMASA_GAIN_EDIT_THR ) { st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 1u; + + /* Limit masa gain edit to a range of +12dB to -infdB with discrete OMASA mode and +12dB to -24dB with parametric OMASA mode */ + if ( hIvasEditableParameters.ism_metadata[obj].gain > EDIT_GAIN_MAX ) + { + st_ivas->hMasaIsmData->gain_ism_edited[obj] = EDIT_GAIN_MAX; + } + else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && hIvasEditableParameters.ism_metadata[obj].gain < EDIT_GAIN_MIN ) + { + st_ivas->hMasaIsmData->gain_ism_edited[obj] = EDIT_GAIN_MIN; + } + else + { + st_ivas->hMasaIsmData->gain_ism_edited[obj] = hIvasEditableParameters.ism_metadata[obj].gain; + } } else { st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 0u; } } + + /* Copy edited values to hIsmMetaData struct */ + if ( st_ivas->hIsmMetaData[obj] != NULL ) + { + st_ivas->hIsmMetaData[obj]->edited_azimuth = hIvasEditableParameters.ism_metadata[obj].azimuth; + st_ivas->hIsmMetaData[obj]->edited_elevation = hIvasEditableParameters.ism_metadata[obj].elevation; + + if ( ism_mode == ISM_MASA_MODE_DISC ) + { + st_ivas->hIsmMetaData[obj]->edited_yaw = hIvasEditableParameters.ism_metadata[obj].yaw; + st_ivas->hIsmMetaData[obj]->edited_pitch = hIvasEditableParameters.ism_metadata[obj].pitch; + st_ivas->hIsmMetaData[obj]->edited_radius = hIvasEditableParameters.ism_metadata[obj].radius; + } + + if ( hIvasEditableParameters.ism_metadata[obj].gain > EDIT_GAIN_MAX ) + { + st_ivas->hIsmMetaData[obj]->edited_gain = EDIT_GAIN_MAX; + } + else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && hIvasEditableParameters.ism_metadata[obj].gain < EDIT_GAIN_MIN ) + { + st_ivas->hIsmMetaData[obj]->edited_gain = EDIT_GAIN_MIN; + } + else + { + st_ivas->hIsmMetaData[obj]->edited_gain = hIvasEditableParameters.ism_metadata[obj].gain; + } + + st_ivas->hIsmMetaData[obj]->non_diegetic_flag = hIvasEditableParameters.ism_metadata[obj].non_diegetic_flag; + } } - if ( st_ivas->hMasaIsmData != NULL ) + if ( fabsf( hIvasEditableParameters.gain_bed - 1.0f ) > OMASA_GAIN_EDIT_THR ) + { + /* Limit masa gain edit to a range of +12dB to -infdB with discrete OMASA mode and +12dB to -24dB with parametric OMASA mode */ + if ( hIvasEditableParameters.gain_bed > EDIT_GAIN_MAX ) + { + st_ivas->hMasaIsmData->gain_masa_edited = EDIT_GAIN_MAX; + } + else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && hIvasEditableParameters.gain_bed < EDIT_GAIN_MIN ) + { + st_ivas->hMasaIsmData->gain_masa_edited = EDIT_GAIN_MIN; + } + else + { + st_ivas->hMasaIsmData->gain_masa_edited = hIvasEditableParameters.gain_bed; + } + st_ivas->hMasaIsmData->masa_gain_is_edited = 1u; + } + else { - /* MASA is not present with the ISM format */ st_ivas->hMasaIsmData->masa_gain_is_edited = 0u; } } - else if ( ism_mode == ISM_MODE_NONE ) - { - if ( hIvasEditableParameters.num_obj != 0 ) - { - return IVAS_ERR_OBJECTS_EDITING_NOT_SUPPORTED; - } + + return IVAS_ERR_OK; + } + + + /*---------------------------------------------------------------------* + * IVAS_DEC_PrepareRenderer( ) + * + * prepare IVAS renderer + *---------------------------------------------------------------------*/ + + ivas_error IVAS_DEC_PrepareRenderer( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ + ) + { + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } -#ifdef DEBUGGING - else + + if ( hIvasDec->hasBeenFedFirstGoodFrame || hIvasDec->isInitialized ) /* note: 'isInitialized' is related to EVS decoder */ { - assert( 0 && "This should never happen!" ); + ivas_dec_prepare_renderer( hIvasDec->st_ivas ); } -#endif + + hIvasDec->hasBeenPreparedRendering = true; + + return IVAS_ERR_OK; } - else if ( st_ivas->ivas_format == MASA_ISM_FORMAT && ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || ism_mode == ISM_MASA_MODE_DISC ) ) - { - int16_t id_th; - float threshold_azi, threshold_ele; -#ifdef DEBUGGING - assert( hIvasEditableParameters.num_obj == st_ivas->nchan_ism ); -#endif - for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) - { - if ( st_ivas->hMasaIsmData != NULL ) - { - /* copy relevant fields also to OMASA structs, but only if the value has been changed. original values are in st_ivas->hIsmMetaData */ - /* first, need to convert float values to ints used internally */ - int16_t new_azi, new_ele; - if ( hIvasEditableParameters.ism_metadata[obj].azimuth > 0.0f ) - { - new_azi = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].azimuth + 0.5f ); - } - else - { - new_azi = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].azimuth - 0.5f ); - } - if ( hIvasEditableParameters.ism_metadata[obj].elevation > 0.0f ) - { - new_ele = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].elevation + 0.5f ); - } - else - { - new_ele = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].elevation - 0.5f ); - } + /*---------------------------------------------------------------------* + * IVAS_DEC_GetSamplesRenderer( ) + * + * Main function to render the decoded data to output data + *---------------------------------------------------------------------*/ - if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) - { - /* Handle MONO output */ - if ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX ) - { - dirac_read_idx = st_ivas->hSpatParamRendCom->render_to_md_map[st_ivas->hSpatParamRendCom->subframes_rendered]; - } - else - { - dirac_read_idx = 0; - } + ivas_error IVAS_DEC_GetSamplesRenderer( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t nSamplesAsked, /* i : number of samples wanted by the caller */ + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ + int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ + bool *needNewFrame /* o : indication that the decoder needs a new frame */ + ) + { + ivas_error error; + uint16_t nSamplesRendered, nSamplesRendered_loop; + uint8_t nOutChannels; + Decoder_Struct *st_ivas; - /* determine thresholds for detecting object metadata edit for direction based on quantization resolution of the spatial direction parameters. - * these depend from the number of bits used to transmit the directions, - * which in turn depends from the object priority and importance: - * importance -> priority -> number of bits -> elevation resolution -> elevation ring index -> azimuth resolution. - * leading to elevation_resolution -> elevation threshold and azimuth resolution -> azimuth threshold */ - id_th = (int16_t) ( fabsf( (float) st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx] ) / delta_theta_masa[st_ivas->hMasaIsmData->bits_ism[obj] - 3] + 0.5f ); - threshold_azi = 360.0f / (float) no_phi_masa[st_ivas->hMasaIsmData->bits_ism[obj] - 1][id_th]; - threshold_ele = delta_theta_masa[st_ivas->hMasaIsmData->bits_ism[obj] - 3]; - - if ( ( (float) abs( new_azi - st_ivas->hMasaIsmData->azimuth_ism[obj][dirac_read_idx] ) > threshold_azi ) || - ( (float) abs( new_ele - st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx] ) > threshold_ele ) ) - { - /* at least one of the threshold is exceeded, so use new direction value and set editing detection flag */ - st_ivas->hMasaIsmData->azimuth_ism_edited[obj] = new_azi; - st_ivas->hMasaIsmData->elevation_ism_edited[obj] = new_ele; + nSamplesRendered = 0; + nOutChannels = 0; + nSamplesRendered_loop = 0; - st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; - } - else - { - st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 0u; - } - } - else - { - /* detect editing in ISM_MASA_MODE_DISC mode */ - if ( fabsf( st_ivas->hIsmMetaData[obj]->azimuth - hIvasEditableParameters.ism_metadata[obj].azimuth ) > OMASA_AZI_EDIT_THR || - fabsf( st_ivas->hIsmMetaData[obj]->elevation - hIvasEditableParameters.ism_metadata[obj].elevation ) > OMASA_ELE_EDIT_THR ) - { - st_ivas->hMasaIsmData->azimuth_ism_edited[obj] = new_azi; - st_ivas->hMasaIsmData->elevation_ism_edited[obj] = new_ele; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; - } - else - { - st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 0u; - } - } + /* the rendering needs to be prepared at this point */ + if ( hIvasDec->hasBeenPreparedRendering == false ) + { + return IVAS_ERR_UNKNOWN; + } - /* compare pre-edit gain and the edited one to detect editing */ - if ( fabsf( st_ivas->hIsmMetaData[obj]->edited_gain - hIvasEditableParameters.ism_metadata[obj].gain ) > OMASA_GAIN_EDIT_THR ) - { - st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 1u; + st_ivas = hIvasDec->st_ivas; - /* Limit masa gain edit to a range of +12dB to -infdB with discrete OMASA mode and +12dB to -24dB with parametric OMASA mode */ - if ( hIvasEditableParameters.ism_metadata[obj].gain > EDIT_GAIN_MAX ) - { - st_ivas->hMasaIsmData->gain_ism_edited[obj] = EDIT_GAIN_MAX; - } - else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && hIvasEditableParameters.ism_metadata[obj].gain < EDIT_GAIN_MIN ) - { - st_ivas->hMasaIsmData->gain_ism_edited[obj] = EDIT_GAIN_MIN; - } - else - { - st_ivas->hMasaIsmData->gain_ism_edited[obj] = hIvasEditableParameters.ism_metadata[obj].gain; - } - } - else - { - st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 0u; - } + if ( hIvasDec->updateOrientation ) + { + /*----------------------------------------------------------------* + * Combine orientations + *----------------------------------------------------------------*/ + + if ( ( error = combine_external_and_head_orientations_dec( st_ivas->hHeadTrackData, st_ivas->hExtOrientationData, st_ivas->hCombinedOrientationData ) ) != IVAS_ERR_OK ) + { + return error; } - /* Copy edited values to hIsmMetaData struct */ - if ( st_ivas->hIsmMetaData[obj] != NULL ) + /*----------------------------------------------------------------* + * Binaural split rendering setup + *----------------------------------------------------------------*/ + + if ( st_ivas->hCombinedOrientationData != NULL && ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) { - st_ivas->hIsmMetaData[obj]->edited_azimuth = hIvasEditableParameters.ism_metadata[obj].azimuth; - st_ivas->hIsmMetaData[obj]->edited_elevation = hIvasEditableParameters.ism_metadata[obj].elevation; + isar_set_split_rend_ht_setup( &st_ivas->hSplitBinRend->splitrend, st_ivas->hCombinedOrientationData->Quaternions, st_ivas->hCombinedOrientationData->Rmat ); + } - if ( ism_mode == ISM_MASA_MODE_DISC ) - { - st_ivas->hIsmMetaData[obj]->edited_yaw = hIvasEditableParameters.ism_metadata[obj].yaw; - st_ivas->hIsmMetaData[obj]->edited_pitch = hIvasEditableParameters.ism_metadata[obj].pitch; - st_ivas->hIsmMetaData[obj]->edited_radius = hIvasEditableParameters.ism_metadata[obj].radius; - } + hIvasDec->updateOrientation = false; + } + + if ( !hIvasDec->hasBeenFedFrame && hIvasDec->nSamplesAvailableNext == 0 ) + { + /* no frame was fed, do nothing but ask for a frame */ + *needNewFrame = true; + *nOutSamples = 0; + hIvasDec->needNewFrame = true; + return IVAS_ERR_OK; + } + + /* check if we are still at the beginning with bad frames, put out zeroes, keep track of subframes */ + if ( !hIvasDec->isInitialized && st_ivas->bfi ) + { + hIvasDec->hasBeenFedFrame = false; + set_s( pcmBuf, 0, st_ivas->hDecoderConfig->nchan_out * nSamplesAsked ); + nSamplesRendered = nSamplesAsked; + hIvasDec->nSamplesAvailableNext -= nSamplesAsked; + } + else + { + nOutChannels = (uint8_t) st_ivas->hDecoderConfig->nchan_out; + hIvasDec->hasBeenFedFrame = false; - if ( hIvasEditableParameters.ism_metadata[obj].gain > EDIT_GAIN_MAX ) + /* check for possible flushed samples from a rate switch */ + if ( hIvasDec->nSamplesFlushed > 0 ) + { +#ifdef DEBUGGING + assert( hIvasDec->pcmType == pcmType ); +#endif + /* note: offset (rendered samples) is always 0 */ + if ( pcmType == IVAS_DEC_PCM_INT16 ) { - st_ivas->hIsmMetaData[obj]->edited_gain = EDIT_GAIN_MAX; + mvs2s( (int16_t *) hIvasDec->flushbuffer, pcmBuf, hIvasDec->nSamplesFlushed * nOutChannels ); } - else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && hIvasEditableParameters.ism_metadata[obj].gain < EDIT_GAIN_MIN ) + else if ( pcmType == IVAS_DEC_PCM_FLOAT ) { - st_ivas->hIsmMetaData[obj]->edited_gain = EDIT_GAIN_MIN; + mvr2r( (float *) hIvasDec->flushbuffer, pcmBuf, hIvasDec->nSamplesFlushed * nOutChannels ); } +#ifdef DEBUGGING else { - st_ivas->hIsmMetaData[obj]->edited_gain = hIvasEditableParameters.ism_metadata[obj].gain; + assert( 0 && "wrong PCM type for the flush buffer!" ); } +#endif + nSamplesRendered = hIvasDec->nSamplesFlushed; + hIvasDec->nSamplesFlushed = 0; + } - st_ivas->hIsmMetaData[obj]->non_diegetic_flag = hIvasEditableParameters.ism_metadata[obj].non_diegetic_flag; + /* render IVAS frames directly to the output buffer */ + if ( ( error = ivas_dec_render( st_ivas, nSamplesAsked - nSamplesRendered, &nSamplesRendered_loop, &hIvasDec->nSamplesAvailableNext, pcm_type_API_to_internal( pcmType ), pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ) ) ) != IVAS_ERR_OK ) + { + return error; } + + nSamplesRendered += nSamplesRendered_loop; } - if ( fabsf( hIvasEditableParameters.gain_bed - 1.0f ) > OMASA_GAIN_EDIT_THR ) + if ( hIvasDec->nSamplesAvailableNext == 0 ) { - /* Limit masa gain edit to a range of +12dB to -infdB with discrete OMASA mode and +12dB to -24dB with parametric OMASA mode */ - if ( hIvasEditableParameters.gain_bed > EDIT_GAIN_MAX ) - { - st_ivas->hMasaIsmData->gain_masa_edited = EDIT_GAIN_MAX; - } - else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && hIvasEditableParameters.gain_bed < EDIT_GAIN_MIN ) - { - st_ivas->hMasaIsmData->gain_masa_edited = EDIT_GAIN_MIN; - } - else - { - st_ivas->hMasaIsmData->gain_masa_edited = hIvasEditableParameters.gain_bed; - } - st_ivas->hMasaIsmData->masa_gain_is_edited = 1u; + *needNewFrame = true; + hIvasDec->needNewFrame = true; } else { - st_ivas->hMasaIsmData->masa_gain_is_edited = 0u; + *needNewFrame = false; } - } - - return IVAS_ERR_OK; -} + *nOutSamples = nSamplesRendered; -/*---------------------------------------------------------------------* - * IVAS_DEC_PrepareRenderer( ) - * - * prepare IVAS renderer - *---------------------------------------------------------------------*/ - -ivas_error IVAS_DEC_PrepareRenderer( - IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ -) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - if ( hIvasDec->hasBeenFedFirstGoodFrame || hIvasDec->isInitialized ) /* note: 'isInitialized' is related to EVS decoder */ - { - ivas_dec_prepare_renderer( hIvasDec->st_ivas ); + return IVAS_ERR_OK; } - hIvasDec->hasBeenPreparedRendering = true; - return IVAS_ERR_OK; -} + /*---------------------------------------------------------------------* + * isar_get_frame_size( ) + * + * + *---------------------------------------------------------------------*/ + static int16_t isar_get_frame_size( + Decoder_Struct * st_ivas /* i : IVAS decoder handle */ + ) + { + int32_t output_Fs; + int16_t nSamplesPerChannel; -/*---------------------------------------------------------------------* - * IVAS_DEC_GetSamplesRenderer( ) - * - * Main function to render the decoded data to output data - *---------------------------------------------------------------------*/ + output_Fs = st_ivas->hDecoderConfig->output_Fs; -ivas_error IVAS_DEC_GetSamplesRenderer( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const int16_t nSamplesAsked, /* i : number of samples wanted by the caller */ - const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ - void *pcmBuf, /* o : output synthesis signal */ - int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ - bool *needNewFrame /* o : indication that the decoder needs a new frame */ -) -{ - ivas_error error; - uint16_t nSamplesRendered, nSamplesRendered_loop; - uint8_t nOutChannels; - Decoder_Struct *st_ivas; - - nSamplesRendered = 0; - nOutChannels = 0; - nSamplesRendered_loop = 0; + if ( st_ivas->hDecoderConfig->render_num_subframes != IVAS_RENDER_NUM_SUBFR_20MS && + ( st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE || + st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) + { + nSamplesPerChannel = (int16_t) ( output_Fs / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ); + nSamplesPerChannel *= (int16_t) st_ivas->hDecoderConfig->render_num_subframes; + } + else + { + nSamplesPerChannel = (int16_t) ( output_Fs / FRAMES_PER_SEC ); + } - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + return nSamplesPerChannel; } - /* the rendering needs to be prepared at this point */ - if ( hIvasDec->hasBeenPreparedRendering == false ) - { - return IVAS_ERR_UNKNOWN; - } - st_ivas = hIvasDec->st_ivas; + /*---------------------------------------------------------------------* + * isar_render_poses( ) + * + * + *---------------------------------------------------------------------*/ - if ( hIvasDec->updateOrientation ) + static ivas_error isar_render_poses( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t nSamplesAsked, /* i : number of samples wanted by the caller */ + int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ + bool *needNewFrame /* o : indication that the decoder needs a new frame */ + ) { - /*----------------------------------------------------------------* - * Combine orientations - *----------------------------------------------------------------*/ - - if ( ( error = combine_external_and_head_orientations_dec( st_ivas->hHeadTrackData, st_ivas->hExtOrientationData, st_ivas->hCombinedOrientationData ) ) != IVAS_ERR_OK ) - { - return error; - } - - /*----------------------------------------------------------------* - * Binaural split rendering setup - *----------------------------------------------------------------*/ + float pcmBuf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES * L_FRAME48k]; + Decoder_Struct *st_ivas; + ivas_error error; + int16_t numPoses; - if ( st_ivas->hCombinedOrientationData != NULL && ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - isar_set_split_rend_ht_setup( &st_ivas->hSplitBinRend->splitrend, st_ivas->hCombinedOrientationData->Quaternions, st_ivas->hCombinedOrientationData->Rmat ); + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - hIvasDec->updateOrientation = false; - } + *needNewFrame = false; - if ( !hIvasDec->hasBeenFedFrame && hIvasDec->nSamplesAvailableNext == 0 ) - { - /* no frame was fed, do nothing but ask for a frame */ - *needNewFrame = true; - *nOutSamples = 0; - hIvasDec->needNewFrame = true; - return IVAS_ERR_OK; - } + st_ivas = hIvasDec->st_ivas; - /* check if we are still at the beginning with bad frames, put out zeroes, keep track of subframes */ - if ( !hIvasDec->isInitialized && st_ivas->bfi ) - { - hIvasDec->hasBeenFedFrame = false; - set_s( pcmBuf, 0, st_ivas->hDecoderConfig->nchan_out * nSamplesAsked ); - nSamplesRendered = nSamplesAsked; - hIvasDec->nSamplesAvailableNext -= nSamplesAsked; - } - else - { - nOutChannels = (uint8_t) st_ivas->hDecoderConfig->nchan_out; - hIvasDec->hasBeenFedFrame = false; + numPoses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; - /* check for possible flushed samples from a rate switch */ - if ( hIvasDec->nSamplesFlushed > 0 ) + /* init flush buffer for rate switch if not already initizalized */ + if ( hIvasDec->flushbuffer == NULL ) { -#ifdef DEBUGGING - assert( hIvasDec->pcmType == pcmType ); -#endif - /* note: offset (rendered samples) is always 0 */ - if ( pcmType == IVAS_DEC_PCM_INT16 ) + hIvasDec->flushbuffer = (void *) malloc( numPoses * BINAURAL_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( float ) ); + if ( hIvasDec->flushbuffer == NULL ) { - mvs2s( (int16_t *) hIvasDec->flushbuffer, pcmBuf, hIvasDec->nSamplesFlushed * nOutChannels ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate flush buffer" ); } - else if ( pcmType == IVAS_DEC_PCM_FLOAT ) - { - mvr2r( (float *) hIvasDec->flushbuffer, pcmBuf, hIvasDec->nSamplesFlushed * nOutChannels ); - } -#ifdef DEBUGGING - else - { - assert( 0 && "wrong PCM type for the flush buffer!" ); - } -#endif - nSamplesRendered = hIvasDec->nSamplesFlushed; - hIvasDec->nSamplesFlushed = 0; + hIvasDec->pcmType = IVAS_DEC_PCM_FLOAT; + set_zero( (float *) hIvasDec->flushbuffer, numPoses * BINAURAL_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ); } - /* render IVAS frames directly to the output buffer */ - if ( ( error = ivas_dec_render( st_ivas, nSamplesAsked - nSamplesRendered, &nSamplesRendered_loop, &hIvasDec->nSamplesAvailableNext, pcm_type_API_to_internal( pcmType ), pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ) ) ) != IVAS_ERR_OK ) + /* render */ + if ( ( error = IVAS_DEC_GetSamplesRenderer( hIvasDec, nSamplesAsked, IVAS_DEC_PCM_FLOAT, pcmBuf, nOutSamples, needNewFrame ) ) != IVAS_ERR_OK ) { return error; } - nSamplesRendered += nSamplesRendered_loop; - } - - if ( hIvasDec->nSamplesAvailableNext == 0 ) - { - *needNewFrame = true; - hIvasDec->needNewFrame = true; - } - else - { - *needNewFrame = false; - } - - *nOutSamples = nSamplesRendered; - - return IVAS_ERR_OK; -} + if ( !hIvasDec->hasBeenFedFirstGoodFrame ) + { + return IVAS_ERR_OK; + } + if ( !ivas_dec_split_rend_cldfb_in( st_ivas->renderer_type ) ) + { + ivas_TD_RINGBUF_PushInterleaved( st_ivas->hSplitBinRend->hMultiBinTdData, pcmBuf, *nOutSamples ); + } -/*---------------------------------------------------------------------* - * isar_get_frame_size( ) - * - * - *---------------------------------------------------------------------*/ + return error; + } -static int16_t isar_get_frame_size( - Decoder_Struct *st_ivas /* i : IVAS decoder handle */ -) -{ - int32_t output_Fs; - int16_t nSamplesPerChannel; - output_Fs = st_ivas->hDecoderConfig->output_Fs; + /*---------------------------------------------------------------------* + * isar_generate_metadata_and_bitstream( ) + * + * + *---------------------------------------------------------------------*/ - if ( st_ivas->hDecoderConfig->render_num_subframes != IVAS_RENDER_NUM_SUBFR_20MS && - ( st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE || - st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) + static ivas_error isar_generate_metadata_and_bitstream( + Decoder_Struct * st_ivas, /* i/o: IVAS decoder handle */ + float **p_head_pose_buf, /* i/o: PCM buffer with head-pose data */ + int16_t nSamples, /* i : duration of audio (in samples per channel) for which metadata should be generated */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ + ) { - nSamplesPerChannel = (int16_t) ( output_Fs / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ); - nSamplesPerChannel *= (int16_t) st_ivas->hDecoderConfig->render_num_subframes; - } - else - { - nSamplesPerChannel = (int16_t) ( output_Fs / FRAMES_PER_SEC ); - } + ivas_error error; + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; + int16_t max_band; + int16_t pcm_out_flag; + int16_t cldfb_in_flag; + int16_t ro_md_flag; + IVAS_QUATERNION Quaternion; + int16_t i, j, num_poses, num_cldfb_slots, n_samples_in_cldfb_slot; + float *p_Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX]; + float *p_Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX]; - return nSamplesPerChannel; -} + hSplitBinRend = st_ivas->hSplitBinRend; + max_band = (int16_t) ( ( BINAURAL_MAXBANDS * st_ivas->hDecoderConfig->output_Fs ) / 48000 ); + pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; + cldfb_in_flag = ivas_dec_split_rend_cldfb_in( st_ivas->renderer_type ); -/*---------------------------------------------------------------------* - * isar_render_poses( ) - * - * - *---------------------------------------------------------------------*/ - -static ivas_error isar_render_poses( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const int16_t nSamplesAsked, /* i : number of samples wanted by the caller */ - int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ - bool *needNewFrame /* o : indication that the decoder needs a new frame */ -) -{ - float pcmBuf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES * L_FRAME48k]; - Decoder_Struct *st_ivas; - ivas_error error; - int16_t numPoses; + if ( cldfb_in_flag ) + { + n_samples_in_cldfb_slot = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); + assert( nSamples % n_samples_in_cldfb_slot == 0 ); + num_cldfb_slots = nSamples / n_samples_in_cldfb_slot; - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + num_poses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; - *needNewFrame = false; + for ( i = 0; i < BINAURAL_CHANNELS * num_poses; ++i ) + { + for ( j = 0; j < num_cldfb_slots; ++j ) + { + /* Save pointers to first CLDFB column in the ring buffer. Allows us to save + * significant amounts of memory by not copying CLDFB values into a separate buffer. */ + ivas_CLDFB_RINGBUF_GetByIdx( hSplitBinRend->hMultiBinCldfbData[i], &p_Cldfb_RealBuffer_Binaural[i][j], &p_Cldfb_ImagBuffer_Binaural[i][j], 0 ); + + /* Pop the CLDFB column we just saved pointers to. This is fine as long as we use + * the saved columns only before any new columns are pushed to the buffer - the new + * columns could potentially overwrite the old columns we wanted to use. + * This requirement is fulfilled in this case. */ + ivas_CLDFB_RINGBUF_Pop( hSplitBinRend->hMultiBinCldfbData[i], NULL, NULL, CLDFB_NO_CHANNELS_MAX ); + } + } + } + else + { + ivas_TD_RINGBUF_PopChannels( st_ivas->hSplitBinRend->hMultiBinTdData, p_head_pose_buf, nSamples ); + } - st_ivas = hIvasDec->st_ivas; - numPoses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; + if ( st_ivas->hBinRendererTd != NULL ) + { + ro_md_flag = 1; + } + else + { + ro_md_flag = 0; + } - /* init flush buffer for rate switch if not already initizalized */ - if ( hIvasDec->flushbuffer == NULL ) - { - hIvasDec->flushbuffer = (void *) malloc( numPoses * BINAURAL_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( float ) ); - if ( hIvasDec->flushbuffer == NULL ) + if ( st_ivas->hHeadTrackData != NULL ) { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate flush buffer" ); + Quaternion = st_ivas->hHeadTrackData->Quaternions[0]; + } + else + { + Quaternion.w = -3.0f; + Quaternion.x = 0.0f; + Quaternion.y = 0.0f; + Quaternion.z = 0.0f; } - hIvasDec->pcmType = IVAS_DEC_PCM_FLOAT; - set_zero( (float *) hIvasDec->flushbuffer, numPoses * BINAURAL_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ); - } - /* render */ - if ( ( error = IVAS_DEC_GetSamplesRenderer( hIvasDec, nSamplesAsked, IVAS_DEC_PCM_FLOAT, pcmBuf, nOutSamples, needNewFrame ) ) != IVAS_ERR_OK ) - { - return error; - } + if ( ( error = ISAR_PRE_REND_MultiBinToSplitBinaural( &hSplitBinRend->splitrend, + Quaternion, + st_ivas->hRenderConfig->split_rend_config.splitRendBitRate, + st_ivas->hRenderConfig->split_rend_config.codec, + st_ivas->hRenderConfig->split_rend_config.isar_frame_size_ms, + st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms, + splitRendBits, + p_Cldfb_RealBuffer_Binaural, + p_Cldfb_ImagBuffer_Binaural, + max_band, p_head_pose_buf, 1, cldfb_in_flag, pcm_out_flag, ro_md_flag ) ) != IVAS_ERR_OK ) + { + return error; + } - if ( !hIvasDec->hasBeenFedFirstGoodFrame ) - { return IVAS_ERR_OK; } - if ( !ivas_dec_split_rend_cldfb_in( st_ivas->renderer_type ) ) - { - ivas_TD_RINGBUF_PushInterleaved( st_ivas->hSplitBinRend->hMultiBinTdData, pcmBuf, *nOutSamples ); - } - - return error; -} - -/*---------------------------------------------------------------------* - * isar_generate_metadata_and_bitstream( ) - * - * - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * IVAS_DEC_GetSplitBinauralBitstream( ) + * + * Get split-rendering bitstream + *---------------------------------------------------------------------*/ -static ivas_error isar_generate_metadata_and_bitstream( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - float **p_head_pose_buf, /* i/o: PCM buffer with head-pose data */ - int16_t nSamples, /* i : duration of audio (in samples per channel) for which metadata should be generated */ - ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ -) -{ - ivas_error error; - ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; - int16_t max_band; - int16_t pcm_out_flag; - int16_t cldfb_in_flag; - int16_t ro_md_flag; - IVAS_QUATERNION Quaternion; - int16_t i, j, num_poses, num_cldfb_slots, n_samples_in_cldfb_slot; - float *p_Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX]; - float *p_Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX]; - - hSplitBinRend = st_ivas->hSplitBinRend; - - max_band = (int16_t) ( ( BINAURAL_MAXBANDS * st_ivas->hDecoderConfig->output_Fs ) / 48000 ); - pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; - cldfb_in_flag = ivas_dec_split_rend_cldfb_in( st_ivas->renderer_type ); - - if ( cldfb_in_flag ) + ivas_error IVAS_DEC_GetSplitBinauralBitstream( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + void *pcmBuf_out, /* o : output synthesis signal for BINAURAL_SPLIT_PCM */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */ + int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ + bool *needNewFrame /* o : indication that the decoder needs a new frame */ + ) { - n_samples_in_cldfb_slot = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); - assert( nSamples % n_samples_in_cldfb_slot == 0 ); - num_cldfb_slots = nSamples / n_samples_in_cldfb_slot; - - num_poses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; + Decoder_Struct *st_ivas; + ivas_error error; + float head_pose_buf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES][L_FRAME48k]; + float *p_head_pose_buf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES]; + int16_t i; + int16_t pcm_out_flag; + int16_t numSamplesPerChannelToOutput; - for ( i = 0; i < BINAURAL_CHANNELS * num_poses; ++i ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - for ( j = 0; j < num_cldfb_slots; ++j ) - { - /* Save pointers to first CLDFB column in the ring buffer. Allows us to save - * significant amounts of memory by not copying CLDFB values into a separate buffer. */ - ivas_CLDFB_RINGBUF_GetByIdx( hSplitBinRend->hMultiBinCldfbData[i], &p_Cldfb_RealBuffer_Binaural[i][j], &p_Cldfb_ImagBuffer_Binaural[i][j], 0 ); - - /* Pop the CLDFB column we just saved pointers to. This is fine as long as we use - * the saved columns only before any new columns are pushed to the buffer - the new - * columns could potentially overwrite the old columns we wanted to use. - * This requirement is fulfilled in this case. */ - ivas_CLDFB_RINGBUF_Pop( hSplitBinRend->hMultiBinCldfbData[i], NULL, NULL, CLDFB_NO_CHANNELS_MAX ); - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - } - else - { - ivas_TD_RINGBUF_PopChannels( st_ivas->hSplitBinRend->hMultiBinTdData, p_head_pose_buf, nSamples ); - } - - - if ( st_ivas->hBinRendererTd != NULL ) - { - ro_md_flag = 1; - } - else - { - ro_md_flag = 0; - } - - if ( st_ivas->hHeadTrackData != NULL ) - { - Quaternion = st_ivas->hHeadTrackData->Quaternions[0]; - } - else - { - Quaternion.w = -3.0f; - Quaternion.x = 0.0f; - Quaternion.y = 0.0f; - Quaternion.z = 0.0f; - } - - if ( ( error = ISAR_PRE_REND_MultiBinToSplitBinaural( &hSplitBinRend->splitrend, - Quaternion, - st_ivas->hRenderConfig->split_rend_config.splitRendBitRate, - st_ivas->hRenderConfig->split_rend_config.codec, - st_ivas->hRenderConfig->split_rend_config.isar_frame_size_ms, - st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms, - splitRendBits, - p_Cldfb_RealBuffer_Binaural, - p_Cldfb_ImagBuffer_Binaural, - max_band, p_head_pose_buf, 1, cldfb_in_flag, pcm_out_flag, ro_md_flag ) ) != IVAS_ERR_OK ) - { - return error; - } - return IVAS_ERR_OK; -} - - -/*---------------------------------------------------------------------* - * IVAS_DEC_GetSplitBinauralBitstream( ) - * - * Get split-rendering bitstream - *---------------------------------------------------------------------*/ - -ivas_error IVAS_DEC_GetSplitBinauralBitstream( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - void *pcmBuf_out, /* o : output synthesis signal for BINAURAL_SPLIT_PCM */ - ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */ - int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ - bool *needNewFrame /* o : indication that the decoder needs a new frame */ -) -{ - Decoder_Struct *st_ivas; - ivas_error error; - float head_pose_buf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES][L_FRAME48k]; - float *p_head_pose_buf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES]; - int16_t i; - int16_t pcm_out_flag; - int16_t numSamplesPerChannelToOutput; - - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - st_ivas = hIvasDec->st_ivas; + st_ivas = hIvasDec->st_ivas; - if ( is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ) == 0 ) - { - return IVAS_ERR_WRONG_PARAMS; - } + if ( is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ) == 0 ) + { + return IVAS_ERR_WRONG_PARAMS; + } - pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; - numSamplesPerChannelToOutput = isar_get_frame_size( st_ivas ); + pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; + numSamplesPerChannelToOutput = isar_get_frame_size( st_ivas ); - if ( ( error = isar_render_poses( hIvasDec, numSamplesPerChannelToOutput, nOutSamples, needNewFrame ) ) != IVAS_ERR_OK ) - { - return error; - } + if ( ( error = isar_render_poses( hIvasDec, numSamplesPerChannelToOutput, nOutSamples, needNewFrame ) ) != IVAS_ERR_OK ) + { + return error; + } - if ( !hIvasDec->hasBeenFedFirstGoodFrame ) - { - return IVAS_ERR_OK; - } + if ( !hIvasDec->hasBeenFedFirstGoodFrame ) + { + return IVAS_ERR_OK; + } - for ( i = 0; i < BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES; ++i ) - { - p_head_pose_buf[i] = head_pose_buf[i]; - } + for ( i = 0; i < BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES; ++i ) + { + p_head_pose_buf[i] = head_pose_buf[i]; + } - if ( ( error = isar_generate_metadata_and_bitstream( st_ivas, p_head_pose_buf, *nOutSamples, splitRendBits ) ) != IVAS_ERR_OK ) - { - return error; - } + if ( ( error = isar_generate_metadata_and_bitstream( st_ivas, p_head_pose_buf, *nOutSamples, splitRendBits ) ) != IVAS_ERR_OK ) + { + return error; + } - /* convert to int16 with limiting for BINAURAL_SPLIT_PCM */ - if ( pcm_out_flag ) - { + /* convert to int16 with limiting for BINAURAL_SPLIT_PCM */ + if ( pcm_out_flag ) + { #ifndef DISABLE_LIMITER - ivas_limiter_dec( st_ivas->hLimiter, p_head_pose_buf, st_ivas->hDecoderConfig->nchan_out, numSamplesPerChannelToOutput, st_ivas->BER_detect ); + ivas_limiter_dec( st_ivas->hLimiter, p_head_pose_buf, st_ivas->hDecoderConfig->nchan_out, numSamplesPerChannelToOutput, st_ivas->BER_detect ); #endif #ifdef DEBUGGING - st_ivas->noClipping += + st_ivas->noClipping += #endif - ivas_syn_output( p_head_pose_buf, numSamplesPerChannelToOutput, st_ivas->hDecoderConfig->nchan_out, (int16_t *) pcmBuf_out ); - } - - return IVAS_ERR_OK; -} - - -/*---------------------------------------------------------------------* - * ivas_dec_setup_all() - * - * Set-up all decoder parts: IVAS decoder, ISAR - *---------------------------------------------------------------------*/ - -static ivas_error ivas_dec_setup_all( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint8_t *nTransportChannels, /* o : number of decoded transport PCM channels */ - ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ -) -{ - ivas_error error; + ivas_syn_output( p_head_pose_buf, numSamplesPerChannelToOutput, st_ivas->hDecoderConfig->nchan_out, (int16_t *) pcmBuf_out ); + } - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) - { - *nTransportChannels = 1; + return IVAS_ERR_OK; } - else - { - Decoder_Struct *st_ivas; - st_ivas = hIvasDec->st_ivas; - /* Setup IVAS split rendering */ - if ( splitRendBits != NULL ) + /*---------------------------------------------------------------------* + * ivas_dec_setup_all() + * + * Set-up all decoder parts: IVAS decoder, ISAR + *---------------------------------------------------------------------*/ + + static ivas_error ivas_dec_setup_all( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint8_t * nTransportChannels, /* o : number of decoded transport PCM channels */ + ISAR_SPLIT_REND_BITS_DATA * splitRendBits /* o : output split rendering bits */ + ) + { + ivas_error error; + + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + { + *nTransportChannels = 1; + } + else { - if ( ( error = isar_set_split_rend_setup( st_ivas->hSplitBinRend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hCombinedOrientationData, splitRendBits ) ) != IVAS_ERR_OK ) + Decoder_Struct *st_ivas; + + st_ivas = hIvasDec->st_ivas; + + /* Setup IVAS split rendering */ + if ( splitRendBits != NULL ) { - return error; + if ( ( error = isar_set_split_rend_setup( st_ivas->hSplitBinRend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hCombinedOrientationData, splitRendBits ) ) != IVAS_ERR_OK ) + { + return error; + } } - } - /*----------------------------------------------------------------* - * IVAS decoder setup - * - read IVAS format signaling - * - read IVAS format specific signaling - * - initialize decoder in the first frame based on IVAS format and number of transport channels - * - reconfigure the decoder when the number of TC or IVAS total bitrate change - *----------------------------------------------------------------*/ + /*----------------------------------------------------------------* + * IVAS decoder setup + * - read IVAS format signaling + * - read IVAS format specific signaling + * - initialize decoder in the first frame based on IVAS format and number of transport channels + * - reconfigure the decoder when the number of TC or IVAS total bitrate change + *----------------------------------------------------------------*/ - if ( st_ivas->bfi == 0 ) - { - if ( ( error = ivas_dec_setup( st_ivas ) ) != IVAS_ERR_OK ) + if ( st_ivas->bfi == 0 ) { - return error; + if ( ( error = ivas_dec_setup( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } } - } - *nTransportChannels = (uint8_t) st_ivas->hTcBuffer->nchan_transport_rend; + *nTransportChannels = (uint8_t) st_ivas->hTcBuffer->nchan_transport_rend; - /*-----------------------------------------------------------------* - * ISAR: - * - initialize ISAR handle at the first frame - * - reconfigure the ISAR handle in case of bitrate switching (renderer might change) - *-----------------------------------------------------------------*/ + /*-----------------------------------------------------------------* + * ISAR: + * - initialize ISAR handle at the first frame + * - reconfigure the ISAR handle in case of bitrate switching (renderer might change) + *-----------------------------------------------------------------*/ - if ( st_ivas->ini_frame == 0 && splitRendBits != NULL ) - { - if ( ( error = ivas_dec_init_split_rend( st_ivas ) ) != IVAS_ERR_OK ) + if ( st_ivas->ini_frame == 0 && splitRendBits != NULL ) { - return error; + if ( ( error = ivas_dec_init_split_rend( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } } - } - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - if ( ( error = ivas_dec_reconfig_split_rend( st_ivas ) ) != IVAS_ERR_OK ) + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - return error; + if ( ( error = ivas_dec_reconfig_split_rend( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } } } - } - - return IVAS_ERR_OK; -} + return IVAS_ERR_OK; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_GetNumObjects( ) - * - * Returns the number of objects available in the decoded bitstream - *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_GetNumObjects( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint16_t *numObjects /* o : number of objects for which the decoder has been configured */ -) -{ - int16_t is_masa_ism; - is_masa_ism = 0; + /*---------------------------------------------------------------------* + * IVAS_DEC_GetNumObjects( ) + * + * Returns the number of objects available in the decoded bitstream + *---------------------------------------------------------------------*/ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + ivas_error IVAS_DEC_GetNumObjects( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint16_t * numObjects /* o : number of objects for which the decoder has been configured */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + int16_t is_masa_ism; + is_masa_ism = 0; - if ( hIvasDec->st_ivas->hMasa != NULL ) - { - if ( hIvasDec->st_ivas->hMasa->config.input_ivas_format == MASA_ISM_FORMAT ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - is_masa_ism = 1; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - } - if ( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || hIvasDec->st_ivas->ivas_format == SBA_ISM_FORMAT || hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT || is_masa_ism ) - { - *numObjects = hIvasDec->st_ivas->nchan_ism; - } - else - { - *numObjects = 0; - } + if ( hIvasDec->st_ivas->hMasa != NULL ) + { + if ( hIvasDec->st_ivas->hMasa->config.input_ivas_format == MASA_ISM_FORMAT ) + { + is_masa_ism = 1; + } + } - return IVAS_ERR_OK; -} + if ( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || hIvasDec->st_ivas->ivas_format == SBA_ISM_FORMAT || hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT || is_masa_ism ) + { + *numObjects = hIvasDec->st_ivas->nchan_ism; + } + else + { + *numObjects = 0; + } + return IVAS_ERR_OK; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_GetFormat( ) - * - * Returns the format of currently decoded bitstream. - * Note: bitstream format is only known after the first (good) frame has been decoded. - *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_GetFormat( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_DEC_BS_FORMAT *format /* o : format detected from bitstream fed to the decoder */ -) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + /*---------------------------------------------------------------------* + * IVAS_DEC_GetFormat( ) + * + * Returns the format of currently decoded bitstream. + * Note: bitstream format is only known after the first (good) frame has been decoded. + *---------------------------------------------------------------------*/ - if ( hIvasDec->hasDecodedFirstGoodFrame ) - { - *format = mapIvasFormat( hIvasDec->st_ivas->ivas_format ); - } - else + ivas_error IVAS_DEC_GetFormat( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_DEC_BS_FORMAT * format /* o : format detected from bitstream fed to the decoder */ + ) { - *format = IVAS_DEC_BS_UNKOWN; - } + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( *format == IVAS_DEC_BS_MASA && hIvasDec->st_ivas->hMasa != NULL ) - { - if ( hIvasDec->st_ivas->hMasa->config.input_ivas_format == MASA_ISM_FORMAT ) + if ( hIvasDec->hasDecodedFirstGoodFrame ) { - *format = IVAS_DEC_BS_MASA_ISM; + *format = mapIvasFormat( hIvasDec->st_ivas->ivas_format ); + } + else + { + *format = IVAS_DEC_BS_UNKOWN; } - } - return IVAS_ERR_OK; -} + if ( *format == IVAS_DEC_BS_MASA && hIvasDec->st_ivas->hMasa != NULL ) + { + if ( hIvasDec->st_ivas->hMasa->config.input_ivas_format == MASA_ISM_FORMAT ) + { + *format = IVAS_DEC_BS_MASA_ISM; + } + } + return IVAS_ERR_OK; + } -/*---------------------------------------------------------------------* - * getOutputBufferSize() - * - * Get size of output buffer in samples - *---------------------------------------------------------------------*/ -static int16_t getOutputBufferSize( - const Decoder_Struct *st_ivas /* i : IVAS decoder handle */ -) -{ - if ( st_ivas->hDecoderConfig == NULL ) - { - return -1; - } + /*---------------------------------------------------------------------* + * getOutputBufferSize() + * + * Get size of output buffer in samples + *---------------------------------------------------------------------*/ - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) - { - return (int16_t) ( st_ivas->hDecoderConfig->output_Fs * ( MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS ) / FRAMES_PER_SEC ); - } - else if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM ) + static int16_t getOutputBufferSize( + const Decoder_Struct *st_ivas /* i : IVAS decoder handle */ + ) { - if ( st_ivas->hLsSetupCustom == NULL ) + if ( st_ivas->hDecoderConfig == NULL ) { return -1; } - return (int16_t) ( st_ivas->hDecoderConfig->output_Fs * ( st_ivas->hLsSetupCustom->num_spk + st_ivas->hLsSetupCustom->num_lfe ) / FRAMES_PER_SEC ); - } - else - { - return (int16_t) ( st_ivas->hDecoderConfig->output_Fs * st_ivas->hDecoderConfig->nchan_out / FRAMES_PER_SEC ); + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) + { + return (int16_t) ( st_ivas->hDecoderConfig->output_Fs * ( MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS ) / FRAMES_PER_SEC ); + } + else if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM ) + { + if ( st_ivas->hLsSetupCustom == NULL ) + { + return -1; + } + + return (int16_t) ( st_ivas->hDecoderConfig->output_Fs * ( st_ivas->hLsSetupCustom->num_spk + st_ivas->hLsSetupCustom->num_lfe ) / FRAMES_PER_SEC ); + } + else + { + return (int16_t) ( st_ivas->hDecoderConfig->output_Fs * st_ivas->hDecoderConfig->nchan_out / FRAMES_PER_SEC ); + } } -} -/*---------------------------------------------------------------------* - * IVAS_DEC_GetOutputBufferSize() - * - * Returns size of output buffer in samples - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * IVAS_DEC_GetOutputBufferSize() + * + * Returns size of output buffer in samples + *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_GetOutputBufferSize( - const IVAS_DEC_HANDLE hIvasDec, /* i : IVAS decoder handle */ - int16_t *outputBufferSize /* o : total number of samples expected in the output buffer for current decoder configuration */ -) -{ - if ( outputBufferSize == NULL || hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + ivas_error IVAS_DEC_GetOutputBufferSize( + const IVAS_DEC_HANDLE hIvasDec, /* i : IVAS decoder handle */ + int16_t *outputBufferSize /* o : total number of samples expected in the output buffer for current decoder configuration */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + if ( outputBufferSize == NULL || hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - *outputBufferSize = getOutputBufferSize( hIvasDec->st_ivas ); + *outputBufferSize = getOutputBufferSize( hIvasDec->st_ivas ); - if ( *outputBufferSize == -1 ) - { - return IVAS_ERR_INVALID_OUTPUT_BUFFER_SIZE; - } - else - { - return IVAS_ERR_OK; + if ( *outputBufferSize == -1 ) + { + return IVAS_ERR_INVALID_OUTPUT_BUFFER_SIZE; + } + else + { + return IVAS_ERR_OK; + } } -} -/*---------------------------------------------------------------------* - * IVAS_DEC_GetNumOutputChannels( ) - * - * Returns number of output channels - *---------------------------------------------------------------------*/ - -ivas_error IVAS_DEC_GetNumOutputChannels( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t *numOutputChannels /* o : number of PCM output channels */ -) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + /*---------------------------------------------------------------------* + * IVAS_DEC_GetNumOutputChannels( ) + * + * Returns number of output channels + *---------------------------------------------------------------------*/ - if ( hIvasDec->hasDecodedFirstGoodFrame ) - { - *numOutputChannels = hIvasDec->st_ivas->hDecoderConfig->nchan_out; - } - else + ivas_error IVAS_DEC_GetNumOutputChannels( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t * numOutputChannels /* o : number of PCM output channels */ + ) { - *numOutputChannels = 0; - } + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - return IVAS_ERR_OK; -} + if ( hIvasDec->hasDecodedFirstGoodFrame ) + { + *numOutputChannels = hIvasDec->st_ivas->hDecoderConfig->nchan_out; + } + else + { + *numOutputChannels = 0; + } + return IVAS_ERR_OK; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_GetObjectMetadata( ) - * - * Get metadata of one object decoded in the most recent frame - *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_GetObjectMetadata( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_ISM_METADATA *metadata, /* o : struct where metadata decoded in most recently decoded frame will be written */ - const uint16_t zero_flag, /* i : if this flag is enabled, this function outputs a zero-initialized metadata struct */ - const uint16_t objectIdx /* i : index of the queried object */ -) -{ - Decoder_Struct *st_ivas; - ISM_METADATA_HANDLE hIsmMeta; - int16_t is_masa_ism; - is_masa_ism = 0; + /*---------------------------------------------------------------------* + * IVAS_DEC_GetObjectMetadata( ) + * + * Get metadata of one object decoded in the most recent frame + *---------------------------------------------------------------------*/ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + ivas_error IVAS_DEC_GetObjectMetadata( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_ISM_METADATA * metadata, /* o : struct where metadata decoded in most recently decoded frame will be written */ + const uint16_t zero_flag, /* i : if this flag is enabled, this function outputs a zero-initialized metadata struct */ + const uint16_t objectIdx /* i : index of the queried object */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + Decoder_Struct *st_ivas; + ISM_METADATA_HANDLE hIsmMeta; + int16_t is_masa_ism; + is_masa_ism = 0; - st_ivas = hIvasDec->st_ivas; - if ( hIvasDec->st_ivas->hMasa != NULL ) - { - if ( hIvasDec->st_ivas->hMasa->config.input_ivas_format == MASA_ISM_FORMAT ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - is_masa_ism = 1; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - } - if ( st_ivas->ivas_format != ISM_FORMAT && st_ivas->ivas_format != MASA_ISM_FORMAT && st_ivas->ivas_format != SBA_ISM_FORMAT && is_masa_ism == 0 ) - { - return IVAS_ERR_WRONG_MODE; - } - - if ( objectIdx >= st_ivas->nchan_ism ) - { - return IVAS_ERR_INVALID_INDEX; - } - - hIsmMeta = st_ivas->hIsmMetaData[objectIdx]; - if ( hIsmMeta == NULL || zero_flag || ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) ) - { - metadata->azimuth = 0.f; - metadata->elevation = 0.f; - metadata->radius = 1.f; - metadata->spread = 0.f; - metadata->gainFactor = 1.f; - metadata->yaw = 0.f; - metadata->pitch = 0.f; - metadata->non_diegetic_flag = 0; - } - else - { - if ( st_ivas->ism_mode == ISM_MODE_DISC ) + st_ivas = hIvasDec->st_ivas; + if ( hIvasDec->st_ivas->hMasa != NULL ) { - metadata->azimuth = hIsmMeta->edited_azimuth; - metadata->elevation = hIsmMeta->edited_elevation; - metadata->radius = hIsmMeta->edited_radius; - - metadata->yaw = hIsmMeta->edited_yaw; - metadata->pitch = hIsmMeta->edited_pitch; - metadata->spread = 0.f; - - metadata->gainFactor = hIsmMeta->edited_gain; - metadata->non_diegetic_flag = hIsmMeta->non_diegetic_flag; + if ( hIvasDec->st_ivas->hMasa->config.input_ivas_format == MASA_ISM_FORMAT ) + { + is_masa_ism = 1; + } } - else if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + if ( st_ivas->ivas_format != ISM_FORMAT && st_ivas->ivas_format != MASA_ISM_FORMAT && st_ivas->ivas_format != SBA_ISM_FORMAT && is_masa_ism == 0 ) { - metadata->azimuth = st_ivas->hParamIsmDec->edited_azimuth_values[objectIdx]; - metadata->elevation = st_ivas->hParamIsmDec->edited_elevation_values[objectIdx]; - metadata->radius = hIsmMeta->radius; - metadata->yaw = hIsmMeta->yaw; - metadata->pitch = hIsmMeta->pitch; - metadata->spread = 0.f; - metadata->gainFactor = 1.f; - metadata->non_diegetic_flag = hIsmMeta->non_diegetic_flag; + return IVAS_ERR_WRONG_MODE; } - else if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + + if ( objectIdx >= st_ivas->nchan_ism ) { - metadata->azimuth = st_ivas->hIsmMetaData[objectIdx]->edited_azimuth; - metadata->elevation = st_ivas->hIsmMetaData[objectIdx]->edited_elevation; - metadata->radius = st_ivas->hIsmMetaData[objectIdx]->edited_radius; - metadata->yaw = st_ivas->hIsmMetaData[objectIdx]->edited_yaw; - metadata->pitch = st_ivas->hIsmMetaData[objectIdx]->edited_pitch; - metadata->spread = 0.f; - metadata->gainFactor = st_ivas->hIsmMetaData[objectIdx]->edited_gain; - metadata->non_diegetic_flag = st_ivas->hIsmMetaData[objectIdx]->non_diegetic_flag; + return IVAS_ERR_INVALID_INDEX; } - else + + hIsmMeta = st_ivas->hIsmMetaData[objectIdx]; + + if ( hIsmMeta == NULL || zero_flag || ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) ) { - metadata->azimuth = hIsmMeta->azimuth; - metadata->elevation = hIsmMeta->elevation; - metadata->radius = hIsmMeta->radius; - metadata->yaw = hIsmMeta->yaw; - metadata->pitch = hIsmMeta->pitch; + metadata->azimuth = 0.f; + metadata->elevation = 0.f; + metadata->radius = 1.f; metadata->spread = 0.f; metadata->gainFactor = 1.f; - metadata->non_diegetic_flag = hIsmMeta->non_diegetic_flag; + metadata->yaw = 0.f; + metadata->pitch = 0.f; + metadata->non_diegetic_flag = 0; } - } - - return IVAS_ERR_OK; -} - + else + { + if ( st_ivas->ism_mode == ISM_MODE_DISC ) + { + metadata->azimuth = hIsmMeta->edited_azimuth; + metadata->elevation = hIsmMeta->edited_elevation; + metadata->radius = hIsmMeta->edited_radius; -/*---------------------------------------------------------------------* - * IVAS_DEC_GetMasaMetadata( ) - * - * Get metadata of the most recently decoded MASA frame - *---------------------------------------------------------------------*/ + metadata->yaw = hIsmMeta->edited_yaw; + metadata->pitch = hIsmMeta->edited_pitch; + metadata->spread = 0.f; -ivas_error IVAS_DEC_GetMasaMetadata( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - MASA_DECODER_EXT_OUT_META_HANDLE *hMasaExtOutMeta, /* o : pointer to handle, which will be set to point to metadata from the most recently decoded frame */ - const uint8_t getFromJbmBuffer /* i : get metadata from a JBM buffer */ -) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + metadata->gainFactor = hIsmMeta->edited_gain; + metadata->non_diegetic_flag = hIsmMeta->non_diegetic_flag; + } + else if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { + metadata->azimuth = st_ivas->hParamIsmDec->edited_azimuth_values[objectIdx]; + metadata->elevation = st_ivas->hParamIsmDec->edited_elevation_values[objectIdx]; + metadata->radius = hIsmMeta->radius; + metadata->yaw = hIsmMeta->yaw; + metadata->pitch = hIsmMeta->pitch; + metadata->spread = 0.f; + metadata->gainFactor = 1.f; + metadata->non_diegetic_flag = hIsmMeta->non_diegetic_flag; + } + else if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + { + metadata->azimuth = st_ivas->hIsmMetaData[objectIdx]->edited_azimuth; + metadata->elevation = st_ivas->hIsmMetaData[objectIdx]->edited_elevation; + metadata->radius = st_ivas->hIsmMetaData[objectIdx]->edited_radius; + metadata->yaw = st_ivas->hIsmMetaData[objectIdx]->edited_yaw; + metadata->pitch = st_ivas->hIsmMetaData[objectIdx]->edited_pitch; + metadata->spread = 0.f; + metadata->gainFactor = st_ivas->hIsmMetaData[objectIdx]->edited_gain; + metadata->non_diegetic_flag = st_ivas->hIsmMetaData[objectIdx]->non_diegetic_flag; + } + else + { + metadata->azimuth = hIsmMeta->azimuth; + metadata->elevation = hIsmMeta->elevation; + metadata->radius = hIsmMeta->radius; + metadata->yaw = hIsmMeta->yaw; + metadata->pitch = hIsmMeta->pitch; + metadata->spread = 0.f; + metadata->gainFactor = 1.f; + metadata->non_diegetic_flag = hIsmMeta->non_diegetic_flag; + } + } - if ( hIvasDec->st_ivas->ivas_format != MASA_FORMAT && hIvasDec->st_ivas->ivas_format != MASA_ISM_FORMAT ) - { - return IVAS_ERR_WRONG_MODE; + return IVAS_ERR_OK; } - if ( getFromJbmBuffer ) - { - ivas_jbm_masa_sf_to_sf_map( hIvasDec->st_ivas ); - } - *hMasaExtOutMeta = hIvasDec->st_ivas->hMasa->data.extOutMeta; + /*---------------------------------------------------------------------* + * IVAS_DEC_GetMasaMetadata( ) + * + * Get metadata of the most recently decoded MASA frame + *---------------------------------------------------------------------*/ - return IVAS_ERR_OK; -} + ivas_error IVAS_DEC_GetMasaMetadata( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + MASA_DECODER_EXT_OUT_META_HANDLE * hMasaExtOutMeta, /* o : pointer to handle, which will be set to point to metadata from the most recently decoded frame */ + const uint8_t getFromJbmBuffer /* i : get metadata from a JBM buffer */ + ) + { + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + if ( hIvasDec->st_ivas->ivas_format != MASA_FORMAT && hIvasDec->st_ivas->ivas_format != MASA_ISM_FORMAT ) + { + return IVAS_ERR_WRONG_MODE; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_FeedHeadTrackData( ) - * - * Feed the decoder with the head tracking data - *---------------------------------------------------------------------*/ + if ( getFromJbmBuffer ) + { + ivas_jbm_masa_sf_to_sf_map( hIvasDec->st_ivas ); + } -ivas_error IVAS_DEC_FeedHeadTrackData( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_QUATERNION orientation, /* i : head-tracking data, listener orientation */ - IVAS_VECTOR3 Pos, /* i : listener position */ - const int16_t subframe_idx, /* i : subframe index */ - const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ -) -{ - HEAD_TRACK_DATA_HANDLE hHeadTrackData; - ivas_error error; + *hMasaExtOutMeta = hIvasDec->st_ivas->hMasa->data.extOutMeta; - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + return IVAS_ERR_OK; } - hHeadTrackData = hIvasDec->st_ivas->hHeadTrackData; - if ( hHeadTrackData == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + /*---------------------------------------------------------------------* + * IVAS_DEC_FeedHeadTrackData( ) + * + * Feed the decoder with the head tracking data + *---------------------------------------------------------------------*/ - /* Move head-tracking data to the decoder handle */ - /* check for Euler angle signaling */ - if ( orientation.w == -3.0f ) + ivas_error IVAS_DEC_FeedHeadTrackData( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_QUATERNION orientation, /* i : head-tracking data, listener orientation */ + IVAS_VECTOR3 Pos, /* i : listener position */ + const int16_t subframe_idx, /* i : subframe index */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ + ) { - Euler2Quat( deg2rad( orientation.x ), deg2rad( orientation.y ), deg2rad( orientation.z ), &orientation ); - } + HEAD_TRACK_DATA_HANDLE hHeadTrackData; + ivas_error error; - if ( ( error = ivas_orient_trk_Process( hHeadTrackData->OrientationTracker, orientation, FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES, &hHeadTrackData->Quaternions[subframe_idx] ) ) != IVAS_ERR_OK ) - { - return error; - } + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - hHeadTrackData->Pos[subframe_idx].x = Pos.x; - hHeadTrackData->Pos[subframe_idx].y = Pos.y; - hHeadTrackData->Pos[subframe_idx].z = Pos.z; + hHeadTrackData = hIvasDec->st_ivas->hHeadTrackData; - hHeadTrackData->sr_pose_pred_axis = rot_axis; - hIvasDec->updateOrientation = true; + if ( hHeadTrackData == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - return IVAS_ERR_OK; -} + /* Move head-tracking data to the decoder handle */ + /* check for Euler angle signaling */ + if ( orientation.w == -3.0f ) + { + Euler2Quat( deg2rad( orientation.x ), deg2rad( orientation.y ), deg2rad( orientation.z ), &orientation ); + } + if ( ( error = ivas_orient_trk_Process( hHeadTrackData->OrientationTracker, orientation, FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES, &hHeadTrackData->Quaternions[subframe_idx] ) ) != IVAS_ERR_OK ) + { + return error; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_FeedRefRotData( ) - * - * Feed the decoder with the reference rotation data - *---------------------------------------------------------------------*/ + hHeadTrackData->Pos[subframe_idx].x = Pos.x; + hHeadTrackData->Pos[subframe_idx].y = Pos.y; + hHeadTrackData->Pos[subframe_idx].z = Pos.z; -ivas_error IVAS_DEC_FeedRefRotData( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_QUATERNION rotation /* i : reference rotation data */ -) -{ - ivas_orient_trk_state_t *pOtr; + hHeadTrackData->sr_pose_pred_axis = rot_axis; + hIvasDec->updateOrientation = true; - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHeadTrackData == NULL || hIvasDec->st_ivas->hHeadTrackData->OrientationTracker == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + return IVAS_ERR_OK; } - pOtr = hIvasDec->st_ivas->hHeadTrackData->OrientationTracker; - pOtr->refRot.w = rotation.w; - pOtr->refRot.x = rotation.x; - pOtr->refRot.z = rotation.z; - pOtr->refRot.y = rotation.y; + /*---------------------------------------------------------------------* + * IVAS_DEC_FeedRefRotData( ) + * + * Feed the decoder with the reference rotation data + *---------------------------------------------------------------------*/ - hIvasDec->updateOrientation = true; + ivas_error IVAS_DEC_FeedRefRotData( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_QUATERNION rotation /* i : reference rotation data */ + ) + { + ivas_orient_trk_state_t *pOtr; - return IVAS_ERR_OK; -} + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHeadTrackData == NULL || hIvasDec->st_ivas->hHeadTrackData->OrientationTracker == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + pOtr = hIvasDec->st_ivas->hHeadTrackData->OrientationTracker; -/*---------------------------------------------------------------------* - * IVAS_DEC_FeedRefVectorData( ) - * - * Feed the decoder with a reference vector spanning from listenerPos - * to refPos. Only available in OTR_TRACKING_REF_POS and - * OTR_TRACKING_REF_POS_LEV modes. - *---------------------------------------------------------------------*/ + pOtr->refRot.w = rotation.w; + pOtr->refRot.x = rotation.x; + pOtr->refRot.z = rotation.z; + pOtr->refRot.y = rotation.y; -ivas_error IVAS_DEC_FeedRefVectorData( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const IVAS_VECTOR3 listenerPos, /* i : Listener position */ - const IVAS_VECTOR3 refPos /* i : Reference position */ -) -{ - ivas_orient_trk_state_t *pOtr; + hIvasDec->updateOrientation = true; - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHeadTrackData == NULL || hIvasDec->st_ivas->hHeadTrackData->OrientationTracker == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + return IVAS_ERR_OK; } - pOtr = hIvasDec->st_ivas->hHeadTrackData->OrientationTracker; - hIvasDec->updateOrientation = true; + /*---------------------------------------------------------------------* + * IVAS_DEC_FeedRefVectorData( ) + * + * Feed the decoder with a reference vector spanning from listenerPos + * to refPos. Only available in OTR_TRACKING_REF_POS and + * OTR_TRACKING_REF_POS_LEV modes. + *---------------------------------------------------------------------*/ - return ivas_orient_trk_SetReferenceVector( pOtr, listenerPos, refPos ); -} + ivas_error IVAS_DEC_FeedRefVectorData( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_VECTOR3 listenerPos, /* i : Listener position */ + const IVAS_VECTOR3 refPos /* i : Reference position */ + ) + { + ivas_orient_trk_state_t *pOtr; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHeadTrackData == NULL || hIvasDec->st_ivas->hHeadTrackData->OrientationTracker == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_FeedExternalOrientationData( ) - * - * Feed the decoder with the external orientation data - *---------------------------------------------------------------------*/ + pOtr = hIvasDec->st_ivas->hHeadTrackData->OrientationTracker; -ivas_error IVAS_DEC_FeedExternalOrientationData( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_QUATERNION orientation, /* i : external orientation data */ - int8_t enableHeadRotation, /* i : flag to enable head rotation for this frame */ - int8_t enableExternalOrientation, /* i : flag to enable external orientation for this frame */ - int8_t enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ - int16_t numFramesToTargetOrientation, /* i : number of frames until target orientation is reached */ - const int16_t subframe_idx /* i : subframe index */ -) -{ - EXTERNAL_ORIENTATION_HANDLE hExternalOrientationData; + hIvasDec->updateOrientation = true; - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + return ivas_orient_trk_SetReferenceVector( pOtr, listenerPos, refPos ); } - hExternalOrientationData = hIvasDec->st_ivas->hExtOrientationData; - if ( hExternalOrientationData == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + /*---------------------------------------------------------------------* + * IVAS_DEC_FeedExternalOrientationData( ) + * + * Feed the decoder with the external orientation data + *---------------------------------------------------------------------*/ - /* Move external orientation data to the decoder handle (invert orientations) */ - QuaternionInverse( orientation, &hExternalOrientationData->Quaternions[subframe_idx] ); + ivas_error IVAS_DEC_FeedExternalOrientationData( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_QUATERNION orientation, /* i : external orientation data */ + int8_t enableHeadRotation, /* i : flag to enable head rotation for this frame */ + int8_t enableExternalOrientation, /* i : flag to enable external orientation for this frame */ + int8_t enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ + int16_t numFramesToTargetOrientation, /* i : number of frames until target orientation is reached */ + const int16_t subframe_idx /* i : subframe index */ + ) + { + EXTERNAL_ORIENTATION_HANDLE hExternalOrientationData; - hExternalOrientationData->enableHeadRotation[subframe_idx] = enableHeadRotation; - hExternalOrientationData->enableExternalOrientation[subframe_idx] = enableExternalOrientation; - hExternalOrientationData->enableRotationInterpolation[subframe_idx] = enableRotationInterpolation; - hExternalOrientationData->numFramesToTargetOrientation[subframe_idx] = numFramesToTargetOrientation; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - hIvasDec->updateOrientation = true; + hExternalOrientationData = hIvasDec->st_ivas->hExtOrientationData; - return IVAS_ERR_OK; -} + if ( hExternalOrientationData == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + /* Move external orientation data to the decoder handle (invert orientations) */ + QuaternionInverse( orientation, &hExternalOrientationData->Quaternions[subframe_idx] ); -/*---------------------------------------------------------------------* - * IVAS_DEC_FeedCustomLsData( ) - * - * Feed the decoder with the Custom loudspeaker data - *---------------------------------------------------------------------*/ + hExternalOrientationData->enableHeadRotation[subframe_idx] = enableHeadRotation; + hExternalOrientationData->enableExternalOrientation[subframe_idx] = enableExternalOrientation; + hExternalOrientationData->enableRotationInterpolation[subframe_idx] = enableRotationInterpolation; + hExternalOrientationData->numFramesToTargetOrientation[subframe_idx] = numFramesToTargetOrientation; -/*! r: error code */ -ivas_error IVAS_DEC_FeedCustomLsData( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const IVAS_CUSTOM_LS_DATA hLsCustomData /* i : Custom loudspeaker setup data */ -) -{ - int16_t i, is_planar; - IVAS_LSSETUP_CUSTOM_HANDLE hLsSetupCustom; + hIvasDec->updateOrientation = true; - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + return IVAS_ERR_OK; } - hLsSetupCustom = hIvasDec->st_ivas->hLsSetupCustom; - if ( hLsSetupCustom == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + /*---------------------------------------------------------------------* + * IVAS_DEC_FeedCustomLsData( ) + * + * Feed the decoder with the Custom loudspeaker data + *---------------------------------------------------------------------*/ - /* Move Custom LS layout data to the decoder handle */ + /*! r: error code */ + ivas_error IVAS_DEC_FeedCustomLsData( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_CUSTOM_LS_DATA hLsCustomData /* i : Custom loudspeaker setup data */ + ) + { + int16_t i, is_planar; + IVAS_LSSETUP_CUSTOM_HANDLE hLsSetupCustom; - /* Loudspeaker azimuths and elevations */ - hLsSetupCustom->num_spk = hLsCustomData.num_spk; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - mvr2r( hLsCustomData.azimuth, hLsSetupCustom->ls_azimuth, hLsCustomData.num_spk ); - mvr2r( hLsCustomData.elevation, hLsSetupCustom->ls_elevation, hLsCustomData.num_spk ); + hLsSetupCustom = hIvasDec->st_ivas->hLsSetupCustom; - /* Set planar flag */ - is_planar = 1; - for ( i = 0; i < hLsCustomData.num_spk; i++ ) - { - if ( is_planar && hLsSetupCustom->ls_elevation[i] != 0.0f ) + if ( hLsSetupCustom == NULL ) { - is_planar = 0; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - } - hLsSetupCustom->is_planar_setup = is_planar; - /* Loudspeaker LFE */ - hLsSetupCustom->num_lfe = hLsCustomData.num_lfe; - mvs2s( hLsCustomData.lfe_idx, hLsSetupCustom->lfe_idx, hLsCustomData.num_lfe ); + /* Move Custom LS layout data to the decoder handle */ - return IVAS_ERR_OK; -} + /* Loudspeaker azimuths and elevations */ + hLsSetupCustom->num_spk = hLsCustomData.num_spk; + mvr2r( hLsCustomData.azimuth, hLsSetupCustom->ls_azimuth, hLsCustomData.num_spk ); + mvr2r( hLsCustomData.elevation, hLsSetupCustom->ls_elevation, hLsCustomData.num_spk ); -/*---------------------------------------------------------------------* - * IVAS_DEC_GetHrtfTDrendHandle( ) - * - * Get TD binaural renderer handle - *---------------------------------------------------------------------*/ + /* Set planar flag */ + is_planar = 1; + for ( i = 0; i < hLsCustomData.num_spk; i++ ) + { + if ( is_planar && hLsSetupCustom->ls_elevation[i] != 0.0f ) + { + is_planar = 0; + } + } + hLsSetupCustom->is_planar_setup = is_planar; -ivas_error IVAS_DEC_GetHrtfTDrendHandle( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_DEC_HRTF_TD_HANDLE **hHrtfTD /* o : HRTF handle */ -) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHrtfTD == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + /* Loudspeaker LFE */ + hLsSetupCustom->num_lfe = hLsCustomData.num_lfe; + mvs2s( hLsCustomData.lfe_idx, hLsSetupCustom->lfe_idx, hLsCustomData.num_lfe ); + + return IVAS_ERR_OK; } - *hHrtfTD = &hIvasDec->st_ivas->hHrtfTD; - return IVAS_ERR_OK; -} + /*---------------------------------------------------------------------* + * IVAS_DEC_GetHrtfTDrendHandle( ) + * + * Get TD binaural renderer handle + *---------------------------------------------------------------------*/ + ivas_error IVAS_DEC_GetHrtfTDrendHandle( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_DEC_HRTF_TD_HANDLE * *hHrtfTD /* o : HRTF handle */ + ) + { + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHrtfTD == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_GetHrtfCRendHandle( ) - * - * Get Crend binaural renderer handle - *---------------------------------------------------------------------*/ + *hHrtfTD = &hIvasDec->st_ivas->hHrtfTD; -ivas_error IVAS_DEC_GetHrtfCRendHandle( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_DEC_HRTF_CREND_HANDLE **hHrtfCrend /* o : Crend HRTF handle */ -) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHrtfCrend == NULL ) - { - return IVAS_ERR_WRONG_PARAMS; + return IVAS_ERR_OK; } - *hHrtfCrend = &hIvasDec->st_ivas->hHrtfCrend; - return IVAS_ERR_OK; -} + /*---------------------------------------------------------------------* + * IVAS_DEC_GetHrtfCRendHandle( ) + * + * Get Crend binaural renderer handle + *---------------------------------------------------------------------*/ + ivas_error IVAS_DEC_GetHrtfCRendHandle( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_DEC_HRTF_CREND_HANDLE * *hHrtfCrend /* o : Crend HRTF handle */ + ) + { + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHrtfCrend == NULL ) + { + return IVAS_ERR_WRONG_PARAMS; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_GetHrtfFastConvHandle( ) - * - * Get FastConv binaural renderer handle - *---------------------------------------------------------------------*/ + *hHrtfCrend = &hIvasDec->st_ivas->hHrtfCrend; -ivas_error IVAS_DEC_GetHrtfFastConvHandle( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_DEC_HRTF_FASTCONV_HANDLE **hHrtfFastConv /* o : FASTCONV HRTF handle */ -) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHrtfFastConv == NULL ) - { - return IVAS_ERR_WRONG_PARAMS; + return IVAS_ERR_OK; } - *hHrtfFastConv = &hIvasDec->st_ivas->hHrtfFastConv; - return IVAS_ERR_OK; -} + /*---------------------------------------------------------------------* + * IVAS_DEC_GetHrtfFastConvHandle( ) + * + * Get FastConv binaural renderer handle + *---------------------------------------------------------------------*/ + ivas_error IVAS_DEC_GetHrtfFastConvHandle( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_DEC_HRTF_FASTCONV_HANDLE * *hHrtfFastConv /* o : FASTCONV HRTF handle */ + ) + { + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHrtfFastConv == NULL ) + { + return IVAS_ERR_WRONG_PARAMS; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_GetHrtfParamBinHandle( ) - * - * Get Parametric binaural renderer handle - *---------------------------------------------------------------------*/ + *hHrtfFastConv = &hIvasDec->st_ivas->hHrtfFastConv; -ivas_error IVAS_DEC_GetHrtfParamBinHandle( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_DEC_HRTF_PARAMBIN_HANDLE **hHrtfParambin /* o : Parametric binauralizer HRTF handle */ -) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHrtfParambin == NULL ) - { - return IVAS_ERR_WRONG_PARAMS; + return IVAS_ERR_OK; } - *hHrtfParambin = &hIvasDec->st_ivas->hHrtfParambin; - return IVAS_ERR_OK; -} + /*---------------------------------------------------------------------* + * IVAS_DEC_GetHrtfParamBinHandle( ) + * + * Get Parametric binaural renderer handle + *---------------------------------------------------------------------*/ -/*---------------------------------------------------------------------* - * IVAS_DEC_GetHrtfStatisticsHandle( ) - * - * Get HRTF statistics (room effect) binaural renderer handle - *---------------------------------------------------------------------*/ - -ivas_error IVAS_DEC_GetHrtfStatisticsHandle( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_DEC_HRTF_STATISTICS_HANDLE **hHrtfStatistics /* o : HRTF statistics handle */ -) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHrtfStatistics == NULL ) + ivas_error IVAS_DEC_GetHrtfParamBinHandle( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_DEC_HRTF_PARAMBIN_HANDLE * *hHrtfParambin /* o : Parametric binauralizer HRTF handle */ + ) { - return IVAS_ERR_WRONG_PARAMS; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHrtfParambin == NULL ) + { + return IVAS_ERR_WRONG_PARAMS; + } + + *hHrtfParambin = &hIvasDec->st_ivas->hHrtfParambin; + + return IVAS_ERR_OK; } - *hHrtfStatistics = &hIvasDec->st_ivas->hHrtfStatistics; + /*---------------------------------------------------------------------* + * IVAS_DEC_GetHrtfStatisticsHandle( ) + * + * Get HRTF statistics (room effect) binaural renderer handle + *---------------------------------------------------------------------*/ - return IVAS_ERR_OK; -} + ivas_error IVAS_DEC_GetHrtfStatisticsHandle( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_DEC_HRTF_STATISTICS_HANDLE * *hHrtfStatistics /* o : HRTF statistics handle */ + ) + { + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHrtfStatistics == NULL ) + { + return IVAS_ERR_WRONG_PARAMS; + } + *hHrtfStatistics = &hIvasDec->st_ivas->hHrtfStatistics; -/*---------------------------------------------------------------------* - * IVAS_DEC_HRTF_binary_open( ) - * - * Allocate HRTF binary handles - *---------------------------------------------------------------------*/ + return IVAS_ERR_OK; + } -ivas_error IVAS_DEC_HRTF_binary_open( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const IVAS_BIN_RENDERER_TYPE binaural_renderer /* i : binaural renderer type */ -) -{ - ivas_error error; - Decoder_Struct *st_ivas; - st_ivas = hIvasDec->st_ivas; + /*---------------------------------------------------------------------* + * IVAS_DEC_HRTF_binary_open( ) + * + * Allocate HRTF binary handles + *---------------------------------------------------------------------*/ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + ivas_error IVAS_DEC_HRTF_binary_open( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_BIN_RENDERER_TYPE binaural_renderer /* i : binaural renderer type */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + ivas_error error; + Decoder_Struct *st_ivas; - if ( st_ivas->hDecoderConfig->Opt_HRTF_binary ) - { - /* TD binaural renderer */ - if ( ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_TDREND || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && st_ivas->hHrtfTD == NULL ) + st_ivas = hIvasDec->st_ivas; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - if ( ( error = ivas_HRTF_td_binary_open( &( st_ivas->hHrtfTD ) ) ) != IVAS_ERR_OK ) - { - return error; - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - /* Crend binaural renderer */ - if ( ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_CREND || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && st_ivas->hHrtfCrend == NULL ) + if ( st_ivas->hDecoderConfig->Opt_HRTF_binary ) { - if ( ( error = ivas_HRTF_CRend_binary_open( &( st_ivas->hHrtfCrend ) ) ) != IVAS_ERR_OK ) + /* TD binaural renderer */ + if ( ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_TDREND || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && st_ivas->hHrtfTD == NULL ) { - return error; + if ( ( error = ivas_HRTF_td_binary_open( &( st_ivas->hHrtfTD ) ) ) != IVAS_ERR_OK ) + { + return error; + } } - } - /* FastConv binaural renderer */ - if ( ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_FASTCONV || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && st_ivas->hHrtfFastConv == NULL ) - { - if ( ( error = ivas_HRTF_fastconv_binary_open( &st_ivas->hHrtfFastConv ) ) != IVAS_ERR_OK ) + /* Crend binaural renderer */ + if ( ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_CREND || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && st_ivas->hHrtfCrend == NULL ) { - return error; + if ( ( error = ivas_HRTF_CRend_binary_open( &( st_ivas->hHrtfCrend ) ) ) != IVAS_ERR_OK ) + { + return error; + } } - } - /* Parametric binaural renderer */ - if ( ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_PARAMBIN || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && st_ivas->hHrtfParambin == NULL ) - { - if ( ( error = ivas_HRTF_parambin_binary_open( &st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK ) + /* FastConv binaural renderer */ + if ( ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_FASTCONV || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && st_ivas->hHrtfFastConv == NULL ) { - return error; + if ( ( error = ivas_HRTF_fastconv_binary_open( &st_ivas->hHrtfFastConv ) ) != IVAS_ERR_OK ) + { + return error; + } } - } - if ( st_ivas->hHrtfStatistics == NULL && ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_FASTCONV || binaural_renderer == IVAS_BIN_RENDERER_TYPE_CREND ) && st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) - { - if ( ( error = ivas_HRTF_statistics_binary_open( &st_ivas->hHrtfStatistics ) ) != IVAS_ERR_OK ) + /* Parametric binaural renderer */ + if ( ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_PARAMBIN || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && st_ivas->hHrtfParambin == NULL ) { - return error; + if ( ( error = ivas_HRTF_parambin_binary_open( &st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK ) + { + return error; + } } - } - } - - return IVAS_ERR_OK; -} - - -/*---------------------------------------------------------------------* - * IVAS_DEC_HRTF_binary_close( ) - * - * Deallocate HRTF binary handles - *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_HRTF_binary_close( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const IVAS_BIN_RENDERER_TYPE binaural_renderer_old /* i : previous binaural renderer type */ -) -{ - Decoder_Struct *st_ivas; + if ( st_ivas->hHrtfStatistics == NULL && ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_FASTCONV || binaural_renderer == IVAS_BIN_RENDERER_TYPE_CREND ) && st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) + { + if ( ( error = ivas_HRTF_statistics_binary_open( &st_ivas->hHrtfStatistics ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + return IVAS_ERR_OK; } - st_ivas = hIvasDec->st_ivas; - if ( st_ivas->hDecoderConfig->Opt_HRTF_binary && st_ivas->ini_frame > 0 ) + /*---------------------------------------------------------------------* + * IVAS_DEC_HRTF_binary_close( ) + * + * Deallocate HRTF binary handles + *---------------------------------------------------------------------*/ + + ivas_error IVAS_DEC_HRTF_binary_close( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_BIN_RENDERER_TYPE binaural_renderer_old /* i : previous binaural renderer type */ + ) { - if ( !( binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_TDREND || binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_DEFAULT ) ) - { - ivas_HRTF_td_binary_close( &st_ivas->hHrtfTD ); - } + Decoder_Struct *st_ivas; - if ( !( binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_CREND || binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_DEFAULT ) ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - /* CRend binaural renderer handle */ - ivas_HRTF_CRend_binary_close( &st_ivas->hHrtfCrend ); + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - if ( !( binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_FASTCONV || binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_DEFAULT ) ) - { - /* Fastconv HRTF filters */ - ivas_HRTF_fastconv_binary_close( &st_ivas->hHrtfFastConv ); - } + st_ivas = hIvasDec->st_ivas; - if ( !( binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_PARAMBIN || binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_DEFAULT ) ) + if ( st_ivas->hDecoderConfig->Opt_HRTF_binary && st_ivas->ini_frame > 0 ) { + if ( !( binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_TDREND || binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_DEFAULT ) ) + { + ivas_HRTF_td_binary_close( &st_ivas->hHrtfTD ); + } - /* Parametric binauralizer HRTF filters */ - ivas_HRTF_parambin_binary_close( &st_ivas->hHrtfParambin ); - } - } - - return IVAS_ERR_OK; -} + if ( !( binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_CREND || binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_DEFAULT ) ) + { + /* CRend binaural renderer handle */ + ivas_HRTF_CRend_binary_close( &st_ivas->hHrtfCrend ); + } + if ( !( binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_FASTCONV || binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_DEFAULT ) ) + { + /* Fastconv HRTF filters */ + ivas_HRTF_fastconv_binary_close( &st_ivas->hHrtfFastConv ); + } -/*---------------------------------------------------------------------* - * IVAS_DEC_AddAcousticEnvironment( ) - * - * Adds acoustic environment configuration - *---------------------------------------------------------------------*/ + if ( !( binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_PARAMBIN || binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_DEFAULT ) ) + { -ivas_error IVAS_DEC_AddAcousticEnvironment( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const IVAS_ROOM_ACOUSTICS_CONFIG_DATA roomAcousticsConfig /* i : Room acoustic configuration */ -) -{ - uint16_t n; - Decoder_Struct *st_ivas; - IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pAE = NULL; + /* Parametric binauralizer HRTF filters */ + ivas_HRTF_parambin_binary_close( &st_ivas->hHrtfParambin ); + } + } - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || ( hIvasDec->st_ivas->acousticEnvironmentsCount > 0 && hIvasDec->st_ivas->pAcousticEnvironments == NULL ) ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + return IVAS_ERR_OK; } - st_ivas = hIvasDec->st_ivas; - /* Check if already there */ - for ( n = 0; n < st_ivas->acousticEnvironmentsCount; n++ ) - { - if ( st_ivas->pAcousticEnvironments[n].aeID == roomAcousticsConfig.aeID ) - { - pAE = &st_ivas->pAcousticEnvironments[n]; - break; - } - } + /*---------------------------------------------------------------------* + * IVAS_DEC_AddAcousticEnvironment( ) + * + * Adds acoustic environment configuration + *---------------------------------------------------------------------*/ - /* If not found */ - if ( pAE == NULL ) + ivas_error IVAS_DEC_AddAcousticEnvironment( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_ROOM_ACOUSTICS_CONFIG_DATA roomAcousticsConfig /* i : Room acoustic configuration */ + ) { - IVAS_ROOM_ACOUSTICS_CONFIG_DATA *ppAE = malloc( ( st_ivas->acousticEnvironmentsCount + 1 ) * sizeof( IVAS_ROOM_ACOUSTICS_CONFIG_DATA ) ); + uint16_t n; + Decoder_Struct *st_ivas; + IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pAE = NULL; - if ( ppAE == NULL ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || ( hIvasDec->st_ivas->acousticEnvironmentsCount > 0 && hIvasDec->st_ivas->pAcousticEnvironments == NULL ) ) { - return IVAS_ERR_FAILED_ALLOC; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + st_ivas = hIvasDec->st_ivas; + + /* Check if already there */ for ( n = 0; n < st_ivas->acousticEnvironmentsCount; n++ ) { - pAE = &ppAE[n]; - pAE->aeID = st_ivas->pAcousticEnvironments[n].aeID; - pAE->nBands = st_ivas->pAcousticEnvironments[n].nBands; - pAE->acousticPreDelay = st_ivas->pAcousticEnvironments[n].acousticPreDelay; - pAE->inputPreDelay = st_ivas->pAcousticEnvironments[n].inputPreDelay; + if ( st_ivas->pAcousticEnvironments[n].aeID == roomAcousticsConfig.aeID ) + { + pAE = &st_ivas->pAcousticEnvironments[n]; + break; + } + } - mvr2r( st_ivas->pAcousticEnvironments[n].pFc_input, pAE->pFc_input, CLDFB_NO_CHANNELS_MAX ); - mvr2r( st_ivas->pAcousticEnvironments[n].pAcoustic_rt60, pAE->pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); - mvr2r( st_ivas->pAcousticEnvironments[n].pAcoustic_dsr, pAE->pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); + /* If not found */ + if ( pAE == NULL ) + { + IVAS_ROOM_ACOUSTICS_CONFIG_DATA *ppAE = malloc( ( st_ivas->acousticEnvironmentsCount + 1 ) * sizeof( IVAS_ROOM_ACOUSTICS_CONFIG_DATA ) ); - pAE->use_er = st_ivas->pAcousticEnvironments[n].use_er; + if ( ppAE == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } - if ( pAE->use_er == 1 ) + for ( n = 0; n < st_ivas->acousticEnvironmentsCount; n++ ) { - pAE->lowComplexity = st_ivas->pAcousticEnvironments[n].lowComplexity; - pAE->dimensions.x = st_ivas->pAcousticEnvironments[n].dimensions.x; - pAE->dimensions.y = st_ivas->pAcousticEnvironments[n].dimensions.y; - pAE->dimensions.z = st_ivas->pAcousticEnvironments[n].dimensions.z; - pAE->ListenerOrigin.x = st_ivas->pAcousticEnvironments[n].ListenerOrigin.x; - pAE->ListenerOrigin.y = st_ivas->pAcousticEnvironments[n].ListenerOrigin.y; - pAE->ListenerOrigin.z = st_ivas->pAcousticEnvironments[n].ListenerOrigin.z; + pAE = &ppAE[n]; + pAE->aeID = st_ivas->pAcousticEnvironments[n].aeID; + pAE->nBands = st_ivas->pAcousticEnvironments[n].nBands; + pAE->acousticPreDelay = st_ivas->pAcousticEnvironments[n].acousticPreDelay; + pAE->inputPreDelay = st_ivas->pAcousticEnvironments[n].inputPreDelay; + + mvr2r( st_ivas->pAcousticEnvironments[n].pFc_input, pAE->pFc_input, CLDFB_NO_CHANNELS_MAX ); + mvr2r( st_ivas->pAcousticEnvironments[n].pAcoustic_rt60, pAE->pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); + mvr2r( st_ivas->pAcousticEnvironments[n].pAcoustic_dsr, pAE->pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); + + pAE->use_er = st_ivas->pAcousticEnvironments[n].use_er; - mvr2r( st_ivas->pAcousticEnvironments[n].AbsCoeff, pAE->AbsCoeff, IVAS_ROOM_ABS_COEFF ); + if ( pAE->use_er == 1 ) + { + pAE->lowComplexity = st_ivas->pAcousticEnvironments[n].lowComplexity; + pAE->dimensions.x = st_ivas->pAcousticEnvironments[n].dimensions.x; + pAE->dimensions.y = st_ivas->pAcousticEnvironments[n].dimensions.y; + pAE->dimensions.z = st_ivas->pAcousticEnvironments[n].dimensions.z; + pAE->ListenerOrigin.x = st_ivas->pAcousticEnvironments[n].ListenerOrigin.x; + pAE->ListenerOrigin.y = st_ivas->pAcousticEnvironments[n].ListenerOrigin.y; + pAE->ListenerOrigin.z = st_ivas->pAcousticEnvironments[n].ListenerOrigin.z; + + mvr2r( st_ivas->pAcousticEnvironments[n].AbsCoeff, pAE->AbsCoeff, IVAS_ROOM_ABS_COEFF ); + } } - } - free( st_ivas->pAcousticEnvironments ); - st_ivas->pAcousticEnvironments = ppAE; - n = st_ivas->acousticEnvironmentsCount++; - pAE = &st_ivas->pAcousticEnvironments[n]; - } + free( st_ivas->pAcousticEnvironments ); + st_ivas->pAcousticEnvironments = ppAE; + n = st_ivas->acousticEnvironmentsCount++; + pAE = &st_ivas->pAcousticEnvironments[n]; + } - pAE->aeID = roomAcousticsConfig.aeID; - pAE->nBands = roomAcousticsConfig.nBands; - pAE->acousticPreDelay = roomAcousticsConfig.acousticPreDelay; - pAE->inputPreDelay = roomAcousticsConfig.inputPreDelay; + pAE->aeID = roomAcousticsConfig.aeID; + pAE->nBands = roomAcousticsConfig.nBands; + pAE->acousticPreDelay = roomAcousticsConfig.acousticPreDelay; + pAE->inputPreDelay = roomAcousticsConfig.inputPreDelay; - mvr2r( roomAcousticsConfig.pFc_input, pAE->pFc_input, CLDFB_NO_CHANNELS_MAX ); - mvr2r( roomAcousticsConfig.pAcoustic_rt60, pAE->pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); - mvr2r( roomAcousticsConfig.pAcoustic_dsr, pAE->pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); + mvr2r( roomAcousticsConfig.pFc_input, pAE->pFc_input, CLDFB_NO_CHANNELS_MAX ); + mvr2r( roomAcousticsConfig.pAcoustic_rt60, pAE->pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); + mvr2r( roomAcousticsConfig.pAcoustic_dsr, pAE->pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); - pAE->use_er = roomAcousticsConfig.use_er; + pAE->use_er = roomAcousticsConfig.use_er; - if ( pAE->use_er == 1 ) - { - pAE->lowComplexity = roomAcousticsConfig.lowComplexity; - pAE->dimensions.x = roomAcousticsConfig.dimensions.x; - pAE->dimensions.y = roomAcousticsConfig.dimensions.y; - pAE->dimensions.z = roomAcousticsConfig.dimensions.z; - pAE->ListenerOrigin.x = roomAcousticsConfig.ListenerOrigin.x; - pAE->ListenerOrigin.y = roomAcousticsConfig.ListenerOrigin.y; - pAE->ListenerOrigin.z = roomAcousticsConfig.ListenerOrigin.z; - - mvr2r( roomAcousticsConfig.AbsCoeff, pAE->AbsCoeff, IVAS_ROOM_ABS_COEFF ); - } + if ( pAE->use_er == 1 ) + { + pAE->lowComplexity = roomAcousticsConfig.lowComplexity; + pAE->dimensions.x = roomAcousticsConfig.dimensions.x; + pAE->dimensions.y = roomAcousticsConfig.dimensions.y; + pAE->dimensions.z = roomAcousticsConfig.dimensions.z; + pAE->ListenerOrigin.x = roomAcousticsConfig.ListenerOrigin.x; + pAE->ListenerOrigin.y = roomAcousticsConfig.ListenerOrigin.y; + pAE->ListenerOrigin.z = roomAcousticsConfig.ListenerOrigin.z; - return IVAS_ERR_OK; -} + mvr2r( roomAcousticsConfig.AbsCoeff, pAE->AbsCoeff, IVAS_ROOM_ABS_COEFF ); + } + return IVAS_ERR_OK; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_GetAcousticEnvironment( ) - * - * Gets acoustic environment configuration with a given ID - *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_GetAcousticEnvironment( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint16_t aeID, /* i : Acoustic environment ID */ - IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pAcEnv /* o : Room acoustic environment data pointer */ -) -{ - uint16_t n, m; - uint16_t found = 0; - Decoder_Struct *st_ivas; + /*---------------------------------------------------------------------* + * IVAS_DEC_GetAcousticEnvironment( ) + * + * Gets acoustic environment configuration with a given ID + *---------------------------------------------------------------------*/ - if ( hIvasDec == NULL || pAcEnv == NULL ) + ivas_error IVAS_DEC_GetAcousticEnvironment( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint16_t aeID, /* i : Acoustic environment ID */ + IVAS_ROOM_ACOUSTICS_CONFIG_DATA * pAcEnv /* o : Room acoustic environment data pointer */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + uint16_t n, m; + uint16_t found = 0; + Decoder_Struct *st_ivas; - st_ivas = hIvasDec->st_ivas; + if ( hIvasDec == NULL || pAcEnv == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - /* In case of default AE ID, select the first one available */ - if ( aeID == IVAS_DEFAULT_AEID && st_ivas->acousticEnvironmentsCount > 0 ) - { - aeID = st_ivas->pAcousticEnvironments[0].aeID; - } + st_ivas = hIvasDec->st_ivas; - for ( n = 0; n < st_ivas->acousticEnvironmentsCount; n++ ) - { - IVAS_ROOM_ACOUSTICS_CONFIG_DATA ae = st_ivas->pAcousticEnvironments[n]; + /* In case of default AE ID, select the first one available */ + if ( aeID == IVAS_DEFAULT_AEID && st_ivas->acousticEnvironmentsCount > 0 ) + { + aeID = st_ivas->pAcousticEnvironments[0].aeID; + } - if ( aeID == ae.aeID ) + for ( n = 0; n < st_ivas->acousticEnvironmentsCount; n++ ) { - found = 1; - pAcEnv->aeID = aeID; - pAcEnv->nBands = ae.nBands; - pAcEnv->inputPreDelay = ae.inputPreDelay; - for ( m = 0; m < pAcEnv->nBands; m++ ) - { - pAcEnv->pFc_input[m] = ae.pFc_input[m]; - pAcEnv->pAcoustic_rt60[m] = ae.pAcoustic_rt60[m]; - pAcEnv->pAcoustic_dsr[m] = ae.pAcoustic_dsr[m]; - } + IVAS_ROOM_ACOUSTICS_CONFIG_DATA ae = st_ivas->pAcousticEnvironments[n]; - /* If ER are allocated then propagate parameters */ - pAcEnv->use_er = ae.use_er; - if ( ae.use_er != 0 ) + if ( aeID == ae.aeID ) { - pAcEnv->lowComplexity = ae.lowComplexity; + found = 1; + pAcEnv->aeID = aeID; + pAcEnv->nBands = ae.nBands; + pAcEnv->inputPreDelay = ae.inputPreDelay; + for ( m = 0; m < pAcEnv->nBands; m++ ) + { + pAcEnv->pFc_input[m] = ae.pFc_input[m]; + pAcEnv->pAcoustic_rt60[m] = ae.pAcoustic_rt60[m]; + pAcEnv->pAcoustic_dsr[m] = ae.pAcoustic_dsr[m]; + } + + /* If ER are allocated then propagate parameters */ + pAcEnv->use_er = ae.use_er; + if ( ae.use_er != 0 ) + { + pAcEnv->lowComplexity = ae.lowComplexity; - pAcEnv->dimensions.x = ae.dimensions.x; - pAcEnv->dimensions.y = ae.dimensions.y; - pAcEnv->dimensions.z = ae.dimensions.z; + pAcEnv->dimensions.x = ae.dimensions.x; + pAcEnv->dimensions.y = ae.dimensions.y; + pAcEnv->dimensions.z = ae.dimensions.z; - pAcEnv->ListenerOrigin.x = ae.ListenerOrigin.x; - pAcEnv->ListenerOrigin.y = ae.ListenerOrigin.y; - pAcEnv->ListenerOrigin.z = ae.ListenerOrigin.z; + pAcEnv->ListenerOrigin.x = ae.ListenerOrigin.x; + pAcEnv->ListenerOrigin.y = ae.ListenerOrigin.y; + pAcEnv->ListenerOrigin.z = ae.ListenerOrigin.z; - for ( m = 0; m < IVAS_ROOM_ABS_COEFF; m++ ) - { - pAcEnv->AbsCoeff[m] = ae.AbsCoeff[m]; + for ( m = 0; m < IVAS_ROOM_ABS_COEFF; m++ ) + { + pAcEnv->AbsCoeff[m] = ae.AbsCoeff[m]; + } } } } - } - return found ? IVAS_ERR_OK : IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING; -} + return found ? IVAS_ERR_OK : IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING; + } -/*---------------------------------------------------------------------* - * copyRendererConfigStruct( ) - * - * - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * copyRendererConfigStruct( ) + * + * + *---------------------------------------------------------------------*/ -static ivas_error copyRendererConfigStruct( - RENDER_CONFIG_HANDLE hRCin, - IVAS_RENDER_CONFIG_HANDLE hRCout ) -{ - if ( hRCin == NULL || hRCout == NULL ) + static ivas_error copyRendererConfigStruct( + RENDER_CONFIG_HANDLE hRCin, + IVAS_RENDER_CONFIG_HANDLE hRCout ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + if ( hRCin == NULL || hRCout == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - hRCout->roomAcoustics.aeID = hRCin->roomAcoustics.aeID; - hRCout->roomAcoustics.nBands = hRCin->roomAcoustics.nBands; - hRCout->roomAcoustics.acousticPreDelay = hRCin->roomAcoustics.acousticPreDelay; - hRCout->roomAcoustics.inputPreDelay = hRCin->roomAcoustics.inputPreDelay; + hRCout->roomAcoustics.aeID = hRCin->roomAcoustics.aeID; + hRCout->roomAcoustics.nBands = hRCin->roomAcoustics.nBands; + hRCout->roomAcoustics.acousticPreDelay = hRCin->roomAcoustics.acousticPreDelay; + hRCout->roomAcoustics.inputPreDelay = hRCin->roomAcoustics.inputPreDelay; - mvr2r( hRCin->roomAcoustics.pFc_input, hRCout->roomAcoustics.pFc_input, CLDFB_NO_CHANNELS_MAX ); - mvr2r( hRCin->roomAcoustics.pAcoustic_rt60, hRCout->roomAcoustics.pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); - mvr2r( hRCin->roomAcoustics.pAcoustic_dsr, hRCout->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); - mvr2r( hRCin->directivity, hRCout->directivity, 3 * MAX_NUM_OBJECTS ); - mvr2r( hRCin->distAtt, hRCout->distAtt, 3 ); + mvr2r( hRCin->roomAcoustics.pFc_input, hRCout->roomAcoustics.pFc_input, CLDFB_NO_CHANNELS_MAX ); + mvr2r( hRCin->roomAcoustics.pAcoustic_rt60, hRCout->roomAcoustics.pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); + mvr2r( hRCin->roomAcoustics.pAcoustic_dsr, hRCout->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); + mvr2r( hRCin->directivity, hRCout->directivity, 3 * MAX_NUM_OBJECTS ); + mvr2r( hRCin->distAtt, hRCout->distAtt, 3 ); - hRCout->split_rend_config = hRCin->split_rend_config; + hRCout->split_rend_config = hRCin->split_rend_config; - hRCout->roomAcoustics.use_er = hRCin->roomAcoustics.use_er; - hRCout->roomAcoustics.lowComplexity = hRCin->roomAcoustics.lowComplexity; + hRCout->roomAcoustics.use_er = hRCin->roomAcoustics.use_er; + hRCout->roomAcoustics.lowComplexity = hRCin->roomAcoustics.lowComplexity; - return IVAS_ERR_OK; -} + return IVAS_ERR_OK; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_GetRenderConfig( ) - * - * Return renderer configuration parameters handle - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * IVAS_DEC_GetRenderConfig( ) + * + * Return renderer configuration parameters handle + *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_GetRenderConfig( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const IVAS_RENDER_CONFIG_HANDLE hRCout /* o : Render configuration handle */ -) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hRenderConfig == NULL || hRCout == NULL ) + ivas_error IVAS_DEC_GetRenderConfig( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_RENDER_CONFIG_HANDLE hRCout /* o : Render configuration handle */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - return copyRendererConfigStruct( hIvasDec->st_ivas->hRenderConfig, hRCout ); -} + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hRenderConfig == NULL || hRCout == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + return copyRendererConfigStruct( hIvasDec->st_ivas->hRenderConfig, hRCout ); + } -/*---------------------------------------------------------------------* - * IVAS_DEC_GetDefaultRenderConfig( ) - * - * Return default renderer configuration parameters - *---------------------------------------------------------------------*/ -/*! r: error code*/ -ivas_error IVAS_DEC_GetDefaultRenderConfig( - IVAS_RENDER_CONFIG_HANDLE hRCout /* o : Render config handle */ -) -{ - RENDER_CONFIG_DATA RCin; - RENDER_CONFIG_HANDLE hRCin = &RCin; - ivas_error error; + /*---------------------------------------------------------------------* + * IVAS_DEC_GetDefaultRenderConfig( ) + * + * Return default renderer configuration parameters + *---------------------------------------------------------------------*/ - if ( ( error = ivas_render_config_init_from_rom( &hRCin ) ) != IVAS_ERR_OK ) + /*! r: error code*/ + ivas_error IVAS_DEC_GetDefaultRenderConfig( + IVAS_RENDER_CONFIG_HANDLE hRCout /* o : Render config handle */ + ) { - return error; - } + RENDER_CONFIG_DATA RCin; + RENDER_CONFIG_HANDLE hRCin = &RCin; + ivas_error error; - return copyRendererConfigStruct( hRCin, hRCout ); -} + if ( ( error = ivas_render_config_init_from_rom( &hRCin ) ) != IVAS_ERR_OK ) + { + return error; + } + return copyRendererConfigStruct( hRCin, hRCout ); + } -/*---------------------------------------------------------------------* - * IVAS_DEC_FeedRenderConfig( ) - * - * Set renderer configuration (acoustic environment) parameters - *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_FeedRenderConfig( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const IVAS_RENDER_CONFIG_DATA renderConfig /* i : Render configuration struct */ -) -{ - RENDER_CONFIG_HANDLE hRenderConfig; - Decoder_Struct *st_ivas; - ivas_error error; + /*---------------------------------------------------------------------* + * IVAS_DEC_FeedRenderConfig( ) + * + * Set renderer configuration (acoustic environment) parameters + *---------------------------------------------------------------------*/ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hRenderConfig == NULL ) + ivas_error IVAS_DEC_FeedRenderConfig( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_RENDER_CONFIG_DATA renderConfig /* i : Render configuration struct */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + RENDER_CONFIG_HANDLE hRenderConfig; + Decoder_Struct *st_ivas; + ivas_error error; - hRenderConfig = hIvasDec->st_ivas->hRenderConfig; - st_ivas = hIvasDec->st_ivas; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hRenderConfig == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + hRenderConfig = hIvasDec->st_ivas->hRenderConfig; + st_ivas = hIvasDec->st_ivas; - hRenderConfig->roomAcoustics.aeID = renderConfig.roomAcoustics.aeID; - hRenderConfig->roomAcoustics.nBands = renderConfig.roomAcoustics.nBands; - hRenderConfig->roomAcoustics.acousticPreDelay = renderConfig.roomAcoustics.acousticPreDelay; - hRenderConfig->roomAcoustics.inputPreDelay = renderConfig.roomAcoustics.inputPreDelay; + hRenderConfig->roomAcoustics.aeID = renderConfig.roomAcoustics.aeID; + hRenderConfig->roomAcoustics.nBands = renderConfig.roomAcoustics.nBands; + hRenderConfig->roomAcoustics.acousticPreDelay = renderConfig.roomAcoustics.acousticPreDelay; + hRenderConfig->roomAcoustics.inputPreDelay = renderConfig.roomAcoustics.inputPreDelay; - hRenderConfig->roomAcoustics.use_er = 0; - if ( renderConfig.roomAcoustics.use_er == 1 ) - { - hRenderConfig->roomAcoustics.use_er = renderConfig.roomAcoustics.use_er; - hRenderConfig->roomAcoustics.lowComplexity = renderConfig.roomAcoustics.lowComplexity; - hRenderConfig->roomAcoustics.dimensions = renderConfig.roomAcoustics.dimensions; - hRenderConfig->roomAcoustics.ListenerOrigin = renderConfig.roomAcoustics.ListenerOrigin; + hRenderConfig->roomAcoustics.use_er = 0; + if ( renderConfig.roomAcoustics.use_er == 1 ) + { + hRenderConfig->roomAcoustics.use_er = renderConfig.roomAcoustics.use_er; + hRenderConfig->roomAcoustics.lowComplexity = renderConfig.roomAcoustics.lowComplexity; + hRenderConfig->roomAcoustics.dimensions = renderConfig.roomAcoustics.dimensions; + hRenderConfig->roomAcoustics.ListenerOrigin = renderConfig.roomAcoustics.ListenerOrigin; - mvr2r( renderConfig.roomAcoustics.AbsCoeff, hRenderConfig->roomAcoustics.AbsCoeff, IVAS_ROOM_ABS_COEFF ); - } + mvr2r( renderConfig.roomAcoustics.AbsCoeff, hRenderConfig->roomAcoustics.AbsCoeff, IVAS_ROOM_ABS_COEFF ); + } - mvr2r( renderConfig.roomAcoustics.pFc_input, hRenderConfig->roomAcoustics.pFc_input, CLDFB_NO_CHANNELS_MAX ); - mvr2r( renderConfig.roomAcoustics.pAcoustic_rt60, hRenderConfig->roomAcoustics.pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); - mvr2r( renderConfig.roomAcoustics.pAcoustic_dsr, hRenderConfig->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); + mvr2r( renderConfig.roomAcoustics.pFc_input, hRenderConfig->roomAcoustics.pFc_input, CLDFB_NO_CHANNELS_MAX ); + mvr2r( renderConfig.roomAcoustics.pAcoustic_rt60, hRenderConfig->roomAcoustics.pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); + mvr2r( renderConfig.roomAcoustics.pAcoustic_dsr, hRenderConfig->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); - /* Re-initialize reverb instance if already available */ + /* Re-initialize reverb instance if already available */ - /* TD renderer Jot reverberator */ - if ( st_ivas->hReverb != NULL ) - { - if ( ( error = ivas_reverb_open( &st_ivas->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + /* TD renderer Jot reverberator */ + if ( st_ivas->hReverb != NULL ) { - return error; + if ( ( error = ivas_reverb_open( &st_ivas->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } } - } - /* CREND Jot reverberator */ - if ( st_ivas->hCrendWrapper != NULL && st_ivas->hCrendWrapper->hCrend[0] != NULL && st_ivas->hCrendWrapper->hCrend[0]->hReverb != NULL ) - { - if ( ( error = ivas_reverb_open( &st_ivas->hCrendWrapper->hCrend[0]->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + /* CREND Jot reverberator */ + if ( st_ivas->hCrendWrapper != NULL && st_ivas->hCrendWrapper->hCrend[0] != NULL && st_ivas->hCrendWrapper->hCrend[0]->hReverb != NULL ) { - return error; + if ( ( error = ivas_reverb_open( &st_ivas->hCrendWrapper->hCrend[0]->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } } - } - /* Parametric renderer reverberator */ - if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->hReverb != NULL ) - { - ivas_binaural_reverb_close( &( st_ivas->hDiracDecBin[0]->hReverb ) ); + /* Parametric renderer reverberator */ + if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->hReverb != NULL ) + { + ivas_binaural_reverb_close( &( st_ivas->hDiracDecBin[0]->hReverb ) ); + + if ( ( error = ivas_binaural_reverb_init( &( st_ivas->hDiracDecBin[0]->hReverb ), st_ivas->hHrtfStatistics, st_ivas->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, + &( hRenderConfig->roomAcoustics ), st_ivas->hDecoderConfig->output_Fs, NULL, NULL, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + } - if ( ( error = ivas_binaural_reverb_init( &( st_ivas->hDiracDecBin[0]->hReverb ), st_ivas->hHrtfStatistics, st_ivas->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, - &( hRenderConfig->roomAcoustics ), st_ivas->hDecoderConfig->output_Fs, NULL, NULL, NULL ) ) != IVAS_ERR_OK ) + /* FastConv renderer reverberator */ + if ( st_ivas->hBinRenderer != NULL && st_ivas->hBinRenderer->hReverb != NULL ) { - return error; + ivas_binaural_reverb_close( &( st_ivas->hBinRenderer->hReverb ) ); + + if ( ( error = ivas_binaural_reverb_init( &( st_ivas->hBinRenderer->hReverb ), st_ivas->hHrtfStatistics, st_ivas->hBinRenderer->conv_band, st_ivas->hBinRenderer->timeSlots, + &( hRenderConfig->roomAcoustics ), st_ivas->hDecoderConfig->output_Fs, NULL, NULL, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } } - } - /* FastConv renderer reverberator */ - if ( st_ivas->hBinRenderer != NULL && st_ivas->hBinRenderer->hReverb != NULL ) - { - ivas_binaural_reverb_close( &( st_ivas->hBinRenderer->hReverb ) ); + mvr2r( renderConfig.directivity, hRenderConfig->directivity, 3 * MAX_NUM_OBJECTS ); + mvr2r( renderConfig.distAtt, hRenderConfig->distAtt, 3 ); + + hRenderConfig->split_rend_config = renderConfig.split_rend_config; - if ( ( error = ivas_binaural_reverb_init( &( st_ivas->hBinRenderer->hReverb ), st_ivas->hHrtfStatistics, st_ivas->hBinRenderer->conv_band, st_ivas->hBinRenderer->timeSlots, - &( hRenderConfig->roomAcoustics ), st_ivas->hDecoderConfig->output_Fs, NULL, NULL, NULL ) ) != IVAS_ERR_OK ) + /* Overwrite any pose correction settings if 0 DOF (no pose correction) was selected */ + if ( hRenderConfig->split_rend_config.dof == 0 ) { - return error; + hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + } + + if ( is_split_rendering_enabled( st_ivas->hDecoderConfig, hRenderConfig ) ) + { + if ( ( error = isar_split_rend_validate_config( &hRenderConfig->split_rend_config, ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + { + return error; + } } + + return IVAS_ERR_OK; } - mvr2r( renderConfig.directivity, hRenderConfig->directivity, 3 * MAX_NUM_OBJECTS ); - mvr2r( renderConfig.distAtt, hRenderConfig->distAtt, 3 ); - hRenderConfig->split_rend_config = renderConfig.split_rend_config; + /*---------------------------------------------------------------------* + * feedAcousticEnvPI( ) + * + * Set acoustic environment from the PI data + *---------------------------------------------------------------------*/ - /* Overwrite any pose correction settings if 0 DOF (no pose correction) was selected */ - if ( hRenderConfig->split_rend_config.dof == 0 ) + static ivas_error feedAcousticEnvPI( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_PIDATA_ACOUSTIC_ENV hAcoustEnvPI /* i : Render configuration struct */ + ) { - hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; - } + RENDER_CONFIG_HANDLE hRenderConfig; + Decoder_Struct *st_ivas; + ivas_error error; - if ( is_split_rendering_enabled( st_ivas->hDecoderConfig, hRenderConfig ) ) - { - if ( ( error = isar_split_rend_validate_config( &hRenderConfig->split_rend_config, ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hRenderConfig == NULL ) { - return error; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - } - - return IVAS_ERR_OK; -} + hRenderConfig = hIvasDec->st_ivas->hRenderConfig; + st_ivas = hIvasDec->st_ivas; -/*---------------------------------------------------------------------* - * feedAcousticEnvPI( ) - * - * Set acoustic environment from the PI data - *---------------------------------------------------------------------*/ + /* Ignore if AE ID already in use */ + if ( hRenderConfig->roomAcoustics.aeID == hAcoustEnvPI.aeid ) + { + return IVAS_ERR_OK; + } -static ivas_error feedAcousticEnvPI( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const IVAS_PIDATA_ACOUSTIC_ENV hAcoustEnvPI /* i : Render configuration struct */ -) -{ - RENDER_CONFIG_HANDLE hRenderConfig; - Decoder_Struct *st_ivas; - ivas_error error; + /* Attempt to load the one already available */ + if ( ( error = IVAS_DEC_GetAcousticEnvironment( hIvasDec, hAcoustEnvPI.aeid, &hRenderConfig->roomAcoustics ) ) == IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING ) + { + /* Add the new compact room environment */ + IVAS_ROOM_ACOUSTICS_CONFIG_DATA acEnv; - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hRenderConfig == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + acEnv.aeID = hAcoustEnvPI.aeid; + acEnv.nBands = IVAS_PI_AE_NUM_BANDS; + acEnv.pFc_input[IVAS_PI_AE_LOW] = IVAS_PI_AE_LOW_FREQ; + acEnv.pFc_input[IVAS_PI_AE_MID] = IVAS_PI_AE_MID_FREQ; + acEnv.pFc_input[IVAS_PI_AE_HIGH] = IVAS_PI_AE_HIGH_FREQ; + acEnv.pAcoustic_rt60[IVAS_PI_AE_LOW] = hAcoustEnvPI.rt60[IVAS_PI_AE_LOW]; + acEnv.pAcoustic_rt60[IVAS_PI_AE_MID] = hAcoustEnvPI.rt60[IVAS_PI_AE_MID]; + acEnv.pAcoustic_rt60[IVAS_PI_AE_HIGH] = hAcoustEnvPI.rt60[IVAS_PI_AE_HIGH]; + acEnv.inputPreDelay = (float) ( 0.1 * hRenderConfig->roomAcoustics.pAcoustic_rt60[IVAS_PI_AE_MID] ); + acEnv.pAcoustic_dsr[IVAS_PI_AE_LOW] = powf( 10.0f, hAcoustEnvPI.dsr[IVAS_PI_AE_LOW] / 10.0f ); + acEnv.pAcoustic_dsr[IVAS_PI_AE_MID] = powf( 10.0f, hAcoustEnvPI.dsr[IVAS_PI_AE_MID] / 10.0f ); + acEnv.pAcoustic_dsr[IVAS_PI_AE_HIGH] = powf( 10.0f, hAcoustEnvPI.dsr[IVAS_PI_AE_HIGH] / 10.0f ); - hRenderConfig = hIvasDec->st_ivas->hRenderConfig; - st_ivas = hIvasDec->st_ivas; + acEnv.use_er = hAcoustEnvPI.availEarlyReflections; - /* Ignore if AE ID already in use */ - if ( hRenderConfig->roomAcoustics.aeID == hAcoustEnvPI.aeid ) - { - return IVAS_ERR_OK; - } + if ( hAcoustEnvPI.availEarlyReflections ) + { + hRenderConfig->roomAcoustics.dimensions.x = hAcoustEnvPI.roomDimensions.x; + hRenderConfig->roomAcoustics.dimensions.y = hAcoustEnvPI.roomDimensions.y; + hRenderConfig->roomAcoustics.dimensions.z = hAcoustEnvPI.roomDimensions.z; + mvr2r( hAcoustEnvPI.absorbCoeffs, hRenderConfig->roomAcoustics.AbsCoeff, IVAS_ROOM_ABS_COEFF ); + } - /* Attempt to load the one already available */ - if ( ( error = IVAS_DEC_GetAcousticEnvironment( hIvasDec, hAcoustEnvPI.aeid, &hRenderConfig->roomAcoustics ) ) == IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING ) - { - /* Add the new compact room environment */ - IVAS_ROOM_ACOUSTICS_CONFIG_DATA acEnv; + if ( ( error = IVAS_DEC_AddAcousticEnvironment( hIvasDec, acEnv ) ) != IVAS_ERR_OK ) + { + return error; + } - acEnv.aeID = hAcoustEnvPI.aeid; - acEnv.nBands = IVAS_PI_AE_NUM_BANDS; - acEnv.pFc_input[IVAS_PI_AE_LOW] = IVAS_PI_AE_LOW_FREQ; - acEnv.pFc_input[IVAS_PI_AE_MID] = IVAS_PI_AE_MID_FREQ; - acEnv.pFc_input[IVAS_PI_AE_HIGH] = IVAS_PI_AE_HIGH_FREQ; - acEnv.pAcoustic_rt60[IVAS_PI_AE_LOW] = hAcoustEnvPI.rt60[IVAS_PI_AE_LOW]; - acEnv.pAcoustic_rt60[IVAS_PI_AE_MID] = hAcoustEnvPI.rt60[IVAS_PI_AE_MID]; - acEnv.pAcoustic_rt60[IVAS_PI_AE_HIGH] = hAcoustEnvPI.rt60[IVAS_PI_AE_HIGH]; - acEnv.inputPreDelay = (float) ( 0.1 * hRenderConfig->roomAcoustics.pAcoustic_rt60[IVAS_PI_AE_MID] ); - acEnv.pAcoustic_dsr[IVAS_PI_AE_LOW] = powf( 10.0f, hAcoustEnvPI.dsr[IVAS_PI_AE_LOW] / 10.0f ); - acEnv.pAcoustic_dsr[IVAS_PI_AE_MID] = powf( 10.0f, hAcoustEnvPI.dsr[IVAS_PI_AE_MID] / 10.0f ); - acEnv.pAcoustic_dsr[IVAS_PI_AE_HIGH] = powf( 10.0f, hAcoustEnvPI.dsr[IVAS_PI_AE_HIGH] / 10.0f ); + if ( ( error = IVAS_DEC_GetAcousticEnvironment( hIvasDec, hAcoustEnvPI.aeid, &hRenderConfig->roomAcoustics ) ) != IVAS_ERR_OK ) + { + return error; + } + } - acEnv.use_er = hAcoustEnvPI.availEarlyReflections; + /* Re-initialize reverb instance if already available */ - if ( hAcoustEnvPI.availEarlyReflections ) + /* TD renderer Jot reverberator */ + if ( st_ivas->hReverb != NULL ) { - hRenderConfig->roomAcoustics.dimensions.x = hAcoustEnvPI.roomDimensions.x; - hRenderConfig->roomAcoustics.dimensions.y = hAcoustEnvPI.roomDimensions.y; - hRenderConfig->roomAcoustics.dimensions.z = hAcoustEnvPI.roomDimensions.z; - mvr2r( hAcoustEnvPI.absorbCoeffs, hRenderConfig->roomAcoustics.AbsCoeff, IVAS_ROOM_ABS_COEFF ); + if ( ( error = ivas_reverb_open( &st_ivas->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } } - if ( ( error = IVAS_DEC_AddAcousticEnvironment( hIvasDec, acEnv ) ) != IVAS_ERR_OK ) + /* CREND Jot reverberator */ + if ( st_ivas->hCrendWrapper != NULL && st_ivas->hCrendWrapper->hCrend[0] != NULL && st_ivas->hCrendWrapper->hCrend[0]->hReverb != NULL ) { - return error; + if ( ( error = ivas_reverb_open( &st_ivas->hCrendWrapper->hCrend[0]->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } } - if ( ( error = IVAS_DEC_GetAcousticEnvironment( hIvasDec, hAcoustEnvPI.aeid, &hRenderConfig->roomAcoustics ) ) != IVAS_ERR_OK ) + /* Parametric renderer reverberator */ + if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->hReverb != NULL ) { - return error; - } - } - - /* Re-initialize reverb instance if already available */ + ivas_binaural_reverb_close( &( st_ivas->hDiracDecBin[0]->hReverb ) ); - /* TD renderer Jot reverberator */ - if ( st_ivas->hReverb != NULL ) - { - if ( ( error = ivas_reverb_open( &st_ivas->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) - { - return error; + if ( ( error = ivas_binaural_reverb_init( &( st_ivas->hDiracDecBin[0]->hReverb ), st_ivas->hHrtfStatistics, st_ivas->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, + &( hRenderConfig->roomAcoustics ), st_ivas->hDecoderConfig->output_Fs, NULL, NULL, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } } - } - /* CREND Jot reverberator */ - if ( st_ivas->hCrendWrapper != NULL && st_ivas->hCrendWrapper->hCrend[0] != NULL && st_ivas->hCrendWrapper->hCrend[0]->hReverb != NULL ) - { - if ( ( error = ivas_reverb_open( &st_ivas->hCrendWrapper->hCrend[0]->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + /* FastConv renderer reverberator */ + if ( st_ivas->hBinRenderer != NULL && st_ivas->hBinRenderer->hReverb != NULL ) { - return error; + ivas_binaural_reverb_close( &( st_ivas->hBinRenderer->hReverb ) ); + + if ( ( error = ivas_binaural_reverb_init( &( st_ivas->hBinRenderer->hReverb ), st_ivas->hHrtfStatistics, st_ivas->hBinRenderer->conv_band, st_ivas->hBinRenderer->timeSlots, + &( hRenderConfig->roomAcoustics ), st_ivas->hDecoderConfig->output_Fs, NULL, NULL, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } } + + return IVAS_ERR_OK; } - /* Parametric renderer reverberator */ - if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->hReverb != NULL ) + + /*---------------------------------------------------------------------* + * IVAS_DEC_GetDelay( ) + * + * Return IVAS decoder delay in nanoseconds + *---------------------------------------------------------------------*/ + + ivas_error IVAS_DEC_GetDelay( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t * nSamples, /* o : decoder delay in samples */ + int32_t * timeScale /* o : time scale of the delay, equal to decoder output sampling rate */ + ) { - ivas_binaural_reverb_close( &( st_ivas->hDiracDecBin[0]->hReverb ) ); + Decoder_Struct *st_ivas; + DECODER_CONFIG_HANDLE hDecoderConfig; - if ( ( error = ivas_binaural_reverb_init( &( st_ivas->hDiracDecBin[0]->hReverb ), st_ivas->hHrtfStatistics, st_ivas->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, - &( hRenderConfig->roomAcoustics ), st_ivas->hDecoderConfig->output_Fs, NULL, NULL, NULL ) ) != IVAS_ERR_OK ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || nSamples == NULL || timeScale == NULL ) { - return error; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - } - - /* FastConv renderer reverberator */ - if ( st_ivas->hBinRenderer != NULL && st_ivas->hBinRenderer->hReverb != NULL ) - { - ivas_binaural_reverb_close( &( st_ivas->hBinRenderer->hReverb ) ); - if ( ( error = ivas_binaural_reverb_init( &( st_ivas->hBinRenderer->hReverb ), st_ivas->hHrtfStatistics, st_ivas->hBinRenderer->conv_band, st_ivas->hBinRenderer->timeSlots, - &( hRenderConfig->roomAcoustics ), st_ivas->hDecoderConfig->output_Fs, NULL, NULL, NULL ) ) != IVAS_ERR_OK ) + if ( !hIvasDec->hasDecodedFirstGoodFrame ) { - return error; + /* Delay depends on IVAS format, which is unknown until first frame has been decoded */ + return IVAS_ERR_WAITING_FOR_BITSTREAM; } - } - return IVAS_ERR_OK; -} + st_ivas = hIvasDec->st_ivas; + hDecoderConfig = st_ivas->hDecoderConfig; + nSamples[1] = NS2SA( hDecoderConfig->output_Fs, get_delay( DEC, hDecoderConfig->output_Fs, st_ivas->ivas_format, st_ivas->cldfbSynDec[0], hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ); -/*---------------------------------------------------------------------* - * IVAS_DEC_GetDelay( ) - * - * Return IVAS decoder delay in nanoseconds - *---------------------------------------------------------------------*/ + nSamples[2] = (int16_t) roundf( (float) st_ivas->binaural_latency_ns * hDecoderConfig->output_Fs / 1000000000.f ); + nSamples[0] = nSamples[1] + nSamples[2]; -ivas_error IVAS_DEC_GetDelay( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t *nSamples, /* o : decoder delay in samples */ - int32_t *timeScale /* o : time scale of the delay, equal to decoder output sampling rate */ -) -{ - Decoder_Struct *st_ivas; - DECODER_CONFIG_HANDLE hDecoderConfig; + if ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) + { + /* note: in MASA, all delay is compensated at the decoder by default, so subtract the encoder delay for print-out */ + nSamples[1] -= NS2SA( hDecoderConfig->output_Fs, IVAS_ENC_DELAY_NS ); + } - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || nSamples == NULL || timeScale == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + *timeScale = hDecoderConfig->output_Fs; - if ( !hIvasDec->hasDecodedFirstGoodFrame ) - { - /* Delay depends on IVAS format, which is unknown until first frame has been decoded */ - return IVAS_ERR_WAITING_FOR_BITSTREAM; + return IVAS_ERR_OK; } - st_ivas = hIvasDec->st_ivas; - hDecoderConfig = st_ivas->hDecoderConfig; - - nSamples[1] = NS2SA( hDecoderConfig->output_Fs, get_delay( DEC, hDecoderConfig->output_Fs, st_ivas->ivas_format, st_ivas->cldfbSynDec[0], hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ); - nSamples[2] = (int16_t) roundf( (float) st_ivas->binaural_latency_ns * hDecoderConfig->output_Fs / 1000000000.f ); - nSamples[0] = nSamples[1] + nSamples[2]; + /*---------------------------------------------------------------------* + * IVAS_DEC_HasDecodedFirstGoodFrame( ) + * + * Return flag indicating if the decoder has decoded a good frame + *---------------------------------------------------------------------*/ - if ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) + ivas_error IVAS_DEC_HasDecodedFirstGoodFrame( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + bool *hasDecodedFirstGoodFrame /* o : flag indicating if the decoder has decoded a good frame since it was configured */ + ) { - /* note: in MASA, all delay is compensated at the decoder by default, so subtract the encoder delay for print-out */ - nSamples[1] -= NS2SA( hDecoderConfig->output_Fs, IVAS_ENC_DELAY_NS ); - } - - *timeScale = hDecoderConfig->output_Fs; - - return IVAS_ERR_OK; -} - + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hasDecodedFirstGoodFrame == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_HasDecodedFirstGoodFrame( ) - * - * Return flag indicating if the decoder has decoded a good frame - *---------------------------------------------------------------------*/ + *hasDecodedFirstGoodFrame = hIvasDec->hasDecodedFirstGoodFrame; -ivas_error IVAS_DEC_HasDecodedFirstGoodFrame( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - bool *hasDecodedFirstGoodFrame /* o : flag indicating if the decoder has decoded a good frame since it was configured */ -) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hasDecodedFirstGoodFrame == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + return IVAS_ERR_OK; } - *hasDecodedFirstGoodFrame = hIvasDec->hasDecodedFirstGoodFrame; - - return IVAS_ERR_OK; -} + /*---------------------------------------------------------------------* + * isSidFrame( ) + * + * Check if a frame contains a SID + *---------------------------------------------------------------------*/ -/*---------------------------------------------------------------------* - * isSidFrame( ) - * - * Check if a frame contains a SID - *---------------------------------------------------------------------*/ - -static bool isSidFrame( - const uint16_t size ) -{ - if ( size == SID_1k75 / FRAMES_PER_SEC ) - { - return true; /* AMR-WB SID */ - } - else if ( size == SID_2k40 / FRAMES_PER_SEC ) - { - return true; /* EVS SID */ - } - else if ( size == IVAS_SID_5k2 / FRAMES_PER_SEC ) + static bool isSidFrame( + const uint16_t size ) { - return true; /* IVAS SID */ - } + if ( size == SID_1k75 / FRAMES_PER_SEC ) + { + return true; /* AMR-WB SID */ + } + else if ( size == SID_2k40 / FRAMES_PER_SEC ) + { + return true; /* EVS SID */ + } + else if ( size == IVAS_SID_5k2 / FRAMES_PER_SEC ) + { + return true; /* IVAS SID */ + } - return false; -} + return false; + } -/*---------------------------------------------------------------------* - * bsCompactToSerial( ) - * - * Bitstream conversion to Byte format - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * bsCompactToSerial( ) + * + * Bitstream conversion to Byte format + *---------------------------------------------------------------------*/ -static void bsCompactToSerial( - const uint8_t *compact, - uint16_t *serial, - const uint16_t num_bits ) -{ + static void bsCompactToSerial( + const uint8_t *compact, + uint16_t *serial, + const uint16_t num_bits ) + { /* Bitstream conversion is not counted towards complexity and memory usage */ #define WMC_TOOL_SKIP - uint32_t i; - uint8_t byte = 0; - const uint8_t mask = 0x80; + uint32_t i; + uint8_t byte = 0; + const uint8_t mask = 0x80; - for ( i = 0; i < num_bits; ++i ) - { - if ( i % 8 == 0 ) + for ( i = 0; i < num_bits; ++i ) { - byte = compact[i / 8]; - } + if ( i % 8 == 0 ) + { + byte = compact[i / 8]; + } - serial[i] = ( byte & mask ) >> 7; + serial[i] = ( byte & mask ) >> 7; - byte <<= 1; - } + byte <<= 1; + } - /* Add 4 padding bytes required by core coder */ - for ( i = 0; i < 4 * 8; ++i ) - { - serial[num_bits + i] = 0; - } + /* Add 4 padding bytes required by core coder */ + for ( i = 0; i < 4 * 8; ++i ) + { + serial[num_bits + i] = 0; + } #undef WMC_TOOL_SKIP -} - + } -/*---------------------------------------------------------------------* - * IVAS_DEC_VoIP_FeedFrame( ) - * - * Feed RTP packet into internal jitter buffer - *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_VoIP_FeedFrame( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint8_t *au, /* i : buffer containing input access unit */ - const uint16_t auSize, /* i : size of the access unit */ - const uint16_t rtpSequenceNumber, /* i : RTP sequence number (16 bits) */ - const uint32_t rtpTimeStamp, /* i : RTP timestamp (32 bits) */ - const uint32_t rcvTime_ms, /* i : receive time of the RTP packet in milliseconds */ - const bool qBit /* i : Q bit for AMR-WB IO */ -) -{ - JB4_DATAUNIT_HANDLE dataUnit; - int16_t partialCopyFrameType, partialCopyOffset; - int16_t result; + /*---------------------------------------------------------------------* + * IVAS_DEC_VoIP_FeedFrame( ) + * + * Feed RTP packet into internal jitter buffer + *---------------------------------------------------------------------*/ - if ( hIvasDec == NULL || hIvasDec->hVoIP == NULL || au == NULL ) + ivas_error IVAS_DEC_VoIP_FeedFrame( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint8_t * au, /* i : buffer containing input access unit */ + const uint16_t auSize, /* i : size of the access unit */ + const uint16_t rtpSequenceNumber, /* i : RTP sequence number (16 bits) */ + const uint32_t rtpTimeStamp, /* i : RTP timestamp (32 bits) */ + const uint32_t rcvTime_ms, /* i : receive time of the RTP packet in milliseconds */ + const bool qBit /* i : Q bit for AMR-WB IO */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + JB4_DATAUNIT_HANDLE dataUnit; + int16_t partialCopyFrameType, partialCopyOffset; + int16_t result; - if ( auSize == 0 ) - { - return IVAS_ERR_OK; /* ignore empty/NO_DATA frame - shouldn't be transmitted in RTP */ - } - if ( ( auSize + 7 ) / 8 > MAX_AU_SIZE ) - { - return IVAS_ERR_INVALID_BITSTREAM; - } + if ( hIvasDec == NULL || hIvasDec->hVoIP == NULL || au == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - partialCopyFrameType = 0; - partialCopyOffset = 0; + if ( auSize == 0 ) + { + return IVAS_ERR_OK; /* ignore empty/NO_DATA frame - shouldn't be transmitted in RTP */ + } + if ( ( auSize + 7 ) / 8 > MAX_AU_SIZE ) + { + return IVAS_ERR_INVALID_BITSTREAM; + } - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) - { - /* check if frame contains a partial copy and get its offset */ - evs_dec_previewFrame( au, auSize, &partialCopyFrameType, &partialCopyOffset ); - } + partialCopyFrameType = 0; + partialCopyOffset = 0; - /* create data unit for primary copy in the frame */ - dataUnit = JB4_AllocDataUnit( hIvasDec->hVoIP->hJBM ); - mvc2c( au, dataUnit->data, (int16_t) ( ( auSize + 7 ) / 8 ) ); - dataUnit->dataSize = auSize; - dataUnit->duration = 20; - dataUnit->sequenceNumber = rtpSequenceNumber; - dataUnit->silenceIndicator = isSidFrame( dataUnit->dataSize ); - dataUnit->timeScale = 1000; - dataUnit->rcvTime = rcvTime_ms; - dataUnit->timeStamp = rtpTimeStamp; - dataUnit->partial_frame = 0; - dataUnit->partialCopyOffset = partialCopyOffset; - dataUnit->qBit = qBit; - - /* add the frame to the JBM */ - result = JB4_PushDataUnit( hIvasDec->hVoIP->hJBM, dataUnit, rcvTime_ms ); - if ( result != 0 ) - { - return IVAS_ERR_UNKNOWN; - } + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + { + /* check if frame contains a partial copy and get its offset */ + evs_dec_previewFrame( au, auSize, &partialCopyFrameType, &partialCopyOffset ); + } - if ( partialCopyFrameType != RF_NO_DATA && partialCopyOffset != 0 ) - { - /* create data unit for partial copy in the frame */ + /* create data unit for primary copy in the frame */ dataUnit = JB4_AllocDataUnit( hIvasDec->hVoIP->hJBM ); mvc2c( au, dataUnit->data, (int16_t) ( ( auSize + 7 ) / 8 ) ); dataUnit->dataSize = auSize; dataUnit->duration = 20; dataUnit->sequenceNumber = rtpSequenceNumber; - dataUnit->silenceIndicator = 0; /* there are no partial copies for SID frames */ + dataUnit->silenceIndicator = isSidFrame( dataUnit->dataSize ); dataUnit->timeScale = 1000; dataUnit->rcvTime = rcvTime_ms; - dataUnit->timeStamp = rtpTimeStamp - partialCopyOffset * dataUnit->duration; - dataUnit->partial_frame = 1; + dataUnit->timeStamp = rtpTimeStamp; + dataUnit->partial_frame = 0; dataUnit->partialCopyOffset = partialCopyOffset; dataUnit->qBit = qBit; @@ -3702,962 +3715,985 @@ ivas_error IVAS_DEC_VoIP_FeedFrame( { return IVAS_ERR_UNKNOWN; } - } - return IVAS_ERR_OK; -} + if ( partialCopyFrameType != RF_NO_DATA && partialCopyOffset != 0 ) + { + /* create data unit for partial copy in the frame */ + dataUnit = JB4_AllocDataUnit( hIvasDec->hVoIP->hJBM ); + mvc2c( au, dataUnit->data, (int16_t) ( ( auSize + 7 ) / 8 ) ); + dataUnit->dataSize = auSize; + dataUnit->duration = 20; + dataUnit->sequenceNumber = rtpSequenceNumber; + dataUnit->silenceIndicator = 0; /* there are no partial copies for SID frames */ + dataUnit->timeScale = 1000; + dataUnit->rcvTime = rcvTime_ms; + dataUnit->timeStamp = rtpTimeStamp - partialCopyOffset * dataUnit->duration; + dataUnit->partial_frame = 1; + dataUnit->partialCopyOffset = partialCopyOffset; + dataUnit->qBit = qBit; + + /* add the frame to the JBM */ + result = JB4_PushDataUnit( hIvasDec->hVoIP->hJBM, dataUnit, rcvTime_ms ); + if ( result != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + } + + return IVAS_ERR_OK; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_VoIP_SetScale( ) - * - * Set the TSM scale - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * IVAS_DEC_VoIP_SetScale( ) + * + * Set the TSM scale + *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_VoIP_SetScale( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const int16_t maxScaling, /* i : max allowed absolute difference in samples from the default 20ms frame size */ - const int16_t scale /* i : TSM scale to set in percent of the default frame size */ -) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + ivas_error IVAS_DEC_VoIP_SetScale( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t maxScaling, /* i : max allowed absolute difference in samples from the default 20ms frame size */ + const int16_t scale /* i : TSM scale to set in percent of the default frame size */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm == 0 ) - { - return IVAS_ERR_TSM_NOT_ENABLED; - } - else - { - hIvasDec->tsm_scale = scale; - hIvasDec->tsm_max_scaling = maxScaling; - } + if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm == 0 ) + { + return IVAS_ERR_TSM_NOT_ENABLED; + } + else + { + hIvasDec->tsm_scale = scale; + hIvasDec->tsm_max_scaling = maxScaling; + } - return IVAS_ERR_OK; -} + return IVAS_ERR_OK; + } #ifdef VARIABLE_SPEED_DECODING -/*---------------------------------------------------------------------* - * IVAS_DEC_EnableTsm( ) - * - * Enable Time-Scale Modification (TSM) - *---------------------------------------------------------------------*/ - -ivas_error IVAS_DEC_EnableTsm( - IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ -) -{ - AUDIO_CONFIG output_config; - ivas_error error; + /*---------------------------------------------------------------------* + * IVAS_DEC_EnableTsm( ) + * + * Enable Time-Scale Modification (TSM) + *---------------------------------------------------------------------*/ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + ivas_error IVAS_DEC_EnableTsm( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + AUDIO_CONFIG output_config; + ivas_error error; - hIvasDec->st_ivas->hDecoderConfig->Opt_tsm = 1; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - /* init flush buffer if necessary (only needed for binaural) */ - output_config = hIvasDec->st_ivas->hDecoderConfig->output_config; - if ( hIvasDec->flushbuffer == NULL && ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) - { - if ( ( error = create_flush_buffer( hIvasDec ) ) != IVAS_ERR_OK ) + hIvasDec->st_ivas->hDecoderConfig->Opt_tsm = 1; + + /* init flush buffer if necessary (only needed for binaural) */ + output_config = hIvasDec->st_ivas->hDecoderConfig->output_config; + if ( hIvasDec->flushbuffer == NULL && ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) { - return error; + if ( ( error = create_flush_buffer( hIvasDec ) ) != IVAS_ERR_OK ) + { + return error; + } } - } - return IVAS_ERR_OK; -} + return IVAS_ERR_OK; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_TSM_SetQuality( ) - * - * set the quality theshold for the time scale modiciation that is used - * to determine if the TSM yielded a signal that satisfies the minimum - * quality requirements. - * quality is lower limit for minimum quality - * Range is [-2;2] - where positive values allow - * only pasting with same phase information - * Negative values would yield cross phased pasting - * When not setting the minimum quality with this function the default - * value used is 1.0f - * - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * IVAS_DEC_TSM_SetQuality( ) + * + * set the quality theshold for the time scale modiciation that is used + * to determine if the TSM yielded a signal that satisfies the minimum + * quality requirements. + * quality is lower limit for minimum quality + * Range is [-2;2] - where positive values allow + * only pasting with same phase information + * Negative values would yield cross phased pasting + * When not setting the minimum quality with this function the default + * value used is 1.0f + * + *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_TSM_SetQuality( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const float quality /* i : target TSM quality */ -) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + ivas_error IVAS_DEC_TSM_SetQuality( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const float quality /* i : target TSM quality */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( !hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) - { - return IVAS_ERR_TSM_NOT_ENABLED; - } - else - { - hIvasDec->tsm_quality = quality; - } + if ( !hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) + { + return IVAS_ERR_TSM_NOT_ENABLED; + } + else + { + hIvasDec->tsm_quality = quality; + } - return IVAS_ERR_OK; -} + return IVAS_ERR_OK; + } #endif -/*---------------------------------------------------------------------* - * ivas_dec_voip_get_samples_common( ) - * - * Main function to output one frame in VoIP. Holds common code for - * regular output configs and split rendering configs. - *---------------------------------------------------------------------*/ - -static ivas_error ivas_dec_voip_get_samples_common( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ - const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ - void *pcmBuf, /* o : output synthesis signal */ - ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */ - float **p_head_pose_buf, /* i : PCM buffer with head-pose data */ + /*---------------------------------------------------------------------* + * ivas_dec_voip_get_samples_common( ) + * + * Main function to output one frame in VoIP. Holds common code for + * regular output configs and split rendering configs. + *---------------------------------------------------------------------*/ + + static ivas_error ivas_dec_voip_get_samples_common( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */ + float **p_head_pose_buf, /* i : PCM buffer with head-pose data */ #ifdef SUPPORT_JBM_TRACEFILE - JbmTraceFileWriterFn jbmWriterFn, - void *jbmWriter, + JbmTraceFileWriterFn jbmWriterFn, + void *jbmWriter, #endif - bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */ - uint16_t *nSamplesRendered, /* o : number of samples rendered */ - bool *parametersAvailableForEditing, /* o : indicates whether objects editing is available */ - const uint32_t systemTimestamp_ms /* i : current system timestamp */ -) -{ - Decoder_Struct *st_ivas; - DECODER_CONFIG_HANDLE hDecoderConfig; - IVAS_DEC_VOIP *hVoIP; - uint32_t extBufferedTime_ms, scale, maxScaling; - JB4_DATAUNIT_HANDLE dataUnit; - uint16_t extBufferedSamples; - int16_t result; - ivas_error error; - uint8_t nOutChannels; - - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->hVoIP == NULL ) + bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */ + uint16_t *nSamplesRendered, /* o : number of samples rendered */ + bool *parametersAvailableForEditing, /* o : indicates whether objects editing is available */ + const uint32_t systemTimestamp_ms /* i : current system timestamp */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + Decoder_Struct *st_ivas; + DECODER_CONFIG_HANDLE hDecoderConfig; + IVAS_DEC_VOIP *hVoIP; + uint32_t extBufferedTime_ms, scale, maxScaling; + JB4_DATAUNIT_HANDLE dataUnit; + uint16_t extBufferedSamples; + int16_t result; + ivas_error error; + uint8_t nOutChannels; - st_ivas = hIvasDec->st_ivas; - hDecoderConfig = st_ivas->hDecoderConfig; - hVoIP = hIvasDec->hVoIP; - nOutChannels = (uint8_t) st_ivas->hDecoderConfig->nchan_out; - *parametersAvailableForEditing = false; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->hVoIP == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( nSamplesPerChannel == 0 ) - { - return IVAS_ERR_WRONG_PARAMS; - } + st_ivas = hIvasDec->st_ivas; + hDecoderConfig = st_ivas->hDecoderConfig; + hVoIP = hIvasDec->hVoIP; + nOutChannels = (uint8_t) st_ivas->hDecoderConfig->nchan_out; + *parametersAvailableForEditing = false; - if ( ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || - hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && - splitRendBits == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + if ( nSamplesPerChannel == 0 ) + { + return IVAS_ERR_WRONG_PARAMS; + } - /* make sure that the FIFO after decoder/scaler contains at least one sound card frame (i.e. 20ms) */ - while ( *nSamplesRendered < nSamplesPerChannel ) - { - if ( hIvasDec->nSamplesAvailableNext == 0 ) + if ( ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || + hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && + splitRendBits == NULL ) { - int16_t nSamplesBuffered; - nSamplesBuffered = 0; - if ( hIvasDec->hasBeenFedFirstGoodFrame ) + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + /* make sure that the FIFO after decoder/scaler contains at least one sound card frame (i.e. 20ms) */ + while ( *nSamplesRendered < nSamplesPerChannel ) + { + if ( hIvasDec->nSamplesAvailableNext == 0 ) { - /* check if the TC buffer already exists, otherweise nothing is buffered anyway */ - if ( st_ivas->hTcBuffer != NULL ) + int16_t nSamplesBuffered; + nSamplesBuffered = 0; + if ( hIvasDec->hasBeenFedFirstGoodFrame ) { - nSamplesBuffered = st_ivas->hTcBuffer->n_samples_buffered - st_ivas->hTcBuffer->n_samples_rendered; - nSamplesBuffered += hVoIP->nSamplesRendered20ms; + /* check if the TC buffer already exists, otherweise nothing is buffered anyway */ + if ( st_ivas->hTcBuffer != NULL ) + { + nSamplesBuffered = st_ivas->hTcBuffer->n_samples_buffered - st_ivas->hTcBuffer->n_samples_rendered; + nSamplesBuffered += hVoIP->nSamplesRendered20ms; + } } - } - extBufferedSamples = nSamplesBuffered; - extBufferedTime_ms = extBufferedSamples * 1000 / hDecoderConfig->output_Fs; - dataUnit = NULL; + extBufferedSamples = nSamplesBuffered; + extBufferedTime_ms = extBufferedSamples * 1000 / hDecoderConfig->output_Fs; + dataUnit = NULL; - /* pop one access unit from the jitter buffer */ - result = JB4_PopDataUnit( hVoIP->hJBM, systemTimestamp_ms, extBufferedTime_ms, &dataUnit, &scale, &maxScaling ); - if ( result != 0 ) - { - return IVAS_ERR_UNKNOWN; - } - maxScaling = maxScaling * hDecoderConfig->output_Fs / 1000; + /* pop one access unit from the jitter buffer */ + result = JB4_PopDataUnit( hVoIP->hJBM, systemTimestamp_ms, extBufferedTime_ms, &dataUnit, &scale, &maxScaling ); + if ( result != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + maxScaling = maxScaling * hDecoderConfig->output_Fs / 1000; #ifdef DEBUG_MODE_JBM - dbgwrite( &extBufferedSamples, sizeof( uint16_t ), 1, 1, "./res/JBM_extBufferedSamples.dat" ); - dbgwrite( &systemTimestamp_ms, sizeof( uint32_t ), 1, 1, "./res/JBM_systemTimestamp.dat" ); - dbgwrite( &scale, sizeof( uint32_t ), 1, 1, "./res/JBM_scale.dat" ); - dbgwrite( &maxScaling, sizeof( uint32_t ), 1, 1, "./res/JBM_maxScale.dat" ); + dbgwrite( &extBufferedSamples, sizeof( uint16_t ), 1, 1, "./res/JBM_extBufferedSamples.dat" ); + dbgwrite( &systemTimestamp_ms, sizeof( uint32_t ), 1, 1, "./res/JBM_systemTimestamp.dat" ); + dbgwrite( &scale, sizeof( uint32_t ), 1, 1, "./res/JBM_scale.dat" ); + dbgwrite( &maxScaling, sizeof( uint32_t ), 1, 1, "./res/JBM_maxScale.dat" ); #endif - /* avoid time scaling multiple times within one 20ms frame*/ - if ( scale != 100U ) - { - if ( hIvasDec->timeScalingDone ) + /* avoid time scaling multiple times within one 20ms frame*/ + if ( scale != 100U ) { - scale = 100; + if ( hIvasDec->timeScalingDone ) + { + scale = 100; + } } - } - - /* limit scale to range supported by time scaler */ - if ( scale < APA_MIN_SCALE ) - { - scale = APA_MIN_SCALE; - } - else if ( scale > APA_MAX_SCALE ) - { - scale = APA_MAX_SCALE; - } - if ( ( error = IVAS_DEC_VoIP_SetScale( hIvasDec, (int16_t) maxScaling, (int16_t) scale ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* copy bitstream into decoder state */ - if ( dataUnit ) - { - hIvasDec->hVoIP->hCurrentDataUnit = dataUnit; - - bsCompactToSerial( dataUnit->data, hIvasDec->hVoIP->bs_conversion_buf, dataUnit->dataSize ); + /* limit scale to range supported by time scaler */ + if ( scale < APA_MIN_SCALE ) + { + scale = APA_MIN_SCALE; + } + else if ( scale > APA_MAX_SCALE ) + { + scale = APA_MAX_SCALE; + } - if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, dataUnit->dataSize, 0 ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_VoIP_SetScale( hIvasDec, (int16_t) maxScaling, (int16_t) scale ) ) != IVAS_ERR_OK ) { return error; } - *bitstreamReadDone = true; - } - else if ( hIvasDec->hasDecodedFirstGoodFrame ) - { - /* Decoder has been initialized with first good frame - do PLC */ - if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, 0, 1 ) ) != IVAS_ERR_OK ) + /* copy bitstream into decoder state */ + if ( dataUnit ) { - return error; + hIvasDec->hVoIP->hCurrentDataUnit = dataUnit; + + bsCompactToSerial( dataUnit->data, hIvasDec->hVoIP->bs_conversion_buf, dataUnit->dataSize ); + + if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, dataUnit->dataSize, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + *bitstreamReadDone = true; + } + else if ( hIvasDec->hasDecodedFirstGoodFrame ) + { + /* Decoder has been initialized with first good frame - do PLC */ + if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, 0, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } } - } #ifdef SUPPORT_JBM_TRACEFILE - /* jbmWriterFn and jbmWriter may be NULL if tracefile writing was not requested on CLI */ - if ( jbmWriterFn != NULL && jbmWriter != NULL ) - { - /* write JBM trace data entry */ - store_JbmData( hVoIP, dataUnit, systemTimestamp_ms, extBufferedSamples, hDecoderConfig->output_Fs ); - if ( ( jbmWriterFn( &hVoIP->JbmTraceData, jbmWriter ) ) != IVAS_ERR_OK ) + /* jbmWriterFn and jbmWriter may be NULL if tracefile writing was not requested on CLI */ + if ( jbmWriterFn != NULL && jbmWriter != NULL ) { - fprintf( stderr, "\nError writing JBM Trace data to file\n" ); - return IVAS_ERR_UNKNOWN; + /* write JBM trace data entry */ + store_JbmData( hVoIP, dataUnit, systemTimestamp_ms, extBufferedSamples, hDecoderConfig->output_Fs ); + if ( ( jbmWriterFn( &hVoIP->JbmTraceData, jbmWriter ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError writing JBM Trace data to file\n" ); + return IVAS_ERR_UNKNOWN; + } } - } #endif - if ( dataUnit ) - { - if ( dataUnit->partial_frame != 0 ) + if ( dataUnit ) { - hVoIP->lastDecodedWasActive = 1; + if ( dataUnit->partial_frame != 0 ) + { + hVoIP->lastDecodedWasActive = 1; + } + else + { + hVoIP->lastDecodedWasActive = !dataUnit->silenceIndicator; + } + + /* data unit memory is no longer used */ + JB4_FreeDataUnit( hVoIP->hJBM, dataUnit ); } - else + + if ( hIvasDec->hasBeenFedFirstGoodFrame && *bitstreamReadDone == true ) { - hVoIP->lastDecodedWasActive = !dataUnit->silenceIndicator; + /* new bitstream was feeded, return for reconfiguration */ + return IVAS_ERR_OK; } - /* data unit memory is no longer used */ - JB4_FreeDataUnit( hVoIP->hJBM, dataUnit ); - } - - if ( hIvasDec->hasBeenFedFirstGoodFrame && *bitstreamReadDone == true ) - { - /* new bitstream was feeded, return for reconfiguration */ - return IVAS_ERR_OK; + if ( !hIvasDec->hasBeenFedFirstGoodFrame ) + { + hIvasDec->nSamplesAvailableNext = hIvasDec->nSamplesFrame; + } } + /* decode */ if ( !hIvasDec->hasBeenFedFirstGoodFrame ) { - hIvasDec->nSamplesAvailableNext = hIvasDec->nSamplesFrame; + /* codec mode to use not known yet - simply output silence */ + /* directly set output zero */ + int16_t nSamplesToZero = min( nSamplesPerChannel, hIvasDec->nSamplesAvailableNext ); + set_pcm_buffer_to_zero( pcm_buffer_offset( pcmBuf, pcmType, ( *nSamplesRendered ) * nOutChannels ), pcmType, nSamplesToZero * nOutChannels ); + *nSamplesRendered += nSamplesToZero; + hIvasDec->nSamplesAvailableNext -= nSamplesToZero; + update_voip_rendered20ms( hIvasDec, nSamplesToZero ); } - } - - /* decode */ - if ( !hIvasDec->hasBeenFedFirstGoodFrame ) - { - /* codec mode to use not known yet - simply output silence */ - /* directly set output zero */ - int16_t nSamplesToZero = min( nSamplesPerChannel, hIvasDec->nSamplesAvailableNext ); - set_pcm_buffer_to_zero( pcm_buffer_offset( pcmBuf, pcmType, ( *nSamplesRendered ) * nOutChannels ), pcmType, nSamplesToZero * nOutChannels ); - *nSamplesRendered += nSamplesToZero; - hIvasDec->nSamplesAvailableNext -= nSamplesToZero; - update_voip_rendered20ms( hIvasDec, nSamplesToZero ); - } - else - { - int16_t nSamplesToRender, nSamplesRendered_loop; - bool tmp; - - /* decode TCs, do TSM and prepare the renderer */ - if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) + else { - if ( hIvasDec->nSamplesAvailableNext == 0 || hIvasDec->nSamplesAvailableNext == hIvasDec->nSamplesFrame ) + int16_t nSamplesToRender, nSamplesRendered_loop; + bool tmp; + + /* decode TCs, do TSM and prepare the renderer */ + if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) { - if ( ( error = IVAS_DEC_GetSamplesDecoder( hIvasDec, splitRendBits ) ) != IVAS_ERR_OK ) + if ( hIvasDec->nSamplesAvailableNext == 0 || hIvasDec->nSamplesAvailableNext == hIvasDec->nSamplesFrame ) { - return error; + if ( ( error = IVAS_DEC_GetSamplesDecoder( hIvasDec, splitRendBits ) ) != IVAS_ERR_OK ) + { + return error; + } + + *bitstreamReadDone = false; + *parametersAvailableForEditing = true; + return IVAS_ERR_OK; } - - *bitstreamReadDone = false; - *parametersAvailableForEditing = true; - return IVAS_ERR_OK; } - } - nSamplesToRender = nSamplesPerChannel - *nSamplesRendered; + nSamplesToRender = nSamplesPerChannel - *nSamplesRendered; - /* check if we still need to prepare the renderer */ - if ( hIvasDec->hasBeenPreparedRendering == false ) - { - if ( ( error = IVAS_DEC_PrepareRenderer( hIvasDec ) ) != IVAS_ERR_OK ) + /* check if we still need to prepare the renderer */ + if ( hIvasDec->hasBeenPreparedRendering == false ) { - return error; + if ( ( error = IVAS_DEC_PrepareRenderer( hIvasDec ) ) != IVAS_ERR_OK ) + { + return error; + } } - } - if ( splitRendBits != NULL ) - { - /* Render head poses from time-scaled transport channels */ - if ( ( error = isar_render_poses( hIvasDec, nSamplesToRender, &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) + if ( splitRendBits != NULL ) { - return error; + /* Render head poses from time-scaled transport channels */ + if ( ( error = isar_render_poses( hIvasDec, nSamplesToRender, &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) + { + return error; + } } - } - else - { - /* render IVAS frames directly to the output buffer */ - if ( ( error = IVAS_DEC_GetSamplesRenderer( hIvasDec, nSamplesToRender, pcmType, pcm_buffer_offset( pcmBuf, pcmType, *nSamplesRendered * nOutChannels ), &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) + else { - return error; + /* render IVAS frames directly to the output buffer */ + if ( ( error = IVAS_DEC_GetSamplesRenderer( hIvasDec, nSamplesToRender, pcmType, pcm_buffer_offset( pcmBuf, pcmType, *nSamplesRendered * nOutChannels ), &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) + { + return error; + } } - } - *nSamplesRendered += nSamplesRendered_loop; - update_voip_rendered20ms( hIvasDec, nSamplesRendered_loop ); + *nSamplesRendered += nSamplesRendered_loop; + update_voip_rendered20ms( hIvasDec, nSamplesRendered_loop ); + } } - } - if ( hIvasDec->hasDecodedFirstGoodFrame && splitRendBits != NULL ) - { - /* Analyse head poses over entire frame, generate ISAR metadata and maybe encode if split coded */ - if ( ( error = isar_generate_metadata_and_bitstream( st_ivas, p_head_pose_buf, *nSamplesRendered, splitRendBits ) ) != IVAS_ERR_OK ) + if ( hIvasDec->hasDecodedFirstGoodFrame && splitRendBits != NULL ) { - return error; - } + /* Analyse head poses over entire frame, generate ISAR metadata and maybe encode if split coded */ + if ( ( error = isar_generate_metadata_and_bitstream( st_ivas, p_head_pose_buf, *nSamplesRendered, splitRendBits ) ) != IVAS_ERR_OK ) + { + return error; + } - /* Synthesise PCM output if split PCM */ - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { + /* Synthesise PCM output if split PCM */ + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { #ifndef DISABLE_LIMITER - ivas_limiter_dec( st_ivas->hLimiter, p_head_pose_buf, st_ivas->hDecoderConfig->nchan_out, *nSamplesRendered, st_ivas->BER_detect ); + ivas_limiter_dec( st_ivas->hLimiter, p_head_pose_buf, st_ivas->hDecoderConfig->nchan_out, *nSamplesRendered, st_ivas->BER_detect ); #endif #ifdef DEBUGGING - st_ivas->noClipping += + st_ivas->noClipping += #endif - ivas_syn_output( p_head_pose_buf, *nSamplesRendered, st_ivas->hDecoderConfig->nchan_out, (int16_t *) pcmBuf ); + ivas_syn_output( p_head_pose_buf, *nSamplesRendered, st_ivas->hDecoderConfig->nchan_out, (int16_t *) pcmBuf ); + } } - } - return IVAS_ERR_OK; -} + return IVAS_ERR_OK; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_VoIP_GetSamples( ) - * - * Main function to decode one frame in VoIP - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * IVAS_DEC_VoIP_GetSamples( ) + * + * Main function to decode one frame in VoIP + *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_VoIP_GetSamples( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ - const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ - void *pcmBuf, /* o : output synthesis signal */ + ivas_error IVAS_DEC_VoIP_GetSamples( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ #ifdef SUPPORT_JBM_TRACEFILE - JbmTraceFileWriterFn jbmWriterFn, - void *jbmWriter, + JbmTraceFileWriterFn jbmWriterFn, + void *jbmWriter, #endif - bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */ - uint16_t *nSamplesRendered, /* o : number of samples rendered */ - bool *parametersAvailableForEditing, /* o : indicates whether objects editing is available */ - const uint32_t systemTimestamp_ms /* i : current system timestamp */ -) -{ - return ivas_dec_voip_get_samples_common( - hIvasDec, - nSamplesPerChannel, - pcmType, - pcmBuf, - NULL, - NULL, + bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */ + uint16_t *nSamplesRendered, /* o : number of samples rendered */ + bool *parametersAvailableForEditing, /* o : indicates whether objects editing is available */ + const uint32_t systemTimestamp_ms /* i : current system timestamp */ + ) + { + return ivas_dec_voip_get_samples_common( + hIvasDec, + nSamplesPerChannel, + pcmType, + pcmBuf, + NULL, + NULL, #ifdef SUPPORT_JBM_TRACEFILE - jbmWriterFn, - jbmWriter, + jbmWriterFn, + jbmWriter, #endif - bitstreamReadDone, - nSamplesRendered, - parametersAvailableForEditing, - systemTimestamp_ms ); -} + bitstreamReadDone, + nSamplesRendered, + parametersAvailableForEditing, + systemTimestamp_ms ); + } -/*---------------------------------------------------------------------* - * IVAS_DEC_VoIP_GetSplitBinauralBitstream( ) - * - * Main function to decode one split-rendering frame in VoIP - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * IVAS_DEC_VoIP_GetSplitBinauralBitstream( ) + * + * Main function to decode one split-rendering frame in VoIP + *---------------------------------------------------------------------*/ -/*! r: error code */ -ivas_error IVAS_DEC_VoIP_GetSplitBinauralBitstream( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - /* const IVAS_DEC_PCM_TYPE pcmType, */ /* i : type for the decoded PCM resolution */ - void *pcmBuf, /* o : output synthesis signal */ - ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */ + /*! r: error code */ + ivas_error IVAS_DEC_VoIP_GetSplitBinauralBitstream( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + /* const IVAS_DEC_PCM_TYPE pcmType, */ /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */ #ifdef SUPPORT_JBM_TRACEFILE - JbmTraceFileWriterFn jbmWriterFn, - void *jbmWriter, + JbmTraceFileWriterFn jbmWriterFn, + void *jbmWriter, #endif - bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */ - uint16_t *nSamplesRendered, /* o : number of samples rendered */ - bool *parametersAvailableForEditing, /* o : indicates whether objects editing is available */ - const uint32_t systemTimestamp_ms /* i : current system timestamp */ -) -{ - int16_t i; - float head_pose_buf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES][L_FRAME48k]; - float *pp_head_pose_buf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES]; - ivas_error error = IVAS_ERR_UNKNOWN; - int16_t nSamplesPerChannel = 0; - - if ( ( error = IVAS_DEC_GetRenderFramesizeSamples( hIvasDec, &nSamplesPerChannel ) ) != IVAS_ERR_OK ) + bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */ + uint16_t *nSamplesRendered, /* o : number of samples rendered */ + bool *parametersAvailableForEditing, /* o : indicates whether objects editing is available */ + const uint32_t systemTimestamp_ms /* i : current system timestamp */ + ) { - return error; - } + int16_t i; + float head_pose_buf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES][L_FRAME48k]; + float *pp_head_pose_buf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES]; + ivas_error error = IVAS_ERR_UNKNOWN; + int16_t nSamplesPerChannel = 0; - /* Set pointers to beginning of head pose buffers */ - for ( i = 0; i < BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES; ++i ) - { - pp_head_pose_buf[i] = head_pose_buf[i]; - } + if ( ( error = IVAS_DEC_GetRenderFramesizeSamples( hIvasDec, &nSamplesPerChannel ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Set pointers to beginning of head pose buffers */ + for ( i = 0; i < BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES; ++i ) + { + pp_head_pose_buf[i] = head_pose_buf[i]; + } - return ivas_dec_voip_get_samples_common( - hIvasDec, - nSamplesPerChannel, - IVAS_DEC_PCM_INT16, - pcmBuf, - splitRendBits, - pp_head_pose_buf, + return ivas_dec_voip_get_samples_common( + hIvasDec, + nSamplesPerChannel, + IVAS_DEC_PCM_INT16, + pcmBuf, + splitRendBits, + pp_head_pose_buf, #ifdef SUPPORT_JBM_TRACEFILE - jbmWriterFn, - jbmWriter, + jbmWriterFn, + jbmWriter, #endif - bitstreamReadDone, - nSamplesRendered, - parametersAvailableForEditing, - systemTimestamp_ms ); -} - - -/*---------------------------------------------------------------------* - * update_voip_rendered20ms( ) - * - * Update the number of samples that have been rendered since the last 20ms render border - *---------------------------------------------------------------------*/ + bitstreamReadDone, + nSamplesRendered, + parametersAvailableForEditing, + systemTimestamp_ms ); + } -static void update_voip_rendered20ms( - IVAS_DEC_HANDLE hIvasDec, - const int16_t nSamplesRendered ) -{ - int16_t nSamplesRenderedTotal; - nSamplesRenderedTotal = hIvasDec->hVoIP->nSamplesRendered20ms + nSamplesRendered; + /*---------------------------------------------------------------------* + * update_voip_rendered20ms( ) + * + * Update the number of samples that have been rendered since the last 20ms render border + *---------------------------------------------------------------------*/ - /* we have crossed a 20ms border, reset the time scaling done flag */ - if ( nSamplesRenderedTotal >= hIvasDec->nSamplesFrame ) + static void update_voip_rendered20ms( + IVAS_DEC_HANDLE hIvasDec, + const int16_t nSamplesRendered ) { - hIvasDec->timeScalingDone = 0; - } + int16_t nSamplesRenderedTotal; - hIvasDec->hVoIP->nSamplesRendered20ms = nSamplesRenderedTotal % hIvasDec->nSamplesFrame; + nSamplesRenderedTotal = hIvasDec->hVoIP->nSamplesRendered20ms + nSamplesRendered; - return; -} + /* we have crossed a 20ms border, reset the time scaling done flag */ + if ( nSamplesRenderedTotal >= hIvasDec->nSamplesFrame ) + { + hIvasDec->timeScalingDone = 0; + } + hIvasDec->hVoIP->nSamplesRendered20ms = nSamplesRenderedTotal % hIvasDec->nSamplesFrame; -/*---------------------------------------------------------------------* - * IVAS_DEC_VoIP_Flush( ) - * - * Function to flush remaining audio samples in VoIP - *---------------------------------------------------------------------*/ + return; + } -ivas_error IVAS_DEC_Flush( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const int16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ - const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ - void *pcmBuf, /* o : output synthesis signal */ - int16_t *nSamplesFlushed /* o : number of samples flushed */ -) -{ - ivas_error error; - uint16_t nSamplesToRender; - uint16_t nSamplesFlushedLocal; - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + /*---------------------------------------------------------------------* + * IVAS_DEC_VoIP_Flush( ) + * + * Function to flush remaining audio samples in VoIP + *---------------------------------------------------------------------*/ + + ivas_error IVAS_DEC_Flush( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ + int16_t *nSamplesFlushed /* o : number of samples flushed */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + ivas_error error; + uint16_t nSamplesToRender; + uint16_t nSamplesFlushedLocal; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } #ifdef TMP_1342_WORKAROUND_DEC_FLUSH_BROKEN_IN_SR - hIvasDec->st_ivas->flushing = 1; + hIvasDec->st_ivas->flushing = 1; #endif - *nSamplesFlushed = min( nSamplesPerChannel, hIvasDec->nSamplesAvailableNext ); + *nSamplesFlushed = min( nSamplesPerChannel, hIvasDec->nSamplesAvailableNext ); - nSamplesToRender = (uint16_t) *nSamplesFlushed; + nSamplesToRender = (uint16_t) *nSamplesFlushed; - /* render IVAS frames */ - error = IVAS_ERR_OK; - if ( nSamplesToRender > 0 && hIvasDec->st_ivas->ivas_format != MONO_FORMAT ) - { - error = ivas_dec_render( hIvasDec->st_ivas, nSamplesToRender, &nSamplesFlushedLocal, &hIvasDec->nSamplesAvailableNext, pcm_type_API_to_internal( pcmType ), pcmBuf ); - } - else - { - *nSamplesFlushed = 0; - } + /* render IVAS frames */ + error = IVAS_ERR_OK; + if ( nSamplesToRender > 0 && hIvasDec->st_ivas->ivas_format != MONO_FORMAT ) + { + error = ivas_dec_render( hIvasDec->st_ivas, nSamplesToRender, &nSamplesFlushedLocal, &hIvasDec->nSamplesAvailableNext, pcm_type_API_to_internal( pcmType ), pcmBuf ); + } + else + { + *nSamplesFlushed = 0; + } #ifdef TMP_1342_WORKAROUND_DEC_FLUSH_BROKEN_IN_SR - hIvasDec->st_ivas->flushing = 0; + hIvasDec->st_ivas->flushing = 0; #endif - return error; -} + return error; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_isRestartNeeded( ) - * - * - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * IVAS_DEC_isRestartNeeded( ) + * + * + *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_isRestartNeeded( - IVAS_DEC_HANDLE hIvasDec, /* i : IVAS decoder handle */ - bool *restartNeeded /* o : flag to signal decoder restart */ + ivas_error IVAS_DEC_isRestartNeeded( + IVAS_DEC_HANDLE hIvasDec, /* i : IVAS decoder handle */ + bool *restartNeeded /* o : flag to signal decoder restart */ -) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - *restartNeeded = hIvasDec->st_ivas->restartNeeded > 0; + *restartNeeded = hIvasDec->st_ivas->restartNeeded > 0; - return IVAS_ERR_OK; -} + return IVAS_ERR_OK; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_VoIP_IsEmpty( ) - * - * Returns 'true' if decoder has no data in VoIP jitter buffer - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * IVAS_DEC_VoIP_IsEmpty( ) + * + * Returns 'true' if decoder has no data in VoIP jitter buffer + *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_VoIP_IsEmpty( - IVAS_DEC_HANDLE hIvasDec, /* i : IVAS decoder handle */ - const int16_t nSamplesAsked, /* i : number of output samples asked */ - bool *isEmpty /* o : isEmpty flag */ -) -{ - if ( hIvasDec == NULL || hIvasDec->hVoIP == NULL ) + ivas_error IVAS_DEC_VoIP_IsEmpty( + IVAS_DEC_HANDLE hIvasDec, /* i : IVAS decoder handle */ + const int16_t nSamplesAsked, /* i : number of output samples asked */ + bool *isEmpty /* o : isEmpty flag */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + if ( hIvasDec == NULL || hIvasDec->hVoIP == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - *isEmpty = ( JB4_bufferedDataUnits( hIvasDec->hVoIP->hJBM ) == 0 ) && ( hIvasDec->nSamplesAvailableNext < nSamplesAsked ); + *isEmpty = ( JB4_bufferedDataUnits( hIvasDec->hVoIP->hJBM ) == 0 ) && ( hIvasDec->nSamplesAvailableNext < nSamplesAsked ); - return IVAS_ERR_OK; -} + return IVAS_ERR_OK; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_VoIP_Get_CA_offset( ) - * - * - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * IVAS_DEC_VoIP_Get_CA_offset( ) + * + * + *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_VoIP_Get_CA_offset( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t *optimum_offset, - int16_t *FEC_hi ) -{ - if ( hIvasDec == NULL || hIvasDec->hVoIP == NULL || hIvasDec->hVoIP->hJBM == NULL ) + ivas_error IVAS_DEC_VoIP_Get_CA_offset( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t * optimum_offset, + int16_t * FEC_hi ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - *optimum_offset = JB4_getFECoffset( hIvasDec->hVoIP->hJBM ); - *FEC_hi = JB4_FECoffset( hIvasDec->hVoIP->hJBM ); + if ( hIvasDec == NULL || hIvasDec->hVoIP == NULL || hIvasDec->hVoIP->hJBM == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - return IVAS_ERR_OK; -} + *optimum_offset = JB4_getFECoffset( hIvasDec->hVoIP->hJBM ); + *FEC_hi = JB4_FECoffset( hIvasDec->hVoIP->hJBM ); + return IVAS_ERR_OK; + } -/*---------------------------------------------------------------------* - * ivas_destroy_handle_VoIP( ) - * - * Deallocate VoIP handle - *---------------------------------------------------------------------*/ -static void ivas_destroy_handle_VoIP( - IVAS_DEC_VOIP *hVoIP /* i/o: VoIP decoder handle */ -) -{ - JB4_Destroy( &hVoIP->hJBM ); + /*---------------------------------------------------------------------* + * ivas_destroy_handle_VoIP( ) + * + * Deallocate VoIP handle + *---------------------------------------------------------------------*/ - if ( hVoIP->bs_conversion_buf != NULL ) + static void ivas_destroy_handle_VoIP( + IVAS_DEC_VOIP * hVoIP /* i/o: VoIP decoder handle */ + ) { + JB4_Destroy( &hVoIP->hJBM ); + + if ( hVoIP->bs_conversion_buf != NULL ) + { #define WMC_TOOL_SKIP - /* Bitstream conversion is not counted towards complexity and memory usage */ - free( hVoIP->bs_conversion_buf ); + /* Bitstream conversion is not counted towards complexity and memory usage */ + free( hVoIP->bs_conversion_buf ); #undef WMC_TOOL_SKIP - } + } - free( hVoIP ); + free( hVoIP ); - return; -} + return; + } #ifdef SUPPORT_JBM_TRACEFILE -/*---------------------------------------------------------------------* - * store_JbmData() - * - * Store JBM trace data entry - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * store_JbmData() + * + * Store JBM trace data entry + *---------------------------------------------------------------------*/ -static void store_JbmData( - IVAS_DEC_VOIP *hVoIP, - JB4_DATAUNIT_HANDLE dataUnit, - const uint32_t systemTimestamp_ms, - const uint16_t extBufferedSamples, - const int32_t output_Fs ) -{ - IVAS_JBM_TRACE_DATA *JbmTraceData; - - if ( hVoIP == NULL ) + static void store_JbmData( + IVAS_DEC_VOIP * hVoIP, + JB4_DATAUNIT_HANDLE dataUnit, + const uint32_t systemTimestamp_ms, + const uint16_t extBufferedSamples, + const int32_t output_Fs ) { - return; - } + IVAS_JBM_TRACE_DATA *JbmTraceData; - JbmTraceData = &hVoIP->JbmTraceData; + if ( hVoIP == NULL ) + { + return; + } - JbmTraceData->systemTimestamp_ms = systemTimestamp_ms; - JbmTraceData->extBufferedSamples = extBufferedSamples; - JbmTraceData->lastDecodedWasActive = hVoIP->lastDecodedWasActive; - JbmTraceData->output_Fs = output_Fs; - JbmTraceData->dataUnit_flag = dataUnit != NULL; - if ( dataUnit != NULL ) - { - JbmTraceData->sequenceNumber = dataUnit->sequenceNumber; - JbmTraceData->timeStamp = dataUnit->timeStamp; - JbmTraceData->rcvTime = dataUnit->rcvTime; - JbmTraceData->partial_frame = dataUnit->partial_frame; - JbmTraceData->partialCopyOffset = dataUnit->partialCopyOffset; - } + JbmTraceData = &hVoIP->JbmTraceData; - return; -} + JbmTraceData->systemTimestamp_ms = systemTimestamp_ms; + JbmTraceData->extBufferedSamples = extBufferedSamples; + JbmTraceData->lastDecodedWasActive = hVoIP->lastDecodedWasActive; + JbmTraceData->output_Fs = output_Fs; + JbmTraceData->dataUnit_flag = dataUnit != NULL; + if ( dataUnit != NULL ) + { + JbmTraceData->sequenceNumber = dataUnit->sequenceNumber; + JbmTraceData->timeStamp = dataUnit->timeStamp; + JbmTraceData->rcvTime = dataUnit->rcvTime; + JbmTraceData->partial_frame = dataUnit->partial_frame; + JbmTraceData->partialCopyOffset = dataUnit->partialCopyOffset; + } + + return; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_GetJbmData() - * - * - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * IVAS_DEC_GetJbmData() + * + * + *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_GetJbmData( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_JBM_TRACE_DATA *JbmTraceData /* o : JBM Trace data */ + ivas_error IVAS_DEC_GetJbmData( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_JBM_TRACE_DATA * JbmTraceData /* o : JBM Trace data */ -) -{ - if ( hIvasDec == NULL || hIvasDec->hVoIP == NULL || JbmTraceData == NULL ) + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + if ( hIvasDec == NULL || hIvasDec->hVoIP == NULL || JbmTraceData == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - *JbmTraceData = hIvasDec->hVoIP->JbmTraceData; + *JbmTraceData = hIvasDec->hVoIP->JbmTraceData; - return IVAS_ERR_OK; -} + return IVAS_ERR_OK; + } #endif -/*---------------------------------------------------------------------* - * IVAS_DEC_GetErrorMessage( ) - * - * Maps error codes to error description strings - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * IVAS_DEC_GetErrorMessage( ) + * + * Maps error codes to error description strings + *---------------------------------------------------------------------*/ -const char *IVAS_DEC_GetErrorMessage( - ivas_error error /* i : decoder error code enum */ -) -{ - return ivas_error_to_string( error ); -} + const char *IVAS_DEC_GetErrorMessage( + ivas_error error /* i : decoder error code enum */ + ) + { + return ivas_error_to_string( error ); + } -/*---------------------------------------------------------------------* - * printConfigInfo_dec( ) - * - * - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * printConfigInfo_dec( ) + * + * + *---------------------------------------------------------------------*/ -static ivas_error printConfigInfo_dec( - Decoder_Struct *st_ivas, - const int16_t bitstreamformat, - const bool Opt_VOIP, - const bool quietModeEnabled ) -{ - ivas_error error; - char config_str[200]; - AUDIO_CONFIG output_config; + static ivas_error printConfigInfo_dec( + Decoder_Struct * st_ivas, + const int16_t bitstreamformat, + const bool Opt_VOIP, + const bool quietModeEnabled ) + { + ivas_error error; + char config_str[200]; + AUDIO_CONFIG output_config; - /*-----------------------------------------------------------------* - * Print info on screen - *-----------------------------------------------------------------*/ + /*-----------------------------------------------------------------* + * Print info on screen + *-----------------------------------------------------------------*/ - fprintf( stdout, "\n" ); + fprintf( stdout, "\n" ); - /*-----------------------------------------------------------------* - * Print output sampling frequency - *-----------------------------------------------------------------*/ + /*-----------------------------------------------------------------* + * Print output sampling frequency + *-----------------------------------------------------------------*/ - fprintf( stdout, "Output sampling rate: %d Hz\n", st_ivas->hDecoderConfig->output_Fs ); + fprintf( stdout, "Output sampling rate: %d Hz\n", st_ivas->hDecoderConfig->output_Fs ); - /*-----------------------------------------------------------------* - * Print bitrate - *-----------------------------------------------------------------*/ + /*-----------------------------------------------------------------* + * Print bitrate + *-----------------------------------------------------------------*/ - if ( !quietModeEnabled ) - { - if ( !Opt_VOIP ) + if ( !quietModeEnabled ) { - fprintf( stdout, "Bitrate: %.2f kbps\n", (float) st_ivas->hDecoderConfig->ivas_total_brate / 1000 ); - - if ( st_ivas->hDecoderConfig->ivas_total_brate <= 0 ) + if ( !Opt_VOIP ) { - if ( bitstreamformat == G192 ) - { - fprintf( stdout, "Active Bitrate not identified in bitstream file \n" ); - } - else /* MIME */ + fprintf( stdout, "Bitrate: %.2f kbps\n", (float) st_ivas->hDecoderConfig->ivas_total_brate / 1000 ); + + if ( st_ivas->hDecoderConfig->ivas_total_brate <= 0 ) { - fprintf( stdout, "Active Bitrate not identified from first MIME frame \n" ); + if ( bitstreamformat == G192 ) + { + fprintf( stdout, "Active Bitrate not identified in bitstream file \n" ); + } + else /* MIME */ + { + fprintf( stdout, "Active Bitrate not identified from first MIME frame \n" ); + } } } } - } - /*-----------------------------------------------------------------* - * Print output configuration - *-----------------------------------------------------------------*/ + /*-----------------------------------------------------------------* + * Print output configuration + *-----------------------------------------------------------------*/ - if ( st_ivas->ivas_format == MONO_FORMAT ) - { - if ( st_ivas->hDecoderConfig->Opt_non_diegetic_pan ) - { - fprintf( stdout, "Output configuration: mono EVS bit-exact decoding to stereo\n" ); - fprintf( stdout, "Non-diegetic panning: %.2f\n", st_ivas->hDecoderConfig->non_diegetic_pan_gain * 90.f ); - } - else + if ( st_ivas->ivas_format == MONO_FORMAT ) { - output_config = st_ivas->hDecoderConfig->output_config; - if ( output_config != IVAS_AUDIO_CONFIG_MONO ) + if ( st_ivas->hDecoderConfig->Opt_non_diegetic_pan ) { - get_channel_config( output_config, &config_str[0] ); - fprintf( stdout, "Output configuration: mono EVS bit-exact decoding rendering to %s\n", config_str ); + fprintf( stdout, "Output configuration: mono EVS bit-exact decoding to stereo\n" ); + fprintf( stdout, "Non-diegetic panning: %.2f\n", st_ivas->hDecoderConfig->non_diegetic_pan_gain * 90.f ); } else { - fprintf( stdout, "Output configuration: mono EVS bit-exact decoding\n" ); + output_config = st_ivas->hDecoderConfig->output_config; + if ( output_config != IVAS_AUDIO_CONFIG_MONO ) + { + get_channel_config( output_config, &config_str[0] ); + fprintf( stdout, "Output configuration: mono EVS bit-exact decoding rendering to %s\n", config_str ); + } + else + { + fprintf( stdout, "Output configuration: mono EVS bit-exact decoding\n" ); + } } } - } - else - { - if ( !quietModeEnabled ) + else { - if ( st_ivas->ivas_format == STEREO_FORMAT ) + if ( !quietModeEnabled ) { - fprintf( stdout, "Input configuration: Stereo\n" ); - } - else if ( st_ivas->ivas_format == ISM_FORMAT ) - { - if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + if ( st_ivas->ivas_format == STEREO_FORMAT ) { - fprintf( stdout, "Input configuration: ISM (ParamISM): 2 transport channels\n" ); + fprintf( stdout, "Input configuration: Stereo\n" ); } - else + else if ( st_ivas->ivas_format == ISM_FORMAT ) + { + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { + fprintf( stdout, "Input configuration: ISM (ParamISM): 2 transport channels\n" ); + } + else + { + fprintf( stdout, "Input configuration: ISM: %d transport channel(s)\n", st_ivas->nchan_transport ); + } + } + else if ( st_ivas->ivas_format == SBA_FORMAT ) + { + fprintf( stdout, "Input configuration: Scene Based Audio, Ambisonic order %i%s, %d transport channel(s)\n", st_ivas->sba_order, st_ivas->sba_planar ? " (Planar)" : "", st_ivas->nchan_transport ); + } + else if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) { - fprintf( stdout, "Input configuration: ISM: %d transport channel(s)\n", st_ivas->nchan_transport ); + fprintf( stdout, "Input configuration: Combined Scene Based Audio, Ambisonic order %i, with %d Objects \n", st_ivas->sba_order, st_ivas->nchan_ism ); + } + else if ( st_ivas->ivas_format == MASA_FORMAT ) + { + fprintf( stdout, "Input configuration: MASA - %d channel(s)\n", st_ivas->nchan_transport ); + } + else if ( st_ivas->ivas_format == MC_FORMAT ) + { + if ( ( error = get_channel_config( st_ivas->transport_config, &config_str[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + + fprintf( stdout, "Input configuration: %s\n", config_str ); + } + else if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) + { + fprintf( stdout, "Input configuration: combined ISM and MASA (%i ISM stream(s)) \n", st_ivas->nchan_ism ); } } - else if ( st_ivas->ivas_format == SBA_FORMAT ) + + output_config = st_ivas->hDecoderConfig->output_config; + get_channel_config( output_config, &config_str[0] ); + fprintf( stdout, "Output configuration: %s\n", config_str ); + + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - fprintf( stdout, "Input configuration: Scene Based Audio, Ambisonic order %i%s, %d transport channel(s)\n", st_ivas->sba_order, st_ivas->sba_planar ? " (Planar)" : "", st_ivas->nchan_transport ); + fprintf( stdout, "Render framesize: %d ms\n", get_render_frame_size_ms( st_ivas->hDecoderConfig->render_num_subframes ) ); } - else if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) + if ( st_ivas->hDecoderConfig->Opt_HRTF_binary ) { - fprintf( stdout, "Input configuration: Combined Scene Based Audio, Ambisonic order %i, with %d Objects \n", st_ivas->sba_order, st_ivas->nchan_ism ); + fprintf( stdout, "HRIR/BRIR file: ON\n" ); } - else if ( st_ivas->ivas_format == MASA_FORMAT ) + + if ( st_ivas->hDecoderConfig->Opt_RendConfigCustom ) { - fprintf( stdout, "Input configuration: MASA - %d channel(s)\n", st_ivas->nchan_transport ); + fprintf( stdout, "Renderer config. file: ON\n" ); } - else if ( st_ivas->ivas_format == MC_FORMAT ) - { - if ( ( error = get_channel_config( st_ivas->transport_config, &config_str[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - fprintf( stdout, "Input configuration: %s\n", config_str ); - } - else if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) + if ( st_ivas->hDecoderConfig->Opt_Headrotation ) { - fprintf( stdout, "Input configuration: combined ISM and MASA (%i ISM stream(s)) \n", st_ivas->nchan_ism ); + fprintf( stdout, "Head rotation: ON\n" ); } - } - - output_config = st_ivas->hDecoderConfig->output_config; - get_channel_config( output_config, &config_str[0] ); - fprintf( stdout, "Output configuration: %s\n", config_str ); - - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - fprintf( stdout, "Render framesize: %d ms\n", get_render_frame_size_ms( st_ivas->hDecoderConfig->render_num_subframes ) ); - } - if ( st_ivas->hDecoderConfig->Opt_HRTF_binary ) - { - fprintf( stdout, "HRIR/BRIR file: ON\n" ); - } - if ( st_ivas->hDecoderConfig->Opt_RendConfigCustom ) - { - fprintf( stdout, "Renderer config. file: ON\n" ); - } + if ( st_ivas->hDecoderConfig->Opt_ExternalOrientation ) + { + fprintf( stdout, "External orientation: ON\n" ); + } - if ( st_ivas->hDecoderConfig->Opt_Headrotation ) - { - fprintf( stdout, "Head rotation: ON\n" ); - } + if ( st_ivas->hDecoderConfig->orientation_tracking != IVAS_HEAD_ORIENT_TRK_NONE ) + { + switch ( st_ivas->hDecoderConfig->orientation_tracking ) + { + case IVAS_HEAD_ORIENT_TRK_AVG: + fprintf( stdout, "Orientation tracking: AVG\n" ); + break; + case IVAS_HEAD_ORIENT_TRK_REF: + fprintf( stdout, "Orientation tracking: REF\n" ); + break; + case IVAS_HEAD_ORIENT_TRK_REF_VEC: + fprintf( stdout, "Orientation tracking: REF_VEC\n" ); + break; + case IVAS_HEAD_ORIENT_TRK_REF_VEC_LEV: + fprintf( stdout, "Orientation tracking: REF_VEC_LEV\n" ); + break; + default: + break; + } + } - if ( st_ivas->hDecoderConfig->Opt_ExternalOrientation ) - { - fprintf( stdout, "External orientation: ON\n" ); - } + if ( st_ivas->hDecoderConfig->Opt_non_diegetic_pan ) + { + fprintf( stdout, "Non-diegetic panning: %.2f\n", st_ivas->hDecoderConfig->non_diegetic_pan_gain * 90.f ); + } - if ( st_ivas->hDecoderConfig->orientation_tracking != IVAS_HEAD_ORIENT_TRK_NONE ) - { - switch ( st_ivas->hDecoderConfig->orientation_tracking ) + if ( st_ivas->hDecoderConfig->Opt_dpid_on ) { - case IVAS_HEAD_ORIENT_TRK_AVG: - fprintf( stdout, "Orientation tracking: AVG\n" ); - break; - case IVAS_HEAD_ORIENT_TRK_REF: - fprintf( stdout, "Orientation tracking: REF\n" ); - break; - case IVAS_HEAD_ORIENT_TRK_REF_VEC: - fprintf( stdout, "Orientation tracking: REF_VEC\n" ); - break; - case IVAS_HEAD_ORIENT_TRK_REF_VEC_LEV: - fprintf( stdout, "Orientation tracking: REF_VEC_LEV\n" ); - break; - default: - break; + fprintf( stdout, "Directivity pattern: ON\n" ); } - } - if ( st_ivas->hDecoderConfig->Opt_non_diegetic_pan ) - { - fprintf( stdout, "Non-diegetic panning: %.2f\n", st_ivas->hDecoderConfig->non_diegetic_pan_gain * 90.f ); - } + if ( st_ivas->hDecoderConfig->Opt_aeid_on ) + { + fprintf( stdout, "Acoustic environment ID:ON\n" ); + } - if ( st_ivas->hDecoderConfig->Opt_dpid_on ) - { - fprintf( stdout, "Directivity pattern: ON\n" ); + if ( st_ivas->hDecoderConfig->Opt_ObjEdit_on ) + { + fprintf( stdout, "Objects editing : ON\n" ); + } } - if ( st_ivas->hDecoderConfig->Opt_aeid_on ) - { - fprintf( stdout, "Acoustic environment ID:ON\n" ); - } + /*-----------------------------------------------------------------* + * Print TSM mode info + *-----------------------------------------------------------------*/ - if ( st_ivas->hDecoderConfig->Opt_ObjEdit_on ) + if ( st_ivas->hDecoderConfig->Opt_tsm ) { - fprintf( stdout, "Objects editing : ON\n" ); + fprintf( stdout, "TSM mode: ON\n" ); } - } - - /*-----------------------------------------------------------------* - * Print TSM mode info - *-----------------------------------------------------------------*/ - if ( st_ivas->hDecoderConfig->Opt_tsm ) - { - fprintf( stdout, "TSM mode: ON\n" ); + return IVAS_ERR_OK; } - return IVAS_ERR_OK; -} - -/*---------------------------------------------------------------------* - * IVAS_DEC_PrintConfig( ) - * - * Print decoder set-up info - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * IVAS_DEC_PrintConfig( ) + * + * Print decoder set-up info + *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_PrintConfig( - const IVAS_DEC_HANDLE hIvasDec, - const bool quietModeEnabled, - const bool voipMode ) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + ivas_error IVAS_DEC_PrintConfig( + const IVAS_DEC_HANDLE hIvasDec, + const bool quietModeEnabled, + const bool voipMode ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - printConfigInfo_dec( hIvasDec->st_ivas, hIvasDec->bitstreamformat, voipMode, quietModeEnabled ); + printConfigInfo_dec( hIvasDec->st_ivas, hIvasDec->bitstreamformat, voipMode, quietModeEnabled ); - return IVAS_ERR_OK; -} + return IVAS_ERR_OK; + } #ifdef DEBUGGING @@ -4667,1080 +4703,1080 @@ ivas_error IVAS_DEC_PrintConfig( * *---------------------------------------------------------------------*/ #define WMC_TOOL_SKIP -void IVAS_DEC_PrintConfigWithBitstream( - IVAS_DEC_HANDLE hIvasDec, - const bool quietModeEnabled, - uint16_t bit_stream[], - const int16_t num_bits ) -{ - Decoder_Struct *st_ivas; + void IVAS_DEC_PrintConfigWithBitstream( + IVAS_DEC_HANDLE hIvasDec, + const bool quietModeEnabled, + uint16_t bit_stream[], + const int16_t num_bits ) + { + Decoder_Struct *st_ivas; - /* Create a copy of decoder struct that will be modified by preview_indices(), - * leaving the original decoder struct unchanged. The additional memory used here - * should not be counted towards memory footprint of the decoder. */ - st_ivas = malloc( sizeof( Decoder_Struct ) ); - memcpy( st_ivas, hIvasDec->st_ivas, sizeof( Decoder_Struct ) ); + /* Create a copy of decoder struct that will be modified by preview_indices(), + * leaving the original decoder struct unchanged. The additional memory used here + * should not be counted towards memory footprint of the decoder. */ + st_ivas = malloc( sizeof( Decoder_Struct ) ); + memcpy( st_ivas, hIvasDec->st_ivas, sizeof( Decoder_Struct ) ); - preview_indices( st_ivas, bit_stream, num_bits ); + preview_indices( st_ivas, bit_stream, num_bits ); - /* Print config from modified decoder struct */ - printConfigInfo_dec( st_ivas, hIvasDec->bitstreamformat, hIvasDec->Opt_VOIP, quietModeEnabled ); + /* Print config from modified decoder struct */ + printConfigInfo_dec( st_ivas, hIvasDec->bitstreamformat, hIvasDec->Opt_VOIP, quietModeEnabled ); - free( st_ivas ); + free( st_ivas ); - return; -} + return; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_PrintConfigWithVoipBitstream( ) - * - * - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * IVAS_DEC_PrintConfigWithVoipBitstream( ) + * + * + *---------------------------------------------------------------------*/ -void IVAS_DEC_PrintConfigWithVoipBitstream( - IVAS_DEC_HANDLE hIvasDec, - const bool quietModeEnabled, - uint8_t *au, - const uint16_t auSizeBits ) -{ - Decoder_Struct *st_ivas; - uint16_t bit_stream[MAX_BITS_PER_FRAME + 4 * 8]; + void IVAS_DEC_PrintConfigWithVoipBitstream( + IVAS_DEC_HANDLE hIvasDec, + const bool quietModeEnabled, + uint8_t *au, + const uint16_t auSizeBits ) + { + Decoder_Struct *st_ivas; + uint16_t bit_stream[MAX_BITS_PER_FRAME + 4 * 8]; - /* Create a copy of decoder struct that will be modified by preview_indices(), - * leaving the original decoder struct unchanged. The additional memory used here - * should not be counted towards memory footprint of the decoder. */ - st_ivas = malloc( sizeof( Decoder_Struct ) ); - memcpy( st_ivas, hIvasDec->st_ivas, sizeof( Decoder_Struct ) ); + /* Create a copy of decoder struct that will be modified by preview_indices(), + * leaving the original decoder struct unchanged. The additional memory used here + * should not be counted towards memory footprint of the decoder. */ + st_ivas = malloc( sizeof( Decoder_Struct ) ); + memcpy( st_ivas, hIvasDec->st_ivas, sizeof( Decoder_Struct ) ); - bsCompactToSerial( au, bit_stream, auSizeBits ); - preview_indices( st_ivas, bit_stream, auSizeBits ); + bsCompactToSerial( au, bit_stream, auSizeBits ); + preview_indices( st_ivas, bit_stream, auSizeBits ); - /* Print config from modified decoder struct */ - printConfigInfo_dec( st_ivas, hIvasDec->bitstreamformat, hIvasDec->Opt_VOIP, quietModeEnabled ); + /* Print config from modified decoder struct */ + printConfigInfo_dec( st_ivas, hIvasDec->bitstreamformat, hIvasDec->Opt_VOIP, quietModeEnabled ); - free( st_ivas ); + free( st_ivas ); - return; -} + return; + } #undef WMC_TOOL_SKIP #endif -/*---------------------------------------------------------------------* - * IVAS_DEC_PrintDisclaimer( ) - * - * Print IVAS disclaimer to console - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * IVAS_DEC_PrintDisclaimer( ) + * + * Print IVAS disclaimer to console + *---------------------------------------------------------------------*/ -void IVAS_DEC_PrintDisclaimer( void ) -{ - print_disclaimer( stderr ); + void IVAS_DEC_PrintDisclaimer( void ) + { + print_disclaimer( stderr ); - return; -} + return; + } -/*---------------------------------------------------------------------* - * evs_dec_main( ) - * - * EVS codec main decoder fucntion - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * evs_dec_main( ) + * + * EVS codec main decoder fucntion + *---------------------------------------------------------------------*/ -static ivas_error evs_dec_main( - Decoder_Struct *st_ivas /* i : IVAS decoder structure */ -) -{ - DEC_CORE_HANDLE *hCoreCoder; - float *p_output[1]; - int16_t nOutSamples; - ivas_error error; + static ivas_error evs_dec_main( + Decoder_Struct * st_ivas /* i : IVAS decoder structure */ + ) + { + DEC_CORE_HANDLE *hCoreCoder; + float *p_output[1]; + int16_t nOutSamples; + ivas_error error; - hCoreCoder = st_ivas->hSCE[0]->hCoreCoder; - hCoreCoder[0]->total_brate = st_ivas->hDecoderConfig->ivas_total_brate; - nOutSamples = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); + hCoreCoder = st_ivas->hSCE[0]->hCoreCoder; + hCoreCoder[0]->total_brate = st_ivas->hDecoderConfig->ivas_total_brate; + nOutSamples = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); - mdct_switching_dec( hCoreCoder[0] ); + mdct_switching_dec( hCoreCoder[0] ); - p_output[0] = st_ivas->p_output_f[0]; + p_output[0] = st_ivas->p_output_f[0]; - /* run the main EVS decoding routine */ - if ( hCoreCoder[0]->codec_mode == MODE1 ) - { - if ( hCoreCoder[0]->Opt_AMR_WB ) + /* run the main EVS decoding routine */ + if ( hCoreCoder[0]->codec_mode == MODE1 ) { - if ( ( error = amr_wb_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0] ) ) != IVAS_ERR_OK ) + if ( hCoreCoder[0]->Opt_AMR_WB ) { - return error; + if ( ( error = amr_wb_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0] ) ) != IVAS_ERR_OK ) + { + return error; + } } - } - else - { - if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_NORMAL ) ) != IVAS_ERR_OK ) + else { - return error; + if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_NORMAL ) ) != IVAS_ERR_OK ) + { + return error; + } } } - } - else - { - if ( hCoreCoder[0]->bfi == 0 ) + else { - if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_NORMAL ) ) != IVAS_ERR_OK ) + if ( hCoreCoder[0]->bfi == 0 ) { - return error; + if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_NORMAL ) ) != IVAS_ERR_OK ) + { + return error; + } } - } - else if ( hCoreCoder[0]->bfi == 2 ) - { - if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_FUTURE ) ) != IVAS_ERR_OK ) + else if ( hCoreCoder[0]->bfi == 2 ) { - return error; + if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_FUTURE ) ) != IVAS_ERR_OK ) + { + return error; + } } - } - else - { - if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_MISSING ) ) != IVAS_ERR_OK ) + else { - return error; + if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_MISSING ) ) != IVAS_ERR_OK ) + { + return error; + } } } - } - st_ivas->BER_detect = hCoreCoder[0]->BER_detect; + st_ivas->BER_detect = hCoreCoder[0]->BER_detect; - if ( st_ivas->hDecoderConfig->Opt_tsm && st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_MONO ) - { - /* BE workaround: in order to keep EVS bit-exact wrt. TS 26.443, convert 'float' output data to 'short' before the TSM */ - int16_t pcm_buf_local[L_FRAME48k]; + if ( st_ivas->hDecoderConfig->Opt_tsm && st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_MONO ) + { + /* BE workaround: in order to keep EVS bit-exact wrt. TS 26.443, convert 'float' output data to 'short' before the TSM */ + int16_t pcm_buf_local[L_FRAME48k]; #ifdef DEBUGGING - st_ivas->noClipping += + st_ivas->noClipping += #endif - ivas_syn_output( &p_output[0], nOutSamples, 1, pcm_buf_local ); - mvs2r( pcm_buf_local, p_output[0], nOutSamples ); - } + ivas_syn_output( &p_output[0], nOutSamples, 1, pcm_buf_local ); + mvs2r( pcm_buf_local, p_output[0], nOutSamples ); + } - return IVAS_ERR_OK; -} + return IVAS_ERR_OK; + } #ifdef DEBUGGING -/*---------------------------------------------------------------------* - * IVAS_DEC_GetBer_detect_flag() - * - * return BER_detect flag - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * IVAS_DEC_GetBer_detect_flag() + * + * return BER_detect flag + *---------------------------------------------------------------------*/ -bool IVAS_DEC_GetBerDetectFlag( - IVAS_DEC_HANDLE hIvasDec /* i : IVAS decoder handle */ -) -{ - if ( hIvasDec->st_ivas->BER_detect == 1 ) - { - return 1; - } - else + bool IVAS_DEC_GetBerDetectFlag( + IVAS_DEC_HANDLE hIvasDec /* i : IVAS decoder handle */ + ) { - return 0; + if ( hIvasDec->st_ivas->BER_detect == 1 ) + { + return 1; + } + else + { + return 0; + } } -} -/*---------------------------------------------------------------------* - * IVAS_DEC_GetNoCLipping() - * - * return number of clipped samples - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * IVAS_DEC_GetNoCLipping() + * + * return number of clipped samples + *---------------------------------------------------------------------*/ -int32_t IVAS_DEC_GetNoCLipping( - IVAS_DEC_HANDLE hIvasDec /* i : IVAS decoder handle */ -) -{ - return hIvasDec->st_ivas->noClipping; -} + int32_t IVAS_DEC_GetNoCLipping( + IVAS_DEC_HANDLE hIvasDec /* i : IVAS decoder handle */ + ) + { + return hIvasDec->st_ivas->noClipping; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_GetCntFramesLimited() - * - * return number of frames where limiter is applied - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * IVAS_DEC_GetCntFramesLimited() + * + * return number of frames where limiter is applied + *---------------------------------------------------------------------*/ -int32_t IVAS_DEC_GetCntFramesLimited( - IVAS_DEC_HANDLE hIvasDec /* i : IVAS decoder handle */ -) -{ - if ( hIvasDec->st_ivas->hLimiter == NULL ) - { - return 0; - } - else + int32_t IVAS_DEC_GetCntFramesLimited( + IVAS_DEC_HANDLE hIvasDec /* i : IVAS decoder handle */ + ) { - return hIvasDec->st_ivas->hLimiter->cnt_frames_limited; + if ( hIvasDec->st_ivas->hLimiter == NULL ) + { + return 0; + } + else + { + return hIvasDec->st_ivas->hLimiter->cnt_frames_limited; + } } -} #ifdef DEBUG_SBA_AUDIO_DUMP -/*---------------------------------------------------------------------* - * IVAS_DEC_GetSbaDebugParams( ) - * - * Returns SBA debug parameters - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * IVAS_DEC_GetSbaDebugParams( ) + * + * Returns SBA debug parameters + *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_GetSbaDebugParams( - const IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t *numOutputChannels, - int16_t *numTransportChannels, - int16_t *pca_ingest_channels ) -{ - if ( hIvasDec->st_ivas == NULL ) + ivas_error IVAS_DEC_GetSbaDebugParams( + const IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *numOutputChannels, + int16_t *numTransportChannels, + int16_t *pca_ingest_channels ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + if ( hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( hIvasDec->st_ivas->ivas_format != SBA_FORMAT || hIvasDec->st_ivas->hSpar == NULL ) - { - *numOutputChannels = 1; - *numTransportChannels = 1; - *pca_ingest_channels = 1; - } - else - { - *numOutputChannels = hIvasDec->st_ivas->hSpar->numOutChannels; - *numTransportChannels = hIvasDec->st_ivas->nchan_transport; - *pca_ingest_channels = hIvasDec->st_ivas->hSpar->pca_ingest_channels; - } + if ( hIvasDec->st_ivas->ivas_format != SBA_FORMAT || hIvasDec->st_ivas->hSpar == NULL ) + { + *numOutputChannels = 1; + *numTransportChannels = 1; + *pca_ingest_channels = 1; + } + else + { + *numOutputChannels = hIvasDec->st_ivas->hSpar->numOutChannels; + *numTransportChannels = hIvasDec->st_ivas->nchan_transport; + *pca_ingest_channels = hIvasDec->st_ivas->hSpar->pca_ingest_channels; + } - return IVAS_ERR_OK; -} + return IVAS_ERR_OK; + } #endif /* DEBUG_SBA_AUDIO_DUMP */ #endif /* DEBUGGING */ -/*---------------------------------------------------------------------* - * input_format_API_to_internal() - * - * - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * input_format_API_to_internal() + * + * + *---------------------------------------------------------------------*/ + + static ivas_error input_format_API_to_internal( + IVAS_DEC_INPUT_FORMAT input_format, + int16_t * bitstream_format_internal, + int16_t * sdp_hf_only, + const bool is_voip_enabled ) + { + switch ( input_format ) + { + case IVAS_DEC_INPUT_FORMAT_G192: + *bitstream_format_internal = is_voip_enabled ? VOIP_G192_RTP : G192; + *sdp_hf_only = 0; + break; + case IVAS_DEC_INPUT_FORMAT_MIME: + *bitstream_format_internal = MIME; + *sdp_hf_only = 0; + break; + case IVAS_DEC_INPUT_FORMAT_RTPDUMP: + assert( is_voip_enabled && "RTP dump only supported in VoIP mode" ); + *bitstream_format_internal = VOIP_RTPDUMP; + *sdp_hf_only = 0; + break; + case IVAS_DEC_INPUT_FORMAT_RTPDUMP_HF: + assert( is_voip_enabled && "RTP dump only supported in VoIP mode" ); + *bitstream_format_internal = VOIP_RTPDUMP; + *sdp_hf_only = 1; + break; + default: + return IVAS_ERR_INVALID_BITSTREAM; + break; + } -static ivas_error input_format_API_to_internal( - IVAS_DEC_INPUT_FORMAT input_format, - int16_t *bitstream_format_internal, - int16_t *sdp_hf_only, - const bool is_voip_enabled ) -{ - switch ( input_format ) - { - case IVAS_DEC_INPUT_FORMAT_G192: - *bitstream_format_internal = is_voip_enabled ? VOIP_G192_RTP : G192; - *sdp_hf_only = 0; - break; - case IVAS_DEC_INPUT_FORMAT_MIME: - *bitstream_format_internal = MIME; - *sdp_hf_only = 0; - break; - case IVAS_DEC_INPUT_FORMAT_RTPDUMP: - assert( is_voip_enabled && "RTP dump only supported in VoIP mode" ); - *bitstream_format_internal = VOIP_RTPDUMP; - *sdp_hf_only = 0; - break; - case IVAS_DEC_INPUT_FORMAT_RTPDUMP_HF: - assert( is_voip_enabled && "RTP dump only supported in VoIP mode" ); - *bitstream_format_internal = VOIP_RTPDUMP; - *sdp_hf_only = 1; - break; - default: - return IVAS_ERR_INVALID_BITSTREAM; - break; + return IVAS_ERR_OK; } - return IVAS_ERR_OK; -} - - -/*---------------------------------------------------------------------* - * apa_setup() - * - * Setup APA decoder - *---------------------------------------------------------------------*/ - -static ivas_error apa_setup( - IVAS_DEC_HANDLE hIvasDec, - const bool isInitialized_voip, - const uint16_t nTransportChannels ) -{ - uint16_t l_ts; - l_ts = (uint16_t) hIvasDec->st_ivas->hTcBuffer->n_samples_granularity; + /*---------------------------------------------------------------------* + * apa_setup() + * + * Setup APA decoder + *---------------------------------------------------------------------*/ - if ( !isInitialized_voip ) + static ivas_error apa_setup( + IVAS_DEC_HANDLE hIvasDec, + const bool isInitialized_voip, + const uint16_t nTransportChannels ) { - DECODER_CONFIG_HANDLE hDecoderConfig; - uint16_t wss, css; - float startQuality; + uint16_t l_ts; - startQuality = hIvasDec->tsm_quality; - hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; + l_ts = (uint16_t) hIvasDec->st_ivas->hTcBuffer->n_samples_granularity; - if ( hDecoderConfig->output_Fs == 8000 ) - { - wss = 1; - css = 1; - } - else if ( hDecoderConfig->output_Fs == 16000 ) - { - wss = 2; - css = 1; - } - else if ( hDecoderConfig->output_Fs == 32000 ) - { - wss = 4; - css = 2; - } - else if ( hDecoderConfig->output_Fs == 48000 ) - { - wss = 6; - css = 3; - } - else + if ( !isInitialized_voip ) { - return IVAS_ERR_INIT_ERROR; - } + DECODER_CONFIG_HANDLE hDecoderConfig; + uint16_t wss, css; + float startQuality; - if ( apa_init( &hIvasDec->hTimeScaler, nTransportChannels ) != IVAS_ERR_OK || - apa_set_rate( hIvasDec->hTimeScaler, hDecoderConfig->output_Fs ) != 0 || - apa_set_complexity_options( hIvasDec->hTimeScaler, wss, css ) != 0 || - apa_set_quality( hIvasDec->hTimeScaler, startQuality, 4, 4 ) != 0 || - apa_set_renderer_granularity( hIvasDec->hTimeScaler, l_ts ) != 0 ) - { - return IVAS_ERR_INIT_ERROR; - } + startQuality = hIvasDec->tsm_quality; + hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) - { - if ( apa_set_evs_compat_mode( hIvasDec->hTimeScaler, true ) != 0 ) + if ( hDecoderConfig->output_Fs == 8000 ) + { + wss = 1; + css = 1; + } + else if ( hDecoderConfig->output_Fs == 16000 ) + { + wss = 2; + css = 1; + } + else if ( hDecoderConfig->output_Fs == 32000 ) + { + wss = 4; + css = 2; + } + else if ( hDecoderConfig->output_Fs == 48000 ) + { + wss = 6; + css = 3; + } + else + { + return IVAS_ERR_INIT_ERROR; + } + + if ( apa_init( &hIvasDec->hTimeScaler, nTransportChannels ) != IVAS_ERR_OK || + apa_set_rate( hIvasDec->hTimeScaler, hDecoderConfig->output_Fs ) != 0 || + apa_set_complexity_options( hIvasDec->hTimeScaler, wss, css ) != 0 || + apa_set_quality( hIvasDec->hTimeScaler, startQuality, 4, 4 ) != 0 || + apa_set_renderer_granularity( hIvasDec->hTimeScaler, l_ts ) != 0 ) { return IVAS_ERR_INIT_ERROR; } + + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + { + if ( apa_set_evs_compat_mode( hIvasDec->hTimeScaler, true ) != 0 ) + { + return IVAS_ERR_INIT_ERROR; + } + } } - } - else - { - if ( apa_reconfigure( hIvasDec->hTimeScaler, nTransportChannels, l_ts ) != 0 ) + else { - return IVAS_ERR_INIT_ERROR; + if ( apa_reconfigure( hIvasDec->hTimeScaler, nTransportChannels, l_ts ) != 0 ) + { + return IVAS_ERR_INIT_ERROR; + } } - } - hIvasDec->nTransportChannelsOld = nTransportChannels; + hIvasDec->nTransportChannelsOld = nTransportChannels; - return IVAS_ERR_OK; -} + return IVAS_ERR_OK; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_GetSplitRendBitstreamHeader() - * - * - *---------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * IVAS_DEC_GetSplitRendBitstreamHeader() + * + * + *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_GetSplitRendBitstreamHeader( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - ISAR_SPLIT_REND_CODEC *pCodec, /* o : pointer to codec setting */ - ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o : pointer to pose correction mode */ - int16_t *pIsar_frame_size_ms, /* o : pointer to ISAR frame size setting */ - int16_t *pCodec_frame_size_ms, /* o : pointer to codec frame size setting */ - int16_t *pLc3plusHighRes /* o : pointer to LC3plus High-Res setting */ -) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + ivas_error IVAS_DEC_GetSplitRendBitstreamHeader( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + ISAR_SPLIT_REND_CODEC * pCodec, /* o : pointer to codec setting */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE * poseCorrection, /* o : pointer to pose correction mode */ + int16_t * pIsar_frame_size_ms, /* o : pointer to ISAR frame size setting */ + int16_t * pCodec_frame_size_ms, /* o : pointer to codec frame size setting */ + int16_t * pLc3plusHighRes /* o : pointer to LC3plus High-Res setting */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - *pCodec = hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec; - *pCodec_frame_size_ms = hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms; - *poseCorrection = hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode; - *pIsar_frame_size_ms = hIvasDec->st_ivas->hRenderConfig->split_rend_config.isar_frame_size_ms; - *pLc3plusHighRes = hIvasDec->st_ivas->hRenderConfig->split_rend_config.lc3plus_highres; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - return IVAS_ERR_OK; -} + *pCodec = hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec; + *pCodec_frame_size_ms = hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms; + *poseCorrection = hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode; + *pIsar_frame_size_ms = hIvasDec->st_ivas->hRenderConfig->split_rend_config.isar_frame_size_ms; + *pLc3plusHighRes = hIvasDec->st_ivas->hRenderConfig->split_rend_config.lc3plus_highres; + return IVAS_ERR_OK; + } -/*---------------------------------------------------------------------* - * IVAS_DEC_GetCldfbSamples() - * - * API function to output CLDFB samples - *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_GetCldfbSamples( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - float *out_real, /* o : buffer for decoded PCM real output in CLDFB domain */ - float *out_imag, /* o : buffer for decoded PCM imag output in CLDFB domain */ - AUDIO_CONFIG *audio_config, /* o : audio configuration */ - int16_t *nOutSamples /* o : number of samples per channel written to output buffer */ -) -{ - ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; - int16_t ch, b, slot_idx, num_chs, maxBand, num_samples; + /*---------------------------------------------------------------------* + * IVAS_DEC_GetCldfbSamples() + * + * API function to output CLDFB samples + *---------------------------------------------------------------------*/ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hSplitBinRend == NULL ) + ivas_error IVAS_DEC_GetCldfbSamples( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + float *out_real, /* o : buffer for decoded PCM real output in CLDFB domain */ + float *out_imag, /* o : buffer for decoded PCM imag output in CLDFB domain */ + AUDIO_CONFIG *audio_config, /* o : audio configuration */ + int16_t *nOutSamples /* o : number of samples per channel written to output buffer */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - hSplitBinRend = hIvasDec->st_ivas->hSplitBinRend; - num_samples = 0; + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; + int16_t ch, b, slot_idx, num_chs, maxBand, num_samples; - if ( hSplitBinRend->hCldfbDataOut != NULL ) - { - *audio_config = hSplitBinRend->hCldfbDataOut->config; - if ( hSplitBinRend->hCldfbDataOut->config != IVAS_AUDIO_CONFIG_INVALID ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hSplitBinRend == NULL ) { - num_chs = audioCfg2channels( hSplitBinRend->hCldfbDataOut->config ); - maxBand = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * hIvasDec->st_ivas->hDecoderConfig->output_Fs ) / 48000 ); + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) + hSplitBinRend = hIvasDec->st_ivas->hSplitBinRend; + num_samples = 0; + + if ( hSplitBinRend->hCldfbDataOut != NULL ) + { + *audio_config = hSplitBinRend->hCldfbDataOut->config; + if ( hSplitBinRend->hCldfbDataOut->config != IVAS_AUDIO_CONFIG_INVALID ) { - for ( b = 0; b < maxBand; b++ ) + num_chs = audioCfg2channels( hSplitBinRend->hCldfbDataOut->config ); + maxBand = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * hIvasDec->st_ivas->hDecoderConfig->output_Fs ) / 48000 ); + + for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) { - for ( ch = 0; ch < num_chs; ch++ ) + for ( b = 0; b < maxBand; b++ ) { - *out_real++ = hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx][b]; - *out_imag++ = hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx][b]; + for ( ch = 0; ch < num_chs; ch++ ) + { + *out_real++ = hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx][b]; + *out_imag++ = hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx][b]; + } } } + num_samples = CLDFB_NO_COL_MAX * maxBand; } - num_samples = CLDFB_NO_COL_MAX * maxBand; - } - } - else - { - *audio_config = IVAS_AUDIO_CONFIG_INVALID; - } - - *nOutSamples = num_samples; - - return IVAS_ERR_OK; -} - - -/*---------------------------------------------------------------------* - * pcm_buffer_offset() - * - * - *---------------------------------------------------------------------*/ - -static void *pcm_buffer_offset( - void *buffer, - const IVAS_DEC_PCM_TYPE pcmType, - const int32_t offset ) -{ - switch ( pcmType ) - { - case IVAS_DEC_PCM_FLOAT: - { - float *tmpBuf = (float *) buffer; - return (void *) ( tmpBuf + offset ); } - break; - case IVAS_DEC_PCM_INT16: + else { - int16_t *tmpBuf = (int16_t *) buffer; - return (void *) ( tmpBuf + offset ); + *audio_config = IVAS_AUDIO_CONFIG_INVALID; } - break; - default: - break; - } - return NULL; -} + *nOutSamples = num_samples; + return IVAS_ERR_OK; + } -/*---------------------------------------------------------------------* - * set_pcm_buffer_to_zero() - * - * - *---------------------------------------------------------------------*/ -static ivas_error set_pcm_buffer_to_zero( - void *buffer, - const IVAS_DEC_PCM_TYPE pcmType, - const int16_t nZeroSamples ) -{ - ivas_error error; + /*---------------------------------------------------------------------* + * pcm_buffer_offset() + * + * + *---------------------------------------------------------------------*/ - error = IVAS_ERR_OK; - switch ( pcmType ) + static void *pcm_buffer_offset( + void *buffer, + const IVAS_DEC_PCM_TYPE pcmType, + const int32_t offset ) { - case IVAS_DEC_PCM_FLOAT: - set_zero( (float *) buffer, nZeroSamples ); + switch ( pcmType ) + { + case IVAS_DEC_PCM_FLOAT: + { + float *tmpBuf = (float *) buffer; + return (void *) ( tmpBuf + offset ); + } break; - case IVAS_DEC_PCM_INT16: - set_s( (int16_t *) buffer, 0, nZeroSamples ); + case IVAS_DEC_PCM_INT16: + { + int16_t *tmpBuf = (int16_t *) buffer; + return (void *) ( tmpBuf + offset ); + } break; - default: - error = IVAS_ERR_INTERNAL; - } - - return error; -} + default: + break; + } + return NULL; + } -/*---------------------------------------------------------------------* - * pcm_type_API_to_internal() - * - * - *---------------------------------------------------------------------*/ -PCM_RESOLUTION pcm_type_API_to_internal( - const IVAS_DEC_PCM_TYPE pcmType ) -{ - PCM_RESOLUTION pcm_resolution; - pcm_resolution = PCM_NOT_KNOW; + /*---------------------------------------------------------------------* + * set_pcm_buffer_to_zero() + * + * + *---------------------------------------------------------------------*/ - switch ( pcmType ) + static ivas_error set_pcm_buffer_to_zero( + void *buffer, + const IVAS_DEC_PCM_TYPE pcmType, + const int16_t nZeroSamples ) { - case IVAS_DEC_PCM_FLOAT: - pcm_resolution = PCM_FLOAT32; - break; - case IVAS_DEC_PCM_INT16: - pcm_resolution = PCM_INT16; - break; - default: - pcm_resolution = PCM_NOT_KNOW; - } + ivas_error error; - return pcm_resolution; -} + error = IVAS_ERR_OK; + switch ( pcmType ) + { + case IVAS_DEC_PCM_FLOAT: + set_zero( (float *) buffer, nZeroSamples ); + break; + case IVAS_DEC_PCM_INT16: + set_s( (int16_t *) buffer, 0, nZeroSamples ); + break; + default: + error = IVAS_ERR_INTERNAL; + } + return error; + } -/*-------------------------------------------------------------------* - * ivas_create_handle_isar() - * - * Initialize IVAS decoder split-rendering handle - *-------------------------------------------------------------------*/ -static ivas_error ivas_create_handle_isar( - ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend_out /* o : ISAR split binaural rendering handle */ -) -{ - ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; - int16_t i; + /*---------------------------------------------------------------------* + * pcm_type_API_to_internal() + * + * + *---------------------------------------------------------------------*/ - if ( ( hSplitBinRend = (ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_WRAPPER ) ) ) == NULL ) + PCM_RESOLUTION pcm_type_API_to_internal( + const IVAS_DEC_PCM_TYPE pcmType ) { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS decoder handle" ); - } + PCM_RESOLUTION pcm_resolution; + pcm_resolution = PCM_NOT_KNOW; - isar_init_split_rend_handles( &hSplitBinRend->splitrend ); + switch ( pcmType ) + { + case IVAS_DEC_PCM_FLOAT: + pcm_resolution = PCM_FLOAT32; + break; + case IVAS_DEC_PCM_INT16: + pcm_resolution = PCM_INT16; + break; + default: + pcm_resolution = PCM_NOT_KNOW; + } - hSplitBinRend->hMultiBinTdData = NULL; - for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) - { - hSplitBinRend->hMultiBinCldfbData[i] = NULL; + return pcm_resolution; } - hSplitBinRend->hCldfbDataOut = NULL; - hSplitBinRend->numTdSamplesPerChannelCached = 0; - - *hSplitBinRend_out = hSplitBinRend; - - return IVAS_ERR_OK; -} - -/*-------------------------------------------------------------------* - * ivas_destroy_handle_isar() - * - * destroy IVAS decoder split rend handle - *-------------------------------------------------------------------*/ -static void ivas_destroy_handle_isar( - ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend /* i/o: ISAR split binaural rendering handle */ -) -{ - int16_t i; + /*-------------------------------------------------------------------* + * ivas_create_handle_isar() + * + * Initialize IVAS decoder split-rendering handle + *-------------------------------------------------------------------*/ - if ( *hSplitBinRend != NULL ) + static ivas_error ivas_create_handle_isar( + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE * hSplitBinRend_out /* o : ISAR split binaural rendering handle */ + ) { - if ( ( *hSplitBinRend )->hMultiBinTdData != NULL ) - { - ivas_TD_RINGBUF_Close( &( *hSplitBinRend )->hMultiBinTdData ); - } - for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; + int16_t i; + + if ( ( hSplitBinRend = (ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_WRAPPER ) ) ) == NULL ) { - if ( ( *hSplitBinRend )->hMultiBinCldfbData[i] != NULL ) - { - ivas_CLDFB_RINGBUF_Close( &( *hSplitBinRend )->hMultiBinCldfbData[i] ); - } + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS decoder handle" ); } - ISAR_PRE_REND_close( &( *hSplitBinRend )->splitrend, NULL ); + isar_init_split_rend_handles( &hSplitBinRend->splitrend ); - if ( ( *hSplitBinRend )->hCldfbDataOut != NULL ) + hSplitBinRend->hMultiBinTdData = NULL; + for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) { - free( ( *hSplitBinRend )->hCldfbDataOut ); - ( *hSplitBinRend )->hCldfbDataOut = NULL; + hSplitBinRend->hMultiBinCldfbData[i] = NULL; } + hSplitBinRend->hCldfbDataOut = NULL; + hSplitBinRend->numTdSamplesPerChannelCached = 0; - free( ( *hSplitBinRend ) ); - ( *hSplitBinRend ) = NULL; + *hSplitBinRend_out = hSplitBinRend; + + return IVAS_ERR_OK; } - return; -} + /*-------------------------------------------------------------------* + * ivas_destroy_handle_isar() + * + * destroy IVAS decoder split rend handle + *-------------------------------------------------------------------*/ -/*---------------------------------------------------------------------* - * IVAS_DEC_is_split_rendering_enabled() - * - * - *---------------------------------------------------------------------*/ + static void ivas_destroy_handle_isar( + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE * hSplitBinRend /* i/o: ISAR split binaural rendering handle */ + ) + { + int16_t i; -/*! r: decoder error code */ -ivas_error IVAS_DEC_is_split_rendering_enabled( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t *isSplitRend /* o : flag to indicate if split rendering is enabled */ -) -{ - Decoder_Struct *st_ivas; + if ( *hSplitBinRend != NULL ) + { + if ( ( *hSplitBinRend )->hMultiBinTdData != NULL ) + { + ivas_TD_RINGBUF_Close( &( *hSplitBinRend )->hMultiBinTdData ); + } + for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) + { + if ( ( *hSplitBinRend )->hMultiBinCldfbData[i] != NULL ) + { + ivas_CLDFB_RINGBUF_Close( &( *hSplitBinRend )->hMultiBinCldfbData[i] ); + } + } - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + ISAR_PRE_REND_close( &( *hSplitBinRend )->splitrend, NULL ); - st_ivas = hIvasDec->st_ivas; + if ( ( *hSplitBinRend )->hCldfbDataOut != NULL ) + { + free( ( *hSplitBinRend )->hCldfbDataOut ); + ( *hSplitBinRend )->hCldfbDataOut = NULL; + } - *isSplitRend = is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ); + free( ( *hSplitBinRend ) ); + ( *hSplitBinRend ) = NULL; + } - return IVAS_ERR_OK; -} + return; + } -/*-------------------------------------------------------------------* - * ivas_dec_reconfig_split_rend() - * - * IVAS decoder split rend reconfig - *-------------------------------------------------------------------*/ + /*---------------------------------------------------------------------* + * IVAS_DEC_is_split_rendering_enabled() + * + * + *---------------------------------------------------------------------*/ -static ivas_error ivas_dec_reconfig_split_rend( - Decoder_Struct *st_ivas /* i : IVAS decoder structure */ -) -{ - ivas_error error; - int16_t cldfb_in_flag, num_ch, ch, isCldfbNeeded, i, pcm_out_flag; - SPLIT_REND_WRAPPER *hSplitRendWrapper; - - hSplitRendWrapper = &st_ivas->hSplitBinRend->splitrend; - pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; - cldfb_in_flag = 0; - - if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || - st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || - st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || - st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) + /*! r: decoder error code */ + ivas_error IVAS_DEC_is_split_rendering_enabled( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t * isSplitRend /* o : flag to indicate if split rendering is enabled */ + ) { - cldfb_in_flag = 1; + Decoder_Struct *st_ivas; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + st_ivas = hIvasDec->st_ivas; + + *isSplitRend = is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ); + + return IVAS_ERR_OK; } - ISAR_PRE_REND_GetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &hSplitRendWrapper->multiBinPoseData, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->sr_pose_pred_axis : DEFAULT_AXIS ); - isCldfbNeeded = 0; + /*-------------------------------------------------------------------* + * ivas_dec_reconfig_split_rend() + * + * IVAS decoder split rend reconfig + *-------------------------------------------------------------------*/ - if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) || - ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) + static ivas_error ivas_dec_reconfig_split_rend( + Decoder_Struct * st_ivas /* i : IVAS decoder structure */ + ) { + ivas_error error; + int16_t cldfb_in_flag, num_ch, ch, isCldfbNeeded, i, pcm_out_flag; + SPLIT_REND_WRAPPER *hSplitRendWrapper; + + hSplitRendWrapper = &st_ivas->hSplitBinRend->splitrend; + pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; cldfb_in_flag = 0; - } - if ( st_ivas->renderer_type != RENDERER_DISABLE ) - { - if ( cldfb_in_flag == 0 ) + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || + st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || + st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) { - isCldfbNeeded = 1; + cldfb_in_flag = 1; } - else if ( st_ivas->hRenderConfig->split_rend_config.codec == ISAR_SPLIT_REND_CODEC_LC3PLUS && cldfb_in_flag ) + + ISAR_PRE_REND_GetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &hSplitRendWrapper->multiBinPoseData, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->sr_pose_pred_axis : DEFAULT_AXIS ); + + isCldfbNeeded = 0; + + if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) || + ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) { - isCldfbNeeded = 1; + cldfb_in_flag = 0; } - else if ( pcm_out_flag && cldfb_in_flag ) + + if ( st_ivas->renderer_type != RENDERER_DISABLE ) { - isCldfbNeeded = 1; + if ( cldfb_in_flag == 0 ) + { + isCldfbNeeded = 1; + } + else if ( st_ivas->hRenderConfig->split_rend_config.codec == ISAR_SPLIT_REND_CODEC_LC3PLUS && cldfb_in_flag ) + { + isCldfbNeeded = 1; + } + else if ( pcm_out_flag && cldfb_in_flag ) + { + isCldfbNeeded = 1; + } } - } - else if ( st_ivas->hDecoderConfig->Opt_non_diegetic_pan ) - { - isCldfbNeeded = 1; - } - - if ( isCldfbNeeded == 1 && hSplitRendWrapper->hCldfbHandles == NULL ) - { - if ( ( hSplitRendWrapper->hCldfbHandles = (CLDFB_HANDLES_WRAPPER_HANDLE) malloc( sizeof( CLDFB_HANDLES_WRAPPER ) ) ) == NULL ) + else if ( st_ivas->hDecoderConfig->Opt_non_diegetic_pan ) { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB handles\n" ) ); + isCldfbNeeded = 1; } - num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; - for ( ch = 0; ch < num_ch; ch++ ) + if ( isCldfbNeeded == 1 && hSplitRendWrapper->hCldfbHandles == NULL ) { - hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL; - } + if ( ( hSplitRendWrapper->hCldfbHandles = (CLDFB_HANDLES_WRAPPER_HANDLE) malloc( sizeof( CLDFB_HANDLES_WRAPPER ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB handles\n" ) ); + } + + num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; + for ( ch = 0; ch < num_ch; ch++ ) + { + hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL; + } - num_ch = hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; + num_ch = hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; - for ( ch = 0; ch < num_ch; ch++ ) - { - if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ), CLDFB_ANALYSIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + for ( ch = 0; ch < num_ch; ch++ ) { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not open CLDFB handles\n" ) ); + if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ), CLDFB_ANALYSIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not open CLDFB handles\n" ) ); + } } - } - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - return error; + if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } } } - } - else if ( isCldfbNeeded == 0 && hSplitRendWrapper->hCldfbHandles != NULL ) - { - num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; - for ( ch = 0; ch < num_ch; ch++ ) + else if ( isCldfbNeeded == 0 && hSplitRendWrapper->hCldfbHandles != NULL ) { - if ( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] != NULL ) + num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; + for ( ch = 0; ch < num_ch; ch++ ) { - deleteCldfb( &hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ); - hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL; + if ( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] != NULL ) + { + deleteCldfb( &hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ); + hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL; + } } - } - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - if ( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] != NULL ) + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - deleteCldfb( &hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ); - hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] = NULL; + if ( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] != NULL ) + { + deleteCldfb( &hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ); + hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] = NULL; + } } - } - free( hSplitRendWrapper->hCldfbHandles ); - hSplitRendWrapper->hCldfbHandles = NULL; - } + free( hSplitRendWrapper->hCldfbHandles ); + hSplitRendWrapper->hCldfbHandles = NULL; + } - if ( ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD ) && - ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV || st_ivas->ivas_format != SBA_ISM_FORMAT ) && - !( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) - { - for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + if ( ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD ) && + ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV || st_ivas->ivas_format != SBA_ISM_FORMAT ) && + !( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) { - if ( st_ivas->hTdRendHandles[i] != NULL ) + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) { - st_ivas->hTdRendHandles[i]->HrFiltSet_p = NULL; - ivas_td_binaural_close( &st_ivas->hTdRendHandles[i] ); + if ( st_ivas->hTdRendHandles[i] != NULL ) + { + st_ivas->hTdRendHandles[i]->HrFiltSet_p = NULL; + ivas_td_binaural_close( &st_ivas->hTdRendHandles[i] ); + } } } - } - return IVAS_ERR_OK; -} + return IVAS_ERR_OK; + } -/*-------------------------------------------------------------------* - * ivas_dec_split_rend_cldfb_in() - * - * - *-------------------------------------------------------------------*/ + /*-------------------------------------------------------------------* + * ivas_dec_split_rend_cldfb_in() + * + * + *-------------------------------------------------------------------*/ -static int16_t ivas_dec_split_rend_cldfb_in( - const RENDERER_TYPE renderer_type /* i : renderer type */ -) -{ - if ( renderer_type == RENDERER_BINAURAL_FASTCONV || - renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || - renderer_type == RENDERER_BINAURAL_PARAMETRIC || - renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) + static int16_t ivas_dec_split_rend_cldfb_in( + const RENDERER_TYPE renderer_type /* i : renderer type */ + ) { - return 1; - } - else - { - return 0; + if ( renderer_type == RENDERER_BINAURAL_FASTCONV || + renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || + renderer_type == RENDERER_BINAURAL_PARAMETRIC || + renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) + { + return 1; + } + else + { + return 0; + } } -} -/*-------------------------------------------------------------------* - * ivas_dec_init_split_rend() - * - * IVAS decoder split rendering initialization - *-------------------------------------------------------------------*/ + /*-------------------------------------------------------------------* + * ivas_dec_init_split_rend() + * + * IVAS decoder split rendering initialization + *-------------------------------------------------------------------*/ -static ivas_error ivas_dec_init_split_rend( - Decoder_Struct *st_ivas /* i : IVAS decoder structure */ -) -{ - ivas_error error; - int16_t cldfb_in_flag, pcm_out_flag; - int16_t mixed_td_cldfb_flag; - int16_t i, num_poses; + static ivas_error ivas_dec_init_split_rend( + Decoder_Struct * st_ivas /* i : IVAS decoder structure */ + ) + { + ivas_error error; + int16_t cldfb_in_flag, pcm_out_flag; + int16_t mixed_td_cldfb_flag; + int16_t i, num_poses; - pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; - cldfb_in_flag = 0; + pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; + cldfb_in_flag = 0; - cldfb_in_flag = ivas_dec_split_rend_cldfb_in( st_ivas->renderer_type ); + cldfb_in_flag = ivas_dec_split_rend_cldfb_in( st_ivas->renderer_type ); - ISAR_PRE_REND_GetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->sr_pose_pred_axis : DEFAULT_AXIS ); + ISAR_PRE_REND_GetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->sr_pose_pred_axis : DEFAULT_AXIS ); - num_poses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; - assert( num_poses <= MAX_HEAD_ROT_POSES ); + num_poses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; + assert( num_poses <= MAX_HEAD_ROT_POSES ); - if ( cldfb_in_flag ) - { - for ( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + if ( cldfb_in_flag ) { - /* note: this is intra-frame heap memory */ - if ( ( error = ivas_CLDFB_RINGBUF_Open( &st_ivas->hSplitBinRend->hMultiBinCldfbData[i], CLDFB_NO_COL_MAX ) ) != IVAS_ERR_OK ) + for ( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for split rendering structure" ); + /* note: this is intra-frame heap memory */ + if ( ( error = ivas_CLDFB_RINGBUF_Open( &st_ivas->hSplitBinRend->hMultiBinCldfbData[i], CLDFB_NO_COL_MAX ) ) != IVAS_ERR_OK ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for split rendering structure" ); + } } } - } - else - { - if ( ( error = ivas_TD_RINGBUF_Open( &st_ivas->hSplitBinRend->hMultiBinTdData, get_render_frame_size_samples( st_ivas->hDecoderConfig ), num_poses * BINAURAL_CHANNELS ) ) != IVAS_ERR_OK ) + else { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for split rendering structure" ); + if ( ( error = ivas_TD_RINGBUF_Open( &st_ivas->hSplitBinRend->hMultiBinTdData, get_render_frame_size_samples( st_ivas->hDecoderConfig ), num_poses * BINAURAL_CHANNELS ) ) != IVAS_ERR_OK ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for split rendering structure" ); + } } - } - if ( cldfb_in_flag == 1 && ( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ) - { - if ( ( st_ivas->hSplitBinRend->hCldfbDataOut = (ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA ) ) ) == NULL ) + if ( cldfb_in_flag == 1 && ( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ) { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for cldfb data out buffer\n" ) ); + if ( ( st_ivas->hSplitBinRend->hCldfbDataOut = (ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for cldfb data out buffer\n" ) ); + } } - } - - mixed_td_cldfb_flag = 0; - if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) || - ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) - { - mixed_td_cldfb_flag = 1; - } - error = ISAR_PRE_REND_open( &st_ivas->hSplitBinRend->splitrend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hDecoderConfig->output_Fs, cldfb_in_flag, pcm_out_flag, (int16_t) st_ivas->hDecoderConfig->render_num_subframes, mixed_td_cldfb_flag ); - - return error; -} - - -/*---------------------------------------------------------------------* - * IVAS_DEC_is_split_rendering_coded_out() - * - * Return flag to indicate if split rendering is enabled - *---------------------------------------------------------------------*/ + mixed_td_cldfb_flag = 0; + if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) || + ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) + { + mixed_td_cldfb_flag = 1; + } -/*! r: decoder error code */ -ivas_error IVAS_DEC_is_split_rendering_coded_out( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t *isSplitCoded /* o : flag to indicate if split rendering is enabled */ -) -{ - Decoder_Struct *st_ivas; + error = ISAR_PRE_REND_open( &st_ivas->hSplitBinRend->splitrend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hDecoderConfig->output_Fs, cldfb_in_flag, pcm_out_flag, (int16_t) st_ivas->hDecoderConfig->render_num_subframes, mixed_td_cldfb_flag ); - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + return error; } - st_ivas = hIvasDec->st_ivas; - *isSplitCoded = 0; + /*---------------------------------------------------------------------* + * IVAS_DEC_is_split_rendering_coded_out() + * + * Return flag to indicate if split rendering is enabled + *---------------------------------------------------------------------*/ - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || - ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO && st_ivas->hDecoderConfig->Opt_non_diegetic_pan && st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) + /*! r: decoder error code */ + ivas_error IVAS_DEC_is_split_rendering_coded_out( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t * isSplitCoded /* o : flag to indicate if split rendering is enabled */ + ) { - *isSplitCoded = 1; - } + Decoder_Struct *st_ivas; - return IVAS_ERR_OK; -} + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + st_ivas = hIvasDec->st_ivas; -/*---------------------------------------------------------------------* - * feedSinglePIorientation( ) - * - * Feed a single orientation PI data to external orientation handle. - *---------------------------------------------------------------------*/ + *isSplitCoded = 0; -static ivas_error feedSinglePIorientation( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_QUATERNION *orientation /* i : orientation for this PI type */ -) -{ - int16_t i; - ivas_error error; - Decoder_Struct *st_ivas; - IVAS_QUATERNION invOrientation; + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || + ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO && st_ivas->hDecoderConfig->Opt_non_diegetic_pan && st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) + { + *isSplitCoded = 1; + } - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + return IVAS_ERR_OK; } - st_ivas = hIvasDec->st_ivas; - if ( !st_ivas->hExtOrientationData ) + /*---------------------------------------------------------------------* + * feedSinglePIorientation( ) + * + * Feed a single orientation PI data to external orientation handle. + *---------------------------------------------------------------------*/ + + static ivas_error feedSinglePIorientation( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_QUATERNION * orientation /* i : orientation for this PI type */ + ) { - if ( ( error = ivas_external_orientation_open( &( st_ivas->hExtOrientationData ), st_ivas->hDecoderConfig->render_num_subframes ) ) != IVAS_ERR_OK ) + int16_t i; + ivas_error error; + Decoder_Struct *st_ivas; + IVAS_QUATERNION invOrientation; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - return error; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - } - if ( !st_ivas->hCombinedOrientationData ) - { - if ( ( error = ivas_combined_orientation_open( &( st_ivas->hCombinedOrientationData ), st_ivas->hDecoderConfig->output_Fs, st_ivas->hDecoderConfig->render_num_subframes ) ) != IVAS_ERR_OK ) + st_ivas = hIvasDec->st_ivas; + + if ( !st_ivas->hExtOrientationData ) { - return error; + if ( ( error = ivas_external_orientation_open( &( st_ivas->hExtOrientationData ), st_ivas->hDecoderConfig->render_num_subframes ) ) != IVAS_ERR_OK ) + { + return error; + } } - } - QuaternionInverse( *orientation, &invOrientation ); + if ( !st_ivas->hCombinedOrientationData ) + { + if ( ( error = ivas_combined_orientation_open( &( st_ivas->hCombinedOrientationData ), st_ivas->hDecoderConfig->output_Fs, st_ivas->hDecoderConfig->render_num_subframes ) ) != IVAS_ERR_OK ) + { + return error; + } + } - /* use the new PI orientation or the previously saved orientation in processing */ - for ( i = 0; i < st_ivas->hExtOrientationData->num_subframes; i++ ) - { - QuaternionProduct( st_ivas->hExtOrientationData->Quaternions[i], invOrientation, - &st_ivas->hExtOrientationData->Quaternions[i] ); - st_ivas->hExtOrientationData->enableExternalOrientation[i] = true; - } + QuaternionInverse( *orientation, &invOrientation ); - hIvasDec->updateOrientation = true; + /* use the new PI orientation or the previously saved orientation in processing */ + for ( i = 0; i < st_ivas->hExtOrientationData->num_subframes; i++ ) + { + QuaternionProduct( st_ivas->hExtOrientationData->Quaternions[i], invOrientation, + &st_ivas->hExtOrientationData->Quaternions[i] ); + st_ivas->hExtOrientationData->enableExternalOrientation[i] = true; + } - return IVAS_ERR_OK; -} + hIvasDec->updateOrientation = true; + return IVAS_ERR_OK; + } -/*---------------------------------------------------------------------* - * setDiegeticInput( ) - * - * Set isDiegeticInput flag for combined orientation handle based on PI data. - *---------------------------------------------------------------------*/ -static void setDiegeticInputPI( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const bool *diegeticPIValues /* i : diegetic values for the input stream */ -) -{ - int16_t i; + /*---------------------------------------------------------------------* + * setDiegeticInput( ) + * + * Set isDiegeticInput flag for combined orientation handle based on PI data. + *---------------------------------------------------------------------*/ - if ( st_ivas->hCombinedOrientationData != NULL ) + static void setDiegeticInputPI( + Decoder_Struct * st_ivas, /* i/o: IVAS decoder handle */ + const bool *diegeticPIValues /* i : diegetic values for the input stream */ + ) { - for ( i = 0; i < ( 1 + IVAS_MAX_NUM_OBJECTS ); i++ ) + int16_t i; + + if ( st_ivas->hCombinedOrientationData != NULL ) { - st_ivas->hCombinedOrientationData->isDiegeticInputPI[i] = diegeticPIValues[i]; + for ( i = 0; i < ( 1 + IVAS_MAX_NUM_OBJECTS ); i++ ) + { + st_ivas->hCombinedOrientationData->isDiegeticInputPI[i] = diegeticPIValues[i]; + } + + st_ivas->hCombinedOrientationData->isDiegeticInputPISet = true; } - st_ivas->hCombinedOrientationData->isDiegeticInputPISet = true; + return; } - return; -} - - -/*---------------------------------------------------------------------* - * IVAS_DEC_FeedPiDataToDecoder( ) - * - * - *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_FeedPiDataToDecoder( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_PIDATA_TS *piData, /* i : PI data received in rtp packet */ - uint32_t numPiData /* i : number of PI data received in rtp packet */ -) -{ - uint32_t i; - Decoder_Struct *st_ivas; - ivas_error error = IVAS_ERR_OK; + /*---------------------------------------------------------------------* + * IVAS_DEC_FeedPiDataToDecoder( ) + * + * + *---------------------------------------------------------------------*/ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + ivas_error IVAS_DEC_FeedPiDataToDecoder( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_PIDATA_TS * piData, /* i : PI data received in rtp packet */ + uint32_t numPiData /* i : number of PI data received in rtp packet */ + ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + uint32_t i; + Decoder_Struct *st_ivas; + ivas_error error = IVAS_ERR_OK; - st_ivas = hIvasDec->st_ivas; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - for ( i = 0; i < numPiData; i++ ) - { - uint32_t piDataType = piData->data.noPiData.piDataType; + st_ivas = hIvasDec->st_ivas; - switch ( piDataType ) + for ( i = 0; i < numPiData; i++ ) { - case IVAS_PI_SCENE_ORIENTATION: + uint32_t piDataType = piData->data.noPiData.piDataType; + + switch ( piDataType ) { - IVAS_QUATERNION *quat = &piData->data.scene.orientation; + case IVAS_PI_SCENE_ORIENTATION: + { + IVAS_QUATERNION *quat = &piData->data.scene.orientation; #ifdef DEBUGGING - fprintf( stdout, "PI_SCENE_ORIENTATION : %f, %f, %f, %f\n", quat->w, quat->x, quat->y, quat->z ); + fprintf( stdout, "PI_SCENE_ORIENTATION : %f, %f, %f, %f\n", quat->w, quat->x, quat->y, quat->z ); #endif - error = feedSinglePIorientation( hIvasDec, quat ); - } - break; + error = feedSinglePIorientation( hIvasDec, quat ); + } + break; - case IVAS_PI_DEVICE_ORIENTATION_COMPENSATED: - { - IVAS_QUATERNION *quat = &piData->data.deviceCompensated.orientation; + case IVAS_PI_DEVICE_ORIENTATION_COMPENSATED: + { + IVAS_QUATERNION *quat = &piData->data.deviceCompensated.orientation; #ifdef DEBUGGING - fprintf( stdout, "PI_DEVICE_ORIENTATION : %f, %f, %f, %f\n", quat->w, quat->x, quat->y, quat->z ); + fprintf( stdout, "PI_DEVICE_ORIENTATION : %f, %f, %f, %f\n", quat->w, quat->x, quat->y, quat->z ); #endif - error = feedSinglePIorientation( hIvasDec, quat ); - } - break; + error = feedSinglePIorientation( hIvasDec, quat ); + } + break; - case IVAS_PI_ACOUSTIC_ENVIRONMENT: - { - uint16_t aeid = piData->data.acousticEnv.aeid; + case IVAS_PI_ACOUSTIC_ENVIRONMENT: + { + uint16_t aeid = piData->data.acousticEnv.aeid; #ifdef DEBUGGING - fprintf( stdout, "PI_ACOUSTIC_ENVIRONMENT : AEID : %d\n", aeid ); + fprintf( stdout, "PI_ACOUSTIC_ENVIRONMENT : AEID : %d\n", aeid ); #endif - if ( piData->data.acousticEnv.availLateReverb && st_ivas->hRenderConfig != NULL && aeid != st_ivas->hRenderConfig->roomAcoustics.aeID ) - { - error = feedAcousticEnvPI( hIvasDec, piData->data.acousticEnv ); + if ( piData->data.acousticEnv.availLateReverb && st_ivas->hRenderConfig != NULL && aeid != st_ivas->hRenderConfig->roomAcoustics.aeID ) + { + error = feedAcousticEnvPI( hIvasDec, piData->data.acousticEnv ); + } } - } - break; + break; - case IVAS_PI_DIEGETIC_TYPE: - { + case IVAS_PI_DIEGETIC_TYPE: + { #ifdef DEBUGGING - fprintf( stdout, "PI_DIEGETIC_TYPE : %d, %d, %d, %d, %d\n", piData->data.digeticIndicator.isDiegetic[0], piData->data.digeticIndicator.isDiegetic[1], piData->data.digeticIndicator.isDiegetic[2], piData->data.digeticIndicator.isDiegetic[3], piData->data.digeticIndicator.isDiegetic[4] ); + fprintf( stdout, "PI_DIEGETIC_TYPE : %d, %d, %d, %d, %d\n", piData->data.digeticIndicator.isDiegetic[0], piData->data.digeticIndicator.isDiegetic[1], piData->data.digeticIndicator.isDiegetic[2], piData->data.digeticIndicator.isDiegetic[3], piData->data.digeticIndicator.isDiegetic[4] ); #endif - setDiegeticInputPI( st_ivas, piData->data.digeticIndicator.isDiegetic ); + setDiegeticInputPI( st_ivas, piData->data.digeticIndicator.isDiegetic ); + } + break; + + default: + { + /* NOT HANDLED PI DATA - DO NOTHING */ + } + break; } - break; - default: + if ( error != IVAS_ERR_OK ) { - /* NOT HANDLED PI DATA - DO NOTHING */ + return error; } - break; - } - if ( error != IVAS_ERR_OK ) - { - return error; + piData++; } - piData++; + return IVAS_ERR_OK; } - - return IVAS_ERR_OK; -} -- GitLab From 6302b1f3a1fb1a50e106e7ed8c63c398d043c745 Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 24 Mar 2026 17:52:24 +0100 Subject: [PATCH 2/9] clang-format --- apps/decoder.c | 1 + lib_dec/ivas_init_dec.c | 44 +- lib_dec/lib_dec.c | 8348 +++++++++++++++++++-------------------- 3 files changed, 4197 insertions(+), 4196 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index aabe221f7..f4beee614 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -4376,6 +4376,7 @@ static ivas_error restartDecoder( } #ifndef FIX_FMSW_DEC + if ( arg->voipMode ) { if ( ( error = IVAS_DEC_EnableVoIP( hIvasDec, 60, arg->inputFormat ) ) != IVAS_ERR_OK ) { diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index a6f0bd3e6..2c330c20b 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -2743,9 +2743,9 @@ void ivas_initialize_handles_dec( if ( st_ivas->restartNeeded == 0 ) { #endif - st_ivas->bit_stream = NULL; - st_ivas->mem_hp20_out = NULL; - st_ivas->hLimiter = NULL; + st_ivas->bit_stream = NULL; + st_ivas->mem_hp20_out = NULL; + st_ivas->hLimiter = NULL; #ifdef FIX_FMSW_DEC } #endif @@ -2878,17 +2878,17 @@ void ivas_destroy_dec( if ( st_ivas->restartNeeded == 0 ) { #endif - /* HP20 filter handles */ - if ( st_ivas->mem_hp20_out != NULL ) - { - for ( i = 0; i < getNumChanSynthesis( st_ivas ); i++ ) + /* HP20 filter handles */ + if ( st_ivas->mem_hp20_out != NULL ) { - free( st_ivas->mem_hp20_out[i] ); - st_ivas->mem_hp20_out[i] = NULL; + for ( i = 0; i < getNumChanSynthesis( st_ivas ); i++ ) + { + free( st_ivas->mem_hp20_out[i] ); + st_ivas->mem_hp20_out[i] = NULL; + } + free( st_ivas->mem_hp20_out ); + st_ivas->mem_hp20_out = NULL; } - free( st_ivas->mem_hp20_out ); - st_ivas->mem_hp20_out = NULL; - } #ifdef FIX_FMSW_DEC } #endif @@ -3019,18 +3019,18 @@ void ivas_destroy_dec( } #ifdef FIX_FMSW_DEC - if ( st_ivas->restartNeeded == 0 ) + if ( st_ivas->restartNeeded == 0 ) { #endif - /* Limiter struct */ - ivas_limiter_close( &( st_ivas->hLimiter ) ); + /* Limiter struct */ + ivas_limiter_close( &( st_ivas->hLimiter ) ); - /* Decoder configuration structure */ - if ( st_ivas->hDecoderConfig != NULL ) - { - free( st_ivas->hDecoderConfig ); - st_ivas->hDecoderConfig = NULL; - } + /* Decoder configuration structure */ + if ( st_ivas->hDecoderConfig != NULL ) + { + free( st_ivas->hDecoderConfig ); + st_ivas->hDecoderConfig = NULL; + } #ifdef FIX_FMSW_DEC } #endif @@ -3055,7 +3055,7 @@ void ivas_destroy_dec( if ( st_ivas->restartNeeded == 0 ) { #endif - free( st_ivas ); + free( st_ivas ); #ifdef FIX_FMSW_DEC } #endif diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 078ea6db2..d5d77dfea 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -228,4473 +228,4473 @@ ivas_error IVAS_DEC_Open( #endif init_decoder_config( hIvasDec->st_ivas->hDecoderConfig ); #ifdef FIX_FMSW_DEC - } + } #endif - /* initialize pointers to handles to NULL */ - ivas_initialize_handles_dec( st_ivas ); + /* initialize pointers to handles to NULL */ + ivas_initialize_handles_dec( st_ivas ); - st_ivas->restartNeeded = 0; + st_ivas->restartNeeded = 0; - /* set high-level parameters */ + /* set high-level parameters */ - st_ivas->codec_mode = 0; /* unknown before first frame */ - st_ivas->transport_config = IVAS_AUDIO_CONFIG_INVALID; - st_ivas->intern_config = IVAS_AUDIO_CONFIG_INVALID; - st_ivas->writeFECoffset = 0; - st_ivas->sba_analysis_order = 0; /* not really used in EVS mode, but initialize here to fix MSAN complaint */ - - if ( mode == IVAS_DEC_MODE_EVS ) - { - st_ivas->element_mode_init = EVS_MONO; - st_ivas->ivas_format = MONO_FORMAT; - hIvasDec->hasDecodedFirstGoodFrame = true; /* Functionality to suppress output for initial lost frames is disabled in EVS operation */ + st_ivas->codec_mode = 0; /* unknown before first frame */ + st_ivas->transport_config = IVAS_AUDIO_CONFIG_INVALID; + st_ivas->intern_config = IVAS_AUDIO_CONFIG_INVALID; + st_ivas->writeFECoffset = 0; + st_ivas->sba_analysis_order = 0; /* not really used in EVS mode, but initialize here to fix MSAN complaint */ - return IVAS_ERR_OK; - } - else if ( mode == IVAS_DEC_MODE_IVAS ) - { - st_ivas->element_mode_init = -1; - st_ivas->ivas_format = UNDEFINED_FORMAT; - st_ivas->renderer_type = RENDERER_DISABLE; - st_ivas->ini_frame = 0; - st_ivas->ini_active_frame = 0; + if ( mode == IVAS_DEC_MODE_EVS ) + { + st_ivas->element_mode_init = EVS_MONO; + st_ivas->ivas_format = MONO_FORMAT; + hIvasDec->hasDecodedFirstGoodFrame = true; /* Functionality to suppress output for initial lost frames is disabled in EVS operation */ - st_ivas->ism_mode = ISM_MODE_NONE; - st_ivas->mc_mode = MC_MODE_NONE; + return IVAS_ERR_OK; + } + else if ( mode == IVAS_DEC_MODE_IVAS ) + { + st_ivas->element_mode_init = -1; + st_ivas->ivas_format = UNDEFINED_FORMAT; + st_ivas->renderer_type = RENDERER_DISABLE; + st_ivas->ini_frame = 0; + st_ivas->ini_active_frame = 0; - st_ivas->sba_order = 0; - st_ivas->sba_planar = 0; + st_ivas->ism_mode = ISM_MODE_NONE; + st_ivas->mc_mode = MC_MODE_NONE; - return IVAS_ERR_OK; - } + st_ivas->sba_order = 0; + st_ivas->sba_planar = 0; - return IVAS_ERR_WRONG_PARAMS; + return IVAS_ERR_OK; } + return IVAS_ERR_WRONG_PARAMS; +} - /*-------------------------------------------------------------------------* - * isar_set_split_rend_setup() - * - * Setup IVAS split rendering - *-------------------------------------------------------------------------*/ - static ivas_error isar_set_split_rend_setup( - ISAR_DEC_SPLIT_REND_WRAPPER * hSplitBinRend, - const ISAR_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, - const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, - ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ - ) +/*-------------------------------------------------------------------------* + * isar_set_split_rend_setup() + * + * Setup IVAS split rendering + *-------------------------------------------------------------------------*/ + +static ivas_error isar_set_split_rend_setup( + ISAR_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, + const ISAR_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, + const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, + ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ +) +{ + splitRendBits->bits_read = 0; + splitRendBits->bits_written = 0; + splitRendBits->buf_len = ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES; + splitRendBits->codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + splitRendBits->pose_correction = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + splitRendBits->codec_frame_size_ms = 0; + splitRendBits->isar_frame_size_ms = 0; + splitRendBits->lc3plus_highres = 0; + + ISAR_PRE_REND_GetMultiBinPoseData( hSplitBinConfig, &hSplitBinRend->splitrend.multiBinPoseData, ( hCombinedOrientationData != NULL ) ? hCombinedOrientationData->sr_pose_pred_axis : DEFAULT_AXIS ); + + if ( hCombinedOrientationData != NULL ) { - splitRendBits->bits_read = 0; - splitRendBits->bits_written = 0; - splitRendBits->buf_len = ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES; - splitRendBits->codec = ISAR_SPLIT_REND_CODEC_DEFAULT; - splitRendBits->pose_correction = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; - splitRendBits->codec_frame_size_ms = 0; - splitRendBits->isar_frame_size_ms = 0; - splitRendBits->lc3plus_highres = 0; - - ISAR_PRE_REND_GetMultiBinPoseData( hSplitBinConfig, &hSplitBinRend->splitrend.multiBinPoseData, ( hCombinedOrientationData != NULL ) ? hCombinedOrientationData->sr_pose_pred_axis : DEFAULT_AXIS ); - - if ( hCombinedOrientationData != NULL ) - { - isar_set_split_rend_ht_setup( &hSplitBinRend->splitrend, hCombinedOrientationData->Quaternions, hCombinedOrientationData->Rmat ); - } - - return IVAS_ERR_OK; + isar_set_split_rend_ht_setup( &hSplitBinRend->splitrend, hCombinedOrientationData->Quaternions, hCombinedOrientationData->Rmat ); } - /*---------------------------------------------------------------------* - * init_decoder_config() - * - * Initialize Decoder Config. handle - *---------------------------------------------------------------------*/ + return IVAS_ERR_OK; +} - static void init_decoder_config( - DECODER_CONFIG_HANDLE hDecoderConfig /* i/o: configuration structure */ - ) - { - hDecoderConfig->Opt_AMR_WB = 0; - hDecoderConfig->output_Fs = -1; - hDecoderConfig->nchan_out = 1; - hDecoderConfig->output_config = IVAS_AUDIO_CONFIG_INVALID; - hDecoderConfig->Opt_LsCustom = 0; - hDecoderConfig->Opt_HRTF_binary = 0; - hDecoderConfig->Opt_Headrotation = 0; - hDecoderConfig->Opt_RendConfigCustom = 0; - hDecoderConfig->room_size = IVAS_ROOM_SIZE_AUTO; - hDecoderConfig->orientation_tracking = IVAS_HEAD_ORIENT_TRK_NONE; - hDecoderConfig->Opt_non_diegetic_pan = 0; - hDecoderConfig->non_diegetic_pan_gain = 0; - hDecoderConfig->Opt_tsm = 0; - hDecoderConfig->Opt_delay_comp = 0; - hDecoderConfig->Opt_ExternalOrientation = 0; - hDecoderConfig->Opt_dpid_on = 0; - hDecoderConfig->Opt_aeid_on = 0; - hDecoderConfig->Opt_ObjEdit_on = 0; +/*---------------------------------------------------------------------* + * init_decoder_config() + * + * Initialize Decoder Config. handle + *---------------------------------------------------------------------*/ - return; - } +static void init_decoder_config( + DECODER_CONFIG_HANDLE hDecoderConfig /* i/o: configuration structure */ +) +{ + hDecoderConfig->Opt_AMR_WB = 0; + hDecoderConfig->output_Fs = -1; + hDecoderConfig->nchan_out = 1; + hDecoderConfig->output_config = IVAS_AUDIO_CONFIG_INVALID; + hDecoderConfig->Opt_LsCustom = 0; + hDecoderConfig->Opt_HRTF_binary = 0; + hDecoderConfig->Opt_Headrotation = 0; + hDecoderConfig->Opt_RendConfigCustom = 0; + hDecoderConfig->room_size = IVAS_ROOM_SIZE_AUTO; + hDecoderConfig->orientation_tracking = IVAS_HEAD_ORIENT_TRK_NONE; + hDecoderConfig->Opt_non_diegetic_pan = 0; + hDecoderConfig->non_diegetic_pan_gain = 0; + hDecoderConfig->Opt_tsm = 0; + hDecoderConfig->Opt_delay_comp = 0; + hDecoderConfig->Opt_ExternalOrientation = 0; + hDecoderConfig->Opt_dpid_on = 0; + hDecoderConfig->Opt_aeid_on = 0; + hDecoderConfig->Opt_ObjEdit_on = 0; + + return; +} - /*---------------------------------------------------------------------* - * IVAS_DEC_Close( ) - * - * Deallocate IVAS decoder memory handles - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_Close( ) + * + * Deallocate IVAS decoder memory handles + *---------------------------------------------------------------------*/ - void IVAS_DEC_Close( - IVAS_DEC_HANDLE * phIvasDec /* i/o: pointer to IVAS decoder handle */ - ) +void IVAS_DEC_Close( + IVAS_DEC_HANDLE *phIvasDec /* i/o: pointer to IVAS decoder handle */ +) +{ + /* Free all memory */ + if ( phIvasDec == NULL || *phIvasDec == NULL ) { - /* Free all memory */ - if ( phIvasDec == NULL || *phIvasDec == NULL ) - { - return; - } + return; + } #ifdef FIX_FMSW_DEC - if ( ( *phIvasDec )->st_ivas->restartNeeded == 0 && ( *phIvasDec )->hVoIP ) + if ( ( *phIvasDec )->st_ivas->restartNeeded == 0 && ( *phIvasDec )->hVoIP ) #else if ( ( *phIvasDec )->hVoIP ) #endif - { - ivas_destroy_handle_VoIP( ( *phIvasDec )->hVoIP ); - ( *phIvasDec )->hVoIP = NULL; - } + { + ivas_destroy_handle_VoIP( ( *phIvasDec )->hVoIP ); + ( *phIvasDec )->hVoIP = NULL; + } - if ( ( *phIvasDec )->st_ivas ) - { - /* destroy Split binaural renderer (ISAR) handle */ - ivas_destroy_handle_isar( &( *phIvasDec )->st_ivas->hSplitBinRend ); + if ( ( *phIvasDec )->st_ivas ) + { + /* destroy Split binaural renderer (ISAR) handle */ + ivas_destroy_handle_isar( &( *phIvasDec )->st_ivas->hSplitBinRend ); - /* destroy IVAS decoder handles */ - ivas_destroy_dec( ( *phIvasDec )->st_ivas ); + /* destroy IVAS decoder handles */ + ivas_destroy_dec( ( *phIvasDec )->st_ivas ); #ifdef FIX_FMSW_DEC - if ( ( *phIvasDec )->st_ivas->restartNeeded == 0 ) - { + if ( ( *phIvasDec )->st_ivas->restartNeeded == 0 ) + { #endif - ( *phIvasDec )->st_ivas = NULL; + ( *phIvasDec )->st_ivas = NULL; #ifdef FIX_FMSW_DEC - } -#endif } +#endif + } #ifdef FIX_FMSW_DEC - if ( ( *phIvasDec )->st_ivas->restartNeeded == 0 ) - { + if ( ( *phIvasDec )->st_ivas->restartNeeded == 0 ) + { #endif - apa_exit( &( *phIvasDec )->hTimeScaler ); + apa_exit( &( *phIvasDec )->hTimeScaler ); - if ( ( *phIvasDec )->flushbuffer != NULL ) - { - free( ( *phIvasDec )->flushbuffer ); - } + if ( ( *phIvasDec )->flushbuffer != NULL ) + { + free( ( *phIvasDec )->flushbuffer ); + } - free( *phIvasDec ); - *phIvasDec = NULL; - phIvasDec = NULL; + free( *phIvasDec ); + *phIvasDec = NULL; + phIvasDec = NULL; #ifdef FIX_FMSW_DEC - } + } #endif - return; - } + return; +} - /*---------------------------------------------------------------------* - * mapIvasFormat( ) - * - * - *---------------------------------------------------------------------*/ - - static IVAS_DEC_BS_FORMAT mapIvasFormat( - const IVAS_FORMAT ivas_format ) - { - switch ( ivas_format ) - { - case MONO_FORMAT: - return IVAS_DEC_BS_MONO; - case STEREO_FORMAT: - return IVAS_DEC_BS_STEREO; - case ISM_FORMAT: - return IVAS_DEC_BS_OBJ; - case MC_FORMAT: - return IVAS_DEC_BS_MC; - case SBA_FORMAT: - return IVAS_DEC_BS_SBA; - case SBA_ISM_FORMAT: - return IVAS_DEC_BS_SBA_ISM; - case MASA_FORMAT: - return IVAS_DEC_BS_MASA; - case MASA_ISM_FORMAT: - return IVAS_DEC_BS_MASA_ISM; - default: - break; - } +/*---------------------------------------------------------------------* + * mapIvasFormat( ) + * + * + *---------------------------------------------------------------------*/ - return IVAS_DEC_BS_UNKOWN; +static IVAS_DEC_BS_FORMAT mapIvasFormat( + const IVAS_FORMAT ivas_format ) +{ + switch ( ivas_format ) + { + case MONO_FORMAT: + return IVAS_DEC_BS_MONO; + case STEREO_FORMAT: + return IVAS_DEC_BS_STEREO; + case ISM_FORMAT: + return IVAS_DEC_BS_OBJ; + case MC_FORMAT: + return IVAS_DEC_BS_MC; + case SBA_FORMAT: + return IVAS_DEC_BS_SBA; + case SBA_ISM_FORMAT: + return IVAS_DEC_BS_SBA_ISM; + case MASA_FORMAT: + return IVAS_DEC_BS_MASA; + case MASA_ISM_FORMAT: + return IVAS_DEC_BS_MASA_ISM; + default: + break; } + return IVAS_DEC_BS_UNKOWN; +} + - /*---------------------------------------------------------------------* - * create_flush_buffer() - * - * Create flush buffer - needed for binaural outputs with TSM or in VoIP mode - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * create_flush_buffer() + * + * Create flush buffer - needed for binaural outputs with TSM or in VoIP mode + *---------------------------------------------------------------------*/ - static ivas_error create_flush_buffer( - IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ - ) +static ivas_error create_flush_buffer( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +) +{ + hIvasDec->flushbuffer = (void *) malloc( CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( int16_t ) ); + if ( hIvasDec->flushbuffer == NULL ) { - hIvasDec->flushbuffer = (void *) malloc( CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( int16_t ) ); - if ( hIvasDec->flushbuffer == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate JBM flush buffer" ); - } + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate JBM flush buffer" ); + } - hIvasDec->pcmType = IVAS_DEC_PCM_INT16; - set_s( (int16_t *) hIvasDec->flushbuffer, 0, CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ); + hIvasDec->pcmType = IVAS_DEC_PCM_INT16; + set_s( (int16_t *) hIvasDec->flushbuffer, 0, CPE_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ); - return IVAS_ERR_OK; + return IVAS_ERR_OK; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_Configure( ) + * + * Decoder configuration + * legacy behavior: if no output format set, then it's EVS mono + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_Configure( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const uint32_t sampleRate, /* i : output sampling frequency */ + const AUDIO_CONFIG outputConfig, /* i : output configuration */ + const IVAS_RENDER_NUM_SUBFR render_num_subframes, /* i : rendering number of subframes */ + const bool customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ + const bool hrtfReaderEnabled, /* i : enable HRTF binary file input */ + const bool enableHeadRotation, /* i : enable head rotation for binaural output */ + const bool enableExternalOrientation, /* i : enable external orientations */ + const IVAS_HEAD_ORIENT_TRK_T orientation_tracking, /* i : head orientation tracking type */ + const bool renderConfigEnabled, /* i : enable Renderer config. file for binaural output */ + const IVAS_ROOM_SIZE_T roomSize, /* i : room size selector for reverb */ + const bool non_diegetic_pan_enabled, /* i : enabled diegetic panning */ + const float non_diegetic_pan_gain, /* i : non diegetic panning gain */ + const bool dpidEnabled, /* i : enable directivity pattern option */ + const uint16_t acousticEnvironmentId, /* i : Acoustic environment ID */ + const bool objEditEnabled, /* i : enable object editing */ + const bool delayCompensationEnabled /* i : enable delay compensation */ +) +{ + Decoder_Struct *st_ivas; + DECODER_CONFIG_HANDLE hDecoderConfig; + ivas_error error; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + if ( sampleRate != 8000 && sampleRate != 16000 && sampleRate != 32000 && sampleRate != 48000 ) + { + return IVAS_ERR_WRONG_PARAMS; + } - /*---------------------------------------------------------------------* - * IVAS_DEC_Configure( ) - * - * Decoder configuration - * legacy behavior: if no output format set, then it's EVS mono - *---------------------------------------------------------------------*/ - - ivas_error IVAS_DEC_Configure( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const uint32_t sampleRate, /* i : output sampling frequency */ - const AUDIO_CONFIG outputConfig, /* i : output configuration */ - const IVAS_RENDER_NUM_SUBFR render_num_subframes, /* i : rendering number of subframes */ - const bool customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ - const bool hrtfReaderEnabled, /* i : enable HRTF binary file input */ - const bool enableHeadRotation, /* i : enable head rotation for binaural output */ - const bool enableExternalOrientation, /* i : enable external orientations */ - const IVAS_HEAD_ORIENT_TRK_T orientation_tracking, /* i : head orientation tracking type */ - const bool renderConfigEnabled, /* i : enable Renderer config. file for binaural output */ - const IVAS_ROOM_SIZE_T roomSize, /* i : room size selector for reverb */ - const bool non_diegetic_pan_enabled, /* i : enabled diegetic panning */ - const float non_diegetic_pan_gain, /* i : non diegetic panning gain */ - const bool dpidEnabled, /* i : enable directivity pattern option */ - const uint16_t acousticEnvironmentId, /* i : Acoustic environment ID */ - const bool objEditEnabled, /* i : enable object editing */ - const bool delayCompensationEnabled /* i : enable delay compensation */ - ) + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS && + ( outputConfig == IVAS_AUDIO_CONFIG_INVALID || + outputConfig == IVAS_AUDIO_CONFIG_ISM1 || + outputConfig == IVAS_AUDIO_CONFIG_ISM2 || + outputConfig == IVAS_AUDIO_CONFIG_ISM3 || + outputConfig == IVAS_AUDIO_CONFIG_ISM4 || + outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || + outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || + outputConfig == IVAS_AUDIO_CONFIG_MASA1 || + outputConfig == IVAS_AUDIO_CONFIG_MASA2 ) ) { - Decoder_Struct *st_ivas; - DECODER_CONFIG_HANDLE hDecoderConfig; - ivas_error error; + return IVAS_ERR_WRONG_MODE; + } - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + st_ivas = hIvasDec->st_ivas; - if ( sampleRate != 8000 && sampleRate != 16000 && sampleRate != 32000 && sampleRate != 48000 ) - { - return IVAS_ERR_WRONG_PARAMS; - } + hDecoderConfig = st_ivas->hDecoderConfig; - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS && - ( outputConfig == IVAS_AUDIO_CONFIG_INVALID || - outputConfig == IVAS_AUDIO_CONFIG_ISM1 || - outputConfig == IVAS_AUDIO_CONFIG_ISM2 || - outputConfig == IVAS_AUDIO_CONFIG_ISM3 || - outputConfig == IVAS_AUDIO_CONFIG_ISM4 || - outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || - outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || - outputConfig == IVAS_AUDIO_CONFIG_MASA1 || - outputConfig == IVAS_AUDIO_CONFIG_MASA2 ) ) - { - return IVAS_ERR_WRONG_MODE; - } + hDecoderConfig->output_config = outputConfig; + if ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_INVALID ) + { + return IVAS_ERR_WRONG_PARAMS; + } - st_ivas = hIvasDec->st_ivas; + hDecoderConfig->output_Fs = sampleRate; - hDecoderConfig = st_ivas->hDecoderConfig; + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + { + st_ivas->element_mode_init = EVS_MONO; + hDecoderConfig->nchan_out = 1; + } - hDecoderConfig->output_config = outputConfig; - if ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_INVALID ) - { - return IVAS_ERR_WRONG_PARAMS; - } + if ( outputConfig != IVAS_AUDIO_CONFIG_EXTERNAL && outputConfig != IVAS_AUDIO_CONFIG_LS_CUSTOM ) + { + hDecoderConfig->nchan_out = audioCfg2channels( hDecoderConfig->output_config ); + } - hDecoderConfig->output_Fs = sampleRate; + hDecoderConfig->Opt_LsCustom = (int16_t) customLsOutputEnabled; + hDecoderConfig->Opt_Headrotation = (int16_t) enableHeadRotation; + hDecoderConfig->orientation_tracking = orientation_tracking; + hDecoderConfig->Opt_HRTF_binary = (int16_t) hrtfReaderEnabled; + hDecoderConfig->Opt_RendConfigCustom = (int16_t) renderConfigEnabled; + hDecoderConfig->room_size = roomSize; + hDecoderConfig->Opt_non_diegetic_pan = (int16_t) non_diegetic_pan_enabled; + hDecoderConfig->non_diegetic_pan_gain = non_diegetic_pan_gain; + hDecoderConfig->Opt_delay_comp = (int16_t) delayCompensationEnabled; + hDecoderConfig->Opt_ExternalOrientation = enableExternalOrientation; + hDecoderConfig->Opt_dpid_on = (int16_t) dpidEnabled; + hDecoderConfig->Opt_aeid_on = acousticEnvironmentId != 65535 ? TRUE : FALSE; + hDecoderConfig->Opt_ObjEdit_on = (int16_t) objEditEnabled; + + if ( outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + hDecoderConfig->Opt_Headrotation = 1; + } - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) - { - st_ivas->element_mode_init = EVS_MONO; - hDecoderConfig->nchan_out = 1; - } + if ( render_num_subframes == IVAS_RENDER_NUM_SUBFR_UNKNOWN ) + { + return IVAS_ERR_WRONG_PARAMS; + } - if ( outputConfig != IVAS_AUDIO_CONFIG_EXTERNAL && outputConfig != IVAS_AUDIO_CONFIG_LS_CUSTOM ) - { - hDecoderConfig->nchan_out = audioCfg2channels( hDecoderConfig->output_config ); - } + if ( outputConfig == IVAS_AUDIO_CONFIG_EXTERNAL ) + { + hDecoderConfig->render_num_subframes = IVAS_RENDER_NUM_SUBFR_20MS; + } + else + { + hDecoderConfig->render_num_subframes = render_num_subframes; + } - hDecoderConfig->Opt_LsCustom = (int16_t) customLsOutputEnabled; - hDecoderConfig->Opt_Headrotation = (int16_t) enableHeadRotation; - hDecoderConfig->orientation_tracking = orientation_tracking; - hDecoderConfig->Opt_HRTF_binary = (int16_t) hrtfReaderEnabled; - hDecoderConfig->Opt_RendConfigCustom = (int16_t) renderConfigEnabled; - hDecoderConfig->room_size = roomSize; - hDecoderConfig->Opt_non_diegetic_pan = (int16_t) non_diegetic_pan_enabled; - hDecoderConfig->non_diegetic_pan_gain = non_diegetic_pan_gain; - hDecoderConfig->Opt_delay_comp = (int16_t) delayCompensationEnabled; - hDecoderConfig->Opt_ExternalOrientation = enableExternalOrientation; - hDecoderConfig->Opt_dpid_on = (int16_t) dpidEnabled; - hDecoderConfig->Opt_aeid_on = acousticEnvironmentId != 65535 ? TRUE : FALSE; - hDecoderConfig->Opt_ObjEdit_on = (int16_t) objEditEnabled; + /* Set decoder parameters to initial values */ + if ( ( error = ivas_init_decoder_front( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } - if ( outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + /* create ISAR handle */ + if ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( ( error = ivas_create_handle_isar( &st_ivas->hSplitBinRend ) ) != IVAS_ERR_OK ) { - hDecoderConfig->Opt_Headrotation = 1; + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for ISAR handle" ); } + } - if ( render_num_subframes == IVAS_RENDER_NUM_SUBFR_UNKNOWN ) - { - return IVAS_ERR_WRONG_PARAMS; - } + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + { + hIvasDec->st_ivas->ivas_format = MONO_FORMAT; + } - if ( outputConfig == IVAS_AUDIO_CONFIG_EXTERNAL ) - { - hDecoderConfig->render_num_subframes = IVAS_RENDER_NUM_SUBFR_20MS; - } - else - { - hDecoderConfig->render_num_subframes = render_num_subframes; - } + hIvasDec->nSamplesFrame = (uint16_t) ( hDecoderConfig->output_Fs / FRAMES_PER_SEC ); - /* Set decoder parameters to initial values */ - if ( ( error = ivas_init_decoder_front( st_ivas ) ) != IVAS_ERR_OK ) - { - return error; - } + return IVAS_ERR_OK; +} - /* create ISAR handle */ - if ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - if ( ( error = ivas_create_handle_isar( &st_ivas->hSplitBinRend ) ) != IVAS_ERR_OK ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for ISAR handle" ); - } - } - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) - { - hIvasDec->st_ivas->ivas_format = MONO_FORMAT; - } +/*---------------------------------------------------------------------* + * IVAS_DEC_EnableSplitRendering( ) + * + * Update IVAS decoder config. if Split rendering is enabled + *---------------------------------------------------------------------*/ - hIvasDec->nSamplesFrame = (uint16_t) ( hDecoderConfig->output_Fs / FRAMES_PER_SEC ); +ivas_error IVAS_DEC_EnableSplitRendering( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +) +{ + DECODER_CONFIG_HANDLE hDecoderConfig; - return IVAS_ERR_OK; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; - /*---------------------------------------------------------------------* - * IVAS_DEC_EnableSplitRendering( ) - * - * Update IVAS decoder config. if Split rendering is enabled - *---------------------------------------------------------------------*/ - - ivas_error IVAS_DEC_EnableSplitRendering( - IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ - ) - { - DECODER_CONFIG_HANDLE hDecoderConfig; + hDecoderConfig->Opt_Headrotation = 1; + hDecoderConfig->render_num_subframes = IVAS_RENDER_NUM_SUBFR_20MS; - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + return IVAS_ERR_OK; +} - hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; - hDecoderConfig->Opt_Headrotation = 1; - hDecoderConfig->render_num_subframes = IVAS_RENDER_NUM_SUBFR_20MS; +/*---------------------------------------------------------------------* + * get_render_framesize_ms( ) + * + * Get render framesize in ms + *---------------------------------------------------------------------*/ - return IVAS_ERR_OK; - } +/*! r: render framesize in ms */ +static int16_t get_render_frame_size_ms( + const IVAS_RENDER_NUM_SUBFR render_num_subframes ) +{ + return (int16_t) ( render_num_subframes * ( 1000 / ( FRAMES_PER_SEC * IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ) ) ); +} - /*---------------------------------------------------------------------* - * get_render_framesize_ms( ) - * - * Get render framesize in ms - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_SetRenderNumSubfr( ) + * + * Set number of rendering subrames + *---------------------------------------------------------------------*/ - /*! r: render framesize in ms */ - static int16_t get_render_frame_size_ms( - const IVAS_RENDER_NUM_SUBFR render_num_subframes ) +ivas_error IVAS_DEC_SetRenderNumSubfr( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_RENDER_NUM_SUBFR render_num_subframes /* i : renderer number of subframes */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hDecoderConfig == NULL ) { - return (int16_t) ( render_num_subframes * ( 1000 / ( FRAMES_PER_SEC * IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ) ) ); + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + hIvasDec->st_ivas->hDecoderConfig->render_num_subframes = render_num_subframes; - /*---------------------------------------------------------------------* - * IVAS_DEC_SetRenderNumSubfr( ) - * - * Set number of rendering subrames - *---------------------------------------------------------------------*/ + if ( hIvasDec->st_ivas->hExtOrientationData != NULL ) + { + hIvasDec->st_ivas->hExtOrientationData->num_subframes = (int16_t) render_num_subframes; + } - ivas_error IVAS_DEC_SetRenderNumSubfr( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const IVAS_RENDER_NUM_SUBFR render_num_subframes /* i : renderer number of subframes */ - ) + if ( hIvasDec->st_ivas->hCombinedOrientationData != NULL ) { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hDecoderConfig == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + hIvasDec->st_ivas->hCombinedOrientationData->num_subframes = (int16_t) render_num_subframes; + } - hIvasDec->st_ivas->hDecoderConfig->render_num_subframes = render_num_subframes; + return IVAS_ERR_OK; +} - if ( hIvasDec->st_ivas->hExtOrientationData != NULL ) - { - hIvasDec->st_ivas->hExtOrientationData->num_subframes = (int16_t) render_num_subframes; - } - if ( hIvasDec->st_ivas->hCombinedOrientationData != NULL ) - { - hIvasDec->st_ivas->hCombinedOrientationData->num_subframes = (int16_t) render_num_subframes; - } +/*---------------------------------------------------------------------* + * IVAS_DEC_GetRenderNumSubfr( ) + * + * Get number of rendering subframes + *---------------------------------------------------------------------*/ - return IVAS_ERR_OK; +ivas_error IVAS_DEC_GetRenderNumSubfr( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_RENDER_NUM_SUBFR *render_num_subframes /* o : rendering number of subframes */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || render_num_subframes == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + *render_num_subframes = hIvasDec->st_ivas->hDecoderConfig->render_num_subframes; - /*---------------------------------------------------------------------* - * IVAS_DEC_GetRenderNumSubfr( ) - * - * Get number of rendering subframes - *---------------------------------------------------------------------*/ + return IVAS_ERR_OK; +} - ivas_error IVAS_DEC_GetRenderNumSubfr( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_RENDER_NUM_SUBFR * render_num_subframes /* o : rendering number of subframes */ - ) - { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || render_num_subframes == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - *render_num_subframes = hIvasDec->st_ivas->hDecoderConfig->render_num_subframes; +/*---------------------------------------------------------------------* + * get_render_frame_size_samples( ) + * + * + *---------------------------------------------------------------------*/ - return IVAS_ERR_OK; - } +static int16_t get_render_frame_size_samples( + const DECODER_CONFIG_HANDLE hDecoderConfig /* i : configuration structure */ +) +{ + return (int16_t) ( hDecoderConfig->output_Fs * hDecoderConfig->render_num_subframes / ( FRAMES_PER_SEC * IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ) ); +} - /*---------------------------------------------------------------------* - * get_render_frame_size_samples( ) - * - * - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_etRenderFramesizeSamples( ) + * + * Get render framesize in samples + *---------------------------------------------------------------------*/ - static int16_t get_render_frame_size_samples( - const DECODER_CONFIG_HANDLE hDecoderConfig /* i : configuration structure */ - ) +ivas_error IVAS_DEC_GetRenderFramesizeSamples( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *render_framesize /* o : render framesize in samples */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || render_framesize == NULL ) { - return (int16_t) ( hDecoderConfig->output_Fs * hDecoderConfig->render_num_subframes / ( FRAMES_PER_SEC * IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ) ); + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + *render_framesize = get_render_frame_size_samples( hIvasDec->st_ivas->hDecoderConfig ); - /*---------------------------------------------------------------------* - * IVAS_DEC_etRenderFramesizeSamples( ) - * - * Get render framesize in samples - *---------------------------------------------------------------------*/ + return IVAS_ERR_OK; +} - ivas_error IVAS_DEC_GetRenderFramesizeSamples( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t * render_framesize /* o : render framesize in samples */ - ) - { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || render_framesize == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - *render_framesize = get_render_frame_size_samples( hIvasDec->st_ivas->hDecoderConfig ); +/*---------------------------------------------------------------------* + * IVAS_DEC_GetRenderFramesizeMs( ) + * + * Get render framesize in milliseconds + *---------------------------------------------------------------------*/ - return IVAS_ERR_OK; +ivas_error IVAS_DEC_GetRenderFramesizeMs( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint32_t *render_framesize_ms /* o : render framesize in ms */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || render_framesize_ms == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + *render_framesize_ms = get_render_frame_size_ms( hIvasDec->st_ivas->hDecoderConfig->render_num_subframes ); - /*---------------------------------------------------------------------* - * IVAS_DEC_GetRenderFramesizeMs( ) - * - * Get render framesize in milliseconds - *---------------------------------------------------------------------*/ + return IVAS_ERR_OK; +} - ivas_error IVAS_DEC_GetRenderFramesizeMs( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint32_t * render_framesize_ms /* o : render framesize in ms */ - ) - { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || render_framesize_ms == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - *render_framesize_ms = get_render_frame_size_ms( hIvasDec->st_ivas->hDecoderConfig->render_num_subframes ); +/*---------------------------------------------------------------------* + * IVAS_DEC_GetReferencesUpdateFrequency( ) + * + * Get update frequency of the reference vector/orientation + *---------------------------------------------------------------------*/ - return IVAS_ERR_OK; +ivas_error IVAS_DEC_GetReferencesUpdateFrequency( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *update_frequency /* o : update frequency */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || update_frequency == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + *update_frequency = (int16_t) ( IVAS_MAX_PARAM_SPATIAL_SUBFRAMES / hIvasDec->st_ivas->hDecoderConfig->render_num_subframes ); - /*---------------------------------------------------------------------* - * IVAS_DEC_GetReferencesUpdateFrequency( ) - * - * Get update frequency of the reference vector/orientation - *---------------------------------------------------------------------*/ - - ivas_error IVAS_DEC_GetReferencesUpdateFrequency( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t * update_frequency /* o : update frequency */ - ) - { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || update_frequency == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + return IVAS_ERR_OK; +} - *update_frequency = (int16_t) ( IVAS_MAX_PARAM_SPATIAL_SUBFRAMES / hIvasDec->st_ivas->hDecoderConfig->render_num_subframes ); - return IVAS_ERR_OK; - } +/*---------------------------------------------------------------------* + * IVAS_DEC_EnableVoIP( ) + * + * Intitialize JBM + * jbmSafetyMargin: allowed delay reserve in addition to network jitter + * to reduce late-loss, default: 60 [milliseconds] + *---------------------------------------------------------------------*/ +ivas_error IVAS_DEC_EnableVoIP( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t jbmSafetyMargin, /* i : allowed delay reserve for JBM, in milliseconds */ + const IVAS_DEC_INPUT_FORMAT inputFormat /* i : format of the input bitstream */ +) +{ + DECODER_CONFIG_HANDLE hDecoderConfig; + ivas_error error; - /*---------------------------------------------------------------------* - * IVAS_DEC_EnableVoIP( ) - * - * Intitialize JBM - * jbmSafetyMargin: allowed delay reserve in addition to network jitter - * to reduce late-loss, default: 60 [milliseconds] - *---------------------------------------------------------------------*/ - - ivas_error IVAS_DEC_EnableVoIP( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const int16_t jbmSafetyMargin, /* i : allowed delay reserve for JBM, in milliseconds */ - const IVAS_DEC_INPUT_FORMAT inputFormat /* i : format of the input bitstream */ - ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - DECODER_CONFIG_HANDLE hDecoderConfig; - ivas_error error; - - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; + hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; #ifdef DEBUGGING - hIvasDec->Opt_VOIP = 1; + hIvasDec->Opt_VOIP = 1; #endif - hDecoderConfig->Opt_tsm = 1; + hDecoderConfig->Opt_tsm = 1; - if ( hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) - { - hDecoderConfig->nchan_out = audioCfg2channels( hDecoderConfig->output_config ); - } + if ( hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) + { + hDecoderConfig->nchan_out = audioCfg2channels( hDecoderConfig->output_config ); + } #ifdef VARIABLE_SPEED_DECODING - else - { - hDecoderConfig->nchan_out = 1; - } + else + { + hDecoderConfig->nchan_out = 1; + } #endif - if ( ( error = input_format_API_to_internal( inputFormat, &hIvasDec->bitstreamformat, &hIvasDec->sdp_hf_only, true ) ) != IVAS_ERR_OK ) - { - return error; - } + if ( ( error = input_format_API_to_internal( inputFormat, &hIvasDec->bitstreamformat, &hIvasDec->sdp_hf_only, true ) ) != IVAS_ERR_OK ) + { + return error; + } - if ( ( hIvasDec->hVoIP = malloc( sizeof( IVAS_DEC_VOIP ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); - } + if ( ( hIvasDec->hVoIP = malloc( sizeof( IVAS_DEC_VOIP ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); + } - hIvasDec->hVoIP->lastDecodedWasActive = 0; - hIvasDec->hVoIP->hCurrentDataUnit = NULL; - hIvasDec->hVoIP->nSamplesRendered20ms = 0; + hIvasDec->hVoIP->lastDecodedWasActive = 0; + hIvasDec->hVoIP->hCurrentDataUnit = NULL; + hIvasDec->hVoIP->nSamplesRendered20ms = 0; #define WMC_TOOL_SKIP - /* Bitstream conversion is not counted towards complexity and memory usage */ - hIvasDec->hVoIP->bs_conversion_buf = malloc( sizeof( uint16_t ) * ( MAX_BITS_PER_FRAME + 4 * 8 ) ); + /* Bitstream conversion is not counted towards complexity and memory usage */ + hIvasDec->hVoIP->bs_conversion_buf = malloc( sizeof( uint16_t ) * ( MAX_BITS_PER_FRAME + 4 * 8 ) ); #undef WMC_TOOL_SKIP - if ( hIvasDec->hVoIP->bs_conversion_buf == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); - } + if ( hIvasDec->hVoIP->bs_conversion_buf == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); + } - /* initialize JBM */ - if ( ( error = JB4_Create( &hIvasDec->hVoIP->hJBM ) != IVAS_ERR_OK ) != IVAS_ERR_OK ) - { - return error; - } + /* initialize JBM */ + if ( ( error = JB4_Create( &hIvasDec->hVoIP->hJBM ) != IVAS_ERR_OK ) != IVAS_ERR_OK ) + { + return error; + } - if ( JB4_Init( hIvasDec->hVoIP->hJBM, jbmSafetyMargin ) != 0 ) - { - return IVAS_ERR_FAILED_ALLOC; - } + if ( JB4_Init( hIvasDec->hVoIP->hJBM, jbmSafetyMargin ) != 0 ) + { + return IVAS_ERR_FAILED_ALLOC; + } #ifdef NONBE_1122_KEEP_EVS_MODE_UNCHANGED - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) - { - JB4_TMP_SetEvsCompatFlag( hIvasDec->hVoIP->hJBM ); - } + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + { + JB4_TMP_SetEvsCompatFlag( hIvasDec->hVoIP->hJBM ); + } #endif - /* init flush buffer (needed for binaural outputs) */ - if ( ( error = create_flush_buffer( hIvasDec ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError in create_flush_buffer , code: %d\n", error ); - return error; - } - - return IVAS_ERR_OK; + /* init flush buffer (needed for binaural outputs) */ + if ( ( error = create_flush_buffer( hIvasDec ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in create_flush_buffer , code: %d\n", error ); + return error; } + return IVAS_ERR_OK; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_FeedFrame_Serial( ) + * + * + *---------------------------------------------------------------------*/ - /*---------------------------------------------------------------------* - * IVAS_DEC_FeedFrame_Serial( ) - * - * - *---------------------------------------------------------------------*/ +ivas_error IVAS_DEC_FeedFrame_Serial( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint16_t *serial, /* i : buffer containing serial input bitstream. Each bit should be stored as a single uint16_t value */ + const uint16_t num_bits, /* i : number of bits in input bitstream */ + int16_t bfi /* i : bad frame indicator flag */ +) +{ + ivas_error error; - ivas_error IVAS_DEC_FeedFrame_Serial( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint16_t * serial, /* i : buffer containing serial input bitstream. Each bit should be stored as a single uint16_t value */ - const uint16_t num_bits, /* i : number of bits in input bitstream */ - int16_t bfi /* i : bad frame indicator flag */ - ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - ivas_error error; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + if ( !hIvasDec->isInitialized ) + { + /* Once first frame is fed, finish initialization in EVS Mono. + * In IVAS mode, initialization is done in ivas_dec(). */ + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + hIvasDec->st_ivas->hDecoderConfig->ivas_total_brate = ACELP_8k00; + hIvasDec->st_ivas->transport_config = IVAS_AUDIO_CONFIG_MONO; - if ( !hIvasDec->isInitialized ) - { - /* Once first frame is fed, finish initialization in EVS Mono. - * In IVAS mode, initialization is done in ivas_dec(). */ - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + if ( ( error = ivas_init_decoder( hIvasDec->st_ivas ) ) != IVAS_ERR_OK ) { - hIvasDec->st_ivas->hDecoderConfig->ivas_total_brate = ACELP_8k00; - hIvasDec->st_ivas->transport_config = IVAS_AUDIO_CONFIG_MONO; - - if ( ( error = ivas_init_decoder( hIvasDec->st_ivas ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( hIvasDec->hVoIP != NULL && hIvasDec->hVoIP->hCurrentDataUnit != NULL ) - { - DEC_CORE_HANDLE st = hIvasDec->st_ivas->hSCE[0]->hCoreCoder[0]; - st->ini_frame = 0; - st->prev_use_partial_copy = 0; - hIvasDec->st_ivas->hDecoderConfig->ivas_total_brate = hIvasDec->hVoIP->hCurrentDataUnit->dataSize * FRAMES_PER_SEC; - } + return error; + } - hIvasDec->isInitialized = true; + if ( hIvasDec->hVoIP != NULL && hIvasDec->hVoIP->hCurrentDataUnit != NULL ) + { + DEC_CORE_HANDLE st = hIvasDec->st_ivas->hSCE[0]->hCoreCoder[0]; + st->ini_frame = 0; + st->prev_use_partial_copy = 0; + hIvasDec->st_ivas->hDecoderConfig->ivas_total_brate = hIvasDec->hVoIP->hCurrentDataUnit->dataSize * FRAMES_PER_SEC; } - } - if ( !bfi ) /* TODO(mcjbm): Is this ok for bfi == 2 (partial frame)? Is there enough info to fully configure decoder? */ - { - hIvasDec->hasBeenFedFirstGoodFrame = true; + hIvasDec->isInitialized = true; } + } - /* Update redundant frame information in EVS (pre- read indices) */ - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS && hIvasDec->hVoIP != NULL && hIvasDec->hVoIP->hCurrentDataUnit != NULL ) - { - DEC_CORE_HANDLE st = hIvasDec->st_ivas->hSCE[0]->hCoreCoder[0]; - st->bit_stream = serial; + if ( !bfi ) /* TODO(mcjbm): Is this ok for bfi == 2 (partial frame)? Is there enough info to fully configure decoder? */ + { + hIvasDec->hasBeenFedFirstGoodFrame = true; + } - if ( hIvasDec->hVoIP->hCurrentDataUnit->partial_frame || st->prev_use_partial_copy ) - { - st->next_coder_type = hIvasDec->hVoIP->hCurrentDataUnit->nextCoderType; - } - else - { - st->next_coder_type = INACTIVE; - } + /* Update redundant frame information in EVS (pre- read indices) */ + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS && hIvasDec->hVoIP != NULL && hIvasDec->hVoIP->hCurrentDataUnit != NULL ) + { + DEC_CORE_HANDLE st = hIvasDec->st_ivas->hSCE[0]->hCoreCoder[0]; + st->bit_stream = serial; - if ( hIvasDec->hVoIP->hCurrentDataUnit->partial_frame == 1 && bfi != 1 ) - { - bfi = 2; - } + if ( hIvasDec->hVoIP->hCurrentDataUnit->partial_frame || st->prev_use_partial_copy ) + { + st->next_coder_type = hIvasDec->hVoIP->hCurrentDataUnit->nextCoderType; } - - if ( ( error = read_indices( hIvasDec->st_ivas, serial, num_bits, &hIvasDec->prev_ft_speech, &hIvasDec->CNG, bfi ) ) != IVAS_ERR_OK ) + else { - return error; + st->next_coder_type = INACTIVE; } - /* Update redundant frame information in EVS (post- read indices) */ - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS && - hIvasDec->hVoIP != NULL && - hIvasDec->hVoIP->hCurrentDataUnit != NULL && - hIvasDec->hVoIP->hCurrentDataUnit->partial_frame != 0 ) + if ( hIvasDec->hVoIP->hCurrentDataUnit->partial_frame == 1 && bfi != 1 ) { - DEC_CORE_HANDLE st = hIvasDec->st_ivas->hSCE[0]->hCoreCoder[0]; - st->codec_mode = MODE2; - st->use_partial_copy = 1; + bfi = 2; } + } - hIvasDec->needNewFrame = false; - hIvasDec->hasBeenFedFrame = true; - hIvasDec->nSamplesAvailableNext = hIvasDec->nSamplesFrame; + if ( ( error = read_indices( hIvasDec->st_ivas, serial, num_bits, &hIvasDec->prev_ft_speech, &hIvasDec->CNG, bfi ) ) != IVAS_ERR_OK ) + { + return error; + } - return IVAS_ERR_OK; + /* Update redundant frame information in EVS (post- read indices) */ + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS && + hIvasDec->hVoIP != NULL && + hIvasDec->hVoIP->hCurrentDataUnit != NULL && + hIvasDec->hVoIP->hCurrentDataUnit->partial_frame != 0 ) + { + DEC_CORE_HANDLE st = hIvasDec->st_ivas->hSCE[0]->hCoreCoder[0]; + st->codec_mode = MODE2; + st->use_partial_copy = 1; } + hIvasDec->needNewFrame = false; + hIvasDec->hasBeenFedFrame = true; + hIvasDec->nSamplesAvailableNext = hIvasDec->nSamplesFrame; + + return IVAS_ERR_OK; +} - /*---------------------------------------------------------------------* - * renderer_type_to_mode() - * - * Convert (codec library) renderer type to (API public) binaural renderer mode - *---------------------------------------------------------------------*/ - - /*! r: binaural renderer mode (API type) */ - static IVAS_BIN_RENDERER_TYPE renderer_type_to_mode( - const RENDERER_TYPE renderer_type /* i : renderer type (codec library type) */ - ) - { - IVAS_BIN_RENDERER_TYPE binaural_renderer; - - switch ( renderer_type ) - { - case RENDERER_BINAURAL_OBJECTS_TD: - binaural_renderer = IVAS_BIN_RENDERER_TYPE_TDREND; - break; - case RENDERER_BINAURAL_MIXER_CONV: - case RENDERER_BINAURAL_MIXER_CONV_ROOM: - binaural_renderer = IVAS_BIN_RENDERER_TYPE_CREND; - break; - case RENDERER_BINAURAL_FASTCONV: - binaural_renderer = IVAS_BIN_RENDERER_TYPE_FASTCONV; - break; - case RENDERER_BINAURAL_FASTCONV_ROOM: - binaural_renderer = IVAS_BIN_RENDERER_TYPE_FASTCONV; - break; - case RENDERER_BINAURAL_PARAMETRIC: - case RENDERER_BINAURAL_PARAMETRIC_ROOM: - binaural_renderer = IVAS_BIN_RENDERER_TYPE_PARAMBIN; - break; - default: - binaural_renderer = IVAS_BIN_RENDERER_TYPE_NONE; - break; - } - return binaural_renderer; +/*---------------------------------------------------------------------* + * renderer_type_to_mode() + * + * Convert (codec library) renderer type to (API public) binaural renderer mode + *---------------------------------------------------------------------*/ + +/*! r: binaural renderer mode (API type) */ +static IVAS_BIN_RENDERER_TYPE renderer_type_to_mode( + const RENDERER_TYPE renderer_type /* i : renderer type (codec library type) */ +) +{ + IVAS_BIN_RENDERER_TYPE binaural_renderer; + + switch ( renderer_type ) + { + case RENDERER_BINAURAL_OBJECTS_TD: + binaural_renderer = IVAS_BIN_RENDERER_TYPE_TDREND; + break; + case RENDERER_BINAURAL_MIXER_CONV: + case RENDERER_BINAURAL_MIXER_CONV_ROOM: + binaural_renderer = IVAS_BIN_RENDERER_TYPE_CREND; + break; + case RENDERER_BINAURAL_FASTCONV: + binaural_renderer = IVAS_BIN_RENDERER_TYPE_FASTCONV; + break; + case RENDERER_BINAURAL_FASTCONV_ROOM: + binaural_renderer = IVAS_BIN_RENDERER_TYPE_FASTCONV; + break; + case RENDERER_BINAURAL_PARAMETRIC: + case RENDERER_BINAURAL_PARAMETRIC_ROOM: + binaural_renderer = IVAS_BIN_RENDERER_TYPE_PARAMBIN; + break; + default: + binaural_renderer = IVAS_BIN_RENDERER_TYPE_NONE; + break; } + return binaural_renderer; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_ReadFormat( ) + * + * Read main parameters from the bitstream to set-up the decoder: + * - IVAS format + * - IVAS format specific signaling + * - compensate for renderer granularity change in JBM + *---------------------------------------------------------------------*/ - /*---------------------------------------------------------------------* - * IVAS_DEC_ReadFormat( ) - * - * Read main parameters from the bitstream to set-up the decoder: - * - IVAS format - * - IVAS format specific signaling - * - compensate for renderer granularity change in JBM - *---------------------------------------------------------------------*/ +ivas_error IVAS_DEC_ReadFormat( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_BIN_RENDERER_TYPE *binaural_renderer, /* o : binaural renderer type */ + IVAS_BIN_RENDERER_TYPE *binaural_renderer_sec, /* o : secondary binaural renderer type */ + IVAS_AUDIO_CONFIG *hrtf_set_audio_cfg /* o : HRTF set audio config. */ +) +{ + ivas_error error; + Decoder_Struct *st_ivas; + ISM_MODE ism_mode_old; + MC_MODE mc_mode_old; + int16_t nchan_transport_old; + AUDIO_CONFIG intern_config_old, transport_config_old, output_config; + RENDERER_TYPE renderer_type_old, renderer_type_sec_new, renderer_type_sec_old; - ivas_error IVAS_DEC_ReadFormat( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_BIN_RENDERER_TYPE * binaural_renderer, /* o : binaural renderer type */ - IVAS_BIN_RENDERER_TYPE * binaural_renderer_sec, /* o : secondary binaural renderer type */ - IVAS_AUDIO_CONFIG * hrtf_set_audio_cfg /* o : HRTF set audio config. */ - ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - ivas_error error; - Decoder_Struct *st_ivas; - ISM_MODE ism_mode_old; - MC_MODE mc_mode_old; - int16_t nchan_transport_old; - AUDIO_CONFIG intern_config_old, transport_config_old, output_config; - RENDERER_TYPE renderer_type_old, renderer_type_sec_new, renderer_type_sec_old; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + st_ivas = hIvasDec->st_ivas; + ism_mode_old = st_ivas->ism_mode; + mc_mode_old = st_ivas->mc_mode; + nchan_transport_old = st_ivas->nchan_transport; + intern_config_old = st_ivas->intern_config; + transport_config_old = st_ivas->transport_config; + renderer_type_old = st_ivas->renderer_type; + renderer_type_sec_old = ivas_renderer_secondary_select( st_ivas ); - st_ivas = hIvasDec->st_ivas; - ism_mode_old = st_ivas->ism_mode; - mc_mode_old = st_ivas->mc_mode; - nchan_transport_old = st_ivas->nchan_transport; - intern_config_old = st_ivas->intern_config; - transport_config_old = st_ivas->transport_config; - renderer_type_old = st_ivas->renderer_type; - renderer_type_sec_old = ivas_renderer_secondary_select( st_ivas ); + output_config = st_ivas->hDecoderConfig->output_config; - output_config = st_ivas->hDecoderConfig->output_config; + if ( st_ivas->ivas_format == MONO_FORMAT ) + { + return IVAS_ERR_OK; + } - if ( st_ivas->ivas_format == MONO_FORMAT ) + if ( st_ivas->bfi == 0 ) + { + if ( ( error = ivas_dec_get_format( st_ivas ) ) != IVAS_ERR_OK ) { - return IVAS_ERR_OK; + return error; } - if ( st_ivas->bfi == 0 ) + if ( st_ivas->restartNeeded == 1 ) { - if ( ( error = ivas_dec_get_format( st_ivas ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( st_ivas->restartNeeded == 1 ) - { - return IVAS_ERR_OK; - } + return IVAS_ERR_OK; + } - /* Select binaural renderer */ - ivas_renderer_select( st_ivas ); - *binaural_renderer = renderer_type_to_mode( st_ivas->renderer_type ); + /* Select binaural renderer */ + ivas_renderer_select( st_ivas ); + *binaural_renderer = renderer_type_to_mode( st_ivas->renderer_type ); - /* Select secondary binaural renderer (used in combined formats) */ - renderer_type_sec_new = ivas_renderer_secondary_select( st_ivas ); - *binaural_renderer_sec = renderer_type_to_mode( renderer_type_sec_new ); + /* Select secondary binaural renderer (used in combined formats) */ + renderer_type_sec_new = ivas_renderer_secondary_select( st_ivas ); + *binaural_renderer_sec = renderer_type_to_mode( renderer_type_sec_new ); - /* select HRTF audio configuration to load the right HRTF set for the external binary file */ - *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_INVALID; - if ( *binaural_renderer == IVAS_BIN_RENDERER_TYPE_FASTCONV ) + /* select HRTF audio configuration to load the right HRTF set for the external binary file */ + *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_INVALID; + if ( *binaural_renderer == IVAS_BIN_RENDERER_TYPE_FASTCONV ) + { + if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) { - if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) - { - /* SHD HRIRs */ - *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_HOA3; + /* SHD HRIRs */ + *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_HOA3; - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) - { - /* BRIRs */ - *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_7_1_4; - } - } - else if ( st_ivas->ivas_format == MC_FORMAT ) + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) { - /* HRIRs */ + /* BRIRs */ *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_7_1_4; - - if ( ( st_ivas->hDecoderConfig->Opt_Headrotation ) && - !( st_ivas->mc_mode == MC_MODE_PARAMUPMIX && output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) ) - { - /* SHD HRIRs for low complexity rotation */ - *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_HOA3; - } } } - else if ( *binaural_renderer == IVAS_BIN_RENDERER_TYPE_CREND ) + else if ( st_ivas->ivas_format == MC_FORMAT ) { - if ( st_ivas->ivas_format == ISM_FORMAT ) + /* HRIRs */ + *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_7_1_4; + + if ( ( st_ivas->hDecoderConfig->Opt_Headrotation ) && + !( st_ivas->mc_mode == MC_MODE_PARAMUPMIX && output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) ) { - /* BRIRs */ - *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_7_1_4; + /* SHD HRIRs for low complexity rotation */ + *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_HOA3; } - else if ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCT ) - { - /* BRIRs */ - *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_7_1_4; + } + } + else if ( *binaural_renderer == IVAS_BIN_RENDERER_TYPE_CREND ) + { + if ( st_ivas->ivas_format == ISM_FORMAT ) + { + /* BRIRs */ + *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_7_1_4; + } + else if ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCT ) + { + /* BRIRs */ + *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_7_1_4; - if ( st_ivas->hDecoderConfig->Opt_Headrotation && ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) - { - /* SHD HRIRs for low complexity rotation */ - *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_HOA3; - } + if ( st_ivas->hDecoderConfig->Opt_Headrotation && ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) + { + /* SHD HRIRs for low complexity rotation */ + *hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_HOA3; } } + } - /* JBM: compensate when binaural renderer granularity changes (happens in bitrate switching) */ - if ( st_ivas->ini_active_frame > 0 && st_ivas->hDecoderConfig->Opt_tsm && - ( ( renderer_type_old != st_ivas->renderer_type ) || - ( renderer_type_sec_old != renderer_type_sec_new ) ) ) - { - int16_t tc_granularity_new = ivas_dec_get_render_granularity( st_ivas->renderer_type, renderer_type_sec_new, st_ivas->hDecoderConfig->output_Fs ); + /* JBM: compensate when binaural renderer granularity changes (happens in bitrate switching) */ + if ( st_ivas->ini_active_frame > 0 && st_ivas->hDecoderConfig->Opt_tsm && + ( ( renderer_type_old != st_ivas->renderer_type ) || + ( renderer_type_sec_old != renderer_type_sec_new ) ) ) + { + int16_t tc_granularity_new = ivas_dec_get_render_granularity( st_ivas->renderer_type, renderer_type_sec_new, st_ivas->hDecoderConfig->output_Fs ); - st_ivas->nchan_transport = nchan_transport_old; + st_ivas->nchan_transport = nchan_transport_old; - if ( st_ivas->hTcBuffer == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + if ( st_ivas->hTcBuffer == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - /* when granularity goes down, render what still fits in the new granularity */ - if ( tc_granularity_new < st_ivas->hTcBuffer->n_samples_granularity ) + /* when granularity goes down, render what still fits in the new granularity */ + if ( tc_granularity_new < st_ivas->hTcBuffer->n_samples_granularity ) + { + if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, tc_granularity_new, renderer_type_old, intern_config_old, &st_ivas->hIntSetup, mc_mode_old, ism_mode_old, &hIvasDec->nSamplesFlushed, pcm_type_API_to_internal( hIvasDec->pcmType ), hIvasDec->flushbuffer ) ) != IVAS_ERR_OK ) { - if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, tc_granularity_new, renderer_type_old, intern_config_old, &st_ivas->hIntSetup, mc_mode_old, ism_mode_old, &hIvasDec->nSamplesFlushed, pcm_type_API_to_internal( hIvasDec->pcmType ), hIvasDec->flushbuffer ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } } } + } + + st_ivas->ism_mode = ism_mode_old; + st_ivas->mc_mode = mc_mode_old; + st_ivas->nchan_transport = nchan_transport_old; + st_ivas->intern_config = intern_config_old; + st_ivas->transport_config = transport_config_old; + st_ivas->renderer_type = renderer_type_old; + + return IVAS_ERR_OK; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_GetSamplesDecoder( ) + * + * Main function to run setup, decode transport channels, do TSM and feed to renderer. + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_GetSamplesDecoder( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ +) +{ + ivas_error error; + Decoder_Struct *st_ivas; + uint16_t nTimeScalerOutSamples; + uint8_t nTransportChannels; + int16_t nResidualSamples, nSamplesTcsScaled; + bool isInitialized_voip; - st_ivas->ism_mode = ism_mode_old; - st_ivas->mc_mode = mc_mode_old; - st_ivas->nchan_transport = nchan_transport_old; - st_ivas->intern_config = intern_config_old; - st_ivas->transport_config = transport_config_old; - st_ivas->renderer_type = renderer_type_old; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + if ( !hIvasDec->hasBeenFedFirstGoodFrame && !hIvasDec->isInitialized ) /* note: 'isInitialized' is related to EVS decoder */ + { return IVAS_ERR_OK; } + st_ivas = hIvasDec->st_ivas; - /*---------------------------------------------------------------------* - * IVAS_DEC_GetSamplesDecoder( ) - * - * Main function to run setup, decode transport channels, do TSM and feed to renderer. - *---------------------------------------------------------------------*/ + isInitialized_voip = hIvasDec->hTimeScaler != NULL; - ivas_error IVAS_DEC_GetSamplesDecoder( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - ISAR_SPLIT_REND_BITS_DATA * splitRendBits /* o : output split rendering bits */ - ) + if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) /* wait for the first good frame */ { - ivas_error error; - Decoder_Struct *st_ivas; - uint16_t nTimeScalerOutSamples; - uint8_t nTransportChannels; - int16_t nResidualSamples, nSamplesTcsScaled; - bool isInitialized_voip; + /*-----------------------------------------------------------------* + * Setup all decoder parts (IVAS decoder, ISAR) + *-----------------------------------------------------------------*/ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + if ( ( error = ivas_dec_setup_all( hIvasDec, &nTransportChannels, splitRendBits ) ) != IVAS_ERR_OK ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + return error; } - if ( !hIvasDec->hasBeenFedFirstGoodFrame && !hIvasDec->isInitialized ) /* note: 'isInitialized' is related to EVS decoder */ + /*-----------------------------------------------------------------* + * IVAS decoder: decode transport channels and metadata + *-----------------------------------------------------------------*/ + + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) { - return IVAS_ERR_OK; + if ( ( error = evs_dec_main( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } } - - st_ivas = hIvasDec->st_ivas; - - isInitialized_voip = hIvasDec->hTimeScaler != NULL; - - if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) /* wait for the first good frame */ + else if ( hIvasDec->mode == IVAS_DEC_MODE_IVAS ) { - /*-----------------------------------------------------------------* - * Setup all decoder parts (IVAS decoder, ISAR) - *-----------------------------------------------------------------*/ - - if ( ( error = ivas_dec_setup_all( hIvasDec, &nTransportChannels, splitRendBits ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_dec( st_ivas ) ) != IVAS_ERR_OK ) { return error; } - /*-----------------------------------------------------------------* - * IVAS decoder: decode transport channels and metadata - *-----------------------------------------------------------------*/ + hIvasDec->isInitialized = true; /* Initialization done in ivas_dec() */ + } + + if ( hIvasDec->hasBeenFedFirstGoodFrame ) + { + hIvasDec->hasDecodedFirstGoodFrame = true; + } - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) - { - if ( ( error = evs_dec_main( st_ivas ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( hIvasDec->mode == IVAS_DEC_MODE_IVAS ) + /*-----------------------------------------------------------------* + * JBM + *-----------------------------------------------------------------*/ + + if ( st_ivas->hDecoderConfig->Opt_tsm ) + { + if ( nTransportChannels != hIvasDec->nTransportChannelsOld ) { - if ( ( error = ivas_dec( st_ivas ) ) != IVAS_ERR_OK ) + if ( ( error = apa_setup( hIvasDec, isInitialized_voip, nTransportChannels ) ) != IVAS_ERR_OK ) { return error; } - - hIvasDec->isInitialized = true; /* Initialization done in ivas_dec() */ } - if ( hIvasDec->hasBeenFedFirstGoodFrame ) + if ( apa_set_scale( hIvasDec->hTimeScaler, hIvasDec->tsm_scale ) != 0 ) { - hIvasDec->hasDecodedFirstGoodFrame = true; + return IVAS_ERR_UNKNOWN; } - /*-----------------------------------------------------------------* - * JBM - *-----------------------------------------------------------------*/ + /* convert deinterleaved decoded TC audio channels buffer to an interleaved one */ + ivas_buffer_deinterleaved_to_interleaved( st_ivas->p_output_f, st_ivas->hTcBuffer->tc_buffer, nTransportChannels, hIvasDec->nSamplesFrame ); - if ( st_ivas->hDecoderConfig->Opt_tsm ) + /* time-scale modification */ + if ( apa_exec( hIvasDec->hTimeScaler, st_ivas->hTcBuffer->tc_buffer, hIvasDec->nSamplesFrame * nTransportChannels, (uint16_t) hIvasDec->tsm_max_scaling, st_ivas->hTcBuffer->tc_buffer, &nTimeScalerOutSamples ) != 0 ) { - if ( nTransportChannels != hIvasDec->nTransportChannelsOld ) - { - if ( ( error = apa_setup( hIvasDec, isInitialized_voip, nTransportChannels ) ) != IVAS_ERR_OK ) - { - return error; - } - } + return IVAS_ERR_UNKNOWN; + } - if ( apa_set_scale( hIvasDec->hTimeScaler, hIvasDec->tsm_scale ) != 0 ) - { - return IVAS_ERR_UNKNOWN; - } - - /* convert deinterleaved decoded TC audio channels buffer to an interleaved one */ - ivas_buffer_deinterleaved_to_interleaved( st_ivas->p_output_f, st_ivas->hTcBuffer->tc_buffer, nTransportChannels, hIvasDec->nSamplesFrame ); - - /* time-scale modification */ - if ( apa_exec( hIvasDec->hTimeScaler, st_ivas->hTcBuffer->tc_buffer, hIvasDec->nSamplesFrame * nTransportChannels, (uint16_t) hIvasDec->tsm_max_scaling, st_ivas->hTcBuffer->tc_buffer, &nTimeScalerOutSamples ) != 0 ) - { - return IVAS_ERR_UNKNOWN; - } - - assert( nTimeScalerOutSamples <= APA_BUF ); - nSamplesTcsScaled = nTimeScalerOutSamples / nTransportChannels; - hIvasDec->timeScalingDone = 1; + assert( nTimeScalerOutSamples <= APA_BUF ); + nSamplesTcsScaled = nTimeScalerOutSamples / nTransportChannels; + hIvasDec->timeScalingDone = 1; - /* convert interleaved time-scaled TC audio channels buffer to deinterleaved one */ - ivas_buffer_interleaved_to_deinterleaved( st_ivas->hTcBuffer->tc_buffer, st_ivas->p_output_f, nTransportChannels, nSamplesTcsScaled ); - } - else - { - nSamplesTcsScaled = hIvasDec->nSamplesFrame; - } + /* convert interleaved time-scaled TC audio channels buffer to deinterleaved one */ + ivas_buffer_interleaved_to_deinterleaved( st_ivas->hTcBuffer->tc_buffer, st_ivas->p_output_f, nTransportChannels, nSamplesTcsScaled ); + } + else + { + nSamplesTcsScaled = hIvasDec->nSamplesFrame; + } - /*-----------------------------------------------------------------* - * Feed decoded transport channels samples to the renderer - *-----------------------------------------------------------------*/ + /*-----------------------------------------------------------------* + * Feed decoded transport channels samples to the renderer + *-----------------------------------------------------------------*/ - ivas_dec_feed_tc_to_renderer( st_ivas, nSamplesTcsScaled, &nResidualSamples ); + ivas_dec_feed_tc_to_renderer( st_ivas, nSamplesTcsScaled, &nResidualSamples ); - if ( st_ivas->hDecoderConfig->Opt_tsm ) + if ( st_ivas->hDecoderConfig->Opt_tsm ) + { + /* feed residual samples to TSM for the next call */ + if ( apa_set_renderer_residual_samples( hIvasDec->hTimeScaler, (uint16_t) nResidualSamples ) != 0 ) { - /* feed residual samples to TSM for the next call */ - if ( apa_set_renderer_residual_samples( hIvasDec->hTimeScaler, (uint16_t) nResidualSamples ) != 0 ) - { - return IVAS_ERR_UNKNOWN; - } + return IVAS_ERR_UNKNOWN; } - - hIvasDec->hasBeenFedFrame = false; } - hIvasDec->hasBeenPreparedRendering = false; + hIvasDec->hasBeenFedFrame = false; + } - /*-----------------------------------------------------------------* - * Set editable metadata - *-----------------------------------------------------------------*/ + hIvasDec->hasBeenPreparedRendering = false; + + /*-----------------------------------------------------------------* + * Set editable metadata + *-----------------------------------------------------------------*/ - if ( st_ivas->hIsmMetaData[0] ) + if ( st_ivas->hIsmMetaData[0] ) + { + if ( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) { - if ( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) + if ( st_ivas->ism_mode == ISM_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { - if ( st_ivas->ism_mode == ISM_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + int16_t obj; + ISM_METADATA_HANDLE *hIsmMetaData = st_ivas->hIsmMetaData; + for ( obj = 0; obj < st_ivas->nchan_ism; obj++ ) { - int16_t obj; - ISM_METADATA_HANDLE *hIsmMetaData = st_ivas->hIsmMetaData; - for ( obj = 0; obj < st_ivas->nchan_ism; obj++ ) - { - hIsmMetaData[obj]->edited_azimuth = hIsmMetaData[obj]->azimuth; - hIsmMetaData[obj]->edited_elevation = hIsmMetaData[obj]->elevation; - hIsmMetaData[obj]->edited_yaw = hIsmMetaData[obj]->yaw; - hIsmMetaData[obj]->edited_pitch = hIsmMetaData[obj]->pitch; - hIsmMetaData[obj]->edited_radius = hIsmMetaData[obj]->radius; - hIsmMetaData[obj]->edited_gain = 1.0f; - } + hIsmMetaData[obj]->edited_azimuth = hIsmMetaData[obj]->azimuth; + hIsmMetaData[obj]->edited_elevation = hIsmMetaData[obj]->elevation; + hIsmMetaData[obj]->edited_yaw = hIsmMetaData[obj]->yaw; + hIsmMetaData[obj]->edited_pitch = hIsmMetaData[obj]->pitch; + hIsmMetaData[obj]->edited_radius = hIsmMetaData[obj]->radius; + hIsmMetaData[obj]->edited_gain = 1.0f; + } - if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) - { - st_ivas->hSbaIsmData->gain_bed = 1.0f; - } + if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + st_ivas->hSbaIsmData->gain_bed = 1.0f; } } } + } - if ( st_ivas->hParamIsmDec != NULL ) + if ( st_ivas->hParamIsmDec != NULL ) + { + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { - if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + int16_t obj = 0; + PARAM_ISM_DEC_HANDLE hParamIsmDec = st_ivas->hParamIsmDec; + for ( obj = 0; obj < st_ivas->nchan_ism; obj++ ) { - int16_t obj = 0; - PARAM_ISM_DEC_HANDLE hParamIsmDec = st_ivas->hParamIsmDec; - for ( obj = 0; obj < st_ivas->nchan_ism; obj++ ) - { - hParamIsmDec->edited_azimuth_values[obj] = hParamIsmDec->azimuth_values[obj]; - hParamIsmDec->edited_elevation_values[obj] = hParamIsmDec->elevation_values[obj]; - } + hParamIsmDec->edited_azimuth_values[obj] = hParamIsmDec->azimuth_values[obj]; + hParamIsmDec->edited_elevation_values[obj] = hParamIsmDec->elevation_values[obj]; } } - - return IVAS_ERR_OK; } + return IVAS_ERR_OK; +} - /*---------------------------------------------------------------------* - * IVAS_DEC_GetEditableParameters( ) - * - * Get editable metadata parameters - *---------------------------------------------------------------------*/ - ivas_error IVAS_DEC_GetEditableParameters( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_EDITABLE_PARAMETERS * hIvasEditableParameters /* o : object editing parameters handle */ - ) - { - int16_t dirac_read_idx, obj; - Decoder_Struct *st_ivas; - ISM_MODE ism_mode; +/*---------------------------------------------------------------------* + * IVAS_DEC_GetEditableParameters( ) + * + * Get editable metadata parameters + *---------------------------------------------------------------------*/ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasEditableParameters == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } +ivas_error IVAS_DEC_GetEditableParameters( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_EDITABLE_PARAMETERS *hIvasEditableParameters /* o : object editing parameters handle */ +) +{ + int16_t dirac_read_idx, obj; + Decoder_Struct *st_ivas; + ISM_MODE ism_mode; - if ( !hIvasDec->hasBeenFedFirstGoodFrame ) - { - hIvasEditableParameters->num_obj = 0; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasEditableParameters == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - return IVAS_ERR_OK; - } + if ( !hIvasDec->hasBeenFedFirstGoodFrame ) + { + hIvasEditableParameters->num_obj = 0; - st_ivas = hIvasDec->st_ivas; - ism_mode = st_ivas->ism_mode; + return IVAS_ERR_OK; + } - if ( !( st_ivas->ivas_format == ISM_FORMAT || - st_ivas->ivas_format == SBA_ISM_FORMAT || - st_ivas->ivas_format == MASA_ISM_FORMAT || - ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nchan_ism > 0 ) ) ) - { - return IVAS_ERROR( IVAS_ERR_OBJECTS_EDITING_NOT_SUPPORTED, "Object editing is not supported in this operation mode." ); - } + st_ivas = hIvasDec->st_ivas; + ism_mode = st_ivas->ism_mode; + + if ( !( st_ivas->ivas_format == ISM_FORMAT || + st_ivas->ivas_format == SBA_ISM_FORMAT || + st_ivas->ivas_format == MASA_ISM_FORMAT || + ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nchan_ism > 0 ) ) ) + { + return IVAS_ERROR( IVAS_ERR_OBJECTS_EDITING_NOT_SUPPORTED, "Object editing is not supported in this operation mode." ); + } - hIvasEditableParameters->gain_bed = 1.0f; - hIvasEditableParameters->num_obj = st_ivas->nchan_ism; - if ( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) + hIvasEditableParameters->gain_bed = 1.0f; + hIvasEditableParameters->num_obj = st_ivas->nchan_ism; + if ( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) + { + if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) { - if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) { - for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) - { - hIvasEditableParameters->ism_metadata[obj].azimuth = st_ivas->hIsmMetaData[obj]->azimuth; - hIvasEditableParameters->ism_metadata[obj].elevation = st_ivas->hIsmMetaData[obj]->elevation; - hIvasEditableParameters->ism_metadata[obj].yaw = st_ivas->hIsmMetaData[obj]->yaw; - hIvasEditableParameters->ism_metadata[obj].pitch = st_ivas->hIsmMetaData[obj]->pitch; - hIvasEditableParameters->ism_metadata[obj].radius = st_ivas->hIsmMetaData[obj]->radius; - hIvasEditableParameters->ism_metadata[obj].gain = st_ivas->hIsmMetaData[obj]->edited_gain; - hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = st_ivas->hIsmMetaData[obj]->non_diegetic_flag; - } - - if ( ism_mode == ISM_SBA_MODE_DISC ) - { - hIvasEditableParameters->gain_bed = 1.0f; - } + hIvasEditableParameters->ism_metadata[obj].azimuth = st_ivas->hIsmMetaData[obj]->azimuth; + hIvasEditableParameters->ism_metadata[obj].elevation = st_ivas->hIsmMetaData[obj]->elevation; + hIvasEditableParameters->ism_metadata[obj].yaw = st_ivas->hIsmMetaData[obj]->yaw; + hIvasEditableParameters->ism_metadata[obj].pitch = st_ivas->hIsmMetaData[obj]->pitch; + hIvasEditableParameters->ism_metadata[obj].radius = st_ivas->hIsmMetaData[obj]->radius; + hIvasEditableParameters->ism_metadata[obj].gain = st_ivas->hIsmMetaData[obj]->edited_gain; + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = st_ivas->hIsmMetaData[obj]->non_diegetic_flag; } - else if ( ism_mode == ISM_MODE_PARAM ) + + if ( ism_mode == ISM_SBA_MODE_DISC ) { - for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) - { - hIvasEditableParameters->ism_metadata[obj].azimuth = st_ivas->hParamIsmDec->azimuth_values[obj]; - hIvasEditableParameters->ism_metadata[obj].elevation = st_ivas->hParamIsmDec->elevation_values[obj]; - hIvasEditableParameters->ism_metadata[obj].yaw = 0.0f; - hIvasEditableParameters->ism_metadata[obj].pitch = 0.0f; - hIvasEditableParameters->ism_metadata[obj].radius = 0.0f; - hIvasEditableParameters->ism_metadata[obj].gain = 1.0f; - hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = 0; - } + hIvasEditableParameters->gain_bed = 1.0f; } - else if ( ism_mode == ISM_MODE_NONE ) + } + else if ( ism_mode == ISM_MODE_PARAM ) + { + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) { - hIvasEditableParameters->num_obj = 0; + hIvasEditableParameters->ism_metadata[obj].azimuth = st_ivas->hParamIsmDec->azimuth_values[obj]; + hIvasEditableParameters->ism_metadata[obj].elevation = st_ivas->hParamIsmDec->elevation_values[obj]; + hIvasEditableParameters->ism_metadata[obj].yaw = 0.0f; + hIvasEditableParameters->ism_metadata[obj].pitch = 0.0f; + hIvasEditableParameters->ism_metadata[obj].radius = 0.0f; + hIvasEditableParameters->ism_metadata[obj].gain = 1.0f; + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = 0; } + } + else if ( ism_mode == ISM_MODE_NONE ) + { + hIvasEditableParameters->num_obj = 0; + } #ifdef DEBUGGING - else + else + { + assert( 0 && "This should never happen!" ); + } +#endif + } + else if ( st_ivas->ivas_format == MASA_ISM_FORMAT || ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nchan_ism > 0 ) ) + { + /* object editing possible only in two highest OMASA modes */ + if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) + { + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) { - assert( 0 && "This should never happen!" ); + hIvasEditableParameters->ism_metadata[obj].azimuth = st_ivas->hIsmMetaData[obj]->azimuth; + hIvasEditableParameters->ism_metadata[obj].elevation = st_ivas->hIsmMetaData[obj]->elevation; + hIvasEditableParameters->ism_metadata[obj].yaw = st_ivas->hIsmMetaData[obj]->yaw; + hIvasEditableParameters->ism_metadata[obj].pitch = st_ivas->hIsmMetaData[obj]->pitch; + hIvasEditableParameters->ism_metadata[obj].radius = st_ivas->hIsmMetaData[obj]->radius; + + /* reset the otherwise unused "gain" field for the object */ + st_ivas->hIsmMetaData[obj]->edited_gain = 1.0f; + hIvasEditableParameters->ism_metadata[obj].gain = st_ivas->hIsmMetaData[obj]->edited_gain; + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = st_ivas->hIsmMetaData[obj]->non_diegetic_flag; } -#endif } - else if ( st_ivas->ivas_format == MASA_ISM_FORMAT || ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nchan_ism > 0 ) ) + else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) { - /* object editing possible only in two highest OMASA modes */ - if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC ) + /* Handle MONO output */ + if ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX ) { - for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) - { - hIvasEditableParameters->ism_metadata[obj].azimuth = st_ivas->hIsmMetaData[obj]->azimuth; - hIvasEditableParameters->ism_metadata[obj].elevation = st_ivas->hIsmMetaData[obj]->elevation; - hIvasEditableParameters->ism_metadata[obj].yaw = st_ivas->hIsmMetaData[obj]->yaw; - hIvasEditableParameters->ism_metadata[obj].pitch = st_ivas->hIsmMetaData[obj]->pitch; - hIvasEditableParameters->ism_metadata[obj].radius = st_ivas->hIsmMetaData[obj]->radius; - - /* reset the otherwise unused "gain" field for the object */ - st_ivas->hIsmMetaData[obj]->edited_gain = 1.0f; - hIvasEditableParameters->ism_metadata[obj].gain = st_ivas->hIsmMetaData[obj]->edited_gain; - hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = st_ivas->hIsmMetaData[obj]->non_diegetic_flag; - } + dirac_read_idx = st_ivas->hSpatParamRendCom->render_to_md_map[st_ivas->hSpatParamRendCom->subframes_rendered]; } - else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + else { - /* Handle MONO output */ - if ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX ) - { - dirac_read_idx = st_ivas->hSpatParamRendCom->render_to_md_map[st_ivas->hSpatParamRendCom->subframes_rendered]; - } - else - { - dirac_read_idx = 0; - } + dirac_read_idx = 0; + } - for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) - { - hIvasEditableParameters->ism_metadata[obj].azimuth = st_ivas->hMasaIsmData->azimuth_ism[obj][dirac_read_idx]; - hIvasEditableParameters->ism_metadata[obj].elevation = st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx]; + for ( obj = 0; obj < hIvasEditableParameters->num_obj; obj++ ) + { + hIvasEditableParameters->ism_metadata[obj].azimuth = st_ivas->hMasaIsmData->azimuth_ism[obj][dirac_read_idx]; + hIvasEditableParameters->ism_metadata[obj].elevation = st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx]; - hIvasEditableParameters->ism_metadata[obj].yaw = st_ivas->hIsmMetaData[obj]->yaw; - hIvasEditableParameters->ism_metadata[obj].pitch = st_ivas->hIsmMetaData[obj]->pitch; - hIvasEditableParameters->ism_metadata[obj].radius = st_ivas->hIsmMetaData[obj]->radius; + hIvasEditableParameters->ism_metadata[obj].yaw = st_ivas->hIsmMetaData[obj]->yaw; + hIvasEditableParameters->ism_metadata[obj].pitch = st_ivas->hIsmMetaData[obj]->pitch; + hIvasEditableParameters->ism_metadata[obj].radius = st_ivas->hIsmMetaData[obj]->radius; - /* reset the otherwise unused "gain" field for the object */ - st_ivas->hIsmMetaData[obj]->edited_gain = 1.0f; - hIvasEditableParameters->ism_metadata[obj].gain = st_ivas->hIsmMetaData[obj]->edited_gain; - hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = st_ivas->hIsmMetaData[obj]->non_diegetic_flag; - } - } - else if ( ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || ism_mode == ISM_MODE_NONE ) - { - hIvasEditableParameters->num_obj = 0; + /* reset the otherwise unused "gain" field for the object */ + st_ivas->hIsmMetaData[obj]->edited_gain = 1.0f; + hIvasEditableParameters->ism_metadata[obj].gain = st_ivas->hIsmMetaData[obj]->edited_gain; + hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = st_ivas->hIsmMetaData[obj]->non_diegetic_flag; } + } + else if ( ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || ism_mode == ISM_MODE_NONE ) + { + hIvasEditableParameters->num_obj = 0; + } #ifdef DEBUGGING - else - { - assert( 0 && "This should never happen!" ); - } -#endif + else + { + assert( 0 && "This should never happen!" ); } - - return IVAS_ERR_OK; +#endif } + return IVAS_ERR_OK; +} - /*---------------------------------------------------------------------* - * IVAS_DEC_SetEditableParameters( ) - * - * Set editable metadata parameters - *---------------------------------------------------------------------*/ - ivas_error IVAS_DEC_SetEditableParameters( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_EDITABLE_PARAMETERS hIvasEditableParameters /* i : object editing parameters handle */ - ) +/*---------------------------------------------------------------------* + * IVAS_DEC_SetEditableParameters( ) + * + * Set editable metadata parameters + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_SetEditableParameters( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_EDITABLE_PARAMETERS hIvasEditableParameters /* i : object editing parameters handle */ +) +{ + int16_t dirac_read_idx, obj; + Decoder_Struct *st_ivas; + ISM_MODE ism_mode; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - int16_t dirac_read_idx, obj; - Decoder_Struct *st_ivas; - ISM_MODE ism_mode; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + if ( !hIvasDec->hasBeenFedFirstGoodFrame ) + { + return IVAS_ERR_OK; + } - if ( !hIvasDec->hasBeenFedFirstGoodFrame ) - { - return IVAS_ERR_OK; - } + st_ivas = hIvasDec->st_ivas; + ism_mode = st_ivas->ism_mode; - st_ivas = hIvasDec->st_ivas; - ism_mode = st_ivas->ism_mode; + if ( !( st_ivas->ivas_format == ISM_FORMAT || + st_ivas->ivas_format == SBA_ISM_FORMAT || + st_ivas->ivas_format == MASA_ISM_FORMAT || + ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nchan_ism > 0 ) ) ) + { + return IVAS_ERROR( IVAS_ERR_OBJECTS_EDITING_NOT_SUPPORTED, "Object editing no supported in this operation mode." ); + } - if ( !( st_ivas->ivas_format == ISM_FORMAT || - st_ivas->ivas_format == SBA_ISM_FORMAT || - st_ivas->ivas_format == MASA_ISM_FORMAT || - ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nchan_ism > 0 ) ) ) + if ( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) + { + if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) { - return IVAS_ERROR( IVAS_ERR_OBJECTS_EDITING_NOT_SUPPORTED, "Object editing no supported in this operation mode." ); - } +#ifdef DEBUGGING + assert( hIvasEditableParameters.num_obj == st_ivas->nchan_ism ); +#endif + for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) + { + st_ivas->hIsmMetaData[obj]->edited_azimuth = hIvasEditableParameters.ism_metadata[obj].azimuth; + st_ivas->hIsmMetaData[obj]->edited_elevation = hIvasEditableParameters.ism_metadata[obj].elevation; + st_ivas->hIsmMetaData[obj]->edited_radius = hIvasEditableParameters.ism_metadata[obj].radius; + st_ivas->hIsmMetaData[obj]->edited_yaw = hIvasEditableParameters.ism_metadata[obj].yaw; + st_ivas->hIsmMetaData[obj]->edited_pitch = hIvasEditableParameters.ism_metadata[obj].pitch; + if ( hIvasEditableParameters.ism_metadata[obj].gain > EDIT_GAIN_MAX ) + { + st_ivas->hIsmMetaData[obj]->edited_gain = EDIT_GAIN_MAX; + } + else + { + st_ivas->hIsmMetaData[obj]->edited_gain = hIvasEditableParameters.ism_metadata[obj].gain; + } + st_ivas->hIsmMetaData[obj]->non_diegetic_flag = hIvasEditableParameters.ism_metadata[obj].non_diegetic_flag; + } - if ( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) - { - if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) + if ( ism_mode == ISM_SBA_MODE_DISC ) { + if ( hIvasEditableParameters.gain_bed > EDIT_GAIN_MAX ) + { + st_ivas->hSbaIsmData->gain_bed = EDIT_GAIN_MAX; + } + else + { + st_ivas->hSbaIsmData->gain_bed = hIvasEditableParameters.gain_bed; + } + } + } + else if ( ism_mode == ISM_MODE_PARAM ) + { #ifdef DEBUGGING - assert( hIvasEditableParameters.num_obj == st_ivas->nchan_ism ); + assert( hIvasEditableParameters.num_obj == st_ivas->nchan_ism ); #endif - for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) + for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) + { + st_ivas->hParamIsmDec->edited_azimuth_values[obj] = hIvasEditableParameters.ism_metadata[obj].azimuth; + st_ivas->hParamIsmDec->edited_elevation_values[obj] = hIvasEditableParameters.ism_metadata[obj].elevation; + + if ( st_ivas->hMasaIsmData != NULL ) { - st_ivas->hIsmMetaData[obj]->edited_azimuth = hIvasEditableParameters.ism_metadata[obj].azimuth; - st_ivas->hIsmMetaData[obj]->edited_elevation = hIvasEditableParameters.ism_metadata[obj].elevation; - st_ivas->hIsmMetaData[obj]->edited_radius = hIvasEditableParameters.ism_metadata[obj].radius; - st_ivas->hIsmMetaData[obj]->edited_yaw = hIvasEditableParameters.ism_metadata[obj].yaw; - st_ivas->hIsmMetaData[obj]->edited_pitch = hIvasEditableParameters.ism_metadata[obj].pitch; + /* Limit gain edit to a range of +12dB to -24dB with parametric ISM mode */ if ( hIvasEditableParameters.ism_metadata[obj].gain > EDIT_GAIN_MAX ) { - st_ivas->hIsmMetaData[obj]->edited_gain = EDIT_GAIN_MAX; + st_ivas->hMasaIsmData->gain_ism_edited[obj] = EDIT_GAIN_MAX; + } + else if ( hIvasEditableParameters.ism_metadata[obj].gain < EDIT_GAIN_MIN ) + { + st_ivas->hMasaIsmData->gain_ism_edited[obj] = EDIT_GAIN_MIN; } else { - st_ivas->hIsmMetaData[obj]->edited_gain = hIvasEditableParameters.ism_metadata[obj].gain; + st_ivas->hMasaIsmData->gain_ism_edited[obj] = hIvasEditableParameters.ism_metadata[obj].gain; } - st_ivas->hIsmMetaData[obj]->non_diegetic_flag = hIvasEditableParameters.ism_metadata[obj].non_diegetic_flag; - } - if ( ism_mode == ISM_SBA_MODE_DISC ) - { - if ( hIvasEditableParameters.gain_bed > EDIT_GAIN_MAX ) + /* Detect direction editing in Param-ISM mode */ + if ( fabsf( st_ivas->hParamIsmDec->azimuth_values[obj] - hIvasEditableParameters.ism_metadata[obj].azimuth ) > OMASA_AZI_EDIT_THR || + fabsf( st_ivas->hParamIsmDec->elevation_values[obj] - hIvasEditableParameters.ism_metadata[obj].elevation ) > OMASA_ELE_EDIT_THR ) { - st_ivas->hSbaIsmData->gain_bed = EDIT_GAIN_MAX; + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; } else { - st_ivas->hSbaIsmData->gain_bed = hIvasEditableParameters.gain_bed; + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 0u; } - } - } - else if ( ism_mode == ISM_MODE_PARAM ) - { -#ifdef DEBUGGING - assert( hIvasEditableParameters.num_obj == st_ivas->nchan_ism ); -#endif - for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) - { - st_ivas->hParamIsmDec->edited_azimuth_values[obj] = hIvasEditableParameters.ism_metadata[obj].azimuth; - st_ivas->hParamIsmDec->edited_elevation_values[obj] = hIvasEditableParameters.ism_metadata[obj].elevation; - if ( st_ivas->hMasaIsmData != NULL ) + /* Detect gain editing in Param-ISM mode */ + if ( fabsf( 1.0f - hIvasEditableParameters.ism_metadata[obj].gain ) > OMASA_GAIN_EDIT_THR ) { - /* Limit gain edit to a range of +12dB to -24dB with parametric ISM mode */ - if ( hIvasEditableParameters.ism_metadata[obj].gain > EDIT_GAIN_MAX ) - { - st_ivas->hMasaIsmData->gain_ism_edited[obj] = EDIT_GAIN_MAX; - } - else if ( hIvasEditableParameters.ism_metadata[obj].gain < EDIT_GAIN_MIN ) - { - st_ivas->hMasaIsmData->gain_ism_edited[obj] = EDIT_GAIN_MIN; - } - else - { - st_ivas->hMasaIsmData->gain_ism_edited[obj] = hIvasEditableParameters.ism_metadata[obj].gain; - } - - /* Detect direction editing in Param-ISM mode */ - if ( fabsf( st_ivas->hParamIsmDec->azimuth_values[obj] - hIvasEditableParameters.ism_metadata[obj].azimuth ) > OMASA_AZI_EDIT_THR || - fabsf( st_ivas->hParamIsmDec->elevation_values[obj] - hIvasEditableParameters.ism_metadata[obj].elevation ) > OMASA_ELE_EDIT_THR ) - { - st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; - } - else - { - st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 0u; - } - - /* Detect gain editing in Param-ISM mode */ - if ( fabsf( 1.0f - hIvasEditableParameters.ism_metadata[obj].gain ) > OMASA_GAIN_EDIT_THR ) - { - st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 1u; - } - else - { - st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 0u; - } + st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 1u; + } + else + { + st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 0u; } - } - - if ( st_ivas->hMasaIsmData != NULL ) - { - /* MASA is not present with the ISM format */ - st_ivas->hMasaIsmData->masa_gain_is_edited = 0u; } } - else if ( ism_mode == ISM_MODE_NONE ) + + if ( st_ivas->hMasaIsmData != NULL ) { - if ( hIvasEditableParameters.num_obj != 0 ) - { - return IVAS_ERR_OBJECTS_EDITING_NOT_SUPPORTED; - } + /* MASA is not present with the ISM format */ + st_ivas->hMasaIsmData->masa_gain_is_edited = 0u; } -#ifdef DEBUGGING - else + } + else if ( ism_mode == ISM_MODE_NONE ) + { + if ( hIvasEditableParameters.num_obj != 0 ) { - assert( 0 && "This should never happen!" ); + return IVAS_ERR_OBJECTS_EDITING_NOT_SUPPORTED; } -#endif } - else if ( st_ivas->ivas_format == MASA_ISM_FORMAT && ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || ism_mode == ISM_MASA_MODE_DISC ) ) +#ifdef DEBUGGING + else { - int16_t id_th; - float threshold_azi, threshold_ele; + assert( 0 && "This should never happen!" ); + } +#endif + } + else if ( st_ivas->ivas_format == MASA_ISM_FORMAT && ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || ism_mode == ISM_MASA_MODE_DISC ) ) + { + int16_t id_th; + float threshold_azi, threshold_ele; #ifdef DEBUGGING - assert( hIvasEditableParameters.num_obj == st_ivas->nchan_ism ); + assert( hIvasEditableParameters.num_obj == st_ivas->nchan_ism ); #endif - for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) + for ( obj = 0; obj < hIvasEditableParameters.num_obj; obj++ ) + { + if ( st_ivas->hMasaIsmData != NULL ) { - if ( st_ivas->hMasaIsmData != NULL ) + /* copy relevant fields also to OMASA structs, but only if the value has been changed. original values are in st_ivas->hIsmMetaData */ + /* first, need to convert float values to ints used internally */ + int16_t new_azi, new_ele; + if ( hIvasEditableParameters.ism_metadata[obj].azimuth > 0.0f ) { - /* copy relevant fields also to OMASA structs, but only if the value has been changed. original values are in st_ivas->hIsmMetaData */ - /* first, need to convert float values to ints used internally */ - int16_t new_azi, new_ele; - if ( hIvasEditableParameters.ism_metadata[obj].azimuth > 0.0f ) - { - new_azi = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].azimuth + 0.5f ); - } - else - { - new_azi = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].azimuth - 0.5f ); - } + new_azi = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].azimuth + 0.5f ); + } + else + { + new_azi = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].azimuth - 0.5f ); + } + + if ( hIvasEditableParameters.ism_metadata[obj].elevation > 0.0f ) + { + new_ele = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].elevation + 0.5f ); + } + else + { + new_ele = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].elevation - 0.5f ); + } - if ( hIvasEditableParameters.ism_metadata[obj].elevation > 0.0f ) + if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + { + /* Handle MONO output */ + if ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX ) { - new_ele = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].elevation + 0.5f ); + dirac_read_idx = st_ivas->hSpatParamRendCom->render_to_md_map[st_ivas->hSpatParamRendCom->subframes_rendered]; } else { - new_ele = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].elevation - 0.5f ); + dirac_read_idx = 0; } - if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + /* determine thresholds for detecting object metadata edit for direction based on quantization resolution of the spatial direction parameters. + * these depend from the number of bits used to transmit the directions, + * which in turn depends from the object priority and importance: + * importance -> priority -> number of bits -> elevation resolution -> elevation ring index -> azimuth resolution. + * leading to elevation_resolution -> elevation threshold and azimuth resolution -> azimuth threshold */ + id_th = (int16_t) ( fabsf( (float) st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx] ) / delta_theta_masa[st_ivas->hMasaIsmData->bits_ism[obj] - 3] + 0.5f ); + threshold_azi = 360.0f / (float) no_phi_masa[st_ivas->hMasaIsmData->bits_ism[obj] - 1][id_th]; + threshold_ele = delta_theta_masa[st_ivas->hMasaIsmData->bits_ism[obj] - 3]; + + if ( ( (float) abs( new_azi - st_ivas->hMasaIsmData->azimuth_ism[obj][dirac_read_idx] ) > threshold_azi ) || + ( (float) abs( new_ele - st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx] ) > threshold_ele ) ) { - /* Handle MONO output */ - if ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX ) - { - dirac_read_idx = st_ivas->hSpatParamRendCom->render_to_md_map[st_ivas->hSpatParamRendCom->subframes_rendered]; - } - else - { - dirac_read_idx = 0; - } - - /* determine thresholds for detecting object metadata edit for direction based on quantization resolution of the spatial direction parameters. - * these depend from the number of bits used to transmit the directions, - * which in turn depends from the object priority and importance: - * importance -> priority -> number of bits -> elevation resolution -> elevation ring index -> azimuth resolution. - * leading to elevation_resolution -> elevation threshold and azimuth resolution -> azimuth threshold */ - id_th = (int16_t) ( fabsf( (float) st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx] ) / delta_theta_masa[st_ivas->hMasaIsmData->bits_ism[obj] - 3] + 0.5f ); - threshold_azi = 360.0f / (float) no_phi_masa[st_ivas->hMasaIsmData->bits_ism[obj] - 1][id_th]; - threshold_ele = delta_theta_masa[st_ivas->hMasaIsmData->bits_ism[obj] - 3]; - - if ( ( (float) abs( new_azi - st_ivas->hMasaIsmData->azimuth_ism[obj][dirac_read_idx] ) > threshold_azi ) || - ( (float) abs( new_ele - st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx] ) > threshold_ele ) ) - { - /* at least one of the threshold is exceeded, so use new direction value and set editing detection flag */ - st_ivas->hMasaIsmData->azimuth_ism_edited[obj] = new_azi; - st_ivas->hMasaIsmData->elevation_ism_edited[obj] = new_ele; - - st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; - } - else - { - st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 0u; - } + /* at least one of the threshold is exceeded, so use new direction value and set editing detection flag */ + st_ivas->hMasaIsmData->azimuth_ism_edited[obj] = new_azi; + st_ivas->hMasaIsmData->elevation_ism_edited[obj] = new_ele; + + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; } else { - /* detect editing in ISM_MASA_MODE_DISC mode */ - if ( fabsf( st_ivas->hIsmMetaData[obj]->azimuth - hIvasEditableParameters.ism_metadata[obj].azimuth ) > OMASA_AZI_EDIT_THR || - fabsf( st_ivas->hIsmMetaData[obj]->elevation - hIvasEditableParameters.ism_metadata[obj].elevation ) > OMASA_ELE_EDIT_THR ) - { - st_ivas->hMasaIsmData->azimuth_ism_edited[obj] = new_azi; - st_ivas->hMasaIsmData->elevation_ism_edited[obj] = new_ele; - - st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; - } - else - { - st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 0u; - } + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 0u; } - - /* compare pre-edit gain and the edited one to detect editing */ - if ( fabsf( st_ivas->hIsmMetaData[obj]->edited_gain - hIvasEditableParameters.ism_metadata[obj].gain ) > OMASA_GAIN_EDIT_THR ) + } + else + { + /* detect editing in ISM_MASA_MODE_DISC mode */ + if ( fabsf( st_ivas->hIsmMetaData[obj]->azimuth - hIvasEditableParameters.ism_metadata[obj].azimuth ) > OMASA_AZI_EDIT_THR || + fabsf( st_ivas->hIsmMetaData[obj]->elevation - hIvasEditableParameters.ism_metadata[obj].elevation ) > OMASA_ELE_EDIT_THR ) { - st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 1u; + st_ivas->hMasaIsmData->azimuth_ism_edited[obj] = new_azi; + st_ivas->hMasaIsmData->elevation_ism_edited[obj] = new_ele; - /* Limit masa gain edit to a range of +12dB to -infdB with discrete OMASA mode and +12dB to -24dB with parametric OMASA mode */ - if ( hIvasEditableParameters.ism_metadata[obj].gain > EDIT_GAIN_MAX ) - { - st_ivas->hMasaIsmData->gain_ism_edited[obj] = EDIT_GAIN_MAX; - } - else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && hIvasEditableParameters.ism_metadata[obj].gain < EDIT_GAIN_MIN ) - { - st_ivas->hMasaIsmData->gain_ism_edited[obj] = EDIT_GAIN_MIN; - } - else - { - st_ivas->hMasaIsmData->gain_ism_edited[obj] = hIvasEditableParameters.ism_metadata[obj].gain; - } + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 1u; } else { - st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 0u; + st_ivas->hMasaIsmData->ism_dir_is_edited[obj] = 0u; } } - /* Copy edited values to hIsmMetaData struct */ - if ( st_ivas->hIsmMetaData[obj] != NULL ) + /* compare pre-edit gain and the edited one to detect editing */ + if ( fabsf( st_ivas->hIsmMetaData[obj]->edited_gain - hIvasEditableParameters.ism_metadata[obj].gain ) > OMASA_GAIN_EDIT_THR ) { - st_ivas->hIsmMetaData[obj]->edited_azimuth = hIvasEditableParameters.ism_metadata[obj].azimuth; - st_ivas->hIsmMetaData[obj]->edited_elevation = hIvasEditableParameters.ism_metadata[obj].elevation; - - if ( ism_mode == ISM_MASA_MODE_DISC ) - { - st_ivas->hIsmMetaData[obj]->edited_yaw = hIvasEditableParameters.ism_metadata[obj].yaw; - st_ivas->hIsmMetaData[obj]->edited_pitch = hIvasEditableParameters.ism_metadata[obj].pitch; - st_ivas->hIsmMetaData[obj]->edited_radius = hIvasEditableParameters.ism_metadata[obj].radius; - } + st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 1u; + /* Limit masa gain edit to a range of +12dB to -infdB with discrete OMASA mode and +12dB to -24dB with parametric OMASA mode */ if ( hIvasEditableParameters.ism_metadata[obj].gain > EDIT_GAIN_MAX ) { - st_ivas->hIsmMetaData[obj]->edited_gain = EDIT_GAIN_MAX; + st_ivas->hMasaIsmData->gain_ism_edited[obj] = EDIT_GAIN_MAX; } else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && hIvasEditableParameters.ism_metadata[obj].gain < EDIT_GAIN_MIN ) { - st_ivas->hIsmMetaData[obj]->edited_gain = EDIT_GAIN_MIN; + st_ivas->hMasaIsmData->gain_ism_edited[obj] = EDIT_GAIN_MIN; } else { - st_ivas->hIsmMetaData[obj]->edited_gain = hIvasEditableParameters.ism_metadata[obj].gain; + st_ivas->hMasaIsmData->gain_ism_edited[obj] = hIvasEditableParameters.ism_metadata[obj].gain; } - - st_ivas->hIsmMetaData[obj]->non_diegetic_flag = hIvasEditableParameters.ism_metadata[obj].non_diegetic_flag; + } + else + { + st_ivas->hMasaIsmData->ism_gain_is_edited[obj] = 0u; } } - if ( fabsf( hIvasEditableParameters.gain_bed - 1.0f ) > OMASA_GAIN_EDIT_THR ) + /* Copy edited values to hIsmMetaData struct */ + if ( st_ivas->hIsmMetaData[obj] != NULL ) { - /* Limit masa gain edit to a range of +12dB to -infdB with discrete OMASA mode and +12dB to -24dB with parametric OMASA mode */ - if ( hIvasEditableParameters.gain_bed > EDIT_GAIN_MAX ) + st_ivas->hIsmMetaData[obj]->edited_azimuth = hIvasEditableParameters.ism_metadata[obj].azimuth; + st_ivas->hIsmMetaData[obj]->edited_elevation = hIvasEditableParameters.ism_metadata[obj].elevation; + + if ( ism_mode == ISM_MASA_MODE_DISC ) { - st_ivas->hMasaIsmData->gain_masa_edited = EDIT_GAIN_MAX; + st_ivas->hIsmMetaData[obj]->edited_yaw = hIvasEditableParameters.ism_metadata[obj].yaw; + st_ivas->hIsmMetaData[obj]->edited_pitch = hIvasEditableParameters.ism_metadata[obj].pitch; + st_ivas->hIsmMetaData[obj]->edited_radius = hIvasEditableParameters.ism_metadata[obj].radius; } - else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && hIvasEditableParameters.gain_bed < EDIT_GAIN_MIN ) + + if ( hIvasEditableParameters.ism_metadata[obj].gain > EDIT_GAIN_MAX ) + { + st_ivas->hIsmMetaData[obj]->edited_gain = EDIT_GAIN_MAX; + } + else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && hIvasEditableParameters.ism_metadata[obj].gain < EDIT_GAIN_MIN ) { - st_ivas->hMasaIsmData->gain_masa_edited = EDIT_GAIN_MIN; + st_ivas->hIsmMetaData[obj]->edited_gain = EDIT_GAIN_MIN; } else { - st_ivas->hMasaIsmData->gain_masa_edited = hIvasEditableParameters.gain_bed; + st_ivas->hIsmMetaData[obj]->edited_gain = hIvasEditableParameters.ism_metadata[obj].gain; } - st_ivas->hMasaIsmData->masa_gain_is_edited = 1u; + + st_ivas->hIsmMetaData[obj]->non_diegetic_flag = hIvasEditableParameters.ism_metadata[obj].non_diegetic_flag; + } + } + + if ( fabsf( hIvasEditableParameters.gain_bed - 1.0f ) > OMASA_GAIN_EDIT_THR ) + { + /* Limit masa gain edit to a range of +12dB to -infdB with discrete OMASA mode and +12dB to -24dB with parametric OMASA mode */ + if ( hIvasEditableParameters.gain_bed > EDIT_GAIN_MAX ) + { + st_ivas->hMasaIsmData->gain_masa_edited = EDIT_GAIN_MAX; + } + else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && hIvasEditableParameters.gain_bed < EDIT_GAIN_MIN ) + { + st_ivas->hMasaIsmData->gain_masa_edited = EDIT_GAIN_MIN; } else { - st_ivas->hMasaIsmData->masa_gain_is_edited = 0u; + st_ivas->hMasaIsmData->gain_masa_edited = hIvasEditableParameters.gain_bed; } + st_ivas->hMasaIsmData->masa_gain_is_edited = 1u; + } + else + { + st_ivas->hMasaIsmData->masa_gain_is_edited = 0u; } - - return IVAS_ERR_OK; } + return IVAS_ERR_OK; +} + - /*---------------------------------------------------------------------* - * IVAS_DEC_PrepareRenderer( ) - * - * prepare IVAS renderer - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_PrepareRenderer( ) + * + * prepare IVAS renderer + *---------------------------------------------------------------------*/ - ivas_error IVAS_DEC_PrepareRenderer( - IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ - ) +ivas_error IVAS_DEC_PrepareRenderer( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( hIvasDec->hasBeenFedFirstGoodFrame || hIvasDec->isInitialized ) /* note: 'isInitialized' is related to EVS decoder */ - { - ivas_dec_prepare_renderer( hIvasDec->st_ivas ); - } + if ( hIvasDec->hasBeenFedFirstGoodFrame || hIvasDec->isInitialized ) /* note: 'isInitialized' is related to EVS decoder */ + { + ivas_dec_prepare_renderer( hIvasDec->st_ivas ); + } - hIvasDec->hasBeenPreparedRendering = true; + hIvasDec->hasBeenPreparedRendering = true; - return IVAS_ERR_OK; - } + return IVAS_ERR_OK; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_GetSamplesRenderer( ) + * + * Main function to render the decoded data to output data + *---------------------------------------------------------------------*/ +ivas_error IVAS_DEC_GetSamplesRenderer( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t nSamplesAsked, /* i : number of samples wanted by the caller */ + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ + int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ + bool *needNewFrame /* o : indication that the decoder needs a new frame */ +) +{ + ivas_error error; + uint16_t nSamplesRendered, nSamplesRendered_loop; + uint8_t nOutChannels; + Decoder_Struct *st_ivas; - /*---------------------------------------------------------------------* - * IVAS_DEC_GetSamplesRenderer( ) - * - * Main function to render the decoded data to output data - *---------------------------------------------------------------------*/ + nSamplesRendered = 0; + nOutChannels = 0; + nSamplesRendered_loop = 0; - ivas_error IVAS_DEC_GetSamplesRenderer( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const int16_t nSamplesAsked, /* i : number of samples wanted by the caller */ - const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ - void *pcmBuf, /* o : output synthesis signal */ - int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ - bool *needNewFrame /* o : indication that the decoder needs a new frame */ - ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - ivas_error error; - uint16_t nSamplesRendered, nSamplesRendered_loop; - uint8_t nOutChannels; - Decoder_Struct *st_ivas; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - nSamplesRendered = 0; - nOutChannels = 0; - nSamplesRendered_loop = 0; + /* the rendering needs to be prepared at this point */ + if ( hIvasDec->hasBeenPreparedRendering == false ) + { + return IVAS_ERR_UNKNOWN; + } - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + st_ivas = hIvasDec->st_ivas; + + if ( hIvasDec->updateOrientation ) + { + /*----------------------------------------------------------------* + * Combine orientations + *----------------------------------------------------------------*/ - /* the rendering needs to be prepared at this point */ - if ( hIvasDec->hasBeenPreparedRendering == false ) + if ( ( error = combine_external_and_head_orientations_dec( st_ivas->hHeadTrackData, st_ivas->hExtOrientationData, st_ivas->hCombinedOrientationData ) ) != IVAS_ERR_OK ) { - return IVAS_ERR_UNKNOWN; + return error; } - st_ivas = hIvasDec->st_ivas; + /*----------------------------------------------------------------* + * Binaural split rendering setup + *----------------------------------------------------------------*/ - if ( hIvasDec->updateOrientation ) + if ( st_ivas->hCombinedOrientationData != NULL && ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) { - /*----------------------------------------------------------------* - * Combine orientations - *----------------------------------------------------------------*/ - - if ( ( error = combine_external_and_head_orientations_dec( st_ivas->hHeadTrackData, st_ivas->hExtOrientationData, st_ivas->hCombinedOrientationData ) ) != IVAS_ERR_OK ) - { - return error; - } - - /*----------------------------------------------------------------* - * Binaural split rendering setup - *----------------------------------------------------------------*/ + isar_set_split_rend_ht_setup( &st_ivas->hSplitBinRend->splitrend, st_ivas->hCombinedOrientationData->Quaternions, st_ivas->hCombinedOrientationData->Rmat ); + } - if ( st_ivas->hCombinedOrientationData != NULL && ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) - { - isar_set_split_rend_ht_setup( &st_ivas->hSplitBinRend->splitrend, st_ivas->hCombinedOrientationData->Quaternions, st_ivas->hCombinedOrientationData->Rmat ); - } + hIvasDec->updateOrientation = false; + } - hIvasDec->updateOrientation = false; - } + if ( !hIvasDec->hasBeenFedFrame && hIvasDec->nSamplesAvailableNext == 0 ) + { + /* no frame was fed, do nothing but ask for a frame */ + *needNewFrame = true; + *nOutSamples = 0; + hIvasDec->needNewFrame = true; + return IVAS_ERR_OK; + } - if ( !hIvasDec->hasBeenFedFrame && hIvasDec->nSamplesAvailableNext == 0 ) - { - /* no frame was fed, do nothing but ask for a frame */ - *needNewFrame = true; - *nOutSamples = 0; - hIvasDec->needNewFrame = true; - return IVAS_ERR_OK; - } + /* check if we are still at the beginning with bad frames, put out zeroes, keep track of subframes */ + if ( !hIvasDec->isInitialized && st_ivas->bfi ) + { + hIvasDec->hasBeenFedFrame = false; + set_s( pcmBuf, 0, st_ivas->hDecoderConfig->nchan_out * nSamplesAsked ); + nSamplesRendered = nSamplesAsked; + hIvasDec->nSamplesAvailableNext -= nSamplesAsked; + } + else + { + nOutChannels = (uint8_t) st_ivas->hDecoderConfig->nchan_out; + hIvasDec->hasBeenFedFrame = false; - /* check if we are still at the beginning with bad frames, put out zeroes, keep track of subframes */ - if ( !hIvasDec->isInitialized && st_ivas->bfi ) - { - hIvasDec->hasBeenFedFrame = false; - set_s( pcmBuf, 0, st_ivas->hDecoderConfig->nchan_out * nSamplesAsked ); - nSamplesRendered = nSamplesAsked; - hIvasDec->nSamplesAvailableNext -= nSamplesAsked; - } - else + /* check for possible flushed samples from a rate switch */ + if ( hIvasDec->nSamplesFlushed > 0 ) { - nOutChannels = (uint8_t) st_ivas->hDecoderConfig->nchan_out; - hIvasDec->hasBeenFedFrame = false; - - /* check for possible flushed samples from a rate switch */ - if ( hIvasDec->nSamplesFlushed > 0 ) - { -#ifdef DEBUGGING - assert( hIvasDec->pcmType == pcmType ); -#endif - /* note: offset (rendered samples) is always 0 */ - if ( pcmType == IVAS_DEC_PCM_INT16 ) - { - mvs2s( (int16_t *) hIvasDec->flushbuffer, pcmBuf, hIvasDec->nSamplesFlushed * nOutChannels ); - } - else if ( pcmType == IVAS_DEC_PCM_FLOAT ) - { - mvr2r( (float *) hIvasDec->flushbuffer, pcmBuf, hIvasDec->nSamplesFlushed * nOutChannels ); - } #ifdef DEBUGGING - else - { - assert( 0 && "wrong PCM type for the flush buffer!" ); - } + assert( hIvasDec->pcmType == pcmType ); #endif - nSamplesRendered = hIvasDec->nSamplesFlushed; - hIvasDec->nSamplesFlushed = 0; + /* note: offset (rendered samples) is always 0 */ + if ( pcmType == IVAS_DEC_PCM_INT16 ) + { + mvs2s( (int16_t *) hIvasDec->flushbuffer, pcmBuf, hIvasDec->nSamplesFlushed * nOutChannels ); } - - /* render IVAS frames directly to the output buffer */ - if ( ( error = ivas_dec_render( st_ivas, nSamplesAsked - nSamplesRendered, &nSamplesRendered_loop, &hIvasDec->nSamplesAvailableNext, pcm_type_API_to_internal( pcmType ), pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ) ) ) != IVAS_ERR_OK ) + else if ( pcmType == IVAS_DEC_PCM_FLOAT ) { - return error; + mvr2r( (float *) hIvasDec->flushbuffer, pcmBuf, hIvasDec->nSamplesFlushed * nOutChannels ); } - - nSamplesRendered += nSamplesRendered_loop; +#ifdef DEBUGGING + else + { + assert( 0 && "wrong PCM type for the flush buffer!" ); + } +#endif + nSamplesRendered = hIvasDec->nSamplesFlushed; + hIvasDec->nSamplesFlushed = 0; } - if ( hIvasDec->nSamplesAvailableNext == 0 ) - { - *needNewFrame = true; - hIvasDec->needNewFrame = true; - } - else + /* render IVAS frames directly to the output buffer */ + if ( ( error = ivas_dec_render( st_ivas, nSamplesAsked - nSamplesRendered, &nSamplesRendered_loop, &hIvasDec->nSamplesAvailableNext, pcm_type_API_to_internal( pcmType ), pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ) ) ) != IVAS_ERR_OK ) { - *needNewFrame = false; + return error; } - *nOutSamples = nSamplesRendered; - - return IVAS_ERR_OK; + nSamplesRendered += nSamplesRendered_loop; } - - /*---------------------------------------------------------------------* - * isar_get_frame_size( ) - * - * - *---------------------------------------------------------------------*/ - - static int16_t isar_get_frame_size( - Decoder_Struct * st_ivas /* i : IVAS decoder handle */ - ) + if ( hIvasDec->nSamplesAvailableNext == 0 ) + { + *needNewFrame = true; + hIvasDec->needNewFrame = true; + } + else { - int32_t output_Fs; - int16_t nSamplesPerChannel; + *needNewFrame = false; + } - output_Fs = st_ivas->hDecoderConfig->output_Fs; + *nOutSamples = nSamplesRendered; - if ( st_ivas->hDecoderConfig->render_num_subframes != IVAS_RENDER_NUM_SUBFR_20MS && - ( st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE || - st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) - { - nSamplesPerChannel = (int16_t) ( output_Fs / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ); - nSamplesPerChannel *= (int16_t) st_ivas->hDecoderConfig->render_num_subframes; - } - else - { - nSamplesPerChannel = (int16_t) ( output_Fs / FRAMES_PER_SEC ); - } + return IVAS_ERR_OK; +} - return nSamplesPerChannel; - } +/*---------------------------------------------------------------------* + * isar_get_frame_size( ) + * + * + *---------------------------------------------------------------------*/ + +static int16_t isar_get_frame_size( + Decoder_Struct *st_ivas /* i : IVAS decoder handle */ +) +{ + int32_t output_Fs; + int16_t nSamplesPerChannel; - /*---------------------------------------------------------------------* - * isar_render_poses( ) - * - * - *---------------------------------------------------------------------*/ + output_Fs = st_ivas->hDecoderConfig->output_Fs; - static ivas_error isar_render_poses( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const int16_t nSamplesAsked, /* i : number of samples wanted by the caller */ - int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ - bool *needNewFrame /* o : indication that the decoder needs a new frame */ - ) + if ( st_ivas->hDecoderConfig->render_num_subframes != IVAS_RENDER_NUM_SUBFR_20MS && + ( st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE || + st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) { - float pcmBuf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES * L_FRAME48k]; - Decoder_Struct *st_ivas; - ivas_error error; - int16_t numPoses; + nSamplesPerChannel = (int16_t) ( output_Fs / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ); + nSamplesPerChannel *= (int16_t) st_ivas->hDecoderConfig->render_num_subframes; + } + else + { + nSamplesPerChannel = (int16_t) ( output_Fs / FRAMES_PER_SEC ); + } - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + return nSamplesPerChannel; +} - *needNewFrame = false; - st_ivas = hIvasDec->st_ivas; +/*---------------------------------------------------------------------* + * isar_render_poses( ) + * + * + *---------------------------------------------------------------------*/ - numPoses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; +static ivas_error isar_render_poses( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t nSamplesAsked, /* i : number of samples wanted by the caller */ + int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ + bool *needNewFrame /* o : indication that the decoder needs a new frame */ +) +{ + float pcmBuf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES * L_FRAME48k]; + Decoder_Struct *st_ivas; + ivas_error error; + int16_t numPoses; - /* init flush buffer for rate switch if not already initizalized */ - if ( hIvasDec->flushbuffer == NULL ) - { - hIvasDec->flushbuffer = (void *) malloc( numPoses * BINAURAL_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( float ) ); - if ( hIvasDec->flushbuffer == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate flush buffer" ); - } - hIvasDec->pcmType = IVAS_DEC_PCM_FLOAT; - set_zero( (float *) hIvasDec->flushbuffer, numPoses * BINAURAL_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ); - } + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - /* render */ - if ( ( error = IVAS_DEC_GetSamplesRenderer( hIvasDec, nSamplesAsked, IVAS_DEC_PCM_FLOAT, pcmBuf, nOutSamples, needNewFrame ) ) != IVAS_ERR_OK ) - { - return error; - } + *needNewFrame = false; - if ( !hIvasDec->hasBeenFedFirstGoodFrame ) - { - return IVAS_ERR_OK; - } + st_ivas = hIvasDec->st_ivas; - if ( !ivas_dec_split_rend_cldfb_in( st_ivas->renderer_type ) ) + numPoses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; + + /* init flush buffer for rate switch if not already initizalized */ + if ( hIvasDec->flushbuffer == NULL ) + { + hIvasDec->flushbuffer = (void *) malloc( numPoses * BINAURAL_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( float ) ); + if ( hIvasDec->flushbuffer == NULL ) { - ivas_TD_RINGBUF_PushInterleaved( st_ivas->hSplitBinRend->hMultiBinTdData, pcmBuf, *nOutSamples ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate flush buffer" ); } + hIvasDec->pcmType = IVAS_DEC_PCM_FLOAT; + set_zero( (float *) hIvasDec->flushbuffer, numPoses * BINAURAL_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ); + } + /* render */ + if ( ( error = IVAS_DEC_GetSamplesRenderer( hIvasDec, nSamplesAsked, IVAS_DEC_PCM_FLOAT, pcmBuf, nOutSamples, needNewFrame ) ) != IVAS_ERR_OK ) + { return error; } + if ( !hIvasDec->hasBeenFedFirstGoodFrame ) + { + return IVAS_ERR_OK; + } - /*---------------------------------------------------------------------* - * isar_generate_metadata_and_bitstream( ) - * - * - *---------------------------------------------------------------------*/ - - static ivas_error isar_generate_metadata_and_bitstream( - Decoder_Struct * st_ivas, /* i/o: IVAS decoder handle */ - float **p_head_pose_buf, /* i/o: PCM buffer with head-pose data */ - int16_t nSamples, /* i : duration of audio (in samples per channel) for which metadata should be generated */ - ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ - ) + if ( !ivas_dec_split_rend_cldfb_in( st_ivas->renderer_type ) ) { - ivas_error error; - ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; - int16_t max_band; - int16_t pcm_out_flag; - int16_t cldfb_in_flag; - int16_t ro_md_flag; - IVAS_QUATERNION Quaternion; - int16_t i, j, num_poses, num_cldfb_slots, n_samples_in_cldfb_slot; - float *p_Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX]; - float *p_Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX]; + ivas_TD_RINGBUF_PushInterleaved( st_ivas->hSplitBinRend->hMultiBinTdData, pcmBuf, *nOutSamples ); + } - hSplitBinRend = st_ivas->hSplitBinRend; + return error; +} - max_band = (int16_t) ( ( BINAURAL_MAXBANDS * st_ivas->hDecoderConfig->output_Fs ) / 48000 ); - pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; - cldfb_in_flag = ivas_dec_split_rend_cldfb_in( st_ivas->renderer_type ); - if ( cldfb_in_flag ) - { - n_samples_in_cldfb_slot = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); - assert( nSamples % n_samples_in_cldfb_slot == 0 ); - num_cldfb_slots = nSamples / n_samples_in_cldfb_slot; +/*---------------------------------------------------------------------* + * isar_generate_metadata_and_bitstream( ) + * + * + *---------------------------------------------------------------------*/ + +static ivas_error isar_generate_metadata_and_bitstream( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + float **p_head_pose_buf, /* i/o: PCM buffer with head-pose data */ + int16_t nSamples, /* i : duration of audio (in samples per channel) for which metadata should be generated */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ +) +{ + ivas_error error; + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; + int16_t max_band; + int16_t pcm_out_flag; + int16_t cldfb_in_flag; + int16_t ro_md_flag; + IVAS_QUATERNION Quaternion; + int16_t i, j, num_poses, num_cldfb_slots, n_samples_in_cldfb_slot; + float *p_Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX]; + float *p_Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX]; + + hSplitBinRend = st_ivas->hSplitBinRend; + + max_band = (int16_t) ( ( BINAURAL_MAXBANDS * st_ivas->hDecoderConfig->output_Fs ) / 48000 ); + pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; + cldfb_in_flag = ivas_dec_split_rend_cldfb_in( st_ivas->renderer_type ); + + if ( cldfb_in_flag ) + { + n_samples_in_cldfb_slot = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); + assert( nSamples % n_samples_in_cldfb_slot == 0 ); + num_cldfb_slots = nSamples / n_samples_in_cldfb_slot; - num_poses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; + num_poses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; - for ( i = 0; i < BINAURAL_CHANNELS * num_poses; ++i ) + for ( i = 0; i < BINAURAL_CHANNELS * num_poses; ++i ) + { + for ( j = 0; j < num_cldfb_slots; ++j ) { - for ( j = 0; j < num_cldfb_slots; ++j ) - { - /* Save pointers to first CLDFB column in the ring buffer. Allows us to save - * significant amounts of memory by not copying CLDFB values into a separate buffer. */ - ivas_CLDFB_RINGBUF_GetByIdx( hSplitBinRend->hMultiBinCldfbData[i], &p_Cldfb_RealBuffer_Binaural[i][j], &p_Cldfb_ImagBuffer_Binaural[i][j], 0 ); - - /* Pop the CLDFB column we just saved pointers to. This is fine as long as we use - * the saved columns only before any new columns are pushed to the buffer - the new - * columns could potentially overwrite the old columns we wanted to use. - * This requirement is fulfilled in this case. */ - ivas_CLDFB_RINGBUF_Pop( hSplitBinRend->hMultiBinCldfbData[i], NULL, NULL, CLDFB_NO_CHANNELS_MAX ); - } + /* Save pointers to first CLDFB column in the ring buffer. Allows us to save + * significant amounts of memory by not copying CLDFB values into a separate buffer. */ + ivas_CLDFB_RINGBUF_GetByIdx( hSplitBinRend->hMultiBinCldfbData[i], &p_Cldfb_RealBuffer_Binaural[i][j], &p_Cldfb_ImagBuffer_Binaural[i][j], 0 ); + + /* Pop the CLDFB column we just saved pointers to. This is fine as long as we use + * the saved columns only before any new columns are pushed to the buffer - the new + * columns could potentially overwrite the old columns we wanted to use. + * This requirement is fulfilled in this case. */ + ivas_CLDFB_RINGBUF_Pop( hSplitBinRend->hMultiBinCldfbData[i], NULL, NULL, CLDFB_NO_CHANNELS_MAX ); } } - else - { - ivas_TD_RINGBUF_PopChannels( st_ivas->hSplitBinRend->hMultiBinTdData, p_head_pose_buf, nSamples ); - } - + } + else + { + ivas_TD_RINGBUF_PopChannels( st_ivas->hSplitBinRend->hMultiBinTdData, p_head_pose_buf, nSamples ); + } - if ( st_ivas->hBinRendererTd != NULL ) - { - ro_md_flag = 1; - } - else - { - ro_md_flag = 0; - } - if ( st_ivas->hHeadTrackData != NULL ) - { - Quaternion = st_ivas->hHeadTrackData->Quaternions[0]; - } - else - { - Quaternion.w = -3.0f; - Quaternion.x = 0.0f; - Quaternion.y = 0.0f; - Quaternion.z = 0.0f; - } + if ( st_ivas->hBinRendererTd != NULL ) + { + ro_md_flag = 1; + } + else + { + ro_md_flag = 0; + } - if ( ( error = ISAR_PRE_REND_MultiBinToSplitBinaural( &hSplitBinRend->splitrend, - Quaternion, - st_ivas->hRenderConfig->split_rend_config.splitRendBitRate, - st_ivas->hRenderConfig->split_rend_config.codec, - st_ivas->hRenderConfig->split_rend_config.isar_frame_size_ms, - st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms, - splitRendBits, - p_Cldfb_RealBuffer_Binaural, - p_Cldfb_ImagBuffer_Binaural, - max_band, p_head_pose_buf, 1, cldfb_in_flag, pcm_out_flag, ro_md_flag ) ) != IVAS_ERR_OK ) - { - return error; - } + if ( st_ivas->hHeadTrackData != NULL ) + { + Quaternion = st_ivas->hHeadTrackData->Quaternions[0]; + } + else + { + Quaternion.w = -3.0f; + Quaternion.x = 0.0f; + Quaternion.y = 0.0f; + Quaternion.z = 0.0f; + } - return IVAS_ERR_OK; + if ( ( error = ISAR_PRE_REND_MultiBinToSplitBinaural( &hSplitBinRend->splitrend, + Quaternion, + st_ivas->hRenderConfig->split_rend_config.splitRendBitRate, + st_ivas->hRenderConfig->split_rend_config.codec, + st_ivas->hRenderConfig->split_rend_config.isar_frame_size_ms, + st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms, + splitRendBits, + p_Cldfb_RealBuffer_Binaural, + p_Cldfb_ImagBuffer_Binaural, + max_band, p_head_pose_buf, 1, cldfb_in_flag, pcm_out_flag, ro_md_flag ) ) != IVAS_ERR_OK ) + { + return error; } + return IVAS_ERR_OK; +} + - /*---------------------------------------------------------------------* - * IVAS_DEC_GetSplitBinauralBitstream( ) - * - * Get split-rendering bitstream - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_GetSplitBinauralBitstream( ) + * + * Get split-rendering bitstream + *---------------------------------------------------------------------*/ - ivas_error IVAS_DEC_GetSplitBinauralBitstream( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - void *pcmBuf_out, /* o : output synthesis signal for BINAURAL_SPLIT_PCM */ - ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */ - int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ - bool *needNewFrame /* o : indication that the decoder needs a new frame */ - ) +ivas_error IVAS_DEC_GetSplitBinauralBitstream( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + void *pcmBuf_out, /* o : output synthesis signal for BINAURAL_SPLIT_PCM */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */ + int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ + bool *needNewFrame /* o : indication that the decoder needs a new frame */ +) +{ + Decoder_Struct *st_ivas; + ivas_error error; + float head_pose_buf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES][L_FRAME48k]; + float *p_head_pose_buf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES]; + int16_t i; + int16_t pcm_out_flag; + int16_t numSamplesPerChannelToOutput; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - Decoder_Struct *st_ivas; - ivas_error error; - float head_pose_buf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES][L_FRAME48k]; - float *p_head_pose_buf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES]; - int16_t i; - int16_t pcm_out_flag; - int16_t numSamplesPerChannelToOutput; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + st_ivas = hIvasDec->st_ivas; - st_ivas = hIvasDec->st_ivas; + if ( is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ) == 0 ) + { + return IVAS_ERR_WRONG_PARAMS; + } - if ( is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ) == 0 ) - { - return IVAS_ERR_WRONG_PARAMS; - } + pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; + numSamplesPerChannelToOutput = isar_get_frame_size( st_ivas ); - pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; - numSamplesPerChannelToOutput = isar_get_frame_size( st_ivas ); + if ( ( error = isar_render_poses( hIvasDec, numSamplesPerChannelToOutput, nOutSamples, needNewFrame ) ) != IVAS_ERR_OK ) + { + return error; + } - if ( ( error = isar_render_poses( hIvasDec, numSamplesPerChannelToOutput, nOutSamples, needNewFrame ) ) != IVAS_ERR_OK ) - { - return error; - } + if ( !hIvasDec->hasBeenFedFirstGoodFrame ) + { + return IVAS_ERR_OK; + } - if ( !hIvasDec->hasBeenFedFirstGoodFrame ) - { - return IVAS_ERR_OK; - } + for ( i = 0; i < BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES; ++i ) + { + p_head_pose_buf[i] = head_pose_buf[i]; + } - for ( i = 0; i < BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES; ++i ) - { - p_head_pose_buf[i] = head_pose_buf[i]; - } + if ( ( error = isar_generate_metadata_and_bitstream( st_ivas, p_head_pose_buf, *nOutSamples, splitRendBits ) ) != IVAS_ERR_OK ) + { + return error; + } - if ( ( error = isar_generate_metadata_and_bitstream( st_ivas, p_head_pose_buf, *nOutSamples, splitRendBits ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* convert to int16 with limiting for BINAURAL_SPLIT_PCM */ - if ( pcm_out_flag ) - { + /* convert to int16 with limiting for BINAURAL_SPLIT_PCM */ + if ( pcm_out_flag ) + { #ifndef DISABLE_LIMITER - ivas_limiter_dec( st_ivas->hLimiter, p_head_pose_buf, st_ivas->hDecoderConfig->nchan_out, numSamplesPerChannelToOutput, st_ivas->BER_detect ); + ivas_limiter_dec( st_ivas->hLimiter, p_head_pose_buf, st_ivas->hDecoderConfig->nchan_out, numSamplesPerChannelToOutput, st_ivas->BER_detect ); #endif #ifdef DEBUGGING - st_ivas->noClipping += + st_ivas->noClipping += #endif - ivas_syn_output( p_head_pose_buf, numSamplesPerChannelToOutput, st_ivas->hDecoderConfig->nchan_out, (int16_t *) pcmBuf_out ); - } - - return IVAS_ERR_OK; + ivas_syn_output( p_head_pose_buf, numSamplesPerChannelToOutput, st_ivas->hDecoderConfig->nchan_out, (int16_t *) pcmBuf_out ); } + return IVAS_ERR_OK; +} - /*---------------------------------------------------------------------* - * ivas_dec_setup_all() - * - * Set-up all decoder parts: IVAS decoder, ISAR - *---------------------------------------------------------------------*/ - static ivas_error ivas_dec_setup_all( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint8_t * nTransportChannels, /* o : number of decoded transport PCM channels */ - ISAR_SPLIT_REND_BITS_DATA * splitRendBits /* o : output split rendering bits */ - ) - { - ivas_error error; +/*---------------------------------------------------------------------* + * ivas_dec_setup_all() + * + * Set-up all decoder parts: IVAS decoder, ISAR + *---------------------------------------------------------------------*/ - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) - { - *nTransportChannels = 1; - } - else - { - Decoder_Struct *st_ivas; +static ivas_error ivas_dec_setup_all( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint8_t *nTransportChannels, /* o : number of decoded transport PCM channels */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ +) +{ + ivas_error error; + + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + { + *nTransportChannels = 1; + } + else + { + Decoder_Struct *st_ivas; - st_ivas = hIvasDec->st_ivas; + st_ivas = hIvasDec->st_ivas; - /* Setup IVAS split rendering */ - if ( splitRendBits != NULL ) + /* Setup IVAS split rendering */ + if ( splitRendBits != NULL ) + { + if ( ( error = isar_set_split_rend_setup( st_ivas->hSplitBinRend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hCombinedOrientationData, splitRendBits ) ) != IVAS_ERR_OK ) { - if ( ( error = isar_set_split_rend_setup( st_ivas->hSplitBinRend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hCombinedOrientationData, splitRendBits ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } + } - /*----------------------------------------------------------------* - * IVAS decoder setup - * - read IVAS format signaling - * - read IVAS format specific signaling - * - initialize decoder in the first frame based on IVAS format and number of transport channels - * - reconfigure the decoder when the number of TC or IVAS total bitrate change - *----------------------------------------------------------------*/ + /*----------------------------------------------------------------* + * IVAS decoder setup + * - read IVAS format signaling + * - read IVAS format specific signaling + * - initialize decoder in the first frame based on IVAS format and number of transport channels + * - reconfigure the decoder when the number of TC or IVAS total bitrate change + *----------------------------------------------------------------*/ - if ( st_ivas->bfi == 0 ) + if ( st_ivas->bfi == 0 ) + { + if ( ( error = ivas_dec_setup( st_ivas ) ) != IVAS_ERR_OK ) { - if ( ( error = ivas_dec_setup( st_ivas ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } + } - *nTransportChannels = (uint8_t) st_ivas->hTcBuffer->nchan_transport_rend; + *nTransportChannels = (uint8_t) st_ivas->hTcBuffer->nchan_transport_rend; - /*-----------------------------------------------------------------* - * ISAR: - * - initialize ISAR handle at the first frame - * - reconfigure the ISAR handle in case of bitrate switching (renderer might change) - *-----------------------------------------------------------------*/ + /*-----------------------------------------------------------------* + * ISAR: + * - initialize ISAR handle at the first frame + * - reconfigure the ISAR handle in case of bitrate switching (renderer might change) + *-----------------------------------------------------------------*/ - if ( st_ivas->ini_frame == 0 && splitRendBits != NULL ) + if ( st_ivas->ini_frame == 0 && splitRendBits != NULL ) + { + if ( ( error = ivas_dec_init_split_rend( st_ivas ) ) != IVAS_ERR_OK ) { - if ( ( error = ivas_dec_init_split_rend( st_ivas ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } + } - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( ( error = ivas_dec_reconfig_split_rend( st_ivas ) ) != IVAS_ERR_OK ) { - if ( ( error = ivas_dec_reconfig_split_rend( st_ivas ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } } - - return IVAS_ERR_OK; } + return IVAS_ERR_OK; +} - /*---------------------------------------------------------------------* - * IVAS_DEC_GetNumObjects( ) - * - * Returns the number of objects available in the decoded bitstream - *---------------------------------------------------------------------*/ - ivas_error IVAS_DEC_GetNumObjects( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint16_t * numObjects /* o : number of objects for which the decoder has been configured */ - ) +/*---------------------------------------------------------------------* + * IVAS_DEC_GetNumObjects( ) + * + * Returns the number of objects available in the decoded bitstream + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_GetNumObjects( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint16_t *numObjects /* o : number of objects for which the decoder has been configured */ +) +{ + int16_t is_masa_ism; + is_masa_ism = 0; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - int16_t is_masa_ism; - is_masa_ism = 0; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + if ( hIvasDec->st_ivas->hMasa != NULL ) + { + if ( hIvasDec->st_ivas->hMasa->config.input_ivas_format == MASA_ISM_FORMAT ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + is_masa_ism = 1; } + } + + if ( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || hIvasDec->st_ivas->ivas_format == SBA_ISM_FORMAT || hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT || is_masa_ism ) + { + *numObjects = hIvasDec->st_ivas->nchan_ism; + } + else + { + *numObjects = 0; + } + + return IVAS_ERR_OK; +} - if ( hIvasDec->st_ivas->hMasa != NULL ) - { - if ( hIvasDec->st_ivas->hMasa->config.input_ivas_format == MASA_ISM_FORMAT ) - { - is_masa_ism = 1; - } - } - if ( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || hIvasDec->st_ivas->ivas_format == SBA_ISM_FORMAT || hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT || is_masa_ism ) +/*---------------------------------------------------------------------* + * IVAS_DEC_GetFormat( ) + * + * Returns the format of currently decoded bitstream. + * Note: bitstream format is only known after the first (good) frame has been decoded. + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_GetFormat( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_DEC_BS_FORMAT *format /* o : format detected from bitstream fed to the decoder */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( hIvasDec->hasDecodedFirstGoodFrame ) + { + *format = mapIvasFormat( hIvasDec->st_ivas->ivas_format ); + } + else + { + *format = IVAS_DEC_BS_UNKOWN; + } + + if ( *format == IVAS_DEC_BS_MASA && hIvasDec->st_ivas->hMasa != NULL ) + { + if ( hIvasDec->st_ivas->hMasa->config.input_ivas_format == MASA_ISM_FORMAT ) { - *numObjects = hIvasDec->st_ivas->nchan_ism; + *format = IVAS_DEC_BS_MASA_ISM; } - else + } + + return IVAS_ERR_OK; +} + + +/*---------------------------------------------------------------------* + * getOutputBufferSize() + * + * Get size of output buffer in samples + *---------------------------------------------------------------------*/ + +static int16_t getOutputBufferSize( + const Decoder_Struct *st_ivas /* i : IVAS decoder handle */ +) +{ + if ( st_ivas->hDecoderConfig == NULL ) + { + return -1; + } + + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) + { + return (int16_t) ( st_ivas->hDecoderConfig->output_Fs * ( MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS ) / FRAMES_PER_SEC ); + } + else if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM ) + { + if ( st_ivas->hLsSetupCustom == NULL ) { - *numObjects = 0; + return -1; } + return (int16_t) ( st_ivas->hDecoderConfig->output_Fs * ( st_ivas->hLsSetupCustom->num_spk + st_ivas->hLsSetupCustom->num_lfe ) / FRAMES_PER_SEC ); + } + else + { + return (int16_t) ( st_ivas->hDecoderConfig->output_Fs * st_ivas->hDecoderConfig->nchan_out / FRAMES_PER_SEC ); + } +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_GetOutputBufferSize() + * + * Returns size of output buffer in samples + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_GetOutputBufferSize( + const IVAS_DEC_HANDLE hIvasDec, /* i : IVAS decoder handle */ + int16_t *outputBufferSize /* o : total number of samples expected in the output buffer for current decoder configuration */ +) +{ + if ( outputBufferSize == NULL || hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + *outputBufferSize = getOutputBufferSize( hIvasDec->st_ivas ); + + if ( *outputBufferSize == -1 ) + { + return IVAS_ERR_INVALID_OUTPUT_BUFFER_SIZE; + } + else + { return IVAS_ERR_OK; } +} - /*---------------------------------------------------------------------* - * IVAS_DEC_GetFormat( ) - * - * Returns the format of currently decoded bitstream. - * Note: bitstream format is only known after the first (good) frame has been decoded. - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_GetNumOutputChannels( ) + * + * Returns number of output channels + *---------------------------------------------------------------------*/ - ivas_error IVAS_DEC_GetFormat( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_DEC_BS_FORMAT * format /* o : format detected from bitstream fed to the decoder */ - ) +ivas_error IVAS_DEC_GetNumOutputChannels( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *numOutputChannels /* o : number of PCM output channels */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( hIvasDec->hasDecodedFirstGoodFrame ) - { - *format = mapIvasFormat( hIvasDec->st_ivas->ivas_format ); - } - else - { - *format = IVAS_DEC_BS_UNKOWN; - } + if ( hIvasDec->hasDecodedFirstGoodFrame ) + { + *numOutputChannels = hIvasDec->st_ivas->hDecoderConfig->nchan_out; + } + else + { + *numOutputChannels = 0; + } + + return IVAS_ERR_OK; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_GetObjectMetadata( ) + * + * Get metadata of one object decoded in the most recent frame + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_GetObjectMetadata( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_ISM_METADATA *metadata, /* o : struct where metadata decoded in most recently decoded frame will be written */ + const uint16_t zero_flag, /* i : if this flag is enabled, this function outputs a zero-initialized metadata struct */ + const uint16_t objectIdx /* i : index of the queried object */ +) +{ + Decoder_Struct *st_ivas; + ISM_METADATA_HANDLE hIsmMeta; + int16_t is_masa_ism; + is_masa_ism = 0; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( *format == IVAS_DEC_BS_MASA && hIvasDec->st_ivas->hMasa != NULL ) + st_ivas = hIvasDec->st_ivas; + if ( hIvasDec->st_ivas->hMasa != NULL ) + { + if ( hIvasDec->st_ivas->hMasa->config.input_ivas_format == MASA_ISM_FORMAT ) { - if ( hIvasDec->st_ivas->hMasa->config.input_ivas_format == MASA_ISM_FORMAT ) - { - *format = IVAS_DEC_BS_MASA_ISM; - } + is_masa_ism = 1; } - - return IVAS_ERR_OK; + } + if ( st_ivas->ivas_format != ISM_FORMAT && st_ivas->ivas_format != MASA_ISM_FORMAT && st_ivas->ivas_format != SBA_ISM_FORMAT && is_masa_ism == 0 ) + { + return IVAS_ERR_WRONG_MODE; } + if ( objectIdx >= st_ivas->nchan_ism ) + { + return IVAS_ERR_INVALID_INDEX; + } - /*---------------------------------------------------------------------* - * getOutputBufferSize() - * - * Get size of output buffer in samples - *---------------------------------------------------------------------*/ + hIsmMeta = st_ivas->hIsmMetaData[objectIdx]; - static int16_t getOutputBufferSize( - const Decoder_Struct *st_ivas /* i : IVAS decoder handle */ - ) + if ( hIsmMeta == NULL || zero_flag || ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) ) { - if ( st_ivas->hDecoderConfig == NULL ) + metadata->azimuth = 0.f; + metadata->elevation = 0.f; + metadata->radius = 1.f; + metadata->spread = 0.f; + metadata->gainFactor = 1.f; + metadata->yaw = 0.f; + metadata->pitch = 0.f; + metadata->non_diegetic_flag = 0; + } + else + { + if ( st_ivas->ism_mode == ISM_MODE_DISC ) { - return -1; - } + metadata->azimuth = hIsmMeta->edited_azimuth; + metadata->elevation = hIsmMeta->edited_elevation; + metadata->radius = hIsmMeta->edited_radius; - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) + metadata->yaw = hIsmMeta->edited_yaw; + metadata->pitch = hIsmMeta->edited_pitch; + metadata->spread = 0.f; + + metadata->gainFactor = hIsmMeta->edited_gain; + metadata->non_diegetic_flag = hIsmMeta->non_diegetic_flag; + } + else if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { - return (int16_t) ( st_ivas->hDecoderConfig->output_Fs * ( MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS ) / FRAMES_PER_SEC ); + metadata->azimuth = st_ivas->hParamIsmDec->edited_azimuth_values[objectIdx]; + metadata->elevation = st_ivas->hParamIsmDec->edited_elevation_values[objectIdx]; + metadata->radius = hIsmMeta->radius; + metadata->yaw = hIsmMeta->yaw; + metadata->pitch = hIsmMeta->pitch; + metadata->spread = 0.f; + metadata->gainFactor = 1.f; + metadata->non_diegetic_flag = hIsmMeta->non_diegetic_flag; } - else if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM ) + else if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) { - if ( st_ivas->hLsSetupCustom == NULL ) - { - return -1; - } - - return (int16_t) ( st_ivas->hDecoderConfig->output_Fs * ( st_ivas->hLsSetupCustom->num_spk + st_ivas->hLsSetupCustom->num_lfe ) / FRAMES_PER_SEC ); + metadata->azimuth = st_ivas->hIsmMetaData[objectIdx]->edited_azimuth; + metadata->elevation = st_ivas->hIsmMetaData[objectIdx]->edited_elevation; + metadata->radius = st_ivas->hIsmMetaData[objectIdx]->edited_radius; + metadata->yaw = st_ivas->hIsmMetaData[objectIdx]->edited_yaw; + metadata->pitch = st_ivas->hIsmMetaData[objectIdx]->edited_pitch; + metadata->spread = 0.f; + metadata->gainFactor = st_ivas->hIsmMetaData[objectIdx]->edited_gain; + metadata->non_diegetic_flag = st_ivas->hIsmMetaData[objectIdx]->non_diegetic_flag; } else { - return (int16_t) ( st_ivas->hDecoderConfig->output_Fs * st_ivas->hDecoderConfig->nchan_out / FRAMES_PER_SEC ); + metadata->azimuth = hIsmMeta->azimuth; + metadata->elevation = hIsmMeta->elevation; + metadata->radius = hIsmMeta->radius; + metadata->yaw = hIsmMeta->yaw; + metadata->pitch = hIsmMeta->pitch; + metadata->spread = 0.f; + metadata->gainFactor = 1.f; + metadata->non_diegetic_flag = hIsmMeta->non_diegetic_flag; } } + return IVAS_ERR_OK; +} + - /*---------------------------------------------------------------------* - * IVAS_DEC_GetOutputBufferSize() - * - * Returns size of output buffer in samples - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_GetMasaMetadata( ) + * + * Get metadata of the most recently decoded MASA frame + *---------------------------------------------------------------------*/ - ivas_error IVAS_DEC_GetOutputBufferSize( - const IVAS_DEC_HANDLE hIvasDec, /* i : IVAS decoder handle */ - int16_t *outputBufferSize /* o : total number of samples expected in the output buffer for current decoder configuration */ - ) +ivas_error IVAS_DEC_GetMasaMetadata( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + MASA_DECODER_EXT_OUT_META_HANDLE *hMasaExtOutMeta, /* o : pointer to handle, which will be set to point to metadata from the most recently decoded frame */ + const uint8_t getFromJbmBuffer /* i : get metadata from a JBM buffer */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - if ( outputBufferSize == NULL || hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - *outputBufferSize = getOutputBufferSize( hIvasDec->st_ivas ); + if ( hIvasDec->st_ivas->ivas_format != MASA_FORMAT && hIvasDec->st_ivas->ivas_format != MASA_ISM_FORMAT ) + { + return IVAS_ERR_WRONG_MODE; + } - if ( *outputBufferSize == -1 ) - { - return IVAS_ERR_INVALID_OUTPUT_BUFFER_SIZE; - } - else - { - return IVAS_ERR_OK; - } + if ( getFromJbmBuffer ) + { + ivas_jbm_masa_sf_to_sf_map( hIvasDec->st_ivas ); } + *hMasaExtOutMeta = hIvasDec->st_ivas->hMasa->data.extOutMeta; - /*---------------------------------------------------------------------* - * IVAS_DEC_GetNumOutputChannels( ) - * - * Returns number of output channels - *---------------------------------------------------------------------*/ + return IVAS_ERR_OK; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_FeedHeadTrackData( ) + * + * Feed the decoder with the head tracking data + *---------------------------------------------------------------------*/ - ivas_error IVAS_DEC_GetNumOutputChannels( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t * numOutputChannels /* o : number of PCM output channels */ - ) +ivas_error IVAS_DEC_FeedHeadTrackData( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_QUATERNION orientation, /* i : head-tracking data, listener orientation */ + IVAS_VECTOR3 Pos, /* i : listener position */ + const int16_t subframe_idx, /* i : subframe index */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ +) +{ + HEAD_TRACK_DATA_HANDLE hHeadTrackData; + ivas_error error; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( hIvasDec->hasDecodedFirstGoodFrame ) - { - *numOutputChannels = hIvasDec->st_ivas->hDecoderConfig->nchan_out; - } - else - { - *numOutputChannels = 0; - } + hHeadTrackData = hIvasDec->st_ivas->hHeadTrackData; - return IVAS_ERR_OK; + if ( hHeadTrackData == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + /* Move head-tracking data to the decoder handle */ + /* check for Euler angle signaling */ + if ( orientation.w == -3.0f ) + { + Euler2Quat( deg2rad( orientation.x ), deg2rad( orientation.y ), deg2rad( orientation.z ), &orientation ); + } + + if ( ( error = ivas_orient_trk_Process( hHeadTrackData->OrientationTracker, orientation, FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES, &hHeadTrackData->Quaternions[subframe_idx] ) ) != IVAS_ERR_OK ) + { + return error; } + hHeadTrackData->Pos[subframe_idx].x = Pos.x; + hHeadTrackData->Pos[subframe_idx].y = Pos.y; + hHeadTrackData->Pos[subframe_idx].z = Pos.z; + + hHeadTrackData->sr_pose_pred_axis = rot_axis; + hIvasDec->updateOrientation = true; + + return IVAS_ERR_OK; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_FeedRefRotData( ) + * + * Feed the decoder with the reference rotation data + *---------------------------------------------------------------------*/ - /*---------------------------------------------------------------------* - * IVAS_DEC_GetObjectMetadata( ) - * - * Get metadata of one object decoded in the most recent frame - *---------------------------------------------------------------------*/ +ivas_error IVAS_DEC_FeedRefRotData( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_QUATERNION rotation /* i : reference rotation data */ +) +{ + ivas_orient_trk_state_t *pOtr; - ivas_error IVAS_DEC_GetObjectMetadata( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_ISM_METADATA * metadata, /* o : struct where metadata decoded in most recently decoded frame will be written */ - const uint16_t zero_flag, /* i : if this flag is enabled, this function outputs a zero-initialized metadata struct */ - const uint16_t objectIdx /* i : index of the queried object */ - ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHeadTrackData == NULL || hIvasDec->st_ivas->hHeadTrackData->OrientationTracker == NULL ) { - Decoder_Struct *st_ivas; - ISM_METADATA_HANDLE hIsmMeta; - int16_t is_masa_ism; - is_masa_ism = 0; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + pOtr = hIvasDec->st_ivas->hHeadTrackData->OrientationTracker; - st_ivas = hIvasDec->st_ivas; - if ( hIvasDec->st_ivas->hMasa != NULL ) - { - if ( hIvasDec->st_ivas->hMasa->config.input_ivas_format == MASA_ISM_FORMAT ) - { - is_masa_ism = 1; - } - } - if ( st_ivas->ivas_format != ISM_FORMAT && st_ivas->ivas_format != MASA_ISM_FORMAT && st_ivas->ivas_format != SBA_ISM_FORMAT && is_masa_ism == 0 ) - { - return IVAS_ERR_WRONG_MODE; - } + pOtr->refRot.w = rotation.w; + pOtr->refRot.x = rotation.x; + pOtr->refRot.z = rotation.z; + pOtr->refRot.y = rotation.y; - if ( objectIdx >= st_ivas->nchan_ism ) - { - return IVAS_ERR_INVALID_INDEX; - } + hIvasDec->updateOrientation = true; - hIsmMeta = st_ivas->hIsmMetaData[objectIdx]; + return IVAS_ERR_OK; +} - if ( hIsmMeta == NULL || zero_flag || ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) ) - { - metadata->azimuth = 0.f; - metadata->elevation = 0.f; - metadata->radius = 1.f; - metadata->spread = 0.f; - metadata->gainFactor = 1.f; - metadata->yaw = 0.f; - metadata->pitch = 0.f; - metadata->non_diegetic_flag = 0; - } - else - { - if ( st_ivas->ism_mode == ISM_MODE_DISC ) - { - metadata->azimuth = hIsmMeta->edited_azimuth; - metadata->elevation = hIsmMeta->edited_elevation; - metadata->radius = hIsmMeta->edited_radius; - metadata->yaw = hIsmMeta->edited_yaw; - metadata->pitch = hIsmMeta->edited_pitch; - metadata->spread = 0.f; +/*---------------------------------------------------------------------* + * IVAS_DEC_FeedRefVectorData( ) + * + * Feed the decoder with a reference vector spanning from listenerPos + * to refPos. Only available in OTR_TRACKING_REF_POS and + * OTR_TRACKING_REF_POS_LEV modes. + *---------------------------------------------------------------------*/ - metadata->gainFactor = hIsmMeta->edited_gain; - metadata->non_diegetic_flag = hIsmMeta->non_diegetic_flag; - } - else if ( st_ivas->ism_mode == ISM_MODE_PARAM ) - { - metadata->azimuth = st_ivas->hParamIsmDec->edited_azimuth_values[objectIdx]; - metadata->elevation = st_ivas->hParamIsmDec->edited_elevation_values[objectIdx]; - metadata->radius = hIsmMeta->radius; - metadata->yaw = hIsmMeta->yaw; - metadata->pitch = hIsmMeta->pitch; - metadata->spread = 0.f; - metadata->gainFactor = 1.f; - metadata->non_diegetic_flag = hIsmMeta->non_diegetic_flag; - } - else if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) - { - metadata->azimuth = st_ivas->hIsmMetaData[objectIdx]->edited_azimuth; - metadata->elevation = st_ivas->hIsmMetaData[objectIdx]->edited_elevation; - metadata->radius = st_ivas->hIsmMetaData[objectIdx]->edited_radius; - metadata->yaw = st_ivas->hIsmMetaData[objectIdx]->edited_yaw; - metadata->pitch = st_ivas->hIsmMetaData[objectIdx]->edited_pitch; - metadata->spread = 0.f; - metadata->gainFactor = st_ivas->hIsmMetaData[objectIdx]->edited_gain; - metadata->non_diegetic_flag = st_ivas->hIsmMetaData[objectIdx]->non_diegetic_flag; - } - else - { - metadata->azimuth = hIsmMeta->azimuth; - metadata->elevation = hIsmMeta->elevation; - metadata->radius = hIsmMeta->radius; - metadata->yaw = hIsmMeta->yaw; - metadata->pitch = hIsmMeta->pitch; - metadata->spread = 0.f; - metadata->gainFactor = 1.f; - metadata->non_diegetic_flag = hIsmMeta->non_diegetic_flag; - } - } +ivas_error IVAS_DEC_FeedRefVectorData( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_VECTOR3 listenerPos, /* i : Listener position */ + const IVAS_VECTOR3 refPos /* i : Reference position */ +) +{ + ivas_orient_trk_state_t *pOtr; - return IVAS_ERR_OK; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHeadTrackData == NULL || hIvasDec->st_ivas->hHeadTrackData->OrientationTracker == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + pOtr = hIvasDec->st_ivas->hHeadTrackData->OrientationTracker; - /*---------------------------------------------------------------------* - * IVAS_DEC_GetMasaMetadata( ) - * - * Get metadata of the most recently decoded MASA frame - *---------------------------------------------------------------------*/ + hIvasDec->updateOrientation = true; - ivas_error IVAS_DEC_GetMasaMetadata( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - MASA_DECODER_EXT_OUT_META_HANDLE * hMasaExtOutMeta, /* o : pointer to handle, which will be set to point to metadata from the most recently decoded frame */ - const uint8_t getFromJbmBuffer /* i : get metadata from a JBM buffer */ - ) + return ivas_orient_trk_SetReferenceVector( pOtr, listenerPos, refPos ); +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_FeedExternalOrientationData( ) + * + * Feed the decoder with the external orientation data + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_FeedExternalOrientationData( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_QUATERNION orientation, /* i : external orientation data */ + int8_t enableHeadRotation, /* i : flag to enable head rotation for this frame */ + int8_t enableExternalOrientation, /* i : flag to enable external orientation for this frame */ + int8_t enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ + int16_t numFramesToTargetOrientation, /* i : number of frames until target orientation is reached */ + const int16_t subframe_idx /* i : subframe index */ +) +{ + EXTERNAL_ORIENTATION_HANDLE hExternalOrientationData; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( hIvasDec->st_ivas->ivas_format != MASA_FORMAT && hIvasDec->st_ivas->ivas_format != MASA_ISM_FORMAT ) - { - return IVAS_ERR_WRONG_MODE; - } + hExternalOrientationData = hIvasDec->st_ivas->hExtOrientationData; - if ( getFromJbmBuffer ) - { - ivas_jbm_masa_sf_to_sf_map( hIvasDec->st_ivas ); - } + if ( hExternalOrientationData == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + /* Move external orientation data to the decoder handle (invert orientations) */ + QuaternionInverse( orientation, &hExternalOrientationData->Quaternions[subframe_idx] ); + + hExternalOrientationData->enableHeadRotation[subframe_idx] = enableHeadRotation; + hExternalOrientationData->enableExternalOrientation[subframe_idx] = enableExternalOrientation; + hExternalOrientationData->enableRotationInterpolation[subframe_idx] = enableRotationInterpolation; + hExternalOrientationData->numFramesToTargetOrientation[subframe_idx] = numFramesToTargetOrientation; + + hIvasDec->updateOrientation = true; + + return IVAS_ERR_OK; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_FeedCustomLsData( ) + * + * Feed the decoder with the Custom loudspeaker data + *---------------------------------------------------------------------*/ - *hMasaExtOutMeta = hIvasDec->st_ivas->hMasa->data.extOutMeta; +/*! r: error code */ +ivas_error IVAS_DEC_FeedCustomLsData( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_CUSTOM_LS_DATA hLsCustomData /* i : Custom loudspeaker setup data */ +) +{ + int16_t i, is_planar; + IVAS_LSSETUP_CUSTOM_HANDLE hLsSetupCustom; - return IVAS_ERR_OK; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + hLsSetupCustom = hIvasDec->st_ivas->hLsSetupCustom; - /*---------------------------------------------------------------------* - * IVAS_DEC_FeedHeadTrackData( ) - * - * Feed the decoder with the head tracking data - *---------------------------------------------------------------------*/ - - ivas_error IVAS_DEC_FeedHeadTrackData( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_QUATERNION orientation, /* i : head-tracking data, listener orientation */ - IVAS_VECTOR3 Pos, /* i : listener position */ - const int16_t subframe_idx, /* i : subframe index */ - const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ - ) + if ( hLsSetupCustom == NULL ) { - HEAD_TRACK_DATA_HANDLE hHeadTrackData; - ivas_error error; - - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - hHeadTrackData = hIvasDec->st_ivas->hHeadTrackData; + /* Move Custom LS layout data to the decoder handle */ - if ( hHeadTrackData == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + /* Loudspeaker azimuths and elevations */ + hLsSetupCustom->num_spk = hLsCustomData.num_spk; - /* Move head-tracking data to the decoder handle */ - /* check for Euler angle signaling */ - if ( orientation.w == -3.0f ) - { - Euler2Quat( deg2rad( orientation.x ), deg2rad( orientation.y ), deg2rad( orientation.z ), &orientation ); - } + mvr2r( hLsCustomData.azimuth, hLsSetupCustom->ls_azimuth, hLsCustomData.num_spk ); + mvr2r( hLsCustomData.elevation, hLsSetupCustom->ls_elevation, hLsCustomData.num_spk ); - if ( ( error = ivas_orient_trk_Process( hHeadTrackData->OrientationTracker, orientation, FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES, &hHeadTrackData->Quaternions[subframe_idx] ) ) != IVAS_ERR_OK ) + /* Set planar flag */ + is_planar = 1; + for ( i = 0; i < hLsCustomData.num_spk; i++ ) + { + if ( is_planar && hLsSetupCustom->ls_elevation[i] != 0.0f ) { - return error; + is_planar = 0; } + } + hLsSetupCustom->is_planar_setup = is_planar; - hHeadTrackData->Pos[subframe_idx].x = Pos.x; - hHeadTrackData->Pos[subframe_idx].y = Pos.y; - hHeadTrackData->Pos[subframe_idx].z = Pos.z; - - hHeadTrackData->sr_pose_pred_axis = rot_axis; - hIvasDec->updateOrientation = true; + /* Loudspeaker LFE */ + hLsSetupCustom->num_lfe = hLsCustomData.num_lfe; + mvs2s( hLsCustomData.lfe_idx, hLsSetupCustom->lfe_idx, hLsCustomData.num_lfe ); - return IVAS_ERR_OK; - } + return IVAS_ERR_OK; +} - /*---------------------------------------------------------------------* - * IVAS_DEC_FeedRefRotData( ) - * - * Feed the decoder with the reference rotation data - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_GetHrtfTDrendHandle( ) + * + * Get TD binaural renderer handle + *---------------------------------------------------------------------*/ - ivas_error IVAS_DEC_FeedRefRotData( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_QUATERNION rotation /* i : reference rotation data */ - ) +ivas_error IVAS_DEC_GetHrtfTDrendHandle( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_DEC_HRTF_TD_HANDLE **hHrtfTD /* o : HRTF handle */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHrtfTD == NULL ) { - ivas_orient_trk_state_t *pOtr; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHeadTrackData == NULL || hIvasDec->st_ivas->hHeadTrackData->OrientationTracker == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + *hHrtfTD = &hIvasDec->st_ivas->hHrtfTD; - pOtr = hIvasDec->st_ivas->hHeadTrackData->OrientationTracker; + return IVAS_ERR_OK; +} - pOtr->refRot.w = rotation.w; - pOtr->refRot.x = rotation.x; - pOtr->refRot.z = rotation.z; - pOtr->refRot.y = rotation.y; - hIvasDec->updateOrientation = true; +/*---------------------------------------------------------------------* + * IVAS_DEC_GetHrtfCRendHandle( ) + * + * Get Crend binaural renderer handle + *---------------------------------------------------------------------*/ - return IVAS_ERR_OK; +ivas_error IVAS_DEC_GetHrtfCRendHandle( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_DEC_HRTF_CREND_HANDLE **hHrtfCrend /* o : Crend HRTF handle */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHrtfCrend == NULL ) + { + return IVAS_ERR_WRONG_PARAMS; } + *hHrtfCrend = &hIvasDec->st_ivas->hHrtfCrend; - /*---------------------------------------------------------------------* - * IVAS_DEC_FeedRefVectorData( ) - * - * Feed the decoder with a reference vector spanning from listenerPos - * to refPos. Only available in OTR_TRACKING_REF_POS and - * OTR_TRACKING_REF_POS_LEV modes. - *---------------------------------------------------------------------*/ + return IVAS_ERR_OK; +} - ivas_error IVAS_DEC_FeedRefVectorData( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const IVAS_VECTOR3 listenerPos, /* i : Listener position */ - const IVAS_VECTOR3 refPos /* i : Reference position */ - ) - { - ivas_orient_trk_state_t *pOtr; - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHeadTrackData == NULL || hIvasDec->st_ivas->hHeadTrackData->OrientationTracker == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } +/*---------------------------------------------------------------------* + * IVAS_DEC_GetHrtfFastConvHandle( ) + * + * Get FastConv binaural renderer handle + *---------------------------------------------------------------------*/ - pOtr = hIvasDec->st_ivas->hHeadTrackData->OrientationTracker; +ivas_error IVAS_DEC_GetHrtfFastConvHandle( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_DEC_HRTF_FASTCONV_HANDLE **hHrtfFastConv /* o : FASTCONV HRTF handle */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHrtfFastConv == NULL ) + { + return IVAS_ERR_WRONG_PARAMS; + } - hIvasDec->updateOrientation = true; + *hHrtfFastConv = &hIvasDec->st_ivas->hHrtfFastConv; - return ivas_orient_trk_SetReferenceVector( pOtr, listenerPos, refPos ); - } + return IVAS_ERR_OK; +} - /*---------------------------------------------------------------------* - * IVAS_DEC_FeedExternalOrientationData( ) - * - * Feed the decoder with the external orientation data - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_GetHrtfParamBinHandle( ) + * + * Get Parametric binaural renderer handle + *---------------------------------------------------------------------*/ - ivas_error IVAS_DEC_FeedExternalOrientationData( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_QUATERNION orientation, /* i : external orientation data */ - int8_t enableHeadRotation, /* i : flag to enable head rotation for this frame */ - int8_t enableExternalOrientation, /* i : flag to enable external orientation for this frame */ - int8_t enableRotationInterpolation, /* i : flag to interpolate rotations from current and previous frames */ - int16_t numFramesToTargetOrientation, /* i : number of frames until target orientation is reached */ - const int16_t subframe_idx /* i : subframe index */ - ) +ivas_error IVAS_DEC_GetHrtfParamBinHandle( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_DEC_HRTF_PARAMBIN_HANDLE **hHrtfParambin /* o : Parametric binauralizer HRTF handle */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHrtfParambin == NULL ) { - EXTERNAL_ORIENTATION_HANDLE hExternalOrientationData; + return IVAS_ERR_WRONG_PARAMS; + } - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + *hHrtfParambin = &hIvasDec->st_ivas->hHrtfParambin; - hExternalOrientationData = hIvasDec->st_ivas->hExtOrientationData; + return IVAS_ERR_OK; +} - if ( hExternalOrientationData == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } +/*---------------------------------------------------------------------* + * IVAS_DEC_GetHrtfStatisticsHandle( ) + * + * Get HRTF statistics (room effect) binaural renderer handle + *---------------------------------------------------------------------*/ - /* Move external orientation data to the decoder handle (invert orientations) */ - QuaternionInverse( orientation, &hExternalOrientationData->Quaternions[subframe_idx] ); +ivas_error IVAS_DEC_GetHrtfStatisticsHandle( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_DEC_HRTF_STATISTICS_HANDLE **hHrtfStatistics /* o : HRTF statistics handle */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHrtfStatistics == NULL ) + { + return IVAS_ERR_WRONG_PARAMS; + } - hExternalOrientationData->enableHeadRotation[subframe_idx] = enableHeadRotation; - hExternalOrientationData->enableExternalOrientation[subframe_idx] = enableExternalOrientation; - hExternalOrientationData->enableRotationInterpolation[subframe_idx] = enableRotationInterpolation; - hExternalOrientationData->numFramesToTargetOrientation[subframe_idx] = numFramesToTargetOrientation; + *hHrtfStatistics = &hIvasDec->st_ivas->hHrtfStatistics; - hIvasDec->updateOrientation = true; + return IVAS_ERR_OK; +} - return IVAS_ERR_OK; - } +/*---------------------------------------------------------------------* + * IVAS_DEC_HRTF_binary_open( ) + * + * Allocate HRTF binary handles + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_HRTF_binary_open( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_BIN_RENDERER_TYPE binaural_renderer /* i : binaural renderer type */ +) +{ + ivas_error error; + Decoder_Struct *st_ivas; - /*---------------------------------------------------------------------* - * IVAS_DEC_FeedCustomLsData( ) - * - * Feed the decoder with the Custom loudspeaker data - *---------------------------------------------------------------------*/ + st_ivas = hIvasDec->st_ivas; - /*! r: error code */ - ivas_error IVAS_DEC_FeedCustomLsData( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const IVAS_CUSTOM_LS_DATA hLsCustomData /* i : Custom loudspeaker setup data */ - ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - int16_t i, is_planar; - IVAS_LSSETUP_CUSTOM_HANDLE hLsSetupCustom; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + if ( st_ivas->hDecoderConfig->Opt_HRTF_binary ) + { + /* TD binaural renderer */ + if ( ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_TDREND || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && st_ivas->hHrtfTD == NULL ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + if ( ( error = ivas_HRTF_td_binary_open( &( st_ivas->hHrtfTD ) ) ) != IVAS_ERR_OK ) + { + return error; + } } - hLsSetupCustom = hIvasDec->st_ivas->hLsSetupCustom; - - if ( hLsSetupCustom == NULL ) + /* Crend binaural renderer */ + if ( ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_CREND || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && st_ivas->hHrtfCrend == NULL ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + if ( ( error = ivas_HRTF_CRend_binary_open( &( st_ivas->hHrtfCrend ) ) ) != IVAS_ERR_OK ) + { + return error; + } } - /* Move Custom LS layout data to the decoder handle */ - - /* Loudspeaker azimuths and elevations */ - hLsSetupCustom->num_spk = hLsCustomData.num_spk; - - mvr2r( hLsCustomData.azimuth, hLsSetupCustom->ls_azimuth, hLsCustomData.num_spk ); - mvr2r( hLsCustomData.elevation, hLsSetupCustom->ls_elevation, hLsCustomData.num_spk ); - - /* Set planar flag */ - is_planar = 1; - for ( i = 0; i < hLsCustomData.num_spk; i++ ) + /* FastConv binaural renderer */ + if ( ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_FASTCONV || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && st_ivas->hHrtfFastConv == NULL ) { - if ( is_planar && hLsSetupCustom->ls_elevation[i] != 0.0f ) + if ( ( error = ivas_HRTF_fastconv_binary_open( &st_ivas->hHrtfFastConv ) ) != IVAS_ERR_OK ) { - is_planar = 0; + return error; } } - hLsSetupCustom->is_planar_setup = is_planar; - /* Loudspeaker LFE */ - hLsSetupCustom->num_lfe = hLsCustomData.num_lfe; - mvs2s( hLsCustomData.lfe_idx, hLsSetupCustom->lfe_idx, hLsCustomData.num_lfe ); + /* Parametric binaural renderer */ + if ( ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_PARAMBIN || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && st_ivas->hHrtfParambin == NULL ) + { + if ( ( error = ivas_HRTF_parambin_binary_open( &st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK ) + { + return error; + } + } - return IVAS_ERR_OK; + if ( st_ivas->hHrtfStatistics == NULL && ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_FASTCONV || binaural_renderer == IVAS_BIN_RENDERER_TYPE_CREND ) && st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) + { + if ( ( error = ivas_HRTF_statistics_binary_open( &st_ivas->hHrtfStatistics ) ) != IVAS_ERR_OK ) + { + return error; + } + } } + return IVAS_ERR_OK; +} - /*---------------------------------------------------------------------* - * IVAS_DEC_GetHrtfTDrendHandle( ) - * - * Get TD binaural renderer handle - *---------------------------------------------------------------------*/ - ivas_error IVAS_DEC_GetHrtfTDrendHandle( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_DEC_HRTF_TD_HANDLE * *hHrtfTD /* o : HRTF handle */ - ) - { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHrtfTD == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } +/*---------------------------------------------------------------------* + * IVAS_DEC_HRTF_binary_close( ) + * + * Deallocate HRTF binary handles + *---------------------------------------------------------------------*/ - *hHrtfTD = &hIvasDec->st_ivas->hHrtfTD; +ivas_error IVAS_DEC_HRTF_binary_close( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_BIN_RENDERER_TYPE binaural_renderer_old /* i : previous binaural renderer type */ +) +{ + Decoder_Struct *st_ivas; - return IVAS_ERR_OK; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + st_ivas = hIvasDec->st_ivas; - /*---------------------------------------------------------------------* - * IVAS_DEC_GetHrtfCRendHandle( ) - * - * Get Crend binaural renderer handle - *---------------------------------------------------------------------*/ - - ivas_error IVAS_DEC_GetHrtfCRendHandle( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_DEC_HRTF_CREND_HANDLE * *hHrtfCrend /* o : Crend HRTF handle */ - ) + if ( st_ivas->hDecoderConfig->Opt_HRTF_binary && st_ivas->ini_frame > 0 ) { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHrtfCrend == NULL ) + if ( !( binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_TDREND || binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_DEFAULT ) ) { - return IVAS_ERR_WRONG_PARAMS; + ivas_HRTF_td_binary_close( &st_ivas->hHrtfTD ); } - *hHrtfCrend = &hIvasDec->st_ivas->hHrtfCrend; - - return IVAS_ERR_OK; - } - - - /*---------------------------------------------------------------------* - * IVAS_DEC_GetHrtfFastConvHandle( ) - * - * Get FastConv binaural renderer handle - *---------------------------------------------------------------------*/ + if ( !( binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_CREND || binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_DEFAULT ) ) + { + /* CRend binaural renderer handle */ + ivas_HRTF_CRend_binary_close( &st_ivas->hHrtfCrend ); + } - ivas_error IVAS_DEC_GetHrtfFastConvHandle( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_DEC_HRTF_FASTCONV_HANDLE * *hHrtfFastConv /* o : FASTCONV HRTF handle */ - ) - { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHrtfFastConv == NULL ) + if ( !( binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_FASTCONV || binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_DEFAULT ) ) { - return IVAS_ERR_WRONG_PARAMS; + /* Fastconv HRTF filters */ + ivas_HRTF_fastconv_binary_close( &st_ivas->hHrtfFastConv ); } - *hHrtfFastConv = &hIvasDec->st_ivas->hHrtfFastConv; + if ( !( binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_PARAMBIN || binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_DEFAULT ) ) + { - return IVAS_ERR_OK; + /* Parametric binauralizer HRTF filters */ + ivas_HRTF_parambin_binary_close( &st_ivas->hHrtfParambin ); + } } + return IVAS_ERR_OK; +} - /*---------------------------------------------------------------------* - * IVAS_DEC_GetHrtfParamBinHandle( ) - * - * Get Parametric binaural renderer handle - *---------------------------------------------------------------------*/ - ivas_error IVAS_DEC_GetHrtfParamBinHandle( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_DEC_HRTF_PARAMBIN_HANDLE * *hHrtfParambin /* o : Parametric binauralizer HRTF handle */ - ) - { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHrtfParambin == NULL ) - { - return IVAS_ERR_WRONG_PARAMS; - } +/*---------------------------------------------------------------------* + * IVAS_DEC_AddAcousticEnvironment( ) + * + * Adds acoustic environment configuration + *---------------------------------------------------------------------*/ - *hHrtfParambin = &hIvasDec->st_ivas->hHrtfParambin; +ivas_error IVAS_DEC_AddAcousticEnvironment( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_ROOM_ACOUSTICS_CONFIG_DATA roomAcousticsConfig /* i : Room acoustic configuration */ +) +{ + uint16_t n; + Decoder_Struct *st_ivas; + IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pAE = NULL; - return IVAS_ERR_OK; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || ( hIvasDec->st_ivas->acousticEnvironmentsCount > 0 && hIvasDec->st_ivas->pAcousticEnvironments == NULL ) ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - /*---------------------------------------------------------------------* - * IVAS_DEC_GetHrtfStatisticsHandle( ) - * - * Get HRTF statistics (room effect) binaural renderer handle - *---------------------------------------------------------------------*/ + st_ivas = hIvasDec->st_ivas; - ivas_error IVAS_DEC_GetHrtfStatisticsHandle( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_DEC_HRTF_STATISTICS_HANDLE * *hHrtfStatistics /* o : HRTF statistics handle */ - ) + /* Check if already there */ + for ( n = 0; n < st_ivas->acousticEnvironmentsCount; n++ ) { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHrtfStatistics == NULL ) + if ( st_ivas->pAcousticEnvironments[n].aeID == roomAcousticsConfig.aeID ) { - return IVAS_ERR_WRONG_PARAMS; + pAE = &st_ivas->pAcousticEnvironments[n]; + break; } - - *hHrtfStatistics = &hIvasDec->st_ivas->hHrtfStatistics; - - return IVAS_ERR_OK; } - - /*---------------------------------------------------------------------* - * IVAS_DEC_HRTF_binary_open( ) - * - * Allocate HRTF binary handles - *---------------------------------------------------------------------*/ - - ivas_error IVAS_DEC_HRTF_binary_open( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const IVAS_BIN_RENDERER_TYPE binaural_renderer /* i : binaural renderer type */ - ) + /* If not found */ + if ( pAE == NULL ) { - ivas_error error; - Decoder_Struct *st_ivas; - - st_ivas = hIvasDec->st_ivas; + IVAS_ROOM_ACOUSTICS_CONFIG_DATA *ppAE = malloc( ( st_ivas->acousticEnvironmentsCount + 1 ) * sizeof( IVAS_ROOM_ACOUSTICS_CONFIG_DATA ) ); - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + if ( ppAE == NULL ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + return IVAS_ERR_FAILED_ALLOC; } - if ( st_ivas->hDecoderConfig->Opt_HRTF_binary ) + for ( n = 0; n < st_ivas->acousticEnvironmentsCount; n++ ) { - /* TD binaural renderer */ - if ( ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_TDREND || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && st_ivas->hHrtfTD == NULL ) - { - if ( ( error = ivas_HRTF_td_binary_open( &( st_ivas->hHrtfTD ) ) ) != IVAS_ERR_OK ) - { - return error; - } - } + pAE = &ppAE[n]; + pAE->aeID = st_ivas->pAcousticEnvironments[n].aeID; + pAE->nBands = st_ivas->pAcousticEnvironments[n].nBands; + pAE->acousticPreDelay = st_ivas->pAcousticEnvironments[n].acousticPreDelay; + pAE->inputPreDelay = st_ivas->pAcousticEnvironments[n].inputPreDelay; - /* Crend binaural renderer */ - if ( ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_CREND || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && st_ivas->hHrtfCrend == NULL ) - { - if ( ( error = ivas_HRTF_CRend_binary_open( &( st_ivas->hHrtfCrend ) ) ) != IVAS_ERR_OK ) - { - return error; - } - } + mvr2r( st_ivas->pAcousticEnvironments[n].pFc_input, pAE->pFc_input, CLDFB_NO_CHANNELS_MAX ); + mvr2r( st_ivas->pAcousticEnvironments[n].pAcoustic_rt60, pAE->pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); + mvr2r( st_ivas->pAcousticEnvironments[n].pAcoustic_dsr, pAE->pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); - /* FastConv binaural renderer */ - if ( ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_FASTCONV || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && st_ivas->hHrtfFastConv == NULL ) - { - if ( ( error = ivas_HRTF_fastconv_binary_open( &st_ivas->hHrtfFastConv ) ) != IVAS_ERR_OK ) - { - return error; - } - } + pAE->use_er = st_ivas->pAcousticEnvironments[n].use_er; - /* Parametric binaural renderer */ - if ( ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_PARAMBIN || binaural_renderer == IVAS_BIN_RENDERER_TYPE_DEFAULT ) && st_ivas->hHrtfParambin == NULL ) + if ( pAE->use_er == 1 ) { - if ( ( error = ivas_HRTF_parambin_binary_open( &st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK ) - { - return error; - } - } + pAE->lowComplexity = st_ivas->pAcousticEnvironments[n].lowComplexity; + pAE->dimensions.x = st_ivas->pAcousticEnvironments[n].dimensions.x; + pAE->dimensions.y = st_ivas->pAcousticEnvironments[n].dimensions.y; + pAE->dimensions.z = st_ivas->pAcousticEnvironments[n].dimensions.z; + pAE->ListenerOrigin.x = st_ivas->pAcousticEnvironments[n].ListenerOrigin.x; + pAE->ListenerOrigin.y = st_ivas->pAcousticEnvironments[n].ListenerOrigin.y; + pAE->ListenerOrigin.z = st_ivas->pAcousticEnvironments[n].ListenerOrigin.z; - if ( st_ivas->hHrtfStatistics == NULL && ( binaural_renderer == IVAS_BIN_RENDERER_TYPE_FASTCONV || binaural_renderer == IVAS_BIN_RENDERER_TYPE_CREND ) && st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) - { - if ( ( error = ivas_HRTF_statistics_binary_open( &st_ivas->hHrtfStatistics ) ) != IVAS_ERR_OK ) - { - return error; - } + mvr2r( st_ivas->pAcousticEnvironments[n].AbsCoeff, pAE->AbsCoeff, IVAS_ROOM_ABS_COEFF ); } } - return IVAS_ERR_OK; + free( st_ivas->pAcousticEnvironments ); + st_ivas->pAcousticEnvironments = ppAE; + n = st_ivas->acousticEnvironmentsCount++; + pAE = &st_ivas->pAcousticEnvironments[n]; } + pAE->aeID = roomAcousticsConfig.aeID; + pAE->nBands = roomAcousticsConfig.nBands; + pAE->acousticPreDelay = roomAcousticsConfig.acousticPreDelay; + pAE->inputPreDelay = roomAcousticsConfig.inputPreDelay; - /*---------------------------------------------------------------------* - * IVAS_DEC_HRTF_binary_close( ) - * - * Deallocate HRTF binary handles - *---------------------------------------------------------------------*/ - - ivas_error IVAS_DEC_HRTF_binary_close( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const IVAS_BIN_RENDERER_TYPE binaural_renderer_old /* i : previous binaural renderer type */ - ) - { - Decoder_Struct *st_ivas; - - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + mvr2r( roomAcousticsConfig.pFc_input, pAE->pFc_input, CLDFB_NO_CHANNELS_MAX ); + mvr2r( roomAcousticsConfig.pAcoustic_rt60, pAE->pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); + mvr2r( roomAcousticsConfig.pAcoustic_dsr, pAE->pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); - st_ivas = hIvasDec->st_ivas; + pAE->use_er = roomAcousticsConfig.use_er; - if ( st_ivas->hDecoderConfig->Opt_HRTF_binary && st_ivas->ini_frame > 0 ) - { - if ( !( binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_TDREND || binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_DEFAULT ) ) - { - ivas_HRTF_td_binary_close( &st_ivas->hHrtfTD ); - } + if ( pAE->use_er == 1 ) + { + pAE->lowComplexity = roomAcousticsConfig.lowComplexity; + pAE->dimensions.x = roomAcousticsConfig.dimensions.x; + pAE->dimensions.y = roomAcousticsConfig.dimensions.y; + pAE->dimensions.z = roomAcousticsConfig.dimensions.z; + pAE->ListenerOrigin.x = roomAcousticsConfig.ListenerOrigin.x; + pAE->ListenerOrigin.y = roomAcousticsConfig.ListenerOrigin.y; + pAE->ListenerOrigin.z = roomAcousticsConfig.ListenerOrigin.z; + + mvr2r( roomAcousticsConfig.AbsCoeff, pAE->AbsCoeff, IVAS_ROOM_ABS_COEFF ); + } - if ( !( binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_CREND || binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_DEFAULT ) ) - { - /* CRend binaural renderer handle */ - ivas_HRTF_CRend_binary_close( &st_ivas->hHrtfCrend ); - } + return IVAS_ERR_OK; +} - if ( !( binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_FASTCONV || binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_DEFAULT ) ) - { - /* Fastconv HRTF filters */ - ivas_HRTF_fastconv_binary_close( &st_ivas->hHrtfFastConv ); - } - if ( !( binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_PARAMBIN || binaural_renderer_old == IVAS_BIN_RENDERER_TYPE_DEFAULT ) ) - { +/*---------------------------------------------------------------------* + * IVAS_DEC_GetAcousticEnvironment( ) + * + * Gets acoustic environment configuration with a given ID + *---------------------------------------------------------------------*/ - /* Parametric binauralizer HRTF filters */ - ivas_HRTF_parambin_binary_close( &st_ivas->hHrtfParambin ); - } - } +ivas_error IVAS_DEC_GetAcousticEnvironment( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint16_t aeID, /* i : Acoustic environment ID */ + IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pAcEnv /* o : Room acoustic environment data pointer */ +) +{ + uint16_t n, m; + uint16_t found = 0; + Decoder_Struct *st_ivas; - return IVAS_ERR_OK; + if ( hIvasDec == NULL || pAcEnv == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + st_ivas = hIvasDec->st_ivas; - /*---------------------------------------------------------------------* - * IVAS_DEC_AddAcousticEnvironment( ) - * - * Adds acoustic environment configuration - *---------------------------------------------------------------------*/ - - ivas_error IVAS_DEC_AddAcousticEnvironment( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const IVAS_ROOM_ACOUSTICS_CONFIG_DATA roomAcousticsConfig /* i : Room acoustic configuration */ - ) + /* In case of default AE ID, select the first one available */ + if ( aeID == IVAS_DEFAULT_AEID && st_ivas->acousticEnvironmentsCount > 0 ) { - uint16_t n; - Decoder_Struct *st_ivas; - IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pAE = NULL; - - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || ( hIvasDec->st_ivas->acousticEnvironmentsCount > 0 && hIvasDec->st_ivas->pAcousticEnvironments == NULL ) ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - st_ivas = hIvasDec->st_ivas; + aeID = st_ivas->pAcousticEnvironments[0].aeID; + } - /* Check if already there */ - for ( n = 0; n < st_ivas->acousticEnvironmentsCount; n++ ) - { - if ( st_ivas->pAcousticEnvironments[n].aeID == roomAcousticsConfig.aeID ) - { - pAE = &st_ivas->pAcousticEnvironments[n]; - break; - } - } + for ( n = 0; n < st_ivas->acousticEnvironmentsCount; n++ ) + { + IVAS_ROOM_ACOUSTICS_CONFIG_DATA ae = st_ivas->pAcousticEnvironments[n]; - /* If not found */ - if ( pAE == NULL ) + if ( aeID == ae.aeID ) { - IVAS_ROOM_ACOUSTICS_CONFIG_DATA *ppAE = malloc( ( st_ivas->acousticEnvironmentsCount + 1 ) * sizeof( IVAS_ROOM_ACOUSTICS_CONFIG_DATA ) ); - - if ( ppAE == NULL ) + found = 1; + pAcEnv->aeID = aeID; + pAcEnv->nBands = ae.nBands; + pAcEnv->inputPreDelay = ae.inputPreDelay; + for ( m = 0; m < pAcEnv->nBands; m++ ) { - return IVAS_ERR_FAILED_ALLOC; + pAcEnv->pFc_input[m] = ae.pFc_input[m]; + pAcEnv->pAcoustic_rt60[m] = ae.pAcoustic_rt60[m]; + pAcEnv->pAcoustic_dsr[m] = ae.pAcoustic_dsr[m]; } - for ( n = 0; n < st_ivas->acousticEnvironmentsCount; n++ ) + /* If ER are allocated then propagate parameters */ + pAcEnv->use_er = ae.use_er; + if ( ae.use_er != 0 ) { - pAE = &ppAE[n]; - pAE->aeID = st_ivas->pAcousticEnvironments[n].aeID; - pAE->nBands = st_ivas->pAcousticEnvironments[n].nBands; - pAE->acousticPreDelay = st_ivas->pAcousticEnvironments[n].acousticPreDelay; - pAE->inputPreDelay = st_ivas->pAcousticEnvironments[n].inputPreDelay; + pAcEnv->lowComplexity = ae.lowComplexity; - mvr2r( st_ivas->pAcousticEnvironments[n].pFc_input, pAE->pFc_input, CLDFB_NO_CHANNELS_MAX ); - mvr2r( st_ivas->pAcousticEnvironments[n].pAcoustic_rt60, pAE->pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); - mvr2r( st_ivas->pAcousticEnvironments[n].pAcoustic_dsr, pAE->pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); + pAcEnv->dimensions.x = ae.dimensions.x; + pAcEnv->dimensions.y = ae.dimensions.y; + pAcEnv->dimensions.z = ae.dimensions.z; - pAE->use_er = st_ivas->pAcousticEnvironments[n].use_er; + pAcEnv->ListenerOrigin.x = ae.ListenerOrigin.x; + pAcEnv->ListenerOrigin.y = ae.ListenerOrigin.y; + pAcEnv->ListenerOrigin.z = ae.ListenerOrigin.z; - if ( pAE->use_er == 1 ) + for ( m = 0; m < IVAS_ROOM_ABS_COEFF; m++ ) { - pAE->lowComplexity = st_ivas->pAcousticEnvironments[n].lowComplexity; - pAE->dimensions.x = st_ivas->pAcousticEnvironments[n].dimensions.x; - pAE->dimensions.y = st_ivas->pAcousticEnvironments[n].dimensions.y; - pAE->dimensions.z = st_ivas->pAcousticEnvironments[n].dimensions.z; - pAE->ListenerOrigin.x = st_ivas->pAcousticEnvironments[n].ListenerOrigin.x; - pAE->ListenerOrigin.y = st_ivas->pAcousticEnvironments[n].ListenerOrigin.y; - pAE->ListenerOrigin.z = st_ivas->pAcousticEnvironments[n].ListenerOrigin.z; - - mvr2r( st_ivas->pAcousticEnvironments[n].AbsCoeff, pAE->AbsCoeff, IVAS_ROOM_ABS_COEFF ); + pAcEnv->AbsCoeff[m] = ae.AbsCoeff[m]; } } - - free( st_ivas->pAcousticEnvironments ); - st_ivas->pAcousticEnvironments = ppAE; - n = st_ivas->acousticEnvironmentsCount++; - pAE = &st_ivas->pAcousticEnvironments[n]; - } - - pAE->aeID = roomAcousticsConfig.aeID; - pAE->nBands = roomAcousticsConfig.nBands; - pAE->acousticPreDelay = roomAcousticsConfig.acousticPreDelay; - pAE->inputPreDelay = roomAcousticsConfig.inputPreDelay; - - mvr2r( roomAcousticsConfig.pFc_input, pAE->pFc_input, CLDFB_NO_CHANNELS_MAX ); - mvr2r( roomAcousticsConfig.pAcoustic_rt60, pAE->pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); - mvr2r( roomAcousticsConfig.pAcoustic_dsr, pAE->pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); - - pAE->use_er = roomAcousticsConfig.use_er; - - if ( pAE->use_er == 1 ) - { - pAE->lowComplexity = roomAcousticsConfig.lowComplexity; - pAE->dimensions.x = roomAcousticsConfig.dimensions.x; - pAE->dimensions.y = roomAcousticsConfig.dimensions.y; - pAE->dimensions.z = roomAcousticsConfig.dimensions.z; - pAE->ListenerOrigin.x = roomAcousticsConfig.ListenerOrigin.x; - pAE->ListenerOrigin.y = roomAcousticsConfig.ListenerOrigin.y; - pAE->ListenerOrigin.z = roomAcousticsConfig.ListenerOrigin.z; - - mvr2r( roomAcousticsConfig.AbsCoeff, pAE->AbsCoeff, IVAS_ROOM_ABS_COEFF ); } - - return IVAS_ERR_OK; } + return found ? IVAS_ERR_OK : IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING; +} - /*---------------------------------------------------------------------* - * IVAS_DEC_GetAcousticEnvironment( ) - * - * Gets acoustic environment configuration with a given ID - *---------------------------------------------------------------------*/ - - ivas_error IVAS_DEC_GetAcousticEnvironment( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint16_t aeID, /* i : Acoustic environment ID */ - IVAS_ROOM_ACOUSTICS_CONFIG_DATA * pAcEnv /* o : Room acoustic environment data pointer */ - ) - { - uint16_t n, m; - uint16_t found = 0; - Decoder_Struct *st_ivas; - - if ( hIvasDec == NULL || pAcEnv == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - st_ivas = hIvasDec->st_ivas; +/*---------------------------------------------------------------------* + * copyRendererConfigStruct( ) + * + * + *---------------------------------------------------------------------*/ - /* In case of default AE ID, select the first one available */ - if ( aeID == IVAS_DEFAULT_AEID && st_ivas->acousticEnvironmentsCount > 0 ) - { - aeID = st_ivas->pAcousticEnvironments[0].aeID; - } +static ivas_error copyRendererConfigStruct( + RENDER_CONFIG_HANDLE hRCin, + IVAS_RENDER_CONFIG_HANDLE hRCout ) +{ + if ( hRCin == NULL || hRCout == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - for ( n = 0; n < st_ivas->acousticEnvironmentsCount; n++ ) - { - IVAS_ROOM_ACOUSTICS_CONFIG_DATA ae = st_ivas->pAcousticEnvironments[n]; + hRCout->roomAcoustics.aeID = hRCin->roomAcoustics.aeID; + hRCout->roomAcoustics.nBands = hRCin->roomAcoustics.nBands; + hRCout->roomAcoustics.acousticPreDelay = hRCin->roomAcoustics.acousticPreDelay; + hRCout->roomAcoustics.inputPreDelay = hRCin->roomAcoustics.inputPreDelay; - if ( aeID == ae.aeID ) - { - found = 1; - pAcEnv->aeID = aeID; - pAcEnv->nBands = ae.nBands; - pAcEnv->inputPreDelay = ae.inputPreDelay; - for ( m = 0; m < pAcEnv->nBands; m++ ) - { - pAcEnv->pFc_input[m] = ae.pFc_input[m]; - pAcEnv->pAcoustic_rt60[m] = ae.pAcoustic_rt60[m]; - pAcEnv->pAcoustic_dsr[m] = ae.pAcoustic_dsr[m]; - } + mvr2r( hRCin->roomAcoustics.pFc_input, hRCout->roomAcoustics.pFc_input, CLDFB_NO_CHANNELS_MAX ); + mvr2r( hRCin->roomAcoustics.pAcoustic_rt60, hRCout->roomAcoustics.pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); + mvr2r( hRCin->roomAcoustics.pAcoustic_dsr, hRCout->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); + mvr2r( hRCin->directivity, hRCout->directivity, 3 * MAX_NUM_OBJECTS ); + mvr2r( hRCin->distAtt, hRCout->distAtt, 3 ); - /* If ER are allocated then propagate parameters */ - pAcEnv->use_er = ae.use_er; - if ( ae.use_er != 0 ) - { - pAcEnv->lowComplexity = ae.lowComplexity; + hRCout->split_rend_config = hRCin->split_rend_config; - pAcEnv->dimensions.x = ae.dimensions.x; - pAcEnv->dimensions.y = ae.dimensions.y; - pAcEnv->dimensions.z = ae.dimensions.z; + hRCout->roomAcoustics.use_er = hRCin->roomAcoustics.use_er; + hRCout->roomAcoustics.lowComplexity = hRCin->roomAcoustics.lowComplexity; - pAcEnv->ListenerOrigin.x = ae.ListenerOrigin.x; - pAcEnv->ListenerOrigin.y = ae.ListenerOrigin.y; - pAcEnv->ListenerOrigin.z = ae.ListenerOrigin.z; + return IVAS_ERR_OK; +} - for ( m = 0; m < IVAS_ROOM_ABS_COEFF; m++ ) - { - pAcEnv->AbsCoeff[m] = ae.AbsCoeff[m]; - } - } - } - } - return found ? IVAS_ERR_OK : IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING; +/*---------------------------------------------------------------------* + * IVAS_DEC_GetRenderConfig( ) + * + * Return renderer configuration parameters handle + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_GetRenderConfig( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_RENDER_CONFIG_HANDLE hRCout /* o : Render configuration handle */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hRenderConfig == NULL || hRCout == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + return copyRendererConfigStruct( hIvasDec->st_ivas->hRenderConfig, hRCout ); +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_GetDefaultRenderConfig( ) + * + * Return default renderer configuration parameters + *---------------------------------------------------------------------*/ - /*---------------------------------------------------------------------* - * copyRendererConfigStruct( ) - * - * - *---------------------------------------------------------------------*/ +/*! r: error code*/ +ivas_error IVAS_DEC_GetDefaultRenderConfig( + IVAS_RENDER_CONFIG_HANDLE hRCout /* o : Render config handle */ +) +{ + RENDER_CONFIG_DATA RCin; + RENDER_CONFIG_HANDLE hRCin = &RCin; + ivas_error error; - static ivas_error copyRendererConfigStruct( - RENDER_CONFIG_HANDLE hRCin, - IVAS_RENDER_CONFIG_HANDLE hRCout ) + if ( ( error = ivas_render_config_init_from_rom( &hRCin ) ) != IVAS_ERR_OK ) { - if ( hRCin == NULL || hRCout == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + return error; + } - hRCout->roomAcoustics.aeID = hRCin->roomAcoustics.aeID; - hRCout->roomAcoustics.nBands = hRCin->roomAcoustics.nBands; - hRCout->roomAcoustics.acousticPreDelay = hRCin->roomAcoustics.acousticPreDelay; - hRCout->roomAcoustics.inputPreDelay = hRCin->roomAcoustics.inputPreDelay; + return copyRendererConfigStruct( hRCin, hRCout ); +} - mvr2r( hRCin->roomAcoustics.pFc_input, hRCout->roomAcoustics.pFc_input, CLDFB_NO_CHANNELS_MAX ); - mvr2r( hRCin->roomAcoustics.pAcoustic_rt60, hRCout->roomAcoustics.pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); - mvr2r( hRCin->roomAcoustics.pAcoustic_dsr, hRCout->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); - mvr2r( hRCin->directivity, hRCout->directivity, 3 * MAX_NUM_OBJECTS ); - mvr2r( hRCin->distAtt, hRCout->distAtt, 3 ); - hRCout->split_rend_config = hRCin->split_rend_config; +/*---------------------------------------------------------------------* + * IVAS_DEC_FeedRenderConfig( ) + * + * Set renderer configuration (acoustic environment) parameters + *---------------------------------------------------------------------*/ - hRCout->roomAcoustics.use_er = hRCin->roomAcoustics.use_er; - hRCout->roomAcoustics.lowComplexity = hRCin->roomAcoustics.lowComplexity; +ivas_error IVAS_DEC_FeedRenderConfig( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_RENDER_CONFIG_DATA renderConfig /* i : Render configuration struct */ +) +{ + RENDER_CONFIG_HANDLE hRenderConfig; + Decoder_Struct *st_ivas; + ivas_error error; - return IVAS_ERR_OK; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hRenderConfig == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + hRenderConfig = hIvasDec->st_ivas->hRenderConfig; + st_ivas = hIvasDec->st_ivas; - /*---------------------------------------------------------------------* - * IVAS_DEC_GetRenderConfig( ) - * - * Return renderer configuration parameters handle - *---------------------------------------------------------------------*/ + hRenderConfig->roomAcoustics.aeID = renderConfig.roomAcoustics.aeID; + hRenderConfig->roomAcoustics.nBands = renderConfig.roomAcoustics.nBands; + hRenderConfig->roomAcoustics.acousticPreDelay = renderConfig.roomAcoustics.acousticPreDelay; + hRenderConfig->roomAcoustics.inputPreDelay = renderConfig.roomAcoustics.inputPreDelay; - ivas_error IVAS_DEC_GetRenderConfig( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const IVAS_RENDER_CONFIG_HANDLE hRCout /* o : Render configuration handle */ - ) + hRenderConfig->roomAcoustics.use_er = 0; + if ( renderConfig.roomAcoustics.use_er == 1 ) { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hRenderConfig == NULL || hRCout == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + hRenderConfig->roomAcoustics.use_er = renderConfig.roomAcoustics.use_er; + hRenderConfig->roomAcoustics.lowComplexity = renderConfig.roomAcoustics.lowComplexity; + hRenderConfig->roomAcoustics.dimensions = renderConfig.roomAcoustics.dimensions; + hRenderConfig->roomAcoustics.ListenerOrigin = renderConfig.roomAcoustics.ListenerOrigin; - return copyRendererConfigStruct( hIvasDec->st_ivas->hRenderConfig, hRCout ); + mvr2r( renderConfig.roomAcoustics.AbsCoeff, hRenderConfig->roomAcoustics.AbsCoeff, IVAS_ROOM_ABS_COEFF ); } + mvr2r( renderConfig.roomAcoustics.pFc_input, hRenderConfig->roomAcoustics.pFc_input, CLDFB_NO_CHANNELS_MAX ); + mvr2r( renderConfig.roomAcoustics.pAcoustic_rt60, hRenderConfig->roomAcoustics.pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); + mvr2r( renderConfig.roomAcoustics.pAcoustic_dsr, hRenderConfig->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); - /*---------------------------------------------------------------------* - * IVAS_DEC_GetDefaultRenderConfig( ) - * - * Return default renderer configuration parameters - *---------------------------------------------------------------------*/ + /* Re-initialize reverb instance if already available */ - /*! r: error code*/ - ivas_error IVAS_DEC_GetDefaultRenderConfig( - IVAS_RENDER_CONFIG_HANDLE hRCout /* o : Render config handle */ - ) + /* TD renderer Jot reverberator */ + if ( st_ivas->hReverb != NULL ) { - RENDER_CONFIG_DATA RCin; - RENDER_CONFIG_HANDLE hRCin = &RCin; - ivas_error error; - - if ( ( error = ivas_render_config_init_from_rom( &hRCin ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_reverb_open( &st_ivas->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) { return error; } - - return copyRendererConfigStruct( hRCin, hRCout ); } - - /*---------------------------------------------------------------------* - * IVAS_DEC_FeedRenderConfig( ) - * - * Set renderer configuration (acoustic environment) parameters - *---------------------------------------------------------------------*/ - - ivas_error IVAS_DEC_FeedRenderConfig( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const IVAS_RENDER_CONFIG_DATA renderConfig /* i : Render configuration struct */ - ) + /* CREND Jot reverberator */ + if ( st_ivas->hCrendWrapper != NULL && st_ivas->hCrendWrapper->hCrend[0] != NULL && st_ivas->hCrendWrapper->hCrend[0]->hReverb != NULL ) { - RENDER_CONFIG_HANDLE hRenderConfig; - Decoder_Struct *st_ivas; - ivas_error error; - - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hRenderConfig == NULL ) + if ( ( error = ivas_reverb_open( &st_ivas->hCrendWrapper->hCrend[0]->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + return error; } + } - hRenderConfig = hIvasDec->st_ivas->hRenderConfig; - st_ivas = hIvasDec->st_ivas; - - hRenderConfig->roomAcoustics.aeID = renderConfig.roomAcoustics.aeID; - hRenderConfig->roomAcoustics.nBands = renderConfig.roomAcoustics.nBands; - hRenderConfig->roomAcoustics.acousticPreDelay = renderConfig.roomAcoustics.acousticPreDelay; - hRenderConfig->roomAcoustics.inputPreDelay = renderConfig.roomAcoustics.inputPreDelay; + /* Parametric renderer reverberator */ + if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->hReverb != NULL ) + { + ivas_binaural_reverb_close( &( st_ivas->hDiracDecBin[0]->hReverb ) ); - hRenderConfig->roomAcoustics.use_er = 0; - if ( renderConfig.roomAcoustics.use_er == 1 ) + if ( ( error = ivas_binaural_reverb_init( &( st_ivas->hDiracDecBin[0]->hReverb ), st_ivas->hHrtfStatistics, st_ivas->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, + &( hRenderConfig->roomAcoustics ), st_ivas->hDecoderConfig->output_Fs, NULL, NULL, NULL ) ) != IVAS_ERR_OK ) { - hRenderConfig->roomAcoustics.use_er = renderConfig.roomAcoustics.use_er; - hRenderConfig->roomAcoustics.lowComplexity = renderConfig.roomAcoustics.lowComplexity; - hRenderConfig->roomAcoustics.dimensions = renderConfig.roomAcoustics.dimensions; - hRenderConfig->roomAcoustics.ListenerOrigin = renderConfig.roomAcoustics.ListenerOrigin; - - mvr2r( renderConfig.roomAcoustics.AbsCoeff, hRenderConfig->roomAcoustics.AbsCoeff, IVAS_ROOM_ABS_COEFF ); + return error; } + } - mvr2r( renderConfig.roomAcoustics.pFc_input, hRenderConfig->roomAcoustics.pFc_input, CLDFB_NO_CHANNELS_MAX ); - mvr2r( renderConfig.roomAcoustics.pAcoustic_rt60, hRenderConfig->roomAcoustics.pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); - mvr2r( renderConfig.roomAcoustics.pAcoustic_dsr, hRenderConfig->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); - - /* Re-initialize reverb instance if already available */ + /* FastConv renderer reverberator */ + if ( st_ivas->hBinRenderer != NULL && st_ivas->hBinRenderer->hReverb != NULL ) + { + ivas_binaural_reverb_close( &( st_ivas->hBinRenderer->hReverb ) ); - /* TD renderer Jot reverberator */ - if ( st_ivas->hReverb != NULL ) + if ( ( error = ivas_binaural_reverb_init( &( st_ivas->hBinRenderer->hReverb ), st_ivas->hHrtfStatistics, st_ivas->hBinRenderer->conv_band, st_ivas->hBinRenderer->timeSlots, + &( hRenderConfig->roomAcoustics ), st_ivas->hDecoderConfig->output_Fs, NULL, NULL, NULL ) ) != IVAS_ERR_OK ) { - if ( ( error = ivas_reverb_open( &st_ivas->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } + } - /* CREND Jot reverberator */ - if ( st_ivas->hCrendWrapper != NULL && st_ivas->hCrendWrapper->hCrend[0] != NULL && st_ivas->hCrendWrapper->hCrend[0]->hReverb != NULL ) - { - if ( ( error = ivas_reverb_open( &st_ivas->hCrendWrapper->hCrend[0]->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) - { - return error; - } - } + mvr2r( renderConfig.directivity, hRenderConfig->directivity, 3 * MAX_NUM_OBJECTS ); + mvr2r( renderConfig.distAtt, hRenderConfig->distAtt, 3 ); - /* Parametric renderer reverberator */ - if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->hReverb != NULL ) - { - ivas_binaural_reverb_close( &( st_ivas->hDiracDecBin[0]->hReverb ) ); + hRenderConfig->split_rend_config = renderConfig.split_rend_config; - if ( ( error = ivas_binaural_reverb_init( &( st_ivas->hDiracDecBin[0]->hReverb ), st_ivas->hHrtfStatistics, st_ivas->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, - &( hRenderConfig->roomAcoustics ), st_ivas->hDecoderConfig->output_Fs, NULL, NULL, NULL ) ) != IVAS_ERR_OK ) - { - return error; - } - } + /* Overwrite any pose correction settings if 0 DOF (no pose correction) was selected */ + if ( hRenderConfig->split_rend_config.dof == 0 ) + { + hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + } - /* FastConv renderer reverberator */ - if ( st_ivas->hBinRenderer != NULL && st_ivas->hBinRenderer->hReverb != NULL ) + if ( is_split_rendering_enabled( st_ivas->hDecoderConfig, hRenderConfig ) ) + { + if ( ( error = isar_split_rend_validate_config( &hRenderConfig->split_rend_config, ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) { - ivas_binaural_reverb_close( &( st_ivas->hBinRenderer->hReverb ) ); - - if ( ( error = ivas_binaural_reverb_init( &( st_ivas->hBinRenderer->hReverb ), st_ivas->hHrtfStatistics, st_ivas->hBinRenderer->conv_band, st_ivas->hBinRenderer->timeSlots, - &( hRenderConfig->roomAcoustics ), st_ivas->hDecoderConfig->output_Fs, NULL, NULL, NULL ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } + } - mvr2r( renderConfig.directivity, hRenderConfig->directivity, 3 * MAX_NUM_OBJECTS ); - mvr2r( renderConfig.distAtt, hRenderConfig->distAtt, 3 ); + return IVAS_ERR_OK; +} - hRenderConfig->split_rend_config = renderConfig.split_rend_config; - /* Overwrite any pose correction settings if 0 DOF (no pose correction) was selected */ - if ( hRenderConfig->split_rend_config.dof == 0 ) - { - hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; - } +/*---------------------------------------------------------------------* + * feedAcousticEnvPI( ) + * + * Set acoustic environment from the PI data + *---------------------------------------------------------------------*/ - if ( is_split_rendering_enabled( st_ivas->hDecoderConfig, hRenderConfig ) ) - { - if ( ( error = isar_split_rend_validate_config( &hRenderConfig->split_rend_config, ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) - { - return error; - } - } +static ivas_error feedAcousticEnvPI( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_PIDATA_ACOUSTIC_ENV hAcoustEnvPI /* i : Render configuration struct */ +) +{ + RENDER_CONFIG_HANDLE hRenderConfig; + Decoder_Struct *st_ivas; + ivas_error error; - return IVAS_ERR_OK; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hRenderConfig == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + hRenderConfig = hIvasDec->st_ivas->hRenderConfig; + st_ivas = hIvasDec->st_ivas; - /*---------------------------------------------------------------------* - * feedAcousticEnvPI( ) - * - * Set acoustic environment from the PI data - *---------------------------------------------------------------------*/ + /* Ignore if AE ID already in use */ + if ( hRenderConfig->roomAcoustics.aeID == hAcoustEnvPI.aeid ) + { + return IVAS_ERR_OK; + } - static ivas_error feedAcousticEnvPI( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const IVAS_PIDATA_ACOUSTIC_ENV hAcoustEnvPI /* i : Render configuration struct */ - ) + /* Attempt to load the one already available */ + if ( ( error = IVAS_DEC_GetAcousticEnvironment( hIvasDec, hAcoustEnvPI.aeid, &hRenderConfig->roomAcoustics ) ) == IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING ) { - RENDER_CONFIG_HANDLE hRenderConfig; - Decoder_Struct *st_ivas; - ivas_error error; + /* Add the new compact room environment */ + IVAS_ROOM_ACOUSTICS_CONFIG_DATA acEnv; - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hRenderConfig == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + acEnv.aeID = hAcoustEnvPI.aeid; + acEnv.nBands = IVAS_PI_AE_NUM_BANDS; + acEnv.pFc_input[IVAS_PI_AE_LOW] = IVAS_PI_AE_LOW_FREQ; + acEnv.pFc_input[IVAS_PI_AE_MID] = IVAS_PI_AE_MID_FREQ; + acEnv.pFc_input[IVAS_PI_AE_HIGH] = IVAS_PI_AE_HIGH_FREQ; + acEnv.pAcoustic_rt60[IVAS_PI_AE_LOW] = hAcoustEnvPI.rt60[IVAS_PI_AE_LOW]; + acEnv.pAcoustic_rt60[IVAS_PI_AE_MID] = hAcoustEnvPI.rt60[IVAS_PI_AE_MID]; + acEnv.pAcoustic_rt60[IVAS_PI_AE_HIGH] = hAcoustEnvPI.rt60[IVAS_PI_AE_HIGH]; + acEnv.inputPreDelay = (float) ( 0.1 * hRenderConfig->roomAcoustics.pAcoustic_rt60[IVAS_PI_AE_MID] ); + acEnv.pAcoustic_dsr[IVAS_PI_AE_LOW] = powf( 10.0f, hAcoustEnvPI.dsr[IVAS_PI_AE_LOW] / 10.0f ); + acEnv.pAcoustic_dsr[IVAS_PI_AE_MID] = powf( 10.0f, hAcoustEnvPI.dsr[IVAS_PI_AE_MID] / 10.0f ); + acEnv.pAcoustic_dsr[IVAS_PI_AE_HIGH] = powf( 10.0f, hAcoustEnvPI.dsr[IVAS_PI_AE_HIGH] / 10.0f ); - hRenderConfig = hIvasDec->st_ivas->hRenderConfig; - st_ivas = hIvasDec->st_ivas; + acEnv.use_er = hAcoustEnvPI.availEarlyReflections; - /* Ignore if AE ID already in use */ - if ( hRenderConfig->roomAcoustics.aeID == hAcoustEnvPI.aeid ) + if ( hAcoustEnvPI.availEarlyReflections ) { - return IVAS_ERR_OK; + hRenderConfig->roomAcoustics.dimensions.x = hAcoustEnvPI.roomDimensions.x; + hRenderConfig->roomAcoustics.dimensions.y = hAcoustEnvPI.roomDimensions.y; + hRenderConfig->roomAcoustics.dimensions.z = hAcoustEnvPI.roomDimensions.z; + mvr2r( hAcoustEnvPI.absorbCoeffs, hRenderConfig->roomAcoustics.AbsCoeff, IVAS_ROOM_ABS_COEFF ); } - /* Attempt to load the one already available */ - if ( ( error = IVAS_DEC_GetAcousticEnvironment( hIvasDec, hAcoustEnvPI.aeid, &hRenderConfig->roomAcoustics ) ) == IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING ) + if ( ( error = IVAS_DEC_AddAcousticEnvironment( hIvasDec, acEnv ) ) != IVAS_ERR_OK ) { - /* Add the new compact room environment */ - IVAS_ROOM_ACOUSTICS_CONFIG_DATA acEnv; - - acEnv.aeID = hAcoustEnvPI.aeid; - acEnv.nBands = IVAS_PI_AE_NUM_BANDS; - acEnv.pFc_input[IVAS_PI_AE_LOW] = IVAS_PI_AE_LOW_FREQ; - acEnv.pFc_input[IVAS_PI_AE_MID] = IVAS_PI_AE_MID_FREQ; - acEnv.pFc_input[IVAS_PI_AE_HIGH] = IVAS_PI_AE_HIGH_FREQ; - acEnv.pAcoustic_rt60[IVAS_PI_AE_LOW] = hAcoustEnvPI.rt60[IVAS_PI_AE_LOW]; - acEnv.pAcoustic_rt60[IVAS_PI_AE_MID] = hAcoustEnvPI.rt60[IVAS_PI_AE_MID]; - acEnv.pAcoustic_rt60[IVAS_PI_AE_HIGH] = hAcoustEnvPI.rt60[IVAS_PI_AE_HIGH]; - acEnv.inputPreDelay = (float) ( 0.1 * hRenderConfig->roomAcoustics.pAcoustic_rt60[IVAS_PI_AE_MID] ); - acEnv.pAcoustic_dsr[IVAS_PI_AE_LOW] = powf( 10.0f, hAcoustEnvPI.dsr[IVAS_PI_AE_LOW] / 10.0f ); - acEnv.pAcoustic_dsr[IVAS_PI_AE_MID] = powf( 10.0f, hAcoustEnvPI.dsr[IVAS_PI_AE_MID] / 10.0f ); - acEnv.pAcoustic_dsr[IVAS_PI_AE_HIGH] = powf( 10.0f, hAcoustEnvPI.dsr[IVAS_PI_AE_HIGH] / 10.0f ); - - acEnv.use_er = hAcoustEnvPI.availEarlyReflections; - - if ( hAcoustEnvPI.availEarlyReflections ) - { - hRenderConfig->roomAcoustics.dimensions.x = hAcoustEnvPI.roomDimensions.x; - hRenderConfig->roomAcoustics.dimensions.y = hAcoustEnvPI.roomDimensions.y; - hRenderConfig->roomAcoustics.dimensions.z = hAcoustEnvPI.roomDimensions.z; - mvr2r( hAcoustEnvPI.absorbCoeffs, hRenderConfig->roomAcoustics.AbsCoeff, IVAS_ROOM_ABS_COEFF ); - } - - if ( ( error = IVAS_DEC_AddAcousticEnvironment( hIvasDec, acEnv ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( ( error = IVAS_DEC_GetAcousticEnvironment( hIvasDec, hAcoustEnvPI.aeid, &hRenderConfig->roomAcoustics ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } - /* Re-initialize reverb instance if already available */ - - /* TD renderer Jot reverberator */ - if ( st_ivas->hReverb != NULL ) + if ( ( error = IVAS_DEC_GetAcousticEnvironment( hIvasDec, hAcoustEnvPI.aeid, &hRenderConfig->roomAcoustics ) ) != IVAS_ERR_OK ) { - if ( ( error = ivas_reverb_open( &st_ivas->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } + } - /* CREND Jot reverberator */ - if ( st_ivas->hCrendWrapper != NULL && st_ivas->hCrendWrapper->hCrend[0] != NULL && st_ivas->hCrendWrapper->hCrend[0]->hReverb != NULL ) - { - if ( ( error = ivas_reverb_open( &st_ivas->hCrendWrapper->hCrend[0]->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) - { - return error; - } - } + /* Re-initialize reverb instance if already available */ - /* Parametric renderer reverberator */ - if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->hReverb != NULL ) + /* TD renderer Jot reverberator */ + if ( st_ivas->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &st_ivas->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) { - ivas_binaural_reverb_close( &( st_ivas->hDiracDecBin[0]->hReverb ) ); - - if ( ( error = ivas_binaural_reverb_init( &( st_ivas->hDiracDecBin[0]->hReverb ), st_ivas->hHrtfStatistics, st_ivas->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, - &( hRenderConfig->roomAcoustics ), st_ivas->hDecoderConfig->output_Fs, NULL, NULL, NULL ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } + } - /* FastConv renderer reverberator */ - if ( st_ivas->hBinRenderer != NULL && st_ivas->hBinRenderer->hReverb != NULL ) + /* CREND Jot reverberator */ + if ( st_ivas->hCrendWrapper != NULL && st_ivas->hCrendWrapper->hCrend[0] != NULL && st_ivas->hCrendWrapper->hCrend[0]->hReverb != NULL ) + { + if ( ( error = ivas_reverb_open( &st_ivas->hCrendWrapper->hCrend[0]->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) { - ivas_binaural_reverb_close( &( st_ivas->hBinRenderer->hReverb ) ); - - if ( ( error = ivas_binaural_reverb_init( &( st_ivas->hBinRenderer->hReverb ), st_ivas->hHrtfStatistics, st_ivas->hBinRenderer->conv_band, st_ivas->hBinRenderer->timeSlots, - &( hRenderConfig->roomAcoustics ), st_ivas->hDecoderConfig->output_Fs, NULL, NULL, NULL ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } - - return IVAS_ERR_OK; } - - /*---------------------------------------------------------------------* - * IVAS_DEC_GetDelay( ) - * - * Return IVAS decoder delay in nanoseconds - *---------------------------------------------------------------------*/ - - ivas_error IVAS_DEC_GetDelay( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t * nSamples, /* o : decoder delay in samples */ - int32_t * timeScale /* o : time scale of the delay, equal to decoder output sampling rate */ - ) + /* Parametric renderer reverberator */ + if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->hReverb != NULL ) { - Decoder_Struct *st_ivas; - DECODER_CONFIG_HANDLE hDecoderConfig; + ivas_binaural_reverb_close( &( st_ivas->hDiracDecBin[0]->hReverb ) ); - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || nSamples == NULL || timeScale == NULL ) + if ( ( error = ivas_binaural_reverb_init( &( st_ivas->hDiracDecBin[0]->hReverb ), st_ivas->hHrtfStatistics, st_ivas->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, + &( hRenderConfig->roomAcoustics ), st_ivas->hDecoderConfig->output_Fs, NULL, NULL, NULL ) ) != IVAS_ERR_OK ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + return error; } + } - if ( !hIvasDec->hasDecodedFirstGoodFrame ) + /* FastConv renderer reverberator */ + if ( st_ivas->hBinRenderer != NULL && st_ivas->hBinRenderer->hReverb != NULL ) + { + ivas_binaural_reverb_close( &( st_ivas->hBinRenderer->hReverb ) ); + + if ( ( error = ivas_binaural_reverb_init( &( st_ivas->hBinRenderer->hReverb ), st_ivas->hHrtfStatistics, st_ivas->hBinRenderer->conv_band, st_ivas->hBinRenderer->timeSlots, + &( hRenderConfig->roomAcoustics ), st_ivas->hDecoderConfig->output_Fs, NULL, NULL, NULL ) ) != IVAS_ERR_OK ) { - /* Delay depends on IVAS format, which is unknown until first frame has been decoded */ - return IVAS_ERR_WAITING_FOR_BITSTREAM; + return error; } + } - st_ivas = hIvasDec->st_ivas; - hDecoderConfig = st_ivas->hDecoderConfig; + return IVAS_ERR_OK; +} - nSamples[1] = NS2SA( hDecoderConfig->output_Fs, get_delay( DEC, hDecoderConfig->output_Fs, st_ivas->ivas_format, st_ivas->cldfbSynDec[0], hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ); - nSamples[2] = (int16_t) roundf( (float) st_ivas->binaural_latency_ns * hDecoderConfig->output_Fs / 1000000000.f ); - nSamples[0] = nSamples[1] + nSamples[2]; +/*---------------------------------------------------------------------* + * IVAS_DEC_GetDelay( ) + * + * Return IVAS decoder delay in nanoseconds + *---------------------------------------------------------------------*/ - if ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) - { - /* note: in MASA, all delay is compensated at the decoder by default, so subtract the encoder delay for print-out */ - nSamples[1] -= NS2SA( hDecoderConfig->output_Fs, IVAS_ENC_DELAY_NS ); - } +ivas_error IVAS_DEC_GetDelay( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *nSamples, /* o : decoder delay in samples */ + int32_t *timeScale /* o : time scale of the delay, equal to decoder output sampling rate */ +) +{ + Decoder_Struct *st_ivas; + DECODER_CONFIG_HANDLE hDecoderConfig; - *timeScale = hDecoderConfig->output_Fs; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || nSamples == NULL || timeScale == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - return IVAS_ERR_OK; + if ( !hIvasDec->hasDecodedFirstGoodFrame ) + { + /* Delay depends on IVAS format, which is unknown until first frame has been decoded */ + return IVAS_ERR_WAITING_FOR_BITSTREAM; } + st_ivas = hIvasDec->st_ivas; + hDecoderConfig = st_ivas->hDecoderConfig; + + nSamples[1] = NS2SA( hDecoderConfig->output_Fs, get_delay( DEC, hDecoderConfig->output_Fs, st_ivas->ivas_format, st_ivas->cldfbSynDec[0], hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ); - /*---------------------------------------------------------------------* - * IVAS_DEC_HasDecodedFirstGoodFrame( ) - * - * Return flag indicating if the decoder has decoded a good frame - *---------------------------------------------------------------------*/ + nSamples[2] = (int16_t) roundf( (float) st_ivas->binaural_latency_ns * hDecoderConfig->output_Fs / 1000000000.f ); + nSamples[0] = nSamples[1] + nSamples[2]; - ivas_error IVAS_DEC_HasDecodedFirstGoodFrame( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - bool *hasDecodedFirstGoodFrame /* o : flag indicating if the decoder has decoded a good frame since it was configured */ - ) + if ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hasDecodedFirstGoodFrame == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + /* note: in MASA, all delay is compensated at the decoder by default, so subtract the encoder delay for print-out */ + nSamples[1] -= NS2SA( hDecoderConfig->output_Fs, IVAS_ENC_DELAY_NS ); + } - *hasDecodedFirstGoodFrame = hIvasDec->hasDecodedFirstGoodFrame; + *timeScale = hDecoderConfig->output_Fs; - return IVAS_ERR_OK; - } + return IVAS_ERR_OK; +} - /*---------------------------------------------------------------------* - * isSidFrame( ) - * - * Check if a frame contains a SID - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_HasDecodedFirstGoodFrame( ) + * + * Return flag indicating if the decoder has decoded a good frame + *---------------------------------------------------------------------*/ - static bool isSidFrame( - const uint16_t size ) +ivas_error IVAS_DEC_HasDecodedFirstGoodFrame( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + bool *hasDecodedFirstGoodFrame /* o : flag indicating if the decoder has decoded a good frame since it was configured */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hasDecodedFirstGoodFrame == NULL ) { - if ( size == SID_1k75 / FRAMES_PER_SEC ) - { - return true; /* AMR-WB SID */ - } - else if ( size == SID_2k40 / FRAMES_PER_SEC ) - { - return true; /* EVS SID */ - } - else if ( size == IVAS_SID_5k2 / FRAMES_PER_SEC ) - { - return true; /* IVAS SID */ - } - - return false; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + *hasDecodedFirstGoodFrame = hIvasDec->hasDecodedFirstGoodFrame; + + return IVAS_ERR_OK; +} + - /*---------------------------------------------------------------------* - * bsCompactToSerial( ) - * - * Bitstream conversion to Byte format - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * isSidFrame( ) + * + * Check if a frame contains a SID + *---------------------------------------------------------------------*/ - static void bsCompactToSerial( - const uint8_t *compact, - uint16_t *serial, - const uint16_t num_bits ) +static bool isSidFrame( + const uint16_t size ) +{ + if ( size == SID_1k75 / FRAMES_PER_SEC ) { + return true; /* AMR-WB SID */ + } + else if ( size == SID_2k40 / FRAMES_PER_SEC ) + { + return true; /* EVS SID */ + } + else if ( size == IVAS_SID_5k2 / FRAMES_PER_SEC ) + { + return true; /* IVAS SID */ + } + + return false; +} + + +/*---------------------------------------------------------------------* + * bsCompactToSerial( ) + * + * Bitstream conversion to Byte format + *---------------------------------------------------------------------*/ + +static void bsCompactToSerial( + const uint8_t *compact, + uint16_t *serial, + const uint16_t num_bits ) +{ /* Bitstream conversion is not counted towards complexity and memory usage */ #define WMC_TOOL_SKIP - uint32_t i; - uint8_t byte = 0; - const uint8_t mask = 0x80; + uint32_t i; + uint8_t byte = 0; + const uint8_t mask = 0x80; - for ( i = 0; i < num_bits; ++i ) + for ( i = 0; i < num_bits; ++i ) + { + if ( i % 8 == 0 ) { - if ( i % 8 == 0 ) - { - byte = compact[i / 8]; - } + byte = compact[i / 8]; + } - serial[i] = ( byte & mask ) >> 7; + serial[i] = ( byte & mask ) >> 7; - byte <<= 1; - } + byte <<= 1; + } - /* Add 4 padding bytes required by core coder */ - for ( i = 0; i < 4 * 8; ++i ) - { - serial[num_bits + i] = 0; - } -#undef WMC_TOOL_SKIP + /* Add 4 padding bytes required by core coder */ + for ( i = 0; i < 4 * 8; ++i ) + { + serial[num_bits + i] = 0; } +#undef WMC_TOOL_SKIP +} - /*---------------------------------------------------------------------* - * IVAS_DEC_VoIP_FeedFrame( ) - * - * Feed RTP packet into internal jitter buffer - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_VoIP_FeedFrame( ) + * + * Feed RTP packet into internal jitter buffer + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_VoIP_FeedFrame( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint8_t *au, /* i : buffer containing input access unit */ + const uint16_t auSize, /* i : size of the access unit */ + const uint16_t rtpSequenceNumber, /* i : RTP sequence number (16 bits) */ + const uint32_t rtpTimeStamp, /* i : RTP timestamp (32 bits) */ + const uint32_t rcvTime_ms, /* i : receive time of the RTP packet in milliseconds */ + const bool qBit /* i : Q bit for AMR-WB IO */ +) +{ + JB4_DATAUNIT_HANDLE dataUnit; + int16_t partialCopyFrameType, partialCopyOffset; + int16_t result; - ivas_error IVAS_DEC_VoIP_FeedFrame( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint8_t * au, /* i : buffer containing input access unit */ - const uint16_t auSize, /* i : size of the access unit */ - const uint16_t rtpSequenceNumber, /* i : RTP sequence number (16 bits) */ - const uint32_t rtpTimeStamp, /* i : RTP timestamp (32 bits) */ - const uint32_t rcvTime_ms, /* i : receive time of the RTP packet in milliseconds */ - const bool qBit /* i : Q bit for AMR-WB IO */ - ) + if ( hIvasDec == NULL || hIvasDec->hVoIP == NULL || au == NULL ) { - JB4_DATAUNIT_HANDLE dataUnit; - int16_t partialCopyFrameType, partialCopyOffset; - int16_t result; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( hIvasDec == NULL || hIvasDec->hVoIP == NULL || au == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + if ( auSize == 0 ) + { + return IVAS_ERR_OK; /* ignore empty/NO_DATA frame - shouldn't be transmitted in RTP */ + } + if ( ( auSize + 7 ) / 8 > MAX_AU_SIZE ) + { + return IVAS_ERR_INVALID_BITSTREAM; + } - if ( auSize == 0 ) - { - return IVAS_ERR_OK; /* ignore empty/NO_DATA frame - shouldn't be transmitted in RTP */ - } - if ( ( auSize + 7 ) / 8 > MAX_AU_SIZE ) - { - return IVAS_ERR_INVALID_BITSTREAM; - } + partialCopyFrameType = 0; + partialCopyOffset = 0; - partialCopyFrameType = 0; - partialCopyOffset = 0; + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + { + /* check if frame contains a partial copy and get its offset */ + evs_dec_previewFrame( au, auSize, &partialCopyFrameType, &partialCopyOffset ); + } - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) - { - /* check if frame contains a partial copy and get its offset */ - evs_dec_previewFrame( au, auSize, &partialCopyFrameType, &partialCopyOffset ); - } + /* create data unit for primary copy in the frame */ + dataUnit = JB4_AllocDataUnit( hIvasDec->hVoIP->hJBM ); + mvc2c( au, dataUnit->data, (int16_t) ( ( auSize + 7 ) / 8 ) ); + dataUnit->dataSize = auSize; + dataUnit->duration = 20; + dataUnit->sequenceNumber = rtpSequenceNumber; + dataUnit->silenceIndicator = isSidFrame( dataUnit->dataSize ); + dataUnit->timeScale = 1000; + dataUnit->rcvTime = rcvTime_ms; + dataUnit->timeStamp = rtpTimeStamp; + dataUnit->partial_frame = 0; + dataUnit->partialCopyOffset = partialCopyOffset; + dataUnit->qBit = qBit; + + /* add the frame to the JBM */ + result = JB4_PushDataUnit( hIvasDec->hVoIP->hJBM, dataUnit, rcvTime_ms ); + if ( result != 0 ) + { + return IVAS_ERR_UNKNOWN; + } - /* create data unit for primary copy in the frame */ + if ( partialCopyFrameType != RF_NO_DATA && partialCopyOffset != 0 ) + { + /* create data unit for partial copy in the frame */ dataUnit = JB4_AllocDataUnit( hIvasDec->hVoIP->hJBM ); mvc2c( au, dataUnit->data, (int16_t) ( ( auSize + 7 ) / 8 ) ); dataUnit->dataSize = auSize; dataUnit->duration = 20; dataUnit->sequenceNumber = rtpSequenceNumber; - dataUnit->silenceIndicator = isSidFrame( dataUnit->dataSize ); + dataUnit->silenceIndicator = 0; /* there are no partial copies for SID frames */ dataUnit->timeScale = 1000; dataUnit->rcvTime = rcvTime_ms; - dataUnit->timeStamp = rtpTimeStamp; - dataUnit->partial_frame = 0; + dataUnit->timeStamp = rtpTimeStamp - partialCopyOffset * dataUnit->duration; + dataUnit->partial_frame = 1; dataUnit->partialCopyOffset = partialCopyOffset; dataUnit->qBit = qBit; - /* add the frame to the JBM */ - result = JB4_PushDataUnit( hIvasDec->hVoIP->hJBM, dataUnit, rcvTime_ms ); - if ( result != 0 ) - { - return IVAS_ERR_UNKNOWN; - } - - if ( partialCopyFrameType != RF_NO_DATA && partialCopyOffset != 0 ) - { - /* create data unit for partial copy in the frame */ - dataUnit = JB4_AllocDataUnit( hIvasDec->hVoIP->hJBM ); - mvc2c( au, dataUnit->data, (int16_t) ( ( auSize + 7 ) / 8 ) ); - dataUnit->dataSize = auSize; - dataUnit->duration = 20; - dataUnit->sequenceNumber = rtpSequenceNumber; - dataUnit->silenceIndicator = 0; /* there are no partial copies for SID frames */ - dataUnit->timeScale = 1000; - dataUnit->rcvTime = rcvTime_ms; - dataUnit->timeStamp = rtpTimeStamp - partialCopyOffset * dataUnit->duration; - dataUnit->partial_frame = 1; - dataUnit->partialCopyOffset = partialCopyOffset; - dataUnit->qBit = qBit; - - /* add the frame to the JBM */ - result = JB4_PushDataUnit( hIvasDec->hVoIP->hJBM, dataUnit, rcvTime_ms ); - if ( result != 0 ) - { - return IVAS_ERR_UNKNOWN; - } - } - - return IVAS_ERR_OK; + /* add the frame to the JBM */ + result = JB4_PushDataUnit( hIvasDec->hVoIP->hJBM, dataUnit, rcvTime_ms ); + if ( result != 0 ) + { + return IVAS_ERR_UNKNOWN; + } } + return IVAS_ERR_OK; +} - /*---------------------------------------------------------------------* - * IVAS_DEC_VoIP_SetScale( ) - * - * Set the TSM scale - *---------------------------------------------------------------------*/ - ivas_error IVAS_DEC_VoIP_SetScale( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const int16_t maxScaling, /* i : max allowed absolute difference in samples from the default 20ms frame size */ - const int16_t scale /* i : TSM scale to set in percent of the default frame size */ - ) - { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } +/*---------------------------------------------------------------------* + * IVAS_DEC_VoIP_SetScale( ) + * + * Set the TSM scale + *---------------------------------------------------------------------*/ - if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm == 0 ) - { - return IVAS_ERR_TSM_NOT_ENABLED; - } - else - { - hIvasDec->tsm_scale = scale; - hIvasDec->tsm_max_scaling = maxScaling; - } +ivas_error IVAS_DEC_VoIP_SetScale( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t maxScaling, /* i : max allowed absolute difference in samples from the default 20ms frame size */ + const int16_t scale /* i : TSM scale to set in percent of the default frame size */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - return IVAS_ERR_OK; + if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm == 0 ) + { + return IVAS_ERR_TSM_NOT_ENABLED; + } + else + { + hIvasDec->tsm_scale = scale; + hIvasDec->tsm_max_scaling = maxScaling; } + return IVAS_ERR_OK; +} + #ifdef VARIABLE_SPEED_DECODING - /*---------------------------------------------------------------------* - * IVAS_DEC_EnableTsm( ) - * - * Enable Time-Scale Modification (TSM) - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_EnableTsm( ) + * + * Enable Time-Scale Modification (TSM) + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_EnableTsm( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +) +{ + AUDIO_CONFIG output_config; + ivas_error error; - ivas_error IVAS_DEC_EnableTsm( - IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ - ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - AUDIO_CONFIG output_config; - ivas_error error; - - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - hIvasDec->st_ivas->hDecoderConfig->Opt_tsm = 1; + hIvasDec->st_ivas->hDecoderConfig->Opt_tsm = 1; - /* init flush buffer if necessary (only needed for binaural) */ - output_config = hIvasDec->st_ivas->hDecoderConfig->output_config; - if ( hIvasDec->flushbuffer == NULL && ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + /* init flush buffer if necessary (only needed for binaural) */ + output_config = hIvasDec->st_ivas->hDecoderConfig->output_config; + if ( hIvasDec->flushbuffer == NULL && ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + if ( ( error = create_flush_buffer( hIvasDec ) ) != IVAS_ERR_OK ) { - if ( ( error = create_flush_buffer( hIvasDec ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } - - return IVAS_ERR_OK; } + return IVAS_ERR_OK; +} - /*---------------------------------------------------------------------* - * IVAS_DEC_TSM_SetQuality( ) - * - * set the quality theshold for the time scale modiciation that is used - * to determine if the TSM yielded a signal that satisfies the minimum - * quality requirements. - * quality is lower limit for minimum quality - * Range is [-2;2] - where positive values allow - * only pasting with same phase information - * Negative values would yield cross phased pasting - * When not setting the minimum quality with this function the default - * value used is 1.0f - * - *---------------------------------------------------------------------*/ - ivas_error IVAS_DEC_TSM_SetQuality( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const float quality /* i : target TSM quality */ - ) - { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } +/*---------------------------------------------------------------------* + * IVAS_DEC_TSM_SetQuality( ) + * + * set the quality theshold for the time scale modiciation that is used + * to determine if the TSM yielded a signal that satisfies the minimum + * quality requirements. + * quality is lower limit for minimum quality + * Range is [-2;2] - where positive values allow + * only pasting with same phase information + * Negative values would yield cross phased pasting + * When not setting the minimum quality with this function the default + * value used is 1.0f + * + *---------------------------------------------------------------------*/ - if ( !hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) - { - return IVAS_ERR_TSM_NOT_ENABLED; - } - else - { - hIvasDec->tsm_quality = quality; - } +ivas_error IVAS_DEC_TSM_SetQuality( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const float quality /* i : target TSM quality */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - return IVAS_ERR_OK; + if ( !hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) + { + return IVAS_ERR_TSM_NOT_ENABLED; + } + else + { + hIvasDec->tsm_quality = quality; } + return IVAS_ERR_OK; +} + #endif - /*---------------------------------------------------------------------* - * ivas_dec_voip_get_samples_common( ) - * - * Main function to output one frame in VoIP. Holds common code for - * regular output configs and split rendering configs. - *---------------------------------------------------------------------*/ - - static ivas_error ivas_dec_voip_get_samples_common( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ - const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ - void *pcmBuf, /* o : output synthesis signal */ - ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */ - float **p_head_pose_buf, /* i : PCM buffer with head-pose data */ +/*---------------------------------------------------------------------* + * ivas_dec_voip_get_samples_common( ) + * + * Main function to output one frame in VoIP. Holds common code for + * regular output configs and split rendering configs. + *---------------------------------------------------------------------*/ + +static ivas_error ivas_dec_voip_get_samples_common( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */ + float **p_head_pose_buf, /* i : PCM buffer with head-pose data */ #ifdef SUPPORT_JBM_TRACEFILE - JbmTraceFileWriterFn jbmWriterFn, - void *jbmWriter, + JbmTraceFileWriterFn jbmWriterFn, + void *jbmWriter, #endif - bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */ - uint16_t *nSamplesRendered, /* o : number of samples rendered */ - bool *parametersAvailableForEditing, /* o : indicates whether objects editing is available */ - const uint32_t systemTimestamp_ms /* i : current system timestamp */ - ) + bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */ + uint16_t *nSamplesRendered, /* o : number of samples rendered */ + bool *parametersAvailableForEditing, /* o : indicates whether objects editing is available */ + const uint32_t systemTimestamp_ms /* i : current system timestamp */ +) +{ + Decoder_Struct *st_ivas; + DECODER_CONFIG_HANDLE hDecoderConfig; + IVAS_DEC_VOIP *hVoIP; + uint32_t extBufferedTime_ms, scale, maxScaling; + JB4_DATAUNIT_HANDLE dataUnit; + uint16_t extBufferedSamples; + int16_t result; + ivas_error error; + uint8_t nOutChannels; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->hVoIP == NULL ) { - Decoder_Struct *st_ivas; - DECODER_CONFIG_HANDLE hDecoderConfig; - IVAS_DEC_VOIP *hVoIP; - uint32_t extBufferedTime_ms, scale, maxScaling; - JB4_DATAUNIT_HANDLE dataUnit; - uint16_t extBufferedSamples; - int16_t result; - ivas_error error; - uint8_t nOutChannels; - - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->hVoIP == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - st_ivas = hIvasDec->st_ivas; - hDecoderConfig = st_ivas->hDecoderConfig; - hVoIP = hIvasDec->hVoIP; - nOutChannels = (uint8_t) st_ivas->hDecoderConfig->nchan_out; - *parametersAvailableForEditing = false; + st_ivas = hIvasDec->st_ivas; + hDecoderConfig = st_ivas->hDecoderConfig; + hVoIP = hIvasDec->hVoIP; + nOutChannels = (uint8_t) st_ivas->hDecoderConfig->nchan_out; + *parametersAvailableForEditing = false; - if ( nSamplesPerChannel == 0 ) - { - return IVAS_ERR_WRONG_PARAMS; - } + if ( nSamplesPerChannel == 0 ) + { + return IVAS_ERR_WRONG_PARAMS; + } - if ( ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || - hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && - splitRendBits == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + if ( ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || + hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && + splitRendBits == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - /* make sure that the FIFO after decoder/scaler contains at least one sound card frame (i.e. 20ms) */ - while ( *nSamplesRendered < nSamplesPerChannel ) + /* make sure that the FIFO after decoder/scaler contains at least one sound card frame (i.e. 20ms) */ + while ( *nSamplesRendered < nSamplesPerChannel ) + { + if ( hIvasDec->nSamplesAvailableNext == 0 ) { - if ( hIvasDec->nSamplesAvailableNext == 0 ) + int16_t nSamplesBuffered; + nSamplesBuffered = 0; + if ( hIvasDec->hasBeenFedFirstGoodFrame ) { - int16_t nSamplesBuffered; - nSamplesBuffered = 0; - if ( hIvasDec->hasBeenFedFirstGoodFrame ) + /* check if the TC buffer already exists, otherweise nothing is buffered anyway */ + if ( st_ivas->hTcBuffer != NULL ) { - /* check if the TC buffer already exists, otherweise nothing is buffered anyway */ - if ( st_ivas->hTcBuffer != NULL ) - { - nSamplesBuffered = st_ivas->hTcBuffer->n_samples_buffered - st_ivas->hTcBuffer->n_samples_rendered; - nSamplesBuffered += hVoIP->nSamplesRendered20ms; - } + nSamplesBuffered = st_ivas->hTcBuffer->n_samples_buffered - st_ivas->hTcBuffer->n_samples_rendered; + nSamplesBuffered += hVoIP->nSamplesRendered20ms; } + } - extBufferedSamples = nSamplesBuffered; - extBufferedTime_ms = extBufferedSamples * 1000 / hDecoderConfig->output_Fs; - dataUnit = NULL; + extBufferedSamples = nSamplesBuffered; + extBufferedTime_ms = extBufferedSamples * 1000 / hDecoderConfig->output_Fs; + dataUnit = NULL; - /* pop one access unit from the jitter buffer */ - result = JB4_PopDataUnit( hVoIP->hJBM, systemTimestamp_ms, extBufferedTime_ms, &dataUnit, &scale, &maxScaling ); - if ( result != 0 ) - { - return IVAS_ERR_UNKNOWN; - } - maxScaling = maxScaling * hDecoderConfig->output_Fs / 1000; + /* pop one access unit from the jitter buffer */ + result = JB4_PopDataUnit( hVoIP->hJBM, systemTimestamp_ms, extBufferedTime_ms, &dataUnit, &scale, &maxScaling ); + if ( result != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + maxScaling = maxScaling * hDecoderConfig->output_Fs / 1000; #ifdef DEBUG_MODE_JBM - dbgwrite( &extBufferedSamples, sizeof( uint16_t ), 1, 1, "./res/JBM_extBufferedSamples.dat" ); - dbgwrite( &systemTimestamp_ms, sizeof( uint32_t ), 1, 1, "./res/JBM_systemTimestamp.dat" ); - dbgwrite( &scale, sizeof( uint32_t ), 1, 1, "./res/JBM_scale.dat" ); - dbgwrite( &maxScaling, sizeof( uint32_t ), 1, 1, "./res/JBM_maxScale.dat" ); + dbgwrite( &extBufferedSamples, sizeof( uint16_t ), 1, 1, "./res/JBM_extBufferedSamples.dat" ); + dbgwrite( &systemTimestamp_ms, sizeof( uint32_t ), 1, 1, "./res/JBM_systemTimestamp.dat" ); + dbgwrite( &scale, sizeof( uint32_t ), 1, 1, "./res/JBM_scale.dat" ); + dbgwrite( &maxScaling, sizeof( uint32_t ), 1, 1, "./res/JBM_maxScale.dat" ); #endif - /* avoid time scaling multiple times within one 20ms frame*/ - if ( scale != 100U ) - { - if ( hIvasDec->timeScalingDone ) - { - scale = 100; - } - } - - /* limit scale to range supported by time scaler */ - if ( scale < APA_MIN_SCALE ) - { - scale = APA_MIN_SCALE; - } - else if ( scale > APA_MAX_SCALE ) + /* avoid time scaling multiple times within one 20ms frame*/ + if ( scale != 100U ) + { + if ( hIvasDec->timeScalingDone ) { - scale = APA_MAX_SCALE; + scale = 100; } + } - if ( ( error = IVAS_DEC_VoIP_SetScale( hIvasDec, (int16_t) maxScaling, (int16_t) scale ) ) != IVAS_ERR_OK ) - { - return error; - } + /* limit scale to range supported by time scaler */ + if ( scale < APA_MIN_SCALE ) + { + scale = APA_MIN_SCALE; + } + else if ( scale > APA_MAX_SCALE ) + { + scale = APA_MAX_SCALE; + } - /* copy bitstream into decoder state */ - if ( dataUnit ) - { - hIvasDec->hVoIP->hCurrentDataUnit = dataUnit; + if ( ( error = IVAS_DEC_VoIP_SetScale( hIvasDec, (int16_t) maxScaling, (int16_t) scale ) ) != IVAS_ERR_OK ) + { + return error; + } - bsCompactToSerial( dataUnit->data, hIvasDec->hVoIP->bs_conversion_buf, dataUnit->dataSize ); + /* copy bitstream into decoder state */ + if ( dataUnit ) + { + hIvasDec->hVoIP->hCurrentDataUnit = dataUnit; - if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, dataUnit->dataSize, 0 ) ) != IVAS_ERR_OK ) - { - return error; - } + bsCompactToSerial( dataUnit->data, hIvasDec->hVoIP->bs_conversion_buf, dataUnit->dataSize ); - *bitstreamReadDone = true; + if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, dataUnit->dataSize, 0 ) ) != IVAS_ERR_OK ) + { + return error; } - else if ( hIvasDec->hasDecodedFirstGoodFrame ) + + *bitstreamReadDone = true; + } + else if ( hIvasDec->hasDecodedFirstGoodFrame ) + { + /* Decoder has been initialized with first good frame - do PLC */ + if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, 0, 1 ) ) != IVAS_ERR_OK ) { - /* Decoder has been initialized with first good frame - do PLC */ - if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, 0, 1 ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } + } #ifdef SUPPORT_JBM_TRACEFILE - /* jbmWriterFn and jbmWriter may be NULL if tracefile writing was not requested on CLI */ - if ( jbmWriterFn != NULL && jbmWriter != NULL ) + /* jbmWriterFn and jbmWriter may be NULL if tracefile writing was not requested on CLI */ + if ( jbmWriterFn != NULL && jbmWriter != NULL ) + { + /* write JBM trace data entry */ + store_JbmData( hVoIP, dataUnit, systemTimestamp_ms, extBufferedSamples, hDecoderConfig->output_Fs ); + if ( ( jbmWriterFn( &hVoIP->JbmTraceData, jbmWriter ) ) != IVAS_ERR_OK ) { - /* write JBM trace data entry */ - store_JbmData( hVoIP, dataUnit, systemTimestamp_ms, extBufferedSamples, hDecoderConfig->output_Fs ); - if ( ( jbmWriterFn( &hVoIP->JbmTraceData, jbmWriter ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError writing JBM Trace data to file\n" ); - return IVAS_ERR_UNKNOWN; - } + fprintf( stderr, "\nError writing JBM Trace data to file\n" ); + return IVAS_ERR_UNKNOWN; } + } #endif - if ( dataUnit ) + if ( dataUnit ) + { + if ( dataUnit->partial_frame != 0 ) { - if ( dataUnit->partial_frame != 0 ) - { - hVoIP->lastDecodedWasActive = 1; - } - else - { - hVoIP->lastDecodedWasActive = !dataUnit->silenceIndicator; - } - - /* data unit memory is no longer used */ - JB4_FreeDataUnit( hVoIP->hJBM, dataUnit ); + hVoIP->lastDecodedWasActive = 1; } - - if ( hIvasDec->hasBeenFedFirstGoodFrame && *bitstreamReadDone == true ) + else { - /* new bitstream was feeded, return for reconfiguration */ - return IVAS_ERR_OK; + hVoIP->lastDecodedWasActive = !dataUnit->silenceIndicator; } - if ( !hIvasDec->hasBeenFedFirstGoodFrame ) - { - hIvasDec->nSamplesAvailableNext = hIvasDec->nSamplesFrame; - } + /* data unit memory is no longer used */ + JB4_FreeDataUnit( hVoIP->hJBM, dataUnit ); } - /* decode */ - if ( !hIvasDec->hasBeenFedFirstGoodFrame ) + if ( hIvasDec->hasBeenFedFirstGoodFrame && *bitstreamReadDone == true ) { - /* codec mode to use not known yet - simply output silence */ - /* directly set output zero */ - int16_t nSamplesToZero = min( nSamplesPerChannel, hIvasDec->nSamplesAvailableNext ); - set_pcm_buffer_to_zero( pcm_buffer_offset( pcmBuf, pcmType, ( *nSamplesRendered ) * nOutChannels ), pcmType, nSamplesToZero * nOutChannels ); - *nSamplesRendered += nSamplesToZero; - hIvasDec->nSamplesAvailableNext -= nSamplesToZero; - update_voip_rendered20ms( hIvasDec, nSamplesToZero ); + /* new bitstream was feeded, return for reconfiguration */ + return IVAS_ERR_OK; } - else + + if ( !hIvasDec->hasBeenFedFirstGoodFrame ) { - int16_t nSamplesToRender, nSamplesRendered_loop; - bool tmp; + hIvasDec->nSamplesAvailableNext = hIvasDec->nSamplesFrame; + } + } + + /* decode */ + if ( !hIvasDec->hasBeenFedFirstGoodFrame ) + { + /* codec mode to use not known yet - simply output silence */ + /* directly set output zero */ + int16_t nSamplesToZero = min( nSamplesPerChannel, hIvasDec->nSamplesAvailableNext ); + set_pcm_buffer_to_zero( pcm_buffer_offset( pcmBuf, pcmType, ( *nSamplesRendered ) * nOutChannels ), pcmType, nSamplesToZero * nOutChannels ); + *nSamplesRendered += nSamplesToZero; + hIvasDec->nSamplesAvailableNext -= nSamplesToZero; + update_voip_rendered20ms( hIvasDec, nSamplesToZero ); + } + else + { + int16_t nSamplesToRender, nSamplesRendered_loop; + bool tmp; - /* decode TCs, do TSM and prepare the renderer */ - if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) + /* decode TCs, do TSM and prepare the renderer */ + if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) + { + if ( hIvasDec->nSamplesAvailableNext == 0 || hIvasDec->nSamplesAvailableNext == hIvasDec->nSamplesFrame ) { - if ( hIvasDec->nSamplesAvailableNext == 0 || hIvasDec->nSamplesAvailableNext == hIvasDec->nSamplesFrame ) + if ( ( error = IVAS_DEC_GetSamplesDecoder( hIvasDec, splitRendBits ) ) != IVAS_ERR_OK ) { - if ( ( error = IVAS_DEC_GetSamplesDecoder( hIvasDec, splitRendBits ) ) != IVAS_ERR_OK ) - { - return error; - } - - *bitstreamReadDone = false; - *parametersAvailableForEditing = true; - return IVAS_ERR_OK; + return error; } + + *bitstreamReadDone = false; + *parametersAvailableForEditing = true; + return IVAS_ERR_OK; } + } - nSamplesToRender = nSamplesPerChannel - *nSamplesRendered; + nSamplesToRender = nSamplesPerChannel - *nSamplesRendered; - /* check if we still need to prepare the renderer */ - if ( hIvasDec->hasBeenPreparedRendering == false ) + /* check if we still need to prepare the renderer */ + if ( hIvasDec->hasBeenPreparedRendering == false ) + { + if ( ( error = IVAS_DEC_PrepareRenderer( hIvasDec ) ) != IVAS_ERR_OK ) { - if ( ( error = IVAS_DEC_PrepareRenderer( hIvasDec ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } + } - if ( splitRendBits != NULL ) + if ( splitRendBits != NULL ) + { + /* Render head poses from time-scaled transport channels */ + if ( ( error = isar_render_poses( hIvasDec, nSamplesToRender, &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) { - /* Render head poses from time-scaled transport channels */ - if ( ( error = isar_render_poses( hIvasDec, nSamplesToRender, &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } - else + } + else + { + /* render IVAS frames directly to the output buffer */ + if ( ( error = IVAS_DEC_GetSamplesRenderer( hIvasDec, nSamplesToRender, pcmType, pcm_buffer_offset( pcmBuf, pcmType, *nSamplesRendered * nOutChannels ), &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) { - /* render IVAS frames directly to the output buffer */ - if ( ( error = IVAS_DEC_GetSamplesRenderer( hIvasDec, nSamplesToRender, pcmType, pcm_buffer_offset( pcmBuf, pcmType, *nSamplesRendered * nOutChannels ), &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } - - *nSamplesRendered += nSamplesRendered_loop; - update_voip_rendered20ms( hIvasDec, nSamplesRendered_loop ); } + + *nSamplesRendered += nSamplesRendered_loop; + update_voip_rendered20ms( hIvasDec, nSamplesRendered_loop ); } + } - if ( hIvasDec->hasDecodedFirstGoodFrame && splitRendBits != NULL ) + if ( hIvasDec->hasDecodedFirstGoodFrame && splitRendBits != NULL ) + { + /* Analyse head poses over entire frame, generate ISAR metadata and maybe encode if split coded */ + if ( ( error = isar_generate_metadata_and_bitstream( st_ivas, p_head_pose_buf, *nSamplesRendered, splitRendBits ) ) != IVAS_ERR_OK ) { - /* Analyse head poses over entire frame, generate ISAR metadata and maybe encode if split coded */ - if ( ( error = isar_generate_metadata_and_bitstream( st_ivas, p_head_pose_buf, *nSamplesRendered, splitRendBits ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; + } - /* Synthesise PCM output if split PCM */ - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { + /* Synthesise PCM output if split PCM */ + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { #ifndef DISABLE_LIMITER - ivas_limiter_dec( st_ivas->hLimiter, p_head_pose_buf, st_ivas->hDecoderConfig->nchan_out, *nSamplesRendered, st_ivas->BER_detect ); + ivas_limiter_dec( st_ivas->hLimiter, p_head_pose_buf, st_ivas->hDecoderConfig->nchan_out, *nSamplesRendered, st_ivas->BER_detect ); #endif #ifdef DEBUGGING - st_ivas->noClipping += + st_ivas->noClipping += #endif - ivas_syn_output( p_head_pose_buf, *nSamplesRendered, st_ivas->hDecoderConfig->nchan_out, (int16_t *) pcmBuf ); - } + ivas_syn_output( p_head_pose_buf, *nSamplesRendered, st_ivas->hDecoderConfig->nchan_out, (int16_t *) pcmBuf ); } - - return IVAS_ERR_OK; } + return IVAS_ERR_OK; +} - /*---------------------------------------------------------------------* - * IVAS_DEC_VoIP_GetSamples( ) - * - * Main function to decode one frame in VoIP - *---------------------------------------------------------------------*/ - ivas_error IVAS_DEC_VoIP_GetSamples( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ - const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ - void *pcmBuf, /* o : output synthesis signal */ +/*---------------------------------------------------------------------* + * IVAS_DEC_VoIP_GetSamples( ) + * + * Main function to decode one frame in VoIP + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_VoIP_GetSamples( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ #ifdef SUPPORT_JBM_TRACEFILE - JbmTraceFileWriterFn jbmWriterFn, - void *jbmWriter, + JbmTraceFileWriterFn jbmWriterFn, + void *jbmWriter, #endif - bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */ - uint16_t *nSamplesRendered, /* o : number of samples rendered */ - bool *parametersAvailableForEditing, /* o : indicates whether objects editing is available */ - const uint32_t systemTimestamp_ms /* i : current system timestamp */ - ) - { - return ivas_dec_voip_get_samples_common( - hIvasDec, - nSamplesPerChannel, - pcmType, - pcmBuf, - NULL, - NULL, + bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */ + uint16_t *nSamplesRendered, /* o : number of samples rendered */ + bool *parametersAvailableForEditing, /* o : indicates whether objects editing is available */ + const uint32_t systemTimestamp_ms /* i : current system timestamp */ +) +{ + return ivas_dec_voip_get_samples_common( + hIvasDec, + nSamplesPerChannel, + pcmType, + pcmBuf, + NULL, + NULL, #ifdef SUPPORT_JBM_TRACEFILE - jbmWriterFn, - jbmWriter, + jbmWriterFn, + jbmWriter, #endif - bitstreamReadDone, - nSamplesRendered, - parametersAvailableForEditing, - systemTimestamp_ms ); - } + bitstreamReadDone, + nSamplesRendered, + parametersAvailableForEditing, + systemTimestamp_ms ); +} - /*---------------------------------------------------------------------* - * IVAS_DEC_VoIP_GetSplitBinauralBitstream( ) - * - * Main function to decode one split-rendering frame in VoIP - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_VoIP_GetSplitBinauralBitstream( ) + * + * Main function to decode one split-rendering frame in VoIP + *---------------------------------------------------------------------*/ - /*! r: error code */ - ivas_error IVAS_DEC_VoIP_GetSplitBinauralBitstream( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - /* const IVAS_DEC_PCM_TYPE pcmType, */ /* i : type for the decoded PCM resolution */ - void *pcmBuf, /* o : output synthesis signal */ - ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */ +/*! r: error code */ +ivas_error IVAS_DEC_VoIP_GetSplitBinauralBitstream( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + /* const IVAS_DEC_PCM_TYPE pcmType, */ /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */ #ifdef SUPPORT_JBM_TRACEFILE - JbmTraceFileWriterFn jbmWriterFn, - void *jbmWriter, + JbmTraceFileWriterFn jbmWriterFn, + void *jbmWriter, #endif - bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */ - uint16_t *nSamplesRendered, /* o : number of samples rendered */ - bool *parametersAvailableForEditing, /* o : indicates whether objects editing is available */ - const uint32_t systemTimestamp_ms /* i : current system timestamp */ - ) - { - int16_t i; - float head_pose_buf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES][L_FRAME48k]; - float *pp_head_pose_buf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES]; - ivas_error error = IVAS_ERR_UNKNOWN; - int16_t nSamplesPerChannel = 0; + bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */ + uint16_t *nSamplesRendered, /* o : number of samples rendered */ + bool *parametersAvailableForEditing, /* o : indicates whether objects editing is available */ + const uint32_t systemTimestamp_ms /* i : current system timestamp */ +) +{ + int16_t i; + float head_pose_buf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES][L_FRAME48k]; + float *pp_head_pose_buf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES]; + ivas_error error = IVAS_ERR_UNKNOWN; + int16_t nSamplesPerChannel = 0; - if ( ( error = IVAS_DEC_GetRenderFramesizeSamples( hIvasDec, &nSamplesPerChannel ) ) != IVAS_ERR_OK ) - { - return error; - } + if ( ( error = IVAS_DEC_GetRenderFramesizeSamples( hIvasDec, &nSamplesPerChannel ) ) != IVAS_ERR_OK ) + { + return error; + } - /* Set pointers to beginning of head pose buffers */ - for ( i = 0; i < BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES; ++i ) - { - pp_head_pose_buf[i] = head_pose_buf[i]; - } + /* Set pointers to beginning of head pose buffers */ + for ( i = 0; i < BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES; ++i ) + { + pp_head_pose_buf[i] = head_pose_buf[i]; + } - return ivas_dec_voip_get_samples_common( - hIvasDec, - nSamplesPerChannel, - IVAS_DEC_PCM_INT16, - pcmBuf, - splitRendBits, - pp_head_pose_buf, + return ivas_dec_voip_get_samples_common( + hIvasDec, + nSamplesPerChannel, + IVAS_DEC_PCM_INT16, + pcmBuf, + splitRendBits, + pp_head_pose_buf, #ifdef SUPPORT_JBM_TRACEFILE - jbmWriterFn, - jbmWriter, + jbmWriterFn, + jbmWriter, #endif - bitstreamReadDone, - nSamplesRendered, - parametersAvailableForEditing, - systemTimestamp_ms ); - } + bitstreamReadDone, + nSamplesRendered, + parametersAvailableForEditing, + systemTimestamp_ms ); +} - /*---------------------------------------------------------------------* - * update_voip_rendered20ms( ) - * - * Update the number of samples that have been rendered since the last 20ms render border - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * update_voip_rendered20ms( ) + * + * Update the number of samples that have been rendered since the last 20ms render border + *---------------------------------------------------------------------*/ - static void update_voip_rendered20ms( - IVAS_DEC_HANDLE hIvasDec, - const int16_t nSamplesRendered ) - { - int16_t nSamplesRenderedTotal; +static void update_voip_rendered20ms( + IVAS_DEC_HANDLE hIvasDec, + const int16_t nSamplesRendered ) +{ + int16_t nSamplesRenderedTotal; - nSamplesRenderedTotal = hIvasDec->hVoIP->nSamplesRendered20ms + nSamplesRendered; + nSamplesRenderedTotal = hIvasDec->hVoIP->nSamplesRendered20ms + nSamplesRendered; - /* we have crossed a 20ms border, reset the time scaling done flag */ - if ( nSamplesRenderedTotal >= hIvasDec->nSamplesFrame ) - { - hIvasDec->timeScalingDone = 0; - } + /* we have crossed a 20ms border, reset the time scaling done flag */ + if ( nSamplesRenderedTotal >= hIvasDec->nSamplesFrame ) + { + hIvasDec->timeScalingDone = 0; + } - hIvasDec->hVoIP->nSamplesRendered20ms = nSamplesRenderedTotal % hIvasDec->nSamplesFrame; + hIvasDec->hVoIP->nSamplesRendered20ms = nSamplesRenderedTotal % hIvasDec->nSamplesFrame; - return; - } + return; +} - /*---------------------------------------------------------------------* - * IVAS_DEC_VoIP_Flush( ) - * - * Function to flush remaining audio samples in VoIP - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_VoIP_Flush( ) + * + * Function to flush remaining audio samples in VoIP + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_Flush( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ + int16_t *nSamplesFlushed /* o : number of samples flushed */ +) +{ + ivas_error error; + uint16_t nSamplesToRender; + uint16_t nSamplesFlushedLocal; - ivas_error IVAS_DEC_Flush( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const int16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ - const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ - void *pcmBuf, /* o : output synthesis signal */ - int16_t *nSamplesFlushed /* o : number of samples flushed */ - ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - ivas_error error; - uint16_t nSamplesToRender; - uint16_t nSamplesFlushedLocal; - - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } #ifdef TMP_1342_WORKAROUND_DEC_FLUSH_BROKEN_IN_SR - hIvasDec->st_ivas->flushing = 1; + hIvasDec->st_ivas->flushing = 1; #endif - *nSamplesFlushed = min( nSamplesPerChannel, hIvasDec->nSamplesAvailableNext ); + *nSamplesFlushed = min( nSamplesPerChannel, hIvasDec->nSamplesAvailableNext ); - nSamplesToRender = (uint16_t) *nSamplesFlushed; + nSamplesToRender = (uint16_t) *nSamplesFlushed; - /* render IVAS frames */ - error = IVAS_ERR_OK; - if ( nSamplesToRender > 0 && hIvasDec->st_ivas->ivas_format != MONO_FORMAT ) - { - error = ivas_dec_render( hIvasDec->st_ivas, nSamplesToRender, &nSamplesFlushedLocal, &hIvasDec->nSamplesAvailableNext, pcm_type_API_to_internal( pcmType ), pcmBuf ); - } - else - { - *nSamplesFlushed = 0; - } + /* render IVAS frames */ + error = IVAS_ERR_OK; + if ( nSamplesToRender > 0 && hIvasDec->st_ivas->ivas_format != MONO_FORMAT ) + { + error = ivas_dec_render( hIvasDec->st_ivas, nSamplesToRender, &nSamplesFlushedLocal, &hIvasDec->nSamplesAvailableNext, pcm_type_API_to_internal( pcmType ), pcmBuf ); + } + else + { + *nSamplesFlushed = 0; + } #ifdef TMP_1342_WORKAROUND_DEC_FLUSH_BROKEN_IN_SR - hIvasDec->st_ivas->flushing = 0; + hIvasDec->st_ivas->flushing = 0; #endif - return error; - } + return error; +} - /*---------------------------------------------------------------------* - * IVAS_DEC_isRestartNeeded( ) - * - * - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_isRestartNeeded( ) + * + * + *---------------------------------------------------------------------*/ - ivas_error IVAS_DEC_isRestartNeeded( - IVAS_DEC_HANDLE hIvasDec, /* i : IVAS decoder handle */ - bool *restartNeeded /* o : flag to signal decoder restart */ +ivas_error IVAS_DEC_isRestartNeeded( + IVAS_DEC_HANDLE hIvasDec, /* i : IVAS decoder handle */ + bool *restartNeeded /* o : flag to signal decoder restart */ - ) +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - *restartNeeded = hIvasDec->st_ivas->restartNeeded > 0; + *restartNeeded = hIvasDec->st_ivas->restartNeeded > 0; - return IVAS_ERR_OK; - } + return IVAS_ERR_OK; +} - /*---------------------------------------------------------------------* - * IVAS_DEC_VoIP_IsEmpty( ) - * - * Returns 'true' if decoder has no data in VoIP jitter buffer - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_VoIP_IsEmpty( ) + * + * Returns 'true' if decoder has no data in VoIP jitter buffer + *---------------------------------------------------------------------*/ - ivas_error IVAS_DEC_VoIP_IsEmpty( - IVAS_DEC_HANDLE hIvasDec, /* i : IVAS decoder handle */ - const int16_t nSamplesAsked, /* i : number of output samples asked */ - bool *isEmpty /* o : isEmpty flag */ - ) +ivas_error IVAS_DEC_VoIP_IsEmpty( + IVAS_DEC_HANDLE hIvasDec, /* i : IVAS decoder handle */ + const int16_t nSamplesAsked, /* i : number of output samples asked */ + bool *isEmpty /* o : isEmpty flag */ +) +{ + if ( hIvasDec == NULL || hIvasDec->hVoIP == NULL ) { - if ( hIvasDec == NULL || hIvasDec->hVoIP == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - *isEmpty = ( JB4_bufferedDataUnits( hIvasDec->hVoIP->hJBM ) == 0 ) && ( hIvasDec->nSamplesAvailableNext < nSamplesAsked ); + *isEmpty = ( JB4_bufferedDataUnits( hIvasDec->hVoIP->hJBM ) == 0 ) && ( hIvasDec->nSamplesAvailableNext < nSamplesAsked ); - return IVAS_ERR_OK; - } + return IVAS_ERR_OK; +} - /*---------------------------------------------------------------------* - * IVAS_DEC_VoIP_Get_CA_offset( ) - * - * - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_VoIP_Get_CA_offset( ) + * + * + *---------------------------------------------------------------------*/ - ivas_error IVAS_DEC_VoIP_Get_CA_offset( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t * optimum_offset, - int16_t * FEC_hi ) +ivas_error IVAS_DEC_VoIP_Get_CA_offset( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *optimum_offset, + int16_t *FEC_hi ) +{ + if ( hIvasDec == NULL || hIvasDec->hVoIP == NULL || hIvasDec->hVoIP->hJBM == NULL ) { - if ( hIvasDec == NULL || hIvasDec->hVoIP == NULL || hIvasDec->hVoIP->hJBM == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - *optimum_offset = JB4_getFECoffset( hIvasDec->hVoIP->hJBM ); - *FEC_hi = JB4_FECoffset( hIvasDec->hVoIP->hJBM ); + *optimum_offset = JB4_getFECoffset( hIvasDec->hVoIP->hJBM ); + *FEC_hi = JB4_FECoffset( hIvasDec->hVoIP->hJBM ); + + return IVAS_ERR_OK; +} - return IVAS_ERR_OK; - } +/*---------------------------------------------------------------------* + * ivas_destroy_handle_VoIP( ) + * + * Deallocate VoIP handle + *---------------------------------------------------------------------*/ - /*---------------------------------------------------------------------* - * ivas_destroy_handle_VoIP( ) - * - * Deallocate VoIP handle - *---------------------------------------------------------------------*/ +static void ivas_destroy_handle_VoIP( + IVAS_DEC_VOIP *hVoIP /* i/o: VoIP decoder handle */ +) +{ + JB4_Destroy( &hVoIP->hJBM ); - static void ivas_destroy_handle_VoIP( - IVAS_DEC_VOIP * hVoIP /* i/o: VoIP decoder handle */ - ) + if ( hVoIP->bs_conversion_buf != NULL ) { - JB4_Destroy( &hVoIP->hJBM ); - - if ( hVoIP->bs_conversion_buf != NULL ) - { #define WMC_TOOL_SKIP - /* Bitstream conversion is not counted towards complexity and memory usage */ - free( hVoIP->bs_conversion_buf ); + /* Bitstream conversion is not counted towards complexity and memory usage */ + free( hVoIP->bs_conversion_buf ); #undef WMC_TOOL_SKIP - } + } - free( hVoIP ); + free( hVoIP ); - return; - } + return; +} #ifdef SUPPORT_JBM_TRACEFILE - /*---------------------------------------------------------------------* - * store_JbmData() - * - * Store JBM trace data entry - *---------------------------------------------------------------------*/ - - static void store_JbmData( - IVAS_DEC_VOIP * hVoIP, - JB4_DATAUNIT_HANDLE dataUnit, - const uint32_t systemTimestamp_ms, - const uint16_t extBufferedSamples, - const int32_t output_Fs ) - { - IVAS_JBM_TRACE_DATA *JbmTraceData; +/*---------------------------------------------------------------------* + * store_JbmData() + * + * Store JBM trace data entry + *---------------------------------------------------------------------*/ - if ( hVoIP == NULL ) - { - return; - } +static void store_JbmData( + IVAS_DEC_VOIP *hVoIP, + JB4_DATAUNIT_HANDLE dataUnit, + const uint32_t systemTimestamp_ms, + const uint16_t extBufferedSamples, + const int32_t output_Fs ) +{ + IVAS_JBM_TRACE_DATA *JbmTraceData; - JbmTraceData = &hVoIP->JbmTraceData; + if ( hVoIP == NULL ) + { + return; + } - JbmTraceData->systemTimestamp_ms = systemTimestamp_ms; - JbmTraceData->extBufferedSamples = extBufferedSamples; - JbmTraceData->lastDecodedWasActive = hVoIP->lastDecodedWasActive; - JbmTraceData->output_Fs = output_Fs; - JbmTraceData->dataUnit_flag = dataUnit != NULL; - if ( dataUnit != NULL ) - { - JbmTraceData->sequenceNumber = dataUnit->sequenceNumber; - JbmTraceData->timeStamp = dataUnit->timeStamp; - JbmTraceData->rcvTime = dataUnit->rcvTime; - JbmTraceData->partial_frame = dataUnit->partial_frame; - JbmTraceData->partialCopyOffset = dataUnit->partialCopyOffset; - } + JbmTraceData = &hVoIP->JbmTraceData; - return; + JbmTraceData->systemTimestamp_ms = systemTimestamp_ms; + JbmTraceData->extBufferedSamples = extBufferedSamples; + JbmTraceData->lastDecodedWasActive = hVoIP->lastDecodedWasActive; + JbmTraceData->output_Fs = output_Fs; + JbmTraceData->dataUnit_flag = dataUnit != NULL; + if ( dataUnit != NULL ) + { + JbmTraceData->sequenceNumber = dataUnit->sequenceNumber; + JbmTraceData->timeStamp = dataUnit->timeStamp; + JbmTraceData->rcvTime = dataUnit->rcvTime; + JbmTraceData->partial_frame = dataUnit->partial_frame; + JbmTraceData->partialCopyOffset = dataUnit->partialCopyOffset; } + return; +} + - /*---------------------------------------------------------------------* - * IVAS_DEC_GetJbmData() - * - * - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_GetJbmData() + * + * + *---------------------------------------------------------------------*/ - ivas_error IVAS_DEC_GetJbmData( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_JBM_TRACE_DATA * JbmTraceData /* o : JBM Trace data */ +ivas_error IVAS_DEC_GetJbmData( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_JBM_TRACE_DATA *JbmTraceData /* o : JBM Trace data */ - ) +) +{ + if ( hIvasDec == NULL || hIvasDec->hVoIP == NULL || JbmTraceData == NULL ) { - if ( hIvasDec == NULL || hIvasDec->hVoIP == NULL || JbmTraceData == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - *JbmTraceData = hIvasDec->hVoIP->JbmTraceData; + *JbmTraceData = hIvasDec->hVoIP->JbmTraceData; - return IVAS_ERR_OK; - } + return IVAS_ERR_OK; +} #endif - /*---------------------------------------------------------------------* - * IVAS_DEC_GetErrorMessage( ) - * - * Maps error codes to error description strings - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_GetErrorMessage( ) + * + * Maps error codes to error description strings + *---------------------------------------------------------------------*/ - const char *IVAS_DEC_GetErrorMessage( - ivas_error error /* i : decoder error code enum */ - ) - { - return ivas_error_to_string( error ); - } +const char *IVAS_DEC_GetErrorMessage( + ivas_error error /* i : decoder error code enum */ +) +{ + return ivas_error_to_string( error ); +} - /*---------------------------------------------------------------------* - * printConfigInfo_dec( ) - * - * - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * printConfigInfo_dec( ) + * + * + *---------------------------------------------------------------------*/ - static ivas_error printConfigInfo_dec( - Decoder_Struct * st_ivas, - const int16_t bitstreamformat, - const bool Opt_VOIP, - const bool quietModeEnabled ) - { - ivas_error error; - char config_str[200]; - AUDIO_CONFIG output_config; +static ivas_error printConfigInfo_dec( + Decoder_Struct *st_ivas, + const int16_t bitstreamformat, + const bool Opt_VOIP, + const bool quietModeEnabled ) +{ + ivas_error error; + char config_str[200]; + AUDIO_CONFIG output_config; - /*-----------------------------------------------------------------* - * Print info on screen - *-----------------------------------------------------------------*/ + /*-----------------------------------------------------------------* + * Print info on screen + *-----------------------------------------------------------------*/ - fprintf( stdout, "\n" ); + fprintf( stdout, "\n" ); - /*-----------------------------------------------------------------* - * Print output sampling frequency - *-----------------------------------------------------------------*/ + /*-----------------------------------------------------------------* + * Print output sampling frequency + *-----------------------------------------------------------------*/ - fprintf( stdout, "Output sampling rate: %d Hz\n", st_ivas->hDecoderConfig->output_Fs ); + fprintf( stdout, "Output sampling rate: %d Hz\n", st_ivas->hDecoderConfig->output_Fs ); - /*-----------------------------------------------------------------* - * Print bitrate - *-----------------------------------------------------------------*/ + /*-----------------------------------------------------------------* + * Print bitrate + *-----------------------------------------------------------------*/ - if ( !quietModeEnabled ) + if ( !quietModeEnabled ) + { + if ( !Opt_VOIP ) { - if ( !Opt_VOIP ) - { - fprintf( stdout, "Bitrate: %.2f kbps\n", (float) st_ivas->hDecoderConfig->ivas_total_brate / 1000 ); + fprintf( stdout, "Bitrate: %.2f kbps\n", (float) st_ivas->hDecoderConfig->ivas_total_brate / 1000 ); - if ( st_ivas->hDecoderConfig->ivas_total_brate <= 0 ) + if ( st_ivas->hDecoderConfig->ivas_total_brate <= 0 ) + { + if ( bitstreamformat == G192 ) { - if ( bitstreamformat == G192 ) - { - fprintf( stdout, "Active Bitrate not identified in bitstream file \n" ); - } - else /* MIME */ - { - fprintf( stdout, "Active Bitrate not identified from first MIME frame \n" ); - } + fprintf( stdout, "Active Bitrate not identified in bitstream file \n" ); + } + else /* MIME */ + { + fprintf( stdout, "Active Bitrate not identified from first MIME frame \n" ); } } } + } - /*-----------------------------------------------------------------* - * Print output configuration - *-----------------------------------------------------------------*/ + /*-----------------------------------------------------------------* + * Print output configuration + *-----------------------------------------------------------------*/ - if ( st_ivas->ivas_format == MONO_FORMAT ) + if ( st_ivas->ivas_format == MONO_FORMAT ) + { + if ( st_ivas->hDecoderConfig->Opt_non_diegetic_pan ) + { + fprintf( stdout, "Output configuration: mono EVS bit-exact decoding to stereo\n" ); + fprintf( stdout, "Non-diegetic panning: %.2f\n", st_ivas->hDecoderConfig->non_diegetic_pan_gain * 90.f ); + } + else { - if ( st_ivas->hDecoderConfig->Opt_non_diegetic_pan ) + output_config = st_ivas->hDecoderConfig->output_config; + if ( output_config != IVAS_AUDIO_CONFIG_MONO ) { - fprintf( stdout, "Output configuration: mono EVS bit-exact decoding to stereo\n" ); - fprintf( stdout, "Non-diegetic panning: %.2f\n", st_ivas->hDecoderConfig->non_diegetic_pan_gain * 90.f ); + get_channel_config( output_config, &config_str[0] ); + fprintf( stdout, "Output configuration: mono EVS bit-exact decoding rendering to %s\n", config_str ); } else { - output_config = st_ivas->hDecoderConfig->output_config; - if ( output_config != IVAS_AUDIO_CONFIG_MONO ) - { - get_channel_config( output_config, &config_str[0] ); - fprintf( stdout, "Output configuration: mono EVS bit-exact decoding rendering to %s\n", config_str ); - } - else - { - fprintf( stdout, "Output configuration: mono EVS bit-exact decoding\n" ); - } + fprintf( stdout, "Output configuration: mono EVS bit-exact decoding\n" ); } } - else + } + else + { + if ( !quietModeEnabled ) { - if ( !quietModeEnabled ) + if ( st_ivas->ivas_format == STEREO_FORMAT ) { - if ( st_ivas->ivas_format == STEREO_FORMAT ) - { - fprintf( stdout, "Input configuration: Stereo\n" ); - } - else if ( st_ivas->ivas_format == ISM_FORMAT ) - { - if ( st_ivas->ism_mode == ISM_MODE_PARAM ) - { - fprintf( stdout, "Input configuration: ISM (ParamISM): 2 transport channels\n" ); - } - else - { - fprintf( stdout, "Input configuration: ISM: %d transport channel(s)\n", st_ivas->nchan_transport ); - } - } - else if ( st_ivas->ivas_format == SBA_FORMAT ) - { - fprintf( stdout, "Input configuration: Scene Based Audio, Ambisonic order %i%s, %d transport channel(s)\n", st_ivas->sba_order, st_ivas->sba_planar ? " (Planar)" : "", st_ivas->nchan_transport ); - } - else if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) - { - fprintf( stdout, "Input configuration: Combined Scene Based Audio, Ambisonic order %i, with %d Objects \n", st_ivas->sba_order, st_ivas->nchan_ism ); - } - else if ( st_ivas->ivas_format == MASA_FORMAT ) - { - fprintf( stdout, "Input configuration: MASA - %d channel(s)\n", st_ivas->nchan_transport ); - } - else if ( st_ivas->ivas_format == MC_FORMAT ) + fprintf( stdout, "Input configuration: Stereo\n" ); + } + else if ( st_ivas->ivas_format == ISM_FORMAT ) + { + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { - if ( ( error = get_channel_config( st_ivas->transport_config, &config_str[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - - fprintf( stdout, "Input configuration: %s\n", config_str ); + fprintf( stdout, "Input configuration: ISM (ParamISM): 2 transport channels\n" ); } - else if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) + else { - fprintf( stdout, "Input configuration: combined ISM and MASA (%i ISM stream(s)) \n", st_ivas->nchan_ism ); + fprintf( stdout, "Input configuration: ISM: %d transport channel(s)\n", st_ivas->nchan_transport ); } } - - output_config = st_ivas->hDecoderConfig->output_config; - get_channel_config( output_config, &config_str[0] ); - fprintf( stdout, "Output configuration: %s\n", config_str ); - - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - fprintf( stdout, "Render framesize: %d ms\n", get_render_frame_size_ms( st_ivas->hDecoderConfig->render_num_subframes ) ); - } - if ( st_ivas->hDecoderConfig->Opt_HRTF_binary ) + else if ( st_ivas->ivas_format == SBA_FORMAT ) { - fprintf( stdout, "HRIR/BRIR file: ON\n" ); + fprintf( stdout, "Input configuration: Scene Based Audio, Ambisonic order %i%s, %d transport channel(s)\n", st_ivas->sba_order, st_ivas->sba_planar ? " (Planar)" : "", st_ivas->nchan_transport ); } - - if ( st_ivas->hDecoderConfig->Opt_RendConfigCustom ) - { - fprintf( stdout, "Renderer config. file: ON\n" ); - } - - if ( st_ivas->hDecoderConfig->Opt_Headrotation ) + else if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) { - fprintf( stdout, "Head rotation: ON\n" ); + fprintf( stdout, "Input configuration: Combined Scene Based Audio, Ambisonic order %i, with %d Objects \n", st_ivas->sba_order, st_ivas->nchan_ism ); } - - if ( st_ivas->hDecoderConfig->Opt_ExternalOrientation ) + else if ( st_ivas->ivas_format == MASA_FORMAT ) { - fprintf( stdout, "External orientation: ON\n" ); + fprintf( stdout, "Input configuration: MASA - %d channel(s)\n", st_ivas->nchan_transport ); } - - if ( st_ivas->hDecoderConfig->orientation_tracking != IVAS_HEAD_ORIENT_TRK_NONE ) + else if ( st_ivas->ivas_format == MC_FORMAT ) { - switch ( st_ivas->hDecoderConfig->orientation_tracking ) + if ( ( error = get_channel_config( st_ivas->transport_config, &config_str[0] ) ) != IVAS_ERR_OK ) { - case IVAS_HEAD_ORIENT_TRK_AVG: - fprintf( stdout, "Orientation tracking: AVG\n" ); - break; - case IVAS_HEAD_ORIENT_TRK_REF: - fprintf( stdout, "Orientation tracking: REF\n" ); - break; - case IVAS_HEAD_ORIENT_TRK_REF_VEC: - fprintf( stdout, "Orientation tracking: REF_VEC\n" ); - break; - case IVAS_HEAD_ORIENT_TRK_REF_VEC_LEV: - fprintf( stdout, "Orientation tracking: REF_VEC_LEV\n" ); - break; - default: - break; + return error; } - } - if ( st_ivas->hDecoderConfig->Opt_non_diegetic_pan ) - { - fprintf( stdout, "Non-diegetic panning: %.2f\n", st_ivas->hDecoderConfig->non_diegetic_pan_gain * 90.f ); + fprintf( stdout, "Input configuration: %s\n", config_str ); } - - if ( st_ivas->hDecoderConfig->Opt_dpid_on ) + else if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) { - fprintf( stdout, "Directivity pattern: ON\n" ); + fprintf( stdout, "Input configuration: combined ISM and MASA (%i ISM stream(s)) \n", st_ivas->nchan_ism ); } + } - if ( st_ivas->hDecoderConfig->Opt_aeid_on ) - { - fprintf( stdout, "Acoustic environment ID:ON\n" ); - } + output_config = st_ivas->hDecoderConfig->output_config; + get_channel_config( output_config, &config_str[0] ); + fprintf( stdout, "Output configuration: %s\n", config_str ); + + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + fprintf( stdout, "Render framesize: %d ms\n", get_render_frame_size_ms( st_ivas->hDecoderConfig->render_num_subframes ) ); + } + if ( st_ivas->hDecoderConfig->Opt_HRTF_binary ) + { + fprintf( stdout, "HRIR/BRIR file: ON\n" ); + } + + if ( st_ivas->hDecoderConfig->Opt_RendConfigCustom ) + { + fprintf( stdout, "Renderer config. file: ON\n" ); + } + + if ( st_ivas->hDecoderConfig->Opt_Headrotation ) + { + fprintf( stdout, "Head rotation: ON\n" ); + } + + if ( st_ivas->hDecoderConfig->Opt_ExternalOrientation ) + { + fprintf( stdout, "External orientation: ON\n" ); + } - if ( st_ivas->hDecoderConfig->Opt_ObjEdit_on ) + if ( st_ivas->hDecoderConfig->orientation_tracking != IVAS_HEAD_ORIENT_TRK_NONE ) + { + switch ( st_ivas->hDecoderConfig->orientation_tracking ) { - fprintf( stdout, "Objects editing : ON\n" ); + case IVAS_HEAD_ORIENT_TRK_AVG: + fprintf( stdout, "Orientation tracking: AVG\n" ); + break; + case IVAS_HEAD_ORIENT_TRK_REF: + fprintf( stdout, "Orientation tracking: REF\n" ); + break; + case IVAS_HEAD_ORIENT_TRK_REF_VEC: + fprintf( stdout, "Orientation tracking: REF_VEC\n" ); + break; + case IVAS_HEAD_ORIENT_TRK_REF_VEC_LEV: + fprintf( stdout, "Orientation tracking: REF_VEC_LEV\n" ); + break; + default: + break; } } - /*-----------------------------------------------------------------* - * Print TSM mode info - *-----------------------------------------------------------------*/ + if ( st_ivas->hDecoderConfig->Opt_non_diegetic_pan ) + { + fprintf( stdout, "Non-diegetic panning: %.2f\n", st_ivas->hDecoderConfig->non_diegetic_pan_gain * 90.f ); + } - if ( st_ivas->hDecoderConfig->Opt_tsm ) + if ( st_ivas->hDecoderConfig->Opt_dpid_on ) { - fprintf( stdout, "TSM mode: ON\n" ); + fprintf( stdout, "Directivity pattern: ON\n" ); } - return IVAS_ERR_OK; - } + if ( st_ivas->hDecoderConfig->Opt_aeid_on ) + { + fprintf( stdout, "Acoustic environment ID:ON\n" ); + } + if ( st_ivas->hDecoderConfig->Opt_ObjEdit_on ) + { + fprintf( stdout, "Objects editing : ON\n" ); + } + } - /*---------------------------------------------------------------------* - * IVAS_DEC_PrintConfig( ) - * - * Print decoder set-up info - *---------------------------------------------------------------------*/ + /*-----------------------------------------------------------------* + * Print TSM mode info + *-----------------------------------------------------------------*/ - ivas_error IVAS_DEC_PrintConfig( - const IVAS_DEC_HANDLE hIvasDec, - const bool quietModeEnabled, - const bool voipMode ) + if ( st_ivas->hDecoderConfig->Opt_tsm ) { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + fprintf( stdout, "TSM mode: ON\n" ); + } - printConfigInfo_dec( hIvasDec->st_ivas, hIvasDec->bitstreamformat, voipMode, quietModeEnabled ); + return IVAS_ERR_OK; +} - return IVAS_ERR_OK; + +/*---------------------------------------------------------------------* + * IVAS_DEC_PrintConfig( ) + * + * Print decoder set-up info + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_PrintConfig( + const IVAS_DEC_HANDLE hIvasDec, + const bool quietModeEnabled, + const bool voipMode ) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + printConfigInfo_dec( hIvasDec->st_ivas, hIvasDec->bitstreamformat, voipMode, quietModeEnabled ); + + return IVAS_ERR_OK; +} + #ifdef DEBUGGING /*---------------------------------------------------------------------* @@ -4703,1080 +4703,1080 @@ ivas_error IVAS_DEC_Open( * *---------------------------------------------------------------------*/ #define WMC_TOOL_SKIP - void IVAS_DEC_PrintConfigWithBitstream( - IVAS_DEC_HANDLE hIvasDec, - const bool quietModeEnabled, - uint16_t bit_stream[], - const int16_t num_bits ) - { - Decoder_Struct *st_ivas; +void IVAS_DEC_PrintConfigWithBitstream( + IVAS_DEC_HANDLE hIvasDec, + const bool quietModeEnabled, + uint16_t bit_stream[], + const int16_t num_bits ) +{ + Decoder_Struct *st_ivas; - /* Create a copy of decoder struct that will be modified by preview_indices(), - * leaving the original decoder struct unchanged. The additional memory used here - * should not be counted towards memory footprint of the decoder. */ - st_ivas = malloc( sizeof( Decoder_Struct ) ); - memcpy( st_ivas, hIvasDec->st_ivas, sizeof( Decoder_Struct ) ); + /* Create a copy of decoder struct that will be modified by preview_indices(), + * leaving the original decoder struct unchanged. The additional memory used here + * should not be counted towards memory footprint of the decoder. */ + st_ivas = malloc( sizeof( Decoder_Struct ) ); + memcpy( st_ivas, hIvasDec->st_ivas, sizeof( Decoder_Struct ) ); - preview_indices( st_ivas, bit_stream, num_bits ); + preview_indices( st_ivas, bit_stream, num_bits ); - /* Print config from modified decoder struct */ - printConfigInfo_dec( st_ivas, hIvasDec->bitstreamformat, hIvasDec->Opt_VOIP, quietModeEnabled ); + /* Print config from modified decoder struct */ + printConfigInfo_dec( st_ivas, hIvasDec->bitstreamformat, hIvasDec->Opt_VOIP, quietModeEnabled ); - free( st_ivas ); + free( st_ivas ); - return; - } + return; +} - /*---------------------------------------------------------------------* - * IVAS_DEC_PrintConfigWithVoipBitstream( ) - * - * - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_PrintConfigWithVoipBitstream( ) + * + * + *---------------------------------------------------------------------*/ - void IVAS_DEC_PrintConfigWithVoipBitstream( - IVAS_DEC_HANDLE hIvasDec, - const bool quietModeEnabled, - uint8_t *au, - const uint16_t auSizeBits ) - { - Decoder_Struct *st_ivas; - uint16_t bit_stream[MAX_BITS_PER_FRAME + 4 * 8]; +void IVAS_DEC_PrintConfigWithVoipBitstream( + IVAS_DEC_HANDLE hIvasDec, + const bool quietModeEnabled, + uint8_t *au, + const uint16_t auSizeBits ) +{ + Decoder_Struct *st_ivas; + uint16_t bit_stream[MAX_BITS_PER_FRAME + 4 * 8]; - /* Create a copy of decoder struct that will be modified by preview_indices(), - * leaving the original decoder struct unchanged. The additional memory used here - * should not be counted towards memory footprint of the decoder. */ - st_ivas = malloc( sizeof( Decoder_Struct ) ); - memcpy( st_ivas, hIvasDec->st_ivas, sizeof( Decoder_Struct ) ); + /* Create a copy of decoder struct that will be modified by preview_indices(), + * leaving the original decoder struct unchanged. The additional memory used here + * should not be counted towards memory footprint of the decoder. */ + st_ivas = malloc( sizeof( Decoder_Struct ) ); + memcpy( st_ivas, hIvasDec->st_ivas, sizeof( Decoder_Struct ) ); - bsCompactToSerial( au, bit_stream, auSizeBits ); - preview_indices( st_ivas, bit_stream, auSizeBits ); + bsCompactToSerial( au, bit_stream, auSizeBits ); + preview_indices( st_ivas, bit_stream, auSizeBits ); - /* Print config from modified decoder struct */ - printConfigInfo_dec( st_ivas, hIvasDec->bitstreamformat, hIvasDec->Opt_VOIP, quietModeEnabled ); + /* Print config from modified decoder struct */ + printConfigInfo_dec( st_ivas, hIvasDec->bitstreamformat, hIvasDec->Opt_VOIP, quietModeEnabled ); - free( st_ivas ); + free( st_ivas ); - return; - } + return; +} #undef WMC_TOOL_SKIP #endif - /*---------------------------------------------------------------------* - * IVAS_DEC_PrintDisclaimer( ) - * - * Print IVAS disclaimer to console - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_PrintDisclaimer( ) + * + * Print IVAS disclaimer to console + *---------------------------------------------------------------------*/ - void IVAS_DEC_PrintDisclaimer( void ) - { - print_disclaimer( stderr ); +void IVAS_DEC_PrintDisclaimer( void ) +{ + print_disclaimer( stderr ); - return; - } + return; +} - /*---------------------------------------------------------------------* - * evs_dec_main( ) - * - * EVS codec main decoder fucntion - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * evs_dec_main( ) + * + * EVS codec main decoder fucntion + *---------------------------------------------------------------------*/ - static ivas_error evs_dec_main( - Decoder_Struct * st_ivas /* i : IVAS decoder structure */ - ) - { - DEC_CORE_HANDLE *hCoreCoder; - float *p_output[1]; - int16_t nOutSamples; - ivas_error error; +static ivas_error evs_dec_main( + Decoder_Struct *st_ivas /* i : IVAS decoder structure */ +) +{ + DEC_CORE_HANDLE *hCoreCoder; + float *p_output[1]; + int16_t nOutSamples; + ivas_error error; - hCoreCoder = st_ivas->hSCE[0]->hCoreCoder; - hCoreCoder[0]->total_brate = st_ivas->hDecoderConfig->ivas_total_brate; - nOutSamples = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); + hCoreCoder = st_ivas->hSCE[0]->hCoreCoder; + hCoreCoder[0]->total_brate = st_ivas->hDecoderConfig->ivas_total_brate; + nOutSamples = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); - mdct_switching_dec( hCoreCoder[0] ); + mdct_switching_dec( hCoreCoder[0] ); - p_output[0] = st_ivas->p_output_f[0]; + p_output[0] = st_ivas->p_output_f[0]; - /* run the main EVS decoding routine */ - if ( hCoreCoder[0]->codec_mode == MODE1 ) + /* run the main EVS decoding routine */ + if ( hCoreCoder[0]->codec_mode == MODE1 ) + { + if ( hCoreCoder[0]->Opt_AMR_WB ) { - if ( hCoreCoder[0]->Opt_AMR_WB ) + if ( ( error = amr_wb_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0] ) ) != IVAS_ERR_OK ) { - if ( ( error = amr_wb_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0] ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } - else + } + else + { + if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_NORMAL ) ) != IVAS_ERR_OK ) { - if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_NORMAL ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } } - else + } + else + { + if ( hCoreCoder[0]->bfi == 0 ) { - if ( hCoreCoder[0]->bfi == 0 ) + if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_NORMAL ) ) != IVAS_ERR_OK ) { - if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_NORMAL ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } - else if ( hCoreCoder[0]->bfi == 2 ) + } + else if ( hCoreCoder[0]->bfi == 2 ) + { + if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_FUTURE ) ) != IVAS_ERR_OK ) { - if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_FUTURE ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } - else + } + else + { + if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_MISSING ) ) != IVAS_ERR_OK ) { - if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_MISSING ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } } + } - st_ivas->BER_detect = hCoreCoder[0]->BER_detect; + st_ivas->BER_detect = hCoreCoder[0]->BER_detect; - if ( st_ivas->hDecoderConfig->Opt_tsm && st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_MONO ) - { - /* BE workaround: in order to keep EVS bit-exact wrt. TS 26.443, convert 'float' output data to 'short' before the TSM */ - int16_t pcm_buf_local[L_FRAME48k]; + if ( st_ivas->hDecoderConfig->Opt_tsm && st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_MONO ) + { + /* BE workaround: in order to keep EVS bit-exact wrt. TS 26.443, convert 'float' output data to 'short' before the TSM */ + int16_t pcm_buf_local[L_FRAME48k]; #ifdef DEBUGGING - st_ivas->noClipping += + st_ivas->noClipping += #endif - ivas_syn_output( &p_output[0], nOutSamples, 1, pcm_buf_local ); - mvs2r( pcm_buf_local, p_output[0], nOutSamples ); - } - - return IVAS_ERR_OK; + ivas_syn_output( &p_output[0], nOutSamples, 1, pcm_buf_local ); + mvs2r( pcm_buf_local, p_output[0], nOutSamples ); } + return IVAS_ERR_OK; +} + #ifdef DEBUGGING - /*---------------------------------------------------------------------* - * IVAS_DEC_GetBer_detect_flag() - * - * return BER_detect flag - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_GetBer_detect_flag() + * + * return BER_detect flag + *---------------------------------------------------------------------*/ - bool IVAS_DEC_GetBerDetectFlag( - IVAS_DEC_HANDLE hIvasDec /* i : IVAS decoder handle */ - ) +bool IVAS_DEC_GetBerDetectFlag( + IVAS_DEC_HANDLE hIvasDec /* i : IVAS decoder handle */ +) +{ + if ( hIvasDec->st_ivas->BER_detect == 1 ) { - if ( hIvasDec->st_ivas->BER_detect == 1 ) - { - return 1; - } - else - { - return 0; - } + return 1; + } + else + { + return 0; } +} - /*---------------------------------------------------------------------* - * IVAS_DEC_GetNoCLipping() - * - * return number of clipped samples - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_GetNoCLipping() + * + * return number of clipped samples + *---------------------------------------------------------------------*/ - int32_t IVAS_DEC_GetNoCLipping( - IVAS_DEC_HANDLE hIvasDec /* i : IVAS decoder handle */ - ) - { - return hIvasDec->st_ivas->noClipping; - } +int32_t IVAS_DEC_GetNoCLipping( + IVAS_DEC_HANDLE hIvasDec /* i : IVAS decoder handle */ +) +{ + return hIvasDec->st_ivas->noClipping; +} - /*---------------------------------------------------------------------* - * IVAS_DEC_GetCntFramesLimited() - * - * return number of frames where limiter is applied - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_GetCntFramesLimited() + * + * return number of frames where limiter is applied + *---------------------------------------------------------------------*/ - int32_t IVAS_DEC_GetCntFramesLimited( - IVAS_DEC_HANDLE hIvasDec /* i : IVAS decoder handle */ - ) +int32_t IVAS_DEC_GetCntFramesLimited( + IVAS_DEC_HANDLE hIvasDec /* i : IVAS decoder handle */ +) +{ + if ( hIvasDec->st_ivas->hLimiter == NULL ) { - if ( hIvasDec->st_ivas->hLimiter == NULL ) - { - return 0; - } - else - { - return hIvasDec->st_ivas->hLimiter->cnt_frames_limited; - } + return 0; + } + else + { + return hIvasDec->st_ivas->hLimiter->cnt_frames_limited; } +} #ifdef DEBUG_SBA_AUDIO_DUMP - /*---------------------------------------------------------------------* - * IVAS_DEC_GetSbaDebugParams( ) - * - * Returns SBA debug parameters - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_GetSbaDebugParams( ) + * + * Returns SBA debug parameters + *---------------------------------------------------------------------*/ - ivas_error IVAS_DEC_GetSbaDebugParams( - const IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t *numOutputChannels, - int16_t *numTransportChannels, - int16_t *pca_ingest_channels ) +ivas_error IVAS_DEC_GetSbaDebugParams( + const IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *numOutputChannels, + int16_t *numTransportChannels, + int16_t *pca_ingest_channels ) +{ + if ( hIvasDec->st_ivas == NULL ) { - if ( hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - if ( hIvasDec->st_ivas->ivas_format != SBA_FORMAT || hIvasDec->st_ivas->hSpar == NULL ) - { - *numOutputChannels = 1; - *numTransportChannels = 1; - *pca_ingest_channels = 1; - } - else - { - *numOutputChannels = hIvasDec->st_ivas->hSpar->numOutChannels; - *numTransportChannels = hIvasDec->st_ivas->nchan_transport; - *pca_ingest_channels = hIvasDec->st_ivas->hSpar->pca_ingest_channels; - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - return IVAS_ERR_OK; + if ( hIvasDec->st_ivas->ivas_format != SBA_FORMAT || hIvasDec->st_ivas->hSpar == NULL ) + { + *numOutputChannels = 1; + *numTransportChannels = 1; + *pca_ingest_channels = 1; } + else + { + *numOutputChannels = hIvasDec->st_ivas->hSpar->numOutChannels; + *numTransportChannels = hIvasDec->st_ivas->nchan_transport; + *pca_ingest_channels = hIvasDec->st_ivas->hSpar->pca_ingest_channels; + } + + return IVAS_ERR_OK; +} #endif /* DEBUG_SBA_AUDIO_DUMP */ #endif /* DEBUGGING */ - /*---------------------------------------------------------------------* - * input_format_API_to_internal() - * - * - *---------------------------------------------------------------------*/ - - static ivas_error input_format_API_to_internal( - IVAS_DEC_INPUT_FORMAT input_format, - int16_t * bitstream_format_internal, - int16_t * sdp_hf_only, - const bool is_voip_enabled ) - { - switch ( input_format ) - { - case IVAS_DEC_INPUT_FORMAT_G192: - *bitstream_format_internal = is_voip_enabled ? VOIP_G192_RTP : G192; - *sdp_hf_only = 0; - break; - case IVAS_DEC_INPUT_FORMAT_MIME: - *bitstream_format_internal = MIME; - *sdp_hf_only = 0; - break; - case IVAS_DEC_INPUT_FORMAT_RTPDUMP: - assert( is_voip_enabled && "RTP dump only supported in VoIP mode" ); - *bitstream_format_internal = VOIP_RTPDUMP; - *sdp_hf_only = 0; - break; - case IVAS_DEC_INPUT_FORMAT_RTPDUMP_HF: - assert( is_voip_enabled && "RTP dump only supported in VoIP mode" ); - *bitstream_format_internal = VOIP_RTPDUMP; - *sdp_hf_only = 1; - break; - default: - return IVAS_ERR_INVALID_BITSTREAM; - break; - } +/*---------------------------------------------------------------------* + * input_format_API_to_internal() + * + * + *---------------------------------------------------------------------*/ - return IVAS_ERR_OK; +static ivas_error input_format_API_to_internal( + IVAS_DEC_INPUT_FORMAT input_format, + int16_t *bitstream_format_internal, + int16_t *sdp_hf_only, + const bool is_voip_enabled ) +{ + switch ( input_format ) + { + case IVAS_DEC_INPUT_FORMAT_G192: + *bitstream_format_internal = is_voip_enabled ? VOIP_G192_RTP : G192; + *sdp_hf_only = 0; + break; + case IVAS_DEC_INPUT_FORMAT_MIME: + *bitstream_format_internal = MIME; + *sdp_hf_only = 0; + break; + case IVAS_DEC_INPUT_FORMAT_RTPDUMP: + assert( is_voip_enabled && "RTP dump only supported in VoIP mode" ); + *bitstream_format_internal = VOIP_RTPDUMP; + *sdp_hf_only = 0; + break; + case IVAS_DEC_INPUT_FORMAT_RTPDUMP_HF: + assert( is_voip_enabled && "RTP dump only supported in VoIP mode" ); + *bitstream_format_internal = VOIP_RTPDUMP; + *sdp_hf_only = 1; + break; + default: + return IVAS_ERR_INVALID_BITSTREAM; + break; } + return IVAS_ERR_OK; +} - /*---------------------------------------------------------------------* - * apa_setup() - * - * Setup APA decoder - *---------------------------------------------------------------------*/ - - static ivas_error apa_setup( - IVAS_DEC_HANDLE hIvasDec, - const bool isInitialized_voip, - const uint16_t nTransportChannels ) - { - uint16_t l_ts; - l_ts = (uint16_t) hIvasDec->st_ivas->hTcBuffer->n_samples_granularity; +/*---------------------------------------------------------------------* + * apa_setup() + * + * Setup APA decoder + *---------------------------------------------------------------------*/ - if ( !isInitialized_voip ) - { - DECODER_CONFIG_HANDLE hDecoderConfig; - uint16_t wss, css; - float startQuality; +static ivas_error apa_setup( + IVAS_DEC_HANDLE hIvasDec, + const bool isInitialized_voip, + const uint16_t nTransportChannels ) +{ + uint16_t l_ts; - startQuality = hIvasDec->tsm_quality; - hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; + l_ts = (uint16_t) hIvasDec->st_ivas->hTcBuffer->n_samples_granularity; - if ( hDecoderConfig->output_Fs == 8000 ) - { - wss = 1; - css = 1; - } - else if ( hDecoderConfig->output_Fs == 16000 ) - { - wss = 2; - css = 1; - } - else if ( hDecoderConfig->output_Fs == 32000 ) - { - wss = 4; - css = 2; - } - else if ( hDecoderConfig->output_Fs == 48000 ) - { - wss = 6; - css = 3; - } - else - { - return IVAS_ERR_INIT_ERROR; - } + if ( !isInitialized_voip ) + { + DECODER_CONFIG_HANDLE hDecoderConfig; + uint16_t wss, css; + float startQuality; - if ( apa_init( &hIvasDec->hTimeScaler, nTransportChannels ) != IVAS_ERR_OK || - apa_set_rate( hIvasDec->hTimeScaler, hDecoderConfig->output_Fs ) != 0 || - apa_set_complexity_options( hIvasDec->hTimeScaler, wss, css ) != 0 || - apa_set_quality( hIvasDec->hTimeScaler, startQuality, 4, 4 ) != 0 || - apa_set_renderer_granularity( hIvasDec->hTimeScaler, l_ts ) != 0 ) - { - return IVAS_ERR_INIT_ERROR; - } + startQuality = hIvasDec->tsm_quality; + hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) - { - if ( apa_set_evs_compat_mode( hIvasDec->hTimeScaler, true ) != 0 ) - { - return IVAS_ERR_INIT_ERROR; - } - } + if ( hDecoderConfig->output_Fs == 8000 ) + { + wss = 1; + css = 1; + } + else if ( hDecoderConfig->output_Fs == 16000 ) + { + wss = 2; + css = 1; + } + else if ( hDecoderConfig->output_Fs == 32000 ) + { + wss = 4; + css = 2; + } + else if ( hDecoderConfig->output_Fs == 48000 ) + { + wss = 6; + css = 3; } else { - if ( apa_reconfigure( hIvasDec->hTimeScaler, nTransportChannels, l_ts ) != 0 ) + return IVAS_ERR_INIT_ERROR; + } + + if ( apa_init( &hIvasDec->hTimeScaler, nTransportChannels ) != IVAS_ERR_OK || + apa_set_rate( hIvasDec->hTimeScaler, hDecoderConfig->output_Fs ) != 0 || + apa_set_complexity_options( hIvasDec->hTimeScaler, wss, css ) != 0 || + apa_set_quality( hIvasDec->hTimeScaler, startQuality, 4, 4 ) != 0 || + apa_set_renderer_granularity( hIvasDec->hTimeScaler, l_ts ) != 0 ) + { + return IVAS_ERR_INIT_ERROR; + } + + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + { + if ( apa_set_evs_compat_mode( hIvasDec->hTimeScaler, true ) != 0 ) { return IVAS_ERR_INIT_ERROR; } } + } + else + { + if ( apa_reconfigure( hIvasDec->hTimeScaler, nTransportChannels, l_ts ) != 0 ) + { + return IVAS_ERR_INIT_ERROR; + } + } - hIvasDec->nTransportChannelsOld = nTransportChannels; + hIvasDec->nTransportChannelsOld = nTransportChannels; - return IVAS_ERR_OK; - } + return IVAS_ERR_OK; +} - /*---------------------------------------------------------------------* - * IVAS_DEC_GetSplitRendBitstreamHeader() - * - * - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_GetSplitRendBitstreamHeader() + * + * + *---------------------------------------------------------------------*/ - ivas_error IVAS_DEC_GetSplitRendBitstreamHeader( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - ISAR_SPLIT_REND_CODEC * pCodec, /* o : pointer to codec setting */ - ISAR_SPLIT_REND_POSE_CORRECTION_MODE * poseCorrection, /* o : pointer to pose correction mode */ - int16_t * pIsar_frame_size_ms, /* o : pointer to ISAR frame size setting */ - int16_t * pCodec_frame_size_ms, /* o : pointer to codec frame size setting */ - int16_t * pLc3plusHighRes /* o : pointer to LC3plus High-Res setting */ - ) +ivas_error IVAS_DEC_GetSplitRendBitstreamHeader( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + ISAR_SPLIT_REND_CODEC *pCodec, /* o : pointer to codec setting */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o : pointer to pose correction mode */ + int16_t *pIsar_frame_size_ms, /* o : pointer to ISAR frame size setting */ + int16_t *pCodec_frame_size_ms, /* o : pointer to codec frame size setting */ + int16_t *pLc3plusHighRes /* o : pointer to LC3plus High-Res setting */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - *pCodec = hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec; - *pCodec_frame_size_ms = hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms; - *poseCorrection = hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode; - *pIsar_frame_size_ms = hIvasDec->st_ivas->hRenderConfig->split_rend_config.isar_frame_size_ms; - *pLc3plusHighRes = hIvasDec->st_ivas->hRenderConfig->split_rend_config.lc3plus_highres; + *pCodec = hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec; + *pCodec_frame_size_ms = hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms; + *poseCorrection = hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode; + *pIsar_frame_size_ms = hIvasDec->st_ivas->hRenderConfig->split_rend_config.isar_frame_size_ms; + *pLc3plusHighRes = hIvasDec->st_ivas->hRenderConfig->split_rend_config.lc3plus_highres; - return IVAS_ERR_OK; - } + return IVAS_ERR_OK; +} - /*---------------------------------------------------------------------* - * IVAS_DEC_GetCldfbSamples() - * - * API function to output CLDFB samples - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * IVAS_DEC_GetCldfbSamples() + * + * API function to output CLDFB samples + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_GetCldfbSamples( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + float *out_real, /* o : buffer for decoded PCM real output in CLDFB domain */ + float *out_imag, /* o : buffer for decoded PCM imag output in CLDFB domain */ + AUDIO_CONFIG *audio_config, /* o : audio configuration */ + int16_t *nOutSamples /* o : number of samples per channel written to output buffer */ +) +{ + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; + int16_t ch, b, slot_idx, num_chs, maxBand, num_samples; - ivas_error IVAS_DEC_GetCldfbSamples( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - float *out_real, /* o : buffer for decoded PCM real output in CLDFB domain */ - float *out_imag, /* o : buffer for decoded PCM imag output in CLDFB domain */ - AUDIO_CONFIG *audio_config, /* o : audio configuration */ - int16_t *nOutSamples /* o : number of samples per channel written to output buffer */ - ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hSplitBinRend == NULL ) { - ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; - int16_t ch, b, slot_idx, num_chs, maxBand, num_samples; - - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hSplitBinRend == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - hSplitBinRend = hIvasDec->st_ivas->hSplitBinRend; - num_samples = 0; + hSplitBinRend = hIvasDec->st_ivas->hSplitBinRend; + num_samples = 0; - if ( hSplitBinRend->hCldfbDataOut != NULL ) + if ( hSplitBinRend->hCldfbDataOut != NULL ) + { + *audio_config = hSplitBinRend->hCldfbDataOut->config; + if ( hSplitBinRend->hCldfbDataOut->config != IVAS_AUDIO_CONFIG_INVALID ) { - *audio_config = hSplitBinRend->hCldfbDataOut->config; - if ( hSplitBinRend->hCldfbDataOut->config != IVAS_AUDIO_CONFIG_INVALID ) - { - num_chs = audioCfg2channels( hSplitBinRend->hCldfbDataOut->config ); - maxBand = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * hIvasDec->st_ivas->hDecoderConfig->output_Fs ) / 48000 ); + num_chs = audioCfg2channels( hSplitBinRend->hCldfbDataOut->config ); + maxBand = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * hIvasDec->st_ivas->hDecoderConfig->output_Fs ) / 48000 ); - for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) + for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) + { + for ( b = 0; b < maxBand; b++ ) { - for ( b = 0; b < maxBand; b++ ) + for ( ch = 0; ch < num_chs; ch++ ) { - for ( ch = 0; ch < num_chs; ch++ ) - { - *out_real++ = hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx][b]; - *out_imag++ = hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx][b]; - } + *out_real++ = hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx][b]; + *out_imag++ = hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx][b]; } } - num_samples = CLDFB_NO_COL_MAX * maxBand; } + num_samples = CLDFB_NO_COL_MAX * maxBand; } - else - { - *audio_config = IVAS_AUDIO_CONFIG_INVALID; - } + } + else + { + *audio_config = IVAS_AUDIO_CONFIG_INVALID; + } - *nOutSamples = num_samples; + *nOutSamples = num_samples; - return IVAS_ERR_OK; - } + return IVAS_ERR_OK; +} - /*---------------------------------------------------------------------* - * pcm_buffer_offset() - * - * - *---------------------------------------------------------------------*/ +/*---------------------------------------------------------------------* + * pcm_buffer_offset() + * + * + *---------------------------------------------------------------------*/ - static void *pcm_buffer_offset( - void *buffer, - const IVAS_DEC_PCM_TYPE pcmType, - const int32_t offset ) +static void *pcm_buffer_offset( + void *buffer, + const IVAS_DEC_PCM_TYPE pcmType, + const int32_t offset ) +{ + switch ( pcmType ) { - switch ( pcmType ) + case IVAS_DEC_PCM_FLOAT: { - case IVAS_DEC_PCM_FLOAT: - { - float *tmpBuf = (float *) buffer; - return (void *) ( tmpBuf + offset ); - } - break; - case IVAS_DEC_PCM_INT16: - { - int16_t *tmpBuf = (int16_t *) buffer; - return (void *) ( tmpBuf + offset ); - } - break; - default: - break; + float *tmpBuf = (float *) buffer; + return (void *) ( tmpBuf + offset ); } - - return NULL; + break; + case IVAS_DEC_PCM_INT16: + { + int16_t *tmpBuf = (int16_t *) buffer; + return (void *) ( tmpBuf + offset ); + } + break; + default: + break; } + return NULL; +} - /*---------------------------------------------------------------------* - * set_pcm_buffer_to_zero() - * - * - *---------------------------------------------------------------------*/ - static ivas_error set_pcm_buffer_to_zero( - void *buffer, - const IVAS_DEC_PCM_TYPE pcmType, - const int16_t nZeroSamples ) - { - ivas_error error; +/*---------------------------------------------------------------------* + * set_pcm_buffer_to_zero() + * + * + *---------------------------------------------------------------------*/ - error = IVAS_ERR_OK; - switch ( pcmType ) - { - case IVAS_DEC_PCM_FLOAT: - set_zero( (float *) buffer, nZeroSamples ); - break; - case IVAS_DEC_PCM_INT16: - set_s( (int16_t *) buffer, 0, nZeroSamples ); - break; - default: - error = IVAS_ERR_INTERNAL; - } +static ivas_error set_pcm_buffer_to_zero( + void *buffer, + const IVAS_DEC_PCM_TYPE pcmType, + const int16_t nZeroSamples ) +{ + ivas_error error; - return error; + error = IVAS_ERR_OK; + switch ( pcmType ) + { + case IVAS_DEC_PCM_FLOAT: + set_zero( (float *) buffer, nZeroSamples ); + break; + case IVAS_DEC_PCM_INT16: + set_s( (int16_t *) buffer, 0, nZeroSamples ); + break; + default: + error = IVAS_ERR_INTERNAL; } + return error; +} - /*---------------------------------------------------------------------* - * pcm_type_API_to_internal() - * - * - *---------------------------------------------------------------------*/ - PCM_RESOLUTION pcm_type_API_to_internal( - const IVAS_DEC_PCM_TYPE pcmType ) - { - PCM_RESOLUTION pcm_resolution; - pcm_resolution = PCM_NOT_KNOW; +/*---------------------------------------------------------------------* + * pcm_type_API_to_internal() + * + * + *---------------------------------------------------------------------*/ - switch ( pcmType ) - { - case IVAS_DEC_PCM_FLOAT: - pcm_resolution = PCM_FLOAT32; - break; - case IVAS_DEC_PCM_INT16: - pcm_resolution = PCM_INT16; - break; - default: - pcm_resolution = PCM_NOT_KNOW; - } +PCM_RESOLUTION pcm_type_API_to_internal( + const IVAS_DEC_PCM_TYPE pcmType ) +{ + PCM_RESOLUTION pcm_resolution; + pcm_resolution = PCM_NOT_KNOW; - return pcm_resolution; + switch ( pcmType ) + { + case IVAS_DEC_PCM_FLOAT: + pcm_resolution = PCM_FLOAT32; + break; + case IVAS_DEC_PCM_INT16: + pcm_resolution = PCM_INT16; + break; + default: + pcm_resolution = PCM_NOT_KNOW; } + return pcm_resolution; +} - /*-------------------------------------------------------------------* - * ivas_create_handle_isar() - * - * Initialize IVAS decoder split-rendering handle - *-------------------------------------------------------------------*/ - static ivas_error ivas_create_handle_isar( - ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE * hSplitBinRend_out /* o : ISAR split binaural rendering handle */ - ) - { - ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; - int16_t i; +/*-------------------------------------------------------------------* + * ivas_create_handle_isar() + * + * Initialize IVAS decoder split-rendering handle + *-------------------------------------------------------------------*/ - if ( ( hSplitBinRend = (ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_WRAPPER ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS decoder handle" ); - } +static ivas_error ivas_create_handle_isar( + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend_out /* o : ISAR split binaural rendering handle */ +) +{ + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; + int16_t i; + + if ( ( hSplitBinRend = (ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_WRAPPER ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS decoder handle" ); + } - isar_init_split_rend_handles( &hSplitBinRend->splitrend ); + isar_init_split_rend_handles( &hSplitBinRend->splitrend ); - hSplitBinRend->hMultiBinTdData = NULL; - for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) - { - hSplitBinRend->hMultiBinCldfbData[i] = NULL; - } - hSplitBinRend->hCldfbDataOut = NULL; - hSplitBinRend->numTdSamplesPerChannelCached = 0; + hSplitBinRend->hMultiBinTdData = NULL; + for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) + { + hSplitBinRend->hMultiBinCldfbData[i] = NULL; + } + hSplitBinRend->hCldfbDataOut = NULL; + hSplitBinRend->numTdSamplesPerChannelCached = 0; - *hSplitBinRend_out = hSplitBinRend; + *hSplitBinRend_out = hSplitBinRend; + + return IVAS_ERR_OK; +} - return IVAS_ERR_OK; - } +/*-------------------------------------------------------------------* + * ivas_destroy_handle_isar() + * + * destroy IVAS decoder split rend handle + *-------------------------------------------------------------------*/ - /*-------------------------------------------------------------------* - * ivas_destroy_handle_isar() - * - * destroy IVAS decoder split rend handle - *-------------------------------------------------------------------*/ +static void ivas_destroy_handle_isar( + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend /* i/o: ISAR split binaural rendering handle */ +) +{ + int16_t i; - static void ivas_destroy_handle_isar( - ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE * hSplitBinRend /* i/o: ISAR split binaural rendering handle */ - ) + if ( *hSplitBinRend != NULL ) { - int16_t i; - - if ( *hSplitBinRend != NULL ) + if ( ( *hSplitBinRend )->hMultiBinTdData != NULL ) { - if ( ( *hSplitBinRend )->hMultiBinTdData != NULL ) - { - ivas_TD_RINGBUF_Close( &( *hSplitBinRend )->hMultiBinTdData ); - } - for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) + ivas_TD_RINGBUF_Close( &( *hSplitBinRend )->hMultiBinTdData ); + } + for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) + { + if ( ( *hSplitBinRend )->hMultiBinCldfbData[i] != NULL ) { - if ( ( *hSplitBinRend )->hMultiBinCldfbData[i] != NULL ) - { - ivas_CLDFB_RINGBUF_Close( &( *hSplitBinRend )->hMultiBinCldfbData[i] ); - } + ivas_CLDFB_RINGBUF_Close( &( *hSplitBinRend )->hMultiBinCldfbData[i] ); } + } - ISAR_PRE_REND_close( &( *hSplitBinRend )->splitrend, NULL ); - - if ( ( *hSplitBinRend )->hCldfbDataOut != NULL ) - { - free( ( *hSplitBinRend )->hCldfbDataOut ); - ( *hSplitBinRend )->hCldfbDataOut = NULL; - } + ISAR_PRE_REND_close( &( *hSplitBinRend )->splitrend, NULL ); - free( ( *hSplitBinRend ) ); - ( *hSplitBinRend ) = NULL; + if ( ( *hSplitBinRend )->hCldfbDataOut != NULL ) + { + free( ( *hSplitBinRend )->hCldfbDataOut ); + ( *hSplitBinRend )->hCldfbDataOut = NULL; } - return; + free( ( *hSplitBinRend ) ); + ( *hSplitBinRend ) = NULL; } + return; +} - /*---------------------------------------------------------------------* - * IVAS_DEC_is_split_rendering_enabled() - * - * - *---------------------------------------------------------------------*/ - /*! r: decoder error code */ - ivas_error IVAS_DEC_is_split_rendering_enabled( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t * isSplitRend /* o : flag to indicate if split rendering is enabled */ - ) - { - Decoder_Struct *st_ivas; +/*---------------------------------------------------------------------* + * IVAS_DEC_is_split_rendering_enabled() + * + * + *---------------------------------------------------------------------*/ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } +/*! r: decoder error code */ +ivas_error IVAS_DEC_is_split_rendering_enabled( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *isSplitRend /* o : flag to indicate if split rendering is enabled */ +) +{ + Decoder_Struct *st_ivas; - st_ivas = hIvasDec->st_ivas; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - *isSplitRend = is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ); + st_ivas = hIvasDec->st_ivas; - return IVAS_ERR_OK; - } + *isSplitRend = is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ); + return IVAS_ERR_OK; +} - /*-------------------------------------------------------------------* - * ivas_dec_reconfig_split_rend() - * - * IVAS decoder split rend reconfig - *-------------------------------------------------------------------*/ - static ivas_error ivas_dec_reconfig_split_rend( - Decoder_Struct * st_ivas /* i : IVAS decoder structure */ - ) - { - ivas_error error; - int16_t cldfb_in_flag, num_ch, ch, isCldfbNeeded, i, pcm_out_flag; - SPLIT_REND_WRAPPER *hSplitRendWrapper; +/*-------------------------------------------------------------------* + * ivas_dec_reconfig_split_rend() + * + * IVAS decoder split rend reconfig + *-------------------------------------------------------------------*/ - hSplitRendWrapper = &st_ivas->hSplitBinRend->splitrend; - pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; - cldfb_in_flag = 0; +static ivas_error ivas_dec_reconfig_split_rend( + Decoder_Struct *st_ivas /* i : IVAS decoder structure */ +) +{ + ivas_error error; + int16_t cldfb_in_flag, num_ch, ch, isCldfbNeeded, i, pcm_out_flag; + SPLIT_REND_WRAPPER *hSplitRendWrapper; + + hSplitRendWrapper = &st_ivas->hSplitBinRend->splitrend; + pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; + cldfb_in_flag = 0; + + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || + st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || + st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) + { + cldfb_in_flag = 1; + } - if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || - st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || - st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || - st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) - { - cldfb_in_flag = 1; - } + ISAR_PRE_REND_GetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &hSplitRendWrapper->multiBinPoseData, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->sr_pose_pred_axis : DEFAULT_AXIS ); - ISAR_PRE_REND_GetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &hSplitRendWrapper->multiBinPoseData, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->sr_pose_pred_axis : DEFAULT_AXIS ); + isCldfbNeeded = 0; - isCldfbNeeded = 0; + if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) || + ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) + { + cldfb_in_flag = 0; + } - if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) || - ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) + if ( st_ivas->renderer_type != RENDERER_DISABLE ) + { + if ( cldfb_in_flag == 0 ) { - cldfb_in_flag = 0; + isCldfbNeeded = 1; } - - if ( st_ivas->renderer_type != RENDERER_DISABLE ) + else if ( st_ivas->hRenderConfig->split_rend_config.codec == ISAR_SPLIT_REND_CODEC_LC3PLUS && cldfb_in_flag ) { - if ( cldfb_in_flag == 0 ) - { - isCldfbNeeded = 1; - } - else if ( st_ivas->hRenderConfig->split_rend_config.codec == ISAR_SPLIT_REND_CODEC_LC3PLUS && cldfb_in_flag ) - { - isCldfbNeeded = 1; - } - else if ( pcm_out_flag && cldfb_in_flag ) - { - isCldfbNeeded = 1; - } + isCldfbNeeded = 1; } - else if ( st_ivas->hDecoderConfig->Opt_non_diegetic_pan ) + else if ( pcm_out_flag && cldfb_in_flag ) { isCldfbNeeded = 1; } + } + else if ( st_ivas->hDecoderConfig->Opt_non_diegetic_pan ) + { + isCldfbNeeded = 1; + } - if ( isCldfbNeeded == 1 && hSplitRendWrapper->hCldfbHandles == NULL ) + if ( isCldfbNeeded == 1 && hSplitRendWrapper->hCldfbHandles == NULL ) + { + if ( ( hSplitRendWrapper->hCldfbHandles = (CLDFB_HANDLES_WRAPPER_HANDLE) malloc( sizeof( CLDFB_HANDLES_WRAPPER ) ) ) == NULL ) { - if ( ( hSplitRendWrapper->hCldfbHandles = (CLDFB_HANDLES_WRAPPER_HANDLE) malloc( sizeof( CLDFB_HANDLES_WRAPPER ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB handles\n" ) ); - } + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB handles\n" ) ); + } - num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; - for ( ch = 0; ch < num_ch; ch++ ) - { - hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL; - } + num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; + for ( ch = 0; ch < num_ch; ch++ ) + { + hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL; + } - num_ch = hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; + num_ch = hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; - for ( ch = 0; ch < num_ch; ch++ ) + for ( ch = 0; ch < num_ch; ch++ ) + { + if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ), CLDFB_ANALYSIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) { - if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ), CLDFB_ANALYSIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not open CLDFB handles\n" ) ); - } + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not open CLDFB handles\n" ) ); } + } - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) { - if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } } - else if ( isCldfbNeeded == 0 && hSplitRendWrapper->hCldfbHandles != NULL ) + } + else if ( isCldfbNeeded == 0 && hSplitRendWrapper->hCldfbHandles != NULL ) + { + num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; + for ( ch = 0; ch < num_ch; ch++ ) { - num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; - for ( ch = 0; ch < num_ch; ch++ ) + if ( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] != NULL ) { - if ( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] != NULL ) - { - deleteCldfb( &hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ); - hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL; - } + deleteCldfb( &hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ); + hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL; } + } - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] != NULL ) { - if ( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] != NULL ) - { - deleteCldfb( &hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ); - hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] = NULL; - } + deleteCldfb( &hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ); + hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] = NULL; } - - free( hSplitRendWrapper->hCldfbHandles ); - hSplitRendWrapper->hCldfbHandles = NULL; } - if ( ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD ) && - ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV || st_ivas->ivas_format != SBA_ISM_FORMAT ) && - !( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) + free( hSplitRendWrapper->hCldfbHandles ); + hSplitRendWrapper->hCldfbHandles = NULL; + } + + if ( ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD ) && + ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV || st_ivas->ivas_format != SBA_ISM_FORMAT ) && + !( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) + { + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) { - for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + if ( st_ivas->hTdRendHandles[i] != NULL ) { - if ( st_ivas->hTdRendHandles[i] != NULL ) - { - st_ivas->hTdRendHandles[i]->HrFiltSet_p = NULL; - ivas_td_binaural_close( &st_ivas->hTdRendHandles[i] ); - } + st_ivas->hTdRendHandles[i]->HrFiltSet_p = NULL; + ivas_td_binaural_close( &st_ivas->hTdRendHandles[i] ); } } - - return IVAS_ERR_OK; } + return IVAS_ERR_OK; +} + - /*-------------------------------------------------------------------* - * ivas_dec_split_rend_cldfb_in() - * - * - *-------------------------------------------------------------------*/ +/*-------------------------------------------------------------------* + * ivas_dec_split_rend_cldfb_in() + * + * + *-------------------------------------------------------------------*/ - static int16_t ivas_dec_split_rend_cldfb_in( - const RENDERER_TYPE renderer_type /* i : renderer type */ - ) +static int16_t ivas_dec_split_rend_cldfb_in( + const RENDERER_TYPE renderer_type /* i : renderer type */ +) +{ + if ( renderer_type == RENDERER_BINAURAL_FASTCONV || + renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || + renderer_type == RENDERER_BINAURAL_PARAMETRIC || + renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) { - if ( renderer_type == RENDERER_BINAURAL_FASTCONV || - renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || - renderer_type == RENDERER_BINAURAL_PARAMETRIC || - renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) - { - return 1; - } - else - { - return 0; - } + return 1; + } + else + { + return 0; } +} - /*-------------------------------------------------------------------* - * ivas_dec_init_split_rend() - * - * IVAS decoder split rendering initialization - *-------------------------------------------------------------------*/ +/*-------------------------------------------------------------------* + * ivas_dec_init_split_rend() + * + * IVAS decoder split rendering initialization + *-------------------------------------------------------------------*/ - static ivas_error ivas_dec_init_split_rend( - Decoder_Struct * st_ivas /* i : IVAS decoder structure */ - ) - { - ivas_error error; - int16_t cldfb_in_flag, pcm_out_flag; - int16_t mixed_td_cldfb_flag; - int16_t i, num_poses; +static ivas_error ivas_dec_init_split_rend( + Decoder_Struct *st_ivas /* i : IVAS decoder structure */ +) +{ + ivas_error error; + int16_t cldfb_in_flag, pcm_out_flag; + int16_t mixed_td_cldfb_flag; + int16_t i, num_poses; - pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; - cldfb_in_flag = 0; + pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; + cldfb_in_flag = 0; - cldfb_in_flag = ivas_dec_split_rend_cldfb_in( st_ivas->renderer_type ); + cldfb_in_flag = ivas_dec_split_rend_cldfb_in( st_ivas->renderer_type ); - ISAR_PRE_REND_GetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->sr_pose_pred_axis : DEFAULT_AXIS ); + ISAR_PRE_REND_GetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->sr_pose_pred_axis : DEFAULT_AXIS ); - num_poses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; - assert( num_poses <= MAX_HEAD_ROT_POSES ); + num_poses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; + assert( num_poses <= MAX_HEAD_ROT_POSES ); - if ( cldfb_in_flag ) - { - for ( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) - { - /* note: this is intra-frame heap memory */ - if ( ( error = ivas_CLDFB_RINGBUF_Open( &st_ivas->hSplitBinRend->hMultiBinCldfbData[i], CLDFB_NO_COL_MAX ) ) != IVAS_ERR_OK ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for split rendering structure" ); - } - } - } - else + if ( cldfb_in_flag ) + { + for ( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) { - if ( ( error = ivas_TD_RINGBUF_Open( &st_ivas->hSplitBinRend->hMultiBinTdData, get_render_frame_size_samples( st_ivas->hDecoderConfig ), num_poses * BINAURAL_CHANNELS ) ) != IVAS_ERR_OK ) + /* note: this is intra-frame heap memory */ + if ( ( error = ivas_CLDFB_RINGBUF_Open( &st_ivas->hSplitBinRend->hMultiBinCldfbData[i], CLDFB_NO_COL_MAX ) ) != IVAS_ERR_OK ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for split rendering structure" ); } } - - if ( cldfb_in_flag == 1 && ( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ) + } + else + { + if ( ( error = ivas_TD_RINGBUF_Open( &st_ivas->hSplitBinRend->hMultiBinTdData, get_render_frame_size_samples( st_ivas->hDecoderConfig ), num_poses * BINAURAL_CHANNELS ) ) != IVAS_ERR_OK ) { - if ( ( st_ivas->hSplitBinRend->hCldfbDataOut = (ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for cldfb data out buffer\n" ) ); - } + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for split rendering structure" ); } + } - mixed_td_cldfb_flag = 0; - if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) || - ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) + if ( cldfb_in_flag == 1 && ( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ) + { + if ( ( st_ivas->hSplitBinRend->hCldfbDataOut = (ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA ) ) ) == NULL ) { - mixed_td_cldfb_flag = 1; + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for cldfb data out buffer\n" ) ); } + } - error = ISAR_PRE_REND_open( &st_ivas->hSplitBinRend->splitrend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hDecoderConfig->output_Fs, cldfb_in_flag, pcm_out_flag, (int16_t) st_ivas->hDecoderConfig->render_num_subframes, mixed_td_cldfb_flag ); - - return error; + mixed_td_cldfb_flag = 0; + if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) || + ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) + { + mixed_td_cldfb_flag = 1; } + error = ISAR_PRE_REND_open( &st_ivas->hSplitBinRend->splitrend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hDecoderConfig->output_Fs, cldfb_in_flag, pcm_out_flag, (int16_t) st_ivas->hDecoderConfig->render_num_subframes, mixed_td_cldfb_flag ); - /*---------------------------------------------------------------------* - * IVAS_DEC_is_split_rendering_coded_out() - * - * Return flag to indicate if split rendering is enabled - *---------------------------------------------------------------------*/ + return error; +} - /*! r: decoder error code */ - ivas_error IVAS_DEC_is_split_rendering_coded_out( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t * isSplitCoded /* o : flag to indicate if split rendering is enabled */ - ) - { - Decoder_Struct *st_ivas; - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } +/*---------------------------------------------------------------------* + * IVAS_DEC_is_split_rendering_coded_out() + * + * Return flag to indicate if split rendering is enabled + *---------------------------------------------------------------------*/ - st_ivas = hIvasDec->st_ivas; +/*! r: decoder error code */ +ivas_error IVAS_DEC_is_split_rendering_coded_out( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *isSplitCoded /* o : flag to indicate if split rendering is enabled */ +) +{ + Decoder_Struct *st_ivas; - *isSplitCoded = 0; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || - ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO && st_ivas->hDecoderConfig->Opt_non_diegetic_pan && st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) - { - *isSplitCoded = 1; - } + st_ivas = hIvasDec->st_ivas; - return IVAS_ERR_OK; + *isSplitCoded = 0; + + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || + ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO && st_ivas->hDecoderConfig->Opt_non_diegetic_pan && st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) + { + *isSplitCoded = 1; } + return IVAS_ERR_OK; +} - /*---------------------------------------------------------------------* - * feedSinglePIorientation( ) - * - * Feed a single orientation PI data to external orientation handle. - *---------------------------------------------------------------------*/ - static ivas_error feedSinglePIorientation( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_QUATERNION * orientation /* i : orientation for this PI type */ - ) - { - int16_t i; - ivas_error error; - Decoder_Struct *st_ivas; - IVAS_QUATERNION invOrientation; +/*---------------------------------------------------------------------* + * feedSinglePIorientation( ) + * + * Feed a single orientation PI data to external orientation handle. + *---------------------------------------------------------------------*/ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } +static ivas_error feedSinglePIorientation( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_QUATERNION *orientation /* i : orientation for this PI type */ +) +{ + int16_t i; + ivas_error error; + Decoder_Struct *st_ivas; + IVAS_QUATERNION invOrientation; - st_ivas = hIvasDec->st_ivas; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( !st_ivas->hExtOrientationData ) - { - if ( ( error = ivas_external_orientation_open( &( st_ivas->hExtOrientationData ), st_ivas->hDecoderConfig->render_num_subframes ) ) != IVAS_ERR_OK ) - { - return error; - } - } + st_ivas = hIvasDec->st_ivas; - if ( !st_ivas->hCombinedOrientationData ) + if ( !st_ivas->hExtOrientationData ) + { + if ( ( error = ivas_external_orientation_open( &( st_ivas->hExtOrientationData ), st_ivas->hDecoderConfig->render_num_subframes ) ) != IVAS_ERR_OK ) { - if ( ( error = ivas_combined_orientation_open( &( st_ivas->hCombinedOrientationData ), st_ivas->hDecoderConfig->output_Fs, st_ivas->hDecoderConfig->render_num_subframes ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } + } - QuaternionInverse( *orientation, &invOrientation ); - - /* use the new PI orientation or the previously saved orientation in processing */ - for ( i = 0; i < st_ivas->hExtOrientationData->num_subframes; i++ ) + if ( !st_ivas->hCombinedOrientationData ) + { + if ( ( error = ivas_combined_orientation_open( &( st_ivas->hCombinedOrientationData ), st_ivas->hDecoderConfig->output_Fs, st_ivas->hDecoderConfig->render_num_subframes ) ) != IVAS_ERR_OK ) { - QuaternionProduct( st_ivas->hExtOrientationData->Quaternions[i], invOrientation, - &st_ivas->hExtOrientationData->Quaternions[i] ); - st_ivas->hExtOrientationData->enableExternalOrientation[i] = true; + return error; } + } - hIvasDec->updateOrientation = true; + QuaternionInverse( *orientation, &invOrientation ); - return IVAS_ERR_OK; + /* use the new PI orientation or the previously saved orientation in processing */ + for ( i = 0; i < st_ivas->hExtOrientationData->num_subframes; i++ ) + { + QuaternionProduct( st_ivas->hExtOrientationData->Quaternions[i], invOrientation, + &st_ivas->hExtOrientationData->Quaternions[i] ); + st_ivas->hExtOrientationData->enableExternalOrientation[i] = true; } + hIvasDec->updateOrientation = true; - /*---------------------------------------------------------------------* - * setDiegeticInput( ) - * - * Set isDiegeticInput flag for combined orientation handle based on PI data. - *---------------------------------------------------------------------*/ + return IVAS_ERR_OK; +} - static void setDiegeticInputPI( - Decoder_Struct * st_ivas, /* i/o: IVAS decoder handle */ - const bool *diegeticPIValues /* i : diegetic values for the input stream */ - ) - { - int16_t i; - if ( st_ivas->hCombinedOrientationData != NULL ) - { - for ( i = 0; i < ( 1 + IVAS_MAX_NUM_OBJECTS ); i++ ) - { - st_ivas->hCombinedOrientationData->isDiegeticInputPI[i] = diegeticPIValues[i]; - } +/*---------------------------------------------------------------------* + * setDiegeticInput( ) + * + * Set isDiegeticInput flag for combined orientation handle based on PI data. + *---------------------------------------------------------------------*/ - st_ivas->hCombinedOrientationData->isDiegeticInputPISet = true; +static void setDiegeticInputPI( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const bool *diegeticPIValues /* i : diegetic values for the input stream */ +) +{ + int16_t i; + + if ( st_ivas->hCombinedOrientationData != NULL ) + { + for ( i = 0; i < ( 1 + IVAS_MAX_NUM_OBJECTS ); i++ ) + { + st_ivas->hCombinedOrientationData->isDiegeticInputPI[i] = diegeticPIValues[i]; } - return; + st_ivas->hCombinedOrientationData->isDiegeticInputPISet = true; } + return; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_FeedPiDataToDecoder( ) + * + * + *---------------------------------------------------------------------*/ - /*---------------------------------------------------------------------* - * IVAS_DEC_FeedPiDataToDecoder( ) - * - * - *---------------------------------------------------------------------*/ +ivas_error IVAS_DEC_FeedPiDataToDecoder( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_PIDATA_TS *piData, /* i : PI data received in rtp packet */ + uint32_t numPiData /* i : number of PI data received in rtp packet */ +) +{ + uint32_t i; + Decoder_Struct *st_ivas; + ivas_error error = IVAS_ERR_OK; - ivas_error IVAS_DEC_FeedPiDataToDecoder( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_PIDATA_TS * piData, /* i : PI data received in rtp packet */ - uint32_t numPiData /* i : number of PI data received in rtp packet */ - ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { - uint32_t i; - Decoder_Struct *st_ivas; - ivas_error error = IVAS_ERR_OK; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + st_ivas = hIvasDec->st_ivas; - st_ivas = hIvasDec->st_ivas; + for ( i = 0; i < numPiData; i++ ) + { + uint32_t piDataType = piData->data.noPiData.piDataType; - for ( i = 0; i < numPiData; i++ ) + switch ( piDataType ) { - uint32_t piDataType = piData->data.noPiData.piDataType; - - switch ( piDataType ) + case IVAS_PI_SCENE_ORIENTATION: { - case IVAS_PI_SCENE_ORIENTATION: - { - IVAS_QUATERNION *quat = &piData->data.scene.orientation; + IVAS_QUATERNION *quat = &piData->data.scene.orientation; #ifdef DEBUGGING - fprintf( stdout, "PI_SCENE_ORIENTATION : %f, %f, %f, %f\n", quat->w, quat->x, quat->y, quat->z ); + fprintf( stdout, "PI_SCENE_ORIENTATION : %f, %f, %f, %f\n", quat->w, quat->x, quat->y, quat->z ); #endif - error = feedSinglePIorientation( hIvasDec, quat ); - } - break; + error = feedSinglePIorientation( hIvasDec, quat ); + } + break; - case IVAS_PI_DEVICE_ORIENTATION_COMPENSATED: - { - IVAS_QUATERNION *quat = &piData->data.deviceCompensated.orientation; + case IVAS_PI_DEVICE_ORIENTATION_COMPENSATED: + { + IVAS_QUATERNION *quat = &piData->data.deviceCompensated.orientation; #ifdef DEBUGGING - fprintf( stdout, "PI_DEVICE_ORIENTATION : %f, %f, %f, %f\n", quat->w, quat->x, quat->y, quat->z ); + fprintf( stdout, "PI_DEVICE_ORIENTATION : %f, %f, %f, %f\n", quat->w, quat->x, quat->y, quat->z ); #endif - error = feedSinglePIorientation( hIvasDec, quat ); - } - break; + error = feedSinglePIorientation( hIvasDec, quat ); + } + break; - case IVAS_PI_ACOUSTIC_ENVIRONMENT: - { - uint16_t aeid = piData->data.acousticEnv.aeid; + case IVAS_PI_ACOUSTIC_ENVIRONMENT: + { + uint16_t aeid = piData->data.acousticEnv.aeid; #ifdef DEBUGGING - fprintf( stdout, "PI_ACOUSTIC_ENVIRONMENT : AEID : %d\n", aeid ); + fprintf( stdout, "PI_ACOUSTIC_ENVIRONMENT : AEID : %d\n", aeid ); #endif - if ( piData->data.acousticEnv.availLateReverb && st_ivas->hRenderConfig != NULL && aeid != st_ivas->hRenderConfig->roomAcoustics.aeID ) - { - error = feedAcousticEnvPI( hIvasDec, piData->data.acousticEnv ); - } + if ( piData->data.acousticEnv.availLateReverb && st_ivas->hRenderConfig != NULL && aeid != st_ivas->hRenderConfig->roomAcoustics.aeID ) + { + error = feedAcousticEnvPI( hIvasDec, piData->data.acousticEnv ); } - break; + } + break; - case IVAS_PI_DIEGETIC_TYPE: - { + case IVAS_PI_DIEGETIC_TYPE: + { #ifdef DEBUGGING - fprintf( stdout, "PI_DIEGETIC_TYPE : %d, %d, %d, %d, %d\n", piData->data.digeticIndicator.isDiegetic[0], piData->data.digeticIndicator.isDiegetic[1], piData->data.digeticIndicator.isDiegetic[2], piData->data.digeticIndicator.isDiegetic[3], piData->data.digeticIndicator.isDiegetic[4] ); + fprintf( stdout, "PI_DIEGETIC_TYPE : %d, %d, %d, %d, %d\n", piData->data.digeticIndicator.isDiegetic[0], piData->data.digeticIndicator.isDiegetic[1], piData->data.digeticIndicator.isDiegetic[2], piData->data.digeticIndicator.isDiegetic[3], piData->data.digeticIndicator.isDiegetic[4] ); #endif - setDiegeticInputPI( st_ivas, piData->data.digeticIndicator.isDiegetic ); - } - break; - - default: - { - /* NOT HANDLED PI DATA - DO NOTHING */ - } - break; + setDiegeticInputPI( st_ivas, piData->data.digeticIndicator.isDiegetic ); } + break; - if ( error != IVAS_ERR_OK ) + default: { - return error; + /* NOT HANDLED PI DATA - DO NOTHING */ } + break; + } - piData++; + if ( error != IVAS_ERR_OK ) + { + return error; } - return IVAS_ERR_OK; + piData++; } + + return IVAS_ERR_OK; +} -- GitLab From c3478cf352940f4b56d7c660c7eb79c0dfa23fa3 Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 24 Mar 2026 18:42:26 +0100 Subject: [PATCH 3/9] fix --- apps/decoder.c | 34 ++++++++++++++++++++--- lib_com/options.h | 2 +- lib_dec/ivas_init_dec.c | 60 ++++++++++++++++++++++++++++++++--------- lib_dec/lib_dec.c | 1 + 4 files changed, 80 insertions(+), 17 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index f4beee614..51fcaaead 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -176,14 +176,22 @@ typedef struct static bool parseCmdlIVAS_dec( int16_t argc, char **argv, DecArguments *arg ); static void usage_dec( void ); static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtfBinary, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); +#ifdef FIX_FMSW_DEC +static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtf, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE *phIvasDec, int16_t *pcmBuf ); +#else static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtf, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_RENDER_CONFIG_DATA *renderConfig, IVAS_DEC_HANDLE *phIvasDec, int16_t *pcmBuf ); +#endif static ivas_error load_hrtf_from_file( IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtfBinary, IVAS_DEC_HANDLE hIvasDec, const IVAS_AUDIO_CONFIG OutputConfig, const int32_t output_Fs ); #ifdef DEBUGGING static ivas_error printBitstreamInfoVoip( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HANDLE hIvasDec ); static int16_t app_own_random( int16_t *seed ); #endif static void do_object_editing( IVAS_EDITABLE_PARAMETERS *editableParameters, ObjectEditFileReader *objectEditFileReader ); +#ifdef FIX_FMSW_DEC +static ivas_error restartDecoder( IVAS_DEC_HANDLE *phIvasDec, const IVAS_DEC_MODE decMode, DecArguments *arg ); +#else static ivas_error restartDecoder( IVAS_DEC_HANDLE *phIvasDec, const IVAS_DEC_MODE decMode, DecArguments *arg, IVAS_RENDER_CONFIG_DATA *renderConfig, IVAS_CUSTOM_LS_DATA *hLsCustomData ); +#endif /*------------------------------------------------------------------------------------------* @@ -775,7 +783,11 @@ int main( if ( arg.voipMode ) { +#ifdef FIX_FMSW_DEC + error = decodeVoIP( arg, hBsReader, &hHrtfBinary, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, objectEditFileReader, &splitRendBits, &hIvasDec, pcmBuf ); +#else error = decodeVoIP( arg, hBsReader, &hHrtfBinary, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, objectEditFileReader, &splitRendBits, &renderConfig, &hIvasDec, pcmBuf ); +#endif } else { @@ -3165,7 +3177,9 @@ static ivas_error decodeVoIP( Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, +#ifndef FIX_FMSW_DEC IVAS_RENDER_CONFIG_DATA *renderConfig, +#endif IVAS_DEC_HANDLE *phIvasDec, int16_t *pcmBuf ) { @@ -3357,6 +3371,9 @@ static ivas_error decodeVoIP( if ( ivasRtp.restartNeeded ) { IVAS_DEC_MODE newDecModeInPacket = ( ivasRtp.codecId == IVAS_RTP_EVS ) ? IVAS_DEC_MODE_EVS : IVAS_DEC_MODE_IVAS; +#ifdef FIX_FMSW_DEC + if ( ( error = restartDecoder( &hIvasDec, newDecModeInPacket, &arg ) ) != IVAS_ERR_OK ) +#else if ( ( error = restartDecoder( &hIvasDec, newDecModeInPacket, @@ -3364,6 +3381,7 @@ static ivas_error decodeVoIP( renderConfig, NULL /* ToDo : Provide LS Custom Data */ ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nFailed to restart decoder from %d to %d\n", arg.decMode, newDecModeInPacket ); goto cleanup; @@ -3609,6 +3627,9 @@ static ivas_error decodeVoIP( } IVAS_DEC_MODE newDecModeInPacket = ( tempBsFormat == IVAS_DEC_BS_MONO ) ? IVAS_DEC_MODE_EVS : IVAS_DEC_MODE_IVAS; +#ifdef FIX_FMSW_DEC + if ( ( error = restartDecoder( &hIvasDec, newDecModeInPacket, &arg ) ) != IVAS_ERR_OK ) +#else if ( ( error = restartDecoder( &hIvasDec, newDecModeInPacket, @@ -3616,6 +3637,7 @@ static ivas_error decodeVoIP( NULL, /* ToDo : Provide rendererConfig */ NULL /* ToDo : Provide LS Custom Data */ ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nFailed to restart decoder\n" ); goto cleanup; @@ -4318,9 +4340,13 @@ static ivas_error load_hrtf_from_file( static ivas_error restartDecoder( IVAS_DEC_HANDLE *phIvasDec, const IVAS_DEC_MODE decMode, - DecArguments *arg, + DecArguments *arg +#ifndef FIX_FMSW_DEC + , IVAS_RENDER_CONFIG_DATA *renderConfig, - IVAS_CUSTOM_LS_DATA *hLsCustomData ) + IVAS_CUSTOM_LS_DATA *hLsCustomData +#endif +) { ivas_error error = IVAS_ERR_OK; IVAS_DEC_HANDLE hIvasDec; @@ -4384,7 +4410,7 @@ static ivas_error restartDecoder( goto cleanup; } } -#endif + /* ISAR frame size is set from command line, not renderer config file. * This will be ignored if output format is not split rendering. */ if ( renderConfig != NULL ) @@ -4409,7 +4435,7 @@ static ivas_error restartDecoder( goto cleanup; } } - +#endif return IVAS_ERR_OK; cleanup: diff --git a/lib_com/options.h b/lib_com/options.h index df79a0cf3..a44133370 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -167,9 +167,9 @@ /* #################### Start NON-BE switches ############################ */ /* any switch which is non-be wrt. TS 26.258 V3.0 */ -#define FIX_FMSW_DEC /* float issue 1542: fix JBM issue in format switching */ #define FIX_1543_MID_LSF_BITS /* VA: float issue 1543: Resolve "MSAN: use-of-uninitialized-value in lib_enc/lsf_enc.c:262:5 for EVS encoder" */ +#define FIX_FMSW_DEC /* float issue 1542: fix JBM issue in format switching */ /* ##################### End NON-BE switches ########################### */ diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 2c330c20b..0830398bd 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1277,7 +1277,11 @@ ivas_error ivas_init_decoder_front( * Allocate and initialize Custom loudspeaker layout handle *--------------------------------------------------------------------*/ +#ifdef FIX_FMSW_DEC + if ( st_ivas->hDecoderConfig->Opt_LsCustom && st_ivas->hLsSetupCustom == NULL ) +#else if ( st_ivas->hDecoderConfig->Opt_LsCustom ) +#endif { if ( ( error = ivas_ls_custom_open( &( st_ivas->hLsSetupCustom ) ) ) != IVAS_ERR_OK ) { @@ -1289,7 +1293,11 @@ ivas_error ivas_init_decoder_front( * Allocate and initialize Head-Tracking handle *--------------------------------------------------------------------*/ +#ifdef FIX_FMSW_DEC + if ( st_ivas->hDecoderConfig->Opt_Headrotation && st_ivas->hHeadTrackData == NULL ) +#else if ( st_ivas->hDecoderConfig->Opt_Headrotation ) +#endif { if ( ( error = ivas_headTrack_open( &( st_ivas->hHeadTrackData ) ) ) != IVAS_ERR_OK ) { @@ -1305,7 +1313,11 @@ ivas_error ivas_init_decoder_front( * Allocate and initialize external orientation handle *--------------------------------------------------------------------*/ +#ifdef FIX_FMSW_DEC + if ( st_ivas->hDecoderConfig->Opt_ExternalOrientation && st_ivas->hExtOrientationData == NULL ) +#else if ( st_ivas->hDecoderConfig->Opt_ExternalOrientation ) +#endif { if ( ( error = ivas_external_orientation_open( &( st_ivas->hExtOrientationData ), st_ivas->hDecoderConfig->render_num_subframes ) ) != IVAS_ERR_OK ) { @@ -1317,7 +1329,11 @@ ivas_error ivas_init_decoder_front( * Allocate and initialize combined orientation handle *--------------------------------------------------------------------*/ +#ifdef FIX_FMSW_DEC + if ( ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) && st_ivas->hCombinedOrientationData == NULL ) +#else if ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) +#endif { if ( ( error = ivas_combined_orientation_open( &( st_ivas->hCombinedOrientationData ), st_ivas->hDecoderConfig->output_Fs, st_ivas->hDecoderConfig->render_num_subframes ) ) != IVAS_ERR_OK ) { @@ -1329,8 +1345,14 @@ ivas_error ivas_init_decoder_front( * Allocate and initialize Binaural Renderer configuration handle *--------------------------------------------------------------------*/ +#ifdef FIX_FMSW_DEC + if ( ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || + ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO && st_ivas->hDecoderConfig->Opt_non_diegetic_pan ) ) && + st_ivas->hRenderConfig == NULL ) +#else if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO && st_ivas->hDecoderConfig->Opt_non_diegetic_pan ) ) +#endif { if ( ( error = ivas_render_config_open( &( st_ivas->hRenderConfig ) ) ) != IVAS_ERR_OK ) { @@ -2791,14 +2813,21 @@ void ivas_initialize_handles_dec( st_ivas->hMasaIsmData = NULL; st_ivas->hSbaIsmData = NULL; - st_ivas->hHeadTrackData = NULL; - st_ivas->hHrtfTD = NULL; - st_ivas->hLsSetupCustom = NULL; - st_ivas->hRenderConfig = NULL; - st_ivas->hExtOrientationData = NULL; - st_ivas->hCombinedOrientationData = NULL; - st_ivas->acousticEnvironmentsCount = 0; - st_ivas->pAcousticEnvironments = NULL; +#ifdef FIX_FMSW_DEC + if ( st_ivas->restartNeeded == 0 ) + { +#endif + st_ivas->hHeadTrackData = NULL; + st_ivas->hHrtfTD = NULL; + st_ivas->hLsSetupCustom = NULL; + st_ivas->hRenderConfig = NULL; + st_ivas->hExtOrientationData = NULL; + st_ivas->hCombinedOrientationData = NULL; + st_ivas->acousticEnvironmentsCount = 0; + st_ivas->pAcousticEnvironments = NULL; +#ifdef FIX_FMSW_DEC + } +#endif st_ivas->hSplitBinRend = NULL; for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) @@ -2966,12 +2995,19 @@ void ivas_destroy_dec( /* LS config converter handle */ ivas_ls_setup_conversion_close( &st_ivas->hLsSetUpConversion ); - /* Custom LS configuration handle */ - if ( st_ivas->hLsSetupCustom != NULL ) +#ifdef FIX_FMSW_DEC + if ( st_ivas->restartNeeded == 0 ) { - free( st_ivas->hLsSetupCustom ); - st_ivas->hLsSetupCustom = NULL; +#endif + /* Custom LS configuration handle */ + if ( st_ivas->hLsSetupCustom != NULL ) + { + free( st_ivas->hLsSetupCustom ); + st_ivas->hLsSetupCustom = NULL; + } +#ifdef FIX_FMSW_DEC } +#endif /* Mono downmix structure */ ivas_mono_dmx_renderer_close( &st_ivas->hMonoDmxRenderer ); diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index d5d77dfea..f6160240c 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -211,6 +211,7 @@ ivas_error IVAS_DEC_Open( { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for Decoder config structure" ); } + hIvasDec->st_ivas->restartNeeded = 0; #ifdef FIX_FMSW_DEC } #endif -- GitLab From 9a2955a104cebd6713b7551aab74f3cb3c90093d Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 24 Mar 2026 19:09:14 +0100 Subject: [PATCH 4/9] fix --- apps/decoder.c | 6 ++---- lib_com/ivas_prot.h | 4 ++++ lib_dec/ivas_init_dec.c | 14 +++++++++++--- lib_dec/lib_dec.c | 32 ++++++++++++++++---------------- 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 51fcaaead..01930e04b 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -4375,9 +4375,7 @@ static ivas_error restartDecoder( IVAS_AUDIO_CONFIG outputConfig = ( decMode == IVAS_DEC_MODE_IVAS ) ? arg->outputConfig : IVAS_AUDIO_CONFIG_MONO; -#ifdef FIX_FMSW_DEC - // the calling of following 3 functions could be avoided as well -#endif + /* thought not needed for configuration of parameters, it is needed to initilize the decoder */ if ( ( error = IVAS_DEC_Configure( hIvasDec, arg->output_Fs, outputConfig, arg->render_num_subframes, arg->customLsOutputEnabled, arg->hrtfReaderEnabled, arg->enableHeadRotation, arg->enableExternalOrientation, arg->orientation_tracking, arg->renderConfigEnabled, arg->roomSize, arg->non_diegetic_pan_enabled, arg->non_diegetic_pan_gain, arg->dpidEnabled, aeID, arg->objEditEnabled, arg->delayCompensationEnabled ) ) != IVAS_ERR_OK ) @@ -4386,6 +4384,7 @@ static ivas_error restartDecoder( goto cleanup; } +#ifndef FIX_FMSW_DEC if ( arg->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { if ( ( error = IVAS_DEC_EnableSplitRendering( hIvasDec ) ) != IVAS_ERR_OK ) @@ -4401,7 +4400,6 @@ static ivas_error restartDecoder( goto cleanup; } -#ifndef FIX_FMSW_DEC if ( arg->voipMode ) { if ( ( error = IVAS_DEC_EnableVoIP( hIvasDec, 60, arg->inputFormat ) ) != IVAS_ERR_OK ) diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 3201fd15b..358d6535a 100755 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -434,7 +434,11 @@ void destroy_core_dec( ); void ivas_destroy_dec( +#ifdef FIX_FMSW_DEC + Decoder_Struct **st_ivas /* i/o: IVAS decoder structure */ +#else Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +#endif ); void ivas_initialize_handles_dec( diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 0830398bd..3e92768b5 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -2855,10 +2855,17 @@ void ivas_initialize_handles_dec( *-------------------------------------------------------------------------*/ void ivas_destroy_dec( +#ifdef FIX_FMSW_DEC + Decoder_Struct **st_ivas_out /* i/o: IVAS decoder handle */ +#else Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */ +#endif ) { int16_t i; +#ifdef FIX_FMSW_DEC + Decoder_Struct *st_ivas = *st_ivas_out; +#endif /* CLDFB handles */ for ( i = 0; i < MAX_INTERN_CHANNELS; i++ ) @@ -3090,10 +3097,11 @@ void ivas_destroy_dec( #ifdef FIX_FMSW_DEC if ( st_ivas->restartNeeded == 0 ) { -#endif - free( st_ivas ); -#ifdef FIX_FMSW_DEC + free( *st_ivas_out ); + *st_ivas_out = NULL; } +#else + free( st_ivas ); #endif return; diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index f6160240c..a166897c4 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -154,6 +154,8 @@ ivas_error IVAS_DEC_Open( if ( ( *phIvasDec ) != NULL && ( *phIvasDec )->st_ivas != NULL && ( *phIvasDec )->st_ivas->restartNeeded != 0 ) { hIvasDec = *phIvasDec; + + st_ivas = hIvasDec->st_ivas; } else { @@ -211,24 +213,18 @@ ivas_error IVAS_DEC_Open( { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for Decoder config structure" ); } - hIvasDec->st_ivas->restartNeeded = 0; -#ifdef FIX_FMSW_DEC - } -#endif - /*-----------------------------------------------------------------* - * Initialize IVAS-codec decoder state - *-----------------------------------------------------------------*/ - - st_ivas = hIvasDec->st_ivas; + /*-----------------------------------------------------------------* + * Initialize IVAS-codec decoder state + *-----------------------------------------------------------------*/ + + st_ivas = hIvasDec->st_ivas; + + /* initialize Decoder Config. handle */ + init_decoder_config( hIvasDec->st_ivas->hDecoderConfig ); - /* initialize Decoder Config. handle */ -#ifdef FIX_FMSW_DEC - if ( st_ivas->restartNeeded == 0 ) - { -#endif - init_decoder_config( hIvasDec->st_ivas->hDecoderConfig ); #ifdef FIX_FMSW_DEC + hIvasDec->st_ivas->restartNeeded = 0; } #endif @@ -371,6 +367,9 @@ void IVAS_DEC_Close( ivas_destroy_handle_isar( &( *phIvasDec )->st_ivas->hSplitBinRend ); /* destroy IVAS decoder handles */ +#ifdef FIX_FMSW_DEC + ivas_destroy_dec( &( *phIvasDec )->st_ivas ); +#else ivas_destroy_dec( ( *phIvasDec )->st_ivas ); #ifdef FIX_FMSW_DEC if ( ( *phIvasDec )->st_ivas->restartNeeded == 0 ) @@ -379,11 +378,12 @@ void IVAS_DEC_Close( ( *phIvasDec )->st_ivas = NULL; #ifdef FIX_FMSW_DEC } +#endif #endif } #ifdef FIX_FMSW_DEC - if ( ( *phIvasDec )->st_ivas->restartNeeded == 0 ) + if ( ( *phIvasDec )->st_ivas == NULL || ( *phIvasDec )->st_ivas->restartNeeded == 0 ) { #endif apa_exit( &( *phIvasDec )->hTimeScaler ); -- GitLab From 828b2dbbcbd8991b3af82119717f23a4c000f85a Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 24 Mar 2026 19:12:52 +0100 Subject: [PATCH 5/9] clang-format --- lib_dec/lib_dec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index a166897c4..7ba049791 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -217,14 +217,14 @@ ivas_error IVAS_DEC_Open( /*-----------------------------------------------------------------* * Initialize IVAS-codec decoder state *-----------------------------------------------------------------*/ - + st_ivas = hIvasDec->st_ivas; - + /* initialize Decoder Config. handle */ - init_decoder_config( hIvasDec->st_ivas->hDecoderConfig ); + init_decoder_config( hIvasDec->st_ivas->hDecoderConfig ); #ifdef FIX_FMSW_DEC - hIvasDec->st_ivas->restartNeeded = 0; + hIvasDec->st_ivas->restartNeeded = 0; } #endif -- GitLab From aaec1abfa74a91a62453163f5283b7059476f411 Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 24 Mar 2026 20:09:47 +0100 Subject: [PATCH 6/9] fix: avoid restart in the first frame --- apps/decoder.c | 3 +-- lib_dec/ivas_init_dec.c | 28 ++++++++++++++++++---------- lib_util/ivas_rtp_api.h | 3 +++ lib_util/ivas_rtp_file.c | 16 ++++++++++------ 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 01930e04b..8736af51d 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -4371,11 +4371,11 @@ static ivas_error restartDecoder( hIvasDec = *phIvasDec; +#ifndef FIX_FMSW_DEC uint16_t aeID = arg->aeSequence.count > 0 ? arg->aeSequence.pID[0] : IVAS_DEFAULT_AEID; IVAS_AUDIO_CONFIG outputConfig = ( decMode == IVAS_DEC_MODE_IVAS ) ? arg->outputConfig : IVAS_AUDIO_CONFIG_MONO; - /* thought not needed for configuration of parameters, it is needed to initilize the decoder */ if ( ( error = IVAS_DEC_Configure( hIvasDec, arg->output_Fs, outputConfig, arg->render_num_subframes, arg->customLsOutputEnabled, arg->hrtfReaderEnabled, arg->enableHeadRotation, arg->enableExternalOrientation, arg->orientation_tracking, arg->renderConfigEnabled, arg->roomSize, arg->non_diegetic_pan_enabled, arg->non_diegetic_pan_gain, arg->dpidEnabled, aeID, arg->objEditEnabled, arg->delayCompensationEnabled ) ) != IVAS_ERR_OK ) @@ -4384,7 +4384,6 @@ static ivas_error restartDecoder( goto cleanup; } -#ifndef FIX_FMSW_DEC if ( arg->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { if ( ( error = IVAS_DEC_EnableSplitRendering( hIvasDec ) ) != IVAS_ERR_OK ) diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 3e92768b5..94027dc1d 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -3051,20 +3051,20 @@ void ivas_destroy_dec( /* HRTF statistics */ ivas_HRTF_statistics_binary_close( &st_ivas->hHrtfStatistics ); - /* Config. Renderer */ - ivas_render_config_close( &( st_ivas->hRenderConfig ) ); - - /* Acoustic environments */ - if ( st_ivas->pAcousticEnvironments != NULL ) - { - free( st_ivas->pAcousticEnvironments ); - st_ivas->pAcousticEnvironments = NULL; - } - #ifdef FIX_FMSW_DEC if ( st_ivas->restartNeeded == 0 ) { #endif + /* Config. Renderer */ + ivas_render_config_close( &( st_ivas->hRenderConfig ) ); + + /* Acoustic environments */ + if ( st_ivas->pAcousticEnvironments != NULL ) + { + free( st_ivas->pAcousticEnvironments ); + st_ivas->pAcousticEnvironments = NULL; + } + /* Limiter struct */ ivas_limiter_close( &( st_ivas->hLimiter ) ); @@ -3076,6 +3076,14 @@ void ivas_destroy_dec( } #ifdef FIX_FMSW_DEC } + else + { + /* resets in case of format switching */ + st_ivas->nchan_ism = 0; + st_ivas->ism_mode = ISM_MODE_NONE; + st_ivas->mc_mode = MC_MODE_NONE; + st_ivas->sba_dirac_stereo_flag = 0; + } #endif /* TC buffer structure */ diff --git a/lib_util/ivas_rtp_api.h b/lib_util/ivas_rtp_api.h index 6b23bd04e..0b2731ed3 100644 --- a/lib_util/ivas_rtp_api.h +++ b/lib_util/ivas_rtp_api.h @@ -82,6 +82,9 @@ /* IVAS Codec Types */ typedef enum { +#ifdef FIX_FMSW_DEC + IVAS_RTP_UNDEF, /* undefined = Codec Type not set yet */ +#endif IVAS_RTP_EVS, /* EVS */ IVAS_RTP_IVAS /* IVAS */ } IVAS_RTP_CODEC; diff --git a/lib_util/ivas_rtp_file.c b/lib_util/ivas_rtp_file.c index 35733681c..c520c1439 100644 --- a/lib_util/ivas_rtp_file.c +++ b/lib_util/ivas_rtp_file.c @@ -1041,15 +1041,19 @@ ivas_error IVAS_RTP_ReadNextFrame( } else { +#ifdef FIX_FMSW_DEC + if ( ( codecId != IVAS_RTP_UNDEF ) && ( ( rtp->codecId != codecId ) || ( codecId == IVAS_RTP_EVS && ( rtp->isAMRWB_IOmode != isAMRWB_IOmode ) ) ) ) +#else rtp->restartNeeded = ( rtp->codecId != codecId ) || ( codecId == IVAS_RTP_EVS && ( rtp->isAMRWB_IOmode != isAMRWB_IOmode ) ); +#endif - if ( rtp->restartNeeded ) - { - fprintf( stdout, "\nRTP packet codec changed %s -> %s\n", - ( rtp->codecId == IVAS_RTP_EVS ) ? ( rtp->isAMRWB_IOmode ? "AMRWB_IO" : "EVS" ) : "IVAS", - ( codecId == IVAS_RTP_EVS ) ? ( isAMRWB_IOmode ? "AMRWB_IO" : "EVS" ) : "IVAS" ); - } + if ( rtp->restartNeeded ) + { + fprintf( stdout, "\nRTP packet codec changed %s -> %s\n", + ( rtp->codecId == IVAS_RTP_EVS ) ? ( rtp->isAMRWB_IOmode ? "AMRWB_IO" : "EVS" ) : "IVAS", + ( codecId == IVAS_RTP_EVS ) ? ( isAMRWB_IOmode ? "AMRWB_IO" : "EVS" ) : "IVAS" ); + } rtp->codecId = codecId; rtp->isAMRWB_IOmode = isAMRWB_IOmode; -- GitLab From 52b40130f30692b954e70314afaa1355393308c4 Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 24 Mar 2026 20:13:09 +0100 Subject: [PATCH 7/9] clang-format --- lib_dec/ivas_init_dec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 94027dc1d..afbc72458 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -3057,14 +3057,14 @@ void ivas_destroy_dec( #endif /* Config. Renderer */ ivas_render_config_close( &( st_ivas->hRenderConfig ) ); - + /* Acoustic environments */ if ( st_ivas->pAcousticEnvironments != NULL ) { free( st_ivas->pAcousticEnvironments ); st_ivas->pAcousticEnvironments = NULL; } - + /* Limiter struct */ ivas_limiter_close( &( st_ivas->hLimiter ) ); -- GitLab From 8db9043fd9c1959b844da4abfd9093d3ffafa8d2 Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 25 Mar 2026 08:20:14 +0100 Subject: [PATCH 8/9] fix build --- apps/decoder.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/decoder.c b/apps/decoder.c index 8736af51d..c25a282e1 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -4349,7 +4349,9 @@ static ivas_error restartDecoder( ) { ivas_error error = IVAS_ERR_OK; +#ifndef FIX_FMSW_DEC IVAS_DEC_HANDLE hIvasDec; +#endif if ( phIvasDec == NULL ) { @@ -4369,9 +4371,9 @@ static ivas_error restartDecoder( arg->decMode = decMode; +#ifndef FIX_FMSW_DEC hIvasDec = *phIvasDec; -#ifndef FIX_FMSW_DEC uint16_t aeID = arg->aeSequence.count > 0 ? arg->aeSequence.pID[0] : IVAS_DEFAULT_AEID; IVAS_AUDIO_CONFIG outputConfig = ( decMode == IVAS_DEC_MODE_IVAS ) ? arg->outputConfig : IVAS_AUDIO_CONFIG_MONO; @@ -4437,6 +4439,7 @@ static ivas_error restartDecoder( cleanup: IVAS_DEC_Close( phIvasDec ); + return error; } -- GitLab From f88b7dfc8b09940a2cfbc52772b0ee1fbefb062e Mon Sep 17 00:00:00 2001 From: vaclav Date: Wed, 25 Mar 2026 09:21:14 +0100 Subject: [PATCH 9/9] explicitly set codecId = IVAS_RTP_UNDEF in the initialization --- lib_util/ivas_rtp_file.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib_util/ivas_rtp_file.c b/lib_util/ivas_rtp_file.c index c520c1439..679728b92 100644 --- a/lib_util/ivas_rtp_file.c +++ b/lib_util/ivas_rtp_file.c @@ -867,6 +867,9 @@ ivas_error IVAS_RTP_READER_Init( rtp->unpackCfg.maxFramesPerPacket = IVAS_MAX_FRAMES_PER_RTP_PACKET; rtp->rtpPacket.buffer = rtp->packet; rtp->rtpPacket.capacity = sizeof( rtp->packet ); +#ifdef FIX_FMSW_DEC + rtp->codecId = IVAS_RTP_UNDEF; +#endif error = IVAS_RTP_UNPACK_Open( &rtp->hUnpack, &rtp->unpackCfg ); if ( error == IVAS_ERR_OK ) -- GitLab