From fbf455224fda7e50573d3c9443391b6c14c74933 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Tue, 28 Nov 2023 16:58:42 +0100 Subject: [PATCH 1/4] IVAS float update 20231128_Update_Ittiam --- Makefile | 6 +- Workspace_msvc/lib_com.vcxproj | 2 - Workspace_msvc/lib_com.vcxproj.filters | 8 +- Workspace_msvc/lib_dec.vcxproj | 1 - Workspace_msvc/lib_dec.vcxproj.filters | 5 +- Workspace_msvc/lib_enc.vcxproj.filters | 2 +- Workspace_msvc/lib_rend.vcxproj | 3 +- Workspace_msvc/lib_rend.vcxproj.filters | 8 +- apps/decoder.c | 232 +- apps/encoder.c | 38 +- apps/renderer.c | 116 +- lib_com/basop32.c | 331 +- lib_com/basop_lsf_tools.c | 1 - lib_com/basop_util.c | 2 +- lib_com/common_api_types.h | 24 +- lib_com/control.h | 82 - lib_com/enh1632.c | 79 +- lib_com/enh1632.h | 30 + lib_com/enh40.c | 90 +- lib_com/enh40.h | 70 +- lib_com/ivas_cnst.h | 32 +- lib_com/ivas_dirac_com.c | 22 +- lib_com/ivas_ism_com.c | 4 - lib_com/ivas_prot.h | 260 +- lib_com/ivas_rom_com.c | 76 +- lib_com/ivas_rom_com.h | 11 +- lib_com/ivas_stat_com.h | 28 - lib_com/ivas_stereo_td_bit_alloc.c | 16 +- lib_com/move.h | 18 +- lib_com/options.h | 28 - lib_com/prot.h | 18 +- lib_com/stl.h | 2 +- lib_com/tcx_ltp.c | 7 +- lib_debug/wmc_auto.c | 490 ++- lib_debug/wmc_auto.h | 423 ++- lib_dec/bass_psfilter.c | 2 +- lib_dec/fd_cng_dec.c | 5 +- lib_dec/ivas_binRenderer_internal.c | 24 +- lib_dec/ivas_core_dec.c | 21 +- lib_dec/ivas_corecoder_dec_reconfig.c | 7 + lib_dec/ivas_cpe_dec.c | 15 +- lib_dec/ivas_dec.c | 920 +----- lib_dec/ivas_dirac_dec.c | 154 +- lib_dec/ivas_init_dec.c | 69 +- lib_dec/ivas_ism_dec.c | 38 +- lib_dec/ivas_ism_dtx_dec.c | 54 +- lib_dec/ivas_ism_param_dec.c | 14 +- lib_dec/ivas_ism_renderer.c | 268 +- lib_dec/ivas_jbm_dec.c | 311 +- lib_dec/ivas_masa_dec.c | 9 +- lib_dec/ivas_mc_param_dec.c | 60 +- lib_dec/ivas_mc_paramupmix_dec.c | 511 +--- lib_dec/ivas_mct_dec.c | 45 +- lib_dec/ivas_mdct_core_dec.c | 4 +- lib_dec/ivas_objectRenderer_internal.c | 19 +- lib_dec/ivas_omasa_dec.c | 137 +- lib_dec/ivas_osba_dec.c | 133 +- lib_dec/ivas_qmetadata_dec.c | 19 + lib_dec/ivas_rom_dec.c | 265 +- lib_dec/ivas_rom_dec.h | 18 - lib_dec/ivas_sba_dec.c | 71 +- lib_dec/ivas_sba_dirac_stereo_dec.c | 6 + lib_dec/ivas_sba_rendering_internal.c | 122 +- lib_dec/ivas_spar_decoder.c | 41 +- lib_dec/ivas_spar_md_dec.c | 353 ++- lib_dec/ivas_stat_dec.h | 28 +- lib_dec/ivas_stereo_dft_dec.c | 18 +- lib_dec/ivas_stereo_mdct_stereo_dec.c | 24 +- lib_dec/ivas_stereo_switching_dec.c | 5 + lib_dec/jbm_jb4_circularbuffer.c | 19 +- lib_dec/jbm_jb4_inputbuffer.c | 21 +- lib_dec/lib_dec.c | 364 ++- lib_dec/lib_dec.h | 39 +- lib_enc/acelp_core_switch_enc.c | 21 - lib_enc/cod_tcx.c | 14 +- lib_enc/evs_enc.c | 10 - lib_enc/init_enc.c | 1 + lib_enc/ivas_core_enc.c | 35 +- lib_enc/ivas_core_pre_proc.c | 5 +- lib_enc/ivas_core_pre_proc_front.c | 21 +- lib_enc/ivas_cpe_enc.c | 21 +- lib_enc/ivas_dirac_enc.c | 22 +- lib_enc/ivas_enc.c | 2 + lib_enc/ivas_ism_enc.c | 4 +- lib_enc/ivas_masa_enc.c | 2 +- lib_enc/ivas_mc_paramupmix_enc.c | 124 +- lib_enc/ivas_mcmasa_enc.c | 6 +- lib_enc/ivas_mct_enc.c | 6 - lib_enc/ivas_omasa_enc.c | 4 - lib_enc/ivas_osba_enc.c | 7 +- lib_enc/ivas_qmetadata_enc.c | 97 - lib_enc/ivas_rom_enc.c | 92 +- lib_enc/ivas_rom_enc.h | 8 +- lib_enc/ivas_sce_enc.c | 2 +- lib_enc/ivas_stereo_classifier.c | 22 +- lib_enc/ivas_stereo_dft_enc.c | 6 +- lib_enc/ivas_stereo_dft_enc_itd.c | 2 +- lib_enc/ivas_stereo_dft_td_itd.c | 2 +- lib_enc/long_enr.c | 16 +- lib_enc/pre_proc.c | 4 - lib_enc/stat_enc.h | 2 + lib_rend/ivas_crend.c | 11 +- lib_rend/ivas_dirac_dec_binaural_functions.c | 282 +- lib_rend/ivas_dirac_decorr_dec.c | 3 +- lib_rend/ivas_dirac_output_synthesis_dec.c | 20 +- lib_rend/ivas_dirac_rend.c | 425 ++- lib_rend/ivas_lcld_prot.h | 39 - lib_rend/ivas_objectRenderer.c | 38 +- lib_rend/ivas_omasa_ana.c | 4 - lib_rend/ivas_output_init.c | 10 +- lib_rend/ivas_prot_rend.h | 147 +- lib_rend/ivas_reflections.c | 2 + lib_rend/ivas_reverb.c | 5 +- lib_rend/ivas_reverb_filter_design.c | 4 +- lib_rend/ivas_rom_rend.c | 143 + lib_rend/ivas_rom_rend.h | 22 + lib_rend/ivas_rotation.c | 104 +- lib_rend/ivas_shoebox.c | 13 + lib_rend/ivas_stat_rend.h | 58 +- {lib_com => lib_rend}/ivas_td_decorr.c | 26 +- {lib_dec => lib_rend}/ivas_vbap.c | 1 + lib_rend/lib_rend.c | 2819 ++++++++++-------- lib_rend/lib_rend.h | 11 +- lib_util/masa_file_writer.c | 15 +- lib_util/render_config_reader.c | 7 +- readme.txt | 29 +- 126 files changed, 5839 insertions(+), 5755 deletions(-) delete mode 100644 lib_com/control.h delete mode 100644 lib_rend/ivas_lcld_prot.h rename {lib_com => lib_rend}/ivas_td_decorr.c (94%) rename {lib_dec => lib_rend}/ivas_vbap.c (99%) diff --git a/Makefile b/Makefile index 74c97cf3b..bef5db441 100644 --- a/Makefile +++ b/Makefile @@ -57,7 +57,7 @@ endif CFLAGS += -std=c99 -pedantic -Wcast-qual -Wall -W -Wextra -Wno-long-long \ -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes \ -Werror-implicit-function-declaration \ - -Wno-unused-function -Wno-implicit-fallthrough + -Wno-implicit-fallthrough -ffp-contract=off # libs to link LDLIBS += -lm @@ -95,8 +95,8 @@ LDFLAGS += -g3 endif ifeq "$(GCOV)" "1" -CFLAGS += -fprofile-arcs -ftest-coverage -LDFLAGS += -fprofile-arcs -ftest-coverage +CFLAGS += -fprofile-arcs -ftest-coverage -fprofile-update=atomic +LDFLAGS += -fprofile-arcs -ftest-coverage -fprofile-update=atomic endif ifeq "$(STRIP)" "1" diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 22407fb02..0c5d4dcca 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -217,7 +217,6 @@ - @@ -283,7 +282,6 @@ - diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters index 7a8f8e013..85fd7e8d6 100644 --- a/Workspace_msvc/lib_com.vcxproj.filters +++ b/Workspace_msvc/lib_com.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -460,9 +460,6 @@ common_ivas_c - - common_ivas_c - common_ivas_c @@ -489,9 +486,6 @@ common_h - - common_h - common_h diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index 10a3ac1b4..0266955ab 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -264,7 +264,6 @@ - diff --git a/Workspace_msvc/lib_dec.vcxproj.filters b/Workspace_msvc/lib_dec.vcxproj.filters index ef14ddf0e..24d58eb97 100644 --- a/Workspace_msvc/lib_dec.vcxproj.filters +++ b/Workspace_msvc/lib_dec.vcxproj.filters @@ -1,9 +1,6 @@ - + - - decoder_ivas_c - decoder_ivas_c diff --git a/Workspace_msvc/lib_enc.vcxproj.filters b/Workspace_msvc/lib_enc.vcxproj.filters index e74f441c4..250aecf0b 100644 --- a/Workspace_msvc/lib_enc.vcxproj.filters +++ b/Workspace_msvc/lib_enc.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj index 11edc9310..ee40123a8 100644 --- a/Workspace_msvc/lib_rend.vcxproj +++ b/Workspace_msvc/lib_rend.vcxproj @@ -173,10 +173,11 @@ + + - diff --git a/Workspace_msvc/lib_rend.vcxproj.filters b/Workspace_msvc/lib_rend.vcxproj.filters index 406ba2c85..4707a48b2 100644 --- a/Workspace_msvc/lib_rend.vcxproj.filters +++ b/Workspace_msvc/lib_rend.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -158,6 +158,9 @@ rend_c + + rend_c + rend_c @@ -167,6 +170,9 @@ rend_c + + rend_c + diff --git a/apps/decoder.c b/apps/decoder.c index afb288dc0..0a4da2bdb 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -113,7 +113,7 @@ typedef struct char *renderConfigFilename; IVAS_DEC_COMPLEXITY_LEVEL complexityLevel; bool tsmEnabled; - bool enable5ms; + IVAS_RENDER_FRAMESIZE renderFramesize; uint16_t acousticEnvironmentId; int16_t Opt_dpid_on; uint16_t directivityPatternId[IVAS_MAX_NUM_OBJECTS]; @@ -128,7 +128,8 @@ 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, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); -static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HANDLE hIvasDec ); +static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec ); + /*------------------------------------------------------------------------------------------* * main() @@ -155,10 +156,11 @@ int main( Vector3PairFileReader *referenceVectorReader = NULL; RenderConfigReader *renderConfigReader = NULL; int16_t *pcmBuf = NULL; + IVAS_RENDER_FRAMESIZE asked_frame_size; #ifdef WMOPS reset_wmops(); - reset_mem( USE_32BITS ); + reset_mem( USE_BYTES ); #endif /*------------------------------------------------------------------------------------------* @@ -359,13 +361,25 @@ int main( * Configure the decoder *------------------------------------------------------------------------------------------*/ - if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputConfig, arg.tsmEnabled, arg.enable5ms, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.enableExternalOrientation, - arg.orientation_tracking, arg.renderConfigEnabled, arg.Opt_non_diegetic_pan, arg.non_diegetic_pan_gain, arg.Opt_dpid_on, arg.acousticEnvironmentId, arg.delayCompensationEnabled ) ) != IVAS_ERR_OK ) + asked_frame_size = arg.renderFramesize; + if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputConfig, arg.tsmEnabled, arg.renderFramesize, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.enableExternalOrientation, arg.orientation_tracking, arg.renderConfigEnabled, arg.Opt_non_diegetic_pan, arg.non_diegetic_pan_gain, + arg.Opt_dpid_on, arg.acousticEnvironmentId, arg.delayCompensationEnabled ) ) != IVAS_ERR_OK ) + + { + fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + if ( ( error = IVAS_DEC_GetRenderFramesize( hIvasDec, &arg.renderFramesize ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } + if ( arg.renderFramesize != asked_frame_size ) + { + fprintf( stderr, "\nChanged render framesize, only 20ms are allowed for decoding to EXT!\n" ); + } + /*------------------------------------------------------------------------------------------* * Configure Split rendering *------------------------------------------------------------------------------------------*/ @@ -546,7 +560,7 @@ int main( if ( arg.voipMode ) { - error = decodeVoIP( arg, hBsReader, hIvasDec ); + error = decodeVoIP( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, hIvasDec ); } else { @@ -755,7 +769,7 @@ static bool parseCmdlIVAS_dec( arg->Opt_non_diegetic_pan = 0; arg->non_diegetic_pan_gain = 0.f; arg->tsmEnabled = false; - arg->enable5ms = false; + arg->renderFramesize = IVAS_RENDER_FRAMESIZE_20MS; arg->acousticEnvironmentId = 65535; for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i ) { @@ -871,10 +885,38 @@ static bool parseCmdlIVAS_dec( arg->headrotTrajFileName = argv[i]; i++; } - else if ( strcmp( argv_to_upper, "-FR5" ) == 0 ) + else if ( strcmp( argv_to_upper, "-FR" ) == 0 ) { - arg->enable5ms = true; + int32_t tmp; i++; + if ( i < argc - 3 ) + { + if ( !is_digits_only( argv[i] ) ) + { + return false; + } + + if ( sscanf( argv[i], "%d", &tmp ) > 0 ) + { + i++; + } + switch ( (int16_t) tmp ) + { + case 5: + arg->renderFramesize = IVAS_RENDER_FRAMESIZE_5MS; + break; + case 10: + arg->renderFramesize = IVAS_RENDER_FRAMESIZE_10MS; + break; + case 20: + arg->renderFramesize = IVAS_RENDER_FRAMESIZE_20MS; + break; + default: + fprintf( stderr, "Error: Invalid render frame size %d \n\n", tmp ); + usage_dec(); + return false; + } + } } else if ( strcmp( argv_to_upper, "-OTR" ) == 0 ) { @@ -1169,11 +1211,6 @@ static bool parseCmdlIVAS_dec( return false; } - if ( ( !arg->enableHeadRotation ) && ( !arg->enableExternalOrientation ) && ( !arg->tsmEnabled ) ) - { - arg->enable5ms = false; - } - return true; } @@ -1212,7 +1249,7 @@ static void usage_dec( void ) #ifdef SUPPORT_JBM_TRACEFILE fprintf( stdout, "-Tracefile TF : VoIP mode: Generate trace file named TF\n" ); #endif - fprintf( stdout, "-fr5 : option to perform rendering + head-tracking with 5ms frame size\n" ); + fprintf( stdout, "-fr L : render frame size in ms L=(5,10,20), default is 20)\n" ); fprintf( stdout, "-fec_cfg_file : Optimal channel aware configuration computed by the JBM \n" ); fprintf( stdout, " as described in Section 6.3.1 of TS26.448. The output is \n" ); fprintf( stdout, " written into a .txt file. Each line contains the FER indicator \n" ); @@ -1487,17 +1524,18 @@ static ivas_error decodeG192( nSamplesAvailableNext = 0; vec_pos_update = 0; - if ( arg.enableHeadRotation && arg.enable5ms ) + if ( ( error = IVAS_DEC_GetRenderFramesizeSamples( hIvasDec, &nOutSamples ) ) != IVAS_ERR_OK ) { - nOutSamples = (int16_t) ( arg.output_Fs / 1000 * HEADROTATION_FETCH_FRAMESIZE_MS ); - vec_pos_len = IVAS_MAX_PARAM_SPATIAL_SUBFRAMES; + fprintf( stderr, "\nError getting render frame size in samples\n" ); + return error; } - else + if ( ( error = IVAS_DEC_GetReferencesUpdateFrequency( hIvasDec, &vec_pos_len ) ) != IVAS_ERR_OK ) { - nOutSamples = (int16_t) ( arg.output_Fs / 1000 * DEFAULT_FETCH_FRAMESIZE_MS ); - vec_pos_len = 1; + fprintf( stderr, "\nError getting render frame size in samples\n" ); + return error; } + /*------------------------------------------------------------------------------------------* * Loop for every packet (frame) of bitstream data * - Read the bitstream packet @@ -1543,14 +1581,12 @@ static ivas_error decodeG192( } } - int16_t enable5ms, num_subframes; - if ( ( error = IVAS_DEC_Get5msFlag( hIvasDec, &enable5ms ) ) != IVAS_ERR_OK ) + int16_t num_subframes; + if ( ( error = IVAS_DEC_GetNumOrientationSubframes( hIvasDec, &num_subframes ) ) != IVAS_ERR_OK ) { - return error; + fprintf( stderr, "\nIVAS_DEC_GetNumOrientationSubframes failed: \n" ); + goto cleanup; } - arg.enable5ms = enable5ms; - num_subframes = ( arg.enable5ms ) ? 1 : IVAS_MAX_PARAM_SPATIAL_SUBFRAMES; - /* Head-tracking input simulation */ /* Head-tracking input simulation */ if ( arg.enableHeadRotation ) @@ -1635,6 +1671,14 @@ static ivas_error decodeG192( } nSamplesRendered += nSamplesRendered_loop; nSamplesToRender -= nSamplesRendered_loop; + if ( needNewFrame ) + { + frame++; + if ( !arg.quietModeEnabled ) + { + fprintf( stdout, "%-8d\b\b\b\b\b\b\b\b", frame ); + } + } } while ( nSamplesRendered < nOutSamples && error == IVAS_ERR_OK ); @@ -1730,14 +1774,6 @@ static ivas_error decodeG192( } } vec_pos_update = ( vec_pos_update + 1 ) % vec_pos_len; - if ( needNewFrame ) - { - frame++; - if ( !arg.quietModeEnabled ) - { - fprintf( stdout, "%-8d\b\b\b\b\b\b\b\b", frame ); - } - } #ifdef WMOPS if ( vec_pos_update == 0 ) { @@ -1963,6 +1999,10 @@ static ivas_error writeJbmTraceFileFrameWrapper( const void *data, void *writer static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, + RotFileReader *headRotReader, + RotFileReader *externalOrientationFileReader, + RotFileReader *refRotReader, + Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec ) { bool decodingFailed = true; /* Assume failure until cleanup is reached without errors */ @@ -2005,6 +2045,26 @@ static ivas_error decodeVoIP( IVAS_DEC_BS_FORMAT bsFormat = IVAS_DEC_BS_UNKOWN; IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS]; + IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES] = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; + int16_t vec_pos_update, vec_pos_len; + int16_t nOutSamples = 0; + + vec_pos_update = 0; + if ( ( error = IVAS_DEC_GetRenderFramesizeMs( hIvasDec, &systemTimeInc_ms ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError getting render frame size in samples\n" ); + return error; + } + if ( ( error = IVAS_DEC_GetRenderFramesizeSamples( hIvasDec, &nOutSamples ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError getting render frame size in samples\n" ); + return error; + } + if ( ( error = IVAS_DEC_GetReferencesUpdateFrequency( hIvasDec, &vec_pos_len ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError getting render frame size in samples\n" ); + return error; + } for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i ) { @@ -2103,11 +2163,103 @@ static ivas_error decodeVoIP( * Main receiving/decoding loop *------------------------------------------------------------------------------------------*/ - while ( 1 ) { - int16_t nOutSamples = 0; - nOutSamples = (int16_t) ( arg.output_Fs / 1000 * JBM_FRONTEND_FETCH_FRAMESIZE_MS ); + + /* reference vector */ + if ( arg.enableReferenceVectorTracking && vec_pos_update == 0 ) + { + IVAS_VECTOR3 listenerPosition, referencePosition; + if ( ( error = Vector3PairFileReader_read( referenceVectorReader, &listenerPosition, &referencePosition ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while reading listener and reference positions from %s\n", IVAS_DEC_GetErrorMessage( error ), Vector3PairFileReader_getFilePath( referenceVectorReader ) ); + goto cleanup; + } + + if ( ( error = IVAS_DEC_FeedRefVectorData( hIvasDec, listenerPosition, referencePosition ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedRefVectorData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + + /* Reference rotation */ + if ( arg.enableReferenceRotation && vec_pos_update == 0 ) + { + IVAS_QUATERNION quaternion; + if ( ( error = HeadRotationFileReading( refRotReader, &quaternion, NULL ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while reading reference rotation from %s\n", IVAS_DEC_GetErrorMessage( error ), RotationFileReader_getFilePath( refRotReader ) ); + goto cleanup; + } + + if ( ( error = IVAS_DEC_FeedRefRotData( hIvasDec, quaternion ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedRefRotData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + int16_t num_subframes; + if ( ( error = IVAS_DEC_GetNumOrientationSubframes( hIvasDec, &num_subframes ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_GetNumOrientationSubframes failed: \n" ); + goto cleanup; + } + + /* Head-tracking input simulation */ + /* Head-tracking input simulation */ + if ( arg.enableHeadRotation ) + { + IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + + for ( i = 0; i < num_subframes; i++ ) + { + if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), + RotationFileReader_getFilePath( headRotReader ) ); + goto cleanup; + } + } + + for ( i = 0; i < num_subframes; i++ ) + { + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i + ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + } + + if ( arg.enableExternalOrientation ) + { + IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + int8_t enableHeadRotation[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + int8_t enableExternalOrientation[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + int8_t enableRotationInterpolation[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + int16_t numFramesToTargetOrientation[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + + for ( i = 0; i < num_subframes; i++ ) + { + + if ( ( error = ExternalOrientationFileReading( externalOrientationFileReader, &Quaternions[i], &enableHeadRotation[i], &enableExternalOrientation[i], &enableRotationInterpolation[i], &numFramesToTargetOrientation[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while reading external orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), + RotationFileReader_getFilePath( externalOrientationFileReader ) ); + goto cleanup; + } + } + for ( i = 0; i < num_subframes; i++ ) + { + if ( ( error = IVAS_DEC_FeedExternalOrientationData( hIvasDec, Quaternions[i], enableHeadRotation[i], enableExternalOrientation[i], enableRotationInterpolation[i], numFramesToTargetOrientation[i], i ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedExternalOrientationData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + } /* read all packets with a receive time smaller than the system time */ while ( nextPacketRcvTime_ms <= systemTime_ms ) @@ -2281,7 +2433,7 @@ static ivas_error decodeVoIP( { fprintf( stdout, "%-8d\b\b\b\b\b\b\b\b", frame ); } - + vec_pos_update = ( vec_pos_update + 1 ) % vec_pos_len; frame++; systemTime_ms += systemTimeInc_ms; @@ -2364,3 +2516,5 @@ cleanup: } + +#undef WMC_TOOL_SKIP diff --git a/apps/encoder.c b/apps/encoder.c index 31c6c334b..c255170a7 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -169,7 +169,7 @@ int main( #ifdef WMOPS reset_wmops(); - reset_mem( USE_32BITS ); + reset_mem( USE_BYTES ); #endif initArgStruct( &arg ); @@ -1419,38 +1419,10 @@ static bool parseCmdlIVAS_enc( i++; } - else if ( strcmp( argv_to_upper, "-BYPASS" ) == 0 ) // TODO: should be renamed to "-pca" + else if ( strcmp( argv_to_upper, "-PCA" ) == 0 ) { + arg->pca = 1; i++; - if ( i < argc - 4 ) - { - switch ( atoi( argv[i] ) ) - { - case 1: - { - arg->pca = 0; - break; - } - case 2: - { - arg->pca = 1; - break; - } - default: - { - fprintf( stderr, "Error: SBA PCA bypass argument is out of range (%d), expected 1 or 2\n", (int32_t) atoi( argv[i] ) ); - usage_enc(); - return false; - } - } - i++; - } - else - { - fprintf( stderr, "Error: SBA unspecified PCA BYPASS value \n\n" ); - usage_enc(); - return false; - } } /*-----------------------------------------------------------------* @@ -1648,7 +1620,7 @@ static void usage_enc( void ) fprintf( stdout, "-mime : Mime output bitstream file format\n" ); fprintf( stdout, " The encoder produces TS26.445 Annex.2.6 Mime Storage Format, (not RFC4867 Mime Format).\n" ); fprintf( stdout, " default output bitstream file format is G.192\n" ); - fprintf( stdout, "-bypass mode : SBA PCA by-pass, mode = (1, 2), 1 = PCA off, 2 = signal adaptive, default is 1\n" ); + fprintf( stdout, "-pca : activate PCA in SBA format FOA at 256 kbps \n" ); fprintf( stdout, "-level level : Complexity level, level = (1, 2, 3), will be defined after characterisation. \n" ); fprintf( stdout, " Currently, all values default to level 3 (full functionality).\n" ); fprintf( stdout, "-q : Quiet mode, no frame counters\n" ); @@ -1744,3 +1716,5 @@ static bool readBitrate( } + +#undef WMC_TOOL_SKIP diff --git a/apps/renderer.c b/apps/renderer.c index 7a04cfb0b..6ac6b0aa3 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -167,7 +167,7 @@ typedef struct bool lfeCustomRoutingEnabled; char inLfePanningMatrixFile[RENDERER_MAX_CLI_ARG_LENGTH]; float syncMdDelay; - bool framing_5ms; + IVAS_RENDER_FRAMESIZE render_framesize; uint16_t directivityPatternId[RENDERER_MAX_ISM_INPUTS]; uint16_t acousticEnvironmentId; } CmdlnArgs; @@ -195,7 +195,7 @@ typedef enum CmdLnOptionId_inputGain, CmdLnOptionId_referenceVectorFile, CmdLnOptionId_exteriorOrientationFile, - CmdLnOptionId_framing5ms, + CmdLnOptionId_framing, CmdLnOptionId_syncMdDelay, CmdLnOptionId_directivityPatternId, CmdLnOptionId_acousticEnvironmentId @@ -241,7 +241,7 @@ static const CmdLnParser_Option cliOptions[] = { { .id = CmdLnOptionId_trajFile, .match = "trajectory_file", - .matchShort = "tf", + .matchShort = "T", .description = "Head rotation trajectory file for simulation of head tracking (only for binaural outputs)", }, { @@ -258,14 +258,14 @@ static const CmdLnParser_Option cliOptions[] = { }, { .id = CmdLnOptionId_renderConfigFile, - .match = "render_config", - .matchShort = "rc", - .description = "Binaural renderer configuration file (only for binaural outputs)", + .match = "render_config_parameters", + .matchShort = "render_config", + .description = "Binaural renderer configuration parameters in file (only for binaural outputs)", }, { .id = CmdLnOptionId_nonDiegeticPan, - .match = "non_diegetic_pan", - .matchShort = "ndp", + .match = "non_diegetic_panning", + .matchShort = "non_diegetic_pan", .description = "Panning mono non diegetic sound to stereo -90<= pan <= 90\nleft or l or 90->left, right or r or -90->right, center or c or 0 ->middle\n", }, { @@ -286,8 +286,8 @@ static const CmdLnParser_Option cliOptions[] = { .description = "LFE panning matrix. File (CSV table) containing a matrix of dimensions [ num_input_lfe x num_output_channels ] with elements specifying linear routing gain (like --gain, -g). \nIf specified, overrides the output LFE position option and the default behavior which attempts to map input to output LFE channel(s)" }, { .id = CmdLnOptionId_noDelayCmp, - .match = "no_delay_cmp", - .matchShort = "ndc", + .match = "no_delay_comparison", + .matchShort = "no_delay_cmp", .description = "[flag] Turn off delay compensation", }, { @@ -327,10 +327,10 @@ static const CmdLnParser_Option cliOptions[] = { .description = "External orientation trajectory file for simulation of external orientations", }, { - .id = CmdLnOptionId_framing5ms, - .match = "framing_5ms", - .matchShort = "fr5", - .description = "Render audio with 5 ms framing.", + .id = CmdLnOptionId_framing, + .match = "framing", + .matchShort = "fr", + .description = "Set Render audio framing.", }, { .id = CmdLnOptionId_syncMdDelay, @@ -624,7 +624,7 @@ int main( #ifdef WMOPS reset_wmops(); - reset_mem( USE_32BITS ); + reset_mem( USE_BYTES ); #endif for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) @@ -789,9 +789,9 @@ int main( fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } - const int16_t frameSize_smpls = (int16_t) ( ( args.framing_5ms ? 5 : 20 ) * args.sampleRate / 1000 ); + const int16_t frameSize_smpls = (int16_t) ( ( args.render_framesize ) * args.sampleRate * 5 / ( 1000 ) ); - if ( ( error = IVAS_REND_Open( &hIvasRend, args.sampleRate, args.outConfig.audioConfig, args.nonDiegeticPan, args.nonDiegeticPanGain, ( args.framing_5ms ) ? 1 : 4 ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_REND_Open( &hIvasRend, args.sampleRate, args.outConfig.audioConfig, args.nonDiegeticPan, args.nonDiegeticPanGain, (int16_t) args.render_framesize ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error opening renderer handle: %s\n", ivas_error_to_string( error ) ); exit( -1 ); @@ -1131,7 +1131,7 @@ int main( { int16_t num_in_channels; num_in_channels = inBuffer.config.numChannels; - const bool isCurrentFrameMultipleOf20ms = !args.framing_5ms || frame % 4 == 0; + const bool isCurrentFrameMultipleOf20ms = frame % ( 4 / args.render_framesize ) == 0; /* Read the input data */ if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) @@ -1150,7 +1150,7 @@ int main( convertInputBuffer( inpInt16Buffer, numSamplesRead, inBuffer.config.numSamplesPerChannel, num_in_channels, inFloatBuffer ); int16_t num_subframes, sf_idx; - num_subframes = ( args.framing_5ms ) ? 1 : IVAS_MAX_PARAM_SPATIAL_SUBFRAMES; + num_subframes = (int16_t) args.render_framesize; if ( isCurrentFrameMultipleOf20ms ) { @@ -1342,15 +1342,22 @@ int main( exit( -1 ); } - if ( masaReaders[i] != NULL ) + if ( isCurrentFrameMultipleOf20ms ) { - /* This will update data in hMasaMetadata[i] */ - MasaFileReader_readNextFrame( masaReaders[i] ); - - if ( ( error = IVAS_REND_FeedInputMasaMetadata( hIvasRend, masaIds[i], hMasaMetadata[i] ) ) != IVAS_ERR_OK ) + if ( masaReaders[i] != NULL ) { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); + /* This will update data in hMasaMetadata[i] */ + if ( ( error = MasaFileReader_readNextFrame( masaReaders[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in MASA Metadata File Reading: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( ( error = IVAS_REND_FeedInputMasaMetadata( hIvasRend, masaIds[i], hMasaMetadata[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } } } } @@ -1779,6 +1786,37 @@ static bool parseDiegeticPan( return true; } + +static bool parseRenderFramesize( + char *value, + IVAS_RENDER_FRAMESIZE *render_framesize ) +{ + int32_t tmp; + + *render_framesize = IVAS_RENDER_FRAMESIZE_UNKNOWN; + if ( !is_digits_only( value ) ) + { + return false; + } + tmp = (int32_t) strtol( value, NULL, 0 ); + switch ( (int16_t) tmp ) + { + case 5: + *render_framesize = IVAS_RENDER_FRAMESIZE_5MS; + break; + case 10: + *render_framesize = IVAS_RENDER_FRAMESIZE_10MS; + break; + case 20: + *render_framesize = IVAS_RENDER_FRAMESIZE_20MS; + break; + default: + return false; + } + + return true; +} + static bool parseOrientationTracking( char *value, int8_t *orientation_tracking ) @@ -1882,9 +1920,7 @@ static IVAS_AUDIO_CONFIG parseAudioConfig( switch ( charBuf[4] ) { case '1': - fprintf( stderr, "1TC MASA support is not functional and is pending on DirAC renderer refactoring.\n" ); - exit( EXIT_FAILURE ); - /*return IVAS_AUDIO_CONFIG_MASA1;*/ // ToDo: temporarily disabled to avoid compilation warnings + return IVAS_AUDIO_CONFIG_MASA1; case '2': return IVAS_AUDIO_CONFIG_MASA2; default: @@ -2049,7 +2085,7 @@ static CmdlnArgs defaultArgs( args.lfeCustomRoutingEnabled = false; clearString( args.inLfePanningMatrixFile ); - args.framing_5ms = false; + args.render_framesize = IVAS_RENDER_FRAMESIZE_20MS; args.syncMdDelay = 0; for ( int32_t i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) @@ -2201,10 +2237,14 @@ static void parseOption( exit( -1 ); } break; - case CmdLnOptionId_framing5ms: - assert( numOptionValues == 0 ); - args->framing_5ms = true; - fprintf( stderr, "Warning: this is a placeholder for 5ms framing.\n" ); + case CmdLnOptionId_framing: + assert( numOptionValues == 1 ); + if ( !parseRenderFramesize( optionValues[0], &args->render_framesize ) ) + { + fprintf( stderr, "Unknown or invalid option for frame size: %s\n", optionValues[0] ); + exit( -1 ); + } + break; case CmdLnOptionId_directivityPatternId: assert( numOptionValues <= RENDERER_MAX_ISM_INPUTS ); @@ -3115,7 +3155,7 @@ static void printSupportedAudioConfigs( void ) "HOA2", "HOA3", "ISMx (input only)", - "MASAx (input only)", + "MASAx", "BINAURAL (output only)", "BINAURAL_ROOM_IR (output only)", "BINAURAL_ROOM_REVERB (output only)", @@ -3153,7 +3193,7 @@ static ivas_error parseLfePanMtxFile( /* set default panning matrix to all zeros any subsequent issue in file reading will gracefully exit the function */ - for ( lfe_in = 0; lfe_in < IVAS_MAX_INPUT_LFE_CHANNELS; lfe_in++ ) + for ( lfe_in = 0; lfe_in < RENDERER_MAX_INPUT_LFE_CHANNELS; lfe_in++ ) { for ( i = 0; i < IVAS_MAX_OUTPUT_CHANNELS; i++ ) { @@ -3161,7 +3201,7 @@ static ivas_error parseLfePanMtxFile( } } - for ( lfe_in = 0; lfe_in < IVAS_MAX_INPUT_LFE_CHANNELS; lfe_in++ ) + for ( lfe_in = 0; lfe_in < RENDERER_MAX_INPUT_LFE_CHANNELS; lfe_in++ ) { ch_out = 0; @@ -3281,3 +3321,5 @@ static void convertOutputBuffer( return; } + +#undef WMC_TOOL_SKIP diff --git a/lib_com/basop32.c b/lib_com/basop32.c index 3e608e4a6..a407ff72d 100644 --- a/lib_com/basop32.c +++ b/lib_com/basop32.c @@ -261,6 +261,9 @@ static Word16 saturate_o( Word32 L_var1, Flag *Overflow ) else { var_out = extract_l( L_var1 ); +#ifdef WMOPS + multiCounter[currCounter].extract_l--; +#endif } BASOP_CHECK(); @@ -286,6 +289,9 @@ static Word16 saturate( Word32 L_var1 ) else { var_out = extract_l( L_var1 ); +#ifdef WMOPS + multiCounter[currCounter].extract_l--; +#endif } BASOP_CHECK(); @@ -336,7 +342,9 @@ Word16 add_o( Word16 var1, Word16 var2, Flag *Overflow ) L_sum = (Word32) var1 + var2; var_out = saturate_o( L_sum, Overflow ); - +#ifdef WMOPS + multiCounter[currCounter].add++; +#endif return ( var_out ); } @@ -349,7 +357,9 @@ Word16 add( Word16 var1, Word16 var2 ) L_sum = (Word32) var1 + var2; var_out = saturate( L_sum ); - +#ifdef WMOPS + multiCounter[currCounter].add++; +#endif return ( var_out ); } @@ -396,6 +406,9 @@ Word16 sub_o( Word16 var1, Word16 var2, Flag *Overflow ) L_diff = (Word32) var1 - var2; var_out = saturate_o( L_diff, Overflow ); +#ifdef WMOPS + multiCounter[currCounter].sub++; +#endif return ( var_out ); } @@ -408,6 +421,9 @@ Word16 sub( Word16 var1, Word16 var2 ) L_diff = (Word32) var1 - var2; var_out = saturate( L_diff ); +#ifdef WMOPS + multiCounter[currCounter].sub++; +#endif return ( var_out ); } @@ -459,6 +475,9 @@ Word16 abs_s( Word16 var1 ) } } +#ifdef WMOPS + multiCounter[currCounter].abs_s++; +#endif BASOP_CHECK(); @@ -515,6 +534,10 @@ Word16 shl_o( Word16 var1, Word16 var2, Flag *Overflow ) var2 = -16; var2 = -var2; var_out = shr( var1, var2 ); + +#ifdef WMOPS + multiCounter[currCounter].shr--; +#endif } else { @@ -532,9 +555,17 @@ Word16 shl_o( Word16 var1, Word16 var2, Flag *Overflow ) else { var_out = extract_l( result ); + +#ifdef WMOPS + multiCounter[currCounter].extract_l--; +#endif } } +#ifdef WMOPS + multiCounter[currCounter].shl++; +#endif + BASOP_CHECK(); @@ -553,6 +584,10 @@ Word16 shl( Word16 var1, Word16 var2 ) var2 = -16; var2 = -var2; var_out = shr( var1, var2 ); + +#ifdef WMOPS + multiCounter[currCounter].shr--; +#endif } else { @@ -566,9 +601,16 @@ Word16 shl( Word16 var1, Word16 var2 ) else { var_out = extract_l( result ); + +#ifdef WMOPS + multiCounter[currCounter].extract_l--; +#endif } } +#ifdef WMOPS + multiCounter[currCounter].shl++; +#endif BASOP_CHECK(); @@ -623,6 +665,10 @@ Word16 shr( Word16 var1, Word16 var2 ) var2 = -16; var2 = -var2; var_out = shl( var1, var2 ); + +#ifdef WMOPS + multiCounter[currCounter].shl--; +#endif } else { @@ -643,6 +689,10 @@ Word16 shr( Word16 var1, Word16 var2 ) } } +#ifdef WMOPS + multiCounter[currCounter].shr++; +#endif + BASOP_CHECK(); @@ -699,6 +749,9 @@ Word16 mult_o( Word16 var1, Word16 var2, Flag *Overflow ) var_out = saturate_o( L_product, Overflow ); +#ifdef WMOPS + multiCounter[currCounter].mult++; +#endif return ( var_out ); } @@ -718,7 +771,9 @@ Word16 mult( Word16 var1, Word16 var2 ) var_out = saturate( L_product ); - +#ifdef WMOPS + multiCounter[currCounter].mult++; +#endif return ( var_out ); } @@ -781,6 +836,10 @@ Word32 L_mult_o( Word16 var1, Word16 var2, Flag *Overflow ) L_var_out = MAX_32; } +#ifdef WMOPS + multiCounter[currCounter].L_mult++; +#endif + BASOP_CHECK(); return ( L_var_out ); @@ -803,6 +862,10 @@ Word32 L_mult( Word16 var1, Word16 var2 ) L_var_out = MAX_32; } +#ifdef WMOPS + multiCounter[currCounter].L_mult++; +#endif + BASOP_CHECK(); return ( L_var_out ); @@ -844,6 +907,10 @@ Word16 negate( Word16 var1 ) var_out = ( var1 == MIN_16 ) ? MAX_16 : -var1; +#ifdef WMOPS + multiCounter[currCounter].negate++; +#endif + BASOP_CHECK(); @@ -884,6 +951,10 @@ Word16 extract_h( Word32 L_var1 ) var_out = (Word16) ( L_var1 >> 16 ); +#ifdef WMOPS + multiCounter[currCounter].extract_h++; +#endif + BASOP_CHECK(); @@ -924,6 +995,10 @@ Word16 extract_l( Word32 L_var1 ) var_out = (Word16) L_var1; +#ifdef WMOPS + multiCounter[currCounter].extract_l++; +#endif + BASOP_CHECK(); @@ -972,6 +1047,12 @@ Word16 round_fx_o( Word32 L_var1, Flag *Overflow ) BASOP_SATURATE_WARNING_ON var_out = extract_h( L_rounded ); +#ifdef WMOPS + multiCounter[currCounter].L_add--; + multiCounter[currCounter].extract_h--; + multiCounter[currCounter].round++; +#endif + BASOP_CHECK(); return ( var_out ); @@ -988,6 +1069,11 @@ Word16 round_fx( Word32 L_var1 ) BASOP_SATURATE_WARNING_ON var_out = extract_h( L_rounded ); +#ifdef WMOPS + multiCounter[currCounter].L_add--; + multiCounter[currCounter].extract_h--; + multiCounter[currCounter].round++; +#endif BASOP_CHECK(); return ( var_out ); @@ -1039,7 +1125,11 @@ Word32 L_mac_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) L_product = L_mult_o( var1, var2, Overflow ); L_var_out = L_add_o( L_var3, L_product, Overflow ); - BASOP_CHECK(); +#ifdef WMOPS + multiCounter[currCounter].L_mult--; + multiCounter[currCounter].L_add--; + multiCounter[currCounter].L_mac++; +#endif return ( L_var_out ); } @@ -1053,6 +1143,11 @@ Word32 L_mac( Word32 L_var3, Word16 var1, Word16 var2 ) L_product = L_mult( var1, var2 ); L_var_out = L_add( L_var3, L_product ); +#ifdef WMOPS + multiCounter[currCounter].L_mult--; + multiCounter[currCounter].L_add--; + multiCounter[currCounter].L_mac++; +#endif BASOP_CHECK(); return ( L_var_out ); @@ -1104,7 +1199,11 @@ Word32 L_msu_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) L_product = L_mult_o( var1, var2, Overflow ); L_var_out = L_sub_o( L_var3, L_product, Overflow ); - BASOP_CHECK(); +#ifdef WMOPS + multiCounter[currCounter].L_mult--; + multiCounter[currCounter].L_sub--; + multiCounter[currCounter].L_msu++; +#endif return ( L_var_out ); } @@ -1118,6 +1217,11 @@ Word32 L_msu( Word32 L_var3, Word16 var1, Word16 var2 ) L_product = L_mult( var1, var2 ); L_var_out = L_sub( L_var3, L_product ); +#ifdef WMOPS + multiCounter[currCounter].L_mult--; + multiCounter[currCounter].L_sub--; + multiCounter[currCounter].L_msu++; +#endif BASOP_CHECK(); return ( L_var_out ); @@ -1185,6 +1289,12 @@ Word32 DEPR_L_macNs( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry ) L_var_out = DEPR_L_add_c( L_var3, L_var_out, Carry ); #endif /* BASOP_NOGLOB */ +#ifdef WMOPS + multiCounter[currCounter].L_mult--; + multiCounter[currCounter].L_add_c--; + multiCounter[currCounter].L_macNs++; +#endif + /* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */ @@ -1253,8 +1363,13 @@ Word32 DEPR_L_msuNs( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry ) L_var_out = DEPR_L_sub_c( L_var3, L_var_out, Carry ); #endif /* BASOP_NOGLOB */ - /* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */ +#ifdef WMOPS + multiCounter[currCounter].L_mult--; + multiCounter[currCounter].L_sub_c--; + multiCounter[currCounter].L_msuNs++; +#endif + /* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */ return ( L_var_out ); } @@ -1314,6 +1429,10 @@ Word32 L_add_o( Word32 L_var1, Word32 L_var2, Flag *Overflow ) } } +#ifdef WMOPS + multiCounter[currCounter].L_add++; +#endif + BASOP_CHECK(); @@ -1336,6 +1455,9 @@ Word32 L_add( Word32 L_var1, Word32 L_var2 ) } } +#ifdef WMOPS + multiCounter[currCounter].L_add++; +#endif return ( L_var_out ); } #endif /* BASOP_NOGLOB */ @@ -1394,6 +1516,10 @@ Word32 L_sub_o( Word32 L_var1, Word32 L_var2, Flag *Overflow ) } } +#ifdef WMOPS + multiCounter[currCounter].L_sub++; +#endif + BASOP_CHECK(); return ( L_var_out ); @@ -1415,6 +1541,9 @@ Word32 L_sub( Word32 L_var1, Word32 L_var2 ) } } +#ifdef WMOPS + multiCounter[currCounter].L_sub++; +#endif BASOP_CHECK(); return ( L_var_out ); @@ -1573,6 +1702,10 @@ Word32 DEPR_L_add_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) #endif /* BASOP_NOGLOB */ } +#ifdef WMOPS + multiCounter[currCounter].L_add_c++; +#endif + /* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */ @@ -1653,6 +1786,9 @@ Word32 DEPR_L_sub_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) #else /* BASOP_NOGLOB */ L_var_out = DEPR_L_add_c( L_var1, -L_var2, Carry ); #endif /* BASOP_NOGLOB */ +#ifdef WMOPS + multiCounter[currCounter].L_add_c--; +#endif } else { @@ -1713,6 +1849,10 @@ Word32 DEPR_L_sub_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) } } +#ifdef WMOPS + multiCounter[currCounter].L_sub_c++; +#endif + /* BASOP_CHECK(); Do not check for overflow here, function produces the carry bit instead */ @@ -1753,6 +1893,11 @@ Word32 L_negate( Word32 L_var1 ) L_var_out = ( L_var1 == MIN_32 ) ? MAX_32 : -L_var1; + +#ifdef WMOPS + multiCounter[currCounter].L_negate++; +#endif + BASOP_CHECK(); return ( L_var_out ); @@ -1809,6 +1954,9 @@ Word16 mult_ro( Word16 var1, Word16 var2, Flag *Overflow ) } var_out = saturate_o( L_product_arr, Overflow ); +#ifdef WMOPS + multiCounter[currCounter].mult_r++; +#endif return ( var_out ); } @@ -1830,7 +1978,9 @@ Word16 mult_r( Word16 var1, Word16 var2 ) } var_out = saturate( L_product_arr ); - +#ifdef WMOPS + multiCounter[currCounter].mult_r++; +#endif return ( var_out ); } @@ -1883,6 +2033,9 @@ Word32 L_shl_o( Word32 L_var1, Word16 var2, Flag *Overflow ) var2 = -32; var2 = -var2; L_var_out = L_shr( L_var1, var2 ); +#ifdef WMOPS + multiCounter[currCounter].L_shr--; +#endif } else { @@ -1916,6 +2069,10 @@ Word32 L_shl_o( Word32 L_var1, Word16 var2, Flag *Overflow ) } } +#ifdef WMOPS + multiCounter[currCounter].L_shl++; +#endif + BASOP_CHECK(); @@ -1934,6 +2091,9 @@ Word32 L_shl( Word32 L_var1, Word16 var2 ) var2 = -32; var2 = -var2; L_var_out = L_shr( L_var1, var2 ); +#ifdef WMOPS + multiCounter[currCounter].L_shr--; +#endif } else { @@ -1959,6 +2119,9 @@ Word32 L_shl( Word32 L_var1, Word16 var2 ) } } +#ifdef WMOPS + multiCounter[currCounter].L_shl++; +#endif BASOP_CHECK(); @@ -2010,6 +2173,9 @@ Word32 L_shr_o( Word32 L_var1, Word16 var2, Flag *Overflow ) var2 = -32; var2 = -var2; L_var_out = L_shl_o( L_var1, var2, Overflow ); +#ifdef WMOPS + multiCounter[currCounter].L_shl--; +#endif } else { @@ -2030,6 +2196,10 @@ Word32 L_shr_o( Word32 L_var1, Word16 var2, Flag *Overflow ) } } +#ifdef WMOPS + multiCounter[currCounter].L_shr++; +#endif + BASOP_CHECK(); @@ -2047,6 +2217,9 @@ Word32 L_shr( Word32 L_var1, Word16 var2 ) var2 = -32; var2 = -var2; L_var_out = L_shl( L_var1, var2 ); +#ifdef WMOPS + multiCounter[currCounter].L_shl--; +#endif } else { @@ -2067,6 +2240,9 @@ Word32 L_shr( Word32 L_var1, Word16 var2 ) } } +#ifdef WMOPS + multiCounter[currCounter].L_shr++; +#endif BASOP_CHECK(); @@ -2127,6 +2303,9 @@ Word16 shr_r( Word16 var1, Word16 var2 ) { var_out = shr( var1, var2 ); +#ifdef WMOPS + multiCounter[currCounter].shr--; +#endif if ( var2 > 0 ) { if ( ( var1 & ( (Word16) 1 << ( var2 - 1 ) ) ) != 0 ) @@ -2136,6 +2315,10 @@ Word16 shr_r( Word16 var1, Word16 var2 ) } } +#ifdef WMOPS + multiCounter[currCounter].shr_r++; +#endif + BASOP_CHECK(); return ( var_out ); @@ -2189,6 +2372,13 @@ Word16 mac_ro( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) L_var3 = L_add_o( L_var3, (Word32) 0x00008000L, Overflow ); var_out = extract_h( L_var3 ); +#ifdef WMOPS + multiCounter[currCounter].L_mac--; + multiCounter[currCounter].L_add--; + multiCounter[currCounter].extract_h--; + multiCounter[currCounter].mac_r++; +#endif + BASOP_CHECK(); @@ -2204,6 +2394,13 @@ Word16 mac_r( Word32 L_var3, Word16 var1, Word16 var2 ) L_var3 = L_add( L_var3, (Word32) 0x00008000L ); var_out = extract_h( L_var3 ); +#ifdef WMOPS + multiCounter[currCounter].L_mac--; + multiCounter[currCounter].L_add--; + multiCounter[currCounter].extract_h--; + multiCounter[currCounter].mac_r++; +#endif + BASOP_CHECK(); @@ -2258,6 +2455,12 @@ Word16 msu_ro( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) L_var3 = L_add_o( L_var3, (Word32) 0x00008000L, Overflow ); var_out = extract_h( L_var3 ); +#ifdef WMOPS + multiCounter[currCounter].L_msu--; + multiCounter[currCounter].L_add--; + multiCounter[currCounter].extract_h--; + multiCounter[currCounter].msu_r++; +#endif BASOP_CHECK(); return ( var_out ); @@ -2272,6 +2475,12 @@ Word16 msu_r( Word32 L_var3, Word16 var1, Word16 var2 ) L_var3 = L_add( L_var3, (Word32) 0x00008000L ); var_out = extract_h( L_var3 ); +#ifdef WMOPS + multiCounter[currCounter].L_msu--; + multiCounter[currCounter].L_add--; + multiCounter[currCounter].extract_h--; + multiCounter[currCounter].msu_r++; +#endif BASOP_CHECK(); return ( var_out ); @@ -2312,6 +2521,10 @@ Word32 L_deposit_h( Word16 var1 ) L_var_out = (Word32) var1 << 16; +#ifdef WMOPS + multiCounter[currCounter].L_deposit_h++; +#endif + BASOP_CHECK(); @@ -2353,6 +2566,10 @@ Word32 L_deposit_l( Word16 var1 ) L_var_out = (Word32) var1; +#ifdef WMOPS + multiCounter[currCounter].L_deposit_l++; +#endif + BASOP_CHECK(); @@ -2413,6 +2630,9 @@ Word32 L_shr_r( Word32 L_var1, Word16 var2 ) { L_var_out = L_shr( L_var1, var2 ); +#ifdef WMOPS + multiCounter[currCounter].L_shr--; +#endif if ( var2 > 0 ) { if ( ( L_var1 & ( (Word32) 1 << ( var2 - 1 ) ) ) != 0 ) @@ -2422,6 +2642,10 @@ Word32 L_shr_r( Word32 L_var1, Word16 var2 ) } } +#ifdef WMOPS + multiCounter[currCounter].L_shr_r++; +#endif + BASOP_CHECK(); @@ -2477,6 +2701,10 @@ Word32 L_abs( Word32 L_var1 ) } } +#ifdef WMOPS + multiCounter[currCounter].L_abs++; +#endif + BASOP_CHECK(); @@ -2542,6 +2770,10 @@ Word32 DEPR_L_sat_co( Word32 L_var1, Flag Overflow, Flag Carry ) #endif /* ! BASOP_NOGLOB */ } +#ifdef WMOPS + multiCounter[currCounter].L_sat++; +#endif + BASOP_CHECK(); @@ -2608,6 +2840,10 @@ Word16 norm_s( Word16 var1 ) } } +#ifdef WMOPS + multiCounter[currCounter].norm_s++; +#endif + BASOP_CHECK(); @@ -2685,6 +2921,11 @@ Word16 div_s( Word16 var1, Word16 var2 ) L_num = L_deposit_l( var1 ); L_denom = L_deposit_l( var2 ); +#ifdef WMOPS + multiCounter[currCounter].L_deposit_l--; + multiCounter[currCounter].L_deposit_l--; +#endif + for ( iteration = 0; iteration < 15; iteration++ ) { var_out <<= 1; @@ -2694,11 +2935,19 @@ Word16 div_s( Word16 var1, Word16 var2 ) { L_num = L_sub( L_num, L_denom ); var_out = add( var_out, 1 ); +#ifdef WMOPS + multiCounter[currCounter].L_sub--; + multiCounter[currCounter].add--; +#endif } } } } +#ifdef WMOPS + multiCounter[currCounter].div_s++; +#endif + BASOP_CHECK(); @@ -2765,6 +3014,10 @@ Word16 norm_l( Word32 L_var1 ) } } +#ifdef WMOPS + multiCounter[currCounter].norm_l++; +#endif + BASOP_CHECK(); @@ -2827,6 +3080,13 @@ Word32 L_mls_o( Word32 Lv, Word16 v, Flag *Overflow ) Temp = L_shr( Temp, (Word16) 15 ); Temp = L_mac_o( Temp, v, extract_h( Lv ), Overflow ); +#ifdef WMOPS + multiCounter[currCounter].L_shr--; + multiCounter[currCounter].L_mac--; + multiCounter[currCounter].extract_h--; + multiCounter[currCounter].L_mls++; +#endif + BASOP_CHECK(); return Temp; @@ -2842,6 +3102,13 @@ Word32 L_mls( Word32 Lv, Word16 v ) Temp = L_shr( Temp, (Word16) 15 ); Temp = L_mac( Temp, v, extract_h( Lv ) ); +#ifdef WMOPS + multiCounter[currCounter].L_shr--; + multiCounter[currCounter].L_mac--; + multiCounter[currCounter].extract_h--; + multiCounter[currCounter].L_mls++; +#endif + BASOP_CHECK(); return Temp; @@ -2892,6 +3159,9 @@ Word16 div_l( Word32 L_num, Word16 den ) Word32 L_den; Word16 iteration; +#ifdef WMOPS + multiCounter[currCounter].div_l++; +#endif if ( den == (Word16) 0 ) { @@ -2906,6 +3176,9 @@ Word16 div_l( Word32 L_num, Word16 den ) } L_den = L_deposit_h( den ); +#ifdef WMOPS + multiCounter[currCounter].L_deposit_h--; +#endif if ( L_num >= L_den ) { @@ -2918,14 +3191,25 @@ Word16 div_l( Word32 L_num, Word16 den ) { L_num = L_shr( L_num, (Word16) 1 ); L_den = L_shr( L_den, (Word16) 1 ); +#ifdef WMOPS + multiCounter[currCounter].L_shr -= 2; +#endif for ( iteration = (Word16) 0; iteration < (Word16) 15; iteration++ ) { var_out = shl( var_out, (Word16) 1 ); L_num = L_shl( L_num, (Word16) 1 ); +#ifdef WMOPS + multiCounter[currCounter].shl--; + multiCounter[currCounter].L_shl--; +#endif if ( L_num >= L_den ) { L_num = L_sub( L_num, L_den ); var_out = add( var_out, (Word16) 1 ); +#ifdef WMOPS + multiCounter[currCounter].L_sub--; + multiCounter[currCounter].add--; +#endif } } @@ -2977,6 +3261,9 @@ Word16 DEPR_i_mult( Word16 a, Word16 b ) return a * b; #else Word32 /*register*/ c = a * b; +#ifdef WMOPS + multiCounter[currCounter].i_mult++; +#endif return saturate( c ); #endif } @@ -3022,7 +3309,9 @@ Word32 L_mult0( Word16 var1, Word16 var2 ) L_var_out = (Word32) var1 * (Word32) var2; - BASOP_CHECK(); +#ifdef WMOPS + multiCounter[currCounter].L_mult0++; +#endif return ( L_var_out ); @@ -3068,8 +3357,13 @@ Word32 L_mac0_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) L_product = L_mult0( var1, var2 ); L_var_out = L_add_o( L_var3, L_product, Overflow ); - BASOP_CHECK(); +#ifdef WMOPS + multiCounter[currCounter].L_mac0++; + multiCounter[currCounter].L_mult0--; + multiCounter[currCounter].L_add--; +#endif + BASOP_CHECK(); return ( L_var_out ); } @@ -3083,6 +3377,12 @@ Word32 L_mac0( Word32 L_var3, Word16 var1, Word16 var2 ) L_product = L_mult0( var1, var2 ); L_var_out = L_add( L_var3, L_product ); +#ifdef WMOPS + multiCounter[currCounter].L_mac0++; + multiCounter[currCounter].L_mult0--; + multiCounter[currCounter].L_add--; +#endif + BASOP_CHECK(); @@ -3129,8 +3429,13 @@ Word32 L_msu0_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) L_product = L_mult0( var1, var2 ); L_var_out = L_sub_o( L_var3, L_product, Overflow ); - BASOP_CHECK(); +#ifdef WMOPS + multiCounter[currCounter].L_msu0++; + multiCounter[currCounter].L_mult0--; + multiCounter[currCounter].L_sub--; +#endif + BASOP_CHECK(); return ( L_var_out ); } @@ -3144,6 +3449,12 @@ Word32 L_msu0( Word32 L_var3, Word16 var1, Word16 var2 ) L_product = L_mult0( var1, var2 ); L_var_out = L_sub( L_var3, L_product ); +#ifdef WMOPS + multiCounter[currCounter].L_msu0++; + multiCounter[currCounter].L_mult0--; + multiCounter[currCounter].L_sub--; +#endif + BASOP_CHECK(); diff --git a/lib_com/basop_lsf_tools.c b/lib_com/basop_lsf_tools.c index eddce99e8..103fe7000 100644 --- a/lib_com/basop_lsf_tools.c +++ b/lib_com/basop_lsf_tools.c @@ -38,7 +38,6 @@ #include #include "options.h" #include "basop_proto_func.h" -#include "control.h" #include "basop_util.h" #define WMC_TOOL_SKIP diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index ff42b0eb4..f3247f2d0 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -41,7 +41,7 @@ #include "rom_com.h" #include "basop_settings.h" #include "basop_mpy.h" -#include "control.h" +#include "stl.h" #include "cnst.h" #define WMC_TOOL_SKIP diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 92331dc9a..c4454fd62 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -46,19 +46,16 @@ #define IVAS_NUM_FRAMES_PER_SEC 50 #define IVAS_MAX_FRAME_SIZE ( 48000 / IVAS_NUM_FRAMES_PER_SEC ) - #define IVAS_MAX_BITS_PER_FRAME ( 512000 / IVAS_NUM_FRAMES_PER_SEC ) -#define IVAS_MAX_NUM_OBJECTS 4 -#define IVAS_MAX_INPUT_CHANNELS 16 -#define IVAS_MAX_OUTPUT_CHANNELS 16 -#define IVAS_CLDFB_NO_COL_MAX 16 -#define IVAS_CLDFB_NO_CHANNELS_MAX 60 -#define IVAS_MAX_INPUT_LFE_CHANNELS 4 +#define IVAS_MAX_NUM_OBJECTS 4 +#define IVAS_MAX_INPUT_CHANNELS 16 +#define IVAS_MAX_OUTPUT_CHANNELS 16 +#define IVAS_CLDFB_NO_COL_MAX 16 +#define IVAS_CLDFB_NO_CHANNELS_MAX 60 #define IVAS_MAX_PARAM_SPATIAL_SUBFRAMES 4 - -#define IVAS_ROOM_ABS_COEFF 6 +#define IVAS_ROOM_ABS_COEFF 6 /*----------------------------------------------------------------------------------* * Common API enum for output audio configurations @@ -150,6 +147,15 @@ typedef enum } IVAS_HEAD_ORIENT_TRK_T; +typedef enum +{ + IVAS_RENDER_FRAMESIZE_UNKNOWN = 0, + IVAS_RENDER_FRAMESIZE_5MS = 1, + IVAS_RENDER_FRAMESIZE_10MS = 2, + IVAS_RENDER_FRAMESIZE_20MS = 4 + +} IVAS_RENDER_FRAMESIZE; + typedef struct ivas_masa_metadata_frame_struct *IVAS_MASA_METADATA_HANDLE; typedef struct ivas_masa_decoder_ext_out_meta_struct *IVAS_MASA_DECODER_EXT_OUT_META_HANDLE; diff --git a/lib_com/control.h b/lib_com/control.h deleted file mode 100644 index 725163728..000000000 --- a/lib_com/control.h +++ /dev/null @@ -1,82 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -/*==================================================================================== - EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 - ====================================================================================*/ - -#ifndef _CONTROL_H -#define _CONTROL_H - -/* BASOP -> FLC brigde: flow control instructions */ - -#include "stl.h" - -#define FOR( a ) \ - if ( incrFor(), 0 ) \ - ; \ - else \ - for ( a ) -static __inline void incrFor( void ) -{ -} - -#define WHILE( a ) \ - if ( incrFlcWhile(), 0 ) \ - ; \ - else \ - while ( a ) -static __inline void incrFlcWhile( void ) -{ -} - -#define DO do - -#define IF( a ) if ( incrIf(), a ) -static __inline void incrIf( void ) -{ -} - -#define ELSE else - -#define SWITCH( a ) switch ( incrSwitch(), a ) -static __inline void incrSwitch( void ) -{ -} - -#define CONTINUE continue - -#define BREAK break - -#define GOTO goto - -#endif /* _CONTROL_H */ diff --git a/lib_com/enh1632.c b/lib_com/enh1632.c index 1dd192faa..4e53ba695 100644 --- a/lib_com/enh1632.c +++ b/lib_com/enh1632.c @@ -145,6 +145,9 @@ Word16 lshl( Word16 var1, Word16 var2 ) { var2 = -var2; var_out = lshr( var1, var2 ); +#ifdef WMOPS + multiCounter[currCounter].lshr--; +#endif } else { @@ -162,6 +165,10 @@ Word16 lshl( Word16 var1, Word16 var2 ) } } +#ifdef WMOPS + multiCounter[currCounter].lshl++; +#endif + BASOP_CHECK(); @@ -208,6 +215,9 @@ Word16 lshr( Word16 var1, Word16 var2 ) { var2 = -var2; var_out = lshl( var1, var2 ); +#ifdef WMOPS + multiCounter[currCounter].lshl--; +#endif } else { @@ -227,6 +237,10 @@ Word16 lshr( Word16 var1, Word16 var2 ) } } +#ifdef WMOPS + multiCounter[currCounter].lshr++; +#endif + BASOP_CHECK(); @@ -274,6 +288,9 @@ Word32 L_lshl( Word32 L_var1, Word16 var2 ) { var2 = -var2; L_var_out = L_lshr( L_var1, var2 ); +#ifdef WMOPS + multiCounter[currCounter].L_lshr--; +#endif } else { @@ -291,8 +308,11 @@ Word32 L_lshl( Word32 L_var1, Word16 var2 ) } } - BASOP_CHECK(); +#ifdef WMOPS + multiCounter[currCounter].L_lshl++; +#endif + BASOP_CHECK(); return ( L_var_out ); } @@ -338,6 +358,9 @@ Word32 L_lshr( Word32 L_var1, Word16 var2 ) { var2 = -var2; L_var_out = L_lshl( L_var1, var2 ); +#ifdef WMOPS + multiCounter[currCounter].L_lshl--; +#endif } else { @@ -357,6 +380,10 @@ Word32 L_lshr( Word32 L_var1, Word16 var2 ) } } +#ifdef WMOPS + multiCounter[currCounter].L_lshr++; +#endif + BASOP_CHECK(); @@ -400,13 +427,22 @@ Word16 shl_r( Word16 var1, Word16 var2 ) if ( var2 >= 0 ) { var_out = shl( var1, var2 ); +#ifdef WMOPS + multiCounter[currCounter].shl--; +#endif } else { var2 = -var2; var_out = shr_r( var1, var2 ); +#ifdef WMOPS + multiCounter[currCounter].shr_r--; +#endif } +#ifdef WMOPS + multiCounter[currCounter].shl_r++; +#endif return ( var_out ); } @@ -448,13 +484,22 @@ Word32 L_shl_r( Word32 L_var1, Word16 var2 ) if ( var2 >= 0 ) { var_out = L_shl( L_var1, var2 ); +#ifdef WMOPS + multiCounter[currCounter].L_shl--; +#endif } else { var2 = -var2; var_out = L_shr_r( L_var1, var2 ); +#ifdef WMOPS + multiCounter[currCounter].L_shr_r--; +#endif } +#ifdef WMOPS + multiCounter[currCounter].L_shl_r++; +#endif return ( var_out ); } @@ -497,6 +542,13 @@ Word16 rotr( Word16 var1, Word16 var2, Word16 *var3 ) *var3 = s_and( var1, 0x1 ); var_out = s_or( lshr( var1, 1 ), lshl( var2, 15 ) ); +#ifdef WMOPS + multiCounter[currCounter].s_and--; + multiCounter[currCounter].lshl--; + multiCounter[currCounter].lshr--; + multiCounter[currCounter].s_or--; + multiCounter[currCounter].rotr++; +#endif return ( var_out ); } @@ -540,6 +592,13 @@ Word16 rotl( Word16 var1, Word16 var2, Word16 *var3 ) var_out = s_or( lshl( var1, 1 ), s_and( var2, 0x1 ) ); +#ifdef WMOPS + multiCounter[currCounter].lshr--; + multiCounter[currCounter].s_and--; + multiCounter[currCounter].lshl--; + multiCounter[currCounter].s_or--; + multiCounter[currCounter].rotl++; +#endif return ( var_out ); } @@ -583,6 +642,15 @@ Word32 L_rotr( Word32 L_var1, Word16 var2, Word16 *var3 ) L_var_out = L_or( L_lshr( L_var1, 1 ), L_lshl( L_deposit_l( var2 ), 31 ) ); +#ifdef WMOPS + multiCounter[currCounter].extract_l--; + multiCounter[currCounter].s_and--; + multiCounter[currCounter].L_deposit_l--; + multiCounter[currCounter].L_lshl--; + multiCounter[currCounter].L_lshr--; + multiCounter[currCounter].L_or--; + multiCounter[currCounter].L_rotr++; +#endif return ( L_var_out ); } @@ -626,6 +694,15 @@ Word32 L_rotl( Word32 L_var1, Word16 var2, Word16 *var3 ) L_var_out = L_or( L_lshl( L_var1, 1 ), L_deposit_l( s_and( var2, 0x1 ) ) ); +#ifdef WMOPS + multiCounter[currCounter].L_lshr--; + multiCounter[currCounter].extract_l--; + multiCounter[currCounter].s_and--; + multiCounter[currCounter].L_deposit_l--; + multiCounter[currCounter].L_lshl--; + multiCounter[currCounter].L_or--; + multiCounter[currCounter].L_rotl++; +#endif return ( L_var_out ); } diff --git a/lib_com/enh1632.h b/lib_com/enh1632.h index 9216ea6c2..8e943d42f 100644 --- a/lib_com/enh1632.h +++ b/lib_com/enh1632.h @@ -131,6 +131,9 @@ static __inline Word16 s_max( Word16 var1, Word16 var2 ) else var_out = var2; +#ifdef WMOPS + multiCounter[currCounter].s_max++; +#endif return ( var_out ); } @@ -173,6 +176,9 @@ static __inline Word16 s_min( Word16 var1, Word16 var2 ) else var_out = var2; +#ifdef WMOPS + multiCounter[currCounter].s_min++; +#endif return ( var_out ); } @@ -215,6 +221,9 @@ static __inline Word32 L_max( Word32 L_var1, Word32 L_var2 ) else L_var_out = L_var2; +#ifdef WMOPS + multiCounter[currCounter].L_max++; +#endif return ( L_var_out ); } @@ -257,6 +266,9 @@ static __inline Word32 L_min( Word32 L_var1, Word32 L_var2 ) else L_var_out = L_var2; +#ifdef WMOPS + multiCounter[currCounter].L_min++; +#endif return ( L_var_out ); } @@ -297,6 +309,9 @@ static __inline Word16 s_and( Word16 var1, Word16 var2 ) var_out = var1 & var2; +#ifdef WMOPS + multiCounter[currCounter].s_and++; +#endif return ( var_out ); } @@ -337,6 +352,9 @@ static __inline Word32 L_and( Word32 L_var1, Word32 L_var2 ) L_var_out = L_var1 & L_var2; +#ifdef WMOPS + multiCounter[currCounter].L_and++; +#endif return ( L_var_out ); } @@ -377,6 +395,9 @@ static __inline Word16 s_or( Word16 var1, Word16 var2 ) var_out = var1 | var2; +#ifdef WMOPS + multiCounter[currCounter].s_or++; +#endif return ( var_out ); } @@ -418,6 +439,9 @@ static __inline Word32 L_or( Word32 L_var1, Word32 L_var2 ) L_var_out = L_var1 | L_var2; +#ifdef WMOPS + multiCounter[currCounter].L_or++; +#endif return ( L_var_out ); } @@ -458,6 +482,9 @@ static __inline Word16 s_xor( Word16 var1, Word16 var2 ) var_out = var1 ^ var2; +#ifdef WMOPS + multiCounter[currCounter].s_xor++; +#endif return ( var_out ); } @@ -498,6 +525,9 @@ static __inline Word32 L_xor( Word32 L_var1, Word32 L_var2 ) L_var_out = L_var1 ^ L_var2; +#ifdef WMOPS + multiCounter[currCounter].L_xor++; +#endif return ( L_var_out ); } diff --git a/lib_com/enh40.c b/lib_com/enh40.c index 8a48cece3..d77e23b23 100644 --- a/lib_com/enh40.c +++ b/lib_com/enh40.c @@ -225,8 +225,11 @@ Word40 L40_shl_o( Word40 L40_var1, Word16 var2, Flag *Overflow ) } } - BASOP_CHECK(); +#ifdef WMOPS + multiCounter[currCounter].L40_shl++; +#endif + BASOP_CHECK(); return ( L40_var_out ); } @@ -281,6 +284,10 @@ Word40 L40_shl( Word40 L40_var1, Word16 var2 ) } } +#ifdef WMOPS + multiCounter[currCounter].L40_shl++; +#endif + BASOP_CHECK(); @@ -336,6 +343,9 @@ Word40 L40_shr( Word40 L40_var1, Word16 var2 ) L40_var_out = L40_var1 >> var2; } +#ifdef WMOPS + multiCounter[currCounter].L40_shr++; +#endif return ( L40_var_out ); } @@ -374,6 +384,10 @@ Word40 L40_negate( Word40 L40_var1 ) L40_var_out = L40_add( ~L40_var1, 0x01 ); +#ifdef WMOPS + multiCounter[currCounter].L40_negate++; +#endif + return ( L40_var_out ); } @@ -440,6 +454,11 @@ Word40 L40_add_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow ) } #endif +#ifdef WMOPS + multiCounter[currCounter].L40_add++; +#endif + + BASOP_CHECK(); @@ -501,6 +520,10 @@ Word40 L40_add( Word40 L40_var1, Word40 L40_var2 ) } #endif +#ifdef WMOPS + multiCounter[currCounter].L40_add++; +#endif + BASOP_CHECK(); @@ -596,6 +619,10 @@ Word40 L40_sub_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow ) } #endif +#ifdef WMOPS + multiCounter[currCounter].L40_sub++; +#endif + BASOP_CHECK(); @@ -633,6 +660,10 @@ Word40 L40_sub( Word40 L40_var1, Word40 L40_var2 ) } #endif +#ifdef WMOPS + multiCounter[currCounter].L40_sub++; +#endif + BASOP_CHECK(); @@ -680,6 +711,9 @@ Word40 L40_abs( Word40 L40_var1 ) L40_var_out = L40_var1; } +#ifdef WMOPS + multiCounter[currCounter].L40_abs++; +#endif return ( L40_var_out ); } @@ -723,6 +757,9 @@ Word40 L40_max( Word40 L40_var1, Word40 L40_var2 ) else L40_var_out = L40_var1; +#ifdef WMOPS + multiCounter[currCounter].L40_max++; +#endif return ( L40_var_out ); } @@ -766,6 +803,9 @@ Word40 L40_min( Word40 L40_var1, Word40 L40_var2 ) else L40_var_out = L40_var2; +#ifdef WMOPS + multiCounter[currCounter].L40_min++; +#endif return ( L40_var_out ); } @@ -832,6 +872,10 @@ Word32 L_saturate40_o( Word40 L40_var1, Flag *Overflow ) L_var_out = L_Extract40( L40_var1 ); +#ifdef WMOPS + multiCounter[currCounter].L_saturate40++; +#endif + BASOP_CHECK(); @@ -860,6 +904,10 @@ Word32 L_saturate40( Word40 L40_var1 ) L_var_out = L_Extract40( L40_var1 ); +#ifdef WMOPS + multiCounter[currCounter].L_saturate40++; +#endif + BASOP_CHECK(); @@ -928,8 +976,20 @@ void Mpy_32_16_ss( Word32 L_var1, Word16 var2, Word32 *L_varout_h, UWord16 *varo L40_var1 = L40_mac( L40_var1, var2, var1_h ); *L_varout_h = L_Extract40( L40_var1 ); + +#ifdef WMOPS + multiCounter[currCounter].extract_l--; + multiCounter[currCounter].extract_h--; + multiCounter[currCounter].Extract40_L--; + multiCounter[currCounter].L40_shr--; + multiCounter[currCounter].L40_mac--; + multiCounter[currCounter].L_Extract40--; +#endif } +#ifdef WMOPS + multiCounter[currCounter].Mpy_32_16_ss++; +#endif return; } @@ -1004,8 +1064,20 @@ void Mpy_32_32_ss( Word32 L_var1, Word32 L_var2, Word32 *L_varout_h, UWord32 *L_ L40_var1 = L40_mac( L40_var1, var1_h, var2_h ); *L_varout_h = L_Extract40( L40_var1 ); + +#ifdef WMOPS + multiCounter[currCounter].extract_l -= 2; + multiCounter[currCounter].extract_h -= 2; + multiCounter[currCounter].L_Extract40 -= 3; + multiCounter[currCounter].L40_shr -= 2; + multiCounter[currCounter].L40_add -= 2; + multiCounter[currCounter].L40_mac--; +#endif } +#ifdef WMOPS + multiCounter[currCounter].Mpy_32_32_ss++; +#endif return; } @@ -1039,7 +1111,7 @@ void Mpy_32_32_ss( Word32 L_var1, Word32 L_var2, Word32 *L_varout_h, UWord32 *L_ * * Return Value : * - * L40_var_out 40 bit long signed integer (Word40) whose value falls in + * L_var_out 32 bit long unsigned integer (UWord32) whose value falls in * the range : MIN_40 <= L40_var_out <= MAX_40. * *****************************************************************************/ @@ -1051,6 +1123,9 @@ Word40 L40_lshl( Word40 L40_var1, Word16 var2 ) { var2 = -var2; L40_var_out = L40_lshr( L40_var1, var2 ); +#ifdef WMOPS + multiCounter[currCounter].L40_lshr--; +#endif } else { @@ -1063,6 +1138,10 @@ Word40 L40_lshl( Word40 L40_var1, Word16 var2 ) L40_var_out = L40_set( L40_var_out ); } +#ifdef WMOPS + multiCounter[currCounter].L40_lshl++; +#endif + BASOP_CHECK(); @@ -1110,6 +1189,9 @@ Word40 L40_lshr( Word40 L40_var1, Word16 var2 ) { var2 = -var2; L40_var_out = L40_lshl( L40_var1, var2 ); +#ifdef WMOPS + multiCounter[currCounter].L40_lshl--; +#endif } else { @@ -1125,6 +1207,10 @@ Word40 L40_lshr( Word40 L40_var1, Word16 var2 ) } } +#ifdef WMOPS + multiCounter[currCounter].L40_lshr++; +#endif + BASOP_CHECK(); diff --git a/lib_com/enh40.h b/lib_com/enh40.h index a55bd925e..8c34ec36a 100644 --- a/lib_com/enh40.h +++ b/lib_com/enh40.h @@ -54,7 +54,6 @@ #ifndef _ENH40_H #define _ENH40_H - #include "stl.h" #if defined( BASOP_NOGLOB ) || defined( _MSC_VER ) @@ -62,11 +61,9 @@ #define MIN_40 ( 0xffffff8000000000 ) #endif - #define L40_OVERFLOW_OCCURED( L40_var1 ) ( Overflow = 1, exit( 1 ), L40_var1 ) #define L40_UNDERFLOW_OCCURED( L40_var1 ) ( Overflow = 1, exit( 2 ), L40_var1 ) - /***************************************************************************** * * Prototypes for enhanced 40 bit arithmetic operators @@ -114,7 +111,6 @@ Word40 L40_max( Word40 L40_var1, Word40 L40_var2 ); Word40 L40_min( Word40 L40_var1, Word40 L40_var2 ); Word32 L_saturate40( Word40 L40_var1 ); Word16 norm_L40( Word40 L40_var1 ); - #ifdef BASOP_NOGLOB /* * Overflowing operators @@ -124,7 +120,6 @@ Word40 L40_add_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow ); Word40 L40_sub_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow ); Word32 L_saturate40_o( Word40 L40_var1, Flag *Overflow ); #endif /* BASOP_NOGLOB */ - /*#ifdef _MSC_VER*/ static __inline Word40 L40_set( Word40 L40_var1 ) { @@ -142,6 +137,9 @@ static __inline Word40 L40_set( Word40 L40_var1 ) L40_var_out = L40_var_out | 0xffffff0000000000LL; #endif +#ifdef WMOPS + multiCounter[currCounter].L40_set++; +#endif return ( L40_var_out ); } @@ -154,6 +152,9 @@ static __inline UWord16 Extract40_H( Word40 L40_var1 ) var_out = (UWord16) ( L40_var1 >> 16 ); +#ifdef WMOPS + multiCounter[currCounter].Extract40_H++; +#endif return ( var_out ); } @@ -165,6 +166,9 @@ static __inline UWord16 Extract40_L( Word40 L40_var1 ) var_out = (UWord16) ( L40_var1 ); +#ifdef WMOPS + multiCounter[currCounter].Extract40_L++; +#endif return ( var_out ); } @@ -176,6 +180,9 @@ static __inline UWord32 L_Extract40( Word40 L40_var1 ) L_var_out = (UWord32) L40_var1; +#ifdef WMOPS + multiCounter[currCounter].L_Extract40++; +#endif return ( L_var_out ); } @@ -191,13 +198,25 @@ static __inline Word40 L40_deposit_h( Word16 var1 ) if ( var1 & 0x8000 ) { L40_var_out = L40_set( L40_var_out | 0xff00000000 ); + +#ifdef WMOPS + multiCounter[currCounter].L40_set--; +#endif + } #else if ( var1 & 0x8000 ) { L40_var_out = L40_set( L40_var_out | 0xff00000000LL ); + +#ifdef WMOPS + multiCounter[currCounter].L40_set--; #endif } +#endif +#ifdef WMOPS + multiCounter[currCounter].L40_deposit_h++; +#endif return ( L40_var_out ); } @@ -213,13 +232,25 @@ static __inline Word40 L40_deposit_l( Word16 var1 ) if ( var1 & 0x8000 ) { L40_var_out = L40_set( L40_var_out | 0xffffff0000 ); + +#ifdef WMOPS + multiCounter[currCounter].L40_set--; +#endif + } #else if ( var1 & 0x8000 ) { L40_var_out = L40_set( L40_var_out | 0xffffff0000LL ); + +#ifdef WMOPS + multiCounter[currCounter].L40_set--; #endif } +#endif +#ifdef WMOPS + multiCounter[currCounter].L40_deposit_l++; +#endif return ( L40_var_out ); } @@ -235,13 +266,25 @@ static __inline Word40 L40_deposit32( Word32 L_var1 ) if ( L_var1 & 0x80000000 ) { L40_var_out = L40_set( L40_var_out | 0xff00000000 ); + +#ifdef WMOPS + multiCounter[currCounter].L40_set--; +#endif + } #else if ( L_var1 & 0x80000000 ) { L40_var_out = L40_set( L40_var_out | 0xff00000000LL ); + +#ifdef WMOPS + multiCounter[currCounter].L40_set--; #endif } +#endif +#ifdef WMOPS + multiCounter[currCounter].L40_deposit32++; +#endif return ( L40_var_out ); } @@ -261,6 +304,11 @@ static __inline Word40 L40_round( Word40 L40_var1 ) L40_var_out = L40_add( 0x8000, L40_var1 ); L40_var_out = L40_var_out & L40_constant; +#ifdef WMOPS + multiCounter[currCounter].L40_set--; + multiCounter[currCounter].L40_add--; + multiCounter[currCounter].L40_round++; +#endif return ( L40_var_out ); } @@ -272,6 +320,12 @@ static __inline Word16 round40( Word40 L40_var1 ) var_out = extract_h( L_saturate40( L40_round( L40_var1 ) ) ); +#ifdef WMOPS + multiCounter[currCounter].L40_round--; + multiCounter[currCounter].L_saturate40--; + multiCounter[currCounter].extract_h--; + multiCounter[currCounter].round40++; +#endif return ( var_out ); } @@ -288,6 +342,9 @@ static __inline Word40 L40_mult( Word16 var1, Word16 var2 ) /* Below line can not overflow, so we can use << instead of L40_shl. */ L40_var_out = L40_var_out << 1; +#ifdef WMOPS + multiCounter[currCounter].L40_mult++; +#endif return ( L40_var_out ); } @@ -300,6 +357,9 @@ static __inline Word40 L40_mac( Word40 L40_var1, Word16 var2, Word16 var3 ) L40_var_out = L40_mult( var2, var3 ); L40_var_out = L40_add( L40_var1, L40_var_out ); +#ifdef WMOPS + multiCounter[currCounter].L40_mac++; +#endif return ( L40_var_out ); } diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 09241a543..6a50483e5 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -182,6 +182,7 @@ typedef enum TC_BUFFER_MODE_BUFFER } TC_BUFFER_MODE; + /*----------------------------------------------------------------------------------* * IVAS Bitrates *----------------------------------------------------------------------------------*/ @@ -1198,7 +1199,6 @@ enum #define MASA_STEREO_MIN_BITRATE IVAS_24k4 #define MAXIMUM_OMASA_FREQ_BANDS 8 /* Corresponds to maximum number of coding bands at 32 kbps */ #define OMASA_STEREO_SW_CNT_MAX 100 - #define MASA_BIT_REDUCT_PARAM 10 #define MASA_MAXIMUM_TWO_DIR_BANDS 24 #define NBITS_HR_COH 4 @@ -1323,7 +1323,6 @@ typedef struct { typedef struct { HUFF_ELEMENTS df0; HUFF_ELEMENTS df; - HUFF_ELEMENTS dt; } HUFF_TABLE; typedef enum { @@ -1331,24 +1330,17 @@ typedef enum { BETA } PAR_TYPE; -typedef enum { - FINE, - COARSE -} QUANT_TYPE; - typedef struct { int16_t nquant; int16_t offset; float data[35]; } ACPL_QUANT_TABLE; - typedef struct { - const int16_t (*alpha[2])[2]; - const int16_t (*beta[2])[2]; + const int16_t (*alpha)[2]; + const int16_t (*beta)[2]; } HUFF_NODE_TABLE; - /*----------------------------------------------------------------------------------* * Parametric MC Constants *----------------------------------------------------------------------------------*/ @@ -1725,29 +1717,11 @@ typedef enum * Early Reflection constants *----------------------------------------------------------------------------------*/ -#define ER_ABS_COEFF 6 -#define ER_MAX_SOURCES 25 -#define ER_REF_ORDER 1 -#define ER_NUM_REF 6 - -#define ER_AIR_COEFF (0.00137f) -#define ER_SOUND_SPEED (343.0f) -#define ER_MIN_WALL_DIST (0.1f) -#define ER_EUCLIDEAN_SCALE (1.29246971E-26f) - -#define ER_DEFAULT_ROOM_L (3.0f) -#define ER_DEFAULT_ROOM_W (4.0f) -#define ER_DEFAULT_ROOM_H (5.0f) #define ER_RADIUS (1.0f) #define ER_LIST_ORIGIN_X (0.0f) #define ER_LIST_ORIGIN_Y (0.0f) #define ER_LIST_HEIGHT (1.6f) -#define ER_MIN_ROOM_DIMENSION (1.0f) -#define ER_MAX_ROOM_DIMENSION (999.0f) -#define ER_MIN_ABS_COEFF (0.0f) -#define ER_MAX_ABS_COEFF (1.0f) - /*----------------------------------------------------------------------------------* * Stereo downmix EVS constants diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index 22b726f31..a490858c8 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -162,7 +162,10 @@ ivas_error ivas_dirac_config( hConfig->dec_param_estim = FALSE; if ( ivas_format == SBA_FORMAT || ivas_format == SBA_ISM_FORMAT ) /* skip for MASA decoder */ { - if ( ( error = ivas_dirac_sba_config( hQMetaData, element_mode, ivas_total_brate, sba_order, hConfig->nbands - spar_dirac_split_band ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_dirac_sba_config( hQMetaData, element_mode, ivas_total_brate, sba_order, hConfig->nbands - spar_dirac_split_band + , + ivas_format + ) ) != IVAS_ERR_OK ) { return error; } @@ -319,7 +322,10 @@ void ivas_get_dirac_sba_max_md_bits( int16_t *bits_frame_nominal, int16_t *metadata_max_bits, int16_t *qmetadata_max_bit_req, - const int16_t nbands ) + const int16_t nbands + , + IVAS_FORMAT ivas_format +) { if ( sba_total_brate <= IVAS_13k2 ) { @@ -335,6 +341,11 @@ void ivas_get_dirac_sba_max_md_bits( { *bits_frame_nominal = ACELP_16k40 / FRAMES_PER_SEC; *metadata_max_bits = 103; + /* OSBA needs an additional 2-bits safety margin to avoid acelp crashes */ + if ( ivas_format == SBA_ISM_FORMAT ) + { + ( *metadata_max_bits ) -= 3; + } } else if ( sba_total_brate <= IVAS_32k ) { @@ -390,6 +401,8 @@ ivas_error ivas_dirac_sba_config( int32_t sba_total_brate, /* i : SBA total bitrate */ const int16_t sba_order, /* i : Ambisonic (SBA) order */ const int16_t nbands /* i : number of frequency bands */ + , + IVAS_FORMAT ivas_format ) { int16_t nbands_coded; @@ -452,7 +465,10 @@ ivas_error ivas_dirac_sba_config( } } - ivas_get_dirac_sba_max_md_bits( sba_total_brate, &hQMetaData->bits_frame_nominal, &hQMetaData->metadata_max_bits, &hQMetaData->qmetadata_max_bit_req, hQMetaData->q_direction[0].cfg.nbands ); + ivas_get_dirac_sba_max_md_bits( sba_total_brate, &hQMetaData->bits_frame_nominal, &hQMetaData->metadata_max_bits, &hQMetaData->qmetadata_max_bit_req, hQMetaData->q_direction[0].cfg.nbands + , + ivas_format + ); return error; } diff --git a/lib_com/ivas_ism_com.c b/lib_com/ivas_ism_com.c index b8e919ad5..d8cb958cc 100644 --- a/lib_com/ivas_ism_com.c +++ b/lib_com/ivas_ism_com.c @@ -582,11 +582,7 @@ void ivas_ism_metadata_close( { int16_t n; -#ifdef FIX_852_FIX_HANDLE_DEREF if ( hIsmMetaData == NULL || *hIsmMetaData == NULL ) -#else - if ( hIsmMetaData == NULL || hIsmMetaData == NULL ) -#endif { return; } diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 7af0edb72..68f3a9de6 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -189,16 +189,17 @@ ivas_error pre_proc_front_ivas( const float tdm_lsp_new_PCh[M], /* i : unq. LSPs of primary channel */ const float currFlatness, /* i : flatness parameter */ const int16_t tdm_ratio_idx, /* i : Current Ratio_L index */ - float fr_bands_LR[CPE_CHANNELS][2 * NB_BANDS], /* i : energy in frequency bands */ - const float Etot_LR[CPE_CHANNELS], /* i : total energy Left & Right channel */ - float lf_E_LR[CPE_CHANNELS][2 * VOIC_BINS], /* i : per bin spectrum energy in lf, LR channels */ - const int16_t localVAD_HE_SAD_LR[CPE_CHANNELS], /* i : HE-SAD flag without hangover, LR channels */ + float fr_bands_LR[][2 * NB_BANDS], /* i : energy in frequency bands */ + const float Etot_LR[], /* i : total energy Left & Right channel */ + float lf_E_LR[][2 * VOIC_BINS], /* i : per bin spectrum energy in lf, LR channels */ + const int16_t localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover, LR channels */ float band_energies_LR[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN */ const int16_t flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz */ const int16_t front_vad_flag, /* i : front-VAD flag to overwrite VAD decision */ const int16_t force_front_vad, /* i : flag to force VAD decision */ const int16_t front_vad_dtx_flag, /* i : front-VAD DTX flag to overwrite VAD decision*/ const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ const int32_t ivas_total_brate /* i : IVAS total bitrate */ ); @@ -294,13 +295,11 @@ ivas_error ivas_init_decoder( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); -#ifdef NONBE_FIX_839_MC_RS_CHANNEL_ALLOC ivas_error ivas_output_buff_dec( float *p_output_f[], /* i/o: output audio buffers */ const int16_t nchan_out_buff_old, /* i : previous frame number of output channels*/ - const int16_t nchan_out_buff /* i : number of output channels */ + const int16_t nchan_out_buff /* i : number of output channels */ ); -#endif ivas_error stereo_dmx_evs_init_encoder( STEREO_DMX_EVS_ENC_HANDLE *hStereoDmxEVS, /* o : Stereo downmix for EVS encoder handle */ @@ -416,52 +415,31 @@ void ivas_initialize_handles_dec( ); ivas_error ivas_core_enc( - SCE_ENC_HANDLE hSCE, /* i/o: SCE encoder structure */ - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ - const int16_t n_CoreChannels, /* i : number of core channels to be coded */ -#ifdef FIX_854_ARRAY_SIZE_MISMATCH - float old_inp_12k8[][L_INP_12k8], /* i : buffer of old input signal */ - float old_inp_16k[][L_INP], /* i : buffer of old input signal */ - float ener[], /* i : residual energy from Levinson-Durbin */ - float A[][NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes */ - float Aw[][NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquantized for subframes */ - float epsP[][M + 1], /* i : LP prediction errors */ - float lsp_new[][M], /* i : LSPs at the end of the frame */ - float lsp_mid[][M], /* i : LSPs in the middle of the frame */ - const int16_t vad_hover_flag[], /* i : VAD hanglover flag */ - int16_t attack_flag[], /* i : attack flag (GSC or TC) */ - float realBuffer[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer */ - float imagBuffer[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer */ - float old_wsp[][L_WSP], /* i : weighted input signal buffer */ - const int16_t loc_harm[], /* i : harmonicity flag */ - const float cor_map_sum[], /* i : speech/music clasif. parameter */ - const int16_t vad_flag_dtx[], /* i : HE-SAD flag with additional DTX HO */ - float enerBuffer[][CLDFB_NO_CHANNELS_MAX], /* i : energy buffer */ - float fft_buff[][2 * L_FFT], /* i : FFT buffer */ -#else - float old_inp_12k8[CPE_CHANNELS][L_INP_12k8], /* i : buffer of old input signal */ - float old_inp_16k[CPE_CHANNELS][L_INP], /* i : buffer of old input signal */ - float ener[CPE_CHANNELS], /* i : residual energy from Levinson-Durbin */ - float A[CPE_CHANNELS][NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes */ - float Aw[CPE_CHANNELS][NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquantized for subframes */ - float epsP[CPE_CHANNELS][M + 1], /* i : LP prediction errors */ - float lsp_new[CPE_CHANNELS][M], /* i : LSPs at the end of the frame */ - float lsp_mid[CPE_CHANNELS][M], /* i : LSPs in the middle of the frame */ - const int16_t vad_hover_flag[CPE_CHANNELS], /* i : VAD hanglover flag */ - int16_t attack_flag[CPE_CHANNELS], /* i : attack flag (GSC or TC) */ - float realBuffer[CPE_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer */ - float imagBuffer[CPE_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer */ - float old_wsp[CPE_CHANNELS][L_WSP], /* i : weighted input signal buffer */ - const int16_t loc_harm[CPE_CHANNELS], /* i : harmonicity flag */ - const float cor_map_sum[CPE_CHANNELS], /* i : speech/music clasif. parameter */ - const int16_t vad_flag_dtx[CPE_CHANNELS], /* i : HE-SAD flag with additional DTX HO */ - float enerBuffer[CPE_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : energy buffer */ - float fft_buff[CPE_CHANNELS][2 * L_FFT], /* i : FFT buffer */ -#endif - const int16_t tdm_SM_flag, /* i : channel combination scheme flag */ - const int16_t ivas_format, /* i : IVAS format */ - const int16_t flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz */ + SCE_ENC_HANDLE hSCE, /* i/o: SCE encoder structure */ + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ + const int16_t n_CoreChannels, /* i : number of core channels to be coded */ + float old_inp_12k8[][L_INP_12k8], /* i : buffer of old input signal */ + float old_inp_16k[][L_INP], /* i : buffer of old input signal */ + float ener[], /* i : residual energy from Levinson-Durbin */ + float A[][NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes */ + float Aw[][NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquantized for subframes*/ + float epsP[][M + 1], /* i : LP prediction errors */ + float lsp_new[][M], /* i : LSPs at the end of the frame */ + float lsp_mid[][M], /* i : LSPs in the middle of the frame */ + const int16_t vad_hover_flag[], /* i : VAD hanglover flag */ + int16_t attack_flag[], /* i : attack flag (GSC or TC) */ + float realBuffer[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer */ + float imagBuffer[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer */ + float old_wsp[][L_WSP], /* i : weighted input signal buffer */ + const int16_t loc_harm[], /* i : harmonicity flag */ + const float cor_map_sum[], /* i : speech/music clasif. parameter */ + const int16_t vad_flag_dtx[], /* i : HE-SAD flag with additional DTX HO */ + float enerBuffer[][CLDFB_NO_CHANNELS_MAX], /* i : energy buffer */ + float fft_buff[][2 * L_FFT], /* i : FFT buffer */ + const int16_t tdm_SM_flag, /* i : channel combination scheme flag */ + const int16_t ivas_format, /* i : IVAS format */ + const int16_t flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz */ ); ivas_error ivas_core_dec( @@ -470,13 +448,8 @@ ivas_error ivas_core_dec( CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */ const int16_t n_channels, /* i : number of channels to be decoded */ -#ifdef FIX_854_ARRAY_SIZE_MISMATCH float *output[], /* o : output synthesis signal */ float outputHB[][L_FRAME48k], /* o : output HB synthesis signal */ -#else - float *output[CPE_CHANNELS], /* o : output synthesis signal */ - float outputHB[CPE_CHANNELS][L_FRAME48k], /* o : output HB synthesis signal */ -#endif float DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* o : DFT buffers */ const int16_t sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ ); @@ -869,10 +842,10 @@ TC_BUFFER_MODE ivas_jbm_dec_get_tc_buffer_mode( /*! r: render granularity */ int16_t ivas_jbm_dec_get_render_granularity( - const RENDERER_TYPE rendererType, /* i : renderer type */ - const IVAS_FORMAT ivas_format, /* i : ivas format */ - const MC_MODE mc_mode, /* i : MC mode */ - const int32_t output_Fs /* i : sampling rate */ + const RENDERER_TYPE rendererType, /* i : renderer type */ + const IVAS_FORMAT ivas_format, /* i : ivas format */ + const MC_MODE mc_mode, /* i : MC mode */ + const int32_t output_Fs /* i : sampling rate */ ); ivas_error ivas_jbm_dec_tc_buffer_open( @@ -985,7 +958,7 @@ ivas_error ivas_ism_metadata_dec_create( ivas_error ivas_ism_enc( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - float *data[MAX_NUM_OBJECTS], /* i : input signal */ + float *data[], /* i : input signal [channels][samples] */ const int16_t input_frame, /* i : input frame length per channel */ int16_t *nb_bits_metadata, /* i : number of metadata bits */ const int16_t flag_omasa_ener_brate /* i : less bitrate for objects in OMASA flag */ @@ -1144,7 +1117,7 @@ int16_t ivas_ism_dtx_enc( int16_t *sid_flag /* o : indication of SID frame */ ); -ivas_error ivas_ism_dtx_dec( +void ivas_ism_dtx_dec( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ int16_t *nb_bits_metadata /* o : number of metadata bits */ ); @@ -1440,7 +1413,7 @@ int16_t stereo_dft_sg_recovery( void stereo_dft_dec_res( CPE_DEC_HANDLE hCPE, /* i/o: decoder CPE handle */ - float res_buf[STEREO_DFT_BUF_MAX], /* i : residual buffer */ + float res_buf[STEREO_DFT_N_8k], /* i : residual buffer */ float *output /* o : output frame */ ); @@ -1448,7 +1421,7 @@ void stereo_dft_dec_res( int16_t res_bpf_adapt( STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo decoder handle */ const float *bpf_error_signal_8k, /* i : BPF modification signal */ - float res_buf[STEREO_DFT_BUF_MAX] /* i : residual buffer */ + float res_buf[STEREO_DFT_N_8k] /* i : residual buffer */ ); void bpf_pitch_coherence( @@ -1464,7 +1437,7 @@ void stereo_dft_dec_read_BS( STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */ const int16_t bwidth, /* i : bandwidth */ const int16_t output_frame, /* i : output frame length */ - float res_buf[STEREO_DFT_BUF_MAX], /* o : residual buffer */ + float res_buf[STEREO_DFT_N_8k], /* o : residual buffer */ int16_t *nb_bits, /* o : number of bits read */ float *coh, /* i/o: Coherence */ const int16_t ivas_format /* i : ivas format */ @@ -1912,8 +1885,7 @@ void stereo_icBWE_decproc( /*! r: element mode */ int16_t select_stereo_mode( CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const int32_t ivas_total_brate /* i : IVAS total brate */ + const IVAS_FORMAT ivas_format /* i : IVAS format */ ); void stereo_classifier_init( @@ -2234,10 +2206,10 @@ void EstimateStereoTCXNoiseLevel( void TNSAnalysisStereo( Encoder_State **sts, /* i : state handle */ - float *mdst_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* o : MDST spectrum */ + float *mdst_spectrum[CPE_CHANNELS][NB_DIV], /* o : MDST spectrum */ const int16_t bWhitenedDomain, /* i : whitened domain flag */ - int16_t tnsSize[MCT_MAX_CHANNELS][NB_DIV], /* i : number of tns parameters put into prm */ - int16_t tnsBits[MCT_MAX_CHANNELS][NB_DIV], /* i : number of tns bits in the frame */ + int16_t tnsSize[CPE_CHANNELS][NB_DIV], /* i : number of tns parameters put into prm */ + int16_t tnsBits[CPE_CHANNELS][NB_DIV], /* i : number of tns bits in the frame */ int16_t param_core[][NB_DIV * NPRM_DIV], /* o : quantized noise filling level */ const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ ); @@ -2520,8 +2492,8 @@ void stereo_decoder_tcx( STEREO_MDCT_DEC_DATA *hStereoMdct, /* i/o: MDCT stereo decoder structure */ int16_t ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ float *spec_r_0[NB_DIV], /* i/o: spectrum right channel */ - float *spec_l[NB_DIV], /* i/o: spectrum left channel */ - float *spec_r[NB_DIV], /* i/o: spectrum right channel */ + float *spec_l[], /* i/o: spectrum left channel [NB_DIV][N] */ + float *spec_r[], /* i/o: spectrum right channel [NB_DIV][N] */ const int16_t mdct_stereo_mode[], /* i : stereo mode (FB/band wise MS, dual mono */ const int16_t core_l, /* i : core for left channel (TCX20/TCX10) */ const int16_t core_r, /* i : core for right channel (TCX20/TCX10) */ @@ -3053,7 +3025,7 @@ void mctStereoIGF_enc( void ivas_mdct_dec_side_bits_frame_channel( CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - int16_t param_lpc[MCT_MAX_CHANNELS][NPRM_LPC_NEW], /* o : lpc_parameters */ + int16_t param_lpc[CPE_CHANNELS][NPRM_LPC_NEW], /* o : lpc_parameters */ int16_t p_param[CPE_CHANNELS][NB_DIV], /* o : pointer to param buffer */ Decoder_State *st0, /* i : pointer to bitstream handle */ int16_t nTnsBitsTCX10[CPE_CHANNELS][NB_DIV], /* o : number of bits for TNS */ @@ -3627,6 +3599,8 @@ void ivas_get_dirac_sba_max_md_bits( int16_t *metadata_max_bits, int16_t *qmetadata_max_bit_req, const int16_t nbands + , + IVAS_FORMAT ivas_format ); ivas_error ivas_dirac_sba_config( @@ -3635,6 +3609,8 @@ ivas_error ivas_dirac_sba_config( int32_t sba_total_brate, /* i : SBA total bitrate */ const int16_t sba_order, /* i : Ambisonic (SBA) order */ const int16_t nbands /* i : number of frequency bands */ + , + IVAS_FORMAT ivas_format ); ivas_error ivas_dirac_dec_config( @@ -3670,13 +3646,6 @@ void ivas_dirac_dec_set_md_map( const int16_t nCldfbTs /* i : number of CLDFB time slots */ ); -void ivas_dirac_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int16_t num_subframes /* i : number of subframes to render */ -); - void ivas_dirac_dec_render( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const int16_t nchan_transport, /* i : number of transport channels */ @@ -3694,15 +3663,6 @@ void ivas_dirac_dec_render_sf( float *pppQMfFrame_ts_im[IVAS_MAX_FB_MIXER_IN_CH][CLDFB_NO_COL_MAX] ); -ivas_error ivas_td_decorr_reconfig_dec( - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const int32_t ivas_total_brate, /* i : total IVAS bitrate */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int32_t output_Fs, /* i : output sampling rate */ - ivas_td_decorr_state_t **hTdDecorr, /* i/o: TD decorrelator handle */ - uint16_t *useTdDecorr /* i/o: TD decorrelator flag */ -); - void computeDiffuseness_mdft( float **buffer_intensity[DIRAC_NUM_DIMS], const float *buffer_energy, @@ -3767,11 +3727,6 @@ void ivas_mc_paramupmix_enc_close( const int32_t input_Fs /* i : input sampling rate */ ); -void ivas_mc_paramupmix_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ -); - ivas_error ivas_mc_paramupmix_dec_open( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); @@ -4131,12 +4086,6 @@ void ivas_spar_config( const int16_t sid_format /* i : IVAS format indicator from SID frame */ ); -ivas_error ivas_sba_upmixer_renderer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ - float *output[], /* i/o: transport/output audio channels */ - const int16_t output_frame /* i : output frame length */ -); - ivas_error ivas_sba_linear_renderer( float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ const int16_t output_frame, /* i : output frame length per channel */ @@ -4632,40 +4581,15 @@ void ivas_td_decorr_get_ducking_gains( const int16_t tdet_flag ); -ivas_error ivas_td_decorr_dec_open( - ivas_td_decorr_state_t **hTdDecorr, /* i/o: TD decorrelator handle */ - const int32_t output_Fs, /* i : output sampling rate */ - const int16_t nchan_internal, /* i : number of internal channels */ - const int16_t ducking_flag /* i : ducking flag */ -); - -void ivas_td_decorr_dec_close( - ivas_td_decorr_state_t **hTdDecorr /* i/o: TD decorrelator handle */ -); - -void ivas_td_decorr_process( - ivas_td_decorr_state_t *hTdDecorr, /* i/o: SPAR Covar. decoder handle */ - float *pcm_in[], /* i : input audio channels */ - float **ppOut_pcm, /* o : output audio channels */ - const int16_t output_frame /* i : output frame length */ -); - -void ivas_td_decorr_APD_iir_filter( - ivas_td_decorr_APD_filt_state_t *filter_state, - float *pIn_out, - const int16_t num_APD_sections, - const int16_t length -); - #define IVAS_CMULT_FLOAT( in1_re, in1_im, in2_re, in2_im, out1_re, out1_im ) \ out1_re = ( in1_re * in2_re ) - ( in1_im * in2_im ); MAC(1); MULT(1); \ out1_im = ( in1_re * in2_im ) + ( in2_re * in1_im ); MAC(1); MULT(1); #define IVAS_CALCULATE_ABS( re, im, out ) \ - out = (float) sqrt( ( re * re ) + ( im * im ) ); MAC(1); MULT(1); SQRT(1); + out = sqrtf( ( re * re ) + ( im * im ) ); MAC(1); MULT(1); SQRT(1); #define IVAS_CALCULATE_RABS( re, out ) \ - out = (float) sqrt( re * re ); MULT(1); SQRT(1); + out = sqrtf( re * re ); MULT(1); SQRT(1); #define IVAS_CALCULATE_SQ_ABS( re, im, out ) \ out = (float) ( ( re * re ) + ( im * im ) ); MAC(1); MULT(1); @@ -5212,7 +5136,6 @@ ivas_error ivas_allocate_binaural_hrtf( void ivas_binRenderer( BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle */ - int16_t subframe_idx, /* i : subframe index */ const int16_t numTimeSlots, /* i : number of time slots to process */ float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ @@ -5240,12 +5163,6 @@ void ivas_ism_renderer_close( ISM_RENDERER_HANDLE *hIsmRendererData /* i/o: ISM renderer handle */ ); -void ivas_ism_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output_f[], /* i/o: core-coder transport channels/object output */ - const int16_t output_frame /* i : output frame length per channel */ -); - void ivas_ism_render_sf( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ float *output_f[], /* i/o: core-coder transport channels/object output */ @@ -5278,15 +5195,6 @@ void ivas_param_mc_mc2sba_cldfb( const float gain_lfe /* i : gain applied to LFE */ ); -void ivas_ism2sba( - float *buffer_td[], /* i/o: TD signal buffers */ - ISM_RENDERER_HANDLE hIsmRendererData, /* i/o: renderer data */ - const ISM_METADATA_HANDLE hIsmMetaData[], /* i : object metadata */ - const int16_t nchan_ism, /* i : number of objects */ - const int16_t output_frame, /* i : output frame length per channel */ - const int16_t sba_order /* i : SBA order */ -); - void ivas_ism2sba_sf( float *buffer_in[], /* i : TC buffer */ float *buffer_out[], /* o : TD signal buffers */ @@ -5309,32 +5217,13 @@ void panning_wrap_angles( float *ele_wrapped /* o : wrapped elevation component */ ); -ivas_error vbap_init_data( - VBAP_HANDLE *hVBAPdata, /* i/o: handle for VBAP data structure that will be initialized */ - const float *speaker_node_azi_deg, /* i : vector of speaker node azimuths (positive left) */ - const float *speaker_node_ele_deg, /* i : vector of speaker node elevations (positive up) */ - const int16_t num_speaker_nodes, /* i : number of speaker nodes in the set */ - const IVAS_FORMAT ivas_format /* i : IVAS format */ -); - -void vbap_free_data( - VBAP_HANDLE *hVBAPdata /* i/o: VBAP handle to be freed */ -); - -void vbap_determine_gains( - const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ - float *gains, /* o : gain vector for speaker nodes for given direction */ - const int16_t azi_deg, /* i : azimuth in degrees for panning direction (positive left) */ - const int16_t ele_deg, /* i : elevation in degrees for panning direction (positive up) */ - const int16_t use_object_mode /* i : select between object mode panning and spatial mode panning */ -); - void v_sort_ind( float *x, /* i/o: Vector to be sorted */ int16_t *idx, /* o : Original index positions */ const int16_t len /* i : vector length */ ); + /*----------------------------------------------------------------------------------* * LS Renderer prototypes *----------------------------------------------------------------------------------*/ @@ -5482,8 +5371,8 @@ void lls_interp_n( void computeReferencePower_enc( const int16_t *band_grouping, /* i : Band grouping for estimation */ - float Cldfb_RealBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Real part of input signal */ - float Cldfb_ImagBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Imag part of input signal */ + float Cldfb_RealBuffer[][DIRAC_NO_FB_BANDS_MAX], /* i : Real part of input signal */ + float Cldfb_ImagBuffer[][DIRAC_NO_FB_BANDS_MAX], /* i : Imag part of input signal */ float *reference_power, /* o : Estimated power */ const int16_t enc_param_start_band, /* i : first band to process */ const int16_t num_freq_bands, /* i : Number of frequency bands */ @@ -5654,11 +5543,6 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( float *output_f[] /* o : rendered time signal */ ); -ivas_error ivas_osba_dirac_td_binaural( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* o : output synthesis signal */ - const int16_t output_frame /* i : output frame length per channel */ -); ivas_error ivas_osba_ism_metadata_dec( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ @@ -5667,10 +5551,12 @@ ivas_error ivas_osba_ism_metadata_dec( int16_t nb_bits_metadata[] /* o : number of ISM metadata bits */ ); -ivas_error ivas_osba_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output_f[], /* i/o: core-coder transport channels/object output */ - const int16_t output_frame /* i : output frame length per channel */ +ivas_error ivas_osba_render_sf( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ + uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ + uint16_t *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ + float *output_f[] /* o : rendered time signal */ ); void ivas_osba_data_close( @@ -5801,12 +5687,6 @@ ivas_error ivas_omasa_ism_metadata_dec( int16_t nb_bits_metadata[] /* o : number of ISM metadata bits */ ); -ivas_error ivas_omasa_dirac_td_binaural( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* o : output synthesis signal */ - const int16_t output_frame /* i : output frame length per channel */ -); - ivas_error ivas_omasa_dirac_td_binaural_jbm( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const uint16_t nSamplesAsked, /* i : number of samples requested */ @@ -5816,12 +5696,6 @@ ivas_error ivas_omasa_dirac_td_binaural_jbm( float *output_f[] /* o : rendered time signal */ ); -void ivas_omasa_dirac_rend( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* o : output synthesis signal */ - const int16_t output_frame /* i : output frame length per channel */ -); - void ivas_omasa_rearrange_channels( float *output[], /* o : output synthesis signal */ const int16_t nchan_transport_ism, /* i : number of ISM TCs */ @@ -5853,16 +5727,10 @@ void ivas_omasa_separate_object_renderer_close( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); -void ivas_omasa_separate_object_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float input_f[][L_FRAME48k], /* i : separated object signal */ - float *output_f[], /* i/o: output signals */ - const int16_t output_frame /* i : output frame length per channel */ -); - void ivas_omasa_separate_object_render_jbm( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const uint16_t nSamplesRendered, /* i : number of samples rendered */ + float input_f[][L_FRAME48k], /* i : separated object signal */ float *output_f[], /* o : rendered time signal */ const int16_t subframes_rendered, /* i : number of subframes rendered */ const int16_t slots_rendered /* i : number of CLDFB slots rendered */ @@ -5885,7 +5753,7 @@ void ivas_omasa_decode_masa_to_total( ); void ivas_omasa_modify_masa_energy_ratios( - IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ + IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */ float masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_MAXIMUM_CODING_SUBBANDS] ); diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c index da44adbdf..ad8279712 100644 --- a/lib_com/ivas_rom_com.c +++ b/lib_com/ivas_rom_com.c @@ -2516,17 +2516,6 @@ const uint16_t ivas_param_mc_sym_freq_ild_delta_combined_48_16bits[2 * PARAM_MC_ }; -/*----------------------------------------------------------------------------------* - * Parametric Upmix MC ROM tables - *----------------------------------------------------------------------------------*/ - -const int16_t ivas_param_upmx_mx_qmap[2][33] = -{ - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, - { 0, 1, 2, 3, 4, 3, 2, 1, 0, 1, 2, 3, 4, 3, 2, 1, 0 } -}; - - /*----------------------------------------------------------------------------------* * MASA ROM tables *----------------------------------------------------------------------------------*/ @@ -6436,103 +6425,68 @@ const int16_t sns_1st_means_32k[2][16] = * MC ParamUpmix ROM tables *-----------------------------------------------------------------------*/ -const ACPL_QUANT_TABLE ivas_mc_paramupmix_alpha_quant_table[] = +const int16_t ivas_param_upmx_mx_qmap[33] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0 +}; + +const ACPL_QUANT_TABLE ivas_mc_paramupmix_alpha_quant_table = { - /* Alfa Fine */ - { 33, /* nquant */ 16, /* offset */ { -2.000000e+000f, -1.809375e+000f, -1.637500e+000f, -1.484375e+000f, -1.350000e+000f, -1.234375e+000f, -1.137500e+000f, -1.059375e+000f, -1.000000e+000f, -9.406250e-001f, -8.625000e-001f, -7.656250e-001f, -6.500000e-001f, -5.156250e-001f, -3.625000e-001f, -1.906250e-001f, +0.000000e+000f, +1.906250e-001f, +3.625000e-001f, +5.156250e-001f, +6.500000e-001f, +7.656250e-001f, +8.625000e-001f, +9.406250e-001f, +1.000000e+000f, +1.059375e+000f, +1.137500e+000f, +1.234375e+000f, +1.350000e+000f, +1.484375e+000f, +1.637500e+000f, +1.809375e+000f, +2.000000e+000f } /* data */ - }, - { /* Alfa Coarse */ - 17, /* nquant */ - 8, /* offset */ - { -2.000000e+000f, -1.637500e+000f, -1.350000e+000f, -1.137500e+000f, -1.000000e+000f, -8.625000e-001f, -6.500000e-001f, -3.625000e-001f, +0.000000e+000f, +3.625000e-001f, - +6.500000e-001f, +8.625000e-001f, +1.000000e+000f, +1.137500e+000f, +1.350000e+000f, +1.637500e+000f, +2.000000e+000f } /* data */ - } }; -const ACPL_QUANT_TABLE ivas_mc_paramupmix_beta_quant_table[2][9] = +const ACPL_QUANT_TABLE ivas_mc_paramupmix_beta_quant_table[9] = { - { - /* Beta Fine #1 */ { 9, /* nquant */ 0, /* offset */ { +0.000000e+000f, +2.375000e-001f, +5.500000e-001f, +9.375000e-001f, +1.400000e+000f, +1.937500e+000f, +2.550000e+000f, +3.237500e+000f, +4.000000e+000f } /* data */ }, - { /* Beta Fine #2 */ + { /* Beta #2 */ 9, /* nquant */ 0, /* offset */ { +0.000000e+000f, +2.035449e-001f, +4.713672e-001f, +8.034668e-001f, +1.199844e+000f, +1.660498e+000f, +2.185430e+000f, +2.774639e+000f, +3.428125e+000f } /* data */ }, - { /* Beta Fine #3 */ + { /* Beta #3 */ 9, /* nquant */ 0, /* offset */ { +0.000000e+000f, +1.729297e-001f, +4.004688e-001f, +6.826172e-001f, +1.019375e+000f, +1.410742e+000f, +1.856719e+000f, +2.357305e+000f, +2.912500e+000f } /* data */ }, - { /* Beta Fine #4 */ + { /* Beta #4 */ 9, /* nquant */ 0, /* offset */ { +0.000000e+000f, +1.456543e-001f, +3.373047e-001f, +5.749512e-001f, +8.585938e-001f, +1.188232e+000f, +1.563867e+000f, +1.985498e+000f, +2.453125e+000f } /* data */ }, - { /* Beta Fine #5 */ + { /* Beta #5 */ 9, /* nquant */ 0, /* offset */ { +0.000000e+000f, +1.217188e-001f, +2.818750e-001f, +4.804688e-001f, +7.175000e-001f, +9.929688e-001f, +1.306875e+000f, +1.659219e+000f, +2.050000e+000f } /* data */ }, - { /* Beta Fine #6 */ + { /* Beta #6 */ 9, /* nquant */ 0, /* offset */ { +0.000000e+000f, +1.011230e-001f, +2.341797e-001f, +3.991699e-001f, +5.960938e-001f, +8.249512e-001f, +1.085742e+000f, +1.378467e+000f, +1.703125e+000f } /* data */ }, - { /* Beta Fine #7 */ + { /* Beta #7 */ 9, /* nquant */ 0, /* offset */ { +0.000000e+000f, +8.386719e-002f, +1.942188e-001f, +3.310547e-001f, +4.943750e-001f, +6.841797e-001f, +9.004688e-001f, +1.143242e+000f, +1.412500e+000f } /* data */ }, - { /* Beta Fine #8 */ + { /* Beta #8 */ 9, /* nquant */ 0, /* offset */ { +0.000000e+000f, +6.995117e-002f, +1.619922e-001f, +2.761230e-001f, +4.123438e-001f, +5.706543e-001f, +7.510547e-001f, +9.535449e-001f, +1.178125e+000f } /* data */ }, - { /* Beta Fine #9 */ + { /* Beta #9 */ 9, /* nquant */ 0, /* offset */ { +0.000000e+000f, +5.937500e-002f, +1.375000e-001f, +2.343750e-001f, +3.500000e-001f, +4.843750e-001f, +6.375000e-001f, +8.093750e-001f, +1.000000e+000f } /* data */ } - }, - { - /* Beta Coarse #1 */ - { - 5, /* nquant */ - 0, /* offset */ - { +0.000000e+000f, +5.500000e-001f, +1.400000e+000f, +2.550000e+000f, +4.000000e+000f } /* data */ - }, - { /* Beta Coarse #2 */ - 5, /* nquant */ - 0, /* offset */ - { +0.000000e+000f, +4.004688e-001f, +1.019375e+000f, +1.856719e+000f, +2.912500e+000f } /* data */ - }, - { /* Beta Coarse #3 */ - 5, /* nquant */ - 0, /* offset */ - { +0.000000e+000f, +2.818750e-001f, +7.175000e-001f, +1.306875e+000f, +2.050000e+000f } /* data */ - }, - { /* Beta Coarse #4 */ - 5, /* nquant */ - 0, /* offset */ - { +0.000000e+000f, +1.942188e-001f, +4.943750e-001f, +9.004688e-001f, +1.412500e+000f } /* data */ - }, - { /* Beta Coarse #5 */ - 5, /* nquant */ - 0, /* offset */ - { +0.000000e+000f, +1.375000e-001f, +3.500000e-001f, +6.375000e-001f, +1.000000e+000f } /* data */ - } - } }; /* clang-format on */ diff --git a/lib_com/ivas_rom_com.h b/lib_com/ivas_rom_com.h index 9823e5ea3..b13d41548 100644 --- a/lib_com/ivas_rom_com.h +++ b/lib_com/ivas_rom_com.h @@ -256,12 +256,6 @@ extern const uint16_t ivas_param_mc_sym_freq_icc_combined_48_16bits[PARAM_MC_SZ_ extern const uint16_t ivas_param_mc_cum_freq_icc_delta_combined_48_16bits[2 * PARAM_MC_SZ_ICC_QUANTIZER]; extern const uint16_t ivas_param_mc_sym_freq_icc_delta_combined_48_16bits[2 * PARAM_MC_SZ_ICC_QUANTIZER - 1]; -/*----------------------------------------------------------------------------------* - * Parametric Upmix MC ROM tables - *----------------------------------------------------------------------------------*/ - -extern const int16_t ivas_param_upmx_mx_qmap[2][33]; - /*----------------------------------------------------------------------------------* * MASA ROM tables @@ -451,8 +445,9 @@ extern const int16_t sns_1st_means_32k[2][16]; * MC ParamUpmix ROM tables *-----------------------------------------------------------------------*/ -extern const ACPL_QUANT_TABLE ivas_mc_paramupmix_alpha_quant_table[]; -extern const ACPL_QUANT_TABLE ivas_mc_paramupmix_beta_quant_table[2][9]; +extern const int16_t ivas_param_upmx_mx_qmap[33]; +extern const ACPL_QUANT_TABLE ivas_mc_paramupmix_alpha_quant_table; +extern const ACPL_QUANT_TABLE ivas_mc_paramupmix_beta_quant_table[9]; /* IVAS_ROM_COM_H */ #endif diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index 4768b1d90..f34610c11 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -668,34 +668,6 @@ typedef struct ivas_trans_det_state_t } ivas_trans_det_state_t; -/*----------------------------------------------------------------------------------* - * Time domain decorrelator - *----------------------------------------------------------------------------------*/ - -typedef struct ivas_td_decorr_APD_filt_state_t -{ - int16_t order[IVAS_MAX_DECORR_APD_SECTIONS]; - int16_t idx[IVAS_MAX_DECORR_APD_SECTIONS]; - float coeffs[IVAS_MAX_DECORR_APD_SECTIONS]; - float *state[IVAS_MAX_DECORR_APD_SECTIONS]; - -} ivas_td_decorr_APD_filt_state_t; - -typedef struct ivas_td_decorr_state_t -{ - ivas_trans_det_state_t *pTrans_det; - float *look_ahead_buf; - ivas_td_decorr_APD_filt_state_t APD_filt_state[IVAS_MAX_DECORR_CHS]; - - int16_t num_apd_outputs; - int16_t num_apd_sections; - int16_t ducking_flag; - - int16_t offset; - -} ivas_td_decorr_state_t; - - /*----------------------------------------------------------------------------------* * Filter Bank (FB) structures *----------------------------------------------------------------------------------*/ diff --git a/lib_com/ivas_stereo_td_bit_alloc.c b/lib_com/ivas_stereo_td_bit_alloc.c index 41a552162..35bfe9046 100644 --- a/lib_com/ivas_stereo_td_bit_alloc.c +++ b/lib_com/ivas_stereo_td_bit_alloc.c @@ -304,15 +304,15 @@ void tdm_bit_alloc( else { *total_brate_sec = min( *total_brate_sec, element_brate_wo_meta - ( 5900 + BWE_brate ) ); + } - if ( coder_type == INACTIVE ) - { - *total_brate_sec = max( *total_brate_sec, tdm_bit_allc_tbl[0][0] ); /* sanity check to ensure the secondary channel always gets the minimal bitrate it needs */ - } - else - { - *total_brate_sec = max( *total_brate_sec, 3500 ); /* sanity check to ensure the secondary channel always gets the minimal bitrate it needs */ - } + if ( coder_type == INACTIVE ) + { + *total_brate_sec = max( *total_brate_sec, tdm_bit_allc_tbl[0][0] ); /* sanity check to ensure the secondary channel always gets the minimal bitrate it needs */ + } + else + { + *total_brate_sec = max( *total_brate_sec, 3500 ); /* sanity check to ensure the secondary channel always gets the minimal bitrate it needs */ } /* Secondary channel bitrate adjusment */ diff --git a/lib_com/move.h b/lib_com/move.h index c7bee82cd..becc9314d 100644 --- a/lib_com/move.h +++ b/lib_com/move.h @@ -39,29 +39,41 @@ /* BASOP -> FLC brigde: data move counting */ -#include "stl.h" - static __inline void move16( void ) { +#ifdef WMOPS + multiCounter[currCounter].move16++; +#endif } static __inline void move32( void ) { +#ifdef WMOPS + multiCounter[currCounter].move32++; +#endif } static __inline void test( void ) { +#ifdef WMOPS + multiCounter[currCounter].Test++; +#endif } static __inline void logic16( void ) { +#ifdef WMOPS + multiCounter[currCounter].Logic16++; +#endif } static __inline void logic32( void ) { +#ifdef WMOPS + multiCounter[currCounter].Logic32++; +#endif } - /*-------- legacy ----------*/ #define data_move() move16() #define L_data_move() move32() diff --git a/lib_com/options.h b/lib_com/options.h index 31d4cb855..b70e22adf 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -60,34 +60,6 @@ #define BASOP_NOGLOB /* Disable global symbols in BASOPs, Overflow/Carry in BASOPs disabled, additional BASOPs in case of Overflow */ -/* ################### Start BE switches ################################# */ -/* only BE switches wrt selection floating point code */ - -/*#define FIX_I4_OL_PITCH*/ /* fix open-loop pitch used for EVS core switching */ - -#define FIX_854_ARRAY_SIZE_MISMATCH /* VA: issue 854: correct the mismatch between definition and declaration of `ivas_core_dec() */ -#define FIX_785_REMOVE_DEAD_CODE /* VA: issue 785: remove dead code */ -#define FIX_852_FIX_HANDLE_DEREF /* VA: issue 852: Fix missing handle dereferencing of hIsmMetadaData in ivas_ism_metadata_close() */ - - -/* #################### End BE switches ################################## */ - - -/* #################### Start NON-BE switches ############################ */ -/* any switch which is non-be wrt selection floating point code */ -/* all switches in this category should start with "NONBE_" */ - -#define NONBE_FIX_838_CRASH_24_4_WB /* FhG: Issue 838: fix encoder crashes for Unified Stereo and MASA 2 TC at 24.4 kbps WB due to missing IGF (re-) allocation */ -#define NONBE_FIX_839_MC_RS_CHANNEL_ALLOC /* FhG: Issues #839: problems with reallocation of the channels on the heap in case of MC RS */ -#define BE_FIX_832_ASAN_ERROR_EFAP_OSBA /* FhG: issue #832: fix ASAN error caused by re-allocating EFAP memories in OSBA*/ -#define NONBE_FIX_819_DOUBLE_PREC_COMB_FORMATS /* VA: issue 820: Double precision arithmetic in combined formats */ -#define NONBE_FIX_849_OMASA_BFI_CRASH /* VA: issue 849: fix OMASA 2TC and FEC crashes */ - - -/* ##################### End NON-BE switches ########################### */ - -/* ################## End DEVELOPMENT switches ######################### */ - /* clang-format on */ #endif diff --git a/lib_com/prot.h b/lib_com/prot.h index d277cefb1..a032dcf7e 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -2231,9 +2231,7 @@ void pre_proc( float **inp, /* o : ptr. to inp. signal in the current frame*/ float fr_bands[2 * NB_BANDS], /* i : energy in frequency bands */ float *ener, /* o : residual energy from Levinson-Durbin */ -#ifndef FIX_I4_OL_PITCH int16_t pitch_orig[3], /* o : open-loop pitch values for quantization */ -#endif float A[NB_SUBFR16k * ( M + 1 )], /* i/o: A(z) unquantized for the 4 subframes */ float Aw[NB_SUBFR16k * ( M + 1 )], /* i/o: weighted A(z) unquantized for subframes */ float epsP[M + 1], /* i/o: LP prediction errors */ @@ -3164,14 +3162,14 @@ void speech_music_clas_init( ); void long_enr( - Encoder_State *st, /* i/o: encoder state structure */ - const float Etot, /* i : total channel energy */ - const int16_t localVAD_HE_SAD, /* i : HE-SAD flag without hangover */ - const int16_t high_lpn_flag, /* i : sp/mus LPN flag */ - FRONT_VAD_ENC_HANDLE hFrontVad[CPE_CHANNELS], /* i/o: front-VAD handles */ - const int16_t n_chan, /* i : number of channels */ - const int16_t localVAD_HE_SAD_LR[CPE_CHANNELS], /* i : HE-SAD flag without hangover LR channels */ - const float Etot_LR[CPE_CHANNELS] /* i : total channel energy LR channels */ + Encoder_State *st, /* i/o: encoder state structure */ + const float Etot, /* i : total channel energy */ + const int16_t localVAD_HE_SAD, /* i : HE-SAD flag without hangover */ + const int16_t high_lpn_flag, /* i : sp/mus LPN flag */ + FRONT_VAD_ENC_HANDLE hFrontVad[], /* i/o: front-VAD handles */ + const int16_t n_chan, /* i : number of channels */ + const int16_t localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover LR channels */ + const float Etot_LR[] /* i : total channel energy LR channels */ ); void noise_est_pre( diff --git a/lib_com/stl.h b/lib_com/stl.h index c9ca42280..be5722630 100644 --- a/lib_com/stl.h +++ b/lib_com/stl.h @@ -60,8 +60,8 @@ #include "options.h" /* note: needed until BASOP_NOGLOB is accepted */ #include "typedef.h" #include "basop32.h" +#include "wmc_auto.h" #include "move.h" -#include "control.h" #include "enh1632.h" #include "enh40.h" diff --git a/lib_com/tcx_ltp.c b/lib_com/tcx_ltp.c index 4ea3f1106..b92c0b607 100644 --- a/lib_com/tcx_ltp.c +++ b/lib_com/tcx_ltp.c @@ -737,7 +737,7 @@ static void tcx_ltp_synth_filter_11_unequal_pitch( gain = prev_gain; gain_step = -prev_gain / length; - for ( j = 0; j < length + L; j++ ) + for ( j = 0; j < length; j++ ) { s = 0; s2 = 0; @@ -758,8 +758,9 @@ static void tcx_ltp_synth_filter_11_unequal_pitch( gain += gain_step; } - mvr2r( out - MAX_TCX_LTP_FILTER_LEN, temp_buf, MAX_TRANSITION_LEN + 2 * MAX_TCX_LTP_FILTER_LEN ); - temp_ptr = &temp_buf[0] + MAX_TCX_LTP_FILTER_LEN; + mvr2r( out - L, temp_buf, length + L ); + mvr2r( in + length, temp_buf + length + L, L ); + temp_ptr = &temp_buf[0] + L; m0 = temp_ptr; m1 = temp_ptr - 1; diff --git a/lib_debug/wmc_auto.c b/lib_debug/wmc_auto.c index 029640a1d..0ff7786f0 100644 --- a/lib_debug/wmc_auto.c +++ b/lib_debug/wmc_auto.c @@ -28,7 +28,6 @@ #include "options.h" #include "wmc_auto.h" - #define WMC_TOOL_SKIP /* Skip the instrumentation of this file, if invoked by accident */ #ifdef WMOPS @@ -37,23 +36,26 @@ * Complexity counting tool *--------------------------------------------------------------------*/ -#define MAX_RECORDS 1024 -#define MAX_CHAR 64 -#define MAX_STACK 64 -#define DOUBLE_MAX 0x80000000 +#define MAX_FUNCTION_NAME_LENGTH 50 /* Maximum length of the function name */ +#define MAX_PARAMS_LENGTH 50 /* Maximum length of the function parameter string */ +#define MAX_NUM_RECORDS 300 /* Initial maximum number of records -> mightb be increased during runtime, if needed */ +#define MAX_NUM_RECORDS_REALLOC_STEP 50 /* When re-allocating the list of records, increase the number of records by this number */ +#define MAX_CALL_TREE_DEPTH 100 /* maximum depth of the function call tree */ +#define DOUBLE_MAX 0x80000000 -struct wmops_record +typedef struct { - char label[MAX_CHAR]; + char label[MAX_FUNCTION_NAME_LENGTH]; long call_number; long update_cnt; - int call_tree[MAX_RECORDS]; + int call_tree[MAX_CALL_TREE_DEPTH]; + long LastWOper; double start_selfcnt; double current_selfcnt; double max_selfcnt; double min_selfcnt; double tot_selfcnt; - double start_cnt; /* The following take into account the decendants */ + double start_cnt; double current_cnt; double max_cnt; double min_cnt; @@ -64,16 +66,14 @@ struct wmops_record double wc_selfcnt; int32_t wc_call_number; #endif -}; +} wmops_record; double ops_cnt; double prom_cnt; double inst_cnt[NUM_INST]; -static struct wmops_record wmops[MAX_RECORDS]; -static int stack[MAX_STACK]; -static int sptr; -static int num_records; +static wmops_record *wmops = NULL; +static int num_wmops_records, max_num_wmops_records; static int current_record; static long update_cnt; static double start_cnt; @@ -81,20 +81,56 @@ static double max_cnt; static double min_cnt; static double inst_cnt_wc[NUM_INST]; static long fnum_cnt_wc; - +static int *wmops_caller_stack = NULL, wmops_caller_stack_index, max_wmops_caller_stack_index = 0; static int *heap_allocation_call_tree = NULL, heap_allocation_call_tree_size = 0, heap_allocation_call_tree_max_size = 0; - void reset_wmops( void ) { int i, j; + unsigned int *ptr; + + num_wmops_records = 0; + max_num_wmops_records = MAX_NUM_RECORDS; + current_record = -1; + update_cnt = 0; + + max_cnt = 0.0; + min_cnt = DOUBLE_MAX; + start_cnt = 0.0; + ops_cnt = 0.0; + + /* allocate the list of wmops records */ + if ( wmops == NULL ) + { + wmops = (wmops_record *)malloc( max_num_wmops_records * sizeof( wmops_record ) ); + } + + if ( wmops == NULL ) + { + fprintf( stderr, "Error: Unable to Allocate List of WMOPS Records!" ); + exit( -1 ); + } + + /* allocate the BASOP WMOPS counter */ + if ( multiCounter == NULL ) + { + multiCounter = (BASIC_OP *) malloc( max_num_wmops_records * sizeof( BASIC_OP ) ); + } - for ( i = 0; i < MAX_RECORDS; i++ ) + if ( multiCounter == NULL ) + { + fprintf( stderr, "Error: Unable to Allocate the BASOP WMOPS counter!" ); + exit( -1 ); + } + + /* initilize the list of wmops records */ + /* initilize the BASOP WMOPS counters */ + for ( i = 0; i < max_num_wmops_records; i++ ) { strcpy( &wmops[i].label[0], "\0" ); wmops[i].call_number = 0; wmops[i].update_cnt = 0; - for ( j = 0; j < MAX_RECORDS; j++ ) + for ( j = 0; j < MAX_CALL_TREE_DEPTH; j++ ) { wmops[i].call_tree[j] = -1; } @@ -112,22 +148,42 @@ void reset_wmops( void ) wmops[i].wc_cnt = 0.0; wmops[i].wc_selfcnt = 0.0; wmops[i].current_call_number = 0; + wmops[i].wc_call_number = -1; #endif + + /* clear all BASOP operation counters */ + ptr = (unsigned int*) &multiCounter[i]; + for ( j = 0; j < (int) ( sizeof(BASIC_OP ) / sizeof( unsigned int ) ); j++ ) + { + *ptr++ = 0; + } + wmops[i].LastWOper = 0; } - for ( i = 0; i < MAX_STACK; i++ ) + /* allocate the list of wmops callers to track the sequence of function calls */ + wmops_caller_stack_index = 0; + max_wmops_caller_stack_index = MAX_NUM_RECORDS; + if ( wmops_caller_stack == NULL ) { - stack[i] = -1; + wmops_caller_stack = malloc( max_wmops_caller_stack_index * sizeof( int ) ); } - sptr = 0; - num_records = 0; - current_record = -1; - update_cnt = 0; - max_cnt = 0.0; - min_cnt = DOUBLE_MAX; - start_cnt = 0.0; - ops_cnt = 0.0; + if ( wmops_caller_stack == NULL ) + { + fprintf( stderr, "Error: Unable to Allocate List of WMOPS Callers!" ); + exit( -1 ); + } + + for ( i = 0; i < max_wmops_caller_stack_index; i++ ) + { + wmops_caller_stack[i] = -1; + } + + /* initialize auxiliary BASOP WMOPS variables */ + call_occurred = 1; + funcId_where_last_call_to_else_occurred = INT_MAX; + + return; } @@ -136,9 +192,9 @@ void push_wmops( const char *label ) int new_flag; int i, j; - /* Check if new function record label */ + /* Check, if this is a new function label */ new_flag = 1; - for ( i = 0; i < num_records; i++ ) + for ( i = 0; i < num_wmops_records; i++ ) { if ( strcmp( wmops[i].label, label ) == 0 ) { @@ -147,33 +203,38 @@ void push_wmops( const char *label ) } } - /* Configure new record */ + /* Create a new record in the list */ if ( new_flag ) { - if ( num_records >= MAX_RECORDS ) + if ( num_wmops_records >= max_num_wmops_records ) { - fprintf( stdout, "push_wmops(): exceeded MAX_RECORDS count.\n\n" ); - exit( -1 ); + /* There is no room for a new wmops record -> reallocate the list */ + max_num_wmops_records += MAX_NUM_RECORDS_REALLOC_STEP; + wmops = realloc( wmops, max_num_wmops_records * sizeof( wmops_record ) ); + multiCounter = realloc( multiCounter, max_num_wmops_records * sizeof( BASIC_OP ) ); } + strcpy( wmops[i].label, label ); - num_records++; + + num_wmops_records++; } - /* Push current context onto stack */ + /* Push the current context info to the new record */ if ( current_record >= 0 ) { - if ( sptr >= MAX_STACK ) + if ( wmops_caller_stack_index >= max_wmops_caller_stack_index ) { - fprintf( stdout, "\r push_wmops(): stack exceeded, try inreasing MAX_STACK\n" ); - exit( -1 ); + /* There is no room for a new record -> reallocate the list */ + max_wmops_caller_stack_index += MAX_NUM_RECORDS_REALLOC_STEP; + wmops_caller_stack = realloc( wmops_caller_stack, max_wmops_caller_stack_index * sizeof( int ) ); } - stack[sptr++] = current_record; + wmops_caller_stack[wmops_caller_stack_index++] = current_record; /* accumulate op counts */ wmops[current_record].current_selfcnt += ops_cnt - wmops[current_record].start_selfcnt; /* update call tree */ - for ( j = 0; j < MAX_RECORDS; j++ ) + for ( j = 0; j < MAX_CALL_TREE_DEPTH; j++ ) { if ( wmops[i].call_tree[j] == current_record ) { @@ -187,7 +248,7 @@ void push_wmops( const char *label ) } } - /* init current record */ + /* update the current context info */ current_record = i; wmops[current_record].start_selfcnt = ops_cnt; wmops[current_record].start_cnt = ops_cnt; @@ -196,12 +257,16 @@ void push_wmops( const char *label ) wmops[current_record].current_call_number++; #endif + /* set the ID of BASOP functions counters */ + Set_BASOP_WMOPS_counter( current_record ); + return; } void pop_wmops( void ) { + long tot; /* Check for underflow */ if ( current_record < 0 ) @@ -210,21 +275,29 @@ void pop_wmops( void ) exit( -1 ); } - /* update count of current record */ + /* add the BASOP complexity to the counter */ + tot = DeltaWeightedOperation(); + ops_cnt += tot; + + /* update count of current record */ wmops[current_record].current_selfcnt += ops_cnt - wmops[current_record].start_selfcnt; wmops[current_record].current_cnt += ops_cnt - wmops[current_record].start_cnt; /* Get back previous context from stack */ - if ( sptr > 0 ) + if ( wmops_caller_stack_index > 0 ) { - current_record = stack[--sptr]; + current_record = wmops_caller_stack[--wmops_caller_stack_index]; wmops[current_record].start_selfcnt = ops_cnt; + + /* set the ID of the previous BASOP counter */ + Set_BASOP_WMOPS_counter( current_record ); } else { current_record = -1; } + return; } @@ -239,9 +312,9 @@ void update_wmops( void ) float tmpF; #endif - if ( sptr != 0 ) + if ( wmops_caller_stack_index != 0 ) { - fprintf( stdout, "update_wmops(): Stack must be empty!\n" ); + fprintf( stdout, "update_wmops(): WMOPS caller stack corrupted - check that all push_wmops() are matched with pop_wmops()!\n" ); exit( -1 ); } @@ -266,7 +339,7 @@ void update_wmops( void ) #ifdef WMOPS_WC_FRAME_ANALYSIS if ( ops_cnt - start_cnt > max_cnt ) { - for ( i = 0; i < num_records; i++ ) + for ( i = 0; i < num_wmops_records; i++ ) { wmops[i].wc_cnt = wmops[i].current_cnt; wmops[i].wc_selfcnt = wmops[i].current_selfcnt; @@ -275,7 +348,7 @@ void update_wmops( void ) } #endif - for ( i = 0; i < num_records; i++ ) + for ( i = 0; i < num_wmops_records; i++ ) { wmops[i].tot_selfcnt += wmops[i].current_selfcnt; wmops[i].tot_cnt += wmops[i].current_cnt; @@ -302,6 +375,7 @@ void update_wmops( void ) wmops[i].max_cnt = wmops[i].current_cnt; } + if ( wmops[i].current_cnt < wmops[i].min_cnt ) { wmops[i].min_cnt = wmops[i].current_cnt; @@ -314,6 +388,10 @@ void update_wmops( void ) #ifdef WMOPS_WC_FRAME_ANALYSIS wmops[i].current_call_number = 0; #endif + + /* update the WC of all BASOP counters */ + Set_BASOP_WMOPS_counter( i ); + Reset_BASOP_WMOPS_counter(); } current_cnt = ops_cnt - start_cnt; @@ -350,28 +428,40 @@ void update_wmops( void ) void print_wmops( void ) { - int i; + int i, label_len, max_label_len; - char *sfmts = "%20s %8s %8s %7s %7s\n"; - char *dfmts = "%20s %8.2f %8.3f %7.3f %7.3f\n"; - char *sfmt = "%20s %8s %8s %7s %7s %7s %7s %7s\n"; - char *dfmt = "%20s %8.2f %8.3f %7.3f %7.3f %7.3f %7.3f %7.3f\n"; + char *sfmts = "%*s %8s %8s %7s %7s\n"; + char *dfmts = "%*s %8.2f %8.3f %7.3f %7.3f\n"; + char *sfmt = "%*s %8s %8s %7s %7s %7s %7s %7s\n"; + char *dfmt = "%*s %8.2f %8.3f %7.3f %7.3f %7.3f %7.3f %7.3f\n"; #ifdef WMOPS_WC_FRAME_ANALYSIS - int j, label_len, max_label_len; + int j; char *sfmtt = "%20s %4s %15s\n"; char *dfmtt = "%20s %4d "; #endif - fprintf( stdout, "\n\n --- Complexity analysis [WMOPS] --- \n\n" ); + /* calculate maximum label length for compact prinout */ + max_label_len = 0; + for ( i = 0; i < num_wmops_records; i++ ) + { + label_len = strlen( wmops[i].label ); + if ( label_len > max_label_len ) + { + max_label_len = label_len; + } + } + max_label_len += 4; - fprintf( stdout, "%54s %23s\n", "|------ SELF ------|", "|--- CUMULATIVE ---|" ); - fprintf( stdout, sfmt, " routine", " calls", " min ", " max ", " avg ", " min ", " max ", " avg " ); - fprintf( stdout, sfmt, "---------------", "------", "------", "------", "------", "------", "------", "------" ); + fprintf( stdout, "\n\n --- Complexity analysis [WMOPS] --- \n\n" ); + + fprintf( stdout, "%*s %33s %23s\n", max_label_len, "", "|------ SELF ------|", "|--- CUMULATIVE ---|" ); + fprintf( stdout, sfmt, max_label_len, " routine", " calls", " min ", " max ", " avg ", " min ", " max ", " avg " ); + fprintf( stdout, sfmt, max_label_len, "---------------", "------", "------", "------", "------", "------", "------", "------" ); - for ( i = 0; i < num_records; i++ ) + for ( i = 0; i < num_wmops_records; i++ ) { - fprintf( stdout, dfmt, wmops[i].label, update_cnt == 0 ? 0 : (float) wmops[i].call_number / update_cnt, + fprintf( stdout, dfmt, max_label_len, wmops[i].label, update_cnt == 0 ? 0 : (float) wmops[i].call_number / update_cnt, wmops[i].min_selfcnt == DOUBLE_MAX ? 0 : FAC * wmops[i].min_selfcnt, FAC * wmops[i].max_selfcnt, wmops[i].update_cnt == 0 ? 0 : FAC * wmops[i].tot_selfcnt / wmops[i].update_cnt, @@ -380,54 +470,47 @@ void print_wmops( void ) wmops[i].update_cnt == 0 ? 0 : FAC * wmops[i].tot_cnt / wmops[i].update_cnt ); } - fprintf( stdout, sfmts, "---------------", "------", "------", "------", "------" ); - fprintf( stdout, dfmts, "total", (float) update_cnt, update_cnt == 0 ? 0 : FAC * min_cnt, FAC * max_cnt, update_cnt == 0 ? 0 : FAC * ops_cnt / update_cnt ); + fprintf( stdout, sfmts, max_label_len, "---------------", "------", "------", "------", "------" ); + fprintf( stdout, dfmts, max_label_len, "total", (float) update_cnt, update_cnt == 0 ? 0 : FAC * min_cnt, FAC * max_cnt, update_cnt == 0 ? 0 : FAC * ops_cnt / update_cnt ); fprintf( stdout, "\n" ); #ifdef WMOPS_WC_FRAME_ANALYSIS - /* calculate maximum label length for compact prinout */ - max_label_len = 0; - for ( i = 0; i < num_records; i++ ) - { - label_len = strlen( wmops[i].label ); - if ( label_len > max_label_len ) - { - max_label_len = label_len; - } - } - max_label_len += 4; - - fprintf( stdout, "\nComplexity analysis for the worst-case frame %ld:\n", fnum_cnt_wc ); - fprintf( stdout, "%*s %8s %10s %12s\n", max_label_len, " routine", " calls", " SELF", " CUMULATIVE" ); + fprintf( stdout, "\nComplexity analysis for the worst-case frame %ld:\n\n", fnum_cnt_wc ); + fprintf( stdout, "%*s %8s %10s %12s\n", max_label_len, " routine", " calls", " SELF", " CUMULATIVE" ); fprintf( stdout, "%*s %8s %10s %10s\n", max_label_len, "---------------", "------", "------", "----------" ); - for ( i = 0; i < num_records; i++ ) + for ( i = 0; i < num_wmops_records; i++ ) { - fprintf( stdout, "%*s %8d %10.3f %12.3f\n", max_label_len, wmops[i].label, wmops[i].wc_call_number, FAC * wmops[i].wc_selfcnt, FAC * wmops[i].wc_cnt ); + if ( wmops[i].wc_call_number > 0 ) + { + fprintf( stdout, "%*s %8d %10.3f %12.3f\n", max_label_len, wmops[i].label, wmops[i].wc_call_number, FAC * wmops[i].wc_selfcnt, FAC * wmops[i].wc_cnt ); + } } - fprintf( stdout, "\nCall Tree:\n\n" ); - fprintf( stdout, sfmtt, " function", "num", "called by: " ); + fprintf( stdout, "\nCall tree for the worst-case frame %ld:\n\n", fnum_cnt_wc ); + fprintf( stdout, sfmtt, " function", "num", "called by " ); fprintf( stdout, sfmtt, "---------------", "---", "--------------" ); - for ( i = 0; i < num_records; i++ ) + for ( i = 0; i < num_wmops_records; i++ ) { - fprintf( stdout, dfmtt, wmops[i].label, i ); - for ( j = 0; wmops[i].call_tree[j] != -1; j++ ) + if ( wmops[i].wc_call_number > 0 ) { - if ( j != 0 ) + fprintf( stdout, dfmtt, wmops[i].label, i ); + for ( j = 0; wmops[i].call_tree[j] != -1 && j < MAX_CALL_TREE_DEPTH; j++ ) { - fprintf( stdout, ", " ); + if ( j != 0 ) + { + fprintf( stdout, ", " ); + } + fprintf( stdout, "%d", wmops[i].call_tree[j] ); } - fprintf( stdout, "%d", wmops[i].call_tree[j] ); + fprintf( stdout, "\n" ); } - fprintf( stdout, "\n" ); } - fprintf( stdout, sfmtt, "---------------", "---", "--------------" ); fprintf( stdout, "\n\n" ); - fprintf( stdout, "\nInstruction type analysis for the worst-case frame %ld:\n\n", fnum_cnt_wc ); /* added -- JPA */ + fprintf( stdout, "\nInstruction type analysis for the worst-case frame %ld:\n\n", fnum_cnt_wc ); for ( i = 0; i < NUM_INST; i++ ) { switch ( (enum instructions) i ) @@ -498,6 +581,24 @@ void print_wmops( void ) } #endif + /* De-allocate the list of wmops record */ + if ( wmops != NULL ) + { + free( wmops ); + } + + /* De-allocate the list of wmops caller functions */ + if ( wmops_caller_stack != NULL ) + { + free( wmops_caller_stack ); + } + + /* De-allocate the BASOP WMOPS counter */ + if ( multiCounter != NULL ) + { + free( multiCounter ); + } + return; } @@ -524,12 +625,6 @@ void print_wmops( void ) * #define WMC_TOOL_SKIP ... #undef WMC_TOOL_SKIP macro pair around the malloc(), calloc() and free(). *--------------------------------------------------------------------*/ -#define MAX_RECORDABLE_CALLS 100 -#define MAX_FUNCTION_NAME_LENGTH 35 /* Maximum length that the function string will be truncated to */ -#define MAX_PARAMS_LENGTH 50 /* Maximum length that the parameter string will be truncated to */ -#define MAX_NUM_RECORDS 300 /* Initial maximum number of memory records -> mightb be increased during runtime, if needed */ -#define MAX_NUM_RECORDS_REALLOC_STEP 50 /* When re-allocating the list of memory records, increase the number of records by this number */ - /* This is the value (in bytes) towards which the block size is rounded. For example, a block of 123 bytes, when using a 32 bits system, will end up taking 124 bytes since the last unused byte cannot be used for another block. */ #ifdef MEM_ALIGN_64BITS @@ -539,15 +634,13 @@ void print_wmops( void ) #endif #define N_32BITS_BLOCKS ( BLOCK_ROUNDING / sizeof( int32_t ) ) +#define ROUND_BLOCK_SIZE( n ) ( ( ( n ) + BLOCK_ROUNDING - 1 ) & ~( BLOCK_ROUNDING - 1 ) ) #define MAGIC_VALUE_OOB 0x12A534F0 /* Signature value which is inserted before and after each allocated memory block, used to detect out-of-bound access */ #define MAGIC_VALUE_USED ( ~MAGIC_VALUE_OOB ) /* Value used to pre-fill allocated memory blocks, used to calculate actual memory usage */ #define OOB_START 0x1 /* Flag indicating out-of-bounds access before memory block */ #define OOB_END 0x2 /* Flag indicating out-of-bounds access after memory block */ -#define ROUND_BLOCK_SIZE( n ) ( ( ( n ) + BLOCK_ROUNDING - 1 ) & ~( BLOCK_ROUNDING - 1 ) ) -#define IS_CALLOC( str ) ( str[0] == 'c' ) - #ifdef MEM_COUNT_DETAILS const char *csv_filename = "mem_analysis.csv"; static FILE *fid_csv_filename = NULL; @@ -559,8 +652,16 @@ typedef struct int16_t *stack_ptr; } caller_info; -caller_info stack_callers[2][MAX_RECORDABLE_CALLS]; +static caller_info *stack_callers[2] = {NULL, NULL}; +static int16_t *ptr_base_stack = 0; /* Pointer to the bottom of stack (base pointer). Stack grows up. */ +static int16_t *ptr_current_stack = 0; /* Pointer to the current stack pointer */ +static int16_t *ptr_max_stack = 0; /* Pointer to the maximum stack pointer (the farest point from the bottom of stack) */ +static int32_t wc_stack_frame = 0; /* Frame corresponding to the worst-case stack usage */ +static int current_calls = 0, max_num_calls = MAX_NUM_RECORDS; +static char location_max_stack[256] = "undefined"; + +/* Heap-related variables */ typedef struct { char name[MAX_FUNCTION_NAME_LENGTH + 1]; /* +1 for NUL */ @@ -580,18 +681,12 @@ typedef struct allocator_record *allocation_list = NULL; -static int16_t *ptr_base_stack = 0; /* Pointer to the bottom of stack (base pointer). Stack grows up. */ -static int16_t *ptr_current_stack = 0; /* Pointer to the current stack pointer */ -static int16_t *ptr_max_stack = 0; /* Pointer to the maximum stack pointer (the farest point from the bottom of stack) */ -static int32_t wc_stack_frame = 0; /* Frame corresponding to the worst-case stack usage */ -static int32_t wc_ram_size, wc_ram_frame; -static int32_t current_heap_size; -static int current_calls = 0; -static char location_max_stack[256] = "undefined"; static int Num_Records, Max_Num_Records; static size_t Stat_Cnt_Size = USE_BYTES; -static const char *Count_Unit[] = { "bytes", "words", "words" }; +static const char *Count_Unit[] = { "bytes", "words", "words", "words" }; +static int32_t wc_ram_size, wc_ram_frame; +static int32_t current_heap_size; static int *list_wc_intra_frame_heap, n_items_wc_intra_frame_heap, max_items_wc_intra_frame_heap, size_wc_intra_frame_heap, location_wc_intra_frame_heap; static int *list_current_inter_frame_heap, n_items_current_inter_frame_heap, max_items_current_inter_frame_heap, size_current_inter_frame_heap; static int *list_wc_inter_frame_heap, n_items_wc_inter_frame_heap, max_items_wc_inter_frame_heap, size_wc_inter_frame_heap, location_wc_inter_frame_heap; @@ -612,11 +707,28 @@ void reset_mem( Counting_Size cnt_size ) int16_t something; size_t tmp_size; + /* initialize list of stack records */ + if ( stack_callers[0] == NULL ) + { + stack_callers[0] = malloc( MAX_NUM_RECORDS * sizeof( caller_info ) ); + stack_callers[1] = malloc( MAX_NUM_RECORDS * sizeof( caller_info ) ); + } + + if ( stack_callers[0] == NULL || stack_callers[1] == NULL ) + { + fprintf( stderr, "Error: Unable to Allocate List of Stack Records!" ); + exit( -1 ); + } + + current_calls = 0; + max_num_calls = MAX_NUM_RECORDS; + /* initialize stack pointers */ ptr_base_stack = &something; ptr_max_stack = ptr_base_stack; ptr_current_stack = ptr_base_stack; + /* initialize the unit of memory block size */ Stat_Cnt_Size = cnt_size; /* Check, if sizeof(int32_t) is 4 bytes */ @@ -742,11 +854,12 @@ int push_stack( const char *filename, const char *fctname ) (void) *filename; /* to avoid compilation warning */ - /* Is there room to save the caller's information? */ - if ( current_calls >= MAX_RECORDABLE_CALLS ) - { /* No */ - fprintf( stderr, "No more room to store call stack info. Please increase MAX_RECORDABLE_CALLS" ); - exit( -1 ); + if ( current_calls >= max_num_calls ) + { + /* There is no room for a new record -> reallocate the list */ + max_num_calls += MAX_NUM_RECORDS_REALLOC_STEP; + stack_callers[0] = realloc( stack_callers[0], max_num_calls * sizeof( caller_info ) ); + stack_callers[1] = realloc( stack_callers[1], max_num_calls * sizeof( caller_info ) ); } /* Valid Function Name? */ @@ -763,7 +876,7 @@ int push_stack( const char *filename, const char *fctname ) /* Save the Stack Pointer */ stack_callers[0][current_calls].stack_ptr = ptr_current_stack; - /* Increase Stack Calling Tree Level */ + /* Increase the Number of Calls in the List */ current_calls++; /* Is this the First Time or the Worst Case? */ @@ -772,15 +885,17 @@ int push_stack( const char *filename, const char *fctname ) /* Save Info about it */ ptr_max_stack = ptr_current_stack; - wc_stack_frame = update_cnt; /* current frame number is stored in the variable update_cnt and updated in the function update_wmops() */ + /* save the worst-case frame number */ + /* current frame number is stored in the variable update_cnt and updated in the function update_wmops() */ + wc_stack_frame = update_cnt; strncpy( location_max_stack, fctname, sizeof( location_max_stack ) - 1 ); location_max_stack[sizeof( location_max_stack ) - 1] = '\0'; /* Save Call Tree */ memmove( stack_callers[1], stack_callers[0], sizeof( caller_info ) * current_calls ); - /* Terminate the List (Unless Full) */ - if ( current_calls < MAX_RECORDABLE_CALLS ) + /* Terminate the List with 0 (for printing purposes) */ + if ( current_calls < max_num_calls ) { stack_callers[1][current_calls].function_name[0] = 0; } @@ -816,13 +931,13 @@ int pop_stack( const char *filename, const char *fctname ) (void) *filename; /* to avoid compilation warning */ - /* Decrease Stack Calling */ + /* Decrease the Number of Records */ current_calls--; /* Get Pointer to Caller Information */ caller_info_ptr = &stack_callers[0][current_calls]; - /* Check, if Names Match */ + /* Check, if the Function Names Match */ if ( strncmp( caller_info_ptr->function_name, fctname, MAX_FUNCTION_NAME_LENGTH ) != 0 ) { fprintf( stderr, "Invalid usage of pop_stack()" ); @@ -861,7 +976,7 @@ static void print_stack_call_tree( void ) fprintf( stdout, "\nList of functions when maximum stack size is reached:\n\n" ); caller_info_ptr = &stack_callers[1][0]; - for ( call_level = 0; call_level < MAX_RECORDABLE_CALLS; call_level++ ) + for ( call_level = 0; call_level < max_num_calls; call_level++ ) { /* Done? */ if ( caller_info_ptr->function_name[0] == 0 ) @@ -1060,7 +1175,7 @@ static void *mem_alloc_block( size_t size, const char *size_str ) /* Fill Memory Block with Magic Value or 0 */ fill_value = MAGIC_VALUE_USED; - if ( IS_CALLOC( size_str ) ) + if ( size_str[0] == 'c' ) { fill_value = 0x00000000; } @@ -1781,7 +1896,16 @@ void print_mem( ROM_Size_Lookup_Table Const_Data_PROM_Table[] ) for ( i = 0; i < nElem; i++ ) { - fprintf( stdout, "Program ROM size (%s): %d instruction words\n", Const_Data_PROM_Table[i].file_spec, Const_Data_PROM_Table[i].PROM_size ); + if ( Stat_Cnt_Size > 0 ) + { + /* words */ + fprintf( stdout, "Program ROM size (%s): %d words\n", Const_Data_PROM_Table[i].file_spec, Const_Data_PROM_Table[i].PROM_size ); + } + else + { + /* bytes */ + fprintf( stdout, "Program ROM size (%s): %d bytes\n", Const_Data_PROM_Table[i].file_spec, Const_Data_PROM_Table[i].PROM_size << Stat_Cnt_Size ); + } } for ( i = 0; i < nElem; i++ ) @@ -1870,11 +1994,12 @@ void print_mem( ROM_Size_Lookup_Table Const_Data_PROM_Table[] ) mem_count_summary(); #endif - if ( Stat_Cnt_Size > 0 ) + if ( Stat_Cnt_Size == 0 ) { - fprintf( stdout, "\nNote: 1 word = %d bits\n", 8 << Stat_Cnt_Size ); - fprintf( stdout, "This is an optimistic estimate of memory consumption assuming that each variable type is stored with sizeof(type) bits\n" ); + /* bytes */ + fprintf( stdout, "\nNote: The Program ROM size is calculated under the assumption that 1 instruction word is stored with %d bytes (%d bits)\n", 1 << Stat_Cnt_Size, 8 << Stat_Cnt_Size ); } + fprintf( stdout, "Note: The Data ROM size is calculated using the sizeof(type) built-in function\n" ); if ( n_items_wc_intra_frame_heap > 0 ) { @@ -1887,6 +2012,17 @@ void print_mem( ROM_Size_Lookup_Table Const_Data_PROM_Table[] ) free( allocation_list ); } + /* De-allocate list of stack records */ + if ( stack_callers[0] != NULL ) + { + free( stack_callers[0] ); + } + + if ( stack_callers[1] != NULL ) + { + free( stack_callers[1] ); + } + /* De-allocate heap allocation call tree */ if ( heap_allocation_call_tree != NULL ) { @@ -1924,3 +2060,105 @@ void print_mem( ROM_Size_Lookup_Table Const_Data_PROM_Table[] ) #ifndef WMOPS int cntr_push_pop = 0; /* global counter for checking balanced push_wmops()/pop_wmops() pairs when WMOPS is not activated */ #endif + +#ifdef WMOPS +/* Global counter for the calculation of BASOP complexity */ +BASIC_OP *multiCounter = NULL; +int currCounter = 0; +int funcId_where_last_call_to_else_occurred; +long funcid_total_wmops_at_last_call_to_else; +int call_occurred = 1; + +BASIC_OP op_weight = { + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 2, 2, 1, + 1, 1, 1, 3, 1, + + 1, 1, 1, 3, 1, + 4, 1, 18, 1, 1, + 2, 1, 2, 2, 1, + 1, 1, 1, 1, 1, + 3, 3, 3, 3, 1, + + 1, 1, 1, 1, 1, + 1, 1, 1, 2, + 1, 2, 2, 4, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 3, + 3, 3, 3, 3, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 4, 4, + 4, 8, 3, 4, 4, + + 5, 32, 3 +}; + +/* Set the counter group to use, default is zero */ +void Set_BASOP_WMOPS_counter( int counterId ) +{ + if ( ( counterId > num_wmops_records ) || ( counterId < 0 ) ) + { + currCounter = 0; + return; + } + currCounter = counterId; + call_occurred = 1; +} + +extern int32_t frame; + +long TotalWeightedOperation() +{ + int i; + unsigned int *ptr, *ptr2; + long tot; + + tot = 0; + ptr = (unsigned int *) &multiCounter[currCounter]; + ptr2 = (unsigned int *) &op_weight; + + for ( i = 0; i < ( int )( sizeof( multiCounter[currCounter] ) / sizeof( unsigned int ) ); i++ ) + { + tot += ( ( *ptr++ ) * ( *ptr2++ ) ); + } + + return ( tot ); +} + +long DeltaWeightedOperation( void ) +{ + long NewWOper, delta; + + NewWOper = TotalWeightedOperation(); + + delta = NewWOper - wmops[currCounter].LastWOper; + wmops[currCounter].LastWOper = NewWOper; + + return ( delta ); +} + +/* Resets the current BASOP WMOPS counter */ +void Reset_BASOP_WMOPS_counter( void ) +{ + int i; + long *ptr; + + /* clear the current BASOP operation counter before new frame begins */ + ptr = (long *) &multiCounter[currCounter]; + for ( i = 0; i < (int) ( sizeof( multiCounter[currCounter] ) / sizeof( long ) ); i++ ) + { + *ptr++ = 0; + } + + wmops[currCounter].LastWOper = 0; + + return; +} + +#endif + + diff --git a/lib_debug/wmc_auto.h b/lib_debug/wmc_auto.h index 9e20a4c7c..e2f2af4d8 100644 --- a/lib_debug/wmc_auto.h +++ b/lib_debug/wmc_auto.h @@ -1,5 +1,5 @@ /* - * (C) 2022 copyright VoiceAge Corporation. All Rights Reserved. + * (C) 2023 copyright VoiceAge Corporation. All Rights Reserved. * * This software is protected by copyright law and by international treaties. The source code, and all of its derivations, * is provided by VoiceAge Corporation under the "ITU-T Software Tools' General Public License". Please, read the license file @@ -29,13 +29,14 @@ #pragma GCC system_header #endif +#ifndef INT_MAX +#define INT_MAX 32767 +#endif + /* Real-time relationships */ -#define FRAMES_PER_SECOND 50.0 -#define MILLION_CYCLES 1e6 +#define FRAMES_PER_SECOND 50.0 #define WMOPS_BOOST_FAC ( 1.0f ) /* scaling factor for equalizing the difference between automatic and manual instrumentation */ -#define FAC ( FRAMES_PER_SECOND / MILLION_CYCLES * WMOPS_BOOST_FAC ) -#define NUM_INST 20 /* Total number of instruction types (in enum below) */ - +#define FAC ( FRAMES_PER_SECOND / 1e6 * WMOPS_BOOST_FAC ) #ifdef WMOPS enum instructions @@ -59,7 +60,8 @@ enum instructions _TEST, _POWER, _LOG, - _MISC + _MISC, + NUM_INST }; #define _ADD_C 1 @@ -561,7 +563,6 @@ enum instructions extern double ops_cnt; extern double prom_cnt; extern double inst_cnt[NUM_INST]; -extern int ops_cnt_activ; void reset_wmops( void ); void push_wmops( const char *label ); @@ -980,7 +981,8 @@ typedef enum { USE_BYTES = 0, USE_16BITS = 1, - USE_32BITS = 2 + USE_32BITS = 2, + USE_64BITS = 3 } Counting_Size; #if ( defined( _WIN32 ) && ( _MSC_VER <= 1800 ) && ( _MSC_VER >= 1300 ) ) @@ -1012,7 +1014,7 @@ int push_stack( const char *filename, const char *fctname ); int pop_stack( const char *filename, const char *fctname ); #ifdef WMOPS_DETAIL -#define STACK_DEPTH_FCT_CALL ( push_wmops( __FUNCTION__ ), push_stack( __FILE__, __FUNCTION__ ) ) /* add push_wmops() in all function calls */ +#define STACK_DEPTH_FCT_CALL ( push_wmops( __FUNCTION__ " [WMC_AUTO]" ), push_stack( __FILE__, __FUNCTION__ ) ) /* add push_wmops() in all function calls */ #define STACK_DEPTH_FCT_RETURN ( pop_wmops(), pop_stack( __FILE__, __FUNCTION__ ) ) /* add pop_wmops() in all function returns */ #else #define STACK_DEPTH_FCT_CALL push_stack( __FILE__, __FUNCTION__ ) @@ -1036,4 +1038,405 @@ void reset_stack( void ); #endif + +/* Global counter variable for calculation of complexity weight */ +typedef struct +{ + unsigned int add; /* Complexity Weight of 1 */ + unsigned int sub; /* Complexity Weight of 1 */ + unsigned int abs_s; /* Complexity Weight of 1 */ + unsigned int shl; /* Complexity Weight of 1 */ + unsigned int shr; /* Complexity Weight of 1 */ + + unsigned int extract_h; /* Complexity Weight of 1 */ + unsigned int extract_l; /* Complexity Weight of 1 */ + unsigned int mult; /* Complexity Weight of 1 */ + unsigned int L_mult; /* Complexity Weight of 1 */ + unsigned int negate; /* Complexity Weight of 1 */ + + unsigned int round; /* Complexity Weight of 1 */ + unsigned int L_mac; /* Complexity Weight of 1 */ + unsigned int L_msu; /* Complexity Weight of 1 */ + unsigned int L_macNs; /* Complexity Weight of 1 */ + unsigned int L_msuNs; /* Complexity Weight of 1 */ + + unsigned int L_add; /* Complexity Weight of 1 */ + unsigned int L_sub; /* Complexity Weight of 1 */ + unsigned int L_add_c; /* Complexity Weight of 2 */ + unsigned int L_sub_c; /* Complexity Weight of 2 */ + unsigned int L_negate; /* Complexity Weight of 1 */ + + unsigned int L_shl; /* Complexity Weight of 1 */ + unsigned int L_shr; /* Complexity Weight of 1 */ + unsigned int mult_r; /* Complexity Weight of 1 */ + unsigned int shr_r; /* Complexity Weight of 3 */ + unsigned int mac_r; /* Complexity Weight of 1 */ + + unsigned int msu_r; /* Complexity Weight of 1 */ + unsigned int L_deposit_h; /* Complexity Weight of 1 */ + unsigned int L_deposit_l; /* Complexity Weight of 1 */ + unsigned int L_shr_r; /* Complexity Weight of 3 */ + unsigned int L_abs; /* Complexity Weight of 1 */ + + unsigned int L_sat; /* Complexity Weight of 4 */ + unsigned int norm_s; /* Complexity Weight of 1 */ + unsigned int div_s; /* Complexity Weight of 18 */ + unsigned int norm_l; /* Complexity Weight of 1 */ + unsigned int move16; /* Complexity Weight of 1 */ + + unsigned int move32; /* Complexity Weight of 2 */ + unsigned int Logic16; /* Complexity Weight of 1 */ + unsigned int Logic32; /* Complexity Weight of 2 */ + unsigned int Test; /* Complexity Weight of 2 */ + unsigned int s_max; /* Complexity Weight of 1 */ + + unsigned int s_min; /* Complexity Weight of 1 */ + unsigned int L_max; /* Complexity Weight of 1 */ + unsigned int L_min; /* Complexity Weight of 1 */ + unsigned int L40_max; /* Complexity Weight of 1 */ + unsigned int L40_min; /* Complexity Weight of 1 */ + + unsigned int shl_r; /* Complexity Weight of 3 */ + unsigned int L_shl_r; /* Complexity Weight of 3 */ + unsigned int L40_shr_r; /* Complexity Weight of 3 */ + unsigned int L40_shl_r; /* Complexity Weight of 3 */ + unsigned int norm_L40; /* Complexity Weight of 1 */ + + unsigned int L40_shl; /* Complexity Weight of 1 */ + unsigned int L40_shr; /* Complexity Weight of 1 */ + unsigned int L40_negate; /* Complexity Weight of 1 */ + unsigned int L40_add; /* Complexity Weight of 1 */ + unsigned int L40_sub; /* Complexity Weight of 1 */ + + unsigned int L40_abs; /* Complexity Weight of 1 */ + unsigned int L40_mult; /* Complexity Weight of 1 */ + unsigned int L40_mac; /* Complexity Weight of 1 */ + unsigned int mac_r40; /* Complexity Weight of 2 */ + + unsigned int L40_msu; /* Complexity Weight of 1 */ + unsigned int msu_r40; /* Complexity Weight of 2 */ + unsigned int Mpy_32_16_ss; /* Complexity Weight of 2 */ + unsigned int Mpy_32_32_ss; /* Complexity Weight of 4 */ + unsigned int L_mult0; /* Complexity Weight of 1 */ + + unsigned int L_mac0; /* Complexity Weight of 1 */ + unsigned int L_msu0; /* Complexity Weight of 1 */ + unsigned int lshl; /* Complexity Weight of 1 */ + unsigned int lshr; /* Complexity Weight of 1 */ + unsigned int L_lshl; /* Complexity Weight of 1 */ + + unsigned int L_lshr; /* Complexity Weight of 1 */ + unsigned int L40_lshl; /* Complexity Weight of 1 */ + unsigned int L40_lshr; /* Complexity Weight of 1 */ + unsigned int s_and; /* Complexity Weight of 1 */ + unsigned int s_or; /* Complexity Weight of 1 */ + + unsigned int s_xor; /* Complexity Weight of 1 */ + unsigned int L_and; /* Complexity Weight of 1 */ + unsigned int L_or; /* Complexity Weight of 1 */ + unsigned int L_xor; /* Complexity Weight of 1 */ + unsigned int rotl; /* Complexity Weight of 3 */ + + unsigned int rotr; /* Complexity Weight of 3 */ + unsigned int L_rotl; /* Complexity Weight of 3 */ + unsigned int L_rotr; /* Complexity Weight of 3 */ + unsigned int L40_set; /* Complexity Weight of 3 */ + unsigned int L40_deposit_h; /* Complexity Weight of 1 */ + + unsigned int L40_deposit_l; /* Complexity Weight of 1 */ + unsigned int L40_deposit32; /* Complexity Weight of 1 */ + unsigned int Extract40_H; /* Complexity Weight of 1 */ + unsigned int Extract40_L; /* Complexity Weight of 1 */ + unsigned int L_Extract40; /* Complexity Weight of 1 */ + + unsigned int L40_round; /* Complexity Weight of 1 */ + unsigned int L_saturate40; /* Complexity Weight of 1 */ + unsigned int round40; /* Complexity Weight of 1 */ + unsigned int If; /* Complexity Weight of 4 */ + unsigned int Goto; /* Complexity Weight of 4 */ + + unsigned int Break; /* Complexity Weight of 4 */ + unsigned int Switch; /* Complexity Weight of 8 */ + unsigned int For; /* Complexity Weight of 3 */ + unsigned int While; /* Complexity Weight of 4 */ + unsigned int Continue; /* Complexity Weight of 4 */ + + unsigned int L_mls; /* Complexity Weight of 6 */ + unsigned int div_l; /* Complexity Weight of 32 */ + unsigned int i_mult; /* Complexity Weight of 3 */ +} BASIC_OP; + +#ifdef WMOPS +extern BASIC_OP *multiCounter; +extern int currCounter; + +/* Technical note : + * The following 3 variables are only used for correct complexity + * evaluation of the following structure : + * IF{ + * ... + * } ELSE IF { + * ... + * } ELSE IF { + * ... + * } + * ... + * } ELSE { + * ... + * } + */ +extern int funcId_where_last_call_to_else_occurred; +extern long funcid_total_wmops_at_last_call_to_else; +extern int call_occurred; + +extern long TotalWeightedOperation( void ); +long DeltaWeightedOperation( void ); + +void Set_BASOP_WMOPS_counter( int counterId ); +void Reset_BASOP_WMOPS_counter( void ); + +#endif + +/***************************************************************************** + * + * Function Name : FOR + * + * Purpose : + * + * The macro FOR should be used instead of the 'for' C statement. + * The complexity is independent of the number of loop iterations that are + * performed. + * + * Complexity weight : 3 (regardless of number of iterations). + * + *****************************************************************************/ +#ifndef WMOPS +#define FOR( a) for( a) + +#else +#define FOR( a) if( incrFor(), 0); else for( a) + +static __inline void incrFor( void) { + multiCounter[currCounter].For++; +} +#endif + + +/***************************************************************************** + * + * Function Name : WHILE + * + * Purpose : + * + * The macro WHILE should be used instead of the 'while' C statement. + * The complexity is proportional to the number of loop iterations that + * are performed. + * + * Complexity weight : 4 x 'number of loop iterations'. + * + *****************************************************************************/ +#ifndef WMOPS +#define WHILE( a) while( a) + +#else +#define WHILE( a) while( incrWhile(), a) + +static __inline void incrWhile( void) { + multiCounter[currCounter].While++; +} +#endif + + +/***************************************************************************** + * + * Function Name : DO + * + * Purpose : + * + * The macro DO should be used instead of the 'do' C statement. + * + * Complexity weight : 0 (complexity counted by WHILE macro). + * + *****************************************************************************/ +#ifndef WMOPS +#define DO do + +#else +#define DO do + +#endif + + +/***************************************************************************** + * + * Function Name : IF + * + * Purpose : + * + * The macro IF should : + * + * - not be used when : + * - the 'if' structure does not have any 'else if' nor 'else' statement + * - and it conditions only one DSP basic operations. + * + * - be used instead of the 'if' C statement in every other case : + * - when there is an 'else' or 'else if' statement, + * - or when the 'if' conditions several DSP basic operations, + * - or when the 'if' conditions a function call. + * + * Complexity weight : 4 + * + *****************************************************************************/ +#ifndef WMOPS +#define IF( a) if( a) + +#else +#define IF( a) if( incrIf(), a) + +static __inline void incrIf( void) { + /* Technical note : + * If the "IF" operator comes just after an "ELSE", its counter + * must not be incremented. + */ + if ( ( currCounter != funcId_where_last_call_to_else_occurred ) || ( TotalWeightedOperation() != funcid_total_wmops_at_last_call_to_else ) || ( call_occurred == 1 ) ) + { + multiCounter[currCounter].If++; + } + + call_occurred = 0; + funcId_where_last_call_to_else_occurred = INT_MAX; +} +#endif + + +/***************************************************************************** + * + * Function Name : ELSE + * + * Purpose : + * + * The macro ELSE should be used instead of the 'else' C statement. + * + * Complexity weight : 4 + * + *****************************************************************************/ +#ifndef WMOPS +#define ELSE else + +#else +#define ELSE else if( incrElse(), 0) ; else + +static __inline void incrElse( void) { + multiCounter[currCounter].If++; + + /* We keep track of the funcId of the last function + * which used ELSE {...} structure. + */ + funcId_where_last_call_to_else_occurred = currCounter; + + /* We keep track of the number of WMOPS of this funcId + * when the ELSE macro was called. + */ + funcid_total_wmops_at_last_call_to_else = TotalWeightedOperation(); + + /* call_occurred is set to 0, in order to count the next IF (if necessary) + */ + call_occurred = 0; +} +#endif + + +/***************************************************************************** + * + * Function Name : SWITCH + * + * Purpose : + * + * The macro SWITCH should be used instead of the 'switch' C statement. + * + * Complexity weight : 8 + * + *****************************************************************************/ +#ifndef WMOPS +#define SWITCH( a) switch( a) + +#else +#define SWITCH( a) switch( incrSwitch(), a) + +static __inline void incrSwitch( void) { + multiCounter[currCounter].Switch++; +} +#endif + + +/***************************************************************************** + * + * Function Name : CONTINUE + * + * Purpose : + * + * The macro CONTINUE should be used instead of the 'continue' C statement. + * + * Complexity weight : 4 + * + *****************************************************************************/ +#ifndef WMOPS +#define CONTINUE continue + +#else +#define CONTINUE if( incrContinue(), 0); else continue + +static __inline void incrContinue( void) { + multiCounter[currCounter].Continue++; +} +#endif + + +/***************************************************************************** + * + * Function Name : BREAK + * + * Purpose : + * + * The macro BREAK should be used instead of the 'break' C statement. + * + * Complexity weight : 4 + * + *****************************************************************************/ +#ifndef WMOPS +#define BREAK break + +#else +#define BREAK if( incrBreak(), 0) break; else break + +static __inline void incrBreak( void) { + multiCounter[currCounter].Break++; +} +#endif + + +/***************************************************************************** + * + * Function Name : GOTO + * + * Purpose : + * + * The macro GOTO should be used instead of the 'goto' C statement. + * + * Complexity weight : 4 + * + *****************************************************************************/ +#ifndef WMOPS +#define GOTO goto + +#else +#define GOTO if( incrGoto(), 0); else goto + +static __inline void incrGoto( void) { + multiCounter[currCounter].Goto++; +} +#endif + #endif /* WMOPS_H */ + + diff --git a/lib_dec/bass_psfilter.c b/lib_dec/bass_psfilter.c index 74ab92747..94538e1e7 100644 --- a/lib_dec/bass_psfilter.c +++ b/lib_dec/bass_psfilter.c @@ -519,7 +519,7 @@ void addBassPostFilter( int16_t res_bpf_adapt( STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo decoder handle */ const float *bpf_error_signal_8k, /* i : BPF modification signal */ - float res_buf[STEREO_DFT_BUF_MAX] /* i : residual buffer */ + float res_buf[STEREO_DFT_N_8k] /* i : residual buffer */ ) { float error_nrg; diff --git a/lib_dec/fd_cng_dec.c b/lib_dec/fd_cng_dec.c index c736e2462..7745630fe 100644 --- a/lib_dec/fd_cng_dec.c +++ b/lib_dec/fd_cng_dec.c @@ -1101,7 +1101,7 @@ void generate_comfort_noise_dec( c2 = (float) sqrt( 1 - hFdCngCom->coherence ); seed2 = &( hFdCngCom->seed2 ); - if ( ( st->element_mode == IVAS_CPE_MDCT && st->idchan == 1 ) || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) ) + if ( st->element_mode == IVAS_CPE_MDCT && st->idchan == 1 ) { seed2 = &( hFdCngCom->seed3 ); } @@ -1351,11 +1351,12 @@ void generate_comfort_noise_dec_hf( float scale = CLDFB_SCALING / hFdCngCom->scalingFactor; int16_t *seed2 = &( hFdCngCom->seed ); + float tmp1, tmp2, c1 = 0.f, c2 = 0.f; if ( cng_coh_flag ) { - seed2 = &( hFdCngCom->seed3 ); + seed2 = &( hFdCngCom->seed2 ); c1 = (float) sqrt( hFdCngCom->coherence ); c2 = (float) sqrt( 1 - hFdCngCom->coherence ); diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index b74191070..77e01cd30 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -161,19 +161,19 @@ static ivas_error ivas_binRenderer_convModuleOpen( } for ( ; bandIdx < 10; bandIdx++ ) { - hBinRenConvModule->numTapsArray[bandIdx] = (int16_t) ceil( 0.6f * hBinRenConvModule->numTaps ); + hBinRenConvModule->numTapsArray[bandIdx] = (int16_t) ceilf( 0.6f * hBinRenConvModule->numTaps ); } for ( ; bandIdx < 20; bandIdx++ ) { - hBinRenConvModule->numTapsArray[bandIdx] = (int16_t) ceil( 0.5f * hBinRenConvModule->numTaps ); + hBinRenConvModule->numTapsArray[bandIdx] = (int16_t) ceilf( 0.5f * hBinRenConvModule->numTaps ); } for ( ; bandIdx < 30; bandIdx++ ) { - hBinRenConvModule->numTapsArray[bandIdx] = (int16_t) ceil( 0.4f * hBinRenConvModule->numTaps ); + hBinRenConvModule->numTapsArray[bandIdx] = (int16_t) ceilf( 0.4f * hBinRenConvModule->numTaps ); } for ( ; bandIdx < hBinRenderer->conv_band; bandIdx++ ) { - hBinRenConvModule->numTapsArray[bandIdx] = (int16_t) ceil( 0.3f * hBinRenConvModule->numTaps ); + hBinRenConvModule->numTapsArray[bandIdx] = (int16_t) ceilf( 0.3f * hBinRenConvModule->numTaps ); } } else @@ -765,12 +765,7 @@ static void ivas_binaural_obtain_DMX( { int16_t chIdx, bandIdx, k; -#ifdef FIX_785_REMOVE_DEAD_CODE if ( hBinRenderer->ivas_format == MC_FORMAT ) -#else - // ToDo: hBinRenderer->ivas_format is never set to ISM_FORMAT - if ( hBinRenderer->ivas_format == MC_FORMAT || hBinRenderer->ivas_format == ISM_FORMAT ) -#endif { /* Obtain the downmix */ float P_in[CLDFB_NO_CHANNELS_MAX]; @@ -1318,8 +1313,7 @@ void ivas_binaural_add_LFE( void ivas_binRenderer( BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle*/ - int16_t subframe_idx, /* i : subframe index */ - const int16_t numTimeSlots, /* i : number of time slots to render */ + const int16_t numTimeSlots, /* i : number of time slots to render */ float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ @@ -1342,24 +1336,24 @@ void ivas_binRenderer( } /* Head rotation in HOA3 or CICPx */ - if ( hCombinedOrientationData != NULL && hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && hBinRenderer->rotInCldfb ) + if ( hCombinedOrientationData != NULL && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] && hBinRenderer->rotInCldfb ) { if ( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 ) { /* Rotation in SHD (HOA3) */ if ( hCombinedOrientationData->shd_rot_max_order == -1 ) { - rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat[subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 ); + rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 ); } else if ( hCombinedOrientationData->shd_rot_max_order > 0 ) { - rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat[subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, hCombinedOrientationData->shd_rot_max_order ); + rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, hCombinedOrientationData->shd_rot_max_order ); } } else { /* Rotation in SD (CICPx) */ - rotateFrame_sd_cldfb( hCombinedOrientationData->Rmat[subframe_idx], RealBuffer, ImagBuffer, hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band ); + rotateFrame_sd_cldfb( hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], RealBuffer, ImagBuffer, hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band ); } } diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index 7ad9082fb..aa3c2a8c8 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -49,18 +49,13 @@ *-------------------------------------------------------------------*/ ivas_error ivas_core_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - SCE_DEC_HANDLE hSCE, /* i/o: SCE decoder structure */ - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */ - const int16_t n_channels, /* i : number of channels to be decoded */ -#ifdef FIX_854_ARRAY_SIZE_MISMATCH - float *output[], /* o : output synthesis signal */ - float hb_synth[][L_FRAME48k], /* o : output HB synthesis signal */ -#else - float *output[L_FRAME48k], /* o : output synthesis signal */ - float hb_synth[CPE_CHANNELS][L_FRAME48k], /* o : output HB synthesis signal */ -#endif + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + SCE_DEC_HANDLE hSCE, /* i/o: SCE decoder structure */ + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */ + const int16_t n_channels, /* i : number of channels to be decoded */ + float *output[], /* o : output synthesis signal */ + float hb_synth[][L_FRAME48k], /* o : output HB synthesis signal */ float DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* o : DFT buffers */ const int16_t sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ ) @@ -111,7 +106,7 @@ ivas_error ivas_core_dec( sts = hSCE->hCoreCoder; hStereoICBWE = NULL; element_brate = hSCE->element_brate; - last_element_brate = hSCE->element_brate; /* hack - the past parameter is not really needed */ + last_element_brate = hSCE->last_element_brate; /* note: this parameter is unused */ last_element_mode = IVAS_SCE; hStereoTD = NULL; p_output_mem = NULL; diff --git a/lib_dec/ivas_corecoder_dec_reconfig.c b/lib_dec/ivas_corecoder_dec_reconfig.c index 824597314..e8d73d28c 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig.c +++ b/lib_dec/ivas_corecoder_dec_reconfig.c @@ -61,6 +61,8 @@ ivas_error ivas_corecoder_dec_reconfig( MC_MODE last_mc_mode; DECODER_CONFIG_HANDLE hDecoderConfig; ivas_error error; + int16_t prev_bfi; + Decoder_State *st0; /*-----------------------------------------------------------------* * Initialization @@ -138,6 +140,8 @@ ivas_error ivas_corecoder_dec_reconfig( } else { + st0 = ( nSCE_old > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; + prev_bfi = st0->prev_bfi; nSCE_existing = min( nSCE_old, st_ivas->nSCE ); nCPE_existing = min( nCPE_old, st_ivas->nCPE ); @@ -210,6 +214,7 @@ ivas_error ivas_corecoder_dec_reconfig( { return error; } + st_ivas->hSCE[sce_id]->hCoreCoder[0]->prev_bfi = prev_bfi; } if ( st_ivas->sba_dirac_stereo_flag && sba_dirac_stereo_flag_old && st_ivas->nchan_transport == 1 && nSCE_old == 0 ) { @@ -238,6 +243,8 @@ ivas_error ivas_corecoder_dec_reconfig( { return error; } + st_ivas->hCPE[cpe_id]->hCoreCoder[0]->prev_bfi = prev_bfi; + st_ivas->hCPE[cpe_id]->hCoreCoder[1]->prev_bfi = prev_bfi; } if ( st_ivas->nCPE > 1 && nCPE_old <= 1 ) diff --git a/lib_dec/ivas_cpe_dec.c b/lib_dec/ivas_cpe_dec.c index 8b7b8ce13..85c7b7a11 100644 --- a/lib_dec/ivas_cpe_dec.c +++ b/lib_dec/ivas_cpe_dec.c @@ -242,6 +242,8 @@ ivas_error ivas_cpe_dec( { nb_bits -= SID_FORMAT_NBITS; sts[1]->bit_stream -= SID_FORMAT_NBITS; + /* set total bitrate of Stereo CNG parameters for BER detection */ + sts[1]->total_brate = IVAS_SID_5k2 - SID_2k40; } if ( ( ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE ) || ( st_ivas->ivas_format == MASA_ISM_FORMAT && cpe_brate < MASA_STEREO_MIN_BITRATE ) ) && ivas_total_brate > IVAS_SID_5k2 ) @@ -250,6 +252,15 @@ ivas_error ivas_cpe_dec( } else { + if ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) + { + nb_bits -= nb_bits_metadata; + if ( hCPE->brate_surplus < 0 ) + { + nb_bits += (int16_t) ( hCPE->brate_surplus / FRAMES_PER_SEC ); + } + } + stereo_dft_dec_read_BS( ivas_total_brate, hCPE->element_brate, &sts[0]->total_brate, sts[1], hCPE->hStereoDft, sts[0]->bwidth, output_frame, res_buf, &nb_bits, hCPE->hStereoCng->coh, st_ivas->ivas_format ); } @@ -1074,10 +1085,8 @@ static void stereo_mode_combined_format_dec( ( ( st_ivas->nchan_ism == 3 && st_ivas->hDecoderConfig->ivas_total_brate == IVAS_96k ) || ( st_ivas->nchan_ism == 4 && st_ivas->hDecoderConfig->ivas_total_brate == IVAS_128k ) ) ) { -#ifdef NONBE_FIX_849_OMASA_BFI_CRASH if ( !st_ivas->bfi ) { -#endif /* read OMASA stereo mode signalling */ if ( get_next_indice( hCPE->hCoreCoder[0], NBITS_ELEMENT_MODE ) ) { @@ -1087,9 +1096,7 @@ static void stereo_mode_combined_format_dec( { hCPE->element_mode = IVAS_CPE_DFT; } -#ifdef NONBE_FIX_849_OMASA_BFI_CRASH } -#endif if ( hCPE->element_mode == IVAS_CPE_MDCT ) { diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index 48d9012b1..e32a69539 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -50,924 +50,12 @@ ivas_error ivas_dec( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - int16_t *data /* o : output synthesis signal */ + int16_t *data /* o : output synthesis signal */ ) { - int16_t n, output_frame, nchan_out; - Decoder_State *st; /* used for bitstream handling */ - float *p_output[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; /* 'float' buffer for output synthesis */ - int16_t nchan_remapped; - int16_t nb_bits_metadata[MAX_SCE + 1]; - int32_t output_Fs, ivas_total_brate; - AUDIO_CONFIG output_config; - ivas_error error; - int16_t num_md_sub_frames; - int32_t ism_total_brate; + // TODO: move here function ivas_jbm_dec_tc() and rename it to ivas_dec() + st_ivas->ivas_format = UNDEFINED_FORMAT; // temp. to avoid compilation warnings + data[0] = 0; // temp. to avoid compilation warnings - push_wmops( "ivas_dec" ); - - /*----------------------------------------------------------------* - * Initialization of local vars after struct has been set - *----------------------------------------------------------------*/ - - output_Fs = st_ivas->hDecoderConfig->output_Fs; - nchan_out = st_ivas->hDecoderConfig->nchan_out; - output_config = st_ivas->hDecoderConfig->output_config; - ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; - - output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC ); - - for ( n = 0; n < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; n++ ) - { - p_output[n] = st_ivas->p_output_f[n]; - } - - /*----------------------------------------------------------------* - * Combine orientations - *----------------------------------------------------------------*/ - - if ( ( error = combine_external_and_head_orientations_dec( st_ivas->hHeadTrackData, st_ivas->hExtOrientationData, st_ivas->hCombinedOrientationData ) ) != IVAS_ERR_OK ) - { - return error; - } - - - /*----------------------------------------------------------------* - * Decoding + Rendering - *----------------------------------------------------------------*/ - - if ( st_ivas->bfi && st_ivas->ini_frame == 0 ) - { - for ( n = 0; n < nchan_out; n++ ) - { - /* note: these are intra-frame heap memories */ - if ( ( st_ivas->p_output_f[n] = (float *) malloc( ( 48000 / FRAMES_PER_SEC ) * sizeof( float ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for floating-point output audio buffer!\n" ) ); - } - p_output[n] = st_ivas->p_output_f[n]; - } - - /* zero output when first frame(s) is lost */ - for ( n = 0; n < nchan_out; n++ ) - { - set_f( p_output[n], 0.0f, output_frame ); - } - - } - else if ( st_ivas->ivas_format == STEREO_FORMAT ) - { - st_ivas->hCPE[0]->element_brate = ivas_total_brate; - - if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, 0 ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* HP filtering */ - for ( n = 0; n < min( nchan_out, st_ivas->nchan_transport ); n++ ) - { - hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); - } - - /* Rendering */ - if ( st_ivas->renderer_type == RENDERER_MC ) - { - ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, output_frame, p_output, p_output ); - } - } - else if ( st_ivas->ivas_format == ISM_FORMAT ) - { - /* Metadata decoding and configuration */ - if ( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) - { - if ( ( error = ivas_ism_dtx_dec( st_ivas, nb_bits_metadata ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* decode dominant object first so the noise energy of the other objects can be limited */ - if ( ( error = ivas_sce_dec( st_ivas, st_ivas->hISMDTX.sce_id_dtx, &p_output[st_ivas->hISMDTX.sce_id_dtx], output_frame, nb_bits_metadata[st_ivas->hISMDTX.sce_id_dtx] ) ) != IVAS_ERR_OK ) - { - return error; - } - - ivas_ism_dtx_limit_noise_energy_for_near_silence( st_ivas->hSCE, st_ivas->hISMDTX.sce_id_dtx, st_ivas->nchan_transport ); - } - else if ( st_ivas->ism_mode == ISM_MODE_PARAM ) - { - if ( ( error = ivas_ism_metadata_dec( ivas_total_brate, st_ivas->nchan_ism, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, st_ivas->hParamIsmDec->hParamIsm, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt, st_ivas->hSCE[0]->hCoreCoder[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else /* ISM_MODE_DISC */ - { - if ( ( error = ivas_ism_metadata_dec( ivas_total_brate, st_ivas->nchan_ism, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, NULL, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt, st_ivas->hSCE[0]->hCoreCoder[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - for ( n = 0; n < st_ivas->nchan_transport; n++ ) - { - /* for DTX frames, dominant object has already been decoded before */ - if ( !( ( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) && n == st_ivas->hISMDTX.sce_id_dtx ) ) - { - if ( ( error = ivas_sce_dec( st_ivas, n, &p_output[n], output_frame, nb_bits_metadata[n] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - /* HP filtering */ - hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); - } - - /* Rendering */ - if ( st_ivas->ism_mode == ISM_MODE_PARAM ) - { - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) - { - /* loudness correction */ - ivas_dirac_dec_binaural_sba_gain( p_output, st_ivas->nchan_transport, output_frame ); - - ivas_param_ism_params_to_masa_param_mapping( st_ivas ); - - ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, p_output, st_ivas->nchan_transport, MAX_PARAM_SPATIAL_SUBFRAMES ); - } - else if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX ) - { - ivas_mono_downmix_render_passive( st_ivas, p_output, output_frame ); - } - else if ( st_ivas->renderer_type == RENDERER_NON_DIEGETIC_DOWNMIX ) - { - ivas_apply_non_diegetic_panning( p_output, st_ivas->hDecoderConfig->non_diegetic_pan_gain, output_frame ); - } - else if ( st_ivas->renderer_type == RENDERER_PARAM_ISM || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) - { - ivas_param_ism_dec( st_ivas, p_output ); - - if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) - { - /* Convert CICP19 -> Ambisonics */ - ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, output_frame, st_ivas->hOutSetup.ambisonics_order, 0.f ); - } - } - } - else /* ISM_MODE_DISC */ - { - /* Loudspeaker or Ambisonics rendering */ - if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX ) - { - ivas_mono_downmix_render_passive( st_ivas, p_output, output_frame ); - } - else if ( st_ivas->renderer_type == RENDERER_NON_DIEGETIC_DOWNMIX ) - { - ivas_apply_non_diegetic_panning( p_output, st_ivas->hDecoderConfig->non_diegetic_pan_gain, output_frame ); - } - else if ( st_ivas->renderer_type == RENDERER_TD_PANNING || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) - { - /* Convert to CICPxx; used also for ISM->CICP19->binaural_room rendering */ - ivas_ism_render( st_ivas, p_output, output_frame ); - } - else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) - { - /* Convert to Ambisonics; used also for ISM->HOA3->binaural rendering */ - ivas_ism2sba( p_output, st_ivas->hIsmRendererData, st_ivas->hIsmMetaData, st_ivas->nchan_ism, output_frame, st_ivas->hIntSetup.ambisonics_order ); - } - - /* Binaural rendering */ - if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) - { - if ( ( error = ivas_td_binaural_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) - { - if ( ( error = ivas_rend_crendProcess( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, NULL, NULL, NULL, NULL, p_output, output_Fs, MAX_PARAM_SPATIAL_SUBFRAMES ) ) != IVAS_ERR_OK ) - { - return error; - } - - ivas_binaural_add_LFE( st_ivas, output_frame, p_output, p_output ); - } - } - } - else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) - { - set_s( nb_bits_metadata, 0, MAX_SCE ); - - /* read parameters from the bitstream */ - if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hQMetaData != NULL ) - { - st = ( st_ivas->nSCE > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; - - if ( ( error = ivas_masa_decode( st_ivas, st, &nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( st_ivas->ivas_format == SBA_FORMAT ) - { - if ( ( error = ivas_spar_dec( st_ivas, nb_bits_metadata ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - if ( st_ivas->nchan_transport == CPE_CHANNELS && st_ivas->nCPE >= 1 ) - { - st_ivas->hCPE[0]->element_brate = ivas_total_brate; - } - - /* core-decoding of transport channels */ - if ( st_ivas->nSCE == 1 ) - { - if ( ( error = ivas_sce_dec( st_ivas, 0, &p_output[0], output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( st_ivas->nCPE == 1 ) - { - if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( st_ivas->nCPE > 1 ) - { - if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - /* TCs remapping */ - nchan_remapped = st_ivas->nchan_transport; - if ( st_ivas->sba_dirac_stereo_flag ) - { - nchan_remapped = nchan_out; - - if ( st_ivas->ivas_format == SBA_FORMAT ) - { - ivas_agc_dec_process( st_ivas->hSpar->hAgcDec, p_output, p_output, st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, output_frame ); - - if ( st_ivas->hSpar->hPCA != NULL ) - { - ivas_pca_dec( st_ivas->hSpar->hPCA, output_frame, st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, ivas_total_brate, st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, p_output ); - } - - ivas_spar_dec_gen_umx_mat( st_ivas->hSpar->hMdDec, st_ivas->nchan_transport, IVAS_MAX_NUM_BANDS, st_ivas->bfi, ivas_get_spar_dec_md_num_subframes( st_ivas->sba_order, ivas_total_brate, st_ivas->last_active_ivas_total_brate ) ); - } - - ivas_sba_dirac_stereo_dec( st_ivas, p_output, output_frame, st_ivas->ivas_format == MC_FORMAT ); - } - else if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && ( ivas_total_brate > IVAS_SID_5k2 || ( ivas_total_brate <= IVAS_SID_5k2 && st_ivas->nCPE > 0 && st_ivas->hCPE[0]->nchan_out == 1 ) ) ) - { - nchan_remapped = 1; /* Only one channel transported */ - } - - /* HP filtering */ - for ( n = 0; n < nchan_remapped; n++ ) - { - hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); - } - if ( st_ivas->ivas_format == SBA_FORMAT ) - { - nchan_remapped = ivas_sba_remapTCs( p_output, st_ivas, output_frame ); - - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) - { - num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( st_ivas->sba_analysis_order, ivas_total_brate, st_ivas->last_active_ivas_total_brate ); - ivas_sba_mix_matrix_determiner( st_ivas->hSpar, p_output, st_ivas->bfi, nchan_remapped, output_frame, num_md_sub_frames ); - } - else if ( st_ivas->renderer_type != RENDERER_DISABLE ) - { - ivas_spar_dec_agc_pca( st_ivas, p_output, output_frame ); - } - } - - if ( st_ivas->ivas_format == MASA_FORMAT ) - { - ivas_masa_prerender( st_ivas, p_output, output_frame, nchan_remapped ); - } - else if ( st_ivas->ivas_format == SBA_FORMAT && ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) - { - /* loudness correction */ - ivas_dirac_dec_binaural_sba_gain( p_output, nchan_remapped, output_frame ); - } - - /* Loudspeakers, Ambisonics or Binaural rendering */ - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) - { - ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, p_output, nchan_remapped, MAX_PARAM_SPATIAL_SUBFRAMES ); - } - else if ( st_ivas->ivas_format == MASA_FORMAT ) - { - if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC ) - { - if ( ( error = ivas_sba_linear_renderer( p_output, output_frame, nchan_remapped, 0, output_config, st_ivas->hOutSetup ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( st_ivas->renderer_type == RENDERER_DIRAC ) - { - ivas_dirac_dec( st_ivas, p_output, nchan_remapped, MAX_PARAM_SPATIAL_SUBFRAMES ); - } - } - else if ( !st_ivas->sba_dirac_stereo_flag && nchan_out != 1 ) - { - if ( ( error = ivas_sba_upmixer_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) /* Note: ivas_sba_linear_renderer() or ivas_dirac_dec() are called internally */ - { - return error; - } - } - } - else if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) - { - int16_t nchan_ism, nchan_transport_ism; - int16_t dirac_bs_md_write_idx; - - set_s( nb_bits_metadata, 0, MAX_SCE + 1 ); - - /* Set the number of objects for the parametric rendering */ - dirac_bs_md_write_idx = 0; - if ( st_ivas->hSpatParamRendCom != NULL ) - { - st_ivas->hSpatParamRendCom->numIsmDirections = 0; - if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ ) - { - st_ivas->hSpatParamRendCom->numIsmDirections = st_ivas->nchan_ism; - } - - dirac_bs_md_write_idx = st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx; /* Store the write-index for this frame */ - } - - /* MASA metadata decoding */ - if ( ( error = ivas_masa_decode( st_ivas, st_ivas->hCPE[0]->hCoreCoder[0], &nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* Configuration of combined-format bit-budget distribution */ - ivas_set_surplus_brate_dec( st_ivas, &ism_total_brate ); - - st_ivas->hCPE[0]->hCoreCoder[0]->bit_stream = &( st_ivas->bit_stream[( ism_total_brate / FRAMES_PER_SEC )] ); - - /* set ISM parameters and decode ISM metadata in OMASA format */ - if ( ( error = ivas_omasa_ism_metadata_dec( st_ivas, ism_total_brate, &nchan_ism, &nchan_transport_ism, dirac_bs_md_write_idx, &nb_bits_metadata[1] ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* decode ISM channels */ - for ( n = 0; n < nchan_transport_ism; n++ ) - { - if ( ( error = ivas_sce_dec( st_ivas, n, &p_output[st_ivas->nchan_transport + n], output_frame, nb_bits_metadata[1] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - /* decode MASA channels */ - if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( st_ivas->hCPE[0]->nchan_out == 1 ) - { - mvr2r( p_output[0], p_output[1], output_frame ); /* Copy mono signal to stereo output channels */ - } - - /* HP filtering */ - for ( n = 0; n < getNumChanSynthesis( st_ivas ); n++ ) - { - hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); - } - - /* Rendering */ - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) - { - if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC && st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC ) - { - if ( ( error = ivas_omasa_dirac_td_binaural( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else - { - ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, p_output, st_ivas->nchan_transport, MAX_PARAM_SPATIAL_SUBFRAMES ); - } - } - else if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX ) - { - ivas_mono_downmix_render_passive( st_ivas, p_output, output_frame ); - } - else if ( st_ivas->renderer_type == RENDERER_DIRAC ) - { - ivas_omasa_dirac_rend( st_ivas, p_output, output_frame ); - } - - /* external output */ - if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) - { - /* sanity check in case of bitrate switching */ - if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified for combined MASA and ISM format" ); - } - - ivas_omasa_rearrange_channels( p_output, nchan_transport_ism, output_frame ); - } - } - else if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) - { - int16_t nchan_ism, sba_ch_idx; - - set_s( nb_bits_metadata, 0, MAX_SCE + 1 ); - nchan_ism = st_ivas->nchan_ism; - if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) - { - /* set ISM parameters and decode ISM metadata in OSBA format */ - if ( ( error = ivas_osba_ism_metadata_dec( st_ivas, ivas_total_brate, &nchan_ism, &nb_bits_metadata[1] ) ) != IVAS_ERR_OK ) - { - return error; - } - sba_ch_idx = st_ivas->nchan_ism; - } - else - { - nb_bits_metadata[1] += NO_BITS_MASA_ISM_NO_OBJ; - sba_ch_idx = 0; - } - - /* SBA metadata decoding */ - if ( ( error = ivas_spar_dec( st_ivas, nb_bits_metadata ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( st_ivas->nchan_transport == CPE_CHANNELS && st_ivas->nCPE >= 1 ) - { - st_ivas->hCPE[0]->element_brate = ivas_total_brate; - } - - /* core-decoding of transport channels */ - if ( st_ivas->nSCE == 1 ) - { - if ( ( error = ivas_sce_dec( st_ivas, 0, &p_output[0], output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( st_ivas->nCPE == 1 ) - { - if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( st_ivas->nCPE > 1 ) - { - if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - if ( st_ivas->sba_dirac_stereo_flag ) - { - ivas_agc_dec_process( st_ivas->hSpar->hAgcDec, &p_output[sba_ch_idx], &p_output[sba_ch_idx], st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, output_frame ); - - if ( st_ivas->hSpar->hPCA != NULL ) - { - ivas_pca_dec( st_ivas->hSpar->hPCA, output_frame, st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, ivas_total_brate, st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, &p_output[sba_ch_idx] ); - } - - ivas_spar_dec_gen_umx_mat( st_ivas->hSpar->hMdDec, st_ivas->nchan_transport, IVAS_MAX_NUM_BANDS, st_ivas->bfi, ivas_get_spar_dec_md_num_subframes( st_ivas->sba_order, ivas_total_brate, st_ivas->last_active_ivas_total_brate ) ); - - ivas_sba_dirac_stereo_dec( st_ivas, &p_output[sba_ch_idx], output_frame, 0 ); - } - - /* HP filtering */ - for ( n = 0; n < getNumChanSynthesis( st_ivas ); n++ ) - { - hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); - } - - nchan_remapped = ivas_sba_remapTCs( &p_output[sba_ch_idx], st_ivas, output_frame ); - - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) - { - num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( st_ivas->sba_analysis_order, ivas_total_brate, st_ivas->last_active_ivas_total_brate ); - ivas_sba_mix_matrix_determiner( st_ivas->hSpar, &p_output[sba_ch_idx], st_ivas->bfi, nchan_remapped, output_frame, num_md_sub_frames ); - } - else if ( st_ivas->renderer_type != RENDERER_DISABLE ) - { - ivas_spar_dec_agc_pca( st_ivas, &p_output[sba_ch_idx], output_frame ); - } - - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) - { - /* loudness correction */ - ivas_dirac_dec_binaural_sba_gain( &p_output[sba_ch_idx], nchan_remapped, output_frame ); - } - - /* Loudspeakers, Ambisonics or Binaural rendering */ - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || - st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || - st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) - { - ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, &p_output[sba_ch_idx], nchan_remapped, MAX_PARAM_SPATIAL_SUBFRAMES ); - } - else if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) - { - if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) - { - if ( ( error = ivas_osba_dirac_td_binaural( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else - { - ivas_sba_upmixer_renderer( st_ivas, &p_output[sba_ch_idx], output_frame ); - } - } - else if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC && ( st_ivas->renderer_type == RENDERER_OSBA_STEREO || st_ivas->renderer_type == RENDERER_MONO_DOWNMIX ) ) - { - if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX ) - { - ivas_mono_downmix_render_passive( st_ivas, p_output, output_frame ); - } - else /* stereo output */ - { - /* shift SBA channels to avoid overwrite by ISM upmix in 1 object case */ - if ( nchan_ism == 1 ) - { - mvr2r( p_output[2], p_output[3], output_frame ); - mvr2r( p_output[1], p_output[2], output_frame ); - } - - ivas_ism_render( st_ivas, p_output, output_frame ); - } - - for ( n = 0; n < nchan_out; n++ ) - { - v_add( p_output[n], p_output[n + max( nchan_out, nchan_ism )], p_output[n], output_frame ); - } - } - else if ( st_ivas->renderer_type == RENDERER_OSBA_AMBI || st_ivas->renderer_type == RENDERER_OSBA_LS ) - { - if ( ( error = ivas_osba_render( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( output_config != IVAS_AUDIO_CONFIG_EXTERNAL && !st_ivas->sba_dirac_stereo_flag && nchan_out != 1 ) - { - if ( ( error = ivas_sba_upmixer_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) /*EXT output = individual objects + HOA3*/ - { - if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) - { - for ( n = 0; n < nchan_ism; n++ ) - { - delay_signal( p_output[n], output_frame, st_ivas->hSbaIsmData->delayBuffer[n], st_ivas->hSbaIsmData->delayBuffer_size ); - } - } - - if ( ( error = ivas_sba_upmixer_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( st_ivas->ism_mode == ISM_MODE_NONE ) - { - for ( n = st_ivas->hIntSetup.nchan_out_woLFE - 1; n >= 0; n-- ) - { - mvr2r( p_output[n], p_output[n + nchan_ism], output_frame ); - } - - for ( n = 0; n < nchan_ism; n++ ) - { - set_zero( p_output[n], output_frame ); - } - } - } - } - else if ( st_ivas->ivas_format == MC_FORMAT ) - { - st = ( st_ivas->nSCE > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; - - if ( st_ivas->mc_mode == MC_MODE_MCT ) - { - /* LFE channel decoder */ - ivas_lfe_dec( st_ivas->hLFE, st, output_frame, st_ivas->bfi, p_output[LFE_CHANNEL] ); - - if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, 0 ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* HP filtering */ - for ( n = 0; n < st_ivas->nchan_transport; n++ ) - { - if ( n != LFE_CHANNEL ) - { - hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); - } - } - - if ( st_ivas->transport_config != st_ivas->intern_config && ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_FOA || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA2 || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA3 ) ) - { - ivas_mc2sba( st_ivas->hTransSetup, p_output, p_output, output_frame, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE ); - } - - /* Rendering */ - if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) - { - if ( ( error = ivas_rend_crendProcess( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, - st_ivas->hCombinedOrientationData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, p_output, output_Fs, MAX_PARAM_SPATIAL_SUBFRAMES ) ) != IVAS_ERR_OK ) - { - return error; - } - - ivas_binaural_add_LFE( st_ivas, output_frame, p_output, p_output ); - } - else if ( st_ivas->renderer_type == RENDERER_MC ) - { - ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, output_frame, p_output, p_output ); - } - else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) - { - ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, output_frame, st_ivas->hOutSetup.ambisonics_order, 0.f ); - } - else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) - { - if ( ( ivas_td_binaural_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - - ivas_binaural_add_LFE( st_ivas, output_frame, p_output, p_output ); - } - } - else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) - { - ivas_lfe_dec( st_ivas->hLFE, st, output_frame, st_ivas->bfi, p_output[LFE_CHANNEL] ); - - ivas_mc_paramupmix_dec_read_BS( st_ivas, st, st_ivas->hMCParamUpmix, &nb_bits_metadata[0] ); - - if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* HP filtering */ - for ( n = 0; n < st_ivas->nchan_transport; n++ ) - { - if ( n != LFE_CHANNEL ) - { - hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); - } - } - - ivas_mc_paramupmix_dec( st_ivas, p_output ); - - if ( st_ivas->transport_config != st_ivas->intern_config && ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_FOA || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA2 || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA3 ) ) - { - ivas_mc2sba( st_ivas->hTransSetup, p_output, p_output, output_frame, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE ); - } - - /* Rendering */ - if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) - { - { - ivas_binaural_add_LFE( st_ivas, output_frame, p_output, p_output ); - } - } - else if ( st_ivas->renderer_type == RENDERER_MC ) - { - if ( output_config == IVAS_AUDIO_CONFIG_MONO || output_config == IVAS_AUDIO_CONFIG_STEREO ) - { - ivas_ls_setup_conversion( st_ivas, audioCfg2channels( IVAS_AUDIO_CONFIG_5_1_2 ), output_frame, p_output, p_output ); - } - else - { - ivas_ls_setup_conversion( st_ivas, MC_PARAMUPMIX_MAX_INPUT_CHANS, output_frame, p_output, p_output ); - } - } - else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) - { - ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, output_frame, st_ivas->hOutSetup.ambisonics_order, 0.f ); - } - else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) - { - if ( ( error = ivas_td_binaural_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - - ivas_binaural_add_LFE( st_ivas, output_frame, p_output, p_output ); - } - } - else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) - { - /* read Parametric MC parameters from the bitstream */ - ivas_param_mc_dec_read_BS( ivas_total_brate, st, st_ivas->hParamMC, &nb_bits_metadata[0] ); - - if ( st_ivas->nCPE == 1 ) - { - if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( st_ivas->nCPE > 1 ) - { - if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - /* HP filtering */ - for ( n = 0; n < st_ivas->nchan_transport; n++ ) - { - hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); - } - - /* Rendering */ - if ( output_config == IVAS_AUDIO_CONFIG_MONO || output_config == IVAS_AUDIO_CONFIG_STEREO ) - { - ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, output_frame, p_output, p_output ); - } - else - { - ivas_param_mc_dec( st_ivas, p_output ); - } - } - else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) - { - if ( st_ivas->hOutSetup.separateChannelEnabled ) - { - st = st_ivas->hCPE[0]->hCoreCoder[0]; /* Metadata is always with CPE in the case of separated channel */ - } - - /* read McMASA parameters from the bitstream */ - if ( ( error = ivas_masa_decode( st_ivas, st, &nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( st_ivas->hOutSetup.separateChannelEnabled ) - { - /* Decode the transport audio signals */ - if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* Identify the index of the separated channel */ - n = st_ivas->hOutSetup.separateChannelIndex; - - /* Decode the separated channel to output[n] to be combined with the synthesized channels */ - if ( ( error = ivas_sce_dec( st_ivas, 0, &p_output[n], output_frame, 0 ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* Delay the separated channel to sync with CLDFB delay of the DirAC synthesis, and synthesize the LFE signal. */ - if ( output_config == IVAS_AUDIO_CONFIG_5_1 || output_config == IVAS_AUDIO_CONFIG_7_1 || - output_config == IVAS_AUDIO_CONFIG_5_1_4 || output_config == IVAS_AUDIO_CONFIG_7_1_4 || - output_config == IVAS_AUDIO_CONFIG_5_1_2 || ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe > 0 ) ) - { - ivas_lfe_synth_with_filters( st_ivas->hMasa->hMasaLfeSynth, p_output, output_frame, n, LFE_CHANNEL ); - } - else if ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe == 0 ) - { - /* Delay the separated channel to sync with the DirAC rendering */ - delay_signal( p_output[n], output_frame, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_size ); - } - } - else - { - if ( st_ivas->nSCE == 1 ) - { - if ( ( error = ivas_sce_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( st_ivas->nCPE == 1 ) - { - if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - } - - if ( st_ivas->sba_dirac_stereo_flag ) /* use the flag to trigger the DFT upmix */ - { - ivas_sba_dirac_stereo_dec( st_ivas, p_output, output_frame, 1 ); - } - - /* HP filtering */ - for ( n = 0; n < getNumChanSynthesis( st_ivas ); n++ ) - { - hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); - } - - /* Rendering */ - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) - { - ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, p_output, st_ivas->nchan_transport, MAX_PARAM_SPATIAL_SUBFRAMES ); - } - else if ( st_ivas->renderer_type == RENDERER_DIRAC || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) /* rendering to CICPxx and Ambisonics */ - { - ivas_dirac_dec( st_ivas, p_output, st_ivas->nchan_transport, MAX_PARAM_SPATIAL_SUBFRAMES ); - - if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) - { - ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, output_frame, st_ivas->hOutSetup.ambisonics_order, 0.f ); - } - else if ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_5_1 && ( output_config == IVAS_AUDIO_CONFIG_5_1_2 || output_config == IVAS_AUDIO_CONFIG_5_1_4 || output_config == IVAS_AUDIO_CONFIG_7_1 ) ) - { - for ( n = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; n < st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; n++ ) - { - set_zero( p_output[n], output_frame ); - } - } - } - else if ( st_ivas->renderer_type == RENDERER_MCMASA_MONO_STEREO ) - { - ivas_mono_stereo_downmix_mcmasa( st_ivas, p_output, output_frame ); - } - } - } - - - /*----------------------------------------------------------------* - * Write IVAS output channels - * - compensation for saturation - * - float to integer conversion - *----------------------------------------------------------------*/ - - { -#ifndef DISABLE_LIMITER - ivas_limiter_dec( st_ivas->hLimiter, p_output, nchan_out, output_frame, st_ivas->BER_detect ); -#endif - } - - ivas_syn_output( p_output, output_frame, nchan_out, data ); - - - /*----------------------------------------------------------------* - * Common updates - *----------------------------------------------------------------*/ - - if ( !st_ivas->bfi ) /* do not update if first frame(s) are lost or NO_DATA */ - { - st_ivas->hDecoderConfig->last_ivas_total_brate = ivas_total_brate; - st_ivas->last_active_ivas_total_brate = ( ivas_total_brate <= IVAS_SID_5k2 ) ? st_ivas->last_active_ivas_total_brate : ivas_total_brate; - } - - if ( st_ivas->ini_frame < MAX_FRAME_COUNTER && !( st_ivas->bfi && st_ivas->ini_frame == 0 ) ) /* keep "st_ivas->ini_frame = 0" until first good received frame */ - { - st_ivas->ini_frame++; - } - - if ( st_ivas->ini_active_frame < MAX_FRAME_COUNTER && !( st_ivas->bfi && st_ivas->ini_frame == 0 ) && ivas_total_brate > IVAS_SID_5k2 ) /* needed in MASA decoder in case the first active frame is BFI, and there were SID-frames decoded before */ - { - st_ivas->ini_active_frame++; - } - - st_ivas->last_ivas_format = st_ivas->ivas_format; - - /* in case first frame(s) was/were lost, deallocate output buffers */ - if ( st_ivas->bfi && st_ivas->ini_frame == 0 ) - { - for ( n = 0; n < nchan_out; n++ ) - { - free( st_ivas->p_output_f[n] ); - st_ivas->p_output_f[n] = NULL; - } - } - - - pop_wmops(); return IVAS_ERR_OK; } diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index e8c9c80d1..348a5ed5f 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -41,6 +41,7 @@ #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" +#include "ivas_rom_rend.h" #include "wmc_auto.h" @@ -834,7 +835,7 @@ ivas_error ivas_dirac_dec_config( { common_rend_config_flag = st_ivas->hSpatParamRendCom == NULL ? DIRAC_OPEN : flag_config_inp; if ( ( error = ivas_spat_hSpatParamRendCom_config( &st_ivas->hSpatParamRendCom, common_rend_config_flag, dec_param_estim_new, - st_ivas->ivas_format, st_ivas->mc_mode, output_Fs, hodirac_flag ) ) != IVAS_ERR_OK ) + st_ivas->ivas_format, st_ivas->mc_mode, output_Fs, hodirac_flag, 0 ) ) != IVAS_ERR_OK ) { return error; } @@ -900,36 +901,6 @@ ivas_error ivas_dirac_dec_config( } } - /* Allocate transport channel buffers for SBA format when in JBM */ - if ( dec_config_flag == DIRAC_OPEN ) - { - if ( - st_ivas->hDecoderConfig->Opt_5ms && - st_ivas->hTcBuffer == NULL ) - { - if ( st_ivas->ivas_format == SBA_FORMAT ) - { - int16_t nchan_to_allocate; - int16_t nchan_transport; - - nchan_transport = st_ivas->nchan_transport; - - nchan_to_allocate = nchan_transport; - if ( st_ivas->nchan_transport == 1 && ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) || ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) ) - { - nchan_to_allocate++; /* we need a channel for the CNG in this case*/ - } - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) - { - nchan_to_allocate = 2 * BINAURAL_CHANNELS; - } - if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_transport, nchan_to_allocate, nchan_to_allocate, st_ivas->hSpatParamRendCom->slot_size ) ) != IVAS_ERR_OK ) - { - return error; - } - } - } - } return error; } @@ -1205,6 +1176,12 @@ void ivas_qmetadata_to_dirac( hSpatParamRendCom->energy_ratio2[meta_write_index][b] = q_direction->band_data[band].energy_ratio[block]; hSpatParamRendCom->diffuseness_vector[meta_write_index][b] -= q_direction->band_data[band].energy_ratio[block]; + /* Sanitize diffuseness for rare cases where floating point inaccuracy could result in negative diffuseness. */ + if ( hSpatParamRendCom->diffuseness_vector[meta_write_index][b] < 0.0f ) + { + hSpatParamRendCom->diffuseness_vector[meta_write_index][b] = 0.0f; + } + if ( q_direction->coherence_band_data != NULL ) { hSpatParamRendCom->spreadCoherence2[meta_write_index][b] = q_direction->coherence_band_data[band].spread_coherence[block] / 255.0f; @@ -1523,81 +1500,6 @@ void ivas_dirac_dec_set_md_map( } -/*------------------------------------------------------------------------- - * ivas_dirac_dec() - * - * DirAC decoding process - *------------------------------------------------------------------------*/ - -void ivas_dirac_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int16_t num_subframes /* i : number of subframes to render */ -) -{ - int16_t subframe_idx; - float *output_f_local[MAX_OUTPUT_CHANNELS]; - float cng_td_buffer[L_FRAME16k]; - int16_t nchan_out, n, n_samples_sf; - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; - - hSpatParamRendCom = st_ivas->hSpatParamRendCom; - nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; - - n_samples_sf = JBM_CLDFB_SLOTS_IN_SUBFRAME * hSpatParamRendCom->slot_size; - - for ( n = 0; n < nchan_out; n++ ) - { - output_f_local[n] = output_f[n]; - } - - for ( n = 0; n < nchan_transport; n++ ) - { - st_ivas->hTcBuffer->tc[n] = output_f[n]; - } - - if ( st_ivas->nchan_transport == 1 && st_ivas->hSCE[0]->hCoreCoder[0] != NULL && st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->ivas_format != SBA_FORMAT ) - { - Decoder_State *st = st_ivas->hSCE[0]->hCoreCoder[0]; - st_ivas->hTcBuffer->tc[nchan_transport] = &cng_td_buffer[0]; - generate_masking_noise_lb_dirac( st->hFdCngDec->hFdCngCom, st_ivas->hTcBuffer->tc[1], DEFAULT_JBM_CLDFB_TIMESLOTS, st->cna_dirac_flag && st->flag_cna ); - } - - ivas_dirac_dec_set_md_map( st_ivas, DEFAULT_JBM_CLDFB_TIMESLOTS ); - - for ( subframe_idx = 0; subframe_idx < num_subframes; subframe_idx++ ) - { - ivas_dirac_dec_render_sf( st_ivas, output_f_local, nchan_transport, NULL, NULL ); - for ( n = 0; n < nchan_out; n++ ) - { - output_f_local[n] += n_samples_sf; - } - } - - if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) - { - hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % hSpatParamRendCom->dirac_md_buffer_length; - } - else - { - hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % hSpatParamRendCom->dirac_md_buffer_length; - } - - for ( n = 0; n < nchan_transport; n++ ) - { - st_ivas->hTcBuffer->tc[n] = NULL; - } - - if ( st_ivas->nchan_transport == 1 && st_ivas->hSCE[0]->hCoreCoder[0] != NULL && st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->ivas_format != SBA_FORMAT ) - { - st_ivas->hTcBuffer->tc[nchan_transport] = NULL; - } - - return; -} - - /*------------------------------------------------------------------------- * ivas_dirac_dec_render() * @@ -1617,13 +1519,15 @@ void ivas_dirac_dec_render( uint16_t slot_size, n_samples_sf, ch, nchan_intern; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; float *output_f_local[MAX_OUTPUT_CHANNELS]; + float output_f_local_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k]; // VE2SB: TBV hSpatParamRendCom = st_ivas->hSpatParamRendCom; nchan_intern = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; for ( ch = 0; ch < nchan_intern; ch++ ) { - output_f_local[ch] = output_f[ch]; + output_f_local[ch] = output_f_local_buff[ch]; + set_zero( output_f_local_buff[ch], nSamplesAsked ); } slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); @@ -1647,6 +1551,17 @@ void ivas_dirac_dec_render( { output_f_local[ch] += n_samples_sf; } + + /* update combined orientation access index */ + ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); + } + + for ( ch = 0; ch < nchan_intern; ch++ ) + { + if ( !( ( st_ivas->hDirACRend->hOutSetup.separateChannelEnabled ) && ( st_ivas->hDirACRend->hOutSetup.separateChannelIndex == ch || st_ivas->hDirACRend->hOutSetup.separateChannelIndex + 1 == ch ) ) ) + { + mvr2r( output_f_local_buff[ch], output_f[ch], *nSamplesRendered ); + } } if ( hSpatParamRendCom->slots_rendered == hSpatParamRendCom->num_slots ) @@ -1668,9 +1583,9 @@ void ivas_dirac_dec_render( /*------------------------------------------------------------------------- - * ivas_dirac_dec() + * ivas_dirac_dec_render_sf() * - * DirAC decoding process + * DirAC decoding renderer process *------------------------------------------------------------------------*/ void ivas_dirac_dec_render_sf( @@ -1722,7 +1637,7 @@ void ivas_dirac_dec_render_sf( DirAC_mem = hDirACRend->stack_mem; reference_power = DirAC_mem.reference_power; - reference_power_smooth = DirAC_mem.reference_power + hSpatParamRendCom->num_freq_bands; + reference_power_smooth = ( DirAC_mem.reference_power == NULL ) ? NULL : DirAC_mem.reference_power + hSpatParamRendCom->num_freq_bands; onset_filter = DirAC_mem.onset_filter; onset_filter_subframe = ( DirAC_mem.onset_filter == NULL ) ? NULL : DirAC_mem.onset_filter + hSpatParamRendCom->num_freq_bands; @@ -1772,9 +1687,9 @@ void ivas_dirac_dec_render_sf( set_zero( onset_filter_subframe, hSpatParamRendCom->num_freq_bands ); } - if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] ) + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] ) { - p_Rmat = &st_ivas->hCombinedOrientationData->Rmat[subframe_idx][0][0]; + p_Rmat = &st_ivas->hCombinedOrientationData->Rmat[st_ivas->hCombinedOrientationData->subframe_idx][0][0]; if ( st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 ) { num_freq_bands = hDirAC->band_grouping[hDirAC->hConfig->enc_param_start_band]; @@ -1838,12 +1753,12 @@ void ivas_dirac_dec_render_sf( } } - if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order == 1 ) + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order == 1 ) { ivas_dirac_dec_compute_directional_responses( hSpatParamRendCom, hDirACRend, st_ivas->hVBAPdata, - st_ivas->hMasa, + st_ivas->hMasa == NULL ? NULL : st_ivas->hMasa->data.band_mapping, st_ivas->hMasaIsmData, azimuth, elevation, @@ -1858,7 +1773,7 @@ void ivas_dirac_dec_render_sf( ivas_dirac_dec_compute_directional_responses( hSpatParamRendCom, hDirACRend, st_ivas->hVBAPdata, - st_ivas->hMasa, + st_ivas->hMasa == NULL ? NULL : st_ivas->hMasa->data.band_mapping, st_ivas->hMasaIsmData, azimuth, elevation, @@ -1965,7 +1880,7 @@ void ivas_dirac_dec_render_sf( if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { - if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 ) + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 ) { protoSignalComputation_shd( Cldfb_RealBuffer, Cldfb_ImagBuffer, hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f, @@ -2150,7 +2065,7 @@ void ivas_dirac_dec_render_sf( } /*Compute PSDs*/ - if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order > 0 ) + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order > 0 ) { ivas_dirac_dec_output_synthesis_process_slot( reference_power, p_onset_filter, @@ -2330,8 +2245,11 @@ void ivas_dirac_dec_render_sf( /* Perform binaural rendering */ - ivas_binRenderer( st_ivas->hBinRenderer, st_ivas->hCombinedOrientationData, subframe_idx, hSpatParamRendCom->subframe_nbslots[subframe_idx], Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); + ivas_binRenderer( st_ivas->hBinRenderer, + st_ivas->hCombinedOrientationData, + hSpatParamRendCom->subframe_nbslots[subframe_idx], + Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); /* Inverse CLDFB*/ for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 86643b646..d23a36417 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -131,9 +131,6 @@ ivas_error ivas_dec_setup( st_ivas->sba_order = st_ivas->bit_stream[num_bits_read + 1]; st_ivas->sba_order += 2 * st_ivas->bit_stream[num_bits_read]; - /* set Ambisonic (SBA) order used for analysis and coding */ - st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( ivas_total_brate, st_ivas->sba_order ); - num_bits_read += SBA_ORDER_BITS; if ( st_ivas->ini_frame > 0 && ivas_total_brate != st_ivas->last_active_ivas_total_brate && ivas_total_brate > IVAS_SID_5k2 ) { @@ -144,6 +141,9 @@ ivas_error ivas_dec_setup( } else { + /* set Ambisonic (SBA) order used for analysis and coding */ + st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( ivas_total_brate, st_ivas->sba_order ); + ivas_sba_config( ivas_total_brate, st_ivas->sba_analysis_order, -1, &( st_ivas->nchan_transport ), st_ivas->sba_planar, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init ); } } @@ -372,8 +372,10 @@ ivas_error ivas_dec_setup( } } - if ( st_ivas->ini_frame == 0 && st_ivas->ivas_format == ISM_FORMAT ) + if ( st_ivas->ivas_format == ISM_FORMAT ) { + ISM_MODE last_ism_mode = st_ivas->ism_mode; + /* read the number of objects */ st_ivas->nchan_transport = 1; nchan_ism = 1; @@ -385,6 +387,11 @@ ivas_error ivas_dec_setup( } k--; + if ( st_ivas->ini_frame > 0 && nchan_ism != st_ivas->nchan_ism ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "wrong number of objects signalled!" ); + } + st_ivas->nchan_ism = nchan_ism; /* read ism_mode */ @@ -396,7 +403,12 @@ ivas_error ivas_dec_setup( st_ivas->ism_mode = (ISM_MODE) ( idx + 1 ); } - if ( ( error = ivas_ism_dec_config( st_ivas, st_ivas->ism_mode, nSamplesRendered, data ) ) != IVAS_ERR_OK ) + if ( st_ivas->ini_frame == 0 ) + { + last_ism_mode = st_ivas->ism_mode; + } + + if ( ( error = ivas_ism_dec_config( st_ivas, last_ism_mode, nSamplesRendered, data ) ) != IVAS_ERR_OK ) { return error; } @@ -626,13 +638,6 @@ int16_t getNumChanSynthesis( if ( st_ivas->sba_dirac_stereo_flag ) { n = CPE_CHANNELS; -#if 0 - /* TODO wkr: this is actually a correct bugfix for OSBA, it is disabled for now to pass the pipelines in the OSBA JBM branch */ - if ( st_ivas->ivas_format == SBA_ISM_FORMAT && st_ivas->ism_mode == ISM_SBA_MODE_DISC ) - { - n += st_ivas->nchan_ism; - } -#endif } else if ( ( st_ivas->hMCT != NULL || st_ivas->ivas_format == SBA_FORMAT ) && st_ivas->ivas_format != SBA_ISM_FORMAT ) { @@ -744,7 +749,7 @@ ivas_error ivas_init_decoder_front( if ( st_ivas->hDecoderConfig->Opt_ExternalOrientation ) { - if ( ( error = ivas_external_orientation_open( &( st_ivas->hExtOrientationData ), ( st_ivas->hDecoderConfig->Opt_5ms ) ? 1 : MAX_PARAM_SPATIAL_SUBFRAMES ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_external_orientation_open( &( st_ivas->hExtOrientationData ), st_ivas->hDecoderConfig->render_framesize ) ) != IVAS_ERR_OK ) { return error; } @@ -756,7 +761,7 @@ ivas_error ivas_init_decoder_front( if ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) { - if ( ( error = ivas_combined_orientation_open( &( st_ivas->hCombinedOrientationData ), ( st_ivas->hDecoderConfig->Opt_5ms ) ? 1 : MAX_PARAM_SPATIAL_SUBFRAMES ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_combined_orientation_open( &( st_ivas->hCombinedOrientationData ), st_ivas->hDecoderConfig->output_Fs, st_ivas->hDecoderConfig->render_framesize ) ) != IVAS_ERR_OK ) { return error; } @@ -1026,7 +1031,14 @@ ivas_error ivas_init_decoder( if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { - st_ivas->hSCE[1]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed3 = st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed2; + st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed2 = st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed3; + } + else if ( st_ivas->ism_mode == ISM_MODE_DISC ) + { + for ( sce_id = 0; sce_id < st_ivas->nSCE; ++sce_id ) + { + st_ivas->hSCE[sce_id]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed2 = 2 + sce_id; + } } } else if ( st_ivas->ivas_format == SBA_FORMAT ) @@ -1049,7 +1061,10 @@ ivas_error ivas_init_decoder( } } - if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) + , + st_ivas->ivas_format + ) ) != IVAS_ERR_OK ) { return error; } @@ -1202,7 +1217,10 @@ ivas_error ivas_init_decoder( } } - if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) + , + st_ivas->ivas_format + ) ) != IVAS_ERR_OK ) { return error; } @@ -1661,8 +1679,6 @@ ivas_error ivas_init_decoder( } } - if ( st_ivas->hDecoderConfig->Opt_5ms ) - { granularity = NS2SA( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); @@ -1670,7 +1686,6 @@ ivas_error ivas_init_decoder( { return error; } - } } else if ( st_ivas->renderer_type == RENDERER_MC ) { @@ -1704,8 +1719,6 @@ ivas_error ivas_init_decoder( st_ivas->binaural_latency_ns = st_ivas->hCrendWrapper->binaural_latency_ns; - if ( st_ivas->hDecoderConfig->Opt_5ms ) - { if ( ( st_ivas->ivas_format == MC_FORMAT ) && ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) ) { granularity = NS2SA( output_Fs, CLDFB_SLOT_NS ); @@ -1728,7 +1741,6 @@ ivas_error ivas_init_decoder( return error; } } - } } if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) @@ -1868,7 +1880,8 @@ ivas_error ivas_init_decoder( * Allocate and initialize JBM struct + buffer *-----------------------------------------------------------------*/ - if ( st_ivas->hDecoderConfig->Opt_5ms && st_ivas->hTcBuffer == NULL ) + if ( st_ivas->hTcBuffer == NULL ) + { /* no module has yet open the TC buffer, open a default one */ n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); @@ -1903,8 +1916,6 @@ ivas_error ivas_init_decoder( * Allocate floating-point output audio buffers *-----------------------------------------------------------------*/ - if ( !st_ivas->hDecoderConfig->Opt_5ms ) - { for ( n = 0; n < ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); n++ ) { /* note: these are intra-frame heap memories */ @@ -1913,17 +1924,13 @@ ivas_error ivas_init_decoder( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for floating-point output audio buffer!\n" ) ); } } - } - else - { - n = 0; - } for ( ; n < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; n++ ) { st_ivas->p_output_f[n] = NULL; } + return error; } diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index 4decf5fc5..d784324e9 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -59,11 +59,7 @@ static ivas_error ivas_ism_bitrate_switching_dec( int16_t tc_nchan_tc_new; int16_t tc_nchan_allocate_new; int16_t tc_granularity_new; -#ifdef NONBE_FIX_839_MC_RS_CHANNEL_ALLOC int16_t nchan_out_buff, nchan_out_buff_old; -#else - int16_t ch, nchan_out_buff, nchan_out_buff_old; -#endif AUDIO_CONFIG intern_config_old; IVAS_OUTPUT_SETUP hIntSetupOld; RENDERER_TYPE renderer_type_old; @@ -72,16 +68,12 @@ static ivas_error ivas_ism_bitrate_switching_dec( nCPE_old = st_ivas->nCPE; nSCE_old = st_ivas->nSCE; - /* we have to temporarily set the ism mode back to the old one, otherwise this can give wrong results*/ + /* temporarily set the ism mode back to the old one, otherwise this can give wrong results*/ ism_mode = st_ivas->ism_mode; st_ivas->ism_mode = last_ism_mode; ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old ); st_ivas->ism_mode = ism_mode; -#ifdef NONBE_FIX_839_MC_RS_CHANNEL_ALLOC nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); -#else - nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); -#endif if ( ( error = ivas_ism_config( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->nchan_ism, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 0 ) ) != IVAS_ERR_OK ) { @@ -128,7 +120,6 @@ static ivas_error ivas_ism_bitrate_switching_dec( ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->hDecoderConfig->output_config ); } - if ( st_ivas->hDecoderConfig->Opt_5ms ) { /* transfer subframe info from DirAC or ParamMC to central tc buffer */ if ( last_ism_mode == ISM_MODE_PARAM && st_ivas->hSpatParamRendCom != NULL && ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE ) ) @@ -296,45 +287,18 @@ static ivas_error ivas_ism_bitrate_switching_dec( * floating-point output audio buffers *-----------------------------------------------------------------*/ - if ( !st_ivas->hDecoderConfig->Opt_5ms ) { -#ifdef NONBE_FIX_839_MC_RS_CHANNEL_ALLOC nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) { return error; } -#else - nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); - - if ( nchan_out_buff > nchan_out_buff_old ) - { - for ( ch = nchan_out_buff_old; ch < nchan_out_buff; ch++ ) - { - /* note: these are intra-frame heap memories */ - if ( ( st_ivas->p_output_f[ch] = (float *) malloc( ( 48000 / FRAMES_PER_SEC ) * sizeof( float ) ) ) == NULL ) /* note: 32000 == max internal sampling rate */ - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for floating-point output audio buffer!\n" ) ); - } - } - } - else - { - for ( ch = nchan_out_buff; ch < nchan_out_buff_old; ch++ ) - { - free( st_ivas->p_output_f[ch] ); - st_ivas->p_output_f[ch] = NULL; - } - } -#endif } /*-----------------------------------------------------------------* * JBM TC buffers *-----------------------------------------------------------------*/ - - if ( st_ivas->hDecoderConfig->Opt_5ms ) { int16_t tc_nchan_full_new; DECODER_TC_BUFFER_HANDLE hTcBuffer; diff --git a/lib_dec/ivas_ism_dtx_dec.c b/lib_dec/ivas_ism_dtx_dec.c index 1ff155e93..998dc97ee 100644 --- a/lib_dec/ivas_ism_dtx_dec.c +++ b/lib_dec/ivas_ism_dtx_dec.c @@ -44,17 +44,15 @@ * ISM DTX Metadata decoding routine *-------------------------------------------------------------------*/ -ivas_error ivas_ism_dtx_dec( +void ivas_ism_dtx_dec( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ int16_t *nb_bits_metadata /* o : number of metadata bits */ ) { - int16_t ch, pos, nchan_ism, nchan_ism_prev; + int16_t ch, nchan_ism, nchan_ism_prev; int32_t ivas_total_brate; int16_t md_diff_flag[MAX_NUM_OBJECTS]; - int16_t idx, flag_noisy_speech, sce_id_dtx; - ISM_MODE last_ism_mode, ism_mode_bstr; - ivas_error error; + int16_t flag_noisy_speech, sce_id_dtx; Decoder_State *st; ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; @@ -64,39 +62,10 @@ ivas_error ivas_ism_dtx_dec( if ( !st_ivas->bfi && ivas_total_brate == IVAS_SID_5k2 ) { - /* read number of objects */ - nchan_ism = 1; - pos = (int16_t) ( ( ivas_total_brate / FRAMES_PER_SEC ) - 1 - SID_FORMAT_NBITS ); + /* 'nchan_ism' was read in ivas_dec_setup() */ + nchan_ism = st_ivas->nchan_ism; - while ( get_indice( st_ivas->hSCE[0]->hCoreCoder[0], pos, 1 ) == 1 && nchan_ism < MAX_NUM_OBJECTS ) - { - ( nchan_ism )++; - pos--; - } - st_ivas->nchan_ism = nchan_ism; - pos--; - - if ( nchan_ism != nchan_ism_prev ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "wrong number of objects signalled!" ); - } - - last_ism_mode = st_ivas->ism_mode; - - /* read ism_mode */ - if ( nchan_ism > 2 ) - { - pos -= nchan_ism; /* SID metadata flags */ - - idx = get_indice( st_ivas->hSCE[0]->hCoreCoder[0], pos, 1 ); - ism_mode_bstr = (ISM_MODE) ( idx + 1 ); - st_ivas->ism_mode = ism_mode_bstr; - } - - if ( ( error = ivas_ism_dec_config( st_ivas, last_ism_mode, NULL, NULL ) ) != IVAS_ERR_OK ) - { - return error; - } + /* ism_mode was read in ivas_dec_setup() as well as reconfiguration ivas_ism_dec_config() */ } else { @@ -128,6 +97,15 @@ ivas_error ivas_ism_dtx_dec( } } + /* synch common seed between SCEs */ + if ( st_ivas->ism_mode == ISM_MODE_DISC ) + { + for ( ch = 0; ch < nchan_ism; ++ch ) + { + st_ivas->hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed = st_ivas->hSCE[st_ivas->hISMDTX.sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed; + } + } + update_last_metadata( nchan_ism, st_ivas->hIsmMetaData, md_diff_flag ); st_ivas->hISMDTX.ism_dtx_hangover_cnt = 0; @@ -152,7 +130,7 @@ ivas_error ivas_ism_dtx_dec( } } - return IVAS_ERR_OK; + return; } diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index e875ef816..9f48c82e1 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -574,12 +574,12 @@ ivas_error ivas_param_ism_dec_open( st_ivas->hParamIsmDec = hParamIsmDec; st_ivas->hSpatParamRendCom = hSpatParamRendCom; - if ( st_ivas->hDecoderConfig->Opt_5ms ) - { + if ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE ) { int16_t nchan_transport = st_ivas->nchan_transport; int16_t nchan_full = 0; + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) { nchan_full = nchan_transport; @@ -632,12 +632,6 @@ ivas_error ivas_param_ism_dec_open( } } } - } - else - { - hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc = NULL; - hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc = NULL; - } pop_wmops(); return error; @@ -1189,7 +1183,7 @@ void ivas_param_ism_dec_digest_tc( } } - if ( st_ivas->hDecoderConfig->Opt_tsm || !st_ivas->hDecoderConfig->Opt_5ms ) + if ( st_ivas->hDecoderConfig->Opt_tsm ) { /*TODO : FhG to check*/ ivas_ism_param_dec_tc_gain_ajust( st_ivas, output_frame, fade_len, transport_channels_f ); @@ -1200,7 +1194,7 @@ void ivas_param_ism_dec_digest_tc( /* CLDFB Analysis */ for ( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) { - if ( st_ivas->hDecoderConfig->Opt_tsm || !st_ivas->hDecoderConfig->Opt_5ms ) + if ( st_ivas->hDecoderConfig->Opt_tsm ) { float RealBuffer[CLDFB_NO_CHANNELS_MAX]; diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c index ee99ce067..767144ddb 100644 --- a/lib_dec/ivas_ism_renderer.c +++ b/lib_dec/ivas_ism_renderer.c @@ -63,11 +63,7 @@ ivas_error ivas_ism_renderer_open( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM renderer\n" ) ); } -#ifdef BE_FIX_832_ASAN_ERROR_EFAP_OSBA if ( st_ivas->hIntSetup.is_loudspeaker_setup && st_ivas->hIntSetup.ls_azimuth != NULL && st_ivas->hIntSetup.ls_elevation != NULL && st_ivas->hEFAPdata == NULL ) -#else - if ( st_ivas->hIntSetup.is_loudspeaker_setup && st_ivas->hIntSetup.ls_azimuth != NULL && st_ivas->hIntSetup.ls_elevation != NULL ) -#endif { if ( ( error = efap_init_data( &( st_ivas->hEFAPdata ), st_ivas->hIntSetup.ls_azimuth, st_ivas->hIntSetup.ls_elevation, st_ivas->hIntSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) { @@ -134,108 +130,6 @@ void ivas_ism_renderer_close( } -/*-------------------------------------------------------------------------* - * ivas_ism_render() - * - * Object rendering process. - *-------------------------------------------------------------------------*/ - -void ivas_ism_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output_f[], /* i/o: core-coder transport channels/object output */ - const int16_t output_frame /* i : output frame length per channel */ -) -{ - int16_t i, j, k, j2; - float input_f[MAX_NUM_OBJECTS][L_FRAME48k]; - float tmp_output_f[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - float gains[MAX_NUM_OBJECTS][MAX_OUTPUT_CHANNELS]; - float g1, g2; - int16_t nchan_ism, nchan_out_woLFE, lfe_index; - int16_t azimuth, elevation; - - nchan_ism = st_ivas->nchan_ism; - nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; - - lfe_index = 0; - - for ( j = 0; j < nchan_out_woLFE; j++ ) - { - set_f( tmp_output_f[j], 0.0f, output_frame ); - } - - for ( i = 0; i < nchan_ism; i++ ) - { - mvr2r( output_f[i], input_f[i], output_frame ); - } - - for ( i = 0; i < nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; i++ ) - { - set_f( output_f[i], 0.0f, output_frame ); - } - - for ( i = 0; i < nchan_ism; i++ ) - { - if ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_STEREO ) - { - ivas_ism_get_stereo_gains( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &gains[i][0], &gains[i][1] ); - } - else - { - /* Combined rotation: rotate the object positions depending the head and external orientations */ - if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) - { - rotateAziEle( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat[0], st_ivas->hIntSetup.is_planar_setup ); - } - else - { - // TODO tmu review when #215 is resolved - azimuth = (int16_t) floorf( st_ivas->hIsmMetaData[i]->azimuth + 0.5f ); - elevation = (int16_t) floorf( st_ivas->hIsmMetaData[i]->elevation + 0.5f ); - - if ( st_ivas->hIntSetup.is_planar_setup ) - { - /* If no elevation support in output format, then rendering should be done with zero elevation */ - elevation = 0; - } - } - - if ( st_ivas->hEFAPdata != NULL ) - { - efap_determine_gains( st_ivas->hEFAPdata, gains[i], azimuth, elevation, EFAP_MODE_EFAP ); - } - } - - for ( j = 0; j < nchan_out_woLFE; j++ ) - { - if ( fabsf( gains[i][j] ) > 0.0f || fabsf( st_ivas->hIsmRendererData->prev_gains[i][j] ) > 0.0f ) - { - for ( k = 0; k < output_frame; k++ ) - { - g1 = st_ivas->hIsmRendererData->interpolator[k]; - g2 = 1.0f - g1; - tmp_output_f[j][k] += ( g1 * gains[i][j] + g2 * st_ivas->hIsmRendererData->prev_gains[i][j] ) * input_f[i][k]; - } - } - - st_ivas->hIsmRendererData->prev_gains[i][j] = gains[i][j]; - } - } - - /* Move to output skipping LFE */ - for ( j = 0, j2 = 0; j < nchan_out_woLFE; j++, j2++ ) - { - if ( ( st_ivas->hIntSetup.num_lfe > 0 ) && ( st_ivas->hIntSetup.index_lfe[lfe_index] == j ) ) - { - ( lfe_index < ( st_ivas->hIntSetup.num_lfe - 1 ) ) ? ( lfe_index++, j2++ ) : j2++; - } - mvr2r( tmp_output_f[j], output_f[j2], output_frame ); - } - - return; -} - - /*-------------------------------------------------------------------------* * ivas_ism_render_sf() * @@ -255,6 +149,8 @@ void ivas_ism_render_sf( int16_t tc_offset; int16_t interp_offset; float gain, prev_gain; + float tc_local[MAX_NUM_OBJECTS][L_FRAME48k]; + float *p_tc[MAX_NUM_OBJECTS]; num_objects = st_ivas->nchan_transport; if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) @@ -267,12 +163,28 @@ void ivas_ism_render_sf( tc_offset = st_ivas->hTcBuffer->n_samples_rendered; interp_offset = st_ivas->hTcBuffer->n_samples_rendered; + if ( st_ivas->hDecoderConfig->Opt_tsm ) + { + for ( i = 0; i < num_objects; i++ ) + { + p_tc[i] = &st_ivas->hTcBuffer->tc[i][tc_offset]; + } + } + else + { + for ( i = 0; i < num_objects; i++ ) + { + mvr2r( &output_f[i][tc_offset], tc_local[i], n_samples_to_render ); + p_tc[i] = tc_local[i]; + } + } + for ( i = 0; i < nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; i++ ) { set_f( output_f[i], 0.0f, n_samples_to_render ); } - if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] ) + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) { ivas_jbm_dec_get_adapted_linear_interpolator( n_samples_to_render, n_samples_to_render, st_ivas->hIsmRendererData->interpolator ); interp_offset = 0; @@ -281,9 +193,10 @@ void ivas_ism_render_sf( for ( i = 0; i < num_objects; i++ ) { /* Combined rotation: rotate the object positions depending the head and external orientations */ - if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) + if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) { rotateAziEle( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat[0], st_ivas->hIntSetup.is_planar_setup ); + if ( st_ivas->hEFAPdata != NULL ) { efap_determine_gains( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains[i], azimuth, elevation, EFAP_MODE_EFAP ); @@ -303,7 +216,7 @@ void ivas_ism_render_sf( if ( fabsf( gain ) > 0.0f || fabsf( prev_gain ) > 0.0f ) { g1 = &st_ivas->hIsmRendererData->interpolator[interp_offset]; - tc = &st_ivas->hTcBuffer->tc[i][tc_offset]; + tc = p_tc[i]; for ( k = 0; k < n_samples_to_render; k++ ) { g2 = 1.0f - *g1; @@ -312,13 +225,16 @@ void ivas_ism_render_sf( } /* update here only in case of head rotation */ - if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) + if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) { st_ivas->hIsmRendererData->prev_gains[i][j] = gain; } } } + /* update combined orientation access index */ + ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_to_render ); + return; } @@ -470,118 +386,6 @@ void ivas_omasa_separate_object_renderer_close( } -/*-------------------------------------------------------------------------* - * ivas_omasa_separate_object_render() - * - * Rendering separated objects and mixing them to the parametrically rendered signals - *-------------------------------------------------------------------------*/ - -void ivas_omasa_separate_object_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float input_f[][L_FRAME48k], /* i : separated object signal */ - float *output_f[], /* i/o: output signals */ - const int16_t output_frame /* i : output frame length per channel */ -) -{ - VBAP_HANDLE hVBAPdata; - int16_t nchan_out_woLFE; - ISM_RENDERER_HANDLE hRendererData; - int16_t j, k, j2; - int16_t obj; - float gains[MAX_OUTPUT_CHANNELS]; - float g1, g2; - int16_t lfe_index; - int16_t azimuth, elevation; - int16_t num_objects; - uint8_t single_separated; - int16_t block; - int16_t subframe_len; - int16_t idx_offset; - int16_t dirac_read_idx; - - hVBAPdata = st_ivas->hVBAPdata; - nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; - hRendererData = st_ivas->hIsmRendererData; - lfe_index = st_ivas->hDirACRend->hOutSetup.index_lfe[0]; - subframe_len = output_frame / MAX_PARAM_SPATIAL_SUBFRAMES; - - if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) - { - single_separated = 1; - num_objects = 1; - } - else - { - single_separated = 0; - num_objects = st_ivas->nchan_ism; - } - - for ( obj = 0; obj < num_objects; obj++ ) - { - delay_signal( input_f[obj], output_frame, st_ivas->hMasaIsmData->delayBuffer[obj], st_ivas->hMasaIsmData->delayBuffer_size ); /* Delay the signal to match CLDFB delay */ - - for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) - { - idx_offset = block * subframe_len; - dirac_read_idx = ( st_ivas->hSpatParamRendCom->dirac_read_idx + block ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length; - - if ( single_separated ) - { - azimuth = st_ivas->hMasaIsmData->azimuth_separated_ism[dirac_read_idx]; - elevation = st_ivas->hMasaIsmData->elevation_separated_ism[dirac_read_idx]; - } - else - { - azimuth = st_ivas->hMasaIsmData->azimuth_ism[obj][dirac_read_idx]; - elevation = st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx]; - } - - if ( st_ivas->hOutSetup.is_planar_setup ) - { - /* If no elevation support in output format, then rendering should be done with zero elevation */ - elevation = 0; - } - - if ( hVBAPdata != NULL ) - { - vbap_determine_gains( hVBAPdata, gains, azimuth, elevation, 1 ); - } - else - { - ivas_dirac_dec_get_response( azimuth, elevation, gains, st_ivas->hDirACRend->hOutSetup.ambisonics_order ); - } - - for ( j = 0; j < nchan_out_woLFE; j++ ) - { - if ( st_ivas->hDirACRend->hOutSetup.num_lfe > 0 ) - { - j2 = j + ( j >= lfe_index ); - } - else - { - j2 = j; - } - - if ( fabsf( gains[j] ) > 0.0f || fabsf( hRendererData->prev_gains[obj][j] ) > 0.0f ) - { - for ( k = 0; k < subframe_len; k++ ) - { - g1 = hRendererData->interpolator[k]; - g2 = 1.0f - g1; - output_f[j2][k + idx_offset] += ( g1 * gains[j] + g2 * hRendererData->prev_gains[obj][j] ) * input_f[obj][k + idx_offset]; - } - } - hRendererData->prev_gains[obj][j] = gains[j]; - } - } - } - - st_ivas->hSpatParamRendCom->dirac_read_idx = ( st_ivas->hSpatParamRendCom->dirac_read_idx + MAX_PARAM_SPATIAL_SUBFRAMES ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length; - - return; -} - - /*-------------------------------------------------------------------------* * ivas_omasa_separate_object_render_jbm() * @@ -589,8 +393,9 @@ void ivas_omasa_separate_object_render( *-------------------------------------------------------------------------*/ void ivas_omasa_separate_object_render_jbm( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const uint16_t nSamplesRendered, /* i : number of samples rendered */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const uint16_t nSamplesRendered, /* i : number of samples rendered */ + float input_f_in[][L_FRAME48k], /* i : separated object signal */ float *output_f[], /* o : rendered time signal */ const int16_t subframes_rendered, /* i : number of subframes rendered */ const int16_t slots_rendered /* i : number of CLDFB slots rendered */ @@ -641,9 +446,19 @@ void ivas_omasa_separate_object_render_jbm( output_f_local[j] = output_f[j]; } - for ( obj = 0; obj < num_objects; obj++ ) + if ( st_ivas->hDecoderConfig->Opt_tsm ) + { + for ( obj = 0; obj < num_objects; obj++ ) + { + input_f[obj] = &st_ivas->hTcBuffer->tc[obj + 2][offsetSamples]; + } + } + else { - input_f[obj] = &st_ivas->hTcBuffer->tc[obj + 2][offsetSamples]; + for ( obj = 0; obj < num_objects; obj++ ) + { + input_f[obj] = input_f_in[obj]; + } } slots_to_render = nSamplesRendered / hSpatParamRendCom->slot_size; @@ -666,7 +481,6 @@ void ivas_omasa_separate_object_render_jbm( tcBufferSize = hSpatParamRendCom->num_slots * hSpatParamRendCom->slot_size; delay_signal( input_f[obj], tcBufferSize, st_ivas->hMasaIsmData->delayBuffer[obj], st_ivas->hMasaIsmData->delayBuffer_size ); } - offsetSamples = 0; for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 88f6e0468..8673c8259 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -68,9 +68,8 @@ ivas_error ivas_jbm_dec_tc( ) { int16_t n, output_frame, nchan_out; - Decoder_State *st; /* used for bitstream handling */ - float *p_output[MAX_TRANSPORT_CHANNELS]; /* 'float' buffer for output synthesis */ - float output_f[MAX_TRANSPORT_CHANNELS][L_FRAME48k]; /* TODO: can be allocated dynamically using st_ivas->p_output_f */ + Decoder_State *st; /* used for bitstream handling */ + float *p_output[MAX_TRANSPORT_CHANNELS]; /* 'float' buffer for output synthesis */ int16_t nchan_remapped; int16_t nb_bits_metadata[MAX_SCE + 1]; int32_t output_Fs, ivas_total_brate; @@ -94,7 +93,19 @@ ivas_error ivas_jbm_dec_tc( for ( n = 0; n < MAX_TRANSPORT_CHANNELS; n++ ) { - p_output[n] = output_f[n]; + p_output[n] = st_ivas->p_output_f[n]; + if ( p_output[n] != NULL ) + { + set_zero( p_output[n], L_FRAME48k ); + } + } + + if ( !st_ivas->hDecoderConfig->Opt_tsm ) + { + for ( n = 0; n < ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); n++ ) + { + st_ivas->hTcBuffer->tc[n] = st_ivas->p_output_f[n]; + } } /*----------------------------------------------------------------* @@ -134,10 +145,7 @@ ivas_error ivas_jbm_dec_tc( /* Metadata decoding and configuration */ if ( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) { - if ( ( error = ivas_ism_dtx_dec( st_ivas, nb_bits_metadata ) ) != IVAS_ERR_OK ) - { - return error; - } + ivas_ism_dtx_dec( st_ivas, nb_bits_metadata ); /* decode dominant object first so the noise energy of the other objects can be limited */ if ( ( error = ivas_sce_dec( st_ivas, st_ivas->hISMDTX.sce_id_dtx, &p_output[st_ivas->hISMDTX.sce_id_dtx], output_frame, nb_bits_metadata[st_ivas->hISMDTX.sce_id_dtx] ) ) != IVAS_ERR_OK ) @@ -191,6 +199,7 @@ ivas_error ivas_jbm_dec_tc( { set_s( nb_bits_metadata, 0, MAX_SCE ); + /* read parameters from the bitstream */ if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hQMetaData != NULL ) { @@ -216,6 +225,7 @@ ivas_error ivas_jbm_dec_tc( if ( st_ivas->nchan_transport == CPE_CHANNELS && st_ivas->nCPE >= 1 ) { + st_ivas->hCPE[0]->brate_surplus = 0; st_ivas->hCPE[0]->element_brate = ivas_total_brate; } @@ -676,7 +686,7 @@ ivas_error ivas_jbm_dec_tc( * Write IVAS transport channels *----------------------------------------------------------------*/ - if ( st_ivas->hDecoderConfig->Opt_tsm == 1 || !st_ivas->hDecoderConfig->Opt_5ms ) + if ( st_ivas->hDecoderConfig->Opt_tsm == 1 ) { ivas_syn_output_f( p_output, output_frame, st_ivas->hTcBuffer->nchan_transport_jbm, data ); } @@ -737,7 +747,8 @@ void ivas_jbm_dec_feed_tc_to_renderer( p_data_f[n] = &data_f[n][0]; } - if ( st_ivas->hDecoderConfig->Opt_tsm || !st_ivas->hDecoderConfig->Opt_5ms ) + + if ( st_ivas->hDecoderConfig->Opt_tsm ) { ivas_jbm_dec_copy_tc( st_ivas, nSamplesForRendering, nSamplesResidual, data, p_data_f ); } @@ -793,11 +804,13 @@ void ivas_jbm_dec_feed_tc_to_renderer( ivas_ism_dec_digest_tc( st_ivas ); /* delay the objects here for all renderers where it is needed */ - if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || - st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || - st_ivas->renderer_type == RENDERER_OSBA_AMBI || - st_ivas->renderer_type == RENDERER_OSBA_LS || - st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) + if ( + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || + st_ivas->renderer_type == RENDERER_OSBA_AMBI || + st_ivas->renderer_type == RENDERER_OSBA_LS || + st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL + ) { for ( n = 0; n < st_ivas->nchan_ism; n++ ) { @@ -817,6 +830,8 @@ void ivas_jbm_dec_feed_tc_to_renderer( } else { + ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); + ivas_sba_dec_digest_tc( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); } } @@ -875,7 +890,6 @@ ivas_error ivas_jbm_dec_render( { int16_t n, nchan_out; int16_t nchan_transport; - float output[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS][L_FRAME48k]; /* 'float' buffer for output synthesis */ int16_t nchan_remapped; int32_t output_Fs; AUDIO_CONFIG output_config; @@ -899,21 +913,39 @@ ivas_error ivas_jbm_dec_render( for ( n = 0; n < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; n++ ) { - p_output[n] = &output[n][0]; + p_output[n] = st_ivas->p_output_f[n]; } - for ( n = 0; n < st_ivas->hTcBuffer->nchan_buffer_full; n++ ) + if ( !st_ivas->hDecoderConfig->Opt_tsm ) { - p_tc[n] = &st_ivas->hTcBuffer->tc[n][st_ivas->hTcBuffer->n_samples_rendered]; + for ( n = 0; n < st_ivas->hTcBuffer->nchan_buffer_full; n++ ) + { + p_tc[n] = p_output[n]; + } + + for ( n = 0; n < MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS; n++ ) + { + st_ivas->hTcBuffer->tc[n] = p_output[n]; + } + } + else + { + for ( n = 0; n < st_ivas->hTcBuffer->nchan_buffer_full; n++ ) + { + p_tc[n] = &st_ivas->hTcBuffer->tc[n][st_ivas->hTcBuffer->n_samples_rendered]; + } } /*----------------------------------------------------------------* - * Combine orientations + * Update combined orientation access index *----------------------------------------------------------------*/ - if ( ( error = combine_external_and_head_orientations_dec( st_ivas->hHeadTrackData, st_ivas->hExtOrientationData, st_ivas->hCombinedOrientationData ) ) != IVAS_ERR_OK ) + if ( st_ivas->hCombinedOrientationData != NULL ) { - return error; + /* take the discard samples into account here to make sure head rotation stays on the correct 5ms grid */ + st_ivas->hCombinedOrientationData->cur_subframe_samples_rendered_start -= st_ivas->hTcBuffer->n_samples_discard; + + ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData ); } /*----------------------------------------------------------------* @@ -985,10 +1017,10 @@ ivas_error ivas_jbm_dec_render( /* Binaural rendering */ if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { - if ( ( ivas_td_binaural_renderer_sf( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) - { - return error; - } + if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) + { + return error; + } } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { @@ -996,8 +1028,6 @@ ivas_error ivas_jbm_dec_render( { return error; } - - ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_output, p_output ); } } } @@ -1030,7 +1060,7 @@ ivas_error ivas_jbm_dec_render( ivas_dirac_dec_render( st_ivas, nchan_remapped, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); } } - else /* SBA_MODE_SPAR */ + else { if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ) ) != IVAS_ERR_OK ) { @@ -1079,10 +1109,19 @@ ivas_error ivas_jbm_dec_render( { *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); + /* shift SBA channels to avoid overwrite by ISM upmix in 1 object case and non-TSM unified channel memory*/ + if ( st_ivas->nchan_ism == 1 && st_ivas->hDecoderConfig->Opt_tsm == 0 ) + { + mvr2r( p_tc[2], p_output[3], *nSamplesRendered ); + mvr2r( p_tc[1], p_output[2], *nSamplesRendered ); + p_tc[1] = p_output[2]; + p_tc[2] = p_output[3]; + } + /* render objects */ ivas_ism_render_sf( st_ivas, p_output, *nSamplesRendered ); - /* add already rendererd SBA part */ + /* add already rendered SBA part */ for ( n = 0; n < nchan_out; n++ ) { v_add( p_output[n], p_tc[n + st_ivas->nchan_ism], p_output[n], *nSamplesRendered ); @@ -1090,32 +1129,10 @@ ivas_error ivas_jbm_dec_render( } else if ( st_ivas->renderer_type == RENDERER_OSBA_AMBI || st_ivas->renderer_type == RENDERER_OSBA_LS || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { - float output_ism[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - float *p_output_ism[MAX_OUTPUT_CHANNELS]; - - for ( n = 0; n < MAX_OUTPUT_CHANNELS; n++ ) - { - p_output_ism[n] = &output_ism[n][0]; - } - - if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_osba_render_sf( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ) ) != IVAS_ERR_OK ) { return error; } - - if ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV_ROOM ) - { - ivas_ism_render_sf( st_ivas, p_output_ism, *nSamplesRendered ); - } - - for ( n = 0; n < nchan_out; n++ ) - { - if ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV_ROOM ) - { - v_add( p_output[n], p_output_ism[n], p_output[n], *nSamplesRendered ); - } - v_multc( p_output[n], 0.5f, p_output[n], *nSamplesRendered ); - } } else if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) /*EXT output = individual objects + HOA3*/ { @@ -1141,7 +1158,7 @@ ivas_error ivas_jbm_dec_render( { ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output ); } - else /* SBA_MODE_SPAR */ + else { if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ) ) != IVAS_ERR_OK ) { @@ -1152,11 +1169,11 @@ ivas_error ivas_jbm_dec_render( { for ( n = st_ivas->hIntSetup.nchan_out_woLFE - 1; n >= 0; n-- ) { - mvr2r( output[n], output[n + st_ivas->nchan_ism], *nSamplesRendered ); + mvr2r( p_output[n], p_output[n + st_ivas->nchan_ism], *nSamplesRendered ); } for ( n = 0; n < st_ivas->nchan_ism; n++ ) { - set_zero( output[n], *nSamplesRendered ); + set_zero( p_output[n], *nSamplesRendered ); } } } @@ -1179,13 +1196,16 @@ ivas_error ivas_jbm_dec_render( /* Rendering */ if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { + if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, crendInPlaceRotation ? p_output : p_tc, p_output, *nSamplesRendered, output_Fs ) ) != IVAS_ERR_OK ) - { - return error; - } - ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_tc, p_output ); + + { + return error; + } + + ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_tc, p_output ); } else if ( st_ivas->renderer_type == RENDERER_MC ) { @@ -1198,25 +1218,21 @@ ivas_error ivas_jbm_dec_render( } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { - if ( ( ivas_td_binaural_renderer_sf( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) - { - return error; - } + if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) + { + return error; + } - ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_tc, p_output ); + ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_tc, p_output ); } } else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) { ivas_mc_paramupmix_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_tc, p_output ); - if ( st_ivas->transport_config != st_ivas->intern_config && ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_FOA || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA2 || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA3 ) ) - { - ivas_mc2sba( st_ivas->hTransSetup, p_output, p_output, *nSamplesRendered, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE ); - } /* Rendering */ - if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) && !st_ivas->hDecoderConfig->Opt_Headrotation ) { { ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_output, p_output ); @@ -1232,12 +1248,12 @@ ivas_error ivas_jbm_dec_render( } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { - if ( ( ivas_td_binaural_renderer( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) - { - return error; - } + if ( ( error = ivas_td_binaural_renderer( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) + { + return error; + } - ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_output, p_output ); + ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_output, p_output ); } } else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) @@ -1262,15 +1278,16 @@ ivas_error ivas_jbm_dec_render( /* we still need to copy the separate channel if available */ if ( st_ivas->hOutSetup.separateChannelEnabled ) { - mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); + mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, p_output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); } + ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f ); } else if ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_5_1 && ( output_config == IVAS_AUDIO_CONFIG_5_1_2 || output_config == IVAS_AUDIO_CONFIG_5_1_4 || output_config == IVAS_AUDIO_CONFIG_7_1 ) ) { for ( n = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; n < st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; n++ ) { - set_zero( output[n], *nSamplesRendered ); + set_zero( p_output[n], *nSamplesRendered ); } } } @@ -1282,13 +1299,13 @@ ivas_error ivas_jbm_dec_render( output_config == IVAS_AUDIO_CONFIG_5_1_4 || output_config == IVAS_AUDIO_CONFIG_7_1_4 || output_config == IVAS_AUDIO_CONFIG_5_1_2 || ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe > 0 ) ) { - mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL] + offset, output[LFE_CHANNEL], *nSamplesRendered ); - mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); + mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL] + offset, p_output[LFE_CHANNEL], *nSamplesRendered ); + mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, p_output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); } else if ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe == 0 ) { /* Delay the separated channel to sync with the DirAC rendering */ - mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); + mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, p_output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); } } } @@ -1303,9 +1320,12 @@ ivas_error ivas_jbm_dec_render( st_ivas->hTcBuffer->n_samples_available -= *nSamplesRendered; st_ivas->hTcBuffer->n_samples_rendered += *nSamplesRendered; + /* update global combined orientation start index */ + ivas_combined_orientation_update_start_index( st_ivas->hCombinedOrientationData, *nSamplesRendered ); + if ( st_ivas->hTcBuffer->n_samples_discard > 0 ) { - for ( n = 0; n < MAX_OUTPUT_CHANNELS; n++ ) + for ( n = 0; n < min( MAX_OUTPUT_CHANNELS, ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ) ); n++ ) { p_output[n] += st_ivas->hTcBuffer->n_samples_discard; } @@ -1358,6 +1378,11 @@ ivas_error ivas_jbm_dec_flush_renderer( float output[MAX_CICP_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; float *p_output[MAX_CICP_CHANNELS]; + if ( !st_ivas->hDecoderConfig->Opt_tsm ) + { + return IVAS_ERR_OK; + } + *nSamplesRendered = 0; hTcBuffer = st_ivas->hTcBuffer; @@ -1369,6 +1394,9 @@ ivas_error ivas_jbm_dec_flush_renderer( n_samples_still_available -= n_samples_to_render; assert( n_samples_still_available < tc_granularity_new ); + /* update combined orientation access index */ + ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData ); + if ( n_slots_still_available ) { int16_t ch_idx; @@ -1421,13 +1449,11 @@ ivas_error ivas_jbm_dec_flush_renderer( ivas_ism_render_sf( st_ivas, p_output, hTcBuffer->n_samples_granularity ); - if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, NULL, - NULL, st_ivas->hTcBuffer, p_output, p_output, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, + NULL, NULL, st_ivas->hTcBuffer, p_output, p_output, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) { return error; } - - ivas_binaural_add_LFE( st_ivas, hTcBuffer->n_samples_granularity, p_output, p_output ); } } else @@ -1541,6 +1567,9 @@ ivas_error ivas_jbm_dec_flush_renderer( #endif } + /* update global combined orientation start index */ + ivas_combined_orientation_update_start_index( st_ivas->hCombinedOrientationData, *nSamplesRendered ); + *nSamplesRendered = n_samples_to_render; /* Only write out the valid data*/ @@ -1799,6 +1828,7 @@ int16_t ivas_jbm_dec_get_num_tc_channels( int32_t ivas_total_brate; AUDIO_CONFIG output_config; + if ( st_ivas->renderer_type == RENDERER_DISABLE ) { num_tc = st_ivas->hDecoderConfig->nchan_out; @@ -1810,7 +1840,12 @@ int16_t ivas_jbm_dec_get_num_tc_channels( output_config = st_ivas->hDecoderConfig->output_config; ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; - if ( st_ivas->ivas_format == STEREO_FORMAT && st_ivas->hDecoderConfig->nchan_out == 1 ) + + if ( st_ivas->ivas_format == MONO_FORMAT ) + { + num_tc = st_ivas->hDecoderConfig->nchan_out; + } + else if ( st_ivas->ivas_format == STEREO_FORMAT && st_ivas->hDecoderConfig->nchan_out == 1 ) { num_tc = 1; } @@ -2110,26 +2145,33 @@ ivas_error ivas_jbm_dec_tc_buffer_open( } else { - if ( ( hTcBuffer->tc_buffer = (float *) malloc( nsamp_to_allocate * sizeof( float ) ) ) == NULL ) + if ( st_ivas->hDecoderConfig->Opt_tsm ) { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for JBM TC Buffer\n" ) ); - } - set_zero( hTcBuffer->tc_buffer, nsamp_to_allocate ); + if ( ( hTcBuffer->tc_buffer = (float *) malloc( nsamp_to_allocate * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for JBM TC Buffer\n" ) ); + } + set_zero( hTcBuffer->tc_buffer, nsamp_to_allocate ); - offset = 0; - for ( ch_idx = 0; ch_idx < hTcBuffer->nchan_buffer_full; ch_idx++ ) - { - hTcBuffer->tc[ch_idx] = &hTcBuffer->tc_buffer[offset]; - offset += n_samp_full; - } - for ( ; ch_idx < hTcBuffer->nchan_transport_internal; ch_idx++ ) - { - hTcBuffer->tc[ch_idx] = &hTcBuffer->tc_buffer[offset]; - offset += n_samp_residual; + offset = 0; + for ( ch_idx = 0; ch_idx < hTcBuffer->nchan_buffer_full; ch_idx++ ) + { + hTcBuffer->tc[ch_idx] = &hTcBuffer->tc_buffer[offset]; + offset += n_samp_full; + } + for ( ; ch_idx < hTcBuffer->nchan_transport_internal; ch_idx++ ) + { + hTcBuffer->tc[ch_idx] = &hTcBuffer->tc_buffer[offset]; + offset += n_samp_residual; + } + for ( ; ch_idx < MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS; ch_idx++ ) + { + hTcBuffer->tc[ch_idx] = NULL; + } } - for ( ; ch_idx < MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS; ch_idx++ ) + else { - hTcBuffer->tc[ch_idx] = NULL; + hTcBuffer->tc_buffer = NULL; } } } @@ -2161,6 +2203,7 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( hTcBuffer = st_ivas->hTcBuffer; + /* if granularity changes, adapt subframe_nb_slots */ if ( n_samples_granularity != hTcBuffer->n_samples_granularity ) { @@ -2187,10 +2230,12 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( hTcBuffer->n_samples_granularity = n_samples_granularity; /* realloc buffers */ - if ( hTcBuffer->tc_buffer ) + if ( hTcBuffer->tc_buffer != NULL ) { free( hTcBuffer->tc_buffer ); + hTcBuffer->tc_buffer = NULL; } + if ( st_ivas->hDecoderConfig->Opt_tsm ) { n_samp_full = ( NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) + hTcBuffer->n_samples_granularity - 1 ); @@ -2204,27 +2249,44 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( nsamp_to_allocate = hTcBuffer->nchan_buffer_full * n_samp_full; nsamp_to_allocate += nchan_residual * n_samp_residual; - if ( ( hTcBuffer->tc_buffer = (float *) malloc( nsamp_to_allocate * sizeof( float ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for JBM TC Buffer\n" ) ); - } - set_zero( hTcBuffer->tc_buffer, nsamp_to_allocate ); - - offset = 0; - for ( ch_idx = 0; ch_idx < hTcBuffer->nchan_buffer_full; ch_idx++ ) + if ( nsamp_to_allocate == 0 ) { - hTcBuffer->tc[ch_idx] = &hTcBuffer->tc_buffer[offset]; - offset += n_samp_full; + hTcBuffer->tc_buffer = NULL; + for ( ch_idx = 0; ch_idx < MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS; ch_idx++ ) + { + hTcBuffer->tc[ch_idx] = NULL; + } } - for ( ; ch_idx < hTcBuffer->nchan_transport_internal; ch_idx++ ) + else { - hTcBuffer->tc[ch_idx] = &hTcBuffer->tc_buffer[offset]; - offset += n_samp_residual; - } + if ( st_ivas->hDecoderConfig->Opt_tsm ) + { + if ( ( hTcBuffer->tc_buffer = (float *) malloc( nsamp_to_allocate * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for JBM TC Buffer\n" ) ); + } + set_zero( hTcBuffer->tc_buffer, nsamp_to_allocate ); - for ( ; ch_idx < MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS; ch_idx++ ) - { - hTcBuffer->tc[ch_idx] = NULL; + offset = 0; + for ( ch_idx = 0; ch_idx < hTcBuffer->nchan_buffer_full; ch_idx++ ) + { + hTcBuffer->tc[ch_idx] = &hTcBuffer->tc_buffer[offset]; + offset += n_samp_full; + } + for ( ; ch_idx < hTcBuffer->nchan_transport_internal; ch_idx++ ) + { + hTcBuffer->tc[ch_idx] = &hTcBuffer->tc_buffer[offset]; + offset += n_samp_residual; + } + for ( ; ch_idx < MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS; ch_idx++ ) + { + hTcBuffer->tc[ch_idx] = NULL; + } + } + else + { + hTcBuffer->tc_buffer = NULL; + } } return IVAS_ERR_OK; @@ -2462,11 +2524,16 @@ void ivas_jbm_dec_copy_tc_no_tsm( hTcBuffer->n_samples_available = hTcBuffer->n_samples_buffered; n_ch_full_copy = min( hTcBuffer->nchan_transport_jbm, hTcBuffer->nchan_buffer_full ); n_ch_cldfb = hTcBuffer->nchan_transport_jbm - hTcBuffer->nchan_buffer_full; + /* copy full tcs*/ - for ( ch_idx = 0; ch_idx < n_ch_full_copy; ch_idx++ ) + if ( st_ivas->hDecoderConfig->Opt_tsm ) { - mvr2r( tc[ch_idx], st_ivas->hTcBuffer->tc[ch_idx], hTcBuffer->n_samples_buffered ); + for ( ch_idx = 0; ch_idx < n_ch_full_copy; ch_idx++ ) + { + mvr2r( tc[ch_idx], st_ivas->hTcBuffer->tc[ch_idx], hTcBuffer->n_samples_buffered ); + } } + ch_idx = 0; /* CLDFB ana for ParamMC/ParamISM */ if ( n_ch_cldfb > 0 ) diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index 73fca37fd..0eb9691b1 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -619,7 +619,7 @@ ivas_error ivas_masa_dec_open( st_ivas->hMasa = hMasa; /* allocate transport channels*/ - if ( st_ivas->hDecoderConfig->Opt_5ms && st_ivas->hTcBuffer == NULL && st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC ) + if ( st_ivas->hTcBuffer == NULL && st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC ) { int16_t nchan_to_allocate, nchan_transport; TC_BUFFER_MODE buffer_mode; @@ -1247,15 +1247,12 @@ ivas_error ivas_masa_dec_reconfigure( ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; last_ivas_total_brate = st_ivas->hDecoderConfig->last_ivas_total_brate; - if ( st_ivas->hDecoderConfig->Opt_5ms == 1 ) - { if ( st_ivas->hSpatParamRendCom != NULL && st_ivas->hSpatParamRendCom->slot_size == st_ivas->hTcBuffer->n_samples_granularity ) { mvs2s( st_ivas->hSpatParamRendCom->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); st_ivas->hTcBuffer->nb_subframes = st_ivas->hSpatParamRendCom->nb_subframes; st_ivas->hTcBuffer->subframes_rendered = st_ivas->hSpatParamRendCom->subframes_rendered; } - } ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old ); @@ -1398,7 +1395,6 @@ ivas_error ivas_masa_dec_reconfigure( st_ivas->ism_mode = ISM_MODE_NONE; } - if ( st_ivas->hDecoderConfig->Opt_5ms == 1 ) { int16_t tc_nchan_to_allocate; int16_t tc_nchan_transport; @@ -1420,11 +1416,9 @@ ivas_error ivas_masa_dec_reconfigure( { tc_nchan_to_allocate = 2 * BINAURAL_CHANNELS; } - if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) { n_samples_granularity = NS2SA( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); /* Use the same granularity as tdrend */ - if ( n_samples_granularity > st_ivas->hTcBuffer->n_samples_granularity ) { if ( ( error = ivas_jbm_dec_set_discard_samples( st_ivas ) ) != IVAS_ERR_OK ) @@ -1450,6 +1444,7 @@ ivas_error ivas_masa_dec_reconfigure( tc_nchan_to_allocate++; } + if ( tc_nchan_transport != st_ivas->hTcBuffer->nchan_transport_jbm || tc_nchan_to_allocate != st_ivas->hTcBuffer->nchan_transport_internal || buffer_mode_new != st_ivas->hTcBuffer->tc_buffer_mode ) { if ( ( error = ivas_jbm_dec_tc_buffer_reconfigure( st_ivas, buffer_mode_new, tc_nchan_transport, tc_nchan_to_allocate, tc_nchan_to_allocate, n_samples_granularity ) ) != IVAS_ERR_OK ) diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 0f84823e5..5536baa14 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -429,7 +429,7 @@ ivas_error ivas_param_mc_dec_open( ivas_param_mc_dec_init( hParamMC, nchan_transport, nchan_out_cov ); - if ( st_ivas->hDecoderConfig->Opt_5ms && hParamMC->synthesis_conf != PARAM_MC_SYNTH_MONO_STEREO ) + if ( hParamMC->synthesis_conf != PARAM_MC_SYNTH_MONO_STEREO ) { int16_t n_cldfb_slots; @@ -953,6 +953,55 @@ ivas_error ivas_param_mc_dec_reconfig( set_zero( hParamMC->proto_frame_f, 2 * hParamMC->diff_proto_info->num_protos_diff * hParamMC->num_freq_bands ); } + + if ( nchan_transport_old != nchan_transport ) + { + if ( hParamMC->synthesis_conf != PARAM_MC_SYNTH_MONO_STEREO ) + { + int16_t n_cldfb_slots; + + if ( hParamMC->Cldfb_RealBuffer_tc != NULL ) + { + free( hParamMC->Cldfb_RealBuffer_tc ); + hParamMC->Cldfb_RealBuffer_tc = NULL; + } + if ( hParamMC->Cldfb_ImagBuffer_tc != NULL ) + { + free( hParamMC->Cldfb_ImagBuffer_tc ); + hParamMC->Cldfb_ImagBuffer_tc = NULL; + } + + n_cldfb_slots = DEFAULT_JBM_CLDFB_TIMESLOTS; + if ( st_ivas->hDecoderConfig->Opt_tsm ) + { + n_cldfb_slots = MAX_JBM_CLDFB_TIMESLOTS; + } + if ( ( hParamMC->Cldfb_RealBuffer_tc = (float *) malloc( n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC JBM\n" ) ); + } + set_zero( hParamMC->Cldfb_RealBuffer_tc, n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands ); + + if ( ( hParamMC->Cldfb_ImagBuffer_tc = (float *) malloc( n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC JBM\n" ) ); + } + set_zero( hParamMC->Cldfb_ImagBuffer_tc, n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands ); + } + else + { + if ( hParamMC->Cldfb_RealBuffer_tc != NULL ) + { + free( hParamMC->Cldfb_RealBuffer_tc ); + hParamMC->Cldfb_RealBuffer_tc = NULL; + } + if ( hParamMC->Cldfb_ImagBuffer_tc != NULL ) + { + free( hParamMC->Cldfb_ImagBuffer_tc ); + hParamMC->Cldfb_ImagBuffer_tc = NULL; + } + } + } return error; } @@ -1411,7 +1460,7 @@ void ivas_param_mc_dec_digest_tc( /* slot loop for gathering the input data */ for ( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) { - if ( st_ivas->hDecoderConfig->Opt_tsm || !st_ivas->hDecoderConfig->Opt_5ms ) + if ( st_ivas->hDecoderConfig->Opt_tsm ) { float RealBuffer[CLDFB_NO_CHANNELS_MAX]; float ImagBuffer[CLDFB_NO_CHANNELS_MAX]; @@ -1698,8 +1747,13 @@ void ivas_param_mc_dec_render( { ivas_binRenderer( st_ivas->hBinRenderer, - st_ivas->hCombinedOrientationData, subframe_idx, hParamMC->subframe_nbslots[subframe_idx], Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); + st_ivas->hCombinedOrientationData, + hParamMC->subframe_nbslots[subframe_idx], + Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); + + /* update combined orientation access index */ + ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, hParamMC->num_freq_bands * hParamMC->subframe_nbslots[subframe_idx] ); } else if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_CLDFB ) { diff --git a/lib_dec/ivas_mc_paramupmix_dec.c b/lib_dec/ivas_mc_paramupmix_dec.c index 26a655425..d98788695 100644 --- a/lib_dec/ivas_mc_paramupmix_dec.c +++ b/lib_dec/ivas_mc_paramupmix_dec.c @@ -58,25 +58,21 @@ const int16_t MC_PARAMUPMIX_CHIDX2[MC_PARAMUPMIX_COMBINATIONS] = { 2, 3, 6, 7 }; * Local function prototypes *-----------------------------------------------------------------------*/ -static void ps_pred_process( MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, float qmf_mod_re[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float qmf_mod_im[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float qmf_side_re[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float qmf_side_im[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const int16_t ch ); - static void ps_pred_process_sf( MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, DECODER_TC_BUFFER_HANDLE hTcBuffer, float qmf_mod_re[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float qmf_mod_im[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float qmf_side_re[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float qmf_side_im[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float *param_interpol, const int16_t ch, const int16_t slots_rendered ); static void ivas_mc_paramupmix_dec_sf( Decoder_Struct *st_ivas, float *output_f[MAX_OUTPUT_CHANNELS] ); static void ivas_param_upmix_dec_decorr_subframes( Decoder_Struct *st_ivas, const int16_t nSamplesForRendering ); -static void paramupmix_td_decorr_process( ivas_td_decorr_state_t *hTdDecorr[], float *pcm_in[], float **pp_out_pcm, const int16_t output_frame ); - static int16_t huff_read( Decoder_State *st, const int16_t ( *ht )[2] ); -static void huffman_decode( Decoder_State *st, const int16_t nv, const int16_t ivStart, PAR_TYPE parType, QUANT_TYPE quant_type, const int16_t bNoDt, int32_t *vq ); +static void huffman_decode( Decoder_State *st, const PAR_TYPE parType, int32_t *vq ); -static void dequant_alpha( const int16_t nv, const int16_t ivStart, const QUANT_TYPE quant_type, int32_t *vq, float *v ); +static void dequant_alpha( int32_t *vq, float *v ); -static void dequant_beta( const int16_t nv, const int16_t ivStart, const QUANT_TYPE quant_type, int32_t *aq, int32_t *bq, float *beta ); +static void dequant_beta( int32_t *aq, int32_t *bq, float *beta ); -static void get_ec_data( Decoder_State *st, const PAR_TYPE parType, const QUANT_TYPE quant_type, const int16_t nParBand, const int16_t parBandStart, int32_t *parQ, int32_t *alphaQEnv, float ab[IVAS_MAX_NUM_BANDS] ); +static void get_ec_data( Decoder_State *st, const PAR_TYPE parType, int32_t *parQ, int32_t *alphaQEnv, float ab[IVAS_MAX_NUM_BANDS] ); /*------------------------------------------------------------------------- @@ -131,11 +127,9 @@ void ivas_mc_paramupmix_dec_read_BS( for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) { - get_ec_data( st0, ALPHA, FINE /*quant_type*/, IVAS_MAX_NUM_BANDS /*nParBand*/, - 0 /*parBandStart*/, hMCParamUpmix->alpha_quant[i], alpha_quant, hMCParamUpmix->alphas[i] ); + get_ec_data( st0, ALPHA, hMCParamUpmix->alpha_quant[i], alpha_quant, hMCParamUpmix->alphas[i] ); - get_ec_data( st0, BETA, FINE /*quant_type*/, IVAS_MAX_NUM_BANDS /*nParBand*/, - 0 /*parBandStart*/, hMCParamUpmix->beta_quant[i], alpha_quant, hMCParamUpmix->betas[i] ); + get_ec_data( st0, BETA, hMCParamUpmix->beta_quant[i], alpha_quant, hMCParamUpmix->betas[i] ); } *nb_bits += st0->next_bit_pos; st0->bit_stream = bit_stream_orig; @@ -157,236 +151,6 @@ void ivas_mc_paramupmix_dec_read_BS( } -/*------------------------------------------------------------------------- - * ivas_mc_paramupmix_dec() - * - * MC ParamUpmix decoding process - *------------------------------------------------------------------------*/ - -void ivas_mc_paramupmix_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - float *output_f[] /* i/o: synthesized core-coder transport channels */ -) -{ - MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix; - int16_t i, k, ch; - int16_t slot_idx; - int16_t first_empty_channel; - int16_t nchan_out_transport; - /*CLDFB*/ - float Cldfb_RealBuffer[MC_PARAMUPMIX_MAX_TRANSPORT_CHANS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer[MC_PARAMUPMIX_MAX_TRANSPORT_CHANS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - int16_t channel_active[MAX_OUTPUT_CHANNELS]; - int32_t output_Fs; - int16_t output_frame; - float Pcm_decorr[MC_PARAMUPMIX_COMBINATIONS][L_FRAME48k]; /* decorrelated channels */ - float *pPcm_temp[MC_PARAMUPMIX_COMBINATIONS * 2]; /* decorrelated and undecorrelated*/ - int16_t noparamupmix_delay; - AUDIO_CONFIG output_config; - int16_t subframeIdx, idx_in, index_slot, maxBand; - float Cldfb_RealBuffer_subfr[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer_subfr[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - - hMCParamUpmix = st_ivas->hMCParamUpmix; - assert( hMCParamUpmix ); - push_wmops( "mc_paramupmix_dec" ); - - set_s( channel_active, 0, MAX_CICP_CHANNELS ); - nchan_out_transport = st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe; - set_s( channel_active, 1, nchan_out_transport ); /* change to nchan_out_transport */ - output_Fs = st_ivas->hDecoderConfig->output_Fs; - output_config = st_ivas->hDecoderConfig->output_config; - output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC ); - - if ( ( output_config == IVAS_AUDIO_CONFIG_STEREO ) || ( output_config == IVAS_AUDIO_CONFIG_MONO ) ) - { - first_empty_channel = 8; /* Don't upmix */ - - /* Compensate loudness for not doing full upmix */ - for ( i = 4; i < 8; i++ ) - { - v_multc( output_f[i], 2.0f, output_f[i], L_FRAME48k ); - } - } - else - { - first_empty_channel = 12; - - for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) - { - pPcm_temp[i] = Pcm_decorr[i]; /* decorrelated */ - } - - paramupmix_td_decorr_process( hMCParamUpmix->hTdDecorr, &( output_f[4] ), pPcm_temp, output_frame ); - - for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) - { - pPcm_temp[2 * i] = output_f[i + 4]; /* un-decorrelated */ - pPcm_temp[2 * i + 1] = Pcm_decorr[i]; /* decorrelated */ - } - - /* CLDFB Analysis*/ - for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS * 2; ch++ ) - { - /* slot loop for gathering the input data */ - for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) - { - cldfbAnalysis_ts( &( pPcm_temp[ch][hMCParamUpmix->num_freq_bands * slot_idx] ), Cldfb_RealBuffer[ch][slot_idx], Cldfb_ImagBuffer[ch][slot_idx], hMCParamUpmix->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); - } - } - for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS; ch++ ) - { - ps_pred_process( hMCParamUpmix, - Cldfb_RealBuffer[2 * ch], /* in/out */ - Cldfb_ImagBuffer[2 * ch], - Cldfb_RealBuffer[2 * ch + 1], /* in/out decorr */ - Cldfb_ImagBuffer[2 * ch + 1], - ch ); - - /*-- m, s -> l, r ----------------------------*/ - for ( i = 0; i < CLDFB_NO_COL_MAX; i++ ) - { - for ( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) - { - float qlre = Cldfb_RealBuffer[2 * ch][i][k]; - float qlim = Cldfb_ImagBuffer[2 * ch][i][k]; - float qrre = Cldfb_RealBuffer[2 * ch + 1][i][k]; - float qrim = Cldfb_ImagBuffer[2 * ch + 1][i][k]; - - Cldfb_RealBuffer[2 * ch][i][k] = qlre + qrre; - Cldfb_ImagBuffer[2 * ch][i][k] = qlim + qrim; - Cldfb_RealBuffer[2 * ch + 1][i][k] = qlre - qrre; - Cldfb_ImagBuffer[2 * ch + 1][i][k] = qlim - qrim; - } - } - - mvr2r( hMCParamUpmix->alphas[ch], hMCParamUpmix->alpha_prev[ch], IVAS_MAX_NUM_BANDS ); - mvr2r( hMCParamUpmix->betas[ch], hMCParamUpmix->beta_prev[ch], IVAS_MAX_NUM_BANDS ); - } - - if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) - { - maxBand = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * st_ivas->hDecoderConfig->output_Fs ) / 48000 ); - /* fastconv binaural rendering and CLDFB synthesis */ - for ( subframeIdx = 0; subframeIdx < ( CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES ); subframeIdx++ ) - { - index_slot = subframeIdx * MAX_PARAM_SPATIAL_SUBFRAMES; - /* cldfb analysis of non-coupled, non-LFE channels */ - idx_in = 0; - for ( ch = 0; ch < first_empty_channel - 2 * MC_PARAMUPMIX_COMBINATIONS; ch++ ) - { - if ( st_ivas->hIntSetup.index_lfe[0] != ch ) - { - pPcm_temp[ch] = output_f[ch]; - /* slot loop for gathering the input data */ - for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) - { - cldfbAnalysis_ts( &( pPcm_temp[ch][hMCParamUpmix->num_freq_bands * ( index_slot + slot_idx )] ), - Cldfb_RealBuffer_subfr[idx_in][slot_idx], - Cldfb_ImagBuffer_subfr[idx_in][slot_idx], - maxBand, st_ivas->cldfbAnaDec[2 * MC_PARAMUPMIX_COMBINATIONS + idx_in] ); - } - idx_in++; - } - } - - /* copy and reorder cldfb analysis of coupled channels */ - for ( ch = 0; ch < MAX_PARAM_SPATIAL_SUBFRAMES; ch++ ) - { - for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) - { - mvr2r( Cldfb_RealBuffer[MC_PARAMUPMIX_CHIDX1[ch]][index_slot + slot_idx], Cldfb_RealBuffer_subfr[idx_in][slot_idx], CLDFB_NO_CHANNELS_MAX ); - mvr2r( Cldfb_ImagBuffer[MC_PARAMUPMIX_CHIDX1[ch]][index_slot + slot_idx], Cldfb_ImagBuffer_subfr[idx_in][slot_idx], CLDFB_NO_CHANNELS_MAX ); - mvr2r( Cldfb_RealBuffer[MC_PARAMUPMIX_CHIDX2[ch]][index_slot + slot_idx], Cldfb_RealBuffer_subfr[idx_in + 1][slot_idx], CLDFB_NO_CHANNELS_MAX ); - mvr2r( Cldfb_ImagBuffer[MC_PARAMUPMIX_CHIDX2[ch]][index_slot + slot_idx], Cldfb_ImagBuffer_subfr[idx_in + 1][slot_idx], CLDFB_NO_CHANNELS_MAX ); - } - idx_in += 2; - } - - if ( st_ivas->hCombinedOrientationData && st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) - { - for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) - { - ivas_param_mc_mc2sba_cldfb( st_ivas->hTransSetup, hMCParamUpmix->hoa_encoder, slot_idx, Cldfb_RealBuffer_subfr, Cldfb_ImagBuffer_subfr, maxBand, GAIN_LFE ); - } - } - - - /* Implement binaural rendering */ - ivas_binRenderer( st_ivas->hBinRenderer, st_ivas->hCombinedOrientationData, subframeIdx, /* TODO (5ms) : tmu2Dlb please verify */ JBM_CLDFB_SLOTS_IN_SUBFRAME, - Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer_subfr, Cldfb_ImagBuffer_subfr ); - - - /* Implement CLDFB synthesis */ - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; - float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; - - for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) - { - RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[ch][slot_idx]; - ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[ch][slot_idx]; - } - - cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * maxBand] ), maxBand * MAX_PARAM_SPATIAL_SUBFRAMES, st_ivas->cldfbSynDec[ch] ); - } - } - } - else - { - pPcm_temp[0] = output_f[4]; - pPcm_temp[1] = output_f[6]; - pPcm_temp[2] = output_f[5]; - pPcm_temp[3] = output_f[7]; - pPcm_temp[4] = output_f[8]; - pPcm_temp[5] = output_f[10]; - pPcm_temp[6] = output_f[9]; - pPcm_temp[7] = output_f[11]; - - /* CLDFB synthesis */ - for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS * 2; ch++ ) - { - for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) - { - float *ptr_im[1], *ptr_re[1]; - ptr_re[0] = Cldfb_RealBuffer[ch][slot_idx]; - ptr_im[0] = Cldfb_ImagBuffer[ch][slot_idx]; - - cldfbSynthesis( ptr_re, ptr_im, &( pPcm_temp[ch][hMCParamUpmix->num_freq_bands * slot_idx] ), - hMCParamUpmix->num_freq_bands, st_ivas->cldfbSynDec[ch] ); - } - } - - /* adjust delay of other channels */ - noparamupmix_delay = NS2SA( output_Fs, IVAS_FB_DEC_DELAY_NS ); - for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS; ch++ ) - { - float tmp_buf[L_SUBFRAME5MS_48k]; - mvr2r( &output_f[ch][output_frame - noparamupmix_delay], tmp_buf, noparamupmix_delay ); - mvr2r( output_f[ch], &output_f[ch][noparamupmix_delay], output_frame - noparamupmix_delay ); - mvr2r( hMCParamUpmix->pcm_delay[ch], output_f[ch], noparamupmix_delay ); - mvr2r( tmp_buf, hMCParamUpmix->pcm_delay[ch], noparamupmix_delay ); - } - } - } - -#ifdef NONBE_FIX_839_MC_RS_CHANNEL_ALLOC - for ( ch = first_empty_channel; ch < ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); ch++ ) -#else - for ( ch = first_empty_channel; ch < ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); ch++ ) -#endif - { - set_f( output_f[ch], 0.0f, output_frame ); - } - - pop_wmops(); - return; -} - - /*------------------------------------------------------------------------- * ivas_mc_paramupmix_dec_digest_tc() * @@ -477,10 +241,14 @@ void ivas_mc_paramupmix_dec_render( int16_t n_samples_sf = slot_size * st_ivas->hTcBuffer->subframe_nbslots[subframe_idx]; ivas_mc_paramupmix_dec_sf( st_ivas, output_f_local ); - for ( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) + + for ( ch = 0; ch < min( MAX_OUTPUT_CHANNELS, ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ) ); ch++ ) { output_f_local[ch] += n_samples_sf; } + + /* update combined orientation access index */ + ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); } for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS; ch++ ) @@ -573,8 +341,6 @@ ivas_error ivas_mc_paramupmix_dec_open( hMCParamUpmix->free_param_interpolator = 0; hMCParamUpmix->param_interpolator = NULL; - if ( st_ivas->hDecoderConfig->Opt_5ms == 1 ) - { if ( ( hMCParamUpmix->param_interpolator = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for interpolator\n" ) ); @@ -582,9 +348,8 @@ ivas_error ivas_mc_paramupmix_dec_open( hMCParamUpmix->free_param_interpolator = 1; ivas_jbm_dec_get_adapted_linear_interpolator( DEFAULT_JBM_CLDFB_TIMESLOTS, DEFAULT_JBM_CLDFB_TIMESLOTS, hMCParamUpmix->param_interpolator ); - } - if ( st_ivas->hDecoderConfig->Opt_5ms == 1 && st_ivas->hTcBuffer == NULL ) + if ( st_ivas->hTcBuffer == NULL ) { int16_t nchan_to_allocate; int16_t nchan_tc; @@ -610,7 +375,6 @@ ivas_error ivas_mc_paramupmix_dec_open( return error; } } - st_ivas->hMCParamUpmix = hMCParamUpmix; return error; @@ -665,7 +429,7 @@ void ivas_mc_paramupmix_dec_close( /*------------------------------------------------------------------------- - * ivas_param_upmix_dec_decorr_subframes() + * paramupmix_td_decorr_process_jbm() * * *------------------------------------------------------------------------*/ @@ -717,6 +481,12 @@ static void paramupmix_td_decorr_process_jbm( } +/*------------------------------------------------------------------------- + * ivas_param_upmix_dec_decorr_subframes() + * + * + *------------------------------------------------------------------------*/ + static void ivas_param_upmix_dec_decorr_subframes( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const int16_t nSamplesForRendering ) @@ -766,69 +536,6 @@ static void ivas_param_upmix_dec_decorr_subframes( /* local functions */ /*****************************************************************************************/ -static void ps_pred_process( - MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, - float qmf_mod_re[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* in/out */ - float qmf_mod_im[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float qmf_side_re[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* in/out */ - float qmf_side_im[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t ch ) -{ - float vmre, vmim, vsre, vsim; - int16_t iqmf, ipar, ismp, iismp; - float alpha_smp, dalpha, beta_smp, dbeta; - float *alpha1, *alpha2; - float *beta1, *beta2; - float *alpha_prev = hMCParamUpmix->alpha_prev[ch]; - float *beta_prev = hMCParamUpmix->beta_prev[ch]; - - const int16_t qmf_to_par_band[] = { - 0, 1, 2, 3, 4, 5, 5, 6, 6, 7, - 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, - 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11 - }; - - for ( iqmf = 0; iqmf < CLDFB_NO_CHANNELS_MAX; iqmf++ ) - { - /* For changing no of parameter bands (ipar1 != ipar2), TIGGER_FRAMING assumed */ - ipar = qmf_to_par_band[iqmf]; - alpha1 = alpha_prev; - beta1 = beta_prev; - - ismp = 0; - alpha2 = hMCParamUpmix->alphas[ch]; - beta2 = hMCParamUpmix->betas[ch]; - alpha_smp = alpha1[ipar]; - beta_smp = beta1[ipar]; - dalpha = ( alpha2[ipar] - alpha1[ipar] ) / CLDFB_NO_COL_MAX; - dbeta = ( beta2[ipar] - beta1[ipar] ) / CLDFB_NO_COL_MAX; - - for ( iismp = 0; iismp < CLDFB_NO_COL_MAX; iismp++ ) - { - alpha_smp += dalpha; - beta_smp += dbeta; - - vmre = qmf_mod_re[ismp][iqmf]; - vmim = qmf_mod_im[ismp][iqmf]; - vsre = qmf_side_re[ismp][iqmf]; - vsim = qmf_side_im[ismp][iqmf]; - - qmf_side_re[ismp][iqmf] = alpha_smp * vmre + beta_smp * vsre; - qmf_side_im[ismp][iqmf] = alpha_smp * vmim + beta_smp * vsim; - - ismp++; - } - - alpha1 = alpha2; - beta1 = beta2; - } - - return; -} - static void ps_pred_process_sf( MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, DECODER_TC_BUFFER_HANDLE hTcBuffer, @@ -1023,7 +730,12 @@ static void ivas_mc_paramupmix_dec_sf( /* Implement binaural rendering */ - ivas_binRenderer( st_ivas->hBinRenderer, st_ivas->hCombinedOrientationData, subframeIdx, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer_subfr, Cldfb_ImagBuffer_subfr ); + ivas_binRenderer( st_ivas->hBinRenderer, + st_ivas->hCombinedOrientationData, + st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], + Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, + Cldfb_RealBuffer_subfr, + Cldfb_ImagBuffer_subfr ); /* Implement CLDFB synthesis */ @@ -1101,53 +813,6 @@ static void ivas_mc_paramupmix_dec_sf( } -static void paramupmix_td_decorr_process( - ivas_td_decorr_state_t *hTdDecorr[], /* i/o: SPAR Covar. decoder handle */ - float *pcm_in[], /* i : input audio channels */ - float **pp_out_pcm, /* o : output audio channels */ - const int16_t output_frame /* i : output frame length */ -) -{ - int16_t j, k; - int16_t offset; - float in_duck_gain[L_FRAME48k], out_duck_gain[L_FRAME48k]; - - offset = (int16_t) ( output_frame * FRAMES_PER_SEC * IVAS_DECORR_PARM_LOOKAHEAD_TAU ); - - /* Look-ahead delay */ - for ( k = 0; k < MC_PARAMUPMIX_COMBINATIONS; k++ ) - { - mvr2r( pcm_in[k], pp_out_pcm[k], output_frame ); - delay_signal( pp_out_pcm[k], output_frame, hTdDecorr[k]->look_ahead_buf, offset ); - - /* In ducking gains */ - if ( hTdDecorr[k]->ducking_flag ) - { - ivas_td_decorr_get_ducking_gains( hTdDecorr[k]->pTrans_det, pcm_in[k], in_duck_gain, out_duck_gain, output_frame, 0 ); - - for ( j = 0; j < output_frame; j++ ) - { - pp_out_pcm[k][j] = pp_out_pcm[k][j] * in_duck_gain[j]; - } - } - - /* All pass delay section */ - ivas_td_decorr_APD_iir_filter( &hTdDecorr[k]->APD_filt_state[0], pp_out_pcm[k], hTdDecorr[k]->num_apd_sections, output_frame ); - - /* Out ducking gains */ - if ( hTdDecorr[k]->ducking_flag ) - { - for ( j = 0; j < output_frame; j++ ) - { - pp_out_pcm[k][j] = pp_out_pcm[k][j] * out_duck_gain[j]; - } - } - } - - return; -} - - static int16_t huff_read( Decoder_State *st, const int16_t ( *ht )[2] ) @@ -1168,92 +833,57 @@ static int16_t huff_read( static void huffman_decode( Decoder_State *st, - const int16_t nv, - const int16_t ivStart, const PAR_TYPE parType, - const QUANT_TYPE quant_type, - const int16_t bNoDt, int32_t *vq ) { const int16_t( *huff_node_table )[2]; - int16_t iv, bdt, nquant, offset; + int16_t iv, nquant, offset; nquant = 0; switch ( parType ) { case ALPHA: - nquant = ivas_mc_paramupmix_alpha_quant_table[quant_type].nquant; + nquant = ivas_mc_paramupmix_alpha_quant_table.nquant; break; case BETA: - nquant = ivas_mc_paramupmix_beta_quant_table[quant_type][0].nquant; + nquant = ivas_mc_paramupmix_beta_quant_table[0].nquant; break; default: assert( 0 ); } - offset = nquant - 1; /* range of df/dt [-(nquant - 1), nquant - 1] */ + offset = nquant - 1; /* range of df [-(nquant - 1), nquant - 1] */ - if ( bNoDt ) + st->next_bit_pos++; + switch ( parType ) { - bdt = 0; + case ALPHA: + huff_node_table = ivas_mc_paramupmix_huff_nodes_df0.alpha; + break; + case BETA: + huff_node_table = ivas_mc_paramupmix_huff_nodes_df0.beta; + break; + default: + huff_node_table = NULL; + assert( 0 ); } - else + vq[0] = huff_read( st, huff_node_table ); + + switch ( parType ) { - bdt = st->bit_stream[st->next_bit_pos]; - st->next_bit_pos++; + case ALPHA: + huff_node_table = ivas_mc_paramupmix_huff_nodes_df.alpha; + break; + case BETA: + huff_node_table = ivas_mc_paramupmix_huff_nodes_df.beta; + break; + default: + assert( 0 ); } - if ( bdt ) - { /* Get dt */ - switch ( parType ) - { - case ALPHA: - huff_node_table = ivas_mc_paramupmix_huff_nodes_dt.alpha[quant_type]; - break; - case BETA: - huff_node_table = ivas_mc_paramupmix_huff_nodes_dt.beta[quant_type]; - break; - default: - huff_node_table = NULL; - assert( 0 ); - } - for ( iv = ivStart; iv < nv; iv++ ) - { - vq[iv] = huff_read( st, huff_node_table ) + vq[iv] - offset; - } - } - else /* Get f0, df */ + for ( iv = 1; iv < IVAS_MAX_NUM_BANDS; iv++ ) { - switch ( parType ) - { - case ALPHA: - huff_node_table = ivas_mc_paramupmix_huff_nodes_df0.alpha[quant_type]; - break; - case BETA: - huff_node_table = ivas_mc_paramupmix_huff_nodes_df0.beta[quant_type]; - break; - default: - huff_node_table = NULL; - assert( 0 ); - } - vq[ivStart] = huff_read( st, huff_node_table ); - - switch ( parType ) - { - case ALPHA: - huff_node_table = ivas_mc_paramupmix_huff_nodes_df.alpha[quant_type]; - break; - case BETA: - huff_node_table = ivas_mc_paramupmix_huff_nodes_df.beta[quant_type]; - break; - default: - assert( 0 ); - } - - for ( iv = ivStart + 1; iv < nv; iv++ ) - { - vq[iv] = huff_read( st, huff_node_table ) + vq[iv - 1] - offset; - } + vq[iv] = huff_read( st, huff_node_table ) + vq[iv - 1] - offset; } return; @@ -1261,21 +891,13 @@ static void huffman_decode( static void dequant_alpha( - const int16_t nv, - const int16_t ivStart, - const QUANT_TYPE quant_type, int32_t *vq, float *v ) { int16_t iv; - const ACPL_QUANT_TABLE *quant_table = &ivas_mc_paramupmix_alpha_quant_table[quant_type]; - - for ( iv = 0; iv < ivStart; iv++ ) - { - v[iv] = 0; - } + const ACPL_QUANT_TABLE *quant_table = &ivas_mc_paramupmix_alpha_quant_table; - for ( iv = ivStart; iv < nv; iv++ ) + for ( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) { v[iv] = quant_table->data[vq[iv]]; } @@ -1285,9 +907,6 @@ static void dequant_alpha( static void dequant_beta( - const int16_t nv, - const int16_t ivStart, - const QUANT_TYPE quant_type, int32_t *aq, int32_t *bq, float *beta ) @@ -1295,14 +914,9 @@ static void dequant_beta( int16_t iv; const ACPL_QUANT_TABLE *quant_table; - for ( iv = 0; iv < ivStart; iv++ ) - { - beta[iv] = 0; - } - - for ( iv = ivStart; iv < nv; iv++ ) + for ( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) { - quant_table = &ivas_mc_paramupmix_beta_quant_table[quant_type][ivas_param_upmx_mx_qmap[quant_type][aq[iv]]]; + quant_table = &ivas_mc_paramupmix_beta_quant_table[ivas_param_upmx_mx_qmap[aq[iv]]]; beta[iv] = quant_table->data[bq[iv]]; } @@ -1313,23 +927,20 @@ static void dequant_beta( static void get_ec_data( Decoder_State *st, const PAR_TYPE parType, - const QUANT_TYPE quant_type, - const int16_t nParBand, - const int16_t parBandStart, int32_t *parQ, int32_t *alphaQEnv, float ab[IVAS_MAX_NUM_BANDS] ) { - huffman_decode( st, nParBand, parBandStart, parType, quant_type, 0, parQ ); + huffman_decode( st, parType, parQ ); if ( parType == ALPHA ) { - dequant_alpha( nParBand, parBandStart, quant_type, parQ, ab ); - mvl2l( parQ, alphaQEnv, (int16_t) nParBand ); + dequant_alpha( parQ, ab ); + mvl2l( parQ, alphaQEnv, (int16_t) IVAS_MAX_NUM_BANDS ); } else { - dequant_beta( nParBand, parBandStart, quant_type, alphaQEnv, parQ, ab ); + dequant_beta( alphaQEnv, parQ, ab ); } return; diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 1f3809b1d..0212b00b5 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -685,19 +685,15 @@ static ivas_error ivas_mc_dec_reconfig( int16_t tc_granularity_new; AUDIO_CONFIG intern_config_old; IVAS_OUTPUT_SETUP hIntSetupOld; -#ifdef NONBE_FIX_839_MC_RS_CHANNEL_ALLOC int16_t nchan_out_buff_old, nchan_out_buff; -#endif error = IVAS_ERR_OK; ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; nchan_transport_old = st_ivas->nchan_transport; -#ifdef NONBE_FIX_839_MC_RS_CHANNEL_ALLOC nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); -#endif last_mc_mode = ivas_mc_mode_select( ivas_mc_map_output_config_to_mc_ls_setup( st_ivas->transport_config ), st_ivas->hDecoderConfig->last_ivas_total_brate ); /* NB: this assumes that LS config remains the same between frames */ - /* we have to temporally set the current mc_mode back to the previous one to make sure the following call to + /* temporally set the current mc_mode back to the previous one to make sure the following call to ivas_init_dec_get_num_cldfb_instances() returns the correct counts */ mc_mode = st_ivas->mc_mode; st_ivas->mc_mode = last_mc_mode; @@ -730,8 +726,7 @@ static ivas_error ivas_mc_dec_reconfig( /* side effect of the renderer selection can be a changed internal config */ ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->intern_config ); - if ( st_ivas->hDecoderConfig->Opt_5ms ) - { + /* transfer subframe info from DirAC or ParamMC to central tc buffer */ if ( last_mc_mode == MC_MODE_PARAMMC ) { @@ -755,7 +750,7 @@ static ivas_error ivas_mc_dec_reconfig( tc_granularity_new = ivas_jbm_dec_get_render_granularity( st_ivas->renderer_type, st_ivas->ivas_format, st_ivas->mc_mode, st_ivas->hDecoderConfig->output_Fs ); 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, &hIntSetupOld, last_mc_mode, ISM_MODE_NONE, nSamplesRendered, data ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, tc_granularity_new, renderer_type_old, intern_config_old, &hIntSetupOld, last_mc_mode, ISM_MODE_NONE, nSamplesRendered, data ) ) != IVAS_ERR_OK ) { return error; } @@ -768,7 +763,6 @@ static ivas_error ivas_mc_dec_reconfig( return error; } } - } if ( st_ivas->mc_mode == MC_MODE_MCT ) { @@ -1221,7 +1215,6 @@ static ivas_error ivas_mc_dec_reconfig( * JBM TC buffers *-----------------------------------------------------------------*/ - if ( st_ivas->hDecoderConfig->Opt_5ms == 1 ) { int16_t tc_nchan_full_new; DECODER_TC_BUFFER_HANDLE hTcBuffer; @@ -1265,7 +1258,6 @@ static ivas_error ivas_mc_dec_reconfig( return error; } } - /* transfer subframe info from central tc buffer to ParamMC or McMASA (DirAC) */ if ( st_ivas->hSpatParamRendCom != NULL ) { @@ -1285,46 +1277,17 @@ static ivas_error ivas_mc_dec_reconfig( } } -#ifdef NONBE_FIX_839_MC_RS_CHANNEL_ALLOC + /*-----------------------------------------------------------------* * floating-point output audio buffers *-----------------------------------------------------------------*/ - if ( !st_ivas->hDecoderConfig->Opt_5ms ) - { -#ifdef NONBE_FIX_839_MC_RS_CHANNEL_ALLOC nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) { return error; } -#else - int16_t nchan_out_buff, ch; - nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); - - if ( nchan_out_buff > nchan_out_buf_old ) - { - for ( ch = nchan_out_buf_old; ch < nchan_out_buff; ch++ ) - { - /* note: these are intra-frame heap memories */ - if ( ( st_ivas->p_output_f[ch] = (float *) malloc( ( 48000 / FRAMES_PER_SEC ) * sizeof( float ) ) ) == NULL ) /* note: 32000 == max internal sampling rate */ - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for floating-point output audio buffer!\n" ) ); - } - } - } - else - { - for ( ch = nchan_out_buff; ch < nchan_out_buf_old; ch++ ) - { - free( st_ivas->p_output_f[ch] ); - st_ivas->p_output_f[ch] = NULL; - } - } -#endif - } -#endif return error; } diff --git a/lib_dec/ivas_mdct_core_dec.c b/lib_dec/ivas_mdct_core_dec.c index 0f9d1c66c..7209018d1 100644 --- a/lib_dec/ivas_mdct_core_dec.c +++ b/lib_dec/ivas_mdct_core_dec.c @@ -267,8 +267,8 @@ static void dec_prm_tcx_spec( *-----------------------------------------------------------------*/ void ivas_mdct_dec_side_bits_frame_channel( - CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ - int16_t param_lpc[MCT_MAX_CHANNELS][NPRM_LPC_NEW], /* o : lpc_parameters */ + CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ + int16_t param_lpc[CPE_CHANNELS][NPRM_LPC_NEW], /* o : lpc_parameters */ int16_t p_param[CPE_CHANNELS][NB_DIV], /* o : pointer to param buffer */ Decoder_State *st0, /* i : pointer to bitstream handle */ int16_t nTnsBitsTCX10[CPE_CHANNELS][NB_DIV], /* o : number of bits for TNS */ diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index 939eac3f0..c05cd617a 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -95,11 +95,8 @@ ivas_error ivas_td_binaural_renderer( ism_md_subframe_update = 2; } - return ivas_td_binaural_renderer_unwrap( st_ivas->hReverb, st_ivas->transport_config, st_ivas->hBinRendererTd, nchan_transport, LFE_CHANNEL, st_ivas->ivas_format, st_ivas->hIsmMetaData, - ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->enableCombinedOrientation : NULL, - ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->Quaternions : NULL, - ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->listenerPos : NULL, - ism_md_subframe_update, output, output_frame, MAX_PARAM_SPATIAL_SUBFRAMES ); + return ivas_td_binaural_renderer_unwrap( st_ivas->hReverb, st_ivas->transport_config, st_ivas->hBinRendererTd, nchan_transport, LFE_CHANNEL, st_ivas->ivas_format, st_ivas->hIsmMetaData, st_ivas->hCombinedOrientationData, ism_md_subframe_update, output, output_frame, MAX_PARAM_SPATIAL_SUBFRAMES ); + } @@ -218,9 +215,10 @@ ivas_error ivas_td_binaural_renderer_sf( /* Update the listener's location/orientation */ if ( ( error = TDREND_Update_listener_orientation( st_ivas->hBinRendererTd, - ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] : 0, - ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->Quaternions : NULL, - ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->listenerPos : NULL ) ) != IVAS_ERR_OK ) + ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] : 0, + ( st_ivas->hCombinedOrientationData != NULL ) ? &st_ivas->hCombinedOrientationData->Quaternions[st_ivas->hCombinedOrientationData->subframe_idx] : NULL, + ( st_ivas->hCombinedOrientationData != NULL ) ? &st_ivas->hCombinedOrientationData->listenerPos[st_ivas->hCombinedOrientationData->subframe_idx] : NULL + ) ) != IVAS_ERR_OK ) { return error; } @@ -258,9 +256,14 @@ ivas_error ivas_td_binaural_renderer_sf( { output_f_local[ch] += output_frame; } + + /* update combined orientation access index */ + ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, output_frame ); } st_ivas->hTcBuffer->subframes_rendered = last_sf; return IVAS_ERR_OK; } + + diff --git a/lib_dec/ivas_omasa_dec.c b/lib_dec/ivas_omasa_dec.c index dfa867ac0..6bf9cdfdd 100644 --- a/lib_dec/ivas_omasa_dec.c +++ b/lib_dec/ivas_omasa_dec.c @@ -46,7 +46,6 @@ #define OMASA_TDREND_MATCHING_GAIN 0.7943f - /*-------------------------------------------------------------------* * ivas_omasa_data_open() * @@ -172,11 +171,7 @@ ivas_error ivas_omasa_dec_config( ivas_format_orig = st_ivas->ivas_format; st_ivas->ivas_format = st_ivas->last_ivas_format; ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old ); -#ifdef NONBE_FIX_839_MC_RS_CHANNEL_ALLOC nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); -#else - nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); -#endif st_ivas->ivas_format = ivas_format_orig; @@ -385,41 +380,14 @@ ivas_error ivas_omasa_dec_config( * floating-point output audio buffers *-----------------------------------------------------------------*/ - if ( !st_ivas->hDecoderConfig->Opt_5ms ) - { -#ifdef NONBE_FIX_839_MC_RS_CHANNEL_ALLOC nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); - if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) { return error; } -#else - nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); - - if ( nchan_out_buff > nchan_out_buff_old ) - { - for ( k = nchan_out_buff_old; k < nchan_out_buff; k++ ) - { - /* note: these are intra-frame heap memories */ - if ( ( st_ivas->p_output_f[k] = (float *) malloc( ( 48000 / FRAMES_PER_SEC ) * sizeof( float ) ) ) == NULL ) /* note: 32000 == max internal sampling rate */ - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for floating-point output audio buffer!\n" ) ); - } - } - } - else - { - for ( k = nchan_out_buff; k < nchan_out_buff_old; k++ ) - { - free( st_ivas->p_output_f[k] ); - st_ivas->p_output_f[k] = NULL; - } - } -#endif - } } + return IVAS_ERR_OK; } @@ -585,45 +553,6 @@ ivas_error ivas_omasa_ism_metadata_dec( } -/*--------------------------------------------------------------------------* - * ivas_omasa_dirac_rend() - * - * Rendering in OMASA format - *--------------------------------------------------------------------------*/ - -void ivas_omasa_dirac_rend( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* o : output synthesis signal */ - const int16_t output_frame /* i : output frame length per channel */ -) -{ - int16_t n, dirac_read_idx; - float data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k]; - - if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) - { - mvr2r( output[2], data_separated_objects[0], output_frame ); - } - else - { - for ( n = 0; n < st_ivas->nchan_ism; n++ ) - { - mvr2r( output[n + 2], data_separated_objects[n], output_frame ); - } - } - - dirac_read_idx = st_ivas->hSpatParamRendCom->dirac_read_idx; - - ivas_dirac_dec( st_ivas, output, st_ivas->nchan_transport, MAX_PARAM_SPATIAL_SUBFRAMES ); - - st_ivas->hSpatParamRendCom->dirac_read_idx = dirac_read_idx; /* Original read index is needed for the next function which will update it again */ - - ivas_omasa_separate_object_render( st_ivas, data_separated_objects, output, output_frame ); - - return; -} - - /*--------------------------------------------------------------------------* * ivas_omasa_dirac_rend_jbm() * @@ -641,65 +570,29 @@ void ivas_omasa_dirac_rend_jbm( { int16_t subframes_rendered; int16_t slots_rendered; - - subframes_rendered = st_ivas->hSpatParamRendCom->subframes_rendered; - slots_rendered = st_ivas->hSpatParamRendCom->slots_rendered; - - ivas_dirac_dec_render( st_ivas, nchan_transport, nSamplesAsked, nSamplesRendered, nSamplesAvailable, output_f ); - - ivas_omasa_separate_object_render_jbm( st_ivas, *nSamplesRendered, output_f, subframes_rendered, slots_rendered ); - - return; -} - - -/*--------------------------------------------------------------------------* - * ivas_omasa_dirac_td_binaural() - * - * Binaural rendering in OMASA format - *--------------------------------------------------------------------------*/ - -ivas_error ivas_omasa_dirac_td_binaural( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* o : output synthesis signal */ - const int16_t output_frame /* i : output frame length per channel */ -) -{ int16_t n; float data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k]; - float gain = OMASA_TDREND_MATCHING_GAIN; - ivas_error error; - float *p_sepobj[MAX_NUM_OBJECTS]; - for ( n = 0; n < MAX_NUM_OBJECTS; n++ ) - { - p_sepobj[n] = &data_separated_objects[n][0]; - } - - for ( n = 0; n < st_ivas->nchan_ism; n++ ) + if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) { - mvr2r( output[2 + n], data_separated_objects[n], output_frame ); - v_multc( data_separated_objects[n], gain, data_separated_objects[n], output_frame ); + mvr2r( output_f[CPE_CHANNELS], data_separated_objects[0], nSamplesAsked ); } - - for ( n = 0; n < st_ivas->nchan_ism; n++ ) + else { - delay_signal( data_separated_objects[n], output_frame, st_ivas->hMasaIsmData->delayBuffer[n], st_ivas->hMasaIsmData->delayBuffer_size ); + for ( n = 0; n < st_ivas->nchan_ism; n++ ) + { + mvr2r( output_f[n + CPE_CHANNELS], data_separated_objects[n], nSamplesAsked ); + } } - ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, output, st_ivas->nchan_transport, MAX_PARAM_SPATIAL_SUBFRAMES ); + subframes_rendered = st_ivas->hSpatParamRendCom->subframes_rendered; + slots_rendered = st_ivas->hSpatParamRendCom->slots_rendered; - if ( ( error = ivas_td_binaural_renderer( st_ivas, p_sepobj, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } + ivas_dirac_dec_render( st_ivas, nchan_transport, nSamplesAsked, nSamplesRendered, nSamplesAvailable, output_f ); - for ( n = 0; n < BINAURAL_CHANNELS; n++ ) - { - v_add( output[n], p_sepobj[n], output[n], output_frame ); - } + ivas_omasa_separate_object_render_jbm( st_ivas, *nSamplesRendered, data_separated_objects, output_f, subframes_rendered, slots_rendered ); - return IVAS_ERR_OK; + return; } @@ -747,11 +640,13 @@ ivas_error ivas_omasa_dirac_td_binaural_jbm( ivas_dirac_dec_binaural_render( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, nchan_transport, output_f ); + /* reset combined orientation access index before calling the td renderer */ + ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData ); + if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_sepobj, *nSamplesRendered ) ) != IVAS_ERR_OK ) { return error; } - for ( n = 0; n < BINAURAL_CHANNELS; n++ ) { v_add( output_f[n], p_sepobj[n], output_f[n], *nSamplesRendered ); diff --git a/lib_dec/ivas_osba_dec.c b/lib_dec/ivas_osba_dec.c index 8da8628e9..903839686 100644 --- a/lib_dec/ivas_osba_dec.c +++ b/lib_dec/ivas_osba_dec.c @@ -131,80 +131,25 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( { int16_t n; ivas_error error; - - if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, &output_f[2] ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, output_f, *nSamplesRendered ) ) != IVAS_ERR_OK ) - { - return error; - } - - for ( n = 0; n < BINAURAL_CHANNELS; n++ ) - { - int16_t i; - for ( i = 0; i < nSamplesAsked; i++ ) - { - output_f[n][i] = 0.5f * output_f[2 + n][i] + 0.5f * output_f[n][i]; - } - } - - return IVAS_ERR_OK; -} - - -/*--------------------------------------------------------------------------* - * ivas_osba_dirac_td_binaural() - * - * Binaural rendering in OSBA format - *--------------------------------------------------------------------------*/ - -ivas_error ivas_osba_dirac_td_binaural( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* o : output synthesis signal */ - const int16_t output_frame /* i : output frame length per channel */ -) -{ - int16_t n; - float data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k]; - ivas_error error; - float *p_sepobj[MAX_NUM_OBJECTS]; + float output_separated_objects[BINAURAL_CHANNELS][L_FRAME48k]; // VE2SB: TBV + float *p_sepobj[BINAURAL_CHANNELS]; int16_t channel_offset; - for ( n = 0; n < MAX_NUM_OBJECTS; n++ ) + for ( n = 0; n < BINAURAL_CHANNELS; n++ ) { - p_sepobj[n] = &data_separated_objects[n][0]; + p_sepobj[n] = &output_separated_objects[n][0]; } channel_offset = st_ivas->nchan_ism; - for ( n = 0; n < st_ivas->nchan_ism; n++ ) + if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, &output_f[channel_offset] ) ) != IVAS_ERR_OK ) { - mvr2r( output[n], data_separated_objects[n], output_frame ); + return error; } - { - for ( n = 0; n < st_ivas->nchan_ism; n++ ) - { - delay_signal( data_separated_objects[n], output_frame, st_ivas->hSbaIsmData->delayBuffer[n], st_ivas->hSbaIsmData->delayBuffer_size ); - } - } - if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) - { - if ( ( error = ivas_sba_upmixer_renderer( st_ivas, output, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else - { - ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, &output[channel_offset], st_ivas->nchan_transport, MAX_PARAM_SPATIAL_SUBFRAMES ); - } - if ( ( error = ivas_td_binaural_renderer( st_ivas, p_sepobj, output_frame ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_sepobj, *nSamplesRendered ) ) != IVAS_ERR_OK ) { return error; } @@ -212,12 +157,11 @@ ivas_error ivas_osba_dirac_td_binaural( for ( n = 0; n < BINAURAL_CHANNELS; n++ ) { int16_t i; - for ( i = 0; i < output_frame; i++ ) + for ( i = 0; i < nSamplesAsked; i++ ) { - output[n][i] = 0.5f * output[channel_offset + n][i] + 0.5f * p_sepobj[n][i]; + output_f[n][i] = 0.5f * output_f[channel_offset + n][i] + 0.5f * p_sepobj[n][i]; } } - return IVAS_ERR_OK; } @@ -252,62 +196,53 @@ ivas_error ivas_osba_ism_metadata_dec( return IVAS_ERR_OK; } - /*-------------------------------------------------------------------------* - * ivas_osba_render() + * ivas_osba_render_sf() * * Object + SBA rendering process. *-------------------------------------------------------------------------*/ -ivas_error ivas_osba_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output_f[], /* i/o: core-coder transport channels/object output */ - const int16_t output_frame /* i : output frame length per channel */ +ivas_error ivas_osba_render_sf( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ + uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ + uint16_t *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ + float *p_output[] /* o : rendered time signal */ ) { - float tmp_ism_out[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - float *p_tmp_ism_out[MAX_OUTPUT_CHANNELS]; - int16_t n, nchan_out, nchan_ism; + int16_t n; + float output_ism[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + float *p_output_ism[MAX_OUTPUT_CHANNELS]; ivas_error error; - nchan_out = st_ivas->hDecoderConfig->nchan_out; - nchan_ism = st_ivas->nchan_ism; - - for ( n = 0; n < max( nchan_out, nchan_ism ); n++ ) + for ( n = 0; n < MAX_OUTPUT_CHANNELS; n++ ) { - p_tmp_ism_out[n] = &tmp_ism_out[n][0]; + p_output_ism[n] = &output_ism[n][0]; } - if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + for ( n = 0; n < st_ivas->nchan_ism; n++ ) { - for ( n = 0; n < nchan_ism; n++ ) - { - mvr2r( output_f[n], tmp_ism_out[n], output_frame ); - delay_signal( tmp_ism_out[n], output_frame, st_ivas->hSbaIsmData->delayBuffer[n], st_ivas->hSbaIsmData->delayBuffer_size ); - } - - if ( st_ivas->renderer_type == RENDERER_OSBA_AMBI ) - { - ivas_ism2sba( p_tmp_ism_out, st_ivas->hIsmRendererData, st_ivas->hIsmMetaData, st_ivas->nchan_ism, output_frame, st_ivas->hIntSetup.ambisonics_order ); - } - else - { - ivas_ism_render( st_ivas, p_tmp_ism_out, output_frame ); - } + mvr2r( p_output[n], output_ism[n], nSamplesAsked ); } - if ( ( error = ivas_sba_upmixer_renderer( st_ivas, output_f, output_frame ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailableNext, p_output ) ) != IVAS_ERR_OK ) { return error; } - if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + if ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV_ROOM ) { - for ( n = 0; n < nchan_out; n++ ) + ivas_ism_render_sf( st_ivas, p_output_ism, *nSamplesRendered ); + } + + for ( n = 0; n < st_ivas->hDecoderConfig->nchan_out; n++ ) + { + if ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV_ROOM ) { - v_add( output_f[n + nchan_ism], tmp_ism_out[n], output_f[n], output_frame ); - v_multc( output_f[n], 0.5f, output_f[n], output_frame ); + v_add( p_output[n], p_output_ism[n], p_output[n], *nSamplesRendered ); } + + v_multc( p_output[n], 0.5f, p_output[n], *nSamplesRendered ); } return IVAS_ERR_OK; diff --git a/lib_dec/ivas_qmetadata_dec.c b/lib_dec/ivas_qmetadata_dec.c index 17dfbfb49..011a16d81 100644 --- a/lib_dec/ivas_qmetadata_dec.c +++ b/lib_dec/ivas_qmetadata_dec.c @@ -963,6 +963,25 @@ int16_t ivas_qmetadata_dec_decode_hr_384_512( } } } + + /* Scale energy ratios that sum to over one */ + for ( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ ) + { + for ( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ ) + { + float ratioSum; + + ratioSum = hQMetaData->q_direction[0].band_data[b].energy_ratio[m] + hQMetaData->q_direction[1].band_data[b].energy_ratio[m]; + + if ( ratioSum > 1.0f ) + { + float ratioSumInv; + ratioSumInv = 1.0f / ratioSum; + hQMetaData->q_direction[0].band_data[b].energy_ratio[m] *= ratioSumInv; + hQMetaData->q_direction[1].band_data[b].energy_ratio[m] *= ratioSumInv; + } + } + } } /* Store status information for renderer use */ diff --git a/lib_dec/ivas_rom_dec.c b/lib_dec/ivas_rom_dec.c index 2bcf76c3f..0ab45b6f1 100644 --- a/lib_dec/ivas_rom_dec.c +++ b/lib_dec/ivas_rom_dec.c @@ -376,16 +376,6 @@ const uint16_t * const sym_freq_ECSQ_tab_abs_lsbs[1 + 4] = * DirAC ROM tables *----------------------------------------------------------------------------------*/ -const float ls_azimuth_4d4[8] = { 45.0f, -45.0f, 135.0f, -135.0f, 45.0f, -45.0f, 135.0f, -135.0f }; - -const float ls_elevation_4d4[8] = { 0.0f, 0.0f, 0.0f, 0.0f, 35.0f, 35.0f, 35.0f, 35.0f }; - -const float diffuse_response_CICP6[5] = { 0.4219f, 0.4219f, 0.3704f, 0.5034f, 0.5034f }; - -const float diffuse_response_CICP14[7] = { 0.3817f, 0.3817f, 0.2819f, 0.5399f, 0.5399f, 0.1519f, 0.1519f }; - -const float diffuse_response_CICP16[9] = { 0.3456f, 0.3456f, 0.3035f, 0.4124f, 0.4124f, 0.2702f, 0.2702f, 0.3023f, 0.3023f }; - const float dirac_dithering_azi_scale[DIRAC_DIFFUSE_LEVELS] = { @@ -397,136 +387,6 @@ const float dirac_dithering_ele_scale[DIRAC_DIFFUSE_LEVELS] = 6.716062e-01f, 1.011804e+00f, 1.796875e+00f, 2.804382e+00f, 4.623130e+00f, 7.802667e+00f, 1.045446e+01f, 1.379538e+01f }; -const int16_t ap_pre_delay[DIRAC_DECORR_NUM_SPLIT_BANDS] = { 7, 2, 1 }; - -const int16_t ap_filter_length[DIRAC_DECORR_NUM_SPLIT_BANDS] = { 15, 6, 3 }; - -const float ap_lattice_delta_phi[DIRAC_MAX_NUM_DECORR_FILTERS*DIRAC_MAX_DECORR_FILTER_LEN] = -{ - 1.802519f, 0.922986f, 1.813685f, 1.272828f, 0.856928f, 0.366571f, 1.531249f, 1.318158f, 0.123812f, 0.897173f, 0.958696f, 1.256384f, 0.179677f, 0.668918f, 1.440292f, 1.573058f, 1.396481f, 1.191463f, 0.444143f, 1.666942f, - 1.273955f, 1.747171f, 1.408330f, 1.002782f, 1.559302f, 1.782992f, 1.474896f, 0.813181f, 1.457724f, 0.588531f, 1.384302f, 0.156493f, 0.600048f, 1.661632f, 0.538958f, 0.645429f, 0.565237f, 0.024684f, 0.264229f, 0.062140f, - 1.235343f, 0.851725f, 1.820211f, 0.116148f, 0.972111f, 0.488703f, 1.777672f, 1.452170f, 0.814134f, 1.272649f, 1.281416f, 0.101871f, 0.897888f, 0.199760f, 0.085732f, 1.686579f, 0.964558f, 0.057281f, 0.910252f, 1.662302f, - 0.955234f, 0.834348f, 1.672478f, 1.324896f, 0.444544f, 1.721172f, 0.153356f, 1.602240f, 0.171880f, 1.169774f, 0.543628f, 1.409581f, 1.763724f, 1.686754f, 1.210390f, 0.402691f, 0.983618f, 0.862997f, 1.220409f, 0.890061f, - 0.031641f, 0.461590f, 1.719550f, 1.357698f, 1.112262f, 1.166531f, 0.246097f, 1.387325f, 0.177485f, 1.446268f, 0.799476f, 1.667227f, 1.723465f, 1.505920f, 0.245874f, 1.155854f, 0.831394f, 0.677194f, 0.568871f, 1.652070f, - 0.019803f, 1.197794f, 0.635553f, 0.531682f, 0.878194f, 0.048050f, 0.080480f, 1.566743f, 0.724210f, 0.853668f, 1.741191f, 0.698465f, 1.553550f, 0.130290f, 0.688346f, 1.331091f, 0.599759f, 1.125466f, 1.764818f, 1.042879f, - 1.486589f, 1.627971f, 1.871181f, 0.102359f, 0.035021f, 1.403176f, 1.468675f, 0.190347f, 0.553282f, 1.031227f, 1.232390f, 1.255724f, 1.504443f, 0.683526f, 0.600958f, 1.746936f, 1.529243f, 1.448196f, 0.646850f, 0.116053f, - 1.283295f, 0.355220f, 1.380620f, 1.858453f, 0.818804f, 0.219006f, 0.476292f, 0.420029f, 1.291187f, 0.568738f, 1.174088f, 0.628805f, 1.753154f, 1.459582f, 1.354449f, 1.755790f, 0.441757f, 0.856240f, 1.647962f, 0.686353f, - 1.395289f, 0.699934f, 0.239310f, 0.239535f, 0.958190f, 0.748780f, 0.513784f, 1.666344f, 1.461995f, 1.599060f, 0.893107f, 0.341873f, 1.387703f, 1.808363f, 0.676542f, 1.424958f, 0.310574f, 0.836247f, 1.011101f, 1.686200f, - 1.823432f, 0.994827f, 1.635555f, 0.684380f, 1.017029f, 1.440371f, 1.694641f, 0.607132f, 1.197331f, 0.862161f, 0.666449f, 1.047956f, 0.159627f, 0.043131f, 1.251515f, 1.618724f, 0.216906f, 0.152250f, 0.471610f, 0.744260f, - 0.576810f, 1.632177f, 1.556912f, 1.866317f, 0.568088f, 1.541817f, 1.726725f, 0.275154f, 0.814958f, 0.863399f, 1.333040f, 0.148277f, 0.197893f, 1.048665f, 1.158090f, 1.692225f, 0.884294f, 0.289619f, 0.380633f, 1.728234f, - 1.433213f, 1.749505f, 1.533837f, 0.669701f, 0.372580f, 1.052390f, 1.116645f, 0.181320f, 1.139126f, 0.222671f, 0.604393f, 1.811797f, 1.743315f, 1.368792f, 1.861434f, 0.751908f, 0.159811f, 1.566503f, 0.443273f, 1.667530f, - 1.083060f, 1.243136f, 0.717777f, 0.675019f, 0.690490f, 0.672228f, 1.060789f, 0.423566f, 1.198457f, 0.485768f, 0.993953f, 0.443540f, 0.361702f, 1.552042f, 0.863562f, 1.517677f, 1.061899f, 0.691413f, 1.642818f, 1.756590f, - 0.278323f, 0.790363f, 0.172303f, 0.417138f, 0.009343f, 0.783325f, 1.369303f, 1.041067f, 0.467102f, 0.992773f, 1.525170f, 0.871213f, 0.243906f, 1.542036f, 0.449148f, 0.843633f, 0.191800f, 1.614246f, 1.038188f, 1.415620f, - 0.551081f, 0.382599f, 1.410121f, 0.102084f, 0.137286f, 0.671081f, 0.254860f, 1.758068f, 1.079013f, 0.129143f, 1.410873f, 0.150485f, 0.601119f, 0.760737f, 0.975905f, 0.223261f, 0.710162f, 1.677048f, 0.996836f, 1.849865f, - 1.536222f, 0.089016f, 0.960881f, 0.388690f, 0.379955f, 1.002223f, 1.271420f, 1.410632f, 0.254397f, 1.535559f, 1.133703f, 1.305280f, 1.466565f, 0.274167f, 0.399688f, 1.359638f, 1.766289f, 1.401348f, 1.310883f, 0.261030f, - 1.314825f, 1.538635f, 1.317986f, 1.243167f, 1.749461f, 1.689706f, 0.024853f, 0.634754f, 1.036317f, 1.828101f, 1.676951f, 0.023606f, 0.857000f, 0.076471f, 1.622198f, 0.254469f, 1.451625f, 1.720881f, 0.763812f, 0.186982f, - 0.056994f, 0.590507f, 0.375291f, 1.609261f, 0.607721f, 0.026355f, 0.483366f, 0.823931f, 0.792878f, 0.163577f, 0.753588f, 0.730789f, 0.135991f, 1.031660f, 1.554135f, 1.192863f, 0.016693f, 0.125796f, 1.017920f, 1.591773f, - 0.575956f, 0.112943f, 0.249506f, 1.399570f, 0.053241f, 1.410759f, 0.251638f, 1.059086f, 0.025315f, 1.422914f, 1.030412f, 0.848758f, 0.317396f, 1.375456f, 1.116858f, 1.682310f, 0.279550f, 0.325974f, 0.937704f, 1.744329f, - 0.447773f, 1.024286f, 1.001528f, 1.863684f, 1.278323f, 0.860699f, 1.346331f, 1.692596f, 0.022627f, 1.033613f, 0.546354f, 0.395804f, 1.486546f, 1.381045f, 1.312260f, 0.245976f, 1.607429f, 1.818793f, 0.964359f, 1.496598f, - 0.669967f, 1.535929f, 1.841878f, 0.979127f, 0.614002f, 1.879218f, 0.512531f, 1.167061f, 0.081697f, 1.773427f, 1.535668f, 0.757729f, 0.220395f, 1.538243f, 1.281162f, 0.302159f, 0.889871f, 0.798522f, 1.476288f, 1.665941f, - 0.915365f, 1.394094f, 0.757041f, 0.350064f, 1.199679f, 1.319499f, 1.128405f, 0.632337f, 0.790673f, 0.461582f, 1.693343f, 1.537442f, 0.346527f, 0.433782f, 1.754552f, 0.550903f, 0.686724f, 0.764433f, 1.792750f, 1.489998f -}; - -const float ap_lattice_coeffs_1[DIRAC_DECORR_FILTER_LEN_1*DIRAC_MAX_NUM_DECORR_FILTERS] = -{ - 0.795329f, 0.502700f, 0.204456f, 0.416566f, 0.459648f, 0.270454f, -0.201944f, 0.027997f, 0.067811f, -0.052627f, -0.038779f, -0.057387f, 0.020480f, 0.367697f, -0.593705f, - 0.533667f, 0.202500f, -0.001953f, 0.195081f, -0.184458f, -0.233867f, 0.228100f, -0.329293f, -0.338714f, -0.079700f, 0.052389f, -0.009468f, 0.178807f, 0.190843f, -0.478877f, - 0.044022f, 0.788498f, 0.133529f, -0.173657f, 0.545391f, 0.681431f, 0.332868f, 0.294685f, 0.325261f, 0.047617f, 0.157401f, 0.116272f, 0.218980f, -0.189248f, -0.317401f, - -0.753681f, 0.772385f, -0.507384f, 0.276980f, -0.692775f, 0.232302f, -0.354759f, -0.015620f, -0.223059f, 0.310506f, -0.035034f, 0.085783f, -0.499998f, 0.215260f, 0.201415f, - -0.495551f, -0.301660f, 0.196510f, 0.326147f, -0.594364f, 0.314921f, 0.668671f, 0.076643f, 0.045711f, -0.124790f, -0.203272f, -0.297190f, 0.125806f, -0.179483f, -0.201757f, - 0.161128f, 0.396050f, 0.266897f, 0.356586f, 0.488145f, -0.056254f, 0.139280f, -0.296405f, -0.112844f, 0.037405f, -0.367425f, -0.216292f, -0.277360f, 0.389420f, 0.115115f, - -0.240449f, -0.271015f, 0.426720f, -0.011059f, 0.151813f, 0.253490f, 0.225764f, 0.498716f, -0.136377f, 0.443004f, -0.305017f, -0.031310f, -0.010765f, 0.170349f, 0.496478f, - -0.139875f, -0.241998f, -0.104850f, 0.294343f, -0.067728f, -0.492202f, -0.487610f, 0.036395f, 0.109393f, 0.396155f, -0.352845f, -0.205913f, -0.082999f, -0.463033f, -0.309296f, - 0.025886f, -0.092456f, -0.125139f, -0.156117f, -0.004887f, 0.178440f, 0.089586f, 0.044827f, 0.238219f, -0.312120f, -0.390688f, -0.178543f, 0.454418f, 0.387012f, -0.388874f, - -0.197797f, 0.035540f, 0.455388f, -0.054410f, 0.380035f, 0.290964f, 0.048804f, 0.078637f, 0.221740f, -0.217548f, 0.121289f, -0.396681f, -0.218482f, -0.127265f, -0.269507f, - -0.344218f, -0.465038f, -0.421415f, -0.026031f, 0.221547f, 0.361993f, -0.348243f, 0.294983f, 0.366175f, 0.070663f, -0.086050f, 0.252129f, 0.156066f, -0.062800f, 0.408972f, - 0.242461f, -0.301764f, -0.066160f, 0.388651f, -0.462227f, -0.158880f, 0.230796f, -0.093179f, 0.047076f, 0.073402f, -0.335018f, 0.022940f, 0.354611f, 0.072391f, 0.019473f, - 0.336900f, -0.480534f, 0.170267f, 0.259663f, -0.393576f, -0.348588f, -0.108962f, 0.278842f, 0.385490f, 0.362249f, -0.318739f, 0.362305f, 0.288936f, 0.291204f, -0.278019f, - -0.449302f, -0.288513f, -0.413973f, -0.405279f, -0.295152f, -0.245110f, 0.002530f, 0.287890f, 0.348229f, -0.178354f, -0.206517f, 0.351081f, -0.482205f, 0.021360f, -0.492207f, - 0.048642f, 0.453282f, 0.109160f, 0.232599f, -0.473781f, 0.140502f, 0.352527f, -0.098606f, 0.147172f, -0.055797f, 0.107739f, -0.231026f, 0.357310f, 0.348031f, 0.232404f, - -0.324788f, 0.162480f, 0.057647f, -0.060734f, -0.009742f, -0.224185f, -0.282355f, -0.065443f, 0.064697f, 0.280370f, -0.284906f, -0.470501f, 0.019484f, -0.442308f, 0.377214f, - 0.447384f, -0.290498f, 0.345528f, 0.370207f, -0.313120f, 0.119592f, 0.300014f, 0.406995f, -0.277922f, 0.447039f, 0.194824f, 0.157703f, -0.223402f, -0.147167f, 0.379073f, - -0.216342f, 0.137967f, -0.397180f, 0.073905f, -0.273110f, -0.443037f, -0.168327f, 0.346264f, 0.037543f, 0.065387f, 0.163901f, -0.122523f, 0.365477f, -0.316321f, 0.117273f, - -0.301282f, 0.169625f, -0.336466f, 0.269914f, -0.420160f, -0.331296f, 0.498523f, -0.393009f, -0.462184f, -0.323097f, 0.470977f, -0.359463f, 0.264315f, 0.216797f, 0.493400f, - 0.151489f, -0.321653f, 0.464413f, -0.355673f, 0.420401f, 0.184297f, -0.302128f, 0.136536f, -0.252849f, 0.193906f, 0.298775f, 0.238808f, -0.386298f, -0.181999f, -0.077326f, - 0.124840f, -0.263394f, 0.389606f, 0.004502f, 0.339804f, 0.415204f, 0.377751f, 0.400221f, 0.352426f, -0.003808f, -0.184530f, 0.433348f, -0.237554f, 0.147684f, 0.407210f, - 0.067616f, -0.249313f, -0.354010f, 0.320937f, 0.426000f, 0.309576f, -0.189689f, -0.209447f, 0.158967f, -0.081929f, 0.386828f, 0.178582f, -0.407143f, 0.222189f, -0.149097f -}; - -const float ap_lattice_coeffs_2[DIRAC_DECORR_FILTER_LEN_2*DIRAC_MAX_NUM_DECORR_FILTERS] = -{ - 0.633692f, 0.681207f, -0.049418f, 0.286715f, 0.146022f, 0.135402f, - -0.410145f, -0.206766f, -0.656968f, -0.101746f, 0.436299f, 0.339818f, - -0.131383f, -0.773746f, -0.301627f, 0.327561f, 0.332227f, 0.205858f, - 0.717602f, -0.552370f, -0.150136f, 0.054556f, 0.239519f, -0.648477f, - -0.721848f, 0.189377f, 0.068185f, 0.006216f, 0.077025f, 0.038678f, - 0.423415f, -0.108658f, 0.432050f, -0.414641f, 0.277840f, 0.418486f, - 0.077811f, -0.283063f, -0.357008f, 0.004634f, -0.442640f, -0.372315f, - 0.403336f, 0.243023f, 0.314367f, 0.444513f, 0.347517f, 0.496043f, - 0.108408f, 0.469382f, -0.170286f, 0.326310f, 0.172157f, 0.440334f, - 0.058417f, 0.339673f, -0.194965f, 0.491219f, -0.281296f, -0.043120f, - -0.482487f, -0.335005f, -0.336159f, 0.196469f, -0.164623f, 0.442491f, - -0.135190f, -0.354385f, 0.452133f, -0.311221f, -0.347640f, 0.498342f, - -0.288999f, 0.376431f, -0.177924f, 0.195542f, 0.333872f, -0.152697f, - 0.053230f, 0.457767f, 0.442476f, 0.235254f, -0.345159f, -0.286098f, - 0.155438f, 0.405393f, 0.217073f, -0.107960f, 0.010698f, 0.368987f, - -0.498358f, -0.495816f, -0.215479f, -0.093869f, 0.320276f, -0.013842f, - 0.489406f, 0.470814f, -0.065834f, 0.346871f, 0.027279f, 0.150086f, - 0.484013f, -0.497391f, 0.168796f, -0.493841f, -0.173528f, 0.334676f, - 0.264235f, -0.424651f, -0.314926f, 0.253086f, 0.397381f, -0.491565f, - -0.453727f, -0.463358f, -0.019128f, 0.000344f, 0.315432f, 0.472345f, - 0.095139f, 0.283375f, -0.225088f, -0.119762f, -0.476871f, 0.037525f, - 0.336951f, 0.494511f, -0.062603f, 0.177652f, 0.463892f, 0.489286f -}; - -const float ap_lattice_coeffs_3[DIRAC_DECORR_FILTER_LEN_3*DIRAC_MAX_NUM_DECORR_FILTERS] = -{ - 0.018977f, -0.212205f, 0.422719f, - -0.400657f, -0.106890f, -0.024589f, - 0.140005f, 0.279582f, 0.032357f, - 0.632535f, 0.578535f, -0.734606f, - 0.017182f, 0.013244f, -0.027715f, - -0.353356f, -0.482160f, -0.491265f, - 0.457024f, 0.165122f, 0.469723f, - -0.195705f, 0.440105f, -0.477366f, - 0.360186f, -0.490565f, 0.484623f, - -0.173791f, 0.007543f, 0.278186f, - 0.434416f, 0.060363f, -0.193717f, - -0.033709f, 0.496222f, 0.002939f, - -0.480848f, -0.109552f, -0.023198f, - 0.324679f, -0.292075f, -0.356148f, - -0.366595f, 0.380917f, -0.301741f, - 0.110318f, 0.383789f, 0.303984f, - -0.499685f, -0.349584f, 0.334749f, - -0.020224f, -0.430078f, -0.154705f, - -0.371129f, 0.334080f, 0.346913f, - -0.166781f, -0.229089f, 0.117956f, - 0.341292f, 0.490463f, 0.493655f, - -0.367726f, 0.426528f, -0.045774f -}; - -const float * const ap_lattice_coeffs[DIRAC_DECORR_NUM_SPLIT_BANDS] = -{ - &ap_lattice_coeffs_1[0], - &ap_lattice_coeffs_2[0], - &ap_lattice_coeffs_3[0], -}; - -const float ap_split_frequencies[DIRAC_DECORR_NUM_SPLIT_BANDS + 1] = -{ - 0.0f, 0.125f, 0.375f, 1.0f -}; - -const int16_t sba_map_tc[11] = -{ - 0, 1, 2, 3, 4, 8, 9, 15, 5, 6, 7 -}; -const int16_t sba_map_tc_512[11] = -{ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15 -}; - - /*----------------------------------------------------------------------------------* * FASTCONV and PARAMETRIC binaural renderer ROM tables *----------------------------------------------------------------------------------*/ @@ -581,27 +441,6 @@ static const int16_t huff_nodes_first_band_alpha[32][2] = { -2, -32 } }; -/* Alpha Coarse Huffman table df0 */ -static const int16_t huff_nodes_first_band_alpha_coarse[16][2] = -{ - { -9, 1 }, - { -8, 2 }, - { -10, 3 }, - { 5, 4 }, - { -7, 6 }, - { -11, 7 }, - { -5, 8 }, - { -6, 9 }, - { -12, 10 }, - { -13, 11 }, - { -4, 12 }, - { -14, 13 }, - { -3, 14 }, - { -15, 15 }, - { -2, -16 }, - { -1, -17 } -}; - /* Alpha Fine Huffman table df */ static const int16_t huff_nodes_alpha_1D_DF[64][2] = { @@ -671,43 +510,6 @@ static const int16_t huff_nodes_alpha_1D_DF[64][2] = { -2, -62 } }; -/* Alpha Coarse Huffman table df */ -static const int16_t huff_nodes_alpha_1D_DF_coarse[32][2] = -{ - { -17, 1 }, - { -18, 2 }, - { -16, 3 }, - { -15, 4 }, - { -19, 5 }, - { 7, 6 }, - { -14, -20 }, - { 9, 8 }, - { -13, -21 }, - { 11, 10 }, - { -22, 12 }, - { -12, 13 }, - { -23, 14 }, - { -11, 15 }, - { -10, 16 }, - { -24, 17 }, - { -9, -25 }, - { 19, 18 }, - { -26, 20 }, - { -8, 21 }, - { 23, 22 }, - { 25, 24 }, - { -27, 26 }, - { -7, 27 }, - { -1, -33 }, - { -6, 28 }, - { -28, 29 }, - { -29, 30 }, - { -5, -31 }, - { -30, 31 }, - { -3, -4 }, - { -2, -32 } -}; - /* Alpha Fine Huffman table dt */ static const int16_t huff_nodes_alpha_1D_DT[64][2] = { @@ -777,95 +579,42 @@ static const int16_t huff_nodes_alpha_1D_DT[64][2] = { -2, -63 } }; -/* Alpha Coarse Huffman table dt */ -static const int16_t huff_nodes_alpha_1D_DT_coarse[32][2] = -{ - { -17, 1 }, - { -18, 2 }, - { -16, 3 }, - { -19, 4 }, - { -15, 5 }, - { 7, 6 }, - { -14, -20 }, - { 9, 8 }, - { -21, 10 }, - { -13, 11 }, - { 13, 12 }, - { -12, -22 }, - { 15, 14 }, - { -11, -23 }, - { 17, 16 }, - { -24, 18 }, - { -10, 19 }, - { -25, 20 }, - { -9, 21 }, - { 23, 22 }, - { -26, 24 }, - { -8, 25 }, - { 27, 26 }, - { -1, -33 }, - { -7, -27 }, - { 29, 28 }, - { -28, 30 }, - { -6, 31 }, - { -5, -29 }, - { -3, -31 }, - { -4, -30 }, - { -2, -32 } -}; - /* Beta Fine Huffman table df0 */ static const int16_t huff_nodes_first_band_beta[8][2] = { { -1, 1 }, { -2, 2 }, { -3, 3 }, { -4, 4 }, { -5, 5 }, { -6, 6 }, { -7, 7 }, { -8, -9 } }; -/* Beta Coarse Huffman table df0 */ -static const int16_t huff_nodes_first_band_beta_coarse[4][2] = -{ - { -1, 1 }, { -2, 2 }, { -3, 3 }, { -4, -5 } -}; - /* Beta Fine Huffman table df */ static const int16_t huff_nodes_beta_1D_DF[16][2] = { { -9, 1 }, { -10, 2 }, { -8, 3 }, { -11, 4 }, { -7, 5 }, { 7, 6 }, { -6, -12 }, { 9, 8 }, { -5, -13 }, { 11, 10 }, { -4, -14 }, { -15, 12 }, { -3, 13 }, { -16, 14 }, { -2, 15 }, { -1, -17 } }; -/* Beta Coarse Huffman table df */ -static const int16_t huff_nodes_beta_1D_DF_coarse[8][2] = -{ - { -5, 1 }, { -6, 2 }, { -4, 3 }, { -3, 4 }, { -7, 5 }, { -2, 6 }, { -8, 7 }, { -1, -9 } -}; - /* Beta Fine Huffman table dt */ static const int16_t huff_nodes_beta_1D_DT[16][2] = { { -9, 1 }, { -10, 2 }, { -8, 3 }, { -11, 4 }, { -7, 5 }, { 7, 6 }, { -6, -12 }, { -13, 8 }, { -5, 9 }, { -14, 10 }, { -4, 11 }, { -15, 12 }, { -3, 13 }, { -16, 14 }, { -2, 15 }, { -1, -17 } }; -/* Beta Coarse Huffman table dt */ -static const int16_t huff_nodes_beta_1D_DT_coarse[8][2] = -{ - { -5, 1 }, { -6, 2 }, { -4, 3 }, { -7, 4 }, { -3, 5 }, { -8, 6 }, { -2, 7 }, { -1, -9 } -}; const HUFF_NODE_TABLE ivas_mc_paramupmix_huff_nodes_df0 = { - { huff_nodes_first_band_alpha, huff_nodes_first_band_alpha_coarse }, - { huff_nodes_first_band_beta, huff_nodes_first_band_beta_coarse } + huff_nodes_first_band_alpha, + huff_nodes_first_band_beta }; const HUFF_NODE_TABLE ivas_mc_paramupmix_huff_nodes_df = { - { huff_nodes_alpha_1D_DF, huff_nodes_alpha_1D_DF_coarse }, - { huff_nodes_beta_1D_DF, huff_nodes_beta_1D_DF_coarse } + huff_nodes_alpha_1D_DF, + huff_nodes_beta_1D_DF }; const HUFF_NODE_TABLE ivas_mc_paramupmix_huff_nodes_dt = { - { huff_nodes_alpha_1D_DT, huff_nodes_alpha_1D_DT_coarse }, - { huff_nodes_beta_1D_DT, huff_nodes_beta_1D_DT_coarse } + huff_nodes_alpha_1D_DT, + huff_nodes_beta_1D_DT }; + /* clang-format on */ diff --git a/lib_dec/ivas_rom_dec.h b/lib_dec/ivas_rom_dec.h index 24e06eb98..4ff133596 100644 --- a/lib_dec/ivas_rom_dec.h +++ b/lib_dec/ivas_rom_dec.h @@ -89,27 +89,10 @@ extern const uint16_t *const sym_freq_ECSQ_tab_abs_lsbs[1 + 4]; * DirAC ROM tables *----------------------------------------------------------------------------------*/ -extern const float ls_azimuth_4d4[8]; -extern const float ls_elevation_4d4[8]; -extern const float diffuse_response_CICP6[5]; -extern const float diffuse_response_CICP14[7]; -extern const float diffuse_response_CICP16[9]; - extern const float dirac_dithering_azi_scale[DIRAC_DIFFUSE_LEVELS]; extern const float dirac_dithering_ele_scale[DIRAC_DIFFUSE_LEVELS]; -extern const int16_t ap_pre_delay[DIRAC_DECORR_NUM_SPLIT_BANDS]; -extern const int16_t ap_filter_length[DIRAC_DECORR_NUM_SPLIT_BANDS]; -extern const float ap_lattice_delta_phi[DIRAC_MAX_NUM_DECORR_FILTERS * DIRAC_MAX_DECORR_FILTER_LEN]; -extern const float ap_lattice_coeffs_1[DIRAC_DECORR_FILTER_LEN_1 * DIRAC_MAX_NUM_DECORR_FILTERS]; -extern const float ap_lattice_coeffs_2[DIRAC_DECORR_FILTER_LEN_2 * DIRAC_MAX_NUM_DECORR_FILTERS]; -extern const float ap_lattice_coeffs_3[DIRAC_DECORR_FILTER_LEN_3 * DIRAC_MAX_NUM_DECORR_FILTERS]; -extern const float *const ap_lattice_coeffs[DIRAC_DECORR_NUM_SPLIT_BANDS]; -extern const float ap_split_frequencies[DIRAC_DECORR_NUM_SPLIT_BANDS + 1]; - -extern const int16_t sba_map_tc[11]; -extern const int16_t sba_map_tc_512[11]; /*----------------------------------------------------------------------------------* * FASTCONV and PARAMETRIC binaural renderer ROM tables @@ -119,7 +102,6 @@ extern const float dmxmtx_table[BINAURAL_CHANNELS][11]; - /*----------------------------------------------------------------------* * MC ParamUpmix ROM tables *-----------------------------------------------------------------------*/ diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 991fb0658..3be1d2ff3 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -110,12 +110,7 @@ ivas_error ivas_sba_dec_reconfigure( int32_t ivas_total_brate; int32_t last_ivas_total_brate; int16_t num_channels, num_md_sub_frames; -#ifdef NONBE_FIX_839_MC_RS_CHANNEL_ALLOC int16_t nchan_out_buff, nchan_out_buff_old; -#else - int16_t ch, nchan_out_buff, nchan_out_buff_old; -#endif - int16_t sba_analysis_order_old; int16_t sba_analysis_order_old_flush; DECODER_CONFIG_HANDLE hDecoderConfig; ivas_error error; @@ -127,14 +122,14 @@ ivas_error ivas_sba_dec_reconfigure( ivas_total_brate = hDecoderConfig->ivas_total_brate; last_ivas_total_brate = st_ivas->last_active_ivas_total_brate; sba_analysis_order_old_flush = st_ivas->sba_analysis_order; - sba_analysis_order_old = ivas_sba_get_analysis_order( last_ivas_total_brate, st_ivas->sba_order ); /*-----------------------------------------------------------------* * Set SBA high-level parameters * Save old SBA high-level parameters *-----------------------------------------------------------------*/ - nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, sba_analysis_order_old, last_ivas_total_brate ); + nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, sba_analysis_order_old_flush, last_ivas_total_brate ); + ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old ); nchan_hp20_old = getNumChanSynthesis( st_ivas ); @@ -229,6 +224,13 @@ ivas_error ivas_sba_dec_reconfigure( { return error; } + + /* make sure the changed number of slots in the last subframe is not lost in the following steps */ + if ( st_ivas->hSpatParamRendCom != NULL ) + { + st_ivas->hSpatParamRendCom->subframe_nbslots[st_ivas->hSpatParamRendCom->nb_subframes - 1] = st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->nb_subframes - 1]; + } + st_ivas->hSpar->subframe_nbslots[st_ivas->hSpar->nb_subframes - 1] = st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->nb_subframes - 1]; } } @@ -368,7 +370,10 @@ ivas_error ivas_sba_dec_reconfigure( ivas_mono_dmx_renderer_close( &st_ivas->hMonoDmxRenderer ); } - if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) + , + st_ivas->ivas_format + ) ) != IVAS_ERR_OK ) { return error; } @@ -557,7 +562,6 @@ ivas_error ivas_sba_dec_reconfigure( * JBM TC buffers *-----------------------------------------------------------------*/ - if ( st_ivas->hDecoderConfig->Opt_5ms == 1 || st_ivas->ivas_format == SBA_ISM_FORMAT ) { int16_t tc_nchan_to_allocate; int16_t tc_nchan_tc; @@ -611,19 +615,15 @@ ivas_error ivas_sba_dec_reconfigure( } /* resync SPAR and DirAC JBM info from TC Buffer */ - if ( st_ivas->hSpatParamRendCom != NULL ) + if ( st_ivas->hSpatParamRendCom != NULL && st_ivas->hSpatParamRendCom->slot_size == st_ivas->hTcBuffer->n_samples_granularity ) { - if ( st_ivas->hSpatParamRendCom->slot_size == st_ivas->hTcBuffer->n_samples_granularity ) - { - mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hSpatParamRendCom->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); - st_ivas->hSpatParamRendCom->nb_subframes = st_ivas->hTcBuffer->nb_subframes; - st_ivas->hSpatParamRendCom->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered; - - mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hSpar->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); - st_ivas->hSpar->nb_subframes = st_ivas->hTcBuffer->nb_subframes; - st_ivas->hSpar->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered; - } + mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hSpatParamRendCom->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); + st_ivas->hSpatParamRendCom->nb_subframes = st_ivas->hTcBuffer->nb_subframes; + st_ivas->hSpatParamRendCom->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered; } + mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hSpar->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); + st_ivas->hSpar->nb_subframes = st_ivas->hTcBuffer->nb_subframes; + st_ivas->hSpar->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered; if ( st_ivas->ivas_format == SBA_ISM_FORMAT && st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { @@ -632,6 +632,7 @@ ivas_error ivas_sba_dec_reconfigure( for ( n = 0; n < MAX_JBM_SUBFRAMES_5MS; n++ ) { st_ivas->hSpatParamRendCom->subframe_nbslots[n] = st_ivas->hTcBuffer->subframe_nbslots[n] * granularityMultiplier; + st_ivas->hSpar->subframe_nbslots[n] = st_ivas->hSpatParamRendCom->subframe_nbslots[n]; } } @@ -639,39 +640,14 @@ ivas_error ivas_sba_dec_reconfigure( * floating-point output audio buffers *-----------------------------------------------------------------*/ - if ( !st_ivas->hDecoderConfig->Opt_5ms ) - { nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); -#ifdef NONBE_FIX_839_MC_RS_CHANNEL_ALLOC if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) { return error; } -#else - if ( nchan_out_buff > nchan_out_buff_old ) - { - for ( ch = nchan_out_buff_old; ch < nchan_out_buff; ch++ ) - { - /* note: these are intra-frame heap memories */ - if ( ( st_ivas->p_output_f[ch] = (float *) malloc( ( 48000 / FRAMES_PER_SEC ) * sizeof( float ) ) ) == NULL ) /* note: 32000 == max internal sampling rate */ - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for floating-point output audio buffer!\n" ) ); - } - } - } - else - { - for ( ch = nchan_out_buff; ch < nchan_out_buff_old; ch++ ) - { - free( st_ivas->p_output_f[ch] ); - st_ivas->p_output_f[ch] = NULL; - } - } -#endif - } - return IVAS_ERR_OK; + return error; } @@ -806,6 +782,9 @@ ivas_error ivas_sba_dec_render( { output_f_local[ch] += n_samples_sf; } + + /* update combined orientation access index */ + ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); } if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC ) diff --git a/lib_dec/ivas_sba_dirac_stereo_dec.c b/lib_dec/ivas_sba_dirac_stereo_dec.c index 19f3e656c..d8487479f 100644 --- a/lib_dec/ivas_sba_dirac_stereo_dec.c +++ b/lib_dec/ivas_sba_dirac_stereo_dec.c @@ -923,5 +923,11 @@ void ivas_sba_dirac_stereo_dec( } } + /* reset the other channels to 0 (they are not used since here) */ + for ( int16_t ch = CPE_CHANNELS; ch < st_ivas->nchan_transport; ch++ ) + { + set_zero( output[ch], output_frame ); + } + return; } diff --git a/lib_dec/ivas_sba_rendering_internal.c b/lib_dec/ivas_sba_rendering_internal.c index 6d0c73eb5..692e1a4cf 100644 --- a/lib_dec/ivas_sba_rendering_internal.c +++ b/lib_dec/ivas_sba_rendering_internal.c @@ -327,71 +327,9 @@ int16_t ivas_sba_remapTCs( } -/*-------------------------------------------------------------------------* - * ivas_ism2sba() - * - * ISM transformed into SBA in TD domain. - *-------------------------------------------------------------------------*/ - -void ivas_ism2sba( - float *buffer_td[], /* i/o: TD signal buffers */ - ISM_RENDERER_HANDLE hIsmRendererData, /* i/o: renderer data */ - const ISM_METADATA_HANDLE hIsmMetaData[], /* i : object metadata */ - const int16_t nchan_ism, /* i : number of objects */ - const int16_t output_frame, /* i : output frame length per channel */ - const int16_t sba_order /* i : Ambisonic (SBA) order */ -) -{ - int16_t i, j, k; - float buffer_tmp[16][L_FRAME48k]; - float gains[16]; - float g1, g2; - int16_t azimuth, elevation; - int16_t sba_num_chans; - - assert( ( sba_order <= 3 ) && "Only order up to 3 is supported!" ); - assert( hIsmRendererData != NULL && "hIsmRendererData not allocated!" ); - - /* Init*/ - sba_num_chans = ( sba_order + 1 ) * ( sba_order + 1 ); - for ( j = 0; j < sba_num_chans; j++ ) - { - set_zero( buffer_tmp[j], output_frame ); - } - - for ( i = 0; i < nchan_ism; i++ ) - { - // TODO tmu review when #215 is resolved - azimuth = (int16_t) floorf( hIsmMetaData[i]->azimuth + 0.5f ); - elevation = (int16_t) floorf( hIsmMetaData[i]->elevation + 0.5f ); - - /*get HOA gets for direction (ACN/SN3D)*/ - ivas_dirac_dec_get_response( azimuth, elevation, gains, sba_order ); - - for ( j = 0; j < sba_num_chans; j++ ) - { - g1 = 1.f; - g2 = 0.f; - for ( k = 0; k < output_frame; k++ ) - { - buffer_tmp[j][k] += ( g2 * gains[j] + g1 * hIsmRendererData->prev_gains[i][j] ) * buffer_td[i][k]; - g2 += 1.f / ( output_frame - 1 ); - g1 = 1.0f - g2; - } - hIsmRendererData->prev_gains[i][j] = gains[j]; - } - } - - for ( j = 0; j < sba_num_chans; j++ ) - { - mvr2r( buffer_tmp[j], buffer_td[j], output_frame ); - } - - return; -} /*-------------------------------------------------------------------------* - * ivas_ism2sba() + * ivas_ism2sba_sf() * * ISM transformed into SBA in TD domain. *-------------------------------------------------------------------------*/ @@ -408,15 +346,17 @@ void ivas_ism2sba_sf( { int16_t i, j, k; float g1, *g2, *tc, *out, gain, prev_gain; + float buffer_tmp[HOA3_CHANNELS][L_FRAME48k]; // VE2SB: TBV int16_t sba_num_chans; assert( ( sba_order <= 3 ) && "Only order up to 3 is supported!" ); assert( hIsmRendererData != NULL && "hIsmRendererData not allocated!" ); + /* Init*/ sba_num_chans = ( sba_order + 1 ) * ( sba_order + 1 ); for ( j = 0; j < sba_num_chans; j++ ) { - set_zero( buffer_out[j], n_samples_to_render ); + set_zero( buffer_tmp[j], n_samples_to_render ); } for ( i = 0; i < num_objects; i++ ) @@ -425,7 +365,7 @@ void ivas_ism2sba_sf( { g2 = hIsmRendererData->interpolator + offset; tc = buffer_in[i] + offset; - out = buffer_out[j]; + out = buffer_tmp[j]; gain = hIsmRendererData->gains[i][j]; prev_gain = hIsmRendererData->prev_gains[i][j]; for ( k = 0; k < n_samples_to_render; k++ ) @@ -436,58 +376,12 @@ void ivas_ism2sba_sf( } } - return; -} - -/*-------------------------------------------------------------------* - * ivas_sba_upmixer_renderer() - * - * SBA upmix & rendering - *-------------------------------------------------------------------*/ - -ivas_error ivas_sba_upmixer_renderer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ - float *output[], /* i/o: transport/output audio channels */ - const int16_t output_frame /* i : output frame length */ -) -{ - int16_t nchan_internal; - int16_t sba_ch_idx; - ivas_error error; - - push_wmops( "ivas_sba_upmixer_renderer" ); - nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); - - /* Upmixer + Renderer */ - ivas_spar_dec_upmixer( st_ivas, output, nchan_internal, output_frame ); - - if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC ) + for ( j = 0; j < sba_num_chans; j++ ) { - float *output_f[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; - int16_t ch; - AUDIO_CONFIG output_config; - - output_config = ( st_ivas->ivas_format == SBA_ISM_FORMAT ? st_ivas->hOutSetup.output_config : st_ivas->hDecoderConfig->output_config ); - - sba_ch_idx = 0; - if ( st_ivas->ivas_format == SBA_ISM_FORMAT && st_ivas->ism_mode == ISM_SBA_MODE_DISC ) - { - sba_ch_idx = st_ivas->nchan_ism; - } - - for ( ch = 0; ch < ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ) - sba_ch_idx; ch++ ) - { - output_f[ch] = output[ch]; - } - - if ( ( error = ivas_sba_linear_renderer( output_f, output_frame, st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->nchan_ism, output_config, st_ivas->hOutSetup ) ) != IVAS_ERR_OK ) - { - return error; - } + mvr2r( buffer_tmp[j], buffer_out[j], n_samples_to_render ); } - pop_wmops(); - return IVAS_ERR_OK; + return; } diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index 147f195dd..ab913d08b 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -72,6 +72,7 @@ ivas_error ivas_spar_dec_open( int16_t num_decor_chs, map_idx; error = IVAS_ERR_OK; + sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); num_channels_internal = ivas_sba_get_nchan_metadata( sba_order_internal, st_ivas->hDecoderConfig->ivas_total_brate ); @@ -208,7 +209,7 @@ ivas_error ivas_spar_dec_open( } /* allocate transport channels*/ - if ( ( st_ivas->hDecoderConfig->Opt_5ms || st_ivas->ivas_format == SBA_ISM_FORMAT ) && st_ivas->hTcBuffer == NULL ) + if ( st_ivas->hTcBuffer == NULL ) { int16_t nchan_to_allocate; int16_t nchan_tc; @@ -251,13 +252,6 @@ ivas_error ivas_spar_dec_open( granularity = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ); } - /* make sure we have a TC buffer with the correct granularity for rate switching in OSBA */ - if ( !st_ivas->hDecoderConfig->Opt_5ms ) - { - nchan_tc = 0; - nchan_to_allocate = 0; - } - if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, buffer_mode, nchan_tc, nchan_to_allocate, nchan_to_allocate, granularity ) ) != IVAS_ERR_OK ) { return error; @@ -1053,6 +1047,8 @@ static void ivas_spar_calc_smooth_facs( float *cldfb_in_ts_re[CLDFB_NO_COL_MAX], float *cldfb_in_ts_im[CLDFB_NO_COL_MAX], int16_t nbands_spar, + const int16_t nSlots, + const int16_t isFirstSubframe, ivas_fb_bin_to_band_data_t *bin2band, float *smooth_fac, float smooth_buf[IVAS_MAX_NUM_BANDS][2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1] ) @@ -1074,15 +1070,22 @@ static void ivas_spar_calc_smooth_facs( subframe_band_nrg[b] = 0.f; while ( bin < CLDFB_NO_CHANNELS_MAX && b == bin2band->p_cldfb_map_to_spar_band[bin] ) { - for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) + for ( ts = 0; ts < nSlots; ts++ ) { subframe_band_nrg[b] += cldfb_in_ts_re[ts][bin] * cldfb_in_ts_re[ts][bin] + cldfb_in_ts_im[ts][bin] * cldfb_in_ts_im[ts][bin]; } bin++; } subframe_band_nrg[b] = sqrtf( subframe_band_nrg[b] ); - smooth_buf[b][0] = subframe_band_nrg[b]; - + if ( isFirstSubframe && nSlots < MAX_PARAM_SPATIAL_SUBFRAMES ) + { + /* fill up to full 5ms subframe */ + smooth_buf[b][0] += subframe_band_nrg[b]; + } + else + { + smooth_buf[b][0] = subframe_band_nrg[b]; + } /* calculate short and long energy averages */ smooth_short_avg[b] = EPSILON; for ( i = 0; i < 2 * SBA_DIRAC_NRG_SMOOTH_SHORT; i++ ) @@ -1119,14 +1122,17 @@ static void ivas_spar_calc_smooth_facs( smooth_fac[b] = max( min_smooth_gains1[b], min( max_smooth_gains2[b], smooth_fac[b] ) ); } - for ( b = 0; b < nbands_spar; b++ ) + /* only update if we collected a full 5ms worth of energies for the buffer */ + if ( isFirstSubframe || nSlots == MAX_PARAM_SPATIAL_SUBFRAMES ) { - for ( i = 2 * SBA_DIRAC_NRG_SMOOTH_LONG; i > 0; i-- ) + for ( b = 0; b < nbands_spar; b++ ) { - smooth_buf[b][i] = smooth_buf[b][i - 1]; + for ( i = 2 * SBA_DIRAC_NRG_SMOOTH_LONG; i > 0; i-- ) + { + smooth_buf[b][i] = smooth_buf[b][i - 1]; + } } } - return; } @@ -1440,6 +1446,9 @@ void ivas_spar_dec_upmixer( { output_f_local[n] += n_samples_sf; } + + /* update combined orientation access index */ + ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); } for ( n = 0; n < nchan_internal_total; n++ ) @@ -1617,7 +1626,7 @@ void ivas_spar_dec_upmixer_sf( if ( ( hDecoderConfig->ivas_total_brate < IVAS_24k4 ) && ( ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_HOA2 ) || ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_HOA3 ) ) ) { - ivas_spar_calc_smooth_facs( cldfb_in_ts_re[0], cldfb_in_ts_im[0], num_spar_bands, &hSpar->hFbMixer->pFb->fb_bin_to_band, hSpar->hMdDec->smooth_fac, hSpar->hMdDec->smooth_buf ); + ivas_spar_calc_smooth_facs( cldfb_in_ts_re[0], cldfb_in_ts_im[0], num_spar_bands, hSpar->subframe_nbslots[hSpar->subframes_rendered], hSpar->subframes_rendered == 0, &hSpar->hFbMixer->pFb->fb_bin_to_band, hSpar->hMdDec->smooth_fac, hSpar->hMdDec->smooth_buf ); } for ( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec.c index e109e00d3..42ea099a6 100644 --- a/lib_dec/ivas_spar_md_dec.c +++ b/lib_dec/ivas_spar_md_dec.c @@ -73,13 +73,15 @@ static void ivas_spar_dec_compute_ramp_down_post_matrix( ivas_spar_md_dec_state_ static void ivas_spar_md_fill_invalid_bands( ivas_spar_dec_matrices_t *pSpar_coeffs, ivas_spar_dec_matrices_t *pSpar_coeffs_prev, const int16_t *valid_bands, int16_t *base_band_age, const int16_t num_bands, const int16_t numch_out, const int16_t num_md_sub_frames ); +static void ivas_spar_md_fill_invalid_bandcoeffs( ivas_band_coeffs_t *pBand_coeffs, ivas_band_coeffs_t *pBand_coeffs_prev, const int16_t *valid_bands, int16_t *base_band_age, int16_t *first_valid_frame, const int16_t num_bands ); static ivas_error ivas_spar_set_dec_config( ivas_spar_md_dec_state_t *hMdDec, const int16_t nchan_transport, float *pFC ); static void ivas_parse_parameter_bitstream_dtx( ivas_spar_md_t *pSpar_md, Decoder_State *st, const int16_t bw, const int16_t num_bands, int16_t *num_dmx_per_band, int16_t *num_dec_per_band ); static ivas_error ivas_deindex_real_index( const int16_t *index, const int16_t q_levels, const float min_value, const float max_value, float *quant, const int16_t num_ch_dim2 ); -static void ivas_spar_dec_parse_md_bs( ivas_spar_md_dec_state_t *hMdDec, Decoder_State *st, int16_t *nB, int16_t *bands_bw, int16_t *dtx_vad, const int32_t ivas_total_brate, const int16_t sba_inactive_mode, const int32_t last_active_brate ); +static void ivas_spar_dec_parse_md_bs( ivas_spar_md_dec_state_t *hMdDec, Decoder_State *st, int16_t *nB, int16_t *bands_bw, int16_t *dtx_vad, const int32_t ivas_total_brate, const int16_t sba_inactive_mode +); /*------------------------------------------------------------------------- @@ -100,6 +102,10 @@ ivas_error ivas_spar_md_dec_matrix_open( { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for band_coeffs in SPAR MD" ); } + if ( ( hMdDec->band_coeffs_prev = (ivas_band_coeffs_t *) malloc( IVAS_MAX_NUM_BANDS * sizeof( ivas_band_coeffs_t ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for band_coeffs in SPAR MD" ); + } if ( ( hMdDec->mixer_mat = (float ***) malloc( num_channels * sizeof( float ** ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); @@ -362,6 +368,11 @@ void ivas_spar_md_dec_matrix_close( free( hMdDecoder->spar_md.band_coeffs ); hMdDecoder->spar_md.band_coeffs = NULL; } + if ( hMdDecoder->band_coeffs_prev != NULL ) + { + free( hMdDecoder->band_coeffs_prev ); + hMdDecoder->band_coeffs_prev = NULL; + } if ( hMdDecoder->mixer_mat != NULL ) { @@ -540,11 +551,13 @@ ivas_error ivas_spar_md_dec_init( /* initialize PLC state */ set_s( hMdDec->valid_bands, 0, IVAS_MAX_NUM_BANDS ); set_s( hMdDec->base_band_age, 0, IVAS_MAX_NUM_BANDS ); + set_s( hMdDec->base_band_coeffs_age, 0, IVAS_MAX_NUM_BANDS ); hMdDec->spar_plc_num_lost_frames = 0; hMdDec->spar_plc_enable_fadeout_flag = 1; hMdDec->dtx_md_smoothing_cntr = 1; ivas_clear_band_coeffs( hMdDec->spar_md.band_coeffs, IVAS_MAX_NUM_BANDS ); + ivas_clear_band_coeffs( hMdDec->band_coeffs_prev, IVAS_MAX_NUM_BANDS ); ivas_clear_band_coeff_idx( hMdDec->spar_md.band_coeffs_idx, IVAS_MAX_NUM_BANDS ); ivas_clear_band_coeff_idx( hMdDec->spar_md_prev.band_coeffs_idx, IVAS_MAX_NUM_BANDS ); ivas_clear_band_coeff_idx( hMdDec->spar_md_prev.band_coeffs_idx_mapped, IVAS_MAX_NUM_BANDS ); @@ -568,6 +581,7 @@ ivas_error ivas_spar_md_dec_init( set_zero( hMdDec->mixer_mat_prev2[i][j], IVAS_MAX_NUM_BANDS ); } } + hMdDec->first_valid_frame = 1; return IVAS_ERR_OK; } @@ -749,7 +763,18 @@ void ivas_spar_md_dec_process( } ivas_spar_dec_parse_md_bs( hMdDec, st0, &nB, &bw, &dtx_vad, st_ivas->hDecoderConfig->ivas_total_brate, - st_ivas->hQMetaData->sba_inactive_mode, st_ivas->last_active_ivas_total_brate ); + st_ivas->hQMetaData->sba_inactive_mode + ); + + assert( nB == hMdDec->spar_md.num_bands ); + assert( bw == 1 ); + ivas_spar_md_fill_invalid_bandcoeffs( + hMdDec->spar_md.band_coeffs, + hMdDec->band_coeffs_prev, + &hMdDec->valid_bands[0], + &hMdDec->base_band_coeffs_age[0], + &hMdDec->first_valid_frame, + nB ); ivas_dec_mono_sba_handling( st_ivas ); @@ -761,10 +786,6 @@ void ivas_spar_md_dec_process( /* set correct number of bands*/ nB = IVAS_MAX_NUM_BANDS; - if ( bw == IVAS_RED_BAND_FACT ) - { - nB = nB >> 1; - } /* expand DirAC MD to all time slots */ for ( i_ts = 1; i_ts < num_md_sub_frames; i_ts++ ) @@ -804,18 +825,9 @@ void ivas_spar_md_dec_process( fprintf( fid, "%.6f\n", hMdDec->mixer_mat[1][0][band] ); } #endif - if ( bw == IVAS_RED_BAND_FACT ) - { - nB = nB << 1; - } - - for ( b = nB; b < num_bands_out; b++ ) - { - hMdDec->valid_bands[b] = 1; - } - ivas_spar_md_fill_invalid_bands( &hMdDec->spar_coeffs, &hMdDec->spar_coeffs_prev, &hMdDec->valid_bands[0], &hMdDec->base_band_age[0], num_bands_out, num_md_chs, num_md_sub_frames ); + hMdDec->dtx_md_smoothing_cntr = 1; return; @@ -1406,6 +1418,47 @@ void ivas_spar_dec_gen_umx_mat( return; } +static void ivas_spar_md_band_upmix( + ivas_band_coeffs_t *band_coeffs, + int16_t *nB, + int16_t *bands_bw, + int16_t *valid_bands, + int16_t bw_final, + int16_t ndec, + int16_t ndm ) +{ + int16_t i, ii, jj, b, idx, bw_fact; + + bw_fact = *bands_bw / bw_final; + for ( i = *nB - 1; i >= 0; i-- ) + { + + for ( b = bw_fact - 1; b >= 0; b-- ) + { + idx = i * bw_fact + b; + for ( ii = 0; ii < ndec + ndm - 1; ii++ ) + { + band_coeffs[idx].pred_re[ii] = band_coeffs[i].pred_re[ii]; + } + for ( ii = 0; ii < ndec; ii++ ) + { + for ( jj = 0; jj < ndm - 1; jj++ ) + { + band_coeffs[idx].C_re[ii][jj] = band_coeffs[i].C_re[ii][jj]; + } + } + for ( jj = 0; jj < ndec; jj++ ) + { + band_coeffs[idx].P_re[jj] = band_coeffs[i].P_re[jj]; + } + valid_bands[idx] = valid_bands[i]; + } + } + *nB = ( *nB ) * ( *bands_bw ) / bw_final; + *bands_bw = bw_final; + + return; +} /*-----------------------------------------------------------------------------------------* * Function ivas_spar_dec_parse_md_bs() @@ -1420,19 +1473,17 @@ static void ivas_spar_dec_parse_md_bs( int16_t *bands_bw, int16_t *dtx_vad, const int32_t ivas_total_brate, - const int16_t sba_inactive_mode, - const int32_t last_active_brate ) + const int16_t sba_inactive_mode +) { int16_t i, j, k, num_bands; - int16_t ii, jj, ndec, ndm, b, idx; + int16_t ii, jj, ndec, ndm; uint16_t qsi; ivas_quant_strat_t qs; int16_t strat, no_ec; int16_t do_diff[IVAS_MAX_NUM_BANDS]; float quant[IVAS_SPAR_MAX_C_COEFF]; int16_t do_repeat[IVAS_MAX_NUM_BANDS]; - int16_t bw_final, bw_fact; - int32_t active_brate; *dtx_vad = 1; *bands_bw = 1; qsi = 0; @@ -1504,40 +1555,19 @@ static void ivas_spar_dec_parse_md_bs( ivas_parse_parameter_bitstream_dtx( &hMdDec->spar_md, st0, *bands_bw, *nB, hMdDec->spar_md_cfg.num_dmx_chans_per_band, hMdDec->spar_md_cfg.num_decorr_per_band ); - active_brate = ( ivas_total_brate > IVAS_SID_5k2 ) ? ivas_total_brate : last_active_brate; - - if ( active_brate >= IVAS_24k4 ) + if ( *bands_bw != 1 ) { - bw_final = 1; + ndec = hMdDec->spar_md_cfg.num_decorr_per_band[0]; + ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[0]; + ivas_spar_md_band_upmix( + hMdDec->spar_md.band_coeffs, + nB, + bands_bw, + hMdDec->valid_bands, + 1, + ndec, + ndm ); } - else - { - bw_final = 2; - } - - bw_fact = *bands_bw / bw_final; - - for ( i = *nB - 1; i >= 0; i-- ) - { - ndec = hMdDec->spar_md_cfg.num_decorr_per_band[bw_fact * i]; - - for ( b = bw_fact - 1; b >= 0; b-- ) - { - idx = i * bw_fact + b; - for ( j = 0; j < FOA_CHANNELS - 1; j++ ) - { - hMdDec->spar_md.band_coeffs[idx].pred_re[j] = hMdDec->spar_md.band_coeffs[i].pred_re[j]; - } - for ( j = 0; j < ndec; j++ ) - { - hMdDec->spar_md.band_coeffs[idx].P_re[j] = hMdDec->spar_md.band_coeffs[i].P_re[j]; - } - hMdDec->valid_bands[idx] = 1; - } - } - - *bands_bw = bw_final; - *nB = num_bands / bw_final; return; } @@ -1590,8 +1620,10 @@ static void ivas_spar_dec_parse_md_bs( do_diff[i] = ( ( ( i + 1 ) & 3 ) != strat - 4 ); do_repeat[i] = 0; } - - ivas_map_prior_coeffs_quant( &hMdDec->spar_md_prev, &hMdDec->spar_md_cfg, qsi, *nB ); + if ( hMdDec->spar_md_cfg.prev_quant_idx >= 0 ) + { + ivas_map_prior_coeffs_quant( &hMdDec->spar_md_prev, &hMdDec->spar_md_cfg, qsi, *nB ); + } } hMdDec->spar_md_cfg.prev_quant_idx = qsi; @@ -1648,13 +1680,24 @@ static void ivas_spar_dec_parse_md_bs( { hMdDec->spar_md_prev.band_coeffs_idx[i].decd_index_re[j] = hMdDec->spar_md.band_coeffs_idx[i].decd_index_re[j]; } - hMdDec->valid_bands[*bands_bw * i] |= ( do_diff[i] == 0 && do_repeat[i] == 0 ) ? 1 : 0; - for ( j = 1; j < *bands_bw; j++ ) - { - hMdDec->valid_bands[*bands_bw * i + j] = hMdDec->valid_bands[*bands_bw * i]; - } + hMdDec->valid_bands[i] |= ( do_diff[i] == 0 && do_repeat[i] == 0 ) ? 1 : 0; } + ndec = hMdDec->spar_md_cfg.num_decorr_per_band[0]; + ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[0]; + if ( *bands_bw != 1 ) + { + ivas_spar_md_band_upmix( + hMdDec->spar_md.band_coeffs, + nB, + bands_bw, + hMdDec->valid_bands, + 1, + ndec, + ndm ); + } + + return; } @@ -1926,31 +1969,21 @@ static void ivas_decode_huffman_bs( return; } - -/*-----------------------------------------------------------------------------------------* - * Function ivas_spar_md_fill_invalid_bands() - * - * Fill invalid bands in interpolation/extrapolation of valid bands - * when PLC is to be done with partial time differential coding - *-----------------------------------------------------------------------------------------*/ - -static void ivas_spar_md_fill_invalid_bands( - ivas_spar_dec_matrices_t *pSpar_coeffs, - ivas_spar_dec_matrices_t *pSpar_coeffs_prev, +static void ivas_spar_plc_get_band_age( const int16_t *valid_bands, int16_t *base_band_age, const int16_t num_bands, - const int16_t num_channels, - const int16_t num_md_sub_frames ) + int16_t last_valid_band_idx[IVAS_MAX_NUM_BANDS], + int16_t valid_band_idx[IVAS_MAX_NUM_BANDS], + int16_t *all_valid, + int16_t *b_idx ) { - int16_t i, j, b, all_valid; - int16_t valid_band_idx[IVAS_MAX_NUM_BANDS], idx = -1; - int16_t last_valid_band_idx[IVAS_MAX_NUM_BANDS]; - float w = 0; + int16_t b, idx; + set_s( valid_band_idx, 0, IVAS_MAX_NUM_BANDS ); set_s( last_valid_band_idx, 0, IVAS_MAX_NUM_BANDS ); - - all_valid = 1; + idx = -1; + *all_valid = 1; for ( b = 0; b < num_bands; b++ ) { if ( valid_bands[b] != 0 ) @@ -1967,10 +2000,65 @@ static void ivas_spar_md_fill_invalid_bands( { last_valid_band_idx[b] = idx; } - all_valid = 0; + *all_valid = 0; } } + *b_idx = idx; + + return; +} + +static void ivas_spar_get_plc_interp_weights( + int16_t valid_band_idx[IVAS_MAX_NUM_BANDS], + int16_t last_valid_band_idx, + int16_t idx, + int16_t b, + float *w, + int16_t *id0, + int16_t *id1 ) +{ + if ( last_valid_band_idx < 0 ) /* Extrapolation */ + { + *id1 = valid_band_idx[0]; + *id0 = 0; + *w = 1; + } + else if ( last_valid_band_idx == idx ) /* Extrapolation */ + { + *id1 = valid_band_idx[last_valid_band_idx]; + *id0 = valid_band_idx[last_valid_band_idx]; + *w = 0; + } + else /* Interpolation */ + { + *id0 = valid_band_idx[last_valid_band_idx]; + *id1 = valid_band_idx[last_valid_band_idx + 1]; + *w = ( (float) ( b - *id0 ) ) / ( *id1 - *id0 ); + } + return; +} +/*-----------------------------------------------------------------------------------------* + * Function ivas_spar_md_fill_invalid_bands() + * + * Fill invalid bands in interpolation/extrapolation of valid bands + * when PLC is to be done with partial time differential coding + *-----------------------------------------------------------------------------------------*/ +static void ivas_spar_md_fill_invalid_bands( + ivas_spar_dec_matrices_t *pSpar_coeffs, + ivas_spar_dec_matrices_t *pSpar_coeffs_prev, + const int16_t *valid_bands, + int16_t *base_band_age, + const int16_t num_bands, + const int16_t num_channels, + const int16_t num_md_sub_frames ) +{ + int16_t i, j, b, all_valid; + int16_t valid_band_idx[IVAS_MAX_NUM_BANDS], idx = -1; + int16_t last_valid_band_idx[IVAS_MAX_NUM_BANDS]; + float w = 0; + ivas_spar_plc_get_band_age( valid_bands, base_band_age, num_bands, + last_valid_band_idx, valid_band_idx, &all_valid, &idx ); assert( idx > 0 ); /* some bands should be valid */ if ( all_valid == 0 ) @@ -1980,28 +2068,9 @@ static void ivas_spar_md_fill_invalid_bands( /* check against non zero in if and else if */ if ( base_band_age[b] > 3 ) /* old invalid bands */ { - int16_t tmp_id, id0, id1; - - tmp_id = last_valid_band_idx[b]; - if ( tmp_id < 0 ) /* Extrapolation */ - { - id1 = valid_band_idx[0]; - id0 = 0; - w = 1; - } - else if ( tmp_id == idx ) /* Extrapolation */ - { - id1 = valid_band_idx[tmp_id]; - id0 = valid_band_idx[tmp_id]; - w = 0; - } - else /* Interpolation */ - { - id0 = valid_band_idx[tmp_id]; - id1 = valid_band_idx[tmp_id + 1]; - w = ( (float) ( b - id0 ) ) / ( id1 - id0 ); - } - + int16_t id0, id1; + ivas_spar_get_plc_interp_weights( valid_band_idx, last_valid_band_idx[b], + idx, b, &w, &id0, &id1 ); for ( i = 0; i < num_channels; i++ ) { for ( j = 0; j < num_channels; j++ ) @@ -2047,6 +2116,86 @@ static void ivas_spar_md_fill_invalid_bands( return; } +static void ivas_spar_md_fill_invalid_bandcoeffs( + ivas_band_coeffs_t *pBand_coeffs, + ivas_band_coeffs_t *pBand_coeffs_prev, + const int16_t *valid_bands, + int16_t *base_band_age, + int16_t *first_valid_frame, + const int16_t num_bands ) +{ + int16_t j, k, b, all_valid; + int16_t valid_band_idx[IVAS_MAX_NUM_BANDS], idx = -1; + int16_t last_valid_band_idx[IVAS_MAX_NUM_BANDS]; + float w = 0; + + ivas_spar_plc_get_band_age( valid_bands, base_band_age, num_bands, + last_valid_band_idx, valid_band_idx, &all_valid, &idx ); + + assert( idx > 0 ); /* some bands should be valid */ + + if ( all_valid == 0 ) + { + for ( b = 0; b < num_bands; b++ ) + { + /* check against non zero in if and else if */ + if ( ( base_band_age[b] > 3 ) || ( *first_valid_frame == 0 ) ) /* old invalid bands */ + { + int16_t id0, id1; + ivas_spar_get_plc_interp_weights( valid_band_idx, last_valid_band_idx[b], + idx, b, &w, &id0, &id1 ); + + for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) + { + pBand_coeffs[b].pred_re[j] = ( 1 - w ) * pBand_coeffs[id0].pred_re[j] + w * pBand_coeffs[id1].pred_re[j]; + } + + for ( j = 0; j < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; j++ ) + { + for ( k = 0; k < IVAS_SPAR_MAX_DMX_CHS - 1; k++ ) + { + pBand_coeffs[b].C_re[j][k] = ( 1 - w ) * pBand_coeffs[id0].C_re[j][k] + w * pBand_coeffs[id1].C_re[j][k]; + } + } + + for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) + { + pBand_coeffs[b].P_re[j] = ( 1 - w ) * pBand_coeffs[id0].P_re[j] + w * pBand_coeffs[id1].P_re[j]; + } + } + else /* young invalid bands */ + { + if ( valid_bands[b] == 0 ) + { + for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) + { + pBand_coeffs[b].pred_re[j] = pBand_coeffs_prev[b].pred_re[j]; + } + + for ( j = 0; j < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; j++ ) + { + for ( k = 0; k < IVAS_SPAR_MAX_DMX_CHS - 1; k++ ) + { + pBand_coeffs[b].C_re[j][k] = pBand_coeffs_prev[b].C_re[j][k]; + } + } + + for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) + { + pBand_coeffs[b].P_re[j] = pBand_coeffs_prev[b].P_re[j]; + } + } + } + } + } + else + { + *first_valid_frame = 1; + } + + return; +} + /*-----------------------------------------------------------------------------------------* * Function ivas_spar_dec_compute_ramp_down_post_matrix() diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index b4eef45cc..d350ec18c 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -603,7 +603,9 @@ typedef struct ivas_spar_md_dec_state_t float smooth_buf[IVAS_MAX_NUM_BANDS][2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1]; float smooth_fac[IVAS_MAX_NUM_BANDS]; float mixer_mat_prev2[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; - + int16_t first_valid_frame; + ivas_band_coeffs_t *band_coeffs_prev; + int16_t base_band_coeffs_age[IVAS_MAX_NUM_BANDS]; } ivas_spar_md_dec_state_t; @@ -904,16 +906,16 @@ typedef struct ivas_masa_ism_data_structure typedef struct decoder_tc_buffer_structure { - float *tc_buffer; /* the buffer itself */ - float *tc[MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS]; /* pointers into the buffer to the beginning of each tc */ - TC_BUFFER_MODE tc_buffer_mode; /* mode of the buffer (no buffering, render buffering, out buffering) */ - int16_t nchan_transport_jbm; /* number of TCs after TC decoding */ - int16_t nchan_transport_internal; /* total number of TC buffer channels, can include e.g. TD decorr data */ - int16_t nchan_buffer_full; /* number of channels to be fully buffered */ - int16_t n_samples_available; /* samples still available for rendering in the current frame */ - int16_t n_samples_buffered; /* full number of samples in the buffer (including spill to next frame) */ - int16_t n_samples_rendered; /* samples already rendered in the current frame */ - int16_t n_samples_granularity; /* render granularity */ + float *tc_buffer; /* the buffer itself */ + float *tc[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; /* pointers into the buffer to the beginning of each tc */ // VE2SB: TBV + TC_BUFFER_MODE tc_buffer_mode; /* mode of the buffer (no buffering, render buffering, out buffering) */ + int16_t nchan_transport_jbm; /* number of TCs after TC decoding */ + int16_t nchan_transport_internal; /* total number of TC buffer channels, can include e.g. TD decorr data */ + int16_t nchan_buffer_full; /* number of channels to be fully buffered */ + int16_t n_samples_available; /* samples still available for rendering in the current frame */ + int16_t n_samples_buffered; /* full number of samples in the buffer (including spill to next frame) */ + int16_t n_samples_rendered; /* samples already rendered in the current frame */ + int16_t n_samples_granularity; /* render granularity */ int16_t n_samples_flushed; int16_t subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; int16_t nb_subframes; @@ -969,8 +971,8 @@ typedef struct decoder_config_structure int16_t Opt_ExternalOrientation; /* indiates whether external orientations are used */ int16_t Opt_dpid_on; /* indicates whether Directivity pattern option is used */ int16_t Opt_aeid_on; /* indicates whether Acoustic environment option is used */ - int16_t Opt_tsm; - int16_t Opt_5ms; + int16_t Opt_tsm; /* indicates whether time scaling modification is activated */ + IVAS_RENDER_FRAMESIZE render_framesize; int16_t Opt_delay_comp; /* flag indicating delay compensation active */ } DECODER_CONFIG, *DECODER_CONFIG_HANDLE; diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c index 210b83557..03c0fe15a 100644 --- a/lib_dec/ivas_stereo_dft_dec.c +++ b/lib_dec/ivas_stereo_dft_dec.c @@ -132,10 +132,10 @@ static void stereo_dft_dequantize_res_gains_f( /* compensate for the offset and extract/remove sign of first index */ sign = ind1[i] < 15 ? -1 : 1; - i1 = (int16_t) floor( ind1[i] < 15 ? 15 - ind1[i] : ind1[i] - 15 ); + i1 = (int16_t) floorf( ind1[i] < 15 ? 15 - ind1[i] : ind1[i] - 15 ); fi = ( ind1[i] < 15 ? 15 - ind1[i] : ind1[i] - 15 ) - i1; - j1 = (int16_t) floor( ind2[i] ); + j1 = (int16_t) floorf( ind2[i] ); fj = ind2[i] - j1; /* choose base indices for interpolation */ @@ -1628,9 +1628,9 @@ void stereo_dft_dec( *-------------------------------------------------------------------------*/ void stereo_dft_dec_res( - CPE_DEC_HANDLE hCPE, /* i/o: decoder CPE handle */ - float res_buf[STEREO_DFT_BUF_MAX], /* i : residual buffer */ - float *output /* o : output */ + CPE_DEC_HANDLE hCPE, /* i/o: decoder CPE handle */ + float res_buf[STEREO_DFT_N_8k], /* i : residual buffer */ + float *output /* o : output */ ) { int16_t i; @@ -1728,10 +1728,10 @@ void stereo_dft_dec_read_BS( STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder stereo handle */ const int16_t bwidth, /* i : bandwidth */ const int16_t output_frame, /* i : output frame length */ - float res_buf[STEREO_DFT_BUF_MAX], /* o : residual buffer */ - int16_t *nb_bits, /* o : number of bits read */ - float *coh, /* i/o: Coherence */ - const int16_t ivas_format /* i : ivas format */ + float res_buf[STEREO_DFT_N_8k], /* o : residual buffer */ + int16_t *nb_bits, /* o : number of bits read */ + float *coh, /* i/o: Coherence */ + const int16_t ivas_format /* i : ivas format */ ) { int16_t b, N_div, nbands; diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec.c b/lib_dec/ivas_stereo_mdct_stereo_dec.c index 7373bc781..42cbf3378 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec.c @@ -199,18 +199,18 @@ void stereo_decoder_tcx( STEREO_MDCT_DEC_DATA *hStereoMdct, /* i/o: MDCT stereo decoder structure */ int16_t ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ float *spec_r_0[NB_DIV], /* i/o: spectrum right channel */ - float *spec_l[NB_DIV], /* i/o: spectrum left channel */ - float *spec_r[NB_DIV], /* i/o: spectrum right channel */ - const int16_t mdct_stereo_mode[], /* i : stereo mode (FB/band wise MS, dual mono */ - const int16_t core_l, /* i : core for left channel (TCX20/TCX10) */ - const int16_t core_r, /* i : core for right channel (TCX20/TCX10) */ - const int16_t igf, /* i : flag for IGF activity */ - const int16_t L_frameTCX_l, /* i : TCX frame length of left channel */ - const int16_t L_frameTCX_r, /* i : TCX frame length of right channel */ - const int16_t mct_on, /* i : flag mct block (1) or stereo (0) */ - const int16_t last_core_l, /* i : last core for left channel */ - const int16_t last_core_r, /* i : last core for right channel */ - const int16_t tmp_plc_upmix /* i : indicates temp upmix for PLC decision */ + float *spec_l[], /* i/o: spectrum left channel [NB_DIV][N] */ + float *spec_r[], /* i/o: spectrum right channel [NB_DIV][N] */ + const int16_t mdct_stereo_mode[], /* i : stereo mode (FB/band wise MS, dual mono */ + const int16_t core_l, /* i : core for left channel (TCX20/TCX10) */ + const int16_t core_r, /* i : core for right channel (TCX20/TCX10) */ + const int16_t igf, /* i : flag for IGF activity */ + const int16_t L_frameTCX_l, /* i : TCX frame length of left channel */ + const int16_t L_frameTCX_r, /* i : TCX frame length of right channel */ + const int16_t mct_on, /* i : flag mct block (1) or stereo (0) */ + const int16_t last_core_l, /* i : last core for left channel */ + const int16_t last_core_r, /* i : last core for right channel */ + const int16_t tmp_plc_upmix /* i : indicates temp upmix for PLC decision */ ) { int16_t i, k, sfb, nSubframes; diff --git a/lib_dec/ivas_stereo_switching_dec.c b/lib_dec/ivas_stereo_switching_dec.c index 681effb0b..96ff3f48f 100644 --- a/lib_dec/ivas_stereo_switching_dec.c +++ b/lib_dec/ivas_stereo_switching_dec.c @@ -1299,6 +1299,11 @@ void synchro_synthesis( } } + if ( hCPE->element_mode == IVAS_CPE_MDCT && hCPE->nchan_out == 1 && !is_DTXrate( hCPE->element_brate ) && is_DTXrate( hCPE->last_element_brate ) ) + { + mvr2r( sts[0]->prev_synth_buffer, sts[1]->prev_synth_buffer, delay_comp_TD ); + } + nChannels = ( hCPE->element_mode == IVAS_CPE_MDCT ) ? 2 : hCPE->nchan_out; for ( n = 0; n < nChannels; n++ ) { diff --git a/lib_dec/jbm_jb4_circularbuffer.c b/lib_dec/jbm_jb4_circularbuffer.c index 03c040c57..da95e4135 100644 --- a/lib_dec/jbm_jb4_circularbuffer.c +++ b/lib_dec/jbm_jb4_circularbuffer.c @@ -50,7 +50,7 @@ * @param[in,out] size size of elements buffer * @param[in] capacity maximum number of elements to buffer * @param[in] newElement element to insert in buffer if great enough */ -static void JB4_CIRCULARBUFFER_calcPercentile( JB4_CIRCULARBUFFER_ELEMENT *elements, uint16_t *size, uint16_t capacity, JB4_CIRCULARBUFFER_ELEMENT newElement ); +static void JB4_CIRCULARBUFFER_calcPercentile( JB4_CIRCULARBUFFER_ELEMENT *elements, uint16_t *size, const uint16_t capacity, JB4_CIRCULARBUFFER_ELEMENT newElement ); /** circular buffer (FIFO) with fixed capacity */ struct JB4_CIRCULARBUFFER @@ -67,7 +67,8 @@ struct JB4_CIRCULARBUFFER /* Creates a circular buffer (FIFO) */ -ivas_error JB4_CIRCULARBUFFER_Create( JB4_CIRCULARBUFFER_HANDLE *ph ) +ivas_error JB4_CIRCULARBUFFER_Create( + JB4_CIRCULARBUFFER_HANDLE *ph ) { JB4_CIRCULARBUFFER_HANDLE h; @@ -430,10 +431,10 @@ void JB4_CIRCULARBUFFER_MinAndPercentile( static void JB4_CIRCULARBUFFER_calcPercentile( JB4_CIRCULARBUFFER_ELEMENT *elements, uint16_t *size, - uint16_t capacity, + const uint16_t capacity, JB4_CIRCULARBUFFER_ELEMENT newElement ) { - uint16_t i; + uint16_t i, j; /* insert newElement if elements buffer is not yet full */ if ( *size < capacity ) @@ -443,7 +444,10 @@ static void JB4_CIRCULARBUFFER_calcPercentile( if ( newElement <= elements[i] ) { /* insert newElement at index i */ - memmove( elements + i + 1, elements + i, ( *size - i ) * sizeof( JB4_CIRCULARBUFFER_ELEMENT ) ); /* IVAS_fmToDo: avoid use of memmove() */ + for ( j = *size; j > i; --j ) + { + elements[j] = elements[j - 1]; + } elements[i] = newElement; ++*size; return; @@ -467,7 +471,10 @@ static void JB4_CIRCULARBUFFER_calcPercentile( if ( newElement >= elements[i] ) { /* insert newElement at index i */ - memmove( elements, elements + 1, i * sizeof( JB4_CIRCULARBUFFER_ELEMENT ) ); + for ( j = 0; j < i; j++ ) + { + elements[j] = elements[1 + j]; + } elements[i] = newElement; return; } diff --git a/lib_dec/jbm_jb4_inputbuffer.c b/lib_dec/jbm_jb4_inputbuffer.c index 0982a781f..852c95946 100644 --- a/lib_dec/jbm_jb4_inputbuffer.c +++ b/lib_dec/jbm_jb4_inputbuffer.c @@ -142,12 +142,13 @@ int16_t JB4_INPUTBUFFER_Enque( JB4_INPUTBUFFER_ELEMENT element, JB4_INPUTBUFFER_ELEMENT *replacedElement ) { - uint16_t size; + uint16_t j, size; int16_t low, high, middle, diff; uint16_t insertPos; uint16_t canMoveRight; uint16_t canMoveLeft; bool replace; + *replacedElement = NULL; size = JB4_INPUTBUFFER_Size( h ); @@ -207,12 +208,6 @@ int16_t JB4_INPUTBUFFER_Enque( } } - assert( h->compareFunction( element, JB4_INPUTBUFFER_Element( h, low ), &replace ) != 0 ); - if ( low > 0 ) - assert( h->compareFunction( element, JB4_INPUTBUFFER_Element( h, low - 1 ), &replace ) > 0 ); - assert( h->compareFunction( element, JB4_INPUTBUFFER_Element( h, low ), &replace ) < 0 ); - if ( (uint16_t) ( low + 1 ) < size ) - assert( h->compareFunction( element, JB4_INPUTBUFFER_Element( h, low + 1 ), &replace ) < 0 ); insertPos = ( h->readPos + low ) % h->capacity; if ( h->readPos < h->writePos ) @@ -231,7 +226,11 @@ int16_t JB4_INPUTBUFFER_Enque( if ( canMoveRight ) { /* move higher elements to the right and insert at insertPos */ - memmove( h->data + insertPos + 1, h->data + insertPos, ( h->writePos - insertPos ) * sizeof( JB4_INPUTBUFFER_ELEMENT ) ); /* IVAS_fmToDo: avoid use of memmove() */ + for ( j = h->writePos; j > insertPos; --j ) + { + h->data[j] = h->data[j - 1]; + } + h->data[insertPos] = element; ++h->writePos; if ( h->writePos == h->capacity ) @@ -242,7 +241,11 @@ int16_t JB4_INPUTBUFFER_Enque( else { /* move lower elements to the left and insert before insertPos */ - memmove( h->data + h->readPos - 1, h->data + h->readPos, low * sizeof( JB4_INPUTBUFFER_ELEMENT ) ); /* IVAS_fmToDo: avoid use of memmove() */ + for ( j = 0; j < low; j++ ) + { + h->data[h->readPos - 1 + j] = h->data[h->readPos + j]; + } + h->data[insertPos - 1] = element; --h->readPos; assert( (int16_t) h->readPos >= 0 ); diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 5cc036b18..9281c292d 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -75,10 +75,12 @@ struct IVAS_DEC bool Opt_VOIP; /* flag indicating VOIP mode with JBM */ int16_t tsm_scale; /* scale for TSM operation */ int16_t tsm_max_scaling; + float tsm_quality; float *apaExecBuffer; /* Buffer for APA scaling */ PCMDSP_APA_HANDLE hTimeScaler; bool needNewFrame; bool hasBeenFedFrame; + bool updateOrientation; uint16_t nSamplesAvailableNext; int16_t nSamplesRendered; int16_t nTransportChannelsOld; @@ -100,13 +102,13 @@ static void store_JbmData( IVAS_DEC_VOIP *hVoIP, JB4_DATAUNIT_HANDLE dataUnit, c static ivas_error evs_dec_main( Decoder_Struct *st_ivas, const int16_t nOutSamples, float *floatBuf, int16_t *pcmBuf ); 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 ); static void init_decoder_config( DECODER_CONFIG_HANDLE hDecoderConfig ); -static int16_t IVAS_DEC_VoIP_GetRenderGranularity( Decoder_Struct *st_ivas ); static ivas_error IVAS_DEC_VoIP_reconfigure( IVAS_DEC_HANDLE hIvasDec, const uint16_t nTransportChannels, const uint16_t l_ts ); static ivas_error IVAS_DEC_Setup( IVAS_DEC_HANDLE hIvasDec, uint16_t *nTcBufferGranularity, uint8_t *nTransportChannels, uint8_t *nOutChannels, uint16_t *nSamplesRendered, int16_t *data ); static ivas_error IVAS_DEC_GetTcSamples( IVAS_DEC_HANDLE hIvasDec, float *pcmBuf, int16_t *nOutSamples ); static ivas_error IVAS_DEC_RendererFeedTcSamples( IVAS_DEC_HANDLE hIvasDec, const int16_t nSamplesForRendering, int16_t *nSamplesResidual, float *pcmBuf ); static ivas_error IVAS_DEC_GetRenderedSamples( IVAS_DEC_HANDLE hIvasDec, const uint16_t nSamplesForRendering, uint16_t *nSamplesRendered, uint16_t *nSamplesAvailableNext, int16_t *pcmBuf ); static ivas_error IVAS_DEC_GetBufferedNumberOfSamples( IVAS_DEC_HANDLE hIvasDec, int16_t *nSamplesBuffered ); +static int16_t get_render_frame_size_ms( IVAS_RENDER_FRAMESIZE render_framesize ); /*---------------------------------------------------------------------* @@ -142,6 +144,8 @@ ivas_error IVAS_DEC_Open( hIvasDec->apaExecBuffer = NULL; hIvasDec->hTimeScaler = NULL; hIvasDec->tsm_scale = 100; + hIvasDec->tsm_max_scaling = 0; + hIvasDec->tsm_quality = 1.0f; hIvasDec->needNewFrame = false; hIvasDec->nTransportChannelsOld = 0; hIvasDec->nSamplesAvailableNext = 0; @@ -151,6 +155,7 @@ ivas_error IVAS_DEC_Open( hIvasDec->hasBeenFedFirstGoodFrame = false; hIvasDec->hasDecodedFirstGoodFrame = false; hIvasDec->isInitialized = false; + hIvasDec->updateOrientation = false; hIvasDec->mode = mode; @@ -245,7 +250,6 @@ static void init_decoder_config( hDecoderConfig->Opt_non_diegetic_pan = 0; hDecoderConfig->non_diegetic_pan_gain = 0; hDecoderConfig->Opt_tsm = 0; - hDecoderConfig->Opt_5ms = 0; hDecoderConfig->Opt_delay_comp = 0; hDecoderConfig->Opt_ExternalOrientation = 0; hDecoderConfig->Opt_dpid_on = 0; @@ -340,16 +344,16 @@ static IVAS_DEC_BS_FORMAT mapIvasFormat( *---------------------------------------------------------------------*/ 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 int16_t tsmEnabled, /* i : enable TSM */ - const int16_t enable5ms, /* i : enable 5ms rendering path */ - const int16_t customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ - const int16_t hrtfReaderEnabled, /* i : enable HRTF binary file input */ - const int16_t enableHeadRotation, /* i : enable head rotation for binaural output */ - const int16_t enableExternalOrientation, /* i : enable external orientations */ - const IVAS_HEAD_ORIENT_TRK_T orientation_tracking, /* i : head orientation tracking type */ + 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 int16_t tsmEnabled, /* i : enable time scale modification */ + const IVAS_RENDER_FRAMESIZE renderFramesize, /* i : rendering frame size */ + const int16_t customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ + const int16_t hrtfReaderEnabled, /* i : enable HRTF binary file input */ + const int16_t enableHeadRotation, /* i : enable head rotation for binaural output */ + const int16_t enableExternalOrientation, /* i : enable external orientations */ + const IVAS_HEAD_ORIENT_TRK_T orientation_tracking, /* i : head orientation tracking type */ const int16_t renderConfigEnabled, /* i : enable Renderer config. file for binaural output */ const int16_t Opt_non_diegetic_pan, /* i : diegetic or not */ const float non_diegetic_pan_gain, /* i : non diegetic panning gain */ @@ -403,7 +407,6 @@ ivas_error IVAS_DEC_Configure( } hDecoderConfig->Opt_tsm = tsmEnabled; - hDecoderConfig->Opt_5ms = enable5ms; hDecoderConfig->Opt_LsCustom = customLsOutputEnabled; hDecoderConfig->Opt_Headrotation = enableHeadRotation; hDecoderConfig->orientation_tracking = orientation_tracking; @@ -416,6 +419,19 @@ ivas_error IVAS_DEC_Configure( hDecoderConfig->Opt_dpid_on = Opt_dpid_on; hDecoderConfig->Opt_aeid_on = acousticEnvironmentId != 65535 ? TRUE : FALSE; + if ( renderFramesize == IVAS_RENDER_FRAMESIZE_UNKNOWN ) + { + return IVAS_ERR_WRONG_PARAMS; + } + if ( outputConfig == IVAS_AUDIO_CONFIG_EXTERNAL ) + { + hDecoderConfig->render_framesize = IVAS_RENDER_FRAMESIZE_20MS; + } + else + { + hDecoderConfig->render_framesize = renderFramesize; + } + /* Set decoder parameters to initial values */ if ( ( error = ivas_init_decoder_front( st_ivas ) ) != IVAS_ERR_OK ) @@ -432,7 +448,8 @@ ivas_error IVAS_DEC_Configure( hIvasDec->nSamplesAvailableNext = 0; hIvasDec->nSamplesRendered = 0; hIvasDec->tsm_scale = 100; - hIvasDec->tsm_max_scaling = 100; + hIvasDec->tsm_max_scaling = 0; + hIvasDec->tsm_quality = 1.0f; return error; } @@ -440,14 +457,27 @@ ivas_error IVAS_DEC_Configure( /*---------------------------------------------------------------------* - * IVAS_DEC_Set5msFlag( ) + * get_render_framesize_ms( ) * * Get the 5ms flag *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_Set5msFlag( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const int16_t enable5ms /* i : 5ms flag */ +int16_t get_render_frame_size_ms( + const IVAS_RENDER_FRAMESIZE render_framesize ) +{ + return (int16_t) ( render_framesize * ( 1000 / ( FRAMES_PER_SEC * IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ) ) ); +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_SetRenderFramesize( ) + * + * Get the 5ms flag + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_SetRenderFramesize( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_RENDER_FRAMESIZE render_framesize /* i : render framesize */ ) { if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hDecoderConfig == NULL ) @@ -455,29 +485,112 @@ ivas_error IVAS_DEC_Set5msFlag( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - hIvasDec->st_ivas->hDecoderConfig->Opt_5ms = enable5ms; + hIvasDec->st_ivas->hDecoderConfig->render_framesize = render_framesize; return IVAS_ERR_OK; } - /*---------------------------------------------------------------------* - * IVAS_DEC_Get5msFlag( ) + * IVAS_DEC_GetGetRenderFramesize( ) * * Get the 5ms flag *---------------------------------------------------------------------*/ -ivas_error IVAS_DEC_Get5msFlag( +ivas_error IVAS_DEC_GetRenderFramesize( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_RENDER_FRAMESIZE *render_framesize /* o : render framesize */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || render_framesize == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + *render_framesize = hIvasDec->st_ivas->hDecoderConfig->render_framesize; + + return IVAS_ERR_OK; +} + +/*---------------------------------------------------------------------* + * IVAS_DEC_GetGetRenderFramesizeSamples( ) + * + * 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; + } + + *render_framesize = (int16_t) ( hIvasDec->st_ivas->hDecoderConfig->output_Fs * hIvasDec->st_ivas->hDecoderConfig->render_framesize / ( FRAMES_PER_SEC * IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ) ); + + return IVAS_ERR_OK; +} + +/*---------------------------------------------------------------------* + * IVAS_DEC_GetGetRenderFramesizeMs( ) + * + * Get render framesize in milliseconds + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_GetRenderFramesizeMs( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint32_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_ms( hIvasDec->st_ivas->hDecoderConfig->render_framesize ); + + return IVAS_ERR_OK; +} + +/*---------------------------------------------------------------------* + * IVAS_DEC_GetGetReferencesUpdateFrequency( ) + * + * 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; + } + + *update_frequency = (int16_t) ( IVAS_MAX_PARAM_SPATIAL_SUBFRAMES / hIvasDec->st_ivas->hDecoderConfig->render_framesize ); + + return IVAS_ERR_OK; +} + +/*---------------------------------------------------------------------* + * IVAS_DEC_GetGetNumOrientationSubframes( ) + * + * Get the number of subframes for head/ecernal orientation per render frame + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_GetNumOrientationSubframes( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t *enable5ms /* o : 5ms flag */ + int16_t *num_subframes /* o : render framesize */ ) { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || enable5ms == NULL ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || num_subframes == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - *enable5ms = (int16_t) hIvasDec->st_ivas->hDecoderConfig->Opt_5ms; + *num_subframes = (int16_t) hIvasDec->st_ivas->hDecoderConfig->render_framesize; return IVAS_ERR_OK; } @@ -512,8 +625,6 @@ ivas_error IVAS_DEC_EnableVoIP( hIvasDec->Opt_VOIP = 1; hDecoderConfig->Opt_tsm = 1; - hDecoderConfig->Opt_5ms = 1; - if ( hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) { hDecoderConfig->nchan_out = audioCfg2channels( hDecoderConfig->output_config ); @@ -656,51 +767,6 @@ ivas_error IVAS_DEC_FeedFrame_Serial( * Main function to decode to PCM data *---------------------------------------------------------------------*/ -static ivas_error _GetSamples( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ - int16_t *nOutSamples /* o : number of samples per channel written to output buffer */ -) -{ - Decoder_Struct *st_ivas; - ivas_error error; - - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - st_ivas = hIvasDec->st_ivas; - - *nOutSamples = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); - - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) - { - if ( ( error = evs_dec_main( st_ivas, *nOutSamples, NULL, pcmBuf ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( hIvasDec->mode == IVAS_DEC_MODE_IVAS ) - { - /* run the main IVAS decoding routine */ - - if ( ( error = ivas_dec( st_ivas, pcmBuf ) ) != IVAS_ERR_OK ) - { - return error; - } - - hIvasDec->isInitialized = true; /* Initialization done in ivas_dec() */ - } - - if ( hIvasDec->hasBeenFedFirstGoodFrame ) - { - hIvasDec->hasDecodedFirstGoodFrame = true; - } - - return IVAS_ERR_OK; -} - ivas_error IVAS_DEC_GetSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ @@ -711,7 +777,7 @@ ivas_error IVAS_DEC_GetSamples( ) { ivas_error error; - int16_t nOutSamplesElse, result, nSamplesToRender; + int16_t nOutSamplesElse, nSamplesToRender; uint16_t nSamplesRendered, nSamplesRendered_loop, l_ts, nTimeScalerOutSamples; uint8_t nTransportChannels, nOutChannels; @@ -726,6 +792,21 @@ ivas_error IVAS_DEC_GetSamples( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + if ( hIvasDec->updateOrientation ) + { + /*----------------------------------------------------------------* + * Combine orientations + *----------------------------------------------------------------*/ + + if ( ( error = combine_external_and_head_orientations_dec( hIvasDec->st_ivas->hHeadTrackData, hIvasDec->st_ivas->hExtOrientationData, hIvasDec->st_ivas->hCombinedOrientationData ) ) != IVAS_ERR_OK ) + { + return error; + } + + + hIvasDec->updateOrientation = false; + } + if ( !hIvasDec->hasBeenFedFrame && hIvasDec->nSamplesAvailableNext == 0 ) { /* no frame was fed, do nothing but ask for a frame */ @@ -749,8 +830,6 @@ ivas_error IVAS_DEC_GetSamples( *needNewFrame = true; } } - - /* only for 1st step 5ms API, split rendering still needs to go through the old decoding function */ else { /* check if we need to run the setup function */ @@ -764,21 +843,6 @@ ivas_error IVAS_DEC_GetSamples( return error; } } - - if ( !hIvasDec->st_ivas->hDecoderConfig->Opt_5ms ) - { - if ( ( error = _GetSamples( hIvasDec, pcmBuf, nOutSamples ) ) != IVAS_ERR_OK ) - { - return error; - } - hIvasDec->nSamplesAvailableNext = 0; - hIvasDec->nSamplesRendered = *nOutSamples; - nSamplesRendered = *nOutSamples; - hIvasDec->needNewFrame = true; - hIvasDec->hasBeenFedFrame = false; - *needNewFrame = true; - } - else { /* check if we need to run the setup function, tc decoding and feeding the renderer */ if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) @@ -786,7 +850,7 @@ ivas_error IVAS_DEC_GetSamples( int16_t nResidualSamples, nSamplesTcsScaled; nSamplesRendered += nSamplesRendered_loop; - if ( nTransportChannels != hIvasDec->nTransportChannelsOld ) + if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm && nTransportChannels != hIvasDec->nTransportChannelsOld ) { if ( ( error = IVAS_DEC_VoIP_reconfigure( hIvasDec, nTransportChannels, l_ts ) ) != IVAS_ERR_OK ) { @@ -794,32 +858,34 @@ ivas_error IVAS_DEC_GetSamples( } } - /* decode TCs only */ + /* IVAS decoder */ if ( ( error = IVAS_DEC_GetTcSamples( hIvasDec, hIvasDec->apaExecBuffer, &nOutSamplesElse ) ) != IVAS_ERR_OK ) { return error; } + /* JBM */ if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) { if ( apa_set_scale( hIvasDec->hTimeScaler, hIvasDec->tsm_scale ) != 0 ) { return IVAS_ERR_UNKNOWN; } - result = apa_exec( hIvasDec->hTimeScaler, hIvasDec->apaExecBuffer, hIvasDec->nSamplesFrame * nTransportChannels, (uint16_t) hIvasDec->tsm_max_scaling, hIvasDec->apaExecBuffer, &nTimeScalerOutSamples ); - if ( result != 0 ) + + if ( apa_exec( hIvasDec->hTimeScaler, hIvasDec->apaExecBuffer, hIvasDec->nSamplesFrame * nTransportChannels, (uint16_t) hIvasDec->tsm_max_scaling, hIvasDec->apaExecBuffer, &nTimeScalerOutSamples ) != 0 ) { return IVAS_ERR_UNKNOWN; } + assert( nTimeScalerOutSamples <= APA_BUF ); + nSamplesTcsScaled = nTimeScalerOutSamples / nTransportChannels; } else { - nTimeScalerOutSamples = hIvasDec->nSamplesFrame * nTransportChannels; + nSamplesTcsScaled = hIvasDec->nSamplesFrame; } - nSamplesTcsScaled = nTimeScalerOutSamples / nTransportChannels; - /* render IVAS frames */ + /* Feed decoded transport channels samples to the renderer */ if ( ( error = IVAS_DEC_RendererFeedTcSamples( hIvasDec, nSamplesTcsScaled, &nResidualSamples, hIvasDec->apaExecBuffer ) ) != IVAS_ERR_OK ) { return error; @@ -836,9 +902,8 @@ ivas_error IVAS_DEC_GetSamples( hIvasDec->hasBeenFedFrame = false; } - /* render IVAS frames directly to the output buffer */ + /* render IVAS frames directly to the output buffer */ nSamplesToRender = nSamplesAsked - nSamplesRendered; - if ( ( error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesRendered_loop, &hIvasDec->nSamplesAvailableNext, pcmBuf + nSamplesRendered * nOutChannels ) ) != IVAS_ERR_OK ) { return error; @@ -983,7 +1048,7 @@ static ivas_error IVAS_DEC_GetTcSamples( /*---------------------------------------------------------------------* * IVAS_DEC_Rendered_FeedTcSamples( ) * - * Main function to decode to PCM data of the transport channels + * Feed decoded transport channels samples to the renderer *---------------------------------------------------------------------*/ static ivas_error IVAS_DEC_RendererFeedTcSamples( @@ -1012,7 +1077,7 @@ static ivas_error IVAS_DEC_RendererFeedTcSamples( /*---------------------------------------------------------------------* * IVAS_DEC_GetRenderedSamples( ) * - * Main function to render the transport channels to PCM output datat + * Main function to render the transport channels to PCM output data *---------------------------------------------------------------------*/ static ivas_error IVAS_DEC_GetRenderedSamples( @@ -1346,6 +1411,7 @@ ivas_error IVAS_DEC_FeedHeadTrackData( hHeadTrackData->Pos[subframe_idx].y = Pos.y; hHeadTrackData->Pos[subframe_idx].z = Pos.z; + hIvasDec->updateOrientation = true; return IVAS_ERR_OK; } @@ -1376,6 +1442,8 @@ ivas_error IVAS_DEC_FeedRefRotData( pOtr->refRot.z = rotation.z; pOtr->refRot.y = rotation.y; + hIvasDec->updateOrientation = true; + return IVAS_ERR_OK; } @@ -1403,6 +1471,8 @@ ivas_error IVAS_DEC_FeedRefVectorData( pOtr = hIvasDec->st_ivas->hHeadTrackData->OrientationTracker; + hIvasDec->updateOrientation = true; + return ivas_orient_trk_SetReferenceVector( pOtr, listenerPos, refPos ); } @@ -1445,6 +1515,8 @@ ivas_error IVAS_DEC_FeedExternalOrientationData( hExternalOrientationData->enableRotationInterpolation[subframe_idx] = enableRotationInterpolation; hExternalOrientationData->numFramesToTargetOrientation[subframe_idx] = numFramesToTargetOrientation; + hIvasDec->updateOrientation = true; + return IVAS_ERR_OK; } @@ -1632,7 +1704,6 @@ ivas_error IVAS_DEC_GetRenderConfig( 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; @@ -1691,7 +1762,7 @@ ivas_error IVAS_DEC_FeedRenderConfig( hRenderConfig->roomAcoustics.dimensions = renderConfig.roomAcoustics.dimensions; hRenderConfig->roomAcoustics.ListenerOrigin = renderConfig.roomAcoustics.ListenerOrigin; - mvr2r( renderConfig.roomAcoustics.AbsCoeff, hRenderConfig->roomAcoustics.AbsCoeff, ER_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 ); @@ -1942,9 +2013,9 @@ ivas_error IVAS_DEC_VoIP_FeedFrame( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_VoIP_SetScale( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const int16_t maxScaling, - const int16_t scale /* i : TSM scale to set */ + 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 */ ) { ivas_error error; @@ -1964,6 +2035,33 @@ ivas_error IVAS_DEC_VoIP_SetScale( return error; } +/*---------------------------------------------------------------------* + * IVAS_DEC_VoIP_SetScale( ) + * + * Set the TSM scale + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_TSM_SetQuality( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const float quality /* i : target TSM quality */ +) +{ + ivas_error error; + + error = IVAS_ERR_OK; + + if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm == false ) + { + return IVAS_ERR_TSM_NOT_ENABLED; + } + else + { + hIvasDec->tsm_quality = quality; + } + + return error; +} + /*---------------------------------------------------------------------* * IVAS_DEC_VoIP_GetSamples( ) @@ -2172,7 +2270,6 @@ ivas_error IVAS_DEC_Flush( nSamplesToRender = (uint16_t) *nSamplesFlushed; /* render IVAS frames */ - error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesFlushedLocal, &hIvasDec->nSamplesAvailableNext, pcmBuf ); return error; @@ -2415,6 +2512,7 @@ static ivas_error printConfigInfo_dec( { ivas_error error; char config_str[50]; + AUDIO_CONFIG output_config; /*-----------------------------------------------------------------* * Print info on screen @@ -2514,9 +2612,14 @@ static ivas_error printConfigInfo_dec( } } - get_channel_config( st_ivas->hDecoderConfig->output_config, &config_str[0] ); + 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 ) + { + fprintf( stdout, "Render framesize: %dms\n", get_render_frame_size_ms( st_ivas->hDecoderConfig->render_framesize ) ); + } if ( st_ivas->hDecoderConfig->Opt_HRTF_binary ) { fprintf( stdout, "HRIR/BRIR file: ON\n" ); @@ -2580,16 +2683,7 @@ static ivas_error printConfigInfo_dec( if ( st_ivas->hDecoderConfig->Opt_tsm ) { - fprintf( stdout, "TSM mode: ON\n" ); - } - - /*-----------------------------------------------------------------* - * Print 5ms API mode info - *-----------------------------------------------------------------*/ - - if ( st_ivas->hDecoderConfig->Opt_5ms ) - { - fprintf( stdout, "API 5ms mode: ON\n" ); + fprintf( stdout, "TSM mode: ON\n" ); } return IVAS_ERR_OK; @@ -2642,7 +2736,6 @@ static ivas_error evs_dec_main( int16_t *pcmBuf ) { DEC_CORE_HANDLE *hCoreCoder; - float output[MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN][L_FRAME48k]; float mixer_left, mixer_rigth; float *p_output[MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN]; int16_t ch; @@ -2655,7 +2748,7 @@ static ivas_error evs_dec_main( for ( ch = 0; ch < MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN; ch++ ) { - p_output[ch] = output[ch]; + p_output[ch] = st_ivas->p_output_f[ch]; } /* run the main EVS decoding routine */ @@ -2663,14 +2756,14 @@ static ivas_error evs_dec_main( { if ( hCoreCoder[0]->Opt_AMR_WB ) { - if ( ( error = amr_wb_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], 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; } } else { - if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], 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; } @@ -2680,21 +2773,21 @@ static ivas_error evs_dec_main( { if ( hCoreCoder[0]->bfi == 0 ) { - if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], 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; } } else if ( hCoreCoder[0]->bfi == 2 ) { - if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], 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; } } else { - if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], 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; } @@ -2707,11 +2800,11 @@ static ivas_error evs_dec_main( { mixer_left = ( st_ivas->hDecoderConfig->non_diegetic_pan_gain + 1.f ) * 0.5f; mixer_rigth = 1.f - mixer_left; - v_multc( output[0], mixer_rigth, output[1], nOutSamples ); - v_multc( output[0], mixer_left, output[0], nOutSamples ); + v_multc( p_output[0], mixer_rigth, p_output[1], nOutSamples ); + v_multc( p_output[0], mixer_left, p_output[0], nOutSamples ); } - if ( !st_ivas->hDecoderConfig->Opt_tsm && st_ivas->hDecoderConfig->Opt_5ms ) + if ( !st_ivas->hDecoderConfig->Opt_tsm ) { ivas_jbm_dec_copy_tc_no_tsm( st_ivas, p_output, nOutSamples ); } @@ -2776,19 +2869,6 @@ static ivas_error input_format_API_to_internal( } -/*---------------------------------------------------------------------* - * IVAS_DEC_VoIP_GetRenderGranularity() - * - * - *---------------------------------------------------------------------*/ - -static int16_t IVAS_DEC_VoIP_GetRenderGranularity( - Decoder_Struct *st_ivas ) -{ - return st_ivas->hTcBuffer->n_samples_granularity; -} - - /*---------------------------------------------------------------------* * IVAS_DEC_VoIP_reconfigure() * @@ -2813,7 +2893,7 @@ static ivas_error IVAS_DEC_VoIP_reconfigure( uint16_t wss, css; float startQuality; - startQuality = 1.0f; + startQuality = hIvasDec->tsm_quality; apa_buffer_size = APA_BUF_PER_CHANNEL; /* get current renderer type*/ diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index fdb92e61b..ad4efa505 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -108,7 +108,7 @@ ivas_error IVAS_DEC_Configure( const uint32_t sampleRate, /* i : output sampling frequency */ const IVAS_AUDIO_CONFIG outputConfig, /* i : audio configuration */ const int16_t tsmEnabled, /* i : enable TSM */ - const int16_t enable5ms, /* i : enable 5ms rendering path */ + const IVAS_RENDER_FRAMESIZE renderFramesize, /* i : rendering frame size */ const int16_t customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ const int16_t hrtfReaderEnabled, /* i : enable HRTF binary file input */ const int16_t enableHeadRotation, /* i : enable head rotation for binaural output */ @@ -211,6 +211,11 @@ ivas_error IVAS_DEC_VoIP_SetScale( const int16_t scale /* i : TSM scale to set */ ); +ivas_error IVAS_DEC_TSM_SetQuality( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const float quality /* i : target TSM quality */ +); + /*! r: error code */ ivas_error IVAS_DEC_VoIP_GetSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ @@ -240,14 +245,34 @@ ivas_error IVAS_DEC_EnableVoIP( ); -ivas_error IVAS_DEC_Set5msFlag( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const int16_t enable5ms /* i : 5ms flag */ +ivas_error IVAS_DEC_SetRenderFramesize( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_RENDER_FRAMESIZE render_framesize /* i : render framesize */ ); -ivas_error IVAS_DEC_Get5msFlag( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t *enable5ms /* o : 5ms flag */ +ivas_error IVAS_DEC_GetRenderFramesize( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_RENDER_FRAMESIZE *render_framesize /* o : render framesize */ +); + +ivas_error IVAS_DEC_GetRenderFramesizeSamples( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *render_framesize /* o : render framesize in samples */ +); + +ivas_error IVAS_DEC_GetReferencesUpdateFrequency( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *update_frequency /* o : update frequency */ +); + +ivas_error IVAS_DEC_GetNumOrientationSubframes( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *num_subframes /* o : render framesize */ +); + +ivas_error IVAS_DEC_GetRenderFramesizeMs( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint32_t *render_framesize /* o : render framesize in samples */ ); diff --git a/lib_enc/acelp_core_switch_enc.c b/lib_enc/acelp_core_switch_enc.c index b54262c4f..b02f9a62c 100644 --- a/lib_enc/acelp_core_switch_enc.c +++ b/lib_enc/acelp_core_switch_enc.c @@ -120,32 +120,11 @@ void acelp_core_switch_enc( } } -#ifdef FIX_I4_OL_PITCH - if ( st->last_codec_mode == MODE1 ) - { - /* in MODE1 T_op is at 12.8 kHz */ - if ( st->last_L_frame != L_FRAME ) /* ACELP@16k core -> convert T_op to 16 kHz */ - { - T_op[0] = (short) ( 1.25f * T_op[0] + 0.5f ); - T_op[1] = (short) ( 1.25f * T_op[1] + 0.5f ); - } - } - else - { - /* in MODE2 T_op is at 16 kHz */ - if ( st->last_L_frame == L_FRAME ) /* ACELP@12.8k core -> convert T_op to 12.8 kHz */ - { - T_op[0] = (short) ( 0.8f * T_op[0] + 0.5f ); - T_op[1] = (short) ( 0.8f * T_op[1] + 0.5f ); - } - } -#else if ( st->last_L_frame != L_FRAME ) /* ACELP@16k core */ { T_op[0] = (short) ( 1.25f * T_op[0] + 0.5f ); T_op[1] = (short) ( 1.25f * T_op[1] + 0.5f ); } -#endif /*----------------------------------------------------------------* * Excitation encoding *----------------------------------------------------------------*/ diff --git a/lib_enc/cod_tcx.c b/lib_enc/cod_tcx.c index b2d8883c5..0577aafef 100644 --- a/lib_enc/cod_tcx.c +++ b/lib_enc/cod_tcx.c @@ -103,13 +103,13 @@ void HBAutocorrelation( #define TNS_GAIN_THRESHOLD_FOR_WHITE ( 3.0f ) void TNSAnalysisStereo( - Encoder_State **sts, /* i : encoder state handle */ - float *mdst_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* o : MDST spectrum */ - const int16_t bWhitenedDomain, /* i : whitened domain flag */ - int16_t tnsSize[MCT_MAX_CHANNELS][NB_DIV], /* i : number of tns parameters put into prm */ - int16_t tnsBits[MCT_MAX_CHANNELS][NB_DIV], /* i : number of tns bits in the frame */ - int16_t param_core[][NB_DIV * NPRM_DIV], /* o : TNS parameters */ - const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ + Encoder_State **sts, /* i : encoder state handle */ + float *mdst_spectrum[CPE_CHANNELS][NB_DIV], /* o : MDST spectrum */ + const int16_t bWhitenedDomain, /* i : whitened domain flag */ + int16_t tnsSize[CPE_CHANNELS][NB_DIV], /* i : number of tns parameters put into prm */ + int16_t tnsBits[CPE_CHANNELS][NB_DIV], /* i : number of tns bits in the frame */ + int16_t param_core[][NB_DIV * NPRM_DIV], /* o : TNS parameters */ + const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ ) { int16_t ch, k, L_spec, L_frame, nSubframes, iFilter; diff --git a/lib_enc/evs_enc.c b/lib_enc/evs_enc.c index 7ae9a30bc..56734fe37 100644 --- a/lib_enc/evs_enc.c +++ b/lib_enc/evs_enc.c @@ -92,9 +92,7 @@ ivas_error evs_enc( int16_t padBits; float realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; /* real buffer */ float imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; /* imag buffer */ -#ifndef FIX_I4_OL_PITCH int16_t pitch_orig[3]; /* original open-loop pitch values that might be altered in core_acelp_tcx20_switching() within MODE2 */ -#endif ivas_error error; error = IVAS_ERR_OK; @@ -167,11 +165,7 @@ ivas_error evs_enc( * Pre-processing *---------------------------------------------------------------------*/ -#ifdef FIX_I4_OL_PITCH - pre_proc( st, input_frame, old_inp_12k8, old_inp_16k, &inp, fr_bands, Etot, &ener, A, Aw, epsP, lsp_new, lsp_mid, &vad_hover_flag, &attack_flag, new_inp_resamp16k, &Voicing_flag, realBuffer, imagBuffer, &hq_core_type ); -#else pre_proc( st, input_frame, old_inp_12k8, old_inp_16k, &inp, fr_bands, &ener, pitch_orig, A, Aw, epsP, lsp_new, lsp_mid, &vad_hover_flag, &attack_flag, new_inp_resamp16k, &Voicing_flag, realBuffer, imagBuffer, &hq_core_type ); -#endif if ( st->mdct_sw == MODE2 ) { @@ -260,12 +254,10 @@ ivas_error evs_enc( core_switching_post_enc( st, old_inp_12k8, old_inp_16k, A ); -#ifndef FIX_I4_OL_PITCH if ( st->core == HQ_CORE ) { mvs2s( pitch_orig, st->pitch, 3 ); /* original open-loop pitch values might be altered in core_acelp_tcx20_switching() */ } -#endif } else /* MODE2 */ @@ -290,9 +282,7 @@ ivas_error evs_enc( /* Call main encoding function */ enc_acelp_tcx_main( st, old_inp_16k + L_INP_MEM, Aw, lsp_new, lsp_mid, bwe_exc_extended, voice_factors, pitch_buf, vad_hover_flag ); -#ifndef FIX_I4_OL_PITCH mvs2s( pitch_orig, st->pitch, 3 ); /* populate the original OL pitch values back */ -#endif /*---------------------------------------------------------------------* * Postprocessing for Mode 1/2 switching diff --git a/lib_enc/init_enc.c b/lib_enc/init_enc.c index 7ac925cf0..e5d8f6294 100644 --- a/lib_enc/init_enc.c +++ b/lib_enc/init_enc.c @@ -97,6 +97,7 @@ ivas_error init_encoder( st->low_rate_mode = 0; st->ini_frame = 0; st->inactive_coder_type_flag = 0; + st->sba_br_sw_while_no_data = 0; st->coder_type_raw = VOICED; st->last_coder_type_raw = st->coder_type_raw; diff --git a/lib_enc/ivas_core_enc.c b/lib_enc/ivas_core_enc.c index b4d7ffc9e..fe16b7784 100644 --- a/lib_enc/ivas_core_enc.c +++ b/lib_enc/ivas_core_enc.c @@ -49,11 +49,10 @@ *-------------------------------------------------------------------*/ ivas_error ivas_core_enc( - SCE_ENC_HANDLE hSCE, /* i/o: SCE encoder structure */ - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ - const int16_t n_CoreChannels, /* i : number of core channels to be coded */ -#ifdef FIX_854_ARRAY_SIZE_MISMATCH + SCE_ENC_HANDLE hSCE, /* i/o: SCE encoder structure */ + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + MCT_ENC_HANDLE hMCT, /* i/o: MCT encoder structure */ + const int16_t n_CoreChannels, /* i : number of core channels to be coded */ float old_inp_12k8[][L_INP_12k8], /* i : buffer of old input signal */ float old_inp_16k[][L_INP], /* i : buffer of old input signal */ float ener[], /* i : residual energy from Levinson-Durbin */ @@ -72,29 +71,9 @@ ivas_error ivas_core_enc( const int16_t vad_flag_dtx[], /* i : HE-SAD flag with additional DTX HO */ float enerBuffer[][CLDFB_NO_CHANNELS_MAX], /* i : energy buffer */ float fft_buff[][2 * L_FFT], /* i : FFT buffer */ -#else - float old_inp_12k8[CPE_CHANNELS][L_INP_12k8], /* i : buffer of old input signal */ - float old_inp_16k[CPE_CHANNELS][L_INP], /* i : buffer of old input signal */ - float ener[CPE_CHANNELS], /* i : residual energy from Levinson-Durbin */ - float A[CPE_CHANNELS][NB_SUBFR16k * ( M + 1 )], /* i : A(z) unquantized for the 4 subframes */ - float Aw[CPE_CHANNELS][NB_SUBFR16k * ( M + 1 )], /* i : weighted A(z) unquantized for subframes */ - float epsP[CPE_CHANNELS][M + 1], /* i : LP prediction errors */ - float lsp_new[CPE_CHANNELS][M], /* i : LSPs at the end of the frame */ - float lsp_mid[CPE_CHANNELS][M], /* i : LSPs in the middle of the frame */ - const int16_t vad_hover_flag[CPE_CHANNELS], /* i : VAD hanglover flag */ - int16_t attack_flag[CPE_CHANNELS], /* i : attack flag (GSC or TC) */ - float realBuffer[CPE_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: real buffer */ - float imagBuffer[CPE_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: imag buffer */ - float old_wsp[CPE_CHANNELS][L_WSP], /* i : weighted input signal buffer */ - const int16_t loc_harm[CPE_CHANNELS], /* i : harmonicity flag */ - const float cor_map_sum[CPE_CHANNELS], /* i : speech/music clasif. parameter */ - const int16_t vad_flag_dtx[CPE_CHANNELS], /* i : HE-SAD flag with additional DTX HO */ - float enerBuffer[CPE_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : energy buffer */ - float fft_buff[CPE_CHANNELS][2 * L_FFT], /* i : FFT buffer */ -#endif - const int16_t tdm_SM_or_LRTD_Pri, /* i : channel combination scheme flag */ - const int16_t ivas_format, /* i : IVAS format */ - const int16_t flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz */ + const int16_t tdm_SM_or_LRTD_Pri, /* i : channel combination scheme flag */ + const int16_t ivas_format, /* i : IVAS format */ + const int16_t flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz */ ) { int16_t n, input_frame; diff --git a/lib_enc/ivas_core_pre_proc.c b/lib_enc/ivas_core_pre_proc.c index dd95f8dbe..35f3eace6 100644 --- a/lib_enc/ivas_core_pre_proc.c +++ b/lib_enc/ivas_core_pre_proc.c @@ -280,7 +280,10 @@ ivas_error pre_proc_ivas( } else if ( element_brate != last_element_brate ) { - SetModeIndex( st, st->bits_frame_nominal * FRAMES_PER_SEC, element_mode, MCT_flag ); + if ( st->core_brate != FRAME_NO_DATA ) + { + SetModeIndex( st, st->bits_frame_nominal * FRAMES_PER_SEC, element_mode, MCT_flag ); + } if ( st->extl != -1 && st->extl != IGF_BWE && st->igf == 1 ) { diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index 8a9c62e1f..d938cf0b1 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -95,16 +95,17 @@ ivas_error pre_proc_front_ivas( const float tdm_lsp_new_PCh[M], /* i : unq. LSPs of primary channel */ const float currFlatness, /* i : flatness parameter */ const int16_t tdm_ratio_idx, /* i : Current Ratio_L index */ - float fr_bands_LR[CPE_CHANNELS][2 * NB_BANDS], /* i : energy in frequency bands */ - const float Etot_LR[CPE_CHANNELS], /* i : total energy Left & Right channel */ - float lf_E_LR[CPE_CHANNELS][2 * VOIC_BINS], /* i : per bin spectrum energy in lf, LR channels */ - const int16_t localVAD_HE_SAD_LR[CPE_CHANNELS], /* i : HE-SAD flag without hangover, LR channels */ + float fr_bands_LR[][2 * NB_BANDS], /* i : energy in frequency bands */ + const float Etot_LR[], /* i : total energy Left & Right channel */ + float lf_E_LR[][2 * VOIC_BINS], /* i : per bin spectrum energy in lf, LR channels */ + const int16_t localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover, LR channels */ float band_energies_LR[2 * NB_BANDS], /* o : energy in critical bands without minimum noise floor E_MIN */ const int16_t flag_16k_smc, /* i : flag to indicate if the OL SMC is run at 16 kHz */ const int16_t front_vad_flag, /* i : front-VAD flag to overwrite VAD decision */ const int16_t force_front_vad, /* i : flag to force VAD decision */ const int16_t front_vad_dtx_flag, /* i : front-VAD DTX flag to overwrite VAD decision*/ const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ const int32_t ivas_total_brate /* i : IVAS total bitrate - for setting the DTX */ ) { @@ -180,7 +181,7 @@ ivas_error pre_proc_front_ivas( st = hSCE->hCoreCoder[n]; signal_in = hSCE->hCoreCoder[n]->input; element_mode = IVAS_SCE; - last_element_brate = hSCE->element_brate; /* hack - the past parameter is not really needed */ + last_element_brate = hSCE->last_element_brate; hStereoClassif = NULL; lr_vad_enabled = 0; } @@ -762,6 +763,16 @@ ivas_error pre_proc_front_ivas( /* SNR-based speech/music classification */ if ( ( element_mode >= IVAS_CPE_DFT && element_brate >= IVAS_24k4 ) || ( element_mode == IVAS_SCE && element_brate >= SCE_SMC_THR ) ) { + if ( ivas_format == SBA_FORMAT && st->core_brate != FRAME_NO_DATA && st->last_core_brate == FRAME_NO_DATA && st->sba_br_sw_while_no_data ) + { + SetModeIndex( st, st->bits_frame_nominal * FRAMES_PER_SEC, element_mode, MCT_flag ); + st->sba_br_sw_while_no_data = 0; + } + else if ( ivas_format == SBA_FORMAT && st->core_brate == FRAME_NO_DATA && element_brate != last_element_brate ) + { + st->sba_br_sw_while_no_data = 1; + } + if ( flag_16k_smc ) { /* Compute core-coder buffers at internal sampling rate */ diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index e56b45c3b..9e2da33be 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -107,12 +107,9 @@ ivas_error ivas_cpe_enc( ivas_error error; int32_t cpe_brate; int32_t element_brate_ref; -#ifdef NONBE_FIX_838_CRASH_24_4_WB int16_t last_bits_frame_nominal; /* last_bits_frame_nominal for M or PCh channel */ -#endif error = IVAS_ERR_OK; - push_wmops( "ivas_cpe_enc" ); hCPE = st_ivas->hCPE[cpe_id]; @@ -123,9 +120,7 @@ ivas_error ivas_cpe_enc( input_Fs = hEncoderConfig->input_Fs; ivas_total_brate = hEncoderConfig->ivas_total_brate; element_brate_ref = hCPE->element_brate; -#ifdef NONBE_FIX_838_CRASH_24_4_WB last_bits_frame_nominal = sts[0]->bits_frame_nominal; -#endif /*------------------------------------------------------------------* * Initialization - general @@ -168,7 +163,7 @@ ivas_error ivas_cpe_enc( if ( sts[0]->ini_frame > 0 && st_ivas->hMCT == NULL ) { - hCPE->element_mode = select_stereo_mode( hCPE, ivas_format, ivas_total_brate ); + hCPE->element_mode = select_stereo_mode( hCPE, ivas_format ); } stereo_mode_combined_format_enc( st_ivas, hCPE ); @@ -449,7 +444,7 @@ ivas_error ivas_cpe_enc( error = pre_proc_front_ivas( NULL, hCPE, hCPE->element_brate, nb_bits_metadata, input_frame, n, old_inp_12k8[n], old_inp_16k[n], &ener[n], &relE[n], A[n], Aw[n], epsP[n], lsp_new[n], lsp_mid[n], &vad_hover_flag[n], &attack_flag[n], realBuffer[n], imagBuffer[n], old_wsp[n], pitch_fr[n], voicing_fr[n], &loc_harm[n], &cor_map_sum[n], &vad_flag_dtx[n], enerBuffer[n], - fft_buff[n], A[0], lsp_new[0], currFlatness[n], tdm_ratio_idx, fr_bands, Etot_LR, lf_E, localVAD_HE_SAD, band_energies_LR, 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_flag : 0, 0, 0, ivas_format, ivas_total_brate ); + fft_buff[n], A[0], lsp_new[0], currFlatness[n], tdm_ratio_idx, fr_bands, Etot_LR, lf_E, localVAD_HE_SAD, band_energies_LR, 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_flag : 0, 0, 0, ivas_format, st_ivas->hMCT != NULL, ivas_total_brate ); if ( error != IVAS_ERR_OK ) { return error; @@ -497,11 +492,7 @@ ivas_error ivas_cpe_enc( /* IGF reconfiguration */ for ( n = 0; n < n_CoreChannels; n++ ) { -#ifdef NONBE_FIX_838_CRASH_24_4_WB if ( ( hCPE->last_element_brate != hCPE->element_brate || hCPE->element_mode != hCPE->last_element_mode || ( hCPE->element_mode == IVAS_CPE_TD && sts[0]->bits_frame_nominal != last_bits_frame_nominal ) || sts[n]->last_bwidth != sts[n]->bwidth ) && ( n == 0 || hCPE->element_mode == IVAS_CPE_MDCT ) ) -#else - if ( ( hCPE->last_element_brate != hCPE->element_brate || sts[n]->last_bwidth != sts[n]->bwidth ) && ( n == 0 || hCPE->element_mode == IVAS_CPE_MDCT ) ) -#endif { int16_t igf; igf = getIgfPresent( sts[n]->element_mode, sts[n]->bits_frame_nominal * FRAMES_PER_SEC, sts[n]->max_bwidth, sts[n]->rf_mode ); @@ -632,19 +623,21 @@ ivas_error ivas_cpe_enc( if ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) { max_bits -= nb_bits_metadata; - max_bits += (int16_t) ( hCPE->brate_surplus / FRAMES_PER_SEC ); + if ( hCPE->brate_surplus < 0 ) + { + max_bits += (int16_t) ( hCPE->brate_surplus / FRAMES_PER_SEC ); + } } stereo_dft_enc_res( hCPE->hStereoDft, old_inp_12k8[1] + L_INP_MEM - STEREO_DFT_OVL_8k, hCPE->hMetaData, &nb_bits, max_bits ); } + if ( sts[0]->core_brate == FRAME_NO_DATA || sts[0]->core_brate == SID_2k40 ) { assert( ( nb_bits <= ( ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS ) ) && "Stereo DFT CNG: bit budget is violated" ); } else { - assert( ( ( hCPE->element_brate / FRAMES_PER_SEC - nb_bits ) >= ( 0.8f * sts[0]->bits_frame_nominal ) ) && "Stereo DFT: bit budget is violated" ); - /* Flexible total bitrate in M channel */ sts[0]->total_brate = hCPE->element_brate - ( nb_bits * FRAMES_PER_SEC ); } diff --git a/lib_enc/ivas_dirac_enc.c b/lib_enc/ivas_dirac_enc.c index e8e770970..2c6f71d39 100644 --- a/lib_enc/ivas_dirac_enc.c +++ b/lib_enc/ivas_dirac_enc.c @@ -527,17 +527,17 @@ static int16_t ivas_dirac_get_mono_flag( *-------------------------------------------------------------------------*/ void computeReferencePower_enc( - const int16_t *band_grouping, /* i : Band grouping for estimation */ - float Cldfb_RealBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Real part of input signal */ - float Cldfb_ImagBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Imag part of input signal */ - float *reference_power, /* o : Estimated power */ - const int16_t enc_param_start_band, /* i : first band to process */ - const int16_t num_freq_bands, /* i : Number of frequency bands */ - const IVAS_FORMAT ivas_format, /* i : ivas_format */ - int16_t ref_power_w, /* i : use 0 if hodirac is enabled */ - const int16_t nchan_ana, /* i : number of analysis channels */ - int16_t *mono_frame_count, /* i/o: Mono Frame Count */ - int16_t *dirac_mono_flag /* i/o: Mono Flag */ + const int16_t *band_grouping, /* i : Band grouping for estimation */ + float Cldfb_RealBuffer[][DIRAC_NO_FB_BANDS_MAX], /* i : Real part of input signal */ + float Cldfb_ImagBuffer[][DIRAC_NO_FB_BANDS_MAX], /* i : Imag part of input signal */ + float *reference_power, /* o : Estimated power */ + const int16_t enc_param_start_band, /* i : first band to process */ + const int16_t num_freq_bands, /* i : Number of frequency bands */ + const IVAS_FORMAT ivas_format, /* i : ivas_format */ + int16_t ref_power_w, /* i : use 0 if hodirac is enabled */ + const int16_t nchan_ana, /* i : number of analysis channels */ + int16_t *mono_frame_count, /* i/o: Mono Frame Count */ + int16_t *dirac_mono_flag /* i/o: Mono Flag */ ) { int16_t brange[2]; diff --git a/lib_enc/ivas_enc.c b/lib_enc/ivas_enc.c index 36fafd8af..0672aeda8 100644 --- a/lib_enc/ivas_enc.c +++ b/lib_enc/ivas_enc.c @@ -256,6 +256,7 @@ ivas_error ivas_enc( else if ( ivas_format == MASA_ISM_FORMAT ) { float *data_separated_object; + int16_t idx_separated_object; int16_t flag_omasa_ener_brate; @@ -278,6 +279,7 @@ ivas_error ivas_enc( set_s( nb_bits_metadata, 0, MAX_SCE + 1 ); idx_separated_object = 0; + data_separated_object = data_f[hEncoderConfig->nchan_ism + CPE_CHANNELS]; /* put audio object data in SCE's */ diff --git a/lib_enc/ivas_ism_enc.c b/lib_enc/ivas_ism_enc.c index 8960038f1..5f34a92a9 100644 --- a/lib_enc/ivas_ism_enc.c +++ b/lib_enc/ivas_ism_enc.c @@ -47,7 +47,7 @@ ivas_error ivas_ism_enc( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - float *data[MAX_NUM_OBJECTS], /* i : input signal */ + float *data[], /* i : input signal [channels][samples] */ const int16_t input_frame, /* i : input frame length per channel */ int16_t *nb_bits_metadata, /* i : number of metadata bits */ const int16_t flag_omasa_ener_brate /* i : less bitrate for objects in OMASA flag */ @@ -168,7 +168,7 @@ ivas_error ivas_ism_enc( error = pre_proc_front_ivas( hSCE, NULL, hSCE->element_brate, nb_bits_metadata[sce_id], input_frame, 0, old_inp_12k8[sce_id][0], old_inp_16k[sce_id][0], &ener[sce_id][0], &relE[sce_id][0], A[sce_id][0], Aw[sce_id][0], epsP[sce_id][0], lsp_new[sce_id][0], lsp_mid[sce_id][0], &vad_hover_flag[sce_id][0], &attack_flag[sce_id][0], realBuffer[sce_id][0], imagBuffer[sce_id][0], old_wsp[sce_id][0], pitch_fr[sce_id][0], voicing_fr[sce_id][0], &loc_harm[sce_id][0], &cor_map_sum[sce_id][0], &vad_flag_dtx[sce_id][0], enerBuffer[sce_id][0], - fft_buff[sce_id][0], A[sce_id][0], lsp_new[sce_id][0], currFlatness[0], 0, fr_bands, Etot_LR, lf_E, localVAD_HE_SAD, NULL, 0, 0, 0, 0, ISM_FORMAT, st_ivas->hEncoderConfig->ivas_total_brate ); + fft_buff[sce_id][0], A[sce_id][0], lsp_new[sce_id][0], currFlatness[0], 0, fr_bands, Etot_LR, lf_E, localVAD_HE_SAD, NULL, 0, 0, 0, 0, ISM_FORMAT, 0, st_ivas->hEncoderConfig->ivas_total_brate ); if ( error != IVAS_ERR_OK ) { return error; diff --git a/lib_enc/ivas_masa_enc.c b/lib_enc/ivas_masa_enc.c index 84e835b2f..bc6993bc0 100644 --- a/lib_enc/ivas_masa_enc.c +++ b/lib_enc/ivas_masa_enc.c @@ -1984,7 +1984,7 @@ void ivas_masa_enc_reconfigure( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->total_brate = st_ivas->hCPE[cpe_id]->element_brate / ( st_ivas->nCPE > 1 ? 1 : CPE_CHANNELS ); /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ } - if ( ivas_total_brate - ism_total_brate < MASA_STEREO_MIN_BITRATE || ivas_total_brate - ism_total_brate < MIN_BRATE_MDCT_STEREO ) + if ( ivas_total_brate - ism_total_brate < MIN_BRATE_MDCT_STEREO ) { st_ivas->hCPE[cpe_id]->element_mode = IVAS_CPE_DFT; } diff --git a/lib_enc/ivas_mc_paramupmix_enc.c b/lib_enc/ivas_mc_paramupmix_enc.c index 11a38d4d5..54f1eba84 100644 --- a/lib_enc/ivas_mc_paramupmix_enc.c +++ b/lib_enc/ivas_mc_paramupmix_enc.c @@ -51,20 +51,17 @@ static void ivas_mc_paramupmix_dmx( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, floa static void ivas_mc_paramupmix_param_est_enc( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, float *input_frame_t[], const int16_t input_frame, float alphas[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS], float betas[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS] ); -static void get_huff_table( const PAR_TYPE par_type, const QUANT_TYPE quant_type, HUFF_TAB *df0, HUFF_TAB *df, HUFF_TAB *dt ); +static void get_huff_table( const PAR_TYPE par_type, HUFF_TAB *df0, HUFF_TAB *df ); static void write_huff_bits( const int32_t value, const uint16_t length, uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS], int16_t *bit_pos ); -static void huffman_encode( const int16_t bdfOnly, const int16_t bdtAllowed, const int16_t nv, const int16_t ivStart, const int32_t *vqPrev, const int32_t *vq, const PAR_TYPE parType, const QUANT_TYPE quant_type, const int16_t nq, uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS], int16_t *bit_pos ); +static void huffman_encode( const int32_t *vqPrev, const int32_t *vq, const PAR_TYPE parType, const int16_t nq, uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS], int16_t *bit_pos ); static void put_ec_data( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, const int16_t ch, const float pars[IVAS_MAX_NUM_BANDS], const float alphas[IVAS_MAX_NUM_BANDS], const PAR_TYPE parType, uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS], int16_t *bit_pos ); -static void quantize_alpha( const int16_t nv, const float *alpha, const QUANT_TYPE quant_type, int16_t *pnq, int32_t aq[IVAS_MAX_NUM_BANDS], float *adeq ); - -static void quantize_pars( const int16_t nv, const float *v, const int16_t nq, const float *data, int32_t vq[IVAS_MAX_NUM_BANDS], float *vdeq ); - -static void quantize_pars( const int16_t nv, const float *v, const int16_t nq, const float *data, int32_t vq[IVAS_MAX_NUM_BANDS], float *vdeq ); +static void quantize_alpha( const float *alpha, int16_t *pnq, int32_t aq[IVAS_MAX_NUM_BANDS], float *adeq ); +static void quantize_pars( const float *v, const int16_t nq, const float *data, int32_t vq[IVAS_MAX_NUM_BANDS], float *vdeq ); /*------------------------------------------------------------------------- * ivas_mc_paramupmix_enc() @@ -350,28 +347,22 @@ void ivas_mc_paramupmix_enc_close( static void get_huff_table( const PAR_TYPE par_type, - const QUANT_TYPE quant_type, HUFF_TAB *df0, - HUFF_TAB *df, - HUFF_TAB *dt ) + HUFF_TAB *df ) { switch ( par_type ) { case ALPHA: - df0->value = huff_alpha_table[quant_type].df0.value; - df0->length = huff_alpha_table[quant_type].df0.length; - df->value = huff_alpha_table[quant_type].df.value; - df->length = huff_alpha_table[quant_type].df.length; - dt->value = huff_alpha_table[quant_type].dt.value; - dt->length = huff_alpha_table[quant_type].dt.length; + df0->value = huff_alpha_table.df0.value; + df0->length = huff_alpha_table.df0.length; + df->value = huff_alpha_table.df.value; + df->length = huff_alpha_table.df.length; break; case BETA: - df0->value = huff_beta_table[quant_type].df0.value; - df0->length = huff_beta_table[quant_type].df0.length; - df->value = huff_beta_table[quant_type].df.value; - df->length = huff_beta_table[quant_type].df.length; - dt->value = huff_beta_table[quant_type].dt.value; - dt->length = huff_beta_table[quant_type].dt.length; + df0->value = huff_beta_table.df0.value; + df0->length = huff_beta_table.df0.length; + df->value = huff_beta_table.df.value; + df->length = huff_beta_table.df.length; break; } @@ -397,77 +388,49 @@ static void write_huff_bits( static void huffman_encode( - const int16_t bdfOnly, - const int16_t bdtAllowed, - const int16_t nv, - const int16_t ivStart, const int32_t *vqPrev, const int32_t *vq, const PAR_TYPE parType, - const QUANT_TYPE quant_type, const int16_t nq, uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS], int16_t *bit_pos ) { - int16_t iv, ndf, ndt; + int16_t iv; int32_t icode; int16_t offset; - HUFF_TAB df0, df, dt; + HUFF_TAB df0, df; - get_huff_table( parType, quant_type, &df0, &df, &dt ); + get_huff_table( parType, &df0, &df ); offset = nq - 1; /* range [-(nquant - 1), nquant - 1] */ - /* Get code length for time and freq diff coding */ - ndf = 0; - ndt = 0; - for ( iv = ivStart; iv < nv; iv++ ) + for ( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) { - if ( iv == ivStart ) + if ( iv == 0 ) { icode = vq[iv]; - ndf += df0.length[icode]; } else { icode = vq[iv] - vq[iv - 1] + offset; - ndf += df.length[icode]; } icode = vq[iv] - vqPrev[iv] + offset; - ndt += dt.length[icode]; - } - - if ( !bdtAllowed ) /* Time diff not allowed due to conformance or other reason even if bdfOnly = 0 */ - { - ndt = ndf + 1; } /* Write the bitstream */ - if ( bdfOnly || ndf < ndt ) + bit_buffer[( *bit_pos )++] = (uint16_t) 0 & 1; + for ( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) { - bit_buffer[( *bit_pos )++] = (uint16_t) 0 & 1; - for ( iv = ivStart; iv < nv; iv++ ) + if ( iv == 0 ) { - if ( iv == ivStart ) - { - icode = vq[iv]; - write_huff_bits( df0.value[icode], df0.length[icode], bit_buffer, bit_pos ); - } - else - { - icode = vq[iv] - vq[iv - 1] + offset; - write_huff_bits( df.value[icode], df.length[icode], bit_buffer, bit_pos ); - } + icode = vq[iv]; + write_huff_bits( df0.value[icode], df0.length[icode], bit_buffer, bit_pos ); } - } - else - { - bit_buffer[( *bit_pos )++] = (uint16_t) 1 & 1; - for ( iv = ivStart; iv < nv; iv++ ) + else { - icode = vq[iv] - vqPrev[iv] + offset; - write_huff_bits( dt.value[icode], dt.length[icode], bit_buffer, bit_pos ); + icode = vq[iv] - vq[iv - 1] + offset; + write_huff_bits( df.value[icode], df.length[icode], bit_buffer, bit_pos ); } } @@ -476,7 +439,6 @@ static void huffman_encode( static void quantize_pars( - const int16_t nv, const float *v, const int16_t nq, const float *data, @@ -485,7 +447,7 @@ static void quantize_pars( { int16_t iv, iq, iq0, iq1; - for ( iv = 0; iv < nv; iv++ ) + for ( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) { iq0 = 0; iq1 = nq - 1; @@ -520,9 +482,7 @@ static void quantize_pars( static void quantize_alpha( - const int16_t nv, const float *alpha, - const QUANT_TYPE quant_type, int16_t *pnq, int32_t aq[IVAS_MAX_NUM_BANDS], float *adeq ) @@ -530,11 +490,10 @@ static void quantize_alpha( int16_t nq; const float *data; - nq = ivas_mc_paramupmix_alpha_quant_table[quant_type].nquant; - data = ivas_mc_paramupmix_alpha_quant_table[quant_type].data; - - quantize_pars( nv, alpha, nq, data, aq, adeq ); + nq = ivas_mc_paramupmix_alpha_quant_table.nquant; + data = ivas_mc_paramupmix_alpha_quant_table.data; + quantize_pars( alpha, nq, data, aq, adeq ); *pnq = nq; return; @@ -542,21 +501,19 @@ static void quantize_alpha( static void quantize_beta( - const int16_t nv, const float *beta, const int32_t aq[IVAS_MAX_NUM_BANDS], - const QUANT_TYPE quant_type, int16_t *pnq, int32_t bq[IVAS_MAX_NUM_BANDS], float *bdeq ) { int16_t iv, iq, iq0, iq1; - const ACPL_QUANT_TABLE *tables = ivas_mc_paramupmix_beta_quant_table[quant_type]; + const ACPL_QUANT_TABLE *tables = ivas_mc_paramupmix_beta_quant_table; ACPL_QUANT_TABLE quant_table; - for ( iv = 0; iv < nv; iv++ ) + for ( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) { - quant_table = tables[ivas_param_upmx_mx_qmap[quant_type][aq[iv]]]; + quant_table = tables[ivas_param_upmx_mx_qmap[aq[iv]]]; iq0 = 0; iq1 = quant_table.nquant - 1; @@ -586,7 +543,7 @@ static void quantize_beta( } } - *pnq = ivas_mc_paramupmix_beta_quant_table[quant_type][0].nquant; + *pnq = ivas_mc_paramupmix_beta_quant_table[0].nquant; return; } @@ -601,10 +558,7 @@ static void put_ec_data( uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS], int16_t *bit_pos ) { - int16_t npar = IVAS_MAX_NUM_BANDS; - int16_t onlyFreq = 1; int16_t nq; - QUANT_TYPE quant_type = FINE; int32_t alphaQuant[IVAS_MAX_NUM_BANDS]; int32_t betaQuant[IVAS_MAX_NUM_BANDS]; float alphaDequant[IVAS_MAX_NUM_BANDS]; @@ -612,12 +566,12 @@ static void put_ec_data( if ( parType == ALPHA ) { - quantize_alpha( npar, pars, quant_type, &nq, alphaQuant, alphaDequant ); + quantize_alpha( pars, &nq, alphaQuant, alphaDequant ); } else { - quantize_alpha( npar, alphas, quant_type, &nq, alphaQuant, alphaDequant ); - quantize_beta( npar, pars, alphaQuant, quant_type, &nq, betaQuant, betaDequant ); + quantize_alpha( alphas, &nq, alphaQuant, alphaDequant ); + quantize_beta( pars, alphaQuant, &nq, betaQuant, betaDequant ); } if ( hMCParamUpmix->first_frame ) @@ -636,11 +590,11 @@ static void put_ec_data( /* Always one parameter set per frame for transient frames. Original PS framing is used internally. */ if ( parType == ALPHA ) { - huffman_encode( onlyFreq, 1, npar, 0, hMCParamUpmix->alpha_quant_prev[ch], alphaQuant, ALPHA, quant_type, nq, bit_buffer, bit_pos ); + huffman_encode( hMCParamUpmix->alpha_quant_prev[ch], alphaQuant, ALPHA, nq, bit_buffer, bit_pos ); } else { - huffman_encode( onlyFreq, 1, npar, 0, hMCParamUpmix->beta_quant_prev[ch], betaQuant, BETA, quant_type, nq, bit_buffer, bit_pos ); + huffman_encode( hMCParamUpmix->beta_quant_prev[ch], betaQuant, BETA, nq, bit_buffer, bit_pos ); } if ( parType == ALPHA ) diff --git a/lib_enc/ivas_mcmasa_enc.c b/lib_enc/ivas_mcmasa_enc.c index a67a9440b..7bb8092d7 100644 --- a/lib_enc/ivas_mcmasa_enc.c +++ b/lib_enc/ivas_mcmasa_enc.c @@ -66,7 +66,7 @@ static void ivas_mcmasa_dmx( MCMASA_ENC_HANDLE hMcMasa, float *data_f[], const i static void compute_cov_mtx( float sr[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], float si[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], const int16_t freq, const int16_t N, CovarianceMatrix *COVls ); -static void computeIntensityVector_enc( const int16_t *band_grouping, float Cldfb_RealBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], float Cldfb_ImagBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], const int16_t enc_param_start_band, const int16_t num_frequency_bands, float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] ); +static void computeIntensityVector_enc( const int16_t *band_grouping, float Cldfb_RealBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX], float Cldfb_ImagBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX], const int16_t enc_param_start_band, const int16_t num_frequency_bands, float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] ); static void computeVerticalDiffuseness( float **buffer_intensity, const float *buffer_energy, const int16_t averaging_length, const int16_t num_freq_bands, float *diffuseness ); @@ -1456,8 +1456,8 @@ static void compute_cov_mtx( static void computeIntensityVector_enc( const int16_t *band_grouping, - float Cldfb_RealBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], - float Cldfb_ImagBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], + float Cldfb_RealBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX], + float Cldfb_ImagBuffer[FOA_CHANNELS][DIRAC_NO_FB_BANDS_MAX], const int16_t enc_param_start_band, /* i : first band to process */ const int16_t num_frequency_bands, float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] ) diff --git a/lib_enc/ivas_mct_enc.c b/lib_enc/ivas_mct_enc.c index e18b52bea..9f1b4a416 100644 --- a/lib_enc/ivas_mct_enc.c +++ b/lib_enc/ivas_mct_enc.c @@ -325,12 +325,6 @@ ivas_error create_mct_enc( { hMCT->nchan_out_woLFE = MC_PARAMUPMIX_MAX_TRANSPORT_CHANS - 1; } -#ifndef FIX_785_REMOVE_DEAD_CODE - else if ( ivas_format == SBA_FORMAT ) - { - hMCT->nchan_out_woLFE = ivas_sba_get_nchan( st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar ); - } -#endif cp_bitrate = ivas_total_brate / hMCT->nchan_out_woLFE * CPE_CHANNELS; if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) diff --git a/lib_enc/ivas_omasa_enc.c b/lib_enc/ivas_omasa_enc.c index 34c073e91..404c1537d 100644 --- a/lib_enc/ivas_omasa_enc.c +++ b/lib_enc/ivas_omasa_enc.c @@ -124,11 +124,7 @@ ivas_error ivas_omasa_enc_open( for ( i = 0; i < MAX_NUM_OBJECTS; i++ ) { -#ifdef NONBE_FIX_819_DOUBLE_PREC_COMB_FORMATS set_f( hOMasa->prev_object_dm_gains[i], INV_SQRT_2, MASA_MAX_TRANSPORT_CHANNELS ); -#else - set_f( hOMasa->prev_object_dm_gains[i], (float) sqrt( 0.5 ), MASA_MAX_TRANSPORT_CHANNELS ); -#endif } set_zero( hOMasa->broadband_energy_sm, MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS ); set_zero( hOMasa->broadband_energy_prev, MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS ); diff --git a/lib_enc/ivas_osba_enc.c b/lib_enc/ivas_osba_enc.c index fb360a010..38c435ad1 100644 --- a/lib_enc/ivas_osba_enc.c +++ b/lib_enc/ivas_osba_enc.c @@ -69,7 +69,7 @@ static void ivas_merge_sba_transports( { for ( j = 0; j < input_frame; j++ ) { - data_out_f[i][j] = data_in_f1[i][j] + data_in_f2[i][j]; + data_out_f[i][j] = ( data_in_f1[i][j] + data_in_f2[i][j] ); } } @@ -93,7 +93,6 @@ ivas_error ivas_osba_enc_open( int16_t len; error = IVAS_ERR_OK; - if ( ( hOSba = (OSBA_ENC_HANDLE) malloc( sizeof( OSBA_ENC_DATA ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA encoder\n" ) ); @@ -101,11 +100,7 @@ ivas_error ivas_osba_enc_open( for ( i = 0; i < MAX_NUM_OBJECTS; i++ ) { -#ifdef NONBE_FIX_819_DOUBLE_PREC_COMB_FORMATS set_f( hOSba->prev_object_dm_gains[i], INV_SQRT_2, MAX_INPUT_CHANNELS ); -#else - set_f( hOSba->prev_object_dm_gains[i], (float) sqrt( 0.5 ), MAX_INPUT_CHANNELS ); -#endif } len = NS2SA( st_ivas->hEncoderConfig->input_Fs, IVAS_FB_ENC_DELAY_NS ); diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc.c index ece5a286a..adf728547 100644 --- a/lib_enc/ivas_qmetadata_enc.c +++ b/lib_enc/ivas_qmetadata_enc.c @@ -47,7 +47,6 @@ * Local function prototypes *-----------------------------------------------------------------------*/ - static void ivas_qmetadata_quantize_diffuseness_nrg_ratios( IVAS_QMETADATA_HANDLE hQMetaData, int16_t *needed_bits, int16_t *nbits_diff, int16_t *dfRatioBits, const int16_t hodirac_flag ); static int16_t ivas_qmetadata_entropy_encode_diffuseness( BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, uint16_t *diffuseness_index_max_ec_frame ); @@ -112,8 +111,6 @@ static void transform_azimuth_dir2( IVAS_QMETADATA_HANDLE hQMetaData, int16_t *d static int16_t calc_var_azi( const IVAS_QDIRECTION *q_direction, const int16_t diffuseness_index_max_ec_frame, const float avg_azimuth, float *avg_azimuth_out ); -static int16_t ivas_qmetadata_entropy_encode_diffuseness_hr( BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, uint16_t *diffuseness_index_max_ec_frame ); - static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_hr_512( IVAS_QMETADATA_HANDLE hQMetaData, int16_t *needed_bits, const int16_t bits_dir_hr, BSTR_ENC_HANDLE hMetaData ); static int16_t encode_surround_coherence_hr( IVAS_QMETADATA *hQMetaData, BSTR_ENC_HANDLE hMetaData ); @@ -1151,100 +1148,6 @@ static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_hr_512( } -/*------------------------------------------------------------------------- - * ivas_qmetadata_entropy_encode_diffuseness() - * - * encode diffuseness - *------------------------------------------------------------------------*/ - -static int16_t ivas_qmetadata_entropy_encode_diffuseness_hr( - BSTR_ENC_HANDLE hMetaData, - IVAS_QDIRECTION *q_direction, - uint16_t *diffuseness_index_max_ec_frame ) -{ - int16_t start_bit_pos; - int16_t diffuseness_bits_raw; - int16_t b; - int16_t min_diffuseness_m_index, max_diffuseness_m_index; - int16_t nbands; - int16_t start_band; - - nbands = q_direction->cfg.nbands; - start_band = q_direction->cfg.start_band; - - start_bit_pos = hMetaData->nb_bits_tot; - - if ( nbands == 1 ) - { - /* If there is only one band, diffuseness should be coded directly as raw with no signaling. */ - push_next_indice( hMetaData, q_direction->band_data[0].energy_ratio_index[0], MASA_BITS_ER_HR ); - *diffuseness_index_max_ec_frame = 10; - return ( hMetaData->nb_bits_tot - start_bit_pos ); - } - - /* compute the number of raw coding bits */ - diffuseness_bits_raw = 0; - for ( b = start_band; b < nbands; b++ ) - { - diffuseness_bits_raw += ivas_qmetadata_encode_quasi_uniform_length( q_direction->band_data[b].energy_ratio_index[0], HR_MASA_ER_LEVELS ); - } - - min_diffuseness_m_index = q_direction->band_data[start_band].energy_ratio_index[0]; - max_diffuseness_m_index = q_direction->band_data[start_band].energy_ratio_index[0]; - - for ( b = start_band; b < nbands; b++ ) - { - if ( q_direction->band_data[b].energy_ratio_index[0] < min_diffuseness_m_index ) - { - min_diffuseness_m_index = q_direction->band_data[b].energy_ratio_index[0]; - } - - if ( q_direction->band_data[b].energy_ratio_index[0] > max_diffuseness_m_index ) - { - max_diffuseness_m_index = q_direction->band_data[b].energy_ratio_index[0]; - } - } - - /* Use similarity coding approach or raw coding when there is a low number of bands. */ - /* one bit is used to indicate whether diffuseness values are entropy coded or coded raw */ - if ( min_diffuseness_m_index == max_diffuseness_m_index ) /* all values are equal */ - { - push_next_indice( hMetaData, 0, 1 ); /* dif_use_raw_coding */ - push_next_indice( hMetaData, 1, 1 ); /* dif_have_unique_value */ - ivas_qmetadata_encode_quasi_uniform( hMetaData, min_diffuseness_m_index, HR_MASA_ER_LEVELS ); /* dif_unique_value */ - } - else if ( min_diffuseness_m_index + 1 == max_diffuseness_m_index ) /* only two consecutive values are present */ - { - push_next_indice( hMetaData, 0, 1 ); /* dif_use_raw_coding */ - push_next_indice( hMetaData, 0, 1 ); /* dif_have_unique_value */ - ivas_qmetadata_encode_quasi_uniform( hMetaData, min_diffuseness_m_index, HR_MASA_ER_LEVELS - 1 ); /* dif_min_value */ - - for ( b = start_band; b < nbands; b++ ) - { - push_next_indice( hMetaData, q_direction->band_data[b].energy_ratio_index[0] - min_diffuseness_m_index, 1 ); /* dif_bit_offset_values */ - } - } - else /* raw coding */ - { - push_next_indice( hMetaData, 1, 1 ); /* dif_use_raw_coding */ - - for ( b = start_band; b < nbands; b++ ) - { - ivas_qmetadata_encode_quasi_uniform( hMetaData, q_direction->band_data[b].energy_ratio_index[0], HR_MASA_ER_LEVELS ); /* dif_values */ - } - } - - *diffuseness_index_max_ec_frame = 10; - /* adaptively select the diffuseness_index_max_ec threshold */ - if ( min_diffuseness_m_index > 10 ) - { - *diffuseness_index_max_ec_frame = HR_MASA_ER_LEVELS - 1; - } - - return ( hMetaData->nb_bits_tot - start_bit_pos ); -} - - /*------------------------------------------------------------------------- * ivas_qmetadata_quantize_diffuseness_nrg_ratios() * diff --git a/lib_enc/ivas_rom_enc.c b/lib_enc/ivas_rom_enc.c index 07e5c5c5f..ebbffc089 100644 --- a/lib_enc/ivas_rom_enc.c +++ b/lib_enc/ivas_rom_enc.c @@ -720,18 +720,21 @@ const float Stereo_dmx_wnd_coef_48k[L_FRAME48k] = { }; -const HUFF_TABLE huff_alpha_table[2] = +/*----------------------------------------------------------------------------------* + * ParamUpmix ROM tables + *----------------------------------------------------------------------------------*/ + +const HUFF_TABLE huff_alpha_table = { - { /* Alfa Fine */ { /* df0 */ - { 0x0002ce, 0x000b5e, 0x0004fe, 0x0005ae, 0x00027e, 0x0002de, 0x00016a, 0x0000b2, 0x00004a, 0x00004b, - 0x0000b6, 0x00004e, 0x000024, 0x00002e, 0x00000a, 0x000006, 0x000000, 0x000007, 0x000008, 0x00002f, - 0x000026, 0x000058, 0x0000b4, 0x00009e, 0x00016e, 0x000166, 0x0002df, 0x0002cf, 0x00027c, 0x00027d, - 0x0004ff, 0x000b5f, 0x0002d6 }, - { 10, 12, 11, 11, 10, 10, 9, 8, 7, 7, - 8, 7, 6, 6, 4, 3, 1, 3, 4, 6, - 6, 7, 8, 8, 9, 9, 10, 10, 10, 10, - 11, 12, 10 } + { 0x0002ce, 0x000b5e, 0x0004fe, 0x0005ae, 0x00027e, 0x0002de, 0x00016a, 0x0000b2, 0x00004a, 0x00004b, + 0x0000b6, 0x00004e, 0x000024, 0x00002e, 0x00000a, 0x000006, 0x000000, 0x000007, 0x000008, 0x00002f, + 0x000026, 0x000058, 0x0000b4, 0x00009e, 0x00016e, 0x000166, 0x0002df, 0x0002cf, 0x00027c, 0x00027d, + 0x0004ff, 0x000b5f, 0x0002d6 }, + { 10, 12, 11, 11, 10, 10, 9, 8, 7, 7, + 8, 7, 6, 6, 4, 3, 1, 3, 4, 6, + 6, 7, 8, 8, 9, 9, 10, 10, 10, 10, + 11, 12, 10 } }, { /* df */ { 0x0011de, 0x011ffe, 0x013dea, 0x013df6, 0x008eea, 0x013df7, 0x013dee, 0x013deb, 0x013dec, 0x008eee, @@ -748,57 +751,11 @@ const HUFF_TABLE huff_alpha_table[2] = 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 14, 15, 15, 16, 16, 17, 16, 16, 17, 16, 16, 17, 17, 17, 13 } - }, - { /* dt */ - { 0x00eeee, 0x03b3ee, 0x03b3f6, 0x03b3fc, 0x01d9bc, 0x01d9bd, 0x01d9b2, 0x03b3fe, 0x01d9be, 0x01d9f6, - 0x01d9fc, 0x00ecda, 0x00ecfa, 0x00eeef, 0x00766e, 0x007776, 0x003b3a, 0x003bba, 0x001d9a, 0x001ddc, - 0x001dde, 0x000eec, 0x000764, 0x000772, 0x0003b0, 0x0003b8, 0x0001da, 0x0001de, 0x000072, 0x000038, - 0x00001e, 0x000006, 0x000000, 0x000002, 0x00001f, 0x00003a, 0x000073, 0x0001df, 0x0001db, 0x0003ba, - 0x0003b1, 0x000773, 0x000765, 0x000eed, 0x000ecc, 0x001d9e, 0x001d9c, 0x003bbe, 0x003b3b, 0x00777e, - 0x00767c, 0x00eefe, 0x00ecfc, 0x00ecd8, 0x01d9fd, 0x01d9fa, 0x01d9bf, 0x01d9b6, 0x01d9b3, 0x03b3fd, - 0x01d9b7, 0x03b3ff, 0x03b3ef, 0x03b3f7, 0x00eeff }, - { 16, 18, 18, 18, 17, 17, 17, 18, 17, 17, - 17, 16, 16, 16, 15, 15, 14, 14, 13, 13, - 13, 12, 11, 11, 10, 10, 9, 9, 7, 6, - 5, 3, 1, 2, 5, 6, 7, 9, 9, 10, - 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, - 15, 16, 16, 16, 17, 17, 17, 17, 17, 18, - 17, 18, 18, 18, 16 } } - }, /* End Alfa Fine */ - { /* Alfa Coarse */ - { /* df0 */ - { 0x0003be, 0x0003fe, 0x0001fe, 0x0000fe, 0x00003e, 0x00003a, 0x00001e, 0x000002, 0x000000, 0x000006, - 0x00001c, 0x00007e, 0x000076, 0x0000ee, 0x0001de, 0x0003ff, 0x0003bf }, - { 10, 10, 9, 8, 6, 6, 5, 2, 1, 3, - 5, 7, 7, 8, 9, 10, 10 } - }, - { /* df */ - { 0x007c76, 0x03e3fe, 0x01f1f6, 0x01f1f7, 0x00f8ea, 0x007c74, 0x007c7c, 0x001f1c, 0x000f9e, 0x0007ce, - 0x0003e2, 0x0001f0, 0x0000fa, 0x00007e, 0x00000e, 0x000006, 0x000000, 0x000002, 0x00001e, 0x00007f, - 0x0000fb, 0x0001f2, 0x0003e6, 0x0007c6, 0x000f9f, 0x001f1e, 0x007c7e, 0x00f8fe, 0x00f8fa, 0x01f1fe, - 0x00f8eb, 0x03e3ff, 0x007c77 }, - { 15, 18, 17, 17, 16, 15, 15, 13, 12, 11, - 10, 9, 8, 7, 4, 3, 1, 2, 5, 7, - 8, 9, 10, 11, 12, 13, 15, 16, 16, 17, - 16, 18, 15 } - }, - { /* dt */ - { 0x003efc, 0x00fbfa, 0x007ddc, 0x00fbfe, 0x007dde, 0x007dfc, 0x003ef6, 0x001f76, 0x000fba, 0x000fbe, - 0x0003ec, 0x0001f2, 0x0000f8, 0x00007e, 0x00001e, 0x000006, 0x000000, 0x000002, 0x00000e, 0x00007f, - 0x0000fa, 0x0001f3, 0x0003ed, 0x0007dc, 0x000fbc, 0x001f7a, 0x003ef7, 0x007dfe, 0x007ddf, 0x00fbff, - 0x007ddd, 0x00fbfb, 0x003efd }, - { 14, 16, 15, 16, 15, 15, 14, 13, 12, 12, - 10, 9, 8, 7, 5, 3, 1, 2, 4, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 15, 16, - 15, 16, 14 } - } - } /* End Alfa Coarse */ }; -const HUFF_TABLE huff_beta_table[2] = +const HUFF_TABLE huff_beta_table = { - { /* Beta Fine */ { /* df0 */ { 0x000000, 0x000002, 0x000006, 0x00000e, 0x00001e, 0x00003e, 0x00007e, 0x0000fe, 0x0000ff }, { 1, 2, 3, 4, 5, 6, 7, 8, 8 } @@ -808,28 +765,7 @@ const HUFF_TABLE huff_beta_table[2] = 0x00000e, 0x00007f, 0x0000fb, 0x0001f3, 0x0001f0, 0x0007c6, 0x001f1f }, { 13, 12, 10, 9, 8, 7, 5, 3, 1, 2, 4, 7, 8, 9, 9, 11, 13 } - }, - { /* dt */ - { 0x007dfe, 0x003efe, 0x000fbe, 0x0003ee, 0x0000fa, 0x00007e, 0x00001e, 0x000006, 0x000000, 0x000002, - 0x00000e, 0x00007f, 0x00007c, 0x0001f6, 0x0007de, 0x001f7e, 0x007dff }, - { 15, 14, 12, 10, 8, 7, 5, 3, 1, 2, - 4, 7, 7, 9, 11, 13, 15 } - } - }, /* End Beta Fine */ - { /* Beta Coarse */ - { /* df0 */ - { 0x000000, 0x000002, 0x000006, 0x00000e, 0x00000f }, - { 1, 2, 3, 4, 4 } - }, - { /* df */ - { 0x0000fe, 0x00003e, 0x00000e, 0x000006, 0x000000, 0x000002, 0x00001e, 0x00007e, 0x0000ff }, - { 8, 6, 4, 3, 1, 2, 5, 7, 8 } - }, - { /* dt */ - { 0x0000fe, 0x00007e, 0x00001e, 0x000006, 0x000000, 0x000002, 0x00000e, 0x00003e, 0x0000ff }, - { 8, 7, 5, 3, 1, 2, 4, 6, 8 } } - } /* End Beta Coarse */ }; const int16_t mc_paramupmix_fb_remix_order[4] = {0, 1, 2, 3}; diff --git a/lib_enc/ivas_rom_enc.h b/lib_enc/ivas_rom_enc.h index c0c42f724..c15d1a27b 100644 --- a/lib_enc/ivas_rom_enc.h +++ b/lib_enc/ivas_rom_enc.h @@ -123,8 +123,12 @@ extern const float Stereo_dmx_s_wnd_coef_48k[L_FRAME48k >> 4]; extern const float Stereo_dmx_wnd_coef_32k[L_FRAME32k]; extern const float Stereo_dmx_wnd_coef_48k[L_FRAME48k]; -extern const HUFF_TABLE huff_alpha_table[2]; -extern const HUFF_TABLE huff_beta_table[2]; +/*----------------------------------------------------------------------------------* + * ParamUpmix ROM tables + *----------------------------------------------------------------------------------*/ + +extern const HUFF_TABLE huff_alpha_table; +extern const HUFF_TABLE huff_beta_table; extern const int16_t mc_paramupmix_fb_remix_order[4]; /*----------------------------------------------------------------------------------* diff --git a/lib_enc/ivas_sce_enc.c b/lib_enc/ivas_sce_enc.c index 082b0ba34..c72feda1d 100644 --- a/lib_enc/ivas_sce_enc.c +++ b/lib_enc/ivas_sce_enc.c @@ -173,7 +173,7 @@ ivas_error ivas_sce_enc( &ener[0], &relE[0], A[0], Aw[0], epsP[0], lsp_new[0], lsp_mid[0], &vad_hover_flag[0], &attack_flag[0], realBuffer[0], imagBuffer[0], old_wsp[0], pitch_fr[0], voicing_fr[0], &loc_harm[0], &cor_map_sum[0], &vad_flag_dtx[0], enerBuffer[0], fft_buff[0], A[0], lsp_new[0], currFlatness[0], 0, fr_bands, Etot_LR, lf_E, localVAD_HE_SAD, NULL, flag_16k_smc, - st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_flag : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->force_front_vad : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_dtx_flag : 0, ivas_format, st_ivas->hEncoderConfig->ivas_total_brate ); + st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_flag : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->force_front_vad : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_dtx_flag : 0, ivas_format, 0, st_ivas->hEncoderConfig->ivas_total_brate ); if ( error != IVAS_ERR_OK ) { return error; diff --git a/lib_enc/ivas_stereo_classifier.c b/lib_enc/ivas_stereo_classifier.c index 087bd8e3f..68be77ad1 100644 --- a/lib_enc/ivas_stereo_classifier.c +++ b/lib_enc/ivas_stereo_classifier.c @@ -84,9 +84,8 @@ static float redge_detect( const float *inp, const int16_t len, const float inp_ /*! r: element mode */ int16_t select_stereo_mode( - CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const int32_t ivas_total_brate /* i : IVAS total brate */ + CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure */ + const IVAS_FORMAT ivas_format /* i : IVAS format */ ) { int16_t element_mode; @@ -108,13 +107,14 @@ int16_t select_stereo_mode( hStereoClassif->lrtd_mode = ( ( hStereoClassif->unclr_decision | hStereoClassif->xtalk_decision ) && is_speech ); stereo_switching_flag = 1; - if ( hCPE->element_brate >= MIN_BRATE_MDCT_STEREO || ( ivas_format >= MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE ) + + if ( hCPE->element_brate >= MIN_BRATE_MDCT_STEREO || ( ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) && hCPE->element_brate < MASA_STEREO_MIN_BITRATE ) ) { stereo_switching_flag = 0; } - if ( hCPE->element_brate >= MIN_BRATE_MDCT_STEREO && !( hCPE->element_brate == IVAS_48k && ivas_total_brate == IVAS_32k ) ) /* the second condition for PARAM mode OMASA */ + if ( hCPE->element_brate >= MIN_BRATE_MDCT_STEREO ) { hStereoClassif->prev_lrtd_mode = 0; hStereoClassif->lrtd_mode = 0; @@ -125,7 +125,7 @@ int16_t select_stereo_mode( hStereoClassif->lrtd_mode = 0; element_mode = IVAS_CPE_DFT; - if ( hCPE->element_brate > IVAS_13k2 && hCPE->hCoreCoder[0]->hSpMusClas->past_dlp[0] < 1.0f && hCPE->hCoreCoder[0]->hSpMusClas->wdlp_xtalk < -0.01f && hCPE->hCoreCoder[0]->vad_flag == 1 && ( hCPE->hStereoMdct->sw_uncorr || hStereoClassif->xtalk_decision ) ) + if ( stereo_switching_flag == 1 && hCPE->element_brate > IVAS_13k2 && hCPE->hCoreCoder[0]->hSpMusClas->past_dlp[0] < 1.0f && hCPE->hCoreCoder[0]->hSpMusClas->wdlp_xtalk < -0.01f && hCPE->hCoreCoder[0]->vad_flag == 1 && ( hCPE->hStereoMdct->sw_uncorr || hStereoClassif->xtalk_decision ) ) { hStereoClassif->lrtd_mode = 1; element_mode = IVAS_CPE_TD; @@ -139,7 +139,14 @@ int16_t select_stereo_mode( } else if ( element_mode < IVAS_CPE_MDCT ) { - if ( element_mode == IVAS_CPE_TD ) + if ( stereo_switching_flag == 0 ) + { + if ( ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) && hCPE->element_brate < MASA_STEREO_MIN_BITRATE ) + { + element_mode = IVAS_CPE_DFT; + } + } + else if ( element_mode == IVAS_CPE_TD ) { if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec > 0 && is_speech ) { @@ -176,6 +183,7 @@ int16_t select_stereo_mode( if ( hCPE->last_element_mode != IVAS_CPE_DFT && hCPE->last_element_mode != IVAS_CPE_TD ) { int16_t lrtd_mode = hStereoClassif->lrtd_mode; + /* reset stereo classifier when switching from MDCT stereo to Unified stereo */ stereo_classifier_init( hCPE->hStereoClassif ); diff --git a/lib_enc/ivas_stereo_dft_enc.c b/lib_enc/ivas_stereo_dft_enc.c index 1233ace35..3463af2da 100644 --- a/lib_enc/ivas_stereo_dft_enc.c +++ b/lib_enc/ivas_stereo_dft_enc.c @@ -2296,7 +2296,7 @@ static void stereo_dft_enc_compute_prm( { hStereoDft->dot_prod_real_smooth[b2] = 0.5f * hStereoDft->dot_prod_real_smooth[b2] + 0.5f * dot_prod_real2; hStereoDft->dot_prod_img_smooth[b2] = 0.5f * hStereoDft->dot_prod_img_smooth[b2] + 0.5f * dot_prod_img2; - pIpd[b2] = (float) atan2( hStereoDft->dot_prod_img_smooth[b2], hStereoDft->dot_prod_real_smooth[b2] ); + pIpd[b2] = (float) atan2f( hStereoDft->dot_prod_img_smooth[b2], hStereoDft->dot_prod_real_smooth[b2] ); ipd_smooth[b2] = stereo_dft_calc_mean_bipd( &pIpd[b2], hStereoDft->ipd_buf[b2] ); @@ -2426,7 +2426,7 @@ static void stereo_dft_enc_compute_prm( { conversion_factor = 2.f / 3; } - dItd32 = (int16_t) floor( conversion_factor * hStereoDft->hItd->deltaItd[k_offset] + 0.5f ); + dItd32 = (int16_t) floorf( conversion_factor * hStereoDft->hItd->deltaItd[k_offset] + 0.5f ); gain_offset = stereo_dft_gain_offset( c, dItd32 ); pPredGain[b] = max( 0, pPredGain[b] - gain_offset ); @@ -2462,7 +2462,7 @@ static void stereo_dft_enc_compute_prm( hStereoDft->sum_dot_prod_real = ( 1.f - hStereoDft->sfm ) * hStereoDft->sum_dot_prod_real + hStereoDft->sfm * sum_dot_prod_real; hStereoDft->sum_dot_prod_img = ( 1.f - hStereoDft->sfm ) * hStereoDft->sum_dot_prod_img + hStereoDft->sfm * sum_dot_prod_img; - pgIpd[0] = (float) atan2( hStereoDft->sum_dot_prod_img, hStereoDft->sum_dot_prod_real ); + pgIpd[0] = (float) atan2f( hStereoDft->sum_dot_prod_img, hStereoDft->sum_dot_prod_real ); stereo_dft_gipd_stabilization( &pgIpd[0], hStereoDft->prev_gipd, ipd_mean_change ); hStereoDft->prev_gipd = pgIpd[0]; diff --git a/lib_enc/ivas_stereo_dft_enc_itd.c b/lib_enc/ivas_stereo_dft_enc_itd.c index 3d0fe1465..2d43e3d30 100644 --- a/lib_enc/ivas_stereo_dft_enc_itd.c +++ b/lib_enc/ivas_stereo_dft_enc_itd.c @@ -1328,7 +1328,7 @@ void stereo_dft_enc_compute_itd( if ( hItd->deltaItd[k_offset - 1] != 0 && itd_max_flip == 0 ) { - int16_t tmp_itd = (int16_t) floor( ( ( hItd->prev_itd ) * ( (float) input_frame / 640 ) ) + 0.5f ); + int16_t tmp_itd = (int16_t) floorf( ( ( hItd->prev_itd ) * ( (float) input_frame / 640 ) ) + 0.5f ); hItd->deltaItd[k_offset] = -1.0f * tmp_itd - hItd->td_itd[k_offset]; } } diff --git a/lib_enc/ivas_stereo_dft_td_itd.c b/lib_enc/ivas_stereo_dft_td_itd.c index 3a043ec54..ce5553518 100644 --- a/lib_enc/ivas_stereo_dft_td_itd.c +++ b/lib_enc/ivas_stereo_dft_td_itd.c @@ -77,7 +77,7 @@ static void stereo_td_get_td_itd( { assert( ( input_Fs % 16000 ) == 0 && "sampling frequency should be divisible by 16000" ); d = (int16_t) ( input_Fs / 16000 ); - *td_itd_32 = 2 * (int16_t) floor( itd / d + 0.5f ); + *td_itd_32 = 2 * (int16_t) floorf( itd / d + 0.5f ); *td_itd = ( ( *td_itd_32 ) / 2 ) * d; } diff --git a/lib_enc/long_enr.c b/lib_enc/long_enr.c index 118630d29..6277129f8 100644 --- a/lib_enc/long_enr.c +++ b/lib_enc/long_enr.c @@ -47,14 +47,14 @@ *-------------------------------------------------------------------*/ void long_enr( - Encoder_State *st, /* i/o: encoder state structure */ - const float Etot, /* i : total channel energy */ - const int16_t localVAD_HE_SAD, /* i : HE-SAD flag without hangover */ - const int16_t high_lpn_flag, /* i : sp/mus LPN flag */ - FRONT_VAD_ENC_HANDLE hFrontVad[CPE_CHANNELS], /* i/o: front-VAD handles */ - const int16_t n_chan, /* i : number of channels */ - const int16_t localVAD_HE_SAD_LR[CPE_CHANNELS], /* i : HE-SAD flag without hangover LR channels */ - const float Etot_LR[CPE_CHANNELS] /* i : total channel energy LR channels */ + Encoder_State *st, /* i/o: encoder state structure */ + const float Etot, /* i : total channel energy */ + const int16_t localVAD_HE_SAD, /* i : HE-SAD flag without hangover */ + const int16_t high_lpn_flag, /* i : sp/mus LPN flag */ + FRONT_VAD_ENC_HANDLE hFrontVad[], /* i/o: front-VAD handles */ + const int16_t n_chan, /* i : number of channels */ + const int16_t localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover LR channels */ + const float Etot_LR[] /* i : total channel energy LR channels */ ) { float tmp; diff --git a/lib_enc/pre_proc.c b/lib_enc/pre_proc.c index b12ee3410..cb85ea29b 100644 --- a/lib_enc/pre_proc.c +++ b/lib_enc/pre_proc.c @@ -57,9 +57,7 @@ void pre_proc( float **inp, /* o : ptr. to inp. signal in the current frame*/ float fr_bands[2 * NB_BANDS], /* i : energy in frequency bands */ float *ener, /* o : residual energy from Levinson-Durbin */ -#ifndef FIX_I4_OL_PITCH int16_t pitch_orig[3], /* o : open-loop pitch values for quantization */ -#endif float A[NB_SUBFR16k * ( M + 1 )], /* i/o: A(z) unquantized for the 4 subframes */ float Aw[NB_SUBFR16k * ( M + 1 )], /* i/o: weighted A(z) unquantized for subframes */ float epsP[M + 1], /* i/o: LP prediction errors */ @@ -846,9 +844,7 @@ void pre_proc( * ACELP/TCX20 Switching Decision *-----------------------------------------------------------------*/ -#ifndef FIX_I4_OL_PITCH mvs2s( st->pitch, pitch_orig, 3 ); -#endif if ( st->codec_mode == MODE2 ) { diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 5c37656b7..3e6fc9a48 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -1547,6 +1547,8 @@ typedef struct enc_core_structure int16_t dtx_sce_sba; /* enable use of FD CNG with transform domain cores in SCE SBA */ + int16_t sba_br_sw_while_no_data; /* Indicator for SBA bitrate switch while in FRAME_NO_DATA mode */ + } Encoder_State, *ENC_CORE_HANDLE; diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index 06b6bae9e..71ad9fec4 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -986,7 +986,7 @@ static ivas_error ivas_shoebox_config_init_params( hShoeboxConfig->room_W = 0.0f; hShoeboxConfig->room_H = 0.0f; - for ( i = 0; i < ER_ABS_COEFF; i++ ) + for ( i = 0; i < IVAS_ROOM_ABS_COEFF; i++ ) { hShoeboxConfig->abs_coeff[i] = 0.0f; } @@ -1617,7 +1617,7 @@ static ivas_error ivas_rend_crendConvolver( /*-----------------------------------------------------------------------------------------* - * Function ivas_rend_crend_Process() + * Function ivas_rend_crendProcess() * * Process call for IVAS Crend renderer *-----------------------------------------------------------------------------------------*/ @@ -1721,6 +1721,9 @@ ivas_error ivas_rend_crendProcess( return error; } } + + /* update combined orientation access index */ + ivas_combined_orientation_update_index( hCombinedOrientationData, subframe_len ); } else { @@ -1880,6 +1883,9 @@ ivas_error ivas_rend_crendProcessSubframe( { return IVAS_ERR_INVALID_INPUT_FORMAT; } + + /* update combined orientation access index */ + ivas_combined_orientation_update_index( hCombinedOrientationData, subframe_len ); } /* move to output */ @@ -1895,3 +1901,4 @@ ivas_error ivas_rend_crendProcessSubframe( } + diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 07ab219ac..28b16eb64 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -115,6 +115,7 @@ static void matrixMul( float Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Ai static void matrixTransp2Mul( float Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] ); +static void ivas_masa_ext_rend_parambin_internal( MASA_EXT_REND_HANDLE hMasaExtRend, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, float *output_f[], const int16_t subframe ); /*------------------------------------------------------------------------- * ivas_dirac_dec_init_binaural_data() @@ -266,8 +267,8 @@ ivas_error ivas_dirac_dec_init_binaural_data( st_ivas->hDiracDecBin = hDiracDecBin; - /* allocate transport channels*/ - if ( st_ivas->hDecoderConfig->Opt_5ms && st_ivas->hTcBuffer == NULL ) + /* allocate transport channels */ + if ( st_ivas->hTcBuffer == NULL ) { int16_t nchan_to_allocate; int16_t n_samples_granularity; @@ -289,7 +290,6 @@ ivas_error ivas_dirac_dec_init_binaural_data( return error; } } - return IVAS_ERR_OK; } @@ -394,12 +394,14 @@ void ivas_dirac_dec_binaural_render( uint16_t nchan_out; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; float *output_f_local[MAX_OUTPUT_CHANNELS]; + float output_f_local_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + int16_t output_length; hSpatParamRendCom = st_ivas->hSpatParamRendCom; nchan_out = BINAURAL_CHANNELS; for ( ch = 0; ch < nchan_out; ch++ ) { - output_f_local[ch] = output_f[ch]; + output_f_local[ch] = output_f_local_buff[ch]; } slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); @@ -415,6 +417,7 @@ void ivas_dirac_dec_binaural_render( last_sf++; } + output_length = 0; for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) { int16_t n_samples_sf = slot_size * hSpatParamRendCom->subframe_nbslots[subframe_idx]; @@ -424,6 +427,16 @@ void ivas_dirac_dec_binaural_render( { output_f_local[ch] += n_samples_sf; } + + output_length += n_samples_sf; + + /* update combined orientation access index */ + ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); + } + + for ( ch = 0; ch < nchan_out; ch++ ) + { + mvr2r( output_f_local_buff[ch], output_f[ch], output_length ); } if ( hSpatParamRendCom->slots_rendered == hSpatParamRendCom->num_slots ) @@ -470,100 +483,6 @@ void ivas_dirac_dec_binaural_sba_gain( } -/*------------------------------------------------------------------------- - * ivas_dirac_dec_binaural() - * - * Parametric binaural renderer main function - *------------------------------------------------------------------------*/ - -void ivas_dirac_dec_binaural( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ - float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int16_t num_subframes /* i : number of subframes to render */ -) -{ - int16_t subframe; - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; - float cng_td_buffer[L_FRAME16k]; - float *p_output[MAX_OUTPUT_CHANNELS]; - int16_t ch; - int16_t slot_size; - int16_t numInChannels; - float *decorr_signal[BINAURAL_CHANNELS], decorr_signal_buff[BINAURAL_CHANNELS][L_FRAME48k]; - - hSpatParamRendCom = st_ivas->hSpatParamRendCom; - - slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - p_output[ch] = output_f[ch]; - p_output[ch + BINAURAL_CHANNELS] = decorr_signal_buff[ch]; - } - numInChannels = nchan_transport; - if ( st_ivas->hOutSetup.separateChannelEnabled || ( st_ivas->ivas_format == MASA_ISM_FORMAT && ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) ) ) - { - numInChannels++; - } - else if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC && ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) - { - numInChannels += (uint8_t) st_ivas->nchan_ism; - } - - for ( ch = 0; ch < numInChannels; ch++ ) - { - st_ivas->hTcBuffer->tc[ch] = &output_f[ch][0]; - } - - ivas_dirac_dec_set_md_map( st_ivas, DEFAULT_JBM_CLDFB_TIMESLOTS ); - if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) - { - ivas_spar_dec_set_render_map( st_ivas, DEFAULT_JBM_CLDFB_TIMESLOTS ); - } - if ( st_ivas->hDiracDecBin->useTdDecorr ) - { - int16_t output_frame; - - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - decorr_signal[ch] = decorr_signal_buff[ch]; - st_ivas->hTcBuffer->tc[ch + BINAURAL_CHANNELS] = decorr_signal[ch]; - } - output_frame = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); - - ivas_td_decorr_process( st_ivas->hDiracDecBin->hTdDecorr, p_output, decorr_signal, output_frame ); - } - - if ( nchan_transport == 1 && st_ivas->nchan_transport != 2 && st_ivas->hSCE[0]->hCoreCoder[0] != NULL && st_ivas->hSCE[0]->hCoreCoder[0]->cng_sba_flag ) - { - Decoder_State *st = st_ivas->hSCE[0]->hCoreCoder[0]; - st_ivas->hTcBuffer->tc[nchan_transport] = &cng_td_buffer[0]; - generate_masking_noise_lb_dirac( st->hFdCngDec->hFdCngCom, st_ivas->hTcBuffer->tc[nchan_transport], DEFAULT_JBM_CLDFB_TIMESLOTS, st->cna_dirac_flag && st->flag_cna ); - } - - for ( subframe = 0; subframe < num_subframes; subframe++ ) - { - int16_t n_samples_sf = slot_size * hSpatParamRendCom->subframe_nbslots[subframe]; - - ivas_dirac_dec_binaural_internal( st_ivas, hCombinedOrientationData, p_output, nchan_transport, subframe ); - - for ( ch = 0; ch < 2 * BINAURAL_CHANNELS; ch++ ) - { - p_output[ch] += n_samples_sf; - } - hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + 1 ) % hSpatParamRendCom->dirac_md_buffer_length; - } - - for ( ch = 0; ch < 2 * BINAURAL_CHANNELS; ch++ ) - { - st_ivas->hTcBuffer->tc[ch] = NULL; - } - - return; -} - - /*------------------------------------------------------------------------- * Local functions *------------------------------------------------------------------------*/ @@ -751,7 +670,7 @@ static void ivas_dirac_dec_binaural_internal( { for ( j = 0; j < 3; j++ ) { - Rmat[i][j] = hCombinedOrientationData->Rmat[subframe][i][j]; + Rmat[i][j] = hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx][i][j]; } } @@ -763,9 +682,8 @@ static void ivas_dirac_dec_binaural_internal( } } - ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, Rmat, subframe, - hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0, st_ivas->hMasaIsmData ); + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, st_ivas->hMasaIsmData ); if ( config_data.ivas_format == ISM_FORMAT ) { @@ -793,8 +711,7 @@ static void ivas_dirac_dec_binaural_internal( } ivas_dirac_dec_binaural_determine_processing_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat, subframe, - hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0, - nchanSeparateChannels, st_ivas->hMasaIsmData ); + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, nchanSeparateChannels, st_ivas->hMasaIsmData ); ivas_dirac_dec_binaural_process_output( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_f, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, max_band_decorr, numInChannels, config_data.processReverb, subframe ); @@ -2671,3 +2588,162 @@ void ivas_omasa_preProcessStereoTransportsForMovedObjects( return; } + +static void ivas_masa_ext_rend_parambin_internal( + MASA_EXT_REND_HANDLE hMasaExtRend, + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, + float *output_f[], + const int16_t subframe ) +{ + DIRAC_DEC_BIN_HANDLE hDiracDecBin; + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; + PARAMBIN_REND_CONFIG config_data; + int16_t slot, ch, numInChannels; + float Cldfb_RealBuffer_in[6][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_in[6][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float Rmat[3][3]; + int16_t max_band_decorr; + int16_t nBins; + int16_t i, j; + int16_t nchan_transport; + + hDiracDecBin = hMasaExtRend->hDiracDecBin; + assert( hDiracDecBin ); + hSpatParamRendCom = hMasaExtRend->hSpatParamRendCom; + nBins = hSpatParamRendCom->num_freq_bands; + + /* Setup internal config. MASA EXT renderer is quite strict. */ + config_data.separateCenterChannelRendering = 0; + config_data.ivas_format = MASA_FORMAT; + config_data.mc_mode = MC_MODE_NONE; + config_data.ivas_total_brate = IVAS_512k; /* Maximum bitrate set for external renderer */ + config_data.nchan_transport = hMasaExtRend->nchan_input; + config_data.qualityBasedSmFactor = 1.0f; + config_data.processReverb = hMasaExtRend->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ? 1 : 0; + config_data.ism_mode = ISM_MODE_NONE; + + /* Set nchan_transport to number of transport channels in MASA input */ + nchan_transport = hMasaExtRend->nchan_input; + + /* The input channel number at this processing function (not nchan_transport) */ + numInChannels = BINAURAL_CHANNELS; + + Rmat[0][0] = 1.0f; + Rmat[0][1] = 0.0f; + Rmat[0][2] = 0.0f; + + Rmat[1][0] = 0.0f; + Rmat[1][1] = 1.0f; + Rmat[1][2] = 0.0f; + + Rmat[2][0] = 0.0f; + Rmat[2][1] = 0.0f; + Rmat[2][2] = 1.0f; + + /* CLDFB Analysis of input */ + for ( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ ) + { + for ( ch = 0; ch < numInChannels; ch++ ) + { + if ( ch == 0 || nchan_transport == 2 ) + { + cldfbAnalysis_ts( + &( output_f[ch][nBins * slot] ), + Cldfb_RealBuffer_in[ch][slot], + Cldfb_ImagBuffer_in[ch][slot], + nBins, hMasaExtRend->cldfbAnaRend[ch] ); + } + else /* when nchan_transport == 1 and ch == 1 */ + { + /* At mono input duplicate the channel to dual-mono, and apply gain + correction to ensure same overall level as in stereo mode */ + v_multc( Cldfb_RealBuffer_in[0][slot], INV_SQRT_2, Cldfb_RealBuffer_in[0][slot], nBins ); + v_multc( Cldfb_ImagBuffer_in[0][slot], INV_SQRT_2, Cldfb_ImagBuffer_in[0][slot], nBins ); + + mvr2r( Cldfb_RealBuffer_in[0][slot], Cldfb_RealBuffer_in[1][slot], nBins ); + mvr2r( Cldfb_ImagBuffer_in[0][slot], Cldfb_ImagBuffer_in[1][slot], nBins ); + } + } + } + + if ( hCombinedOrientationData ) + { + for ( i = 0; i < 3; i++ ) + { + for ( j = 0; j < 3; j++ ) + { + Rmat[i][j] = hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx][i][j]; + } + } + + if ( nchan_transport == 2 ) + { + adaptTransportSignalsHeadtracked( hCombinedOrientationData, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, hSpatParamRendCom->subframe_nbslots[subframe], Rmat ); + + ivas_dirac_dec_binaural_check_and_switch_transports_headtracked( hCombinedOrientationData, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, hSpatParamRendCom->subframe_nbslots[subframe], Rmat ); + } + } + + + ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, Rmat, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, NULL ); + + /* Always using CLDFB decorrelation in MASA EXT renderer */ + max_band_decorr = hDiracDecBin->h_freq_domain_decorr_ap_params->max_band_decorr; + + + + ivas_dirac_dec_binaural_determine_processing_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, + 0, NULL ); + + ivas_dirac_dec_binaural_process_output( hDiracDecBin, hSpatParamRendCom, hMasaExtRend->cldfbSynRend, output_f, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, max_band_decorr, numInChannels, config_data.processReverb, subframe ); + + hDiracDecBin->hDiffuseDist = NULL; + + hSpatParamRendCom->slots_rendered += hSpatParamRendCom->subframe_nbslots[subframe]; + hSpatParamRendCom->subframes_rendered++; + + return; +} + + +void ivas_masa_ext_rend_parambin_render( + MASA_EXT_REND_HANDLE hMasaExtRend, /* i/o: MASA ext rend structure */ + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ + float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ + const int16_t num_subframes ) /* i : number of subframes to render */ +{ + int16_t subframe; + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; + float *p_output[BINAURAL_CHANNELS]; + int16_t ch; + + hSpatParamRendCom = hMasaExtRend->hSpatParamRendCom; + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + p_output[ch] = output_f[ch]; + } + + hSpatParamRendCom->subframes_rendered = hSpatParamRendCom->dirac_read_idx; + + for ( subframe = 0; subframe < num_subframes; subframe++ ) + { + int16_t n_samples_sf = hSpatParamRendCom->slot_size * CLDFB_SLOTS_PER_SUBFRAME; + hSpatParamRendCom->slots_rendered = 0; + + ivas_masa_ext_rend_parambin_internal( hMasaExtRend, hCombinedOrientationData, p_output, hSpatParamRendCom->dirac_read_idx ); + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + p_output[ch] += n_samples_sf; + } + + ivas_combined_orientation_update_index( hCombinedOrientationData, n_samples_sf ); + + hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + 1 ) % hSpatParamRendCom->dirac_md_buffer_length; + } + + return; +} diff --git a/lib_rend/ivas_dirac_decorr_dec.c b/lib_rend/ivas_dirac_decorr_dec.c index 1f7b67835..0240eb7ea 100644 --- a/lib_rend/ivas_dirac_decorr_dec.c +++ b/lib_rend/ivas_dirac_decorr_dec.c @@ -38,9 +38,8 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" -#include "ivas_stat_dec.h" #include "ivas_cnst.h" -#include "ivas_rom_dec.h" +#include "ivas_rom_rend.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 7ac648d8d..a85ea96d0 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -1738,11 +1738,11 @@ static void ivas_dirac_dec_get_response_split_order( *------------------------------------------------------------------------*/ void ivas_dirac_dec_compute_directional_responses( - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ - DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */ - const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ - const MASA_DECODER_HANDLE hMasa, /* i : MASA decoder structure */ - MASA_ISM_DATA_HANDLE hMasaIsm, /* i : MASA_ISM data structure */ + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ + DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */ + const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ + const int16_t *masa_band_mapping, /* i : Band mapping for MASA, NULL assumes not using MASA in any form */ + MASA_ISM_DATA_HANDLE hMasaIsm, /* i : MASA_ISM data structure */ const int16_t *azimuth, const int16_t *elevation, const int16_t md_idx, @@ -1790,13 +1790,13 @@ void ivas_dirac_dec_compute_directional_responses( for ( k = 0; k < hSpatParamRendCom->num_freq_bands; ++k ) { - if ( hMasa != NULL && k == MASA_band_grouping_24[hMasa->data.band_mapping[codingBand + 1]] ) + if ( masa_band_mapping != NULL && k == MASA_band_grouping_24[masa_band_mapping[codingBand + 1]] ) { codingBand++; } - if ( hMasa != NULL && k > MASA_band_grouping_24[hMasa->data.band_mapping[codingBand]] && - k < MASA_band_grouping_24[hMasa->data.band_mapping[codingBand + 1]] && + if ( masa_band_mapping != NULL && k > MASA_band_grouping_24[masa_band_mapping[codingBand]] && + k < MASA_band_grouping_24[masa_band_mapping[codingBand + 1]] && k != hDirACRend->h_output_synthesis_psd_params.max_band_decorr ) { /* Panning gains have to be computed only for the first bin of the coding band in MASA, for other bins the previous values can be used */ @@ -1838,7 +1838,7 @@ void ivas_dirac_dec_compute_directional_responses( } } - if ( hMasa == NULL && hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) + if ( masa_band_mapping == NULL && hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { mvr2r_inc( direct_response_hoa, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); @@ -1847,7 +1847,7 @@ void ivas_dirac_dec_compute_directional_responses( mvr2r_inc( direct_response_dir2, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses[k + hSpatParamRendCom->num_freq_bands * num_channels_dir], hSpatParamRendCom->num_freq_bands, num_channels_dir ); } } - else if ( ( ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) && ( hMasa != NULL ) ) || + else if ( ( ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) && ( masa_band_mapping != NULL ) ) || hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD || hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO ) { /* Synthesize the first direction */ diff --git a/lib_rend/ivas_dirac_rend.c b/lib_rend/ivas_dirac_rend.c index 859136ac6..b998b9636 100644 --- a/lib_rend/ivas_dirac_rend.c +++ b/lib_rend/ivas_dirac_rend.c @@ -39,7 +39,7 @@ #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" -#include "ivas_rom_dec.h" +#include "ivas_rom_rend.h" #include "wmc_auto.h" @@ -194,7 +194,8 @@ ivas_error ivas_spat_hSpatParamRendCom_config( const IVAS_FORMAT ivas_format, const MC_MODE mc_mode, const int32_t output_Fs, - const int16_t hodirac_flag ) + const int16_t hodirac_flag, + const int16_t masa_ext_rend_flag ) { ivas_error error; int16_t map_idx; @@ -263,7 +264,7 @@ ivas_error ivas_spat_hSpatParamRendCom_config( hSpatParamRendCom->dirac_md_buffer_length = 0; hSpatParamRendCom->dirac_bs_md_write_idx = 0; hSpatParamRendCom->dirac_read_idx = 0; - if ( mc_mode == MC_MODE_MCMASA ) + if ( mc_mode == MC_MODE_MCMASA || masa_ext_rend_flag == 1 ) { hSpatParamRendCom->dirac_md_buffer_length = MAX_PARAM_SPATIAL_SUBFRAMES; @@ -2081,3 +2082,421 @@ void rotateAziEle_DirAC( return; } + +/* A reduced rewrite of the corresponding decoder side function */ +static void ivas_masa_ext_dirac_render_sf( + MASA_EXT_REND_HANDLE hMasaExtRend, /* i/o: IVAS decoder structure */ + float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ +) +{ + int16_t i, ch, idx_in, idx_lfe; + DIRAC_REND_HANDLE hDirACRend; + float dirEne; + float surCohEner; + float surCohRatio[CLDFB_NO_CHANNELS_MAX]; + int16_t subframe_idx; + int16_t slot_idx, index_slot; + int16_t slot_idx_start, slot_idx_start_cldfb_synth, md_idx; + int16_t nchan_transport; + int16_t masa_band_mapping[MASA_FREQUENCY_BANDS + 1]; + + /* CLDFB: last output channels reserved to LFT for CICPx */ + float Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + + /* local copies of azi, ele, diffuseness */ + int16_t azimuth[CLDFB_NO_CHANNELS_MAX]; + int16_t elevation[CLDFB_NO_CHANNELS_MAX]; + float diffuseness_vector[CLDFB_NO_CHANNELS_MAX]; + + DIRAC_DEC_STACK_MEM DirAC_mem; + float *reference_power, *reference_power_smooth; + float *onset_filter, *onset_filter_subframe, *p_onset_filter = NULL; + uint16_t coherence_flag; + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; + + push_wmops( "ivas_masa_ext_dirac_render_sf" ); + + /* Initialize aux buffers */ + hDirACRend = hMasaExtRend->hDirACRend; + hSpatParamRendCom = hMasaExtRend->hSpatParamRendCom; + nchan_transport = hMasaExtRend->nchan_input; + + DirAC_mem = hDirACRend->stack_mem; + + reference_power = DirAC_mem.reference_power; + reference_power_smooth = ( DirAC_mem.reference_power == NULL ) ? NULL : DirAC_mem.reference_power + hSpatParamRendCom->num_freq_bands; + onset_filter = DirAC_mem.onset_filter; + onset_filter_subframe = ( DirAC_mem.onset_filter == NULL ) ? NULL : DirAC_mem.onset_filter + hSpatParamRendCom->num_freq_bands; + coherence_flag = 1; /* There is always coherence assumed for ext rend of MASA */ + + /* Construct default MASA band mapping */ + for ( i = 0; i < MASA_FREQUENCY_BANDS + 1; i++ ) + { + masa_band_mapping[i] = i; + } + + /* Subframe loop */ + slot_idx_start = hSpatParamRendCom->slots_rendered; + slot_idx_start_cldfb_synth = 0; + + subframe_idx = hSpatParamRendCom->subframes_rendered; + md_idx = hSpatParamRendCom->render_to_md_map[subframe_idx]; + + /* copy parameters into local buffers*/ + mvs2s( hSpatParamRendCom->azimuth[hSpatParamRendCom->render_to_md_map[subframe_idx]], azimuth, hSpatParamRendCom->num_freq_bands ); + mvs2s( hSpatParamRendCom->elevation[hSpatParamRendCom->render_to_md_map[subframe_idx]], elevation, hSpatParamRendCom->num_freq_bands ); + mvr2r( hSpatParamRendCom->diffuseness_vector[hSpatParamRendCom->render_to_md_map[subframe_idx]], diffuseness_vector, hSpatParamRendCom->num_freq_bands ); + + if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD ) + { + set_zero( reference_power_smooth, hSpatParamRendCom->num_freq_bands ); + } + else + { + set_zero( onset_filter_subframe, hSpatParamRendCom->num_freq_bands ); + } + + /* compute response */ + if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD ) + { + ivas_dirac_dec_compute_power_factors( hSpatParamRendCom->num_freq_bands, + diffuseness_vector, + hDirACRend->h_output_synthesis_psd_params.max_band_decorr, + hDirACRend->h_output_synthesis_psd_state.direct_power_factor, + hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor ); + + if ( coherence_flag ) + { + for ( i = 0; i < hSpatParamRendCom->num_freq_bands; i++ ) + { + dirEne = hDirACRend->h_output_synthesis_psd_state.direct_power_factor[i]; + surCohEner = hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor[i] * hSpatParamRendCom->surroundingCoherence[md_idx][i]; + hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor[i] -= surCohEner; + hDirACRend->h_output_synthesis_psd_state.direct_power_factor[i] += surCohEner; + + surCohRatio[i] = surCohEner / ( 1e-12f + dirEne + surCohEner ); + } + } + else + { + set_zero( surCohRatio, hSpatParamRendCom->num_freq_bands ); + } + } + else + { + ivas_dirac_dec_compute_gain_factors( hSpatParamRendCom->num_freq_bands, + hSpatParamRendCom->diffuseness_vector[md_idx], + hDirACRend->h_output_synthesis_psd_params.max_band_decorr, + hDirACRend->h_output_synthesis_psd_state.direct_power_factor, + hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor ); + + if ( coherence_flag ) + { + for ( i = 0; i < hSpatParamRendCom->num_freq_bands; i++ ) + { + surCohRatio[i] = hSpatParamRendCom->surroundingCoherence[md_idx][i]; + } + } + else + { + set_zero( surCohRatio, hSpatParamRendCom->num_freq_bands ); + } + } + + ivas_dirac_dec_compute_directional_responses( hSpatParamRendCom, + hDirACRend, + hMasaExtRend->hVBAPdata, + masa_band_mapping, + NULL, + azimuth, + elevation, + md_idx, + surCohRatio, + 0, + NULL, + 0 ); + + + for ( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) + { + index_slot = slot_idx_start + slot_idx; + md_idx = hSpatParamRendCom->render_to_md_map[subframe_idx]; + + /* CLDFB Analysis*/ + for ( ch = 0; ch < nchan_transport; ch++ ) + { + cldfbAnalysis_ts( &( output_f[ch][hSpatParamRendCom->num_freq_bands * index_slot] ), + Cldfb_RealBuffer[ch][0], + Cldfb_ImagBuffer[ch][0], + hSpatParamRendCom->num_freq_bands, + hMasaExtRend->cldfbAnaRend[ch] ); + } + + + if ( nchan_transport == 1 ) + { + /* Need to set second CLDFB channel to zero as further processing assumes CNA content in it */ + set_zero( Cldfb_RealBuffer[1][0], hSpatParamRendCom->num_freq_bands ); + set_zero( Cldfb_ImagBuffer[1][0], hSpatParamRendCom->num_freq_bands ); + } + + /*-----------------------------------------------------------------* + * prototype signal computation + *-----------------------------------------------------------------*/ + + if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) + { + protoSignalComputation_shd( Cldfb_RealBuffer, Cldfb_ImagBuffer, + hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f, + hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f, + reference_power, slot_idx, nchan_transport, + hDirACRend->num_outputs_diff, + hSpatParamRendCom->num_freq_bands, + 0 ); + } + else if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO ) + { + protoSignalComputation2( Cldfb_RealBuffer, Cldfb_ImagBuffer, hDirACRend->proto_frame_f, + hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f, + reference_power, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth, + 0, slot_idx, hSpatParamRendCom->num_freq_bands, hDirACRend->masa_stereo_type_detect ); + } + else + { + switch ( nchan_transport ) + { + case 2: + protoSignalComputation2( Cldfb_RealBuffer, Cldfb_ImagBuffer, + hDirACRend->proto_frame_f, + hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f, + reference_power, + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth, + hDirACRend->hOutSetup.is_loudspeaker_setup, + slot_idx, + hSpatParamRendCom->num_freq_bands, + hDirACRend->masa_stereo_type_detect ); + break; + case 1: + protoSignalComputation1( Cldfb_RealBuffer, Cldfb_ImagBuffer, + hDirACRend->proto_frame_f, + hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f, + reference_power, + hDirACRend->h_output_synthesis_psd_state.proto_power_smooth, + slot_idx, + hDirACRend->num_protos_diff, + hSpatParamRendCom->num_freq_bands ); + break; + default: + return; + } + } + + /*-----------------------------------------------------------------* + * frequency domain decorrelation + *-----------------------------------------------------------------*/ + + if ( hDirACRend->proto_signal_decorr_on == 1 ) + { + /* decorrelate prototype frame */ + if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) + { + ivas_dirac_dec_decorr_process( hSpatParamRendCom->num_freq_bands, + hDirACRend->num_outputs_diff, + hDirACRend->num_protos_diff, + hDirACRend->synthesisConf, + nchan_transport, + hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f + slot_idx * 2 * hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff, + hDirACRend->num_protos_diff, + hDirACRend->proto_index_diff, + hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f + slot_idx * 2 * hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff + 2 * hSpatParamRendCom->num_freq_bands * min( 4, nchan_transport ), + onset_filter, + hDirACRend->h_freq_domain_decorr_ap_params, + hDirACRend->h_freq_domain_decorr_ap_state ); + + v_multc( onset_filter, 0.25f, onset_filter, hSpatParamRendCom->num_freq_bands ); + v_add( onset_filter, onset_filter_subframe, onset_filter_subframe, hSpatParamRendCom->num_freq_bands ); + p_onset_filter = onset_filter_subframe; + } + else + { + ivas_dirac_dec_decorr_process( hSpatParamRendCom->num_freq_bands, + hDirACRend->num_outputs_diff, + hDirACRend->num_protos_diff, + hDirACRend->synthesisConf, + nchan_transport, + hDirACRend->proto_frame_f, + hDirACRend->num_protos_diff, + hDirACRend->proto_index_diff, + DirAC_mem.frame_dec_f, + onset_filter, + hDirACRend->h_freq_domain_decorr_ap_params, + hDirACRend->h_freq_domain_decorr_ap_state ); + + hDirACRend->proto_frame_dec_f = DirAC_mem.frame_dec_f; + p_onset_filter = onset_filter; + } + } + else + { + if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) + { + set_f( onset_filter_subframe, 1.f, hSpatParamRendCom->num_freq_bands ); + p_onset_filter = onset_filter_subframe; + } + else + { + /* no frequency domain decorrelation: use prototype frame */ + hDirACRend->proto_frame_dec_f = hDirACRend->proto_frame_f; + p_onset_filter = NULL; + } + } + + /*-----------------------------------------------------------------* + * output synthesis + *-----------------------------------------------------------------*/ + + if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_LS || hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD ) + { + /* Compute diffuse prototypes */ + ivas_dirac_dec_compute_diffuse_proto( hDirACRend, hSpatParamRendCom->num_freq_bands, slot_idx ); + } + + ivas_dirac_dec_output_synthesis_process_slot( reference_power, + p_onset_filter, + azimuth, + elevation, + hSpatParamRendCom->diffuseness_vector[md_idx], + hSpatParamRendCom, + hDirACRend, + 0, + 0, + hMasaExtRend->hVBAPdata, + hDirACRend->hOutSetup, + nchan_transport, + md_idx, + 0, + 0 ); + + if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD ) + { + v_add( reference_power, reference_power_smooth, reference_power_smooth, hSpatParamRendCom->num_freq_bands ); + } + } + + ivas_dirac_dec_output_synthesis_get_interpolator( &hDirACRend->h_output_synthesis_psd_params, hSpatParamRendCom->subframe_nbslots[subframe_idx] ); + + + if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) + { + ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( Cldfb_RealBuffer, + Cldfb_ImagBuffer, + hSpatParamRendCom, + hDirACRend, + nchan_transport, + hSpatParamRendCom->subframe_nbslots[subframe_idx], + p_onset_filter, + diffuseness_vector, + 0, + 0 ); + } + else + { + ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( Cldfb_RealBuffer, + Cldfb_ImagBuffer, + hSpatParamRendCom, + hDirACRend, + hSpatParamRendCom->subframe_nbslots[subframe_idx], + diffuseness_vector, + reference_power_smooth, + 1.0f, + 0 ); + } + + /*-----------------------------------------------------------------* + * CLDFB synthesis (and binaural rendering) + *-----------------------------------------------------------------*/ + + index_slot = slot_idx_start_cldfb_synth; + + { + float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; + float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; + int16_t outchannels; + + idx_in = 0; + idx_lfe = 0; + + outchannels = hDirACRend->hOutSetup.nchan_out_woLFE + hDirACRend->hOutSetup.num_lfe; + + /* Note here that compared to decoder path, there is no separate channel ever for MASA ext rend path */ + + for ( ch = 0; ch < outchannels; ch++ ) + { + if ( ( hDirACRend->hOutSetup.num_lfe > 0 ) && ( hDirACRend->hOutSetup.index_lfe[idx_lfe] == ch ) ) + { + /* No LFE for MASA rendering */ + set_zero( &( output_f[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), hSpatParamRendCom->subframe_nbslots[subframe_idx] * hSpatParamRendCom->num_freq_bands ); + + if ( idx_lfe < ( hDirACRend->hOutSetup.num_lfe - 1 ) ) + { + idx_lfe++; + } + } + else + { + /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */ + for ( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++ ) + { + RealBuffer[i] = Cldfb_RealBuffer[idx_in][i]; + ImagBuffer[i] = Cldfb_ImagBuffer[idx_in][i]; + } + cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], hMasaExtRend->cldfbSynRend[idx_in] ); + idx_in++; + } + } + } + hSpatParamRendCom->slots_rendered += hSpatParamRendCom->subframe_nbslots[subframe_idx]; + hSpatParamRendCom->subframes_rendered++; + + pop_wmops(); + + return; +} + +void ivas_masa_ext_dirac_render( + MASA_EXT_REND_HANDLE hMasaExtRend, /* i/o: MASA renderer structure */ + float *output_f[], /* i/o: input/output signals in time domain */ + const int16_t num_subframes /* i : number of subframes to render */ +) +{ + int16_t subframe_idx; + float *output_f_local[MAX_OUTPUT_CHANNELS]; + int16_t n, n_samples_sf; + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; + + hSpatParamRendCom = hMasaExtRend->hSpatParamRendCom; + + n_samples_sf = JBM_CLDFB_SLOTS_IN_SUBFRAME * hSpatParamRendCom->slot_size; + + for ( n = 0; n < MAX_OUTPUT_CHANNELS; n++ ) + { + output_f_local[n] = output_f[n]; + } + + hSpatParamRendCom->subframes_rendered = hSpatParamRendCom->dirac_read_idx; + + for ( subframe_idx = 0; subframe_idx < num_subframes; subframe_idx++ ) + { + hSpatParamRendCom->slots_rendered = 0; + ivas_masa_ext_dirac_render_sf( hMasaExtRend, output_f_local ); + for ( n = 0; n < MAX_OUTPUT_CHANNELS; n++ ) + { + output_f_local[n] += n_samples_sf; + } + + hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + 1 ) % hSpatParamRendCom->dirac_md_buffer_length; + } + + return; +} diff --git a/lib_rend/ivas_lcld_prot.h b/lib_rend/ivas_lcld_prot.h deleted file mode 100644 index 03fb9b06f..000000000 --- a/lib_rend/ivas_lcld_prot.h +++ /dev/null @@ -1,39 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository. All Rights Reserved. - - This software is protected by copyright law and by international treaties. - The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, - Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., - Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, - Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other - contributors to this repository retain full ownership rights in their respective contributions in - the software. This notice grants no license of any kind, including but not limited to patent - license, nor is any license granted by implication, estoppel or otherwise. - - Contributors are required to enter into the IVAS codec Public Collaboration agreement before making - contributions. - - This software is provided "AS IS", without any express or implied warranties. The software is in the - development stage. It is intended exclusively for experts who have experience with such software and - solely for the purpose of inspection. All implied warranties of non-infringement, merchantability - and fitness for a particular purpose are hereby disclaimed and excluded. - - Any dispute, controversy or claim arising under or in relation to providing this software shall be - submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in - accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and - the United Nations Convention on Contracts on the International Sales of Goods. - -*******************************************************************************************************/ - -#ifndef _IVAS_LCLD_ENCODER_H_ -#define _IVAS_LCLD_ENCODER_H_ - -#include "options.h" -/* clang-format on */ - -#endif /* _LCLD_ENCODER_H_ */ diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 8399f2d34..984f35ed3 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -281,13 +281,11 @@ ivas_error ivas_td_binaural_renderer_unwrap( const int16_t lfe_idx, /* i : LFE channel index */ const IVAS_FORMAT ivas_format, /* i : IVAS format */ ISM_METADATA_HANDLE *hIsmMetaData, /* i : ISM metadata handle */ - const int16_t *enableCombinedOrientation, /* i : Combined orientation flag */ - const IVAS_QUATERNION *Quaternions, /* i : Head tracking data per subframe */ - const IVAS_VECTOR3 *Pos, /* i : Listener position data per subframe */ - const int16_t ism_md_subframe_update, /* i : Number of subframes to delay ism metadata to sync with audio */ - float *output[], /* i/o: SCE channels / Binaural synthesis */ - const int16_t output_frame, /* i : output frame length */ - const int16_t num_subframes /* i : number of subframes to render */ + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientaton data handle */ + const int16_t ism_md_subframe_update, /* i : Number of subframes to delay ism metadata to sync with audio */ + float *output[], /* i/o: SCE channels / Binaural synthesis */ + const int16_t output_frame, /* i : output frame length */ + const int16_t num_subframes /* i : number of subframes to render */ ) { int16_t subframe_length; @@ -297,6 +295,19 @@ ivas_error ivas_td_binaural_renderer_unwrap( int16_t c_indx, nS; float *p_reverb_signal[BINAURAL_CHANNELS]; int16_t ch; + int16_t *enableCombinedOrientation; /* i : Combined orientation flag */ + IVAS_QUATERNION *Quaternions; /* i : Head tracking data per subframe */ + IVAS_VECTOR3 *Pos; /* i : Listener position data per subframe */ + + enableCombinedOrientation = NULL; + Quaternions = NULL; + Pos = NULL; + if ( hCombinedOrientationData != NULL ) + { + enableCombinedOrientation = hCombinedOrientationData->enableCombinedOrientation; + Quaternions = hCombinedOrientationData->Quaternions; + Pos = hCombinedOrientationData->listenerPos; + } for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { @@ -328,7 +339,7 @@ ivas_error ivas_td_binaural_renderer_unwrap( } /* Update the listener's location/orientation */ - if ( ( error = TDREND_Update_listener_orientation( hBinRendererTd, ( enableCombinedOrientation != NULL ) ? enableCombinedOrientation[subframe_idx] : 0, ( Quaternions != NULL ) ? &Quaternions[subframe_idx] : NULL, ( Pos != NULL ) ? &Pos[subframe_idx] : NULL ) ) != IVAS_ERR_OK ) + if ( ( error = TDREND_Update_listener_orientation( hBinRendererTd, ( enableCombinedOrientation != NULL ) ? enableCombinedOrientation[hCombinedOrientationData->subframe_idx] : 0, ( Quaternions != NULL ) ? &Quaternions[hCombinedOrientationData->subframe_idx] : NULL, ( Pos != NULL ) ? &Pos[hCombinedOrientationData->subframe_idx] : NULL ) ) != IVAS_ERR_OK ) { return error; } @@ -357,6 +368,9 @@ ivas_error ivas_td_binaural_renderer_unwrap( c_indx++; } } + + /* update combined orientation access index */ + ivas_combined_orientation_update_index( hCombinedOrientationData, subframe_length ); } if ( hReverb != NULL ) @@ -730,12 +744,8 @@ ivas_error ivas_td_binaural_renderer_ext( hIsmMetaData[0]->non_diegetic_flag = currentPos->non_diegetic_flag; } - if ( ( error = ivas_td_binaural_renderer_unwrap( hReverb, transport_config, pTDRend->hBinRendererTd, num_src, lfe_idx, ivas_format, hIsmMetaData, - ( hCombinedOrientationData != NULL ) ? ( *hCombinedOrientationData )->enableCombinedOrientation : NULL, - ( hCombinedOrientationData != NULL ) ? ( *hCombinedOrientationData )->Quaternions : NULL, - ( hCombinedOrientationData != NULL ) ? ( *hCombinedOrientationData )->listenerPos : NULL, - ism_md_subframe_update_ext, p_output, output_frame, - (int16_t) ( ( output_frame * FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) / output_Fs ) ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_td_binaural_renderer_unwrap( hReverb, transport_config, pTDRend->hBinRendererTd, num_src, lfe_idx, ivas_format, hIsmMetaData, *hCombinedOrientationData, + ism_md_subframe_update_ext, p_output, output_frame, (int16_t) ( ( output_frame * FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) / output_Fs ) ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_rend/ivas_omasa_ana.c b/lib_rend/ivas_omasa_ana.c index 460beddc6..dd29384c6 100644 --- a/lib_rend/ivas_omasa_ana.c +++ b/lib_rend/ivas_omasa_ana.c @@ -147,11 +147,7 @@ ivas_error ivas_omasa_ana_open( for ( i = 0; i < MAX_NUM_OBJECTS; i++ ) { -#ifdef NONBE_FIX_819_DOUBLE_PREC_COMB_FORMATS set_f( hOMasa->prev_object_dm_gains[i], INV_SQRT_2, MASA_MAX_TRANSPORT_CHANNELS ); -#else - set_f( hOMasa->prev_object_dm_gains[i], (float) sqrt( 0.5 ), MASA_MAX_TRANSPORT_CHANNELS ); -#endif } input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC ); diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index 380ab5773..ae9312cff 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -262,7 +262,7 @@ int16_t ivas_get_nchan_buffers_dec( if ( st_ivas->ivas_format == MONO_FORMAT ) { - nchan_out_buff = 0; + nchan_out_buff = st_ivas->hDecoderConfig->nchan_out; } else if ( st_ivas->ivas_format == STEREO_FORMAT ) { @@ -307,6 +307,10 @@ int16_t ivas_get_nchan_buffers_dec( { nchan_out_buff = max( nchan_out_buff, st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ); } + else if ( output_config == IVAS_AUDIO_CONFIG_STEREO || output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) + { + nchan_out_buff = 2 * CPE_CHANNELS; + } else if ( output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) { nchan_out_buff = max( nchan_out_buff, audioCfg2channels( st_ivas->intern_config ) ); @@ -353,7 +357,7 @@ int16_t ivas_get_nchan_buffers_dec( } else { - nchan_out_buff = max( nchan_out_buff + st_ivas->nchan_ism, audioCfg2channels( output_config ) ); /* needed for iivas_spar_dec_upmixer_sf() which is based on 'nchan_out' */ + nchan_out_buff = max( nchan_out_buff + st_ivas->nchan_ism, audioCfg2channels( output_config ) ); /* needed for ivas_spar_dec_upmixer_sf() which is based on 'nchan_out' */ } } else if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) @@ -387,7 +391,6 @@ int16_t ivas_get_nchan_buffers_dec( } -#ifdef NONBE_FIX_839_MC_RS_CHANNEL_ALLOC /*-------------------------------------------------------------------* * ivas_output_buff_dec() * @@ -424,4 +427,3 @@ ivas_error ivas_output_buff_dec( return IVAS_ERR_OK; } -#endif diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index e32a339e8..ef1e6f7f3 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -77,7 +77,6 @@ int16_t ivas_get_nchan_buffers_dec( const int32_t ivas_total_brate /* i : total IVAS bitrate */ ); - /*----------------------------------------------------------------------------------* * Limiter prototypes *----------------------------------------------------------------------------------*/ @@ -110,6 +109,44 @@ void limiter_process( int16_t *strong_saturation_cnt /* i/o: counter of strong saturations (can be NULL) */ ); +/*----------------------------------------------------------------------------------* + * TD decorr. function prototypes + *----------------------------------------------------------------------------------*/ + +ivas_error ivas_td_decorr_dec_open( + ivas_td_decorr_state_t **hTdDecorr, /* i/o: TD decorrelator handle */ + const int32_t output_Fs, /* i : output sampling rate */ + const int16_t nchan_internal, /* i : number of internal channels */ + const int16_t ducking_flag /* i : ducking flag */ +); + +void ivas_td_decorr_dec_close( + ivas_td_decorr_state_t **hTdDecorr /* i/o: TD decorrelator handle */ +); + +void ivas_td_decorr_process( + ivas_td_decorr_state_t *hTdDecorr, /* i/o: TD decoderrelator handle */ + float *pcm_in[], /* i : input audio channels */ + float **ppOut_pcm, /* o : output audio channels */ + const int16_t output_frame /* i : output frame length */ +); + +ivas_error ivas_td_decorr_reconfig_dec( + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const int32_t ivas_total_brate, /* i : total IVAS bitrate */ + const int16_t nchan_transport, /* i : number of transport channels */ + const int32_t output_Fs, /* i : output sampling rate */ + ivas_td_decorr_state_t **hTdDecorr, /* i/o: TD decorrelator handle */ + uint16_t *useTdDecorr /* i/o: TD decorrelator flag */ +); + +void ivas_td_decorr_APD_iir_filter( + ivas_td_decorr_APD_filt_state_t *filter_state, /* i/o: TD decorrelator filter handle */ + float *pIn_out, /* i/o: audio channels */ + const int16_t num_APD_sections, /* i : numbef of APD sections */ + const int16_t output_frame /* i : output frame length */ +); + /*----------------------------------------------------------------------------------* * Amplitude Panning EFAP prototypes @@ -136,6 +173,31 @@ void efap_determine_gains( ); +/*----------------------------------------------------------------------------------* + * Amplitude Panning VBAP prototypes + *----------------------------------------------------------------------------------*/ + +ivas_error vbap_init_data( + VBAP_HANDLE *hVBAPdata, /* i/o: handle for VBAP data structure that will be initialized */ + const float *speaker_node_azi_deg, /* i : vector of speaker node azimuths (positive left) */ + const float *speaker_node_ele_deg, /* i : vector of speaker node elevations (positive up) */ + const int16_t num_speaker_nodes, /* i : number of speaker nodes in the set */ + const IVAS_FORMAT ivas_format /* i : IVAS format */ +); + +void vbap_free_data( + VBAP_HANDLE *hVBAPdata /* i/o: VBAP handle to be freed */ +); + +void vbap_determine_gains( + const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ + float *gains, /* o : gain vector for speaker nodes for given direction */ + const int16_t azi_deg, /* i : azimuth in degrees for panning direction (positive left) */ + const int16_t ele_deg, /* i : elevation in degrees for panning direction (positive up) */ + const int16_t use_object_mode /* i : select between object mode panning and spatial mode panning */ +); + + /*----------------------------------------------------------------------------------* * DirAC/MASA rendering *----------------------------------------------------------------------------------*/ @@ -159,14 +221,6 @@ void ivas_dirac_dec_binaural_sba_gain( const int16_t output_frame /* i : output frame length */ ); -void ivas_dirac_dec_binaural( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ - float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int16_t num_subframes /* i : number of subframes to render */ -); - void ivas_dirac_dec_binaural_render( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ @@ -176,6 +230,12 @@ void ivas_dirac_dec_binaural_render( float *output_f[] /* o : rendered time signal */ ); +void ivas_masa_ext_rend_parambin_render( + MASA_EXT_REND_HANDLE hMasaExtRend, /* i/o: MASA ext rend structure */ + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ + float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ + const int16_t num_subframes /* i : number of subframes to render */ +); ivas_error ivas_dirac_dec_init_binaural_data( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ HRTFS_PARAMBIN_HANDLE hHrtfParambin /* i : HRTF structure for rendering */ @@ -458,18 +518,18 @@ void ivas_dirac_dec_compute_power_factors( ); void ivas_dirac_dec_compute_directional_responses( - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ - DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */ - const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ - const MASA_DECODER_HANDLE hMasa, /* i : MASA decoder structure */ - MASA_ISM_DATA_HANDLE hMasaIsm, /* i : MASA_ISM data structure */ + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ + DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */ + const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ + const int16_t *masa_band_mapping, /* i : Band mapping for MASA, NULL assumes not using MASA in any form */ + MASA_ISM_DATA_HANDLE hMasaIsm, /* i : MASA_ISM data structure */ const int16_t *azimuth, const int16_t *elevation, const int16_t md_idx, const float *surCohRatio, - const int16_t shd_rot_max_order, /* i : split-order rotation method */ - const float *p_Rmat, /* i : rotation matrix */ - const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ + const int16_t shd_rot_max_order, /* i : split-order rotation method */ + const float *p_Rmat, /* i : rotation matrix */ + const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ ); void ivas_dirac_dec_get_frequency_axis( @@ -485,7 +545,8 @@ ivas_error ivas_spat_hSpatParamRendCom_config( const IVAS_FORMAT ivas_format, const MC_MODE mc_mode, const int32_t output_Fs, - const int16_t hodirac_flag + const int16_t hodirac_flag, + const int16_t masa_ext_rend_flag ); void ivas_spat_hSpatParamRendCom_close( @@ -506,6 +567,11 @@ void ivas_dirac_deallocate_parameters( const int16_t params_flag /* i : set of parameters flag */ ); +void ivas_masa_ext_dirac_render( + MASA_EXT_REND_HANDLE hMasaExtRend, /* i/o: MASA renderer structure */ + float *output_f[], /* i/o: input/output signals in time domain */ + const int16_t num_subframes /* i : number of subframes to render */ +); /*----------------------------------------------------------------------------------* * HRTF @@ -556,13 +622,11 @@ ivas_error ivas_td_binaural_renderer_unwrap( const int16_t lfe_idx, /* i : LFE channel index */ const IVAS_FORMAT ivas_format, /* i : IVAS format */ ISM_METADATA_HANDLE *hIsmMetaData, /* i : ISM metadata handle */ - const int16_t *enableCombinedOrientation, /* i : Combined orientation flag */ - const IVAS_QUATERNION *Quaternions, /* i : Head tracking data per subframe */ - const IVAS_VECTOR3 *Pos, /* i : Listener position data per subframe */ + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientaton data handle */ const int16_t ism_md_subframe_update, float *output[], /* i/o: SCE channels / Binaural synthesis */ const int16_t output_frame, /* i : output frame length */ - const int16_t num_subframes /* i : number of subframes to render */ + const int16_t num_subframes /* i : number of subframes to render */ ); ivas_error ivas_td_binaural_renderer_ext( @@ -1213,6 +1277,20 @@ void rotateFrame_sd( const int16_t subframe_idx /* i : subframe index */ ); +void ivas_combined_orientation_update_index( + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientation handle */ + const int16_t samples_rendered /* i : samples rendered since the last call */ +); + +void ivas_combined_orientation_update_start_index( + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientation handle */ + const int16_t samples_rendered /* i : samples rendered since the last call */ +); + +void ivas_combined_orientation_set_to_start_index( + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ +); + void rotateFrame_shd_cldfb( float Cldfb_RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: unrotated HOA3 signal buffer in cldfb domain real part */ float Cldfb_ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: unrotated HOA3 signal buffer in cldfb domain imag part */ @@ -1242,8 +1320,9 @@ void ivas_external_orientation_close( ); ivas_error ivas_combined_orientation_open( - COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData, /* o : combined orientation handle */ - const int16_t num_subframes /* i : number of subframes */ + COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData, /* o : combined orientation handle */ + const int32_t fs, /* i : sampling rate */ + const int16_t num_subframes /* i : number of subframes */ ); void ivas_combined_orientation_close( @@ -1385,19 +1464,19 @@ void ivas_omasa_ana_close( ); void computeIntensityVector_ana( - const int16_t *band_grouping, /* i : Band grouping for estimation */ - float Cldfb_RealBuffer[DIRAC_MAX_ANA_CHANS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */ - float Cldfb_ImagBuffer[DIRAC_MAX_ANA_CHANS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal */ - const int16_t num_frequency_bands, /* i : Number of frequency bands */ - float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] /* o : Intensity vector */ + const int16_t *band_grouping, /* i : Band grouping for estimation */ + float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */ + float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal */ + const int16_t num_frequency_bands, /* i : Number of frequency bands */ + float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] /* o : Intensity vector */ ); void computeReferencePower_ana( - const int16_t *band_grouping, /* i : Band grouping for estimation */ - float Cldfb_RealBuffer[DIRAC_MAX_ANA_CHANS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */ - float Cldfb_ImagBuffer[DIRAC_MAX_ANA_CHANS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal */ - float *reference_power, /* o : Estimated power */ - const int16_t num_freq_bands /* i : Number of frequency bands */ + const int16_t *band_grouping, /* i : Band grouping for estimation */ + float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */ + float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal */ + float *reference_power, /* o : Estimated power */ + const int16_t num_freq_bands /* i : Number of frequency bands */ ); void ivas_create_masa_out_meta( diff --git a/lib_rend/ivas_reflections.c b/lib_rend/ivas_reflections.c index ae954fbac..d5742624c 100644 --- a/lib_rend/ivas_reflections.c +++ b/lib_rend/ivas_reflections.c @@ -48,6 +48,8 @@ * Local constants/tabels *-----------------------------------------------------------------------------------------*/ +#define ER_NUM_REF 6 + static uint16_t LC_mixing_5_1[5] = { 0, 1, 2, 0, 1 }; static uint16_t LC_mixing_7_1[7] = { 0, 1, 2, 3, 4, 3, 4 }; diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb.c index 0e895db9f..cf61669c9 100644 --- a/lib_rend/ivas_reverb.c +++ b/lib_rend/ivas_reverb.c @@ -1194,8 +1194,9 @@ ivas_error ivas_reverb_open( /* Defining appropriate windowing parameters for FFT filters to prevent aliasing */ fft_hist_size = pState->fft_size - pState->fft_subblock_size; - transition_start = (int16_t) round( FFT_FILTER_WND_FLAT_REGION * fft_hist_size ); - transition_length = (int16_t) round( FFT_FILTER_WND_TRANS_REGION * fft_hist_size ); + + transition_start = (int16_t) roundf( FFT_FILTER_WND_FLAT_REGION * fft_hist_size ); + transition_length = (int16_t) roundf( FFT_FILTER_WND_TRANS_REGION * fft_hist_size ); /* Compute the window used for FFT filters */ ivas_reverb_define_window_fft( pTime_window, transition_start, transition_length, nr_fc_fft_filter ); diff --git a/lib_rend/ivas_reverb_filter_design.c b/lib_rend/ivas_reverb_filter_design.c index 8a17fc620..3bd53cdb4 100644 --- a/lib_rend/ivas_reverb_filter_design.c +++ b/lib_rend/ivas_reverb_filter_design.c @@ -584,7 +584,7 @@ void ivas_reverb_calc_color_levels( /* Limiting the frequency response gradients Find frequency band closest to chosen pivot frequency. */ - idx_pivot = (int16_t) round( STEP_LIMIT_PIVOT_FREQ / freq_step ); + idx_pivot = (int16_t) roundf( STEP_LIMIT_PIVOT_FREQ / freq_step ); /* Perform step limiting */ response_step_limit( pTarget_color_L, freq_count, RESPONSE_STEP_LIMIT_LF, RESPONSE_STEP_LIMIT_HF, idx_pivot ); @@ -720,7 +720,7 @@ void ivas_reverb_get_hrtf_set_properties( } else { - base_idx = (int16_t) floor( tbl_index ); + base_idx = (int16_t) floorf( tbl_index ); relative_pos = tbl_index - base_idx; if ( base_idx > ( in_freq_count - 2 ) ) /* In case of extrapolation (above last bin), choose nearest */ { diff --git a/lib_rend/ivas_rom_rend.c b/lib_rend/ivas_rom_rend.c index 21ab8210e..4a5bb177f 100644 --- a/lib_rend/ivas_rom_rend.c +++ b/lib_rend/ivas_rom_rend.c @@ -36,6 +36,149 @@ /* clang-format off */ +/*----------------------------------------------------------------------------------* + * DirAC renderer ROM tables + *----------------------------------------------------------------------------------*/ + +const float ls_azimuth_4d4[8] = { 45.0f, -45.0f, 135.0f, -135.0f, 45.0f, -45.0f, 135.0f, -135.0f }; + +const float ls_elevation_4d4[8] = { 0.0f, 0.0f, 0.0f, 0.0f, 35.0f, 35.0f, 35.0f, 35.0f }; + +const float diffuse_response_CICP6[5] = { 0.4219f, 0.4219f, 0.3704f, 0.5034f, 0.5034f }; + +const float diffuse_response_CICP14[7] = { 0.3817f, 0.3817f, 0.2819f, 0.5399f, 0.5399f, 0.1519f, 0.1519f }; + +const float diffuse_response_CICP16[9] = { 0.3456f, 0.3456f, 0.3035f, 0.4124f, 0.4124f, 0.2702f, 0.2702f, 0.3023f, 0.3023f }; + +const int16_t ap_pre_delay[DIRAC_DECORR_NUM_SPLIT_BANDS] = { 7, 2, 1 }; + +const int16_t ap_filter_length[DIRAC_DECORR_NUM_SPLIT_BANDS] = { 15, 6, 3 }; + +const float ap_lattice_delta_phi[DIRAC_MAX_NUM_DECORR_FILTERS*DIRAC_MAX_DECORR_FILTER_LEN] = +{ + 1.802519f, 0.922986f, 1.813685f, 1.272828f, 0.856928f, 0.366571f, 1.531249f, 1.318158f, 0.123812f, 0.897173f, 0.958696f, 1.256384f, 0.179677f, 0.668918f, 1.440292f, 1.573058f, 1.396481f, 1.191463f, 0.444143f, 1.666942f, + 1.273955f, 1.747171f, 1.408330f, 1.002782f, 1.559302f, 1.782992f, 1.474896f, 0.813181f, 1.457724f, 0.588531f, 1.384302f, 0.156493f, 0.600048f, 1.661632f, 0.538958f, 0.645429f, 0.565237f, 0.024684f, 0.264229f, 0.062140f, + 1.235343f, 0.851725f, 1.820211f, 0.116148f, 0.972111f, 0.488703f, 1.777672f, 1.452170f, 0.814134f, 1.272649f, 1.281416f, 0.101871f, 0.897888f, 0.199760f, 0.085732f, 1.686579f, 0.964558f, 0.057281f, 0.910252f, 1.662302f, + 0.955234f, 0.834348f, 1.672478f, 1.324896f, 0.444544f, 1.721172f, 0.153356f, 1.602240f, 0.171880f, 1.169774f, 0.543628f, 1.409581f, 1.763724f, 1.686754f, 1.210390f, 0.402691f, 0.983618f, 0.862997f, 1.220409f, 0.890061f, + 0.031641f, 0.461590f, 1.719550f, 1.357698f, 1.112262f, 1.166531f, 0.246097f, 1.387325f, 0.177485f, 1.446268f, 0.799476f, 1.667227f, 1.723465f, 1.505920f, 0.245874f, 1.155854f, 0.831394f, 0.677194f, 0.568871f, 1.652070f, + 0.019803f, 1.197794f, 0.635553f, 0.531682f, 0.878194f, 0.048050f, 0.080480f, 1.566743f, 0.724210f, 0.853668f, 1.741191f, 0.698465f, 1.553550f, 0.130290f, 0.688346f, 1.331091f, 0.599759f, 1.125466f, 1.764818f, 1.042879f, + 1.486589f, 1.627971f, 1.871181f, 0.102359f, 0.035021f, 1.403176f, 1.468675f, 0.190347f, 0.553282f, 1.031227f, 1.232390f, 1.255724f, 1.504443f, 0.683526f, 0.600958f, 1.746936f, 1.529243f, 1.448196f, 0.646850f, 0.116053f, + 1.283295f, 0.355220f, 1.380620f, 1.858453f, 0.818804f, 0.219006f, 0.476292f, 0.420029f, 1.291187f, 0.568738f, 1.174088f, 0.628805f, 1.753154f, 1.459582f, 1.354449f, 1.755790f, 0.441757f, 0.856240f, 1.647962f, 0.686353f, + 1.395289f, 0.699934f, 0.239310f, 0.239535f, 0.958190f, 0.748780f, 0.513784f, 1.666344f, 1.461995f, 1.599060f, 0.893107f, 0.341873f, 1.387703f, 1.808363f, 0.676542f, 1.424958f, 0.310574f, 0.836247f, 1.011101f, 1.686200f, + 1.823432f, 0.994827f, 1.635555f, 0.684380f, 1.017029f, 1.440371f, 1.694641f, 0.607132f, 1.197331f, 0.862161f, 0.666449f, 1.047956f, 0.159627f, 0.043131f, 1.251515f, 1.618724f, 0.216906f, 0.152250f, 0.471610f, 0.744260f, + 0.576810f, 1.632177f, 1.556912f, 1.866317f, 0.568088f, 1.541817f, 1.726725f, 0.275154f, 0.814958f, 0.863399f, 1.333040f, 0.148277f, 0.197893f, 1.048665f, 1.158090f, 1.692225f, 0.884294f, 0.289619f, 0.380633f, 1.728234f, + 1.433213f, 1.749505f, 1.533837f, 0.669701f, 0.372580f, 1.052390f, 1.116645f, 0.181320f, 1.139126f, 0.222671f, 0.604393f, 1.811797f, 1.743315f, 1.368792f, 1.861434f, 0.751908f, 0.159811f, 1.566503f, 0.443273f, 1.667530f, + 1.083060f, 1.243136f, 0.717777f, 0.675019f, 0.690490f, 0.672228f, 1.060789f, 0.423566f, 1.198457f, 0.485768f, 0.993953f, 0.443540f, 0.361702f, 1.552042f, 0.863562f, 1.517677f, 1.061899f, 0.691413f, 1.642818f, 1.756590f, + 0.278323f, 0.790363f, 0.172303f, 0.417138f, 0.009343f, 0.783325f, 1.369303f, 1.041067f, 0.467102f, 0.992773f, 1.525170f, 0.871213f, 0.243906f, 1.542036f, 0.449148f, 0.843633f, 0.191800f, 1.614246f, 1.038188f, 1.415620f, + 0.551081f, 0.382599f, 1.410121f, 0.102084f, 0.137286f, 0.671081f, 0.254860f, 1.758068f, 1.079013f, 0.129143f, 1.410873f, 0.150485f, 0.601119f, 0.760737f, 0.975905f, 0.223261f, 0.710162f, 1.677048f, 0.996836f, 1.849865f, + 1.536222f, 0.089016f, 0.960881f, 0.388690f, 0.379955f, 1.002223f, 1.271420f, 1.410632f, 0.254397f, 1.535559f, 1.133703f, 1.305280f, 1.466565f, 0.274167f, 0.399688f, 1.359638f, 1.766289f, 1.401348f, 1.310883f, 0.261030f, + 1.314825f, 1.538635f, 1.317986f, 1.243167f, 1.749461f, 1.689706f, 0.024853f, 0.634754f, 1.036317f, 1.828101f, 1.676951f, 0.023606f, 0.857000f, 0.076471f, 1.622198f, 0.254469f, 1.451625f, 1.720881f, 0.763812f, 0.186982f, + 0.056994f, 0.590507f, 0.375291f, 1.609261f, 0.607721f, 0.026355f, 0.483366f, 0.823931f, 0.792878f, 0.163577f, 0.753588f, 0.730789f, 0.135991f, 1.031660f, 1.554135f, 1.192863f, 0.016693f, 0.125796f, 1.017920f, 1.591773f, + 0.575956f, 0.112943f, 0.249506f, 1.399570f, 0.053241f, 1.410759f, 0.251638f, 1.059086f, 0.025315f, 1.422914f, 1.030412f, 0.848758f, 0.317396f, 1.375456f, 1.116858f, 1.682310f, 0.279550f, 0.325974f, 0.937704f, 1.744329f, + 0.447773f, 1.024286f, 1.001528f, 1.863684f, 1.278323f, 0.860699f, 1.346331f, 1.692596f, 0.022627f, 1.033613f, 0.546354f, 0.395804f, 1.486546f, 1.381045f, 1.312260f, 0.245976f, 1.607429f, 1.818793f, 0.964359f, 1.496598f, + 0.669967f, 1.535929f, 1.841878f, 0.979127f, 0.614002f, 1.879218f, 0.512531f, 1.167061f, 0.081697f, 1.773427f, 1.535668f, 0.757729f, 0.220395f, 1.538243f, 1.281162f, 0.302159f, 0.889871f, 0.798522f, 1.476288f, 1.665941f, + 0.915365f, 1.394094f, 0.757041f, 0.350064f, 1.199679f, 1.319499f, 1.128405f, 0.632337f, 0.790673f, 0.461582f, 1.693343f, 1.537442f, 0.346527f, 0.433782f, 1.754552f, 0.550903f, 0.686724f, 0.764433f, 1.792750f, 1.489998f +}; + +const float ap_lattice_coeffs_1[DIRAC_DECORR_FILTER_LEN_1*DIRAC_MAX_NUM_DECORR_FILTERS] = +{ + 0.795329f, 0.502700f, 0.204456f, 0.416566f, 0.459648f, 0.270454f, -0.201944f, 0.027997f, 0.067811f, -0.052627f, -0.038779f, -0.057387f, 0.020480f, 0.367697f, -0.593705f, + 0.533667f, 0.202500f, -0.001953f, 0.195081f, -0.184458f, -0.233867f, 0.228100f, -0.329293f, -0.338714f, -0.079700f, 0.052389f, -0.009468f, 0.178807f, 0.190843f, -0.478877f, + 0.044022f, 0.788498f, 0.133529f, -0.173657f, 0.545391f, 0.681431f, 0.332868f, 0.294685f, 0.325261f, 0.047617f, 0.157401f, 0.116272f, 0.218980f, -0.189248f, -0.317401f, + -0.753681f, 0.772385f, -0.507384f, 0.276980f, -0.692775f, 0.232302f, -0.354759f, -0.015620f, -0.223059f, 0.310506f, -0.035034f, 0.085783f, -0.499998f, 0.215260f, 0.201415f, + -0.495551f, -0.301660f, 0.196510f, 0.326147f, -0.594364f, 0.314921f, 0.668671f, 0.076643f, 0.045711f, -0.124790f, -0.203272f, -0.297190f, 0.125806f, -0.179483f, -0.201757f, + 0.161128f, 0.396050f, 0.266897f, 0.356586f, 0.488145f, -0.056254f, 0.139280f, -0.296405f, -0.112844f, 0.037405f, -0.367425f, -0.216292f, -0.277360f, 0.389420f, 0.115115f, + -0.240449f, -0.271015f, 0.426720f, -0.011059f, 0.151813f, 0.253490f, 0.225764f, 0.498716f, -0.136377f, 0.443004f, -0.305017f, -0.031310f, -0.010765f, 0.170349f, 0.496478f, + -0.139875f, -0.241998f, -0.104850f, 0.294343f, -0.067728f, -0.492202f, -0.487610f, 0.036395f, 0.109393f, 0.396155f, -0.352845f, -0.205913f, -0.082999f, -0.463033f, -0.309296f, + 0.025886f, -0.092456f, -0.125139f, -0.156117f, -0.004887f, 0.178440f, 0.089586f, 0.044827f, 0.238219f, -0.312120f, -0.390688f, -0.178543f, 0.454418f, 0.387012f, -0.388874f, + -0.197797f, 0.035540f, 0.455388f, -0.054410f, 0.380035f, 0.290964f, 0.048804f, 0.078637f, 0.221740f, -0.217548f, 0.121289f, -0.396681f, -0.218482f, -0.127265f, -0.269507f, + -0.344218f, -0.465038f, -0.421415f, -0.026031f, 0.221547f, 0.361993f, -0.348243f, 0.294983f, 0.366175f, 0.070663f, -0.086050f, 0.252129f, 0.156066f, -0.062800f, 0.408972f, + 0.242461f, -0.301764f, -0.066160f, 0.388651f, -0.462227f, -0.158880f, 0.230796f, -0.093179f, 0.047076f, 0.073402f, -0.335018f, 0.022940f, 0.354611f, 0.072391f, 0.019473f, + 0.336900f, -0.480534f, 0.170267f, 0.259663f, -0.393576f, -0.348588f, -0.108962f, 0.278842f, 0.385490f, 0.362249f, -0.318739f, 0.362305f, 0.288936f, 0.291204f, -0.278019f, + -0.449302f, -0.288513f, -0.413973f, -0.405279f, -0.295152f, -0.245110f, 0.002530f, 0.287890f, 0.348229f, -0.178354f, -0.206517f, 0.351081f, -0.482205f, 0.021360f, -0.492207f, + 0.048642f, 0.453282f, 0.109160f, 0.232599f, -0.473781f, 0.140502f, 0.352527f, -0.098606f, 0.147172f, -0.055797f, 0.107739f, -0.231026f, 0.357310f, 0.348031f, 0.232404f, + -0.324788f, 0.162480f, 0.057647f, -0.060734f, -0.009742f, -0.224185f, -0.282355f, -0.065443f, 0.064697f, 0.280370f, -0.284906f, -0.470501f, 0.019484f, -0.442308f, 0.377214f, + 0.447384f, -0.290498f, 0.345528f, 0.370207f, -0.313120f, 0.119592f, 0.300014f, 0.406995f, -0.277922f, 0.447039f, 0.194824f, 0.157703f, -0.223402f, -0.147167f, 0.379073f, + -0.216342f, 0.137967f, -0.397180f, 0.073905f, -0.273110f, -0.443037f, -0.168327f, 0.346264f, 0.037543f, 0.065387f, 0.163901f, -0.122523f, 0.365477f, -0.316321f, 0.117273f, + -0.301282f, 0.169625f, -0.336466f, 0.269914f, -0.420160f, -0.331296f, 0.498523f, -0.393009f, -0.462184f, -0.323097f, 0.470977f, -0.359463f, 0.264315f, 0.216797f, 0.493400f, + 0.151489f, -0.321653f, 0.464413f, -0.355673f, 0.420401f, 0.184297f, -0.302128f, 0.136536f, -0.252849f, 0.193906f, 0.298775f, 0.238808f, -0.386298f, -0.181999f, -0.077326f, + 0.124840f, -0.263394f, 0.389606f, 0.004502f, 0.339804f, 0.415204f, 0.377751f, 0.400221f, 0.352426f, -0.003808f, -0.184530f, 0.433348f, -0.237554f, 0.147684f, 0.407210f, + 0.067616f, -0.249313f, -0.354010f, 0.320937f, 0.426000f, 0.309576f, -0.189689f, -0.209447f, 0.158967f, -0.081929f, 0.386828f, 0.178582f, -0.407143f, 0.222189f, -0.149097f +}; + +const float ap_lattice_coeffs_2[DIRAC_DECORR_FILTER_LEN_2*DIRAC_MAX_NUM_DECORR_FILTERS] = +{ + 0.633692f, 0.681207f, -0.049418f, 0.286715f, 0.146022f, 0.135402f, + -0.410145f, -0.206766f, -0.656968f, -0.101746f, 0.436299f, 0.339818f, + -0.131383f, -0.773746f, -0.301627f, 0.327561f, 0.332227f, 0.205858f, + 0.717602f, -0.552370f, -0.150136f, 0.054556f, 0.239519f, -0.648477f, + -0.721848f, 0.189377f, 0.068185f, 0.006216f, 0.077025f, 0.038678f, + 0.423415f, -0.108658f, 0.432050f, -0.414641f, 0.277840f, 0.418486f, + 0.077811f, -0.283063f, -0.357008f, 0.004634f, -0.442640f, -0.372315f, + 0.403336f, 0.243023f, 0.314367f, 0.444513f, 0.347517f, 0.496043f, + 0.108408f, 0.469382f, -0.170286f, 0.326310f, 0.172157f, 0.440334f, + 0.058417f, 0.339673f, -0.194965f, 0.491219f, -0.281296f, -0.043120f, + -0.482487f, -0.335005f, -0.336159f, 0.196469f, -0.164623f, 0.442491f, + -0.135190f, -0.354385f, 0.452133f, -0.311221f, -0.347640f, 0.498342f, + -0.288999f, 0.376431f, -0.177924f, 0.195542f, 0.333872f, -0.152697f, + 0.053230f, 0.457767f, 0.442476f, 0.235254f, -0.345159f, -0.286098f, + 0.155438f, 0.405393f, 0.217073f, -0.107960f, 0.010698f, 0.368987f, + -0.498358f, -0.495816f, -0.215479f, -0.093869f, 0.320276f, -0.013842f, + 0.489406f, 0.470814f, -0.065834f, 0.346871f, 0.027279f, 0.150086f, + 0.484013f, -0.497391f, 0.168796f, -0.493841f, -0.173528f, 0.334676f, + 0.264235f, -0.424651f, -0.314926f, 0.253086f, 0.397381f, -0.491565f, + -0.453727f, -0.463358f, -0.019128f, 0.000344f, 0.315432f, 0.472345f, + 0.095139f, 0.283375f, -0.225088f, -0.119762f, -0.476871f, 0.037525f, + 0.336951f, 0.494511f, -0.062603f, 0.177652f, 0.463892f, 0.489286f +}; + +const float ap_lattice_coeffs_3[DIRAC_DECORR_FILTER_LEN_3*DIRAC_MAX_NUM_DECORR_FILTERS] = +{ + 0.018977f, -0.212205f, 0.422719f, + -0.400657f, -0.106890f, -0.024589f, + 0.140005f, 0.279582f, 0.032357f, + 0.632535f, 0.578535f, -0.734606f, + 0.017182f, 0.013244f, -0.027715f, + -0.353356f, -0.482160f, -0.491265f, + 0.457024f, 0.165122f, 0.469723f, + -0.195705f, 0.440105f, -0.477366f, + 0.360186f, -0.490565f, 0.484623f, + -0.173791f, 0.007543f, 0.278186f, + 0.434416f, 0.060363f, -0.193717f, + -0.033709f, 0.496222f, 0.002939f, + -0.480848f, -0.109552f, -0.023198f, + 0.324679f, -0.292075f, -0.356148f, + -0.366595f, 0.380917f, -0.301741f, + 0.110318f, 0.383789f, 0.303984f, + -0.499685f, -0.349584f, 0.334749f, + -0.020224f, -0.430078f, -0.154705f, + -0.371129f, 0.334080f, 0.346913f, + -0.166781f, -0.229089f, 0.117956f, + 0.341292f, 0.490463f, 0.493655f, + -0.367726f, 0.426528f, -0.045774f +}; + +const float * const ap_lattice_coeffs[DIRAC_DECORR_NUM_SPLIT_BANDS] = +{ + &ap_lattice_coeffs_1[0], + &ap_lattice_coeffs_2[0], + &ap_lattice_coeffs_3[0], +}; + +const float ap_split_frequencies[DIRAC_DECORR_NUM_SPLIT_BANDS + 1] = +{ + 0.0f, 0.125f, 0.375f, 1.0f +}; + +const int16_t sba_map_tc[11] = +{ + 0, 1, 2, 3, 4, 8, 9, 15, 5, 6, 7 +}; +const int16_t sba_map_tc_512[11] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15 +}; + /*----------------------------------------------------------------------------------* * FASTCONV and PARAMETRIC binaural renderer ROM tables *----------------------------------------------------------------------------------*/ diff --git a/lib_rend/ivas_rom_rend.h b/lib_rend/ivas_rom_rend.h index 6e67315b8..9e7d0b889 100644 --- a/lib_rend/ivas_rom_rend.h +++ b/lib_rend/ivas_rom_rend.h @@ -38,6 +38,28 @@ #include "ivas_cnst.h" #include "ivas_stat_rend.h" +/*----------------------------------------------------------------------------------* + * DirAC renderer ROM tables + *----------------------------------------------------------------------------------*/ + +extern const float ls_azimuth_4d4[8]; +extern const float ls_elevation_4d4[8]; +extern const float diffuse_response_CICP6[5]; +extern const float diffuse_response_CICP14[7]; +extern const float diffuse_response_CICP16[9]; + +extern const int16_t ap_pre_delay[DIRAC_DECORR_NUM_SPLIT_BANDS]; +extern const int16_t ap_filter_length[DIRAC_DECORR_NUM_SPLIT_BANDS]; +extern const float ap_lattice_delta_phi[DIRAC_MAX_NUM_DECORR_FILTERS * DIRAC_MAX_DECORR_FILTER_LEN]; +extern const float ap_lattice_coeffs_1[DIRAC_DECORR_FILTER_LEN_1 * DIRAC_MAX_NUM_DECORR_FILTERS]; +extern const float ap_lattice_coeffs_2[DIRAC_DECORR_FILTER_LEN_2 * DIRAC_MAX_NUM_DECORR_FILTERS]; +extern const float ap_lattice_coeffs_3[DIRAC_DECORR_FILTER_LEN_3 * DIRAC_MAX_NUM_DECORR_FILTERS]; +extern const float *const ap_lattice_coeffs[DIRAC_DECORR_NUM_SPLIT_BANDS]; +extern const float ap_split_frequencies[DIRAC_DECORR_NUM_SPLIT_BANDS + 1]; + +extern const int16_t sba_map_tc[11]; +extern const int16_t sba_map_tc_512[11]; + /*----------------------------------------------------------------------------------* * FASTCONV and PARAMETRIC binaural renderer ROM tables *----------------------------------------------------------------------------------*/ diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 9826da1fd..bda768ca4 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -326,7 +326,7 @@ void rotateFrame_shd( /* calculate ambisonics rotation matrices for the previous and current frames */ SHrotmatgen( SHrotmat_prev, hCombinedOrientationData->Rmat_prev, shd_rot_max_order ); - SHrotmatgen( SHrotmat, hCombinedOrientationData->Rmat[subframe_idx], shd_rot_max_order ); + SHrotmatgen( SHrotmat, hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], shd_rot_max_order ); for ( i = 0; i < subframe_len; i++ ) { @@ -380,7 +380,7 @@ void rotateFrame_shd( for ( i = 0; i < 3; i++ ) { mvr2r( - hCombinedOrientationData->Rmat[subframe_idx][i], + hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx][i], hCombinedOrientationData->Rmat_prev[i], 3 ); } @@ -468,7 +468,8 @@ void rotateFrame_sd( } /* gains for current subframe rotation */ - rotateAziEle( hTransSetup.ls_azimuth[ch_in_woLFE], hTransSetup.ls_elevation[ch_in_woLFE], &azimuth, &elevation, hCombinedOrientationData->Rmat[subframe_idx], hTransSetup.is_planar_setup ); + rotateAziEle( hTransSetup.ls_azimuth[ch_in_woLFE], hTransSetup.ls_elevation[ch_in_woLFE], &azimuth, &elevation, hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], hTransSetup.is_planar_setup ); + if ( hEFAPdata != NULL && ( hTransSetup.ls_azimuth[ch_in_woLFE] != azimuth || hTransSetup.ls_elevation[ch_in_woLFE] != elevation ) ) { efap_determine_gains( hEFAPdata, tmp_gains, azimuth, elevation, EFAP_MODE_EFAP ); @@ -506,7 +507,7 @@ void rotateFrame_sd( for ( i = 0; i < 3; i++ ) { mvr2r( - hCombinedOrientationData->Rmat[subframe_idx][i], + hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx][i], hCombinedOrientationData->Rmat_prev[i], 3 ); } @@ -791,7 +792,8 @@ void ivas_external_orientation_close( ivas_error ivas_combined_orientation_open( COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData, /* o : combined orientation handle */ - const int16_t num_subframes /* i : number of subframes */ + const int32_t fs, /* i : sampling rate */ + const int16_t num_subframes /* i : number of subframes */ ) { int16_t i; @@ -861,6 +863,10 @@ ivas_error ivas_combined_orientation_open( ( *hCombinedOrientationData )->isExtOrientationFrozen = 0; ( *hCombinedOrientationData )->isHeadRotationFrozen = 0; + ( *hCombinedOrientationData )->subframe_idx = 0; + ( *hCombinedOrientationData )->subframe_size = (int16_t) ( fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ); + ( *hCombinedOrientationData )->cur_subframe_samples_rendered = 0; + return IVAS_ERR_OK; } @@ -1199,6 +1205,10 @@ ivas_error combine_external_and_head_orientations( } } + hCombinedOrientationData->subframe_idx = 0; + hCombinedOrientationData->cur_subframe_samples_rendered = 0; + hCombinedOrientationData->subframe_idx_start = 0; + hCombinedOrientationData->cur_subframe_samples_rendered_start = 0; return IVAS_ERR_OK; } @@ -1547,3 +1557,87 @@ void SHrotmatgen( return; } + + +/*------------------------------------------------------------------------- + * ivas_combined_orientation_update_index() + * + * update read index based on the number of rendered samples + *------------------------------------------------------------------------*/ + +void ivas_combined_orientation_update_index( + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientation handle */ + const int16_t samples_rendered /* i : samples rendered since the last call */ +) +{ + if ( hCombinedOrientationData != NULL ) + { + if ( hCombinedOrientationData->num_subframes == 1 + ) + { + /* only one orientation available anyway or split rendering with low resolution*/ + hCombinedOrientationData->subframe_idx = 0; + } + else + { + hCombinedOrientationData->cur_subframe_samples_rendered += samples_rendered; + hCombinedOrientationData->subframe_idx += hCombinedOrientationData->cur_subframe_samples_rendered / hCombinedOrientationData->subframe_size; + hCombinedOrientationData->cur_subframe_samples_rendered = hCombinedOrientationData->cur_subframe_samples_rendered % hCombinedOrientationData->subframe_size; + hCombinedOrientationData->subframe_idx = min( hCombinedOrientationData->subframe_idx, hCombinedOrientationData->num_subframes - 1 ); + } + } + + return; +} + + +/*------------------------------------------------------------------------- + * ivas_combined_orientation_update_index() + * + * update read index based on the number of rendered samples + *------------------------------------------------------------------------*/ + +void ivas_combined_orientation_set_to_start_index( + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ +) +{ + if ( hCombinedOrientationData != NULL ) + { + hCombinedOrientationData->subframe_idx = hCombinedOrientationData->subframe_idx_start; + hCombinedOrientationData->cur_subframe_samples_rendered = hCombinedOrientationData->cur_subframe_samples_rendered_start; + } + + return; +} + + +/*------------------------------------------------------------------------- + * ivas_combined_orientation_update_start_index() + * + * update start index based on the number of rendered samples + *------------------------------------------------------------------------*/ + +void ivas_combined_orientation_update_start_index( + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientation handle */ + const int16_t samples_rendered /* i : samples rendered since the last call */ +) +{ + if ( hCombinedOrientationData != NULL ) + { + if ( hCombinedOrientationData->num_subframes == 1 ) + { + /* only one orientation available anyway or split rendering with low resolution*/ + hCombinedOrientationData->subframe_idx = 0; + } + else + { + hCombinedOrientationData->cur_subframe_samples_rendered_start += samples_rendered; + hCombinedOrientationData->subframe_idx_start += hCombinedOrientationData->cur_subframe_samples_rendered / hCombinedOrientationData->subframe_size; + hCombinedOrientationData->cur_subframe_samples_rendered_start = hCombinedOrientationData->cur_subframe_samples_rendered % hCombinedOrientationData->subframe_size; + hCombinedOrientationData->subframe_idx_start = min( hCombinedOrientationData->subframe_idx, hCombinedOrientationData->num_subframes - 1 ); + } + } + + return; +} + diff --git a/lib_rend/ivas_shoebox.c b/lib_rend/ivas_shoebox.c index 7c0f3c67d..12368f5fd 100644 --- a/lib_rend/ivas_shoebox.c +++ b/lib_rend/ivas_shoebox.c @@ -39,6 +39,19 @@ #include "prot.h" #include "wmc_auto.h" + +/*------------------------------------------------------------------------- + * Local constants + *------------------------------------------------------------------------*/ + +#define ER_MAX_SOURCES 25 +#define ER_REF_ORDER 1 +#define ER_AIR_COEFF ( 0.00137f ) +#define ER_SOUND_SPEED ( 343.0f ) +#define ER_MIN_WALL_DIST ( 0.1f ) +#define ER_EUCLIDEAN_SCALE ( 1.29246971E-26f ) + + /*-----------------------------------------------------------------------------------------* * Function ivas_shoebox_config_init * diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index eac562e69..12175766d 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -67,6 +67,34 @@ typedef struct ivas_output_setup_structure } IVAS_OUTPUT_SETUP, *IVAS_OUTPUT_SETUP_HANDLE; +/*----------------------------------------------------------------------------------* + * Time domain decorrelator structures + *----------------------------------------------------------------------------------*/ + +typedef struct ivas_td_decorr_APD_filt_state_t +{ + int16_t order[IVAS_MAX_DECORR_APD_SECTIONS]; + int16_t idx[IVAS_MAX_DECORR_APD_SECTIONS]; + float coeffs[IVAS_MAX_DECORR_APD_SECTIONS]; + float *state[IVAS_MAX_DECORR_APD_SECTIONS]; + +} ivas_td_decorr_APD_filt_state_t; + +typedef struct ivas_td_decorr_state_t +{ + ivas_trans_det_state_t *pTrans_det; + float *look_ahead_buf; + ivas_td_decorr_APD_filt_state_t APD_filt_state[IVAS_MAX_DECORR_CHS]; + + int16_t num_apd_outputs; + int16_t num_apd_sections; + int16_t ducking_flag; + + int16_t offset; + +} ivas_td_decorr_state_t; + + /*----------------------------------------------------------------------------------* * Spatial parametric rendering common structures *----------------------------------------------------------------------------------*/ @@ -683,7 +711,11 @@ typedef struct ivas_combined_orientation_struct int8_t isExtOrientationFrozen; int8_t isHeadRotationFrozen; int16_t num_subframes; - + int16_t subframe_idx; + int16_t subframe_size; + int16_t cur_subframe_samples_rendered; + int16_t subframe_idx_start; + int16_t cur_subframe_samples_rendered_start; } COMBINED_ORIENTATION_DATA, *COMBINED_ORIENTATION_HANDLE; @@ -783,7 +815,7 @@ typedef struct float room_L; float room_W; float room_H; - float abs_coeff[ER_ABS_COEFF]; + float abs_coeff[IVAS_ROOM_ABS_COEFF]; float list_orig[3]; } shoebox_config_t; @@ -1319,6 +1351,28 @@ typedef enum } ChannelType; +/*----------------------------------------------------------------------------------* + * MASA external renderer structure + *----------------------------------------------------------------------------------*/ + +typedef struct ivas_masa_external_rendering_struct +{ + int16_t nchan_input; + int16_t nchan_output; + RENDERER_TYPE renderer_type; + DIRAC_REND_HANDLE hDirACRend; + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; + DIRAC_DEC_BIN_HANDLE hDiracDecBin; + + REVERB_STRUCT_HANDLE hReverb; + HRTFS_PARAMBIN_HANDLE hHrtfParambin; + VBAP_HANDLE hVBAPdata; + float *hoa_dec_mtx; + + HANDLE_CLDFB_FILTER_BANK cldfbAnaRend[MASA_MAX_TRANSPORT_CHANNELS]; + HANDLE_CLDFB_FILTER_BANK cldfbSynRend[MAX_OUTPUT_CHANNELS]; +} MASA_EXT_REND_DATA, *MASA_EXT_REND_HANDLE; + /*----------------------------------------------------------------------------------* * Multichannel MASA (McMASA) analysis structure *----------------------------------------------------------------------------------*/ diff --git a/lib_com/ivas_td_decorr.c b/lib_rend/ivas_td_decorr.c similarity index 94% rename from lib_com/ivas_td_decorr.c rename to lib_rend/ivas_td_decorr.c index 12c4853bc..8deab7b15 100644 --- a/lib_com/ivas_td_decorr.c +++ b/lib_rend/ivas_td_decorr.c @@ -34,6 +34,7 @@ #include "options.h" #include "prot.h" #include "ivas_prot.h" +#include "ivas_prot_rend.h" #include "math.h" #include #include "wmc_auto.h" @@ -355,9 +356,10 @@ static int16_t ivas_get_APD_filt_orders( *-----------------------------------------------------------------------------------------*/ static void ivas_td_decorr_init( - ivas_td_decorr_state_t *hTdDecorr, - const int16_t num_out_chans, - const int16_t ducking_flag ) + ivas_td_decorr_state_t *hTdDecorr, /* i/o: TD decorrelator handle */ + const int16_t num_out_chans, /* i : number of channels */ + const int16_t ducking_flag /* i : TD ducking flag */ +) { int16_t i, j; @@ -385,10 +387,11 @@ static void ivas_td_decorr_init( *-----------------------------------------------------------------------------------------*/ void ivas_td_decorr_APD_iir_filter( - ivas_td_decorr_APD_filt_state_t *filter_state, - float *pIn_out, - const int16_t num_APD_sections, - const int16_t length ) + ivas_td_decorr_APD_filt_state_t *filter_state, /* i/o: TD decorrelator filter handle */ + float *pIn_out, /* i/o: audio channels */ + const int16_t num_APD_sections, /* i : numbef of APD sections */ + const int16_t length /* i : output frame length */ +) { int16_t i, k; int16_t idx; @@ -431,9 +434,10 @@ void ivas_td_decorr_APD_iir_filter( *-----------------------------------------------------------------------------------------*/ static void ivas_td_decorr_APD_sections( - ivas_td_decorr_state_t *hTdDecorr, - float **ppOut_pcm, - const int16_t output_frame ) + ivas_td_decorr_state_t *hTdDecorr, /* i/o: TD decorrelator handle */ + float **ppOut_pcm, /* i/o: audio channels */ + const int16_t output_frame /* i : output frame length */ +) { int16_t i; @@ -453,7 +457,7 @@ static void ivas_td_decorr_APD_sections( *-----------------------------------------------------------------------------------------*/ void ivas_td_decorr_process( - ivas_td_decorr_state_t *hTdDecorr, /* i/o: SPAR Covar. decoder handle */ + ivas_td_decorr_state_t *hTdDecorr, /* i/o: TD decorrelator handle */ float *pcm_in[], /* i : input audio channels */ float **ppOut_pcm, /* o : output audio channels */ const int16_t output_frame /* i : output frame length */ diff --git a/lib_dec/ivas_vbap.c b/lib_rend/ivas_vbap.c similarity index 99% rename from lib_dec/ivas_vbap.c rename to lib_rend/ivas_vbap.c index 87bf38831..38a7a86c0 100644 --- a/lib_dec/ivas_vbap.c +++ b/lib_rend/ivas_vbap.c @@ -36,6 +36,7 @@ #include #include "prot.h" #include "ivas_prot.h" +#include "ivas_prot_rend.h" #include "ivas_stat_dec.h" #include "wmc_auto.h" diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index f19d8f423..4ffc2cc07 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -170,17 +170,14 @@ typedef struct } input_sba; -/* Due to API of some rendering methods, the renderer has to use the decoder struct. - Only struct members relevant for rendering will be initialized, therefore typedef as "dummy" decoder struct */ -typedef Decoder_Struct DecoderDummy; typedef struct { input_base base; - DecoderDummy *decDummy; MASA_METADATA_FRAME masaMetadata; bool metadataHasBeenFed; float *bufferData; + MASA_EXT_REND_HANDLE hMasaExtRend; MASA_PREREND_HANDLE hMasaPrerend; } input_masa; @@ -212,6 +209,13 @@ struct IVAS_REND }; +/*-------------------------------------------------------------------* + * Local function prototypes + *-------------------------------------------------------------------*/ + +static ivas_error initMasaExtRenderer( input_masa *inputMasa, const AUDIO_CONFIG outConfig ); +static void freeMasaExtRenderer( MASA_EXT_REND_HANDLE *hMasaExtRendOut ); + /*-------------------------------------------------------------------* * Local functions *-------------------------------------------------------------------*/ @@ -286,7 +290,7 @@ static float *getSmplPtr( static void copyBufferTo2dArray( const IVAS_REND_AudioBuffer buffer, - float array[MAX_OUTPUT_CHANNELS][L_FRAME48k] ) + float array[][L_FRAME48k] ) { uint32_t smplIdx; uint32_t chnlIdx; @@ -306,7 +310,7 @@ static void copyBufferTo2dArray( } static void accumulate2dArrayToBuffer( - float array[MAX_OUTPUT_CHANNELS][L_FRAME48k], + float array[][L_FRAME48k], IVAS_REND_AudioBuffer *buffer ) { int16_t smplIdx, chnlIdx; @@ -395,6 +399,8 @@ static ivas_error validateOutputAudioConfig( case IVAS_AUDIO_CONFIG_BINAURAL: case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: + case IVAS_AUDIO_CONFIG_MASA1: + case IVAS_AUDIO_CONFIG_MASA2: return IVAS_ERR_OK; default: break; @@ -471,17 +477,17 @@ static ivas_error validateOutputSampleRate( return IVAS_ERR_OK; } - /* Otherwise rendering to binaural, support the same set as IVAS decoder */ - switch ( sampleRate ) - { - case 8000: - case 16000: - case 32000: - case 48000: - return IVAS_ERR_OK; - } + /* Otherwise rendering to binaural, support the same set as IVAS decoder */ + switch ( sampleRate ) + { + case 8000: + case 16000: + case 32000: + case 48000: + return IVAS_ERR_OK; + } - return IVAS_ERR_INVALID_SAMPLING_RATE; + return IVAS_ERR_INVALID_SAMPLING_RATE; } @@ -1100,19 +1106,6 @@ static TDREND_WRAPPER defaultTdRendWrapper( } -static CREND_WRAPPER defaultCrendWrapper( - void ) -{ - CREND_WRAPPER w; - - w.hCrend = NULL; - w.hHrtfCrend = NULL; - w.binaural_latency_ns = 0; - - return w; -} - - static bool isIoConfigPairSupported( const AUDIO_CONFIG inConfig, const AUDIO_CONFIG outConfig ) @@ -2026,7 +2019,7 @@ static lfe_routing defaultLfeRouting( /* Set all output gains to zero, then route each input LFE consecutively to the next available output LFE. */ - for ( i = 0; i < IVAS_MAX_INPUT_LFE_CHANNELS; ++i ) + for ( i = 0; i < RENDERER_MAX_INPUT_LFE_CHANNELS; ++i ) { set_zero( routing.lfePanMtx[i], IVAS_MAX_OUTPUT_CHANNELS ); } @@ -2427,918 +2420,473 @@ static void clearInputSba( } -static ivas_error initMasaDummyDecForMcOut( - input_masa *inputMasa, - const AUDIO_CONFIG outConfig ) +static ivas_error setRendInputActiveMasa( + void *input, + const AUDIO_CONFIG inConfig, + const IVAS_REND_InputId id, + RENDER_CONFIG_DATA *hRendCfg ) /* Todo: This is not used at all within MASA. Support might be better to do after refactoring. */ { ivas_error error; - int16_t numCldfbAnalyses; - int16_t numCldfbSyntheses; - int16_t i; - DecoderDummy *decDummy; - - decDummy = inputMasa->decDummy; - decDummy->hDecoderConfig->output_config = outConfig; - decDummy->sba_analysis_order = 1; - decDummy->hDecoderConfig->ivas_total_brate = IVAS_512k; /* Todo Nokia: This is preventing initialization of 2TC as 1TC, should be fixed properly in ivas_dirac_dec_config() */ - decDummy->mc_mode = MC_MODE_NONE; /* Todo Nokia: This should be also refactored in such way that it is not checked if not in MC mode */ + rendering_context rendCtx; + AUDIO_CONFIG outConfig; + input_masa *inputMasa; + int16_t numInChannels; - ivas_output_init( &( decDummy->hOutSetup ), outConfig ); - ivas_output_init( &( decDummy->hIntSetup ), outConfig ); + inputMasa = (input_masa *) input; + rendCtx = inputMasa->base.ctx; + outConfig = *rendCtx.pOutConfig; + (void) hRendCfg; /* Suppress warning */ - decDummy->renderer_type = RENDERER_DIRAC; - if ( outConfig == IVAS_AUDIO_CONFIG_STEREO ) + if ( !isIoConfigPairSupported( inConfig, outConfig ) ) { - decDummy->renderer_type = RENDERER_STEREO_PARAMETRIC; + return IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED; } - decDummy->ivas_format = MASA_FORMAT; - decDummy->transport_config = IVAS_AUDIO_CONFIG_INVALID; - - /* Todo refactor: Access to qmetadata is not required by the algorithm. */ - if ( ( error = ivas_qmetadata_open( &( decDummy->hQMetaData ) ) ) != IVAS_ERR_OK ) + if ( ( error = allocateInputBaseBufferData( &inputMasa->bufferData, MAX_BUFFER_LENGTH ) ) != IVAS_ERR_OK ) { return error; } - decDummy->hQMetaData->coherence_flag = 1; + initRendInputBase( &inputMasa->base, inConfig, id, rendCtx, inputMasa->bufferData, MAX_BUFFER_LENGTH ); - if ( ( error = ivas_dirac_dec_config( decDummy, DIRAC_OPEN ) ) != IVAS_ERR_OK ) + if ( ( error = getAudioConfigNumChannels( inConfig, &numInChannels ) ) != IVAS_ERR_OK ) { return error; } - decDummy->hSpatParamRendCom->dirac_bs_md_write_idx = 0; - if ( decDummy->renderer_type == RENDERER_STEREO_PARAMETRIC ) + if ( getAudioConfigType( outConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_MASA ) { - if ( ( error = ivas_dirac_dec_init_binaural_data( decDummy, NULL ) ) != IVAS_ERR_OK ) + inputMasa->metadataHasBeenFed = false; + if ( ( error = masaPrerendOpen( &inputMasa->hMasaPrerend, inputMasa->base.inConfig == IVAS_AUDIO_CONFIG_MASA1 ? 1 : 2, *( inputMasa->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) { return error; } } - - numCldfbAnalyses = decDummy->nchan_transport; - numCldfbSyntheses = decDummy->hDecoderConfig->nchan_out; - - for ( i = 0; i < numCldfbAnalyses; i++ ) + else { - if ( ( error = openCldfb( &( decDummy->cldfbAnaDec[i] ), CLDFB_ANALYSIS, decDummy->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + if ( ( error = initMasaExtRenderer( inputMasa, outConfig ) ) != IVAS_ERR_OK ) { return error; } - } - for ( ; i < MAX_INTERN_CHANNELS; i++ ) - { - decDummy->cldfbAnaDec[i] = NULL; - } - for ( i = 0; i < numCldfbSyntheses; i++ ) - { - if ( ( error = openCldfb( &( decDummy->cldfbSynDec[i] ), CLDFB_SYNTHESIS, decDummy->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) - { - return error; - } - } - for ( ; i < MAX_OUTPUT_CHANNELS; i++ ) - { - decDummy->cldfbSynDec[i] = NULL; + inputMasa->metadataHasBeenFed = false; } return IVAS_ERR_OK; } -static ivas_error initMasaDummyDecForSbaOut( - input_masa *inputMasa, - const AUDIO_CONFIG outConfig ) +static void clearInputMasa( + input_masa *inputMasa ) { - ivas_error error; - int16_t numCldfbAnalyses; - int16_t numCldfbSyntheses; - int16_t i; - DecoderDummy *decDummy; + rendering_context rendCtx; + + rendCtx = inputMasa->base.ctx; + + freeInputBaseBufferData( &inputMasa->bufferData ); + + masaPrerendClose( &inputMasa->hMasaPrerend ); + freeMasaExtRenderer( &inputMasa->hMasaExtRend ); - decDummy = inputMasa->decDummy; - decDummy->hDecoderConfig->output_config = outConfig; - decDummy->hDecoderConfig->ivas_total_brate = IVAS_512k; /* Todo Nokia: This is preventing initialization of 2TC as 1TC, should be fixed properly in ivas_dirac_dec_config() */ - decDummy->mc_mode = MC_MODE_NONE; /* Todo Nokia: This should be also refactored in such way that it is not checked if not in MC mode */ - decDummy->sba_analysis_order = 1; + initRendInputBase( &inputMasa->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 ); + + return; +} - ivas_output_init( &( decDummy->hOutSetup ), outConfig ); - ivas_output_init( &( decDummy->hIntSetup ), outConfig ); - decDummy->renderer_type = RENDERER_DIRAC; - decDummy->ivas_format = MASA_FORMAT; - decDummy->transport_config = IVAS_AUDIO_CONFIG_INVALID; - /* Todo refactor: Access to qmetadata is not required by the algorithm. */ - if ( ( error = ivas_qmetadata_open( &( decDummy->hQMetaData ) ) ) != IVAS_ERR_OK ) + +/*------------------------------------------------------------------------- + * IVAS_REND_Open() + * + * + *------------------------------------------------------------------------*/ + +ivas_error IVAS_REND_Open( + IVAS_REND_HANDLE *phIvasRend, + const int32_t outputSampleRate, + const AUDIO_CONFIG outConfig, + const int16_t nonDiegeticPan, + const float nonDiegeticPanGain, + const int16_t num_subframes ) +{ + int16_t i; + IVAS_REND_HANDLE hIvasRend; + ivas_error error; + int16_t numOutChannels; + + /* Validate function arguments */ + if ( phIvasRend == NULL ) { - return error; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - decDummy->hQMetaData->coherence_flag = 1; - if ( ( error = ivas_dirac_dec_config( decDummy, DIRAC_OPEN ) ) != IVAS_ERR_OK ) + if ( ( error = validateOutputAudioConfig( outConfig ) ) != IVAS_ERR_OK ) { return error; } - decDummy->hSpatParamRendCom->dirac_bs_md_write_idx = 0; - - numCldfbAnalyses = decDummy->nchan_transport; - numCldfbSyntheses = decDummy->hDecoderConfig->nchan_out; - for ( i = 0; i < numCldfbAnalyses; i++ ) + if ( ( error = validateOutputSampleRate( outputSampleRate, outConfig ) ) != IVAS_ERR_OK ) { - if ( ( error = openCldfb( &( decDummy->cldfbAnaDec[i] ), CLDFB_ANALYSIS, decDummy->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } - for ( ; i < MAX_INTERN_CHANNELS; i++ ) + + *phIvasRend = (IVAS_REND_HANDLE) malloc( sizeof( struct IVAS_REND ) ); + if ( *phIvasRend == NULL ) { - decDummy->cldfbAnaDec[i] = NULL; + return IVAS_ERR_FAILED_ALLOC; } - for ( i = 0; i < numCldfbSyntheses; i++ ) + hIvasRend = *phIvasRend; + hIvasRend->sampleRateOut = outputSampleRate; + hIvasRend->outputConfig = outConfig; + hIvasRend->customLsOut = defaultCustomLs(); + hIvasRend->hLimiter = NULL; + hIvasRend->efapOutWrapper.hEfap = NULL; + hIvasRend->efapOutWrapper.pCustomLsSetup = NULL; + hIvasRend->num_subframes = num_subframes; + + /* Initialize limiter */ + if ( ( error = IVAS_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) { - if ( ( error = openCldfb( &( decDummy->cldfbSynDec[i] ), CLDFB_SYNTHESIS, decDummy->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } - for ( ; i < MAX_OUTPUT_CHANNELS; i++ ) + + if ( ( error = initLimiter( &hIvasRend->hLimiter, numOutChannels, outputSampleRate ) ) != IVAS_ERR_OK ) { - decDummy->cldfbSynDec[i] = NULL; + return error; } - return IVAS_ERR_OK; -} - - -static ivas_error initMasaDummyDecForBinauralOut( - input_masa *inputMasa, - const AUDIO_CONFIG outConfig ) -{ - ivas_error error; - int16_t i; - DecoderDummy *decDummy; - - decDummy = inputMasa->decDummy; - decDummy->hDecoderConfig->output_config = outConfig; - decDummy->sba_analysis_order = 1; - decDummy->hDecoderConfig->ivas_total_brate = IVAS_512k; /* Todo Nokia: This is preventing initialization of 2TC as 1TC, should be fixed properly in ivas_dirac_dec_config() */ - decDummy->mc_mode = MC_MODE_NONE; /* Todo Nokia: This should be also refactored in such way that it is not checked if not in MC mode */ - - ivas_output_init( &( decDummy->hOutSetup ), outConfig ); - - if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL ) + /* Initialize headrotation data */ + if ( ( error = initHeadRotation( hIvasRend ) ) != IVAS_ERR_OK ) { - decDummy->renderer_type = RENDERER_BINAURAL_PARAMETRIC; + return error; } - else + + /* Initialize external orientation data */ + if ( ( error = ivas_external_orientation_open( &( hIvasRend->hExternalOrientationData ), num_subframes ) ) != IVAS_ERR_OK ) { - decDummy->renderer_type = RENDERER_BINAURAL_PARAMETRIC_ROOM; + return error; } - decDummy->ivas_format = MASA_FORMAT; - decDummy->transport_config = IVAS_AUDIO_CONFIG_INVALID; - if ( ( error = ivas_dirac_dec_config( decDummy, DIRAC_OPEN ) ) != IVAS_ERR_OK ) + /* Initilize combined orientation data */ + if ( ( error = ivas_combined_orientation_open( &( hIvasRend->hCombinedOrientationData ), outputSampleRate, num_subframes ) ) != IVAS_ERR_OK ) { return error; } - decDummy->hSpatParamRendCom->dirac_bs_md_write_idx = 0; - if ( ( error = ivas_dirac_dec_binaural_copy_hrtfs( &decDummy->hHrtfParambin ) ) != IVAS_ERR_OK ) + /* Initialize EFAP */ + if ( ( error = initEfap( &hIvasRend->efapOutWrapper, outConfig, &hIvasRend->customLsOut ) ) != IVAS_ERR_OK ) { return error; } - if ( ( error = ivas_dirac_dec_init_binaural_data( decDummy, decDummy->hHrtfParambin ) ) != IVAS_ERR_OK ) + /* Initialize inputs */ + + for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) { - return error; + initRendInputBase( &hIvasRend->inputsIsm[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 ); + + hIvasRend->inputsIsm[i].crendWrapper = NULL; + hIvasRend->inputsIsm[i].hReverb = NULL; + hIvasRend->inputsIsm[i].tdRendWrapper.hBinRendererTd = NULL; + hIvasRend->inputsIsm[i].bufferData = NULL; + hIvasRend->inputsIsm[i].nonDiegeticPan = nonDiegeticPan; + hIvasRend->inputsIsm[i].nonDiegeticPanGain = nonDiegeticPanGain; + hIvasRend->inputsIsm[i].hOMasa = NULL; } - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) { - if ( ( error = openCldfb( &( decDummy->cldfbAnaDec[i] ), CLDFB_ANALYSIS, decDummy->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) - { - return error; - } - if ( ( error = openCldfb( &( decDummy->cldfbSynDec[i] ), CLDFB_SYNTHESIS, decDummy->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) - { - return error; - } + initRendInputBase( &hIvasRend->inputsMc[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 ); + + hIvasRend->inputsMc[i].efapInWrapper.hEfap = NULL; + hIvasRend->inputsMc[i].crendWrapper = NULL; + hIvasRend->inputsMc[i].hReverb = NULL; + hIvasRend->inputsMc[i].tdRendWrapper.hBinRendererTd = NULL; + hIvasRend->inputsMc[i].bufferData = NULL; + hIvasRend->inputsMc[i].lfeDelayBuffer = NULL; + hIvasRend->inputsMc[i].nonDiegeticPan = nonDiegeticPan; + hIvasRend->inputsMc[i].nonDiegeticPanGain = nonDiegeticPanGain; + hIvasRend->inputsMc[i].hMcMasa = NULL; + } + + for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) + { + initRendInputBase( &hIvasRend->inputsSba[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 ); + + hIvasRend->inputsSba[i].crendWrapper = NULL; + hIvasRend->inputsSba[i].bufferData = NULL; + hIvasRend->inputsSba[i].hDirAC = NULL; } - for ( ; i < MAX_INTERN_CHANNELS; i++ ) + + for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) { - decDummy->cldfbAnaDec[i] = NULL; - decDummy->cldfbSynDec[i] = NULL; + initRendInputBase( &hIvasRend->inputsMasa[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 ); + + hIvasRend->inputsMasa[i].metadataHasBeenFed = false; + hIvasRend->inputsMasa[i].bufferData = NULL; + hIvasRend->inputsMasa[i].hMasaPrerend = NULL; + hIvasRend->inputsMasa[i].hMasaExtRend = NULL; } + return IVAS_ERR_OK; } -static ivas_error updateMasaDummyDec( - input_masa *inputMasa, - const AUDIO_CONFIG outConfig ) +static LSSETUP_CUSTOM_STRUCT makeCustomLsSetup( + const IVAS_CUSTOM_LS_DATA rendCustomLsLayout ) { - ivas_error error; + int16_t i; + LSSETUP_CUSTOM_STRUCT customLs; - switch ( getAudioConfigType( outConfig ) ) + /* Copy layout description */ + customLs.num_spk = rendCustomLsLayout.num_spk; + mvr2r( rendCustomLsLayout.azimuth, customLs.ls_azimuth, rendCustomLsLayout.num_spk ); + mvr2r( rendCustomLsLayout.elevation, customLs.ls_elevation, rendCustomLsLayout.num_spk ); + + customLs.is_planar_setup = 1; + for ( i = 0; i < rendCustomLsLayout.num_spk; ++i ) { - case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: - error = initMasaDummyDecForMcOut( inputMasa, outConfig ); - break; - case IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS: - error = initMasaDummyDecForSbaOut( inputMasa, outConfig ); - break; - case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: - error = initMasaDummyDecForBinauralOut( inputMasa, outConfig ); + if ( fabsf( rendCustomLsLayout.elevation[i] ) > EPSILON ) + { + customLs.is_planar_setup = 0; break; - default: - return IVAS_ERR_INVALID_OUTPUT_FORMAT; + } } - return error; + customLs.num_lfe = rendCustomLsLayout.num_lfe; + mvs2s( rendCustomLsLayout.lfe_idx, customLs.lfe_idx, rendCustomLsLayout.num_lfe ); + + return customLs; } -static DecoderDummy *initDecoderDummy( - const int32_t sampleRate, - const int16_t numTransChannels, - const AUDIO_CONFIG outConfig, - const uint8_t enableRenderConfig -) +static ivas_error validateCustomLsLayout( + const IVAS_CUSTOM_LS_DATA layout ) { - ivas_error error; int16_t i; - int16_t numOutChannels; - DecoderDummy *decDummy; - int16_t num_subframes; - num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; - if ( ( error = getAudioConfigNumChannels( outConfig, &numOutChannels ) ) != IVAS_ERR_OK ) + /* Negative number of speakers or LFEs makes no sense */ + if ( layout.num_spk < 0 || layout.num_lfe < 0 ) { - /* Checking error with assert is enough, this function is only temporary anyway */ - assert( error == IVAS_ERR_OK ); - } - - decDummy = malloc( sizeof( DecoderDummy ) ); - decDummy->hDecoderConfig = malloc( sizeof( DECODER_CONFIG ) ); - decDummy->hDecoderConfig->output_Fs = sampleRate; - decDummy->hDecoderConfig->nchan_out = numOutChannels; - decDummy->hDecoderConfig->Opt_Headrotation = 0; - decDummy->hDecoderConfig->Opt_tsm = 0; - decDummy->hDecoderConfig->Opt_5ms = 0; - decDummy->hBinRenderer = NULL; - - decDummy->hEFAPdata = NULL; - decDummy->hCrendWrapper = NULL; - decDummy->hHrtfTD = NULL; - decDummy->hSpar = NULL; - decDummy->hoa_dec_mtx = NULL; - decDummy->hVBAPdata = NULL; // note: not used at the moment - decDummy->hMasa = NULL; - - decDummy->hDiracDecBin = NULL; - - decDummy->hDirACRend = NULL; - decDummy->hSpatParamRendCom = NULL; - decDummy->hQMetaData = NULL; - decDummy->hHrtfParambin = NULL; - decDummy->hHeadTrackData = NULL; - decDummy->hDirAC = NULL; - decDummy->hTcBuffer = NULL; - decDummy->hDecoderConfig->output_config = outConfig; - decDummy->nchan_transport = numTransChannels; - - if ( getAudioConfigType( outConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) - { - decDummy->hHeadTrackData = malloc( sizeof( HEAD_TRACK_DATA ) ); - /* Initialise Rmat_prev to I, Rmat will be computed later */ - for ( i = 0; i < 3; i++ ) - { - set_zero( decDummy->hHeadTrackData->Rmat_prev[i], 3 ); - decDummy->hHeadTrackData->Rmat_prev[i][i] = 1.0f; - } + return IVAS_ERR_INVALID_CUSTOM_LS_LAYOUT; + } - set_zero( decDummy->hHeadTrackData->chEneIIR[0], MASA_FREQUENCY_BANDS ); - set_zero( decDummy->hHeadTrackData->chEneIIR[1], MASA_FREQUENCY_BANDS ); - set_zero( decDummy->hHeadTrackData->procChEneIIR[0], MASA_FREQUENCY_BANDS ); - set_zero( decDummy->hHeadTrackData->procChEneIIR[1], MASA_FREQUENCY_BANDS ); - for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) - { - decDummy->hHeadTrackData->Quaternions[i].w = 1.0f; - decDummy->hHeadTrackData->Quaternions[i].x = 0.0f; - decDummy->hHeadTrackData->Quaternions[i].y = 0.0f; - decDummy->hHeadTrackData->Quaternions[i].z = 0.0f; - } - decDummy->hHeadTrackData->lrSwitchInterpVal = 0.0f; - decDummy->hHeadTrackData->lrSwitchedCurrent = 0; - decDummy->hHeadTrackData->lrSwitchedNext = 0; - decDummy->hHeadTrackData->OrientationTracker = (ivas_orient_trk_state_t *) malloc( sizeof( ivas_orient_trk_state_t ) ); - ivas_orient_trk_Init( decDummy->hHeadTrackData->OrientationTracker ); + /* There must be at least one speaker or LFE in the layout */ + if ( layout.num_spk + layout.num_lfe <= 0 ) + { + return IVAS_ERR_INVALID_CUSTOM_LS_LAYOUT; + } - /* External orientations */ - if ( ( error = ivas_external_orientation_open( &( decDummy->hExtOrientationData ), num_subframes ) ) != IVAS_ERR_OK ) - { - assert( error == IVAS_ERR_OK ); - } - - /* Combined orientations */ - if ( ( error = ivas_combined_orientation_open( &( decDummy->hCombinedOrientationData ), num_subframes ) ) != IVAS_ERR_OK ) + /* LFE indices must be positive */ + for ( i = 0; i < layout.num_lfe; ++i ) + { + if ( layout.lfe_idx[i] < 0 ) { - assert( error == IVAS_ERR_OK ); + return IVAS_ERR_INVALID_CUSTOM_LS_LAYOUT; } } - else - { - decDummy->hHeadTrackData = NULL; - decDummy->hExtOrientationData = NULL; - decDummy->hCombinedOrientationData = NULL; - } - - if ( enableRenderConfig ) - { - ivas_render_config_open( &decDummy->hRenderConfig ); - } - else - { - decDummy->hRenderConfig = NULL; - } - - /* get a default TC buffer, needed for some renderers */ - ivas_jbm_dec_tc_buffer_open( decDummy, TC_BUFFER_MODE_NONE, 0, 0, 0, 1 ); - decDummy->renderer_type = RENDERER_DISABLE; - - return decDummy; + return IVAS_ERR_OK; } -static ivas_error setRendInputActiveMasa( - void *input, - const AUDIO_CONFIG inConfig, - const IVAS_REND_InputId id, - RENDER_CONFIG_DATA *hRendCfg ) /* Todo: This is not used at all within MASA. Support might be better to do after refactoring. */ +/*-------------------------------------------------------------------* + * IVAS_REND_ConfigureCustomOutputLoudspeakerLayout() + * + * + *-------------------------------------------------------------------*/ + +ivas_error IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( + IVAS_REND_HANDLE hIvasRend, + const IVAS_CUSTOM_LS_DATA layout ) { + int16_t i, numOutChannels; ivas_error error; - rendering_context rendCtx; - AUDIO_CONFIG outConfig; - input_masa *inputMasa; - int16_t numInChannels; - - inputMasa = (input_masa *) input; - rendCtx = inputMasa->base.ctx; - outConfig = *rendCtx.pOutConfig; - (void) hRendCfg; /* Suppress warning */ + input_mc *inputMc; + input_sba *inputSba; - if ( !isIoConfigPairSupported( inConfig, outConfig ) ) + /* Validate function arguments */ + if ( hIvasRend == NULL ) { - return IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - if ( ( error = allocateInputBaseBufferData( &inputMasa->bufferData, MAX_BUFFER_LENGTH ) ) != IVAS_ERR_OK ) + if ( hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_LS_CUSTOM ) { - return error; + /* Specifying details of custom speaker layout only makes sense if output config is set to custom speaker layout */ + return IVAS_ERR_INVALID_OUTPUT_FORMAT; } - initRendInputBase( &inputMasa->base, inConfig, id, rendCtx, inputMasa->bufferData, MAX_BUFFER_LENGTH ); - if ( ( error = getAudioConfigNumChannels( inConfig, &numInChannels ) ) != IVAS_ERR_OK ) + if ( ( error = validateCustomLsLayout( layout ) ) != IVAS_ERR_OK ) { return error; } - if ( getAudioConfigType( outConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_MASA ) - { - inputMasa->metadataHasBeenFed = false; - if ( ( error = masaPrerendOpen( &inputMasa->hMasaPrerend, inputMasa->base.inConfig == IVAS_AUDIO_CONFIG_MASA1 ? 1 : 2, *( inputMasa->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else - { - inputMasa->decDummy = initDecoderDummy( *rendCtx.pOutSampleRate, numInChannels, outConfig, 0 ); - - inputMasa->metadataHasBeenFed = false; + hIvasRend->customLsOut = makeCustomLsSetup( layout ); - if ( ( error = updateMasaDummyDec( inputMasa, outConfig ) ) != IVAS_ERR_OK ) - { - return error; - } + /* Re-initialize limiter - number of output channels may have changed */ + if ( ( error = IVAS_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) + { + return error; } - return IVAS_ERR_OK; -} - - -static void freeDecoderDummy( - DecoderDummy **ppDecDummy ) -{ - int16_t i; - DecoderDummy *pDecDummy; - - if ( ppDecDummy == NULL || *ppDecDummy == NULL ) + if ( ( error = initLimiter( &hIvasRend->hLimiter, numOutChannels, hIvasRend->sampleRateOut ) ) != IVAS_ERR_OK ) { - return; + return error; } - pDecDummy = *ppDecDummy; - if ( pDecDummy->hDecoderConfig != NULL ) + /* Re-initialize EFAP - output layout has changed or has been fully defined for the first time */ + if ( ( error = initEfap( &hIvasRend->efapOutWrapper, hIvasRend->outputConfig, &hIvasRend->customLsOut ) ) != IVAS_ERR_OK ) { - free( pDecDummy->hDecoderConfig ); + return error; } - if ( pDecDummy->hHeadTrackData != NULL ) + /* Re-initialize panning gains for each active MC input, This includes re-initializing + * LFE handling for the new output layout, which means custom LFE handling is overwritten, + * if previously set for any MC input. */ + for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) { - if ( pDecDummy->hHeadTrackData->OrientationTracker != NULL ) + inputMc = &hIvasRend->inputsMc[i]; + if ( inputMc->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) { - free( pDecDummy->hHeadTrackData->OrientationTracker ); + /* Input inactive, skip. */ + continue; } - free( pDecDummy->hHeadTrackData ); - } - if ( pDecDummy->hExtOrientationData != NULL ) - { - free( pDecDummy->hExtOrientationData ); - } + inputMc->lfeRouting = defaultLfeRouting( inputMc->base.inConfig, inputMc->customLsInput, hIvasRend->outputConfig, *inputMc->base.ctx.pCustomLsOut ); - if ( pDecDummy->hCombinedOrientationData != NULL ) - { - free( pDecDummy->hCombinedOrientationData ); + if ( ( error = updateMcPanGains( inputMc, hIvasRend->outputConfig ) ) != IVAS_ERR_OK ) + { + return error; + } } - ivas_render_config_close( &pDecDummy->hRenderConfig ); - - /* CLDFB handles */ - for ( i = 0; i < MAX_INTERN_CHANNELS; i++ ) + /* Re-initialize panning gains for each active SBA input */ + for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) { - if ( pDecDummy->cldfbAnaDec[i] != NULL ) + inputSba = &hIvasRend->inputsSba[i]; + + if ( inputSba->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) { - deleteCldfb( &( pDecDummy->cldfbAnaDec[i] ) ); + /* Input inactive, skip. */ + continue; } - } - for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) - { - if ( pDecDummy->cldfbSynDec[i] != NULL ) + if ( ( error = updateSbaPanGains( inputSba, hIvasRend->outputConfig, hIvasRend->hRendererConfig ) ) != IVAS_ERR_OK ) { - deleteCldfb( &( pDecDummy->cldfbSynDec[i] ) ); + return error; } } - /* DirAC handle */ - ivas_dirac_rend_close( &( pDecDummy->hDirACRend ) ); - ivas_spat_hSpatParamRendCom_close( &( pDecDummy->hSpatParamRendCom ) ); - ivas_dirac_dec_close( &( pDecDummy->hDirAC ) ); + return IVAS_ERR_OK; +} - /* Qmetadata handle */ - ivas_qmetadata_close( &pDecDummy->hQMetaData ); - /* VBAP handle */ - vbap_free_data( &( pDecDummy->hVBAPdata ) ); +/*-------------------------------------------------------------------* + * IVAS_REND_NumOutChannels() + * + * + *-------------------------------------------------------------------*/ + +ivas_error IVAS_REND_NumOutChannels( + IVAS_REND_CONST_HANDLE hIvasRend, + int16_t *numOutChannels ) +{ + ivas_error error; - /* HOA decoder matrix */ - if ( pDecDummy->hoa_dec_mtx != NULL ) + /* Validate function arguments */ + if ( hIvasRend == NULL || numOutChannels == NULL ) { - free( pDecDummy->hoa_dec_mtx ); - pDecDummy->hoa_dec_mtx = NULL; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - /* Parametric binaural renderer HRTF structure */ - if ( pDecDummy->hHrtfParambin != NULL ) + /* Handle special cases where additional info is needed from the renderer, otherwise use getAudioConfigNumChannels() */ + switch ( hIvasRend->outputConfig ) { - free( pDecDummy->hHrtfParambin ); - pDecDummy->hHrtfParambin = NULL; + case IVAS_AUDIO_CONFIG_LS_CUSTOM: + *numOutChannels = hIvasRend->customLsOut.num_spk + hIvasRend->customLsOut.num_lfe; + break; + default: + if ( ( error = getAudioConfigNumChannels( hIvasRend->outputConfig, numOutChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + break; } - - /* Parametric binaural renderer handle */ - ivas_dirac_dec_close_binaural_data( &pDecDummy->hDiracDecBin ); - - /* TC buffer */ - ivas_jbm_dec_tc_buffer_close( &pDecDummy->hTcBuffer ); - - free( pDecDummy ); - pDecDummy = NULL; - - return; + return IVAS_ERR_OK; } -static void clearInputMasa( - input_masa *inputMasa ) +static IVAS_REND_InputId makeInputId( + AUDIO_CONFIG config, + const int32_t inputIndex ) { - rendering_context rendCtx; - - rendCtx = inputMasa->base.ctx; - - freeInputBaseBufferData( &inputMasa->bufferData ); - - masaPrerendClose( &inputMasa->hMasaPrerend ); - - initRendInputBase( &inputMasa->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 ); - freeDecoderDummy( &inputMasa->decDummy ); - - return; + /* Put config type in second byte (from LSB), put index + 1 in first byte + * + * Index is incremented here so that a valid ID can never be 0. */ + return (IVAS_REND_InputId) ( ( ( (uint32_t) getAudioConfigType( config ) ) << 8 ) | ( inputIndex + 1 ) ); } - - -/*------------------------------------------------------------------------- - * IVAS_REND_Open() - * - * - *------------------------------------------------------------------------*/ - -ivas_error IVAS_REND_Open( - IVAS_REND_HANDLE *phIvasRend, - const int32_t outputSampleRate, - const AUDIO_CONFIG outConfig, - const int16_t nonDiegeticPan, - const float nonDiegeticPanGain, - const int16_t num_subframes ) +static ivas_error getInputById( + IVAS_REND_HANDLE hIvasRend, + IVAS_REND_InputId inputId, + void **ppInput ) { - int16_t i; - IVAS_REND_HANDLE hIvasRend; - ivas_error error; - int16_t numOutChannels; + int32_t inputIndex; + IVAS_REND_AudioConfigType configType; + input_base *pInputBase; - /* Validate function arguments */ - if ( phIvasRend == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + /* Reverse makeInputId() */ + inputIndex = ( inputId & 0xFF ) - 1; + configType = ( inputId & 0xFF00 ) >> 8; - if ( ( error = validateOutputAudioConfig( outConfig ) ) != IVAS_ERR_OK ) + /* Validate values derived from input ID */ + if ( inputIndex < 0 ) { - return error; + return IVAS_ERR_INVALID_INPUT_ID; } - - if ( ( error = validateOutputSampleRate( outputSampleRate, outConfig ) ) != IVAS_ERR_OK ) + switch ( configType ) { - return error; + case IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED: + if ( inputIndex > RENDERER_MAX_ISM_INPUTS ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsIsm[inputIndex].base; + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: + if ( inputIndex > RENDERER_MAX_MC_INPUTS ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsMc[inputIndex].base; + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS: + if ( inputIndex > RENDERER_MAX_SBA_INPUTS ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsSba[inputIndex].base; + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_MASA: + if ( inputIndex > RENDERER_MAX_MASA_INPUTS ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsMasa[inputIndex].base; + break; + default: + return IVAS_ERR_INVALID_INPUT_ID; } - *phIvasRend = (IVAS_REND_HANDLE) malloc( sizeof( struct IVAS_REND ) ); - if ( *phIvasRend == NULL ) + /* Ensure input ID matches and that input is active */ + if ( pInputBase->id != inputId || pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID ) { - return IVAS_ERR_FAILED_ALLOC; - } - - hIvasRend = *phIvasRend; - hIvasRend->sampleRateOut = outputSampleRate; - hIvasRend->outputConfig = outConfig; - hIvasRend->customLsOut = defaultCustomLs(); - hIvasRend->hLimiter = NULL; - hIvasRend->efapOutWrapper.hEfap = NULL; - hIvasRend->efapOutWrapper.pCustomLsSetup = NULL; - hIvasRend->num_subframes = num_subframes; - - /* Initialize limiter */ - if ( ( error = IVAS_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( ( error = initLimiter( &hIvasRend->hLimiter, numOutChannels, outputSampleRate ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* Initialize headrotation data */ - if ( ( error = initHeadRotation( hIvasRend ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* Initialize external orientation data */ - if ( ( error = ivas_external_orientation_open( &( hIvasRend->hExternalOrientationData ), num_subframes ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* Initilize combined orientation data */ - if ( ( error = ivas_combined_orientation_open( &( hIvasRend->hCombinedOrientationData ), num_subframes ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* Initialize EFAP */ - if ( ( error = initEfap( &hIvasRend->efapOutWrapper, outConfig, &hIvasRend->customLsOut ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* Initialize inputs */ - - for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) - { - initRendInputBase( &hIvasRend->inputsIsm[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 ); - - hIvasRend->inputsIsm[i].crendWrapper = NULL; - hIvasRend->inputsIsm[i].hReverb = NULL; - hIvasRend->inputsIsm[i].tdRendWrapper.hBinRendererTd = NULL; - hIvasRend->inputsIsm[i].bufferData = NULL; - hIvasRend->inputsIsm[i].nonDiegeticPan = nonDiegeticPan; - hIvasRend->inputsIsm[i].nonDiegeticPanGain = nonDiegeticPanGain; - hIvasRend->inputsIsm[i].hOMasa = NULL; - } - - for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) - { - initRendInputBase( &hIvasRend->inputsMc[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 ); - - hIvasRend->inputsMc[i].efapInWrapper.hEfap = NULL; - hIvasRend->inputsMc[i].crendWrapper = NULL; - hIvasRend->inputsMc[i].hReverb = NULL; - hIvasRend->inputsMc[i].tdRendWrapper.hBinRendererTd = NULL; - hIvasRend->inputsMc[i].bufferData = NULL; - hIvasRend->inputsMc[i].lfeDelayBuffer = NULL; - hIvasRend->inputsMc[i].nonDiegeticPan = nonDiegeticPan; - hIvasRend->inputsMc[i].nonDiegeticPanGain = nonDiegeticPanGain; - hIvasRend->inputsMc[i].hMcMasa = NULL; - } - - for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) - { - initRendInputBase( &hIvasRend->inputsSba[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 ); - - hIvasRend->inputsSba[i].crendWrapper = NULL; - hIvasRend->inputsSba[i].bufferData = NULL; - hIvasRend->inputsSba[i].hDirAC = NULL; - } - - for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) - { - initRendInputBase( &hIvasRend->inputsMasa[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 ); - - hIvasRend->inputsMasa[i].decDummy = NULL; - hIvasRend->inputsMasa[i].metadataHasBeenFed = false; - hIvasRend->inputsMasa[i].bufferData = NULL; - hIvasRend->inputsMasa[i].hMasaPrerend = NULL; - } - - - return IVAS_ERR_OK; -} - - -static LSSETUP_CUSTOM_STRUCT makeCustomLsSetup( - const IVAS_CUSTOM_LS_DATA rendCustomLsLayout ) -{ - int16_t i; - LSSETUP_CUSTOM_STRUCT customLs; - - /* Copy layout description */ - customLs.num_spk = rendCustomLsLayout.num_spk; - mvr2r( rendCustomLsLayout.azimuth, customLs.ls_azimuth, rendCustomLsLayout.num_spk ); - mvr2r( rendCustomLsLayout.elevation, customLs.ls_elevation, rendCustomLsLayout.num_spk ); - - customLs.is_planar_setup = 1; - for ( i = 0; i < rendCustomLsLayout.num_spk; ++i ) - { - if ( fabsf( rendCustomLsLayout.elevation[i] ) > EPSILON ) - { - customLs.is_planar_setup = 0; - break; - } - } - - customLs.num_lfe = rendCustomLsLayout.num_lfe; - mvs2s( rendCustomLsLayout.lfe_idx, customLs.lfe_idx, rendCustomLsLayout.num_lfe ); - - return customLs; -} - - -static ivas_error validateCustomLsLayout( - const IVAS_CUSTOM_LS_DATA layout ) -{ - int16_t i; - - /* Negative number of speakers or LFEs makes no sense */ - if ( layout.num_spk < 0 || layout.num_lfe < 0 ) - { - return IVAS_ERR_INVALID_CUSTOM_LS_LAYOUT; - } - - /* There must be at least one speaker or LFE in the layout */ - if ( layout.num_spk + layout.num_lfe <= 0 ) - { - return IVAS_ERR_INVALID_CUSTOM_LS_LAYOUT; - } - - /* LFE indices must be positive */ - for ( i = 0; i < layout.num_lfe; ++i ) - { - if ( layout.lfe_idx[i] < 0 ) - { - return IVAS_ERR_INVALID_CUSTOM_LS_LAYOUT; - } - } - - return IVAS_ERR_OK; -} - - -/*-------------------------------------------------------------------* - * IVAS_REND_ConfigureCustomOutputLoudspeakerLayout() - * - * - *-------------------------------------------------------------------*/ - -ivas_error IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( - IVAS_REND_HANDLE hIvasRend, - const IVAS_CUSTOM_LS_DATA layout ) -{ - int16_t i, numOutChannels; - ivas_error error; - input_mc *inputMc; - input_sba *inputSba; - - /* Validate function arguments */ - if ( hIvasRend == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - if ( hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_LS_CUSTOM ) - { - /* Specifying details of custom speaker layout only makes sense if output config is set to custom speaker layout */ - return IVAS_ERR_INVALID_OUTPUT_FORMAT; - } - - if ( ( error = validateCustomLsLayout( layout ) ) != IVAS_ERR_OK ) - { - return error; - } - - hIvasRend->customLsOut = makeCustomLsSetup( layout ); - - /* Re-initialize limiter - number of output channels may have changed */ - if ( ( error = IVAS_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( ( error = initLimiter( &hIvasRend->hLimiter, numOutChannels, hIvasRend->sampleRateOut ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* Re-initialize EFAP - output layout has changed or has been fully defined for the first time */ - if ( ( error = initEfap( &hIvasRend->efapOutWrapper, hIvasRend->outputConfig, &hIvasRend->customLsOut ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* Re-initialize panning gains for each active MC input, This includes re-initializing - * LFE handling for the new output layout, which means custom LFE handling is overwritten, - * if previously set for any MC input. */ - for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) - { - inputMc = &hIvasRend->inputsMc[i]; - if ( inputMc->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) - { - /* Input inactive, skip. */ - continue; - } - - inputMc->lfeRouting = defaultLfeRouting( inputMc->base.inConfig, inputMc->customLsInput, hIvasRend->outputConfig, *inputMc->base.ctx.pCustomLsOut ); - - if ( ( error = updateMcPanGains( inputMc, hIvasRend->outputConfig ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - /* Re-initialize panning gains for each active SBA input */ - for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) - { - inputSba = &hIvasRend->inputsSba[i]; - - if ( inputSba->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) - { - /* Input inactive, skip. */ - continue; - } - - if ( ( error = updateSbaPanGains( inputSba, hIvasRend->outputConfig, hIvasRend->hRendererConfig ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - return IVAS_ERR_OK; -} - - -/*-------------------------------------------------------------------* - * IVAS_REND_NumOutChannels() - * - * - *-------------------------------------------------------------------*/ - -ivas_error IVAS_REND_NumOutChannels( - IVAS_REND_CONST_HANDLE hIvasRend, - int16_t *numOutChannels ) -{ - ivas_error error; - - /* Validate function arguments */ - if ( hIvasRend == NULL || numOutChannels == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - /* Handle special cases where additional info is needed from the renderer, otherwise use getAudioConfigNumChannels() */ - switch ( hIvasRend->outputConfig ) - { - case IVAS_AUDIO_CONFIG_LS_CUSTOM: - *numOutChannels = hIvasRend->customLsOut.num_spk + hIvasRend->customLsOut.num_lfe; - break; - default: - if ( ( error = getAudioConfigNumChannels( hIvasRend->outputConfig, numOutChannels ) ) != IVAS_ERR_OK ) - { - return error; - } - break; - } - - return IVAS_ERR_OK; -} - - -static IVAS_REND_InputId makeInputId( - AUDIO_CONFIG config, - const int32_t inputIndex ) -{ - /* Put config type in second byte (from LSB), put index + 1 in first byte - * - * Index is incremented here so that a valid ID can never be 0. */ - return (IVAS_REND_InputId) ( ( ( (uint32_t) getAudioConfigType( config ) ) << 8 ) | ( inputIndex + 1 ) ); -} - - -static ivas_error getInputById( - IVAS_REND_HANDLE hIvasRend, - IVAS_REND_InputId inputId, - void **ppInput ) -{ - int32_t inputIndex; - IVAS_REND_AudioConfigType configType; - input_base *pInputBase; - - /* Reverse makeInputId() */ - inputIndex = ( inputId & 0xFF ) - 1; - configType = ( inputId & 0xFF00 ) >> 8; - - /* Validate values derived from input ID */ - if ( inputIndex < 0 ) - { - return IVAS_ERR_INVALID_INPUT_ID; - } - switch ( configType ) - { - case IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED: - if ( inputIndex > RENDERER_MAX_ISM_INPUTS ) - { - return IVAS_ERR_INVALID_INPUT_ID; - } - pInputBase = &hIvasRend->inputsIsm[inputIndex].base; - break; - case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: - if ( inputIndex > RENDERER_MAX_MC_INPUTS ) - { - return IVAS_ERR_INVALID_INPUT_ID; - } - pInputBase = &hIvasRend->inputsMc[inputIndex].base; - break; - case IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS: - if ( inputIndex > RENDERER_MAX_SBA_INPUTS ) - { - return IVAS_ERR_INVALID_INPUT_ID; - } - pInputBase = &hIvasRend->inputsSba[inputIndex].base; - break; - case IVAS_REND_AUDIO_CONFIG_TYPE_MASA: - if ( inputIndex > RENDERER_MAX_MASA_INPUTS ) - { - return IVAS_ERR_INVALID_INPUT_ID; - } - pInputBase = &hIvasRend->inputsMasa[inputIndex].base; - break; - default: - return IVAS_ERR_INVALID_INPUT_ID; - } - - /* Ensure input ID matches and that input is active */ - if ( pInputBase->id != inputId || pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID ) - { - return IVAS_ERR_INVALID_INPUT_ID; + return IVAS_ERR_INVALID_INPUT_ID; } /* Validation done, set value via output parameter */ @@ -3665,7 +3213,7 @@ ivas_error IVAS_REND_SetInputLfeMtx( pInputMc = (input_mc *) pInputBase; /* copy LFE panning matrix */ - for ( i = 0; i < IVAS_MAX_INPUT_LFE_CHANNELS; i++ ) + for ( i = 0; i < RENDERER_MAX_INPUT_LFE_CHANNELS; i++ ) { mvr2r( ( *lfePanMtx )[i], pInputMc->lfeRouting.lfePanMtx[i], IVAS_MAX_OUTPUT_CHANNELS ); } @@ -4207,7 +3755,7 @@ int16_t IVAS_REND_FeedRenderConfig( hRenderConfig->roomAcoustics.dimensions = renderConfig.roomAcoustics.dimensions; hRenderConfig->roomAcoustics.ListenerOrigin = renderConfig.roomAcoustics.ListenerOrigin; - mvr2r( renderConfig.roomAcoustics.AbsCoeff, hRenderConfig->roomAcoustics.AbsCoeff, ER_ABS_COEFF ); + mvr2r( renderConfig.roomAcoustics.AbsCoeff, hRenderConfig->roomAcoustics.AbsCoeff, IVAS_ROOM_ABS_COEFF ); } @@ -4903,7 +4451,7 @@ static ivas_error renderIsmToBinaural( push_wmops( "renderIsmToBinaural" ); /* Metadata Delay to sync with audio delay converted from ms to 5ms (1000/50/4) subframe index */ - ism_md_subframe_update_ext = (int16_t) round( ismInput->ism_metadata_delay_ms / ( 1000 / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ) ); + ism_md_subframe_update_ext = (int16_t) roundf( ismInput->ism_metadata_delay_ms / ( 1000 / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ) ); copyBufferTo2dArray( ismInput->base.inputBuffer, tmpTDRendBuffer ); if ( ( error = ivas_td_binaural_renderer_ext( &ismInput->tdRendWrapper, ismInput->base.inConfig, NULL, ismInput->base.ctx.pCombinedOrientationData, &ismInput->currentPos, ismInput->hReverb, ism_md_subframe_update_ext, @@ -5104,7 +4652,8 @@ static ivas_error renderIsmToBinauralReverb( push_wmops( "renderIsmToBinauralRoom" ); /* Metadata Delay to sync with audio delay converted from ms to 5ms (1000/50/4) subframe index */ - ism_md_subframe_update_ext = (int16_t) round( ismInput->ism_metadata_delay_ms / ( 1000 / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ) ); + ism_md_subframe_update_ext = (int16_t) roundf( ismInput->ism_metadata_delay_ms / ( 1000 / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ) ); + copyBufferTo2dArray( ismInput->base.inputBuffer, tmpRendBuffer ); if ( ( error = ivas_td_binaural_renderer_ext( &ismInput->tdRendWrapper, ismInput->base.inConfig, NULL, ismInput->base.ctx.pCombinedOrientationData, &ismInput->currentPos, ismInput->hReverb, @@ -5301,6 +4850,9 @@ static ivas_error renderInputIsm( /* Apply input gain to new audio */ v_multc( inAudio.data, ismInput->base.gain, inAudio.data, inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); + /* set combined orientation subframe info to start info */ + ivas_combined_orientation_set_to_start_index( *ismInput->base.ctx.pCombinedOrientationData ); + switch ( getAudioConfigType( outConfig ) ) { case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: @@ -5793,6 +5345,9 @@ static ivas_error renderInputMc( /* Apply input gain to new audio */ v_multc( inAudio.data, mcInput->base.gain, inAudio.data, inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); + /* set combined orientation subframe info to start info */ + ivas_combined_orientation_set_to_start_index( *( mcInput->base.ctx.pCombinedOrientationData ) ); + switch ( getAudioConfigType( outConfig ) ) { case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: @@ -6073,86 +5628,360 @@ static ivas_error renderSbaToBinauralRoom( -static void renderSbaToMasa( - input_sba *sbaInput, - IVAS_REND_AudioBuffer outAudio ) -{ - float tmpRendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; +static void renderSbaToMasa( + input_sba *sbaInput, + IVAS_REND_AudioBuffer outAudio ) +{ + float tmpRendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + + push_wmops( "renderMcToMasa" ); + copyBufferTo2dArray( sbaInput->base.inputBuffer, tmpRendBuffer ); + ivas_dirac_ana( sbaInput->hDirAC, tmpRendBuffer, sbaInput->base.inputBuffer.config.numSamplesPerChannel, outAudio.config.numChannels ); + accumulate2dArrayToBuffer( tmpRendBuffer, &outAudio ); + + pop_wmops(); + return; +} + + +static ivas_error renderInputSba( + input_sba *sbaInput, + const AUDIO_CONFIG outConfig, + IVAS_REND_AudioBuffer outAudio ) +{ + ivas_error error; + IVAS_REND_AudioBuffer inAudio; + + error = IVAS_ERR_OK; + inAudio = sbaInput->base.inputBuffer; + + if ( sbaInput->base.numNewSamplesPerChannel != outAudio.config.numSamplesPerChannel ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Mismatch between the number of input samples vs number of requested output samples - currently not allowed" ); + } + sbaInput->base.numNewSamplesPerChannel = 0; + + /* Apply input gain to new audio */ + v_multc( inAudio.data, sbaInput->base.gain, inAudio.data, inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); + + /* set combined orientation subframe info to start info */ + ivas_combined_orientation_set_to_start_index( *( sbaInput->base.ctx.pCombinedOrientationData ) ); + + switch ( getAudioConfigType( outConfig ) ) + { + case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: + renderSbaToMc( sbaInput, outAudio ); + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS: + renderSbaToSba( sbaInput, outAudio ); + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: + switch ( outConfig ) + { + case IVAS_AUDIO_CONFIG_BINAURAL: + error = renderSbaToBinaural( sbaInput, outConfig, outAudio ); + break; + case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: + case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: + error = renderSbaToBinauralRoom( sbaInput, outConfig, outAudio ); + break; + default: + return IVAS_ERR_INVALID_OUTPUT_FORMAT; + } + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_MASA: + renderSbaToMasa( sbaInput, outAudio ); + break; + default: + return IVAS_ERR_INVALID_OUTPUT_FORMAT; + } + + return error; +} + + + + +static ivas_error renderActiveInputsSba( + IVAS_REND_HANDLE hIvasRend, + IVAS_REND_AudioBuffer outAudio ) +{ + int16_t i; + input_sba *pCurrentInput; + ivas_error error; + + for ( i = 0, pCurrentInput = hIvasRend->inputsSba; i < RENDERER_MAX_SBA_INPUTS; ++i, ++pCurrentInput ) + { + if ( pCurrentInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + /* Skip inactive inputs */ + continue; + } + + if ( ( error = renderInputSba( pCurrentInput, hIvasRend->outputConfig, outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + return IVAS_ERR_OK; +} + + +static void copyMasaMetadataToDiracRenderer( + MASA_METADATA_FRAME *meta, + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, + const int16_t maxBin ) +{ + int16_t band, sf, bin; + int16_t meta_write_index; + + hSpatParamRendCom->numParametricDirections = meta->descriptive_meta.numberOfDirections + 1; + hSpatParamRendCom->numSimultaneousDirections = meta->descriptive_meta.numberOfDirections + 1; + + for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + { + meta_write_index = ( hSpatParamRendCom->dirac_bs_md_write_idx + sf ) % hSpatParamRendCom->dirac_md_buffer_length; + + for ( band = 0; band < MASA_MAXIMUM_CODING_SUBBANDS; band++ ) + { + for ( bin = MASA_band_grouping_24[band]; bin < MASA_band_grouping_24[band + 1] && bin < maxBin; bin++ ) + { + hSpatParamRendCom->azimuth[meta_write_index][bin] = (int16_t) meta->directional_meta[0].azimuth[sf][band]; + hSpatParamRendCom->elevation[meta_write_index][bin] = (int16_t) meta->directional_meta[0].elevation[sf][band]; + hSpatParamRendCom->energy_ratio1[meta_write_index][bin] = meta->directional_meta[0].energy_ratio[sf][band]; + hSpatParamRendCom->diffuseness_vector[meta_write_index][bin] = 1.0f - meta->directional_meta[0].energy_ratio[sf][band]; + hSpatParamRendCom->spreadCoherence[meta_write_index][bin] = meta->directional_meta[0].spread_coherence[sf][band]; + hSpatParamRendCom->surroundingCoherence[meta_write_index][bin] = meta->common_meta.surround_coherence[sf][band]; + + if ( hSpatParamRendCom->numSimultaneousDirections == 2 ) + { + hSpatParamRendCom->azimuth2[meta_write_index][bin] = (int16_t) meta->directional_meta[1].azimuth[sf][band]; + hSpatParamRendCom->elevation2[meta_write_index][bin] = (int16_t) meta->directional_meta[1].elevation[sf][band]; + hSpatParamRendCom->energy_ratio2[meta_write_index][bin] = meta->directional_meta[1].energy_ratio[sf][band]; + hSpatParamRendCom->diffuseness_vector[meta_write_index][bin] -= meta->directional_meta[1].energy_ratio[sf][band]; + hSpatParamRendCom->spreadCoherence2[meta_write_index][bin] = meta->directional_meta[1].spread_coherence[sf][band]; + } + } + } + } + + hSpatParamRendCom->dirac_bs_md_write_idx = ( hSpatParamRendCom->dirac_bs_md_write_idx + MAX_PARAM_SPATIAL_SUBFRAMES ) % hSpatParamRendCom->dirac_md_buffer_length; + + return; +} + + +static void renderMasaToMasa( + input_masa *masaInput, + IVAS_REND_AudioBuffer outAudio ) +{ + int16_t sf, band, dir, numDirs; + float ratioSum; + MASA_DECODER_EXT_OUT_META_HANDLE outMeta; + MASA_METADATA_FRAME *inMeta; + float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + int16_t ts, i, j, l_ts; + float Chan_RealBuffer[MASA_MAX_TRANSPORT_CHANNELS][CLDFB_NO_CHANNELS_MAX]; + float Chan_ImagBuffer[MASA_MAX_TRANSPORT_CHANNELS][CLDFB_NO_CHANNELS_MAX]; + int16_t band_m_idx, block_m_idx; + int16_t mrange[2]; + int16_t brange[2]; + int16_t numAnalysisChannels; + + copyBufferTo2dArray( masaInput->base.inputBuffer, tmpBuffer ); + + /* Calculate energy */ + l_ts = masaInput->base.inputBuffer.config.numSamplesPerChannel / CLDFB_NO_COL_MAX; + numAnalysisChannels = masaInput->hMasaPrerend->num_Cldfb_instances; + + /* do processing over all CLDFB time slots */ + for ( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ ) + { + mrange[0] = DirAC_block_grouping[block_m_idx]; + mrange[1] = DirAC_block_grouping[block_m_idx + 1]; + + set_zero( masaInput->hMasaPrerend->energy[block_m_idx], MASA_FREQUENCY_BANDS ); + + for ( ts = mrange[0]; ts < mrange[1]; ts++ ) + { + for ( i = 0; i < numAnalysisChannels; i++ ) + { + cldfbAnalysis_ts( &( tmpBuffer[i][l_ts * ts] ), Chan_RealBuffer[i], Chan_ImagBuffer[i], l_ts, masaInput->hMasaPrerend->cldfbAnaEnc[i] ); + } + + /* Compute channel energy for metadata processing */ + for ( band_m_idx = 0; band_m_idx < MASA_FREQUENCY_BANDS; band_m_idx++ ) + { + brange[0] = MASA_band_grouping_24[band_m_idx]; + brange[1] = MASA_band_grouping_24[band_m_idx + 1]; + for ( j = brange[0]; j < brange[1]; j++ ) + { + for ( i = 0; i < numAnalysisChannels; i++ ) + { + masaInput->hMasaPrerend->energy[block_m_idx][band_m_idx] += Chan_RealBuffer[0][j] * Chan_RealBuffer[0][j] + Chan_ImagBuffer[0][j] * Chan_ImagBuffer[0][j]; + } + } + } + } + } + + /* Copy audio channels if mismatch in number of transports */ + if ( masaInput->base.inputBuffer.config.numChannels == 1 && outAudio.config.numChannels == 2 ) + { + mvr2r( tmpBuffer[0], tmpBuffer[1], masaInput->base.inputBuffer.config.numSamplesPerChannel ); + } + else if ( masaInput->base.inputBuffer.config.numChannels == 2 && outAudio.config.numChannels == 1 ) + { + v_add( tmpBuffer[0], tmpBuffer[1], tmpBuffer[0], masaInput->base.inputBuffer.config.numSamplesPerChannel ); + } + + /* Copy metadata */ + outMeta = masaInput->hMasaPrerend->hMasaOut; + inMeta = &masaInput->masaMetadata; + numDirs = inMeta->descriptive_meta.numberOfDirections + 1; + + for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + { + for ( band = 0; band < MASA_FREQUENCY_BANDS; band++ ) + { + /* Remainder is always set to zero and energy removal is compensated in following steps + * to other ratios. */ + inMeta->common_meta.remainder_to_total_ratio[sf][band] = 0.0f; + + ratioSum = 0; + for ( dir = 0; dir < numDirs; dir++ ) + { + ratioSum += inMeta->directional_meta[dir].energy_ratio[sf][band]; + } + ratioSum += inMeta->common_meta.diffuse_to_total_ratio[sf][band]; + + if ( ratioSum == 0.0f ) + { + for ( dir = 0; dir < numDirs; dir++ ) + { + inMeta->directional_meta[dir].energy_ratio[sf][band] = 0.0f; + } + inMeta->common_meta.diffuse_to_total_ratio[sf][band] = 1.0f; + } + else if ( ratioSum != 1.0f ) + { + for ( dir = 0; dir < numDirs; dir++ ) + { + inMeta->directional_meta[dir].energy_ratio[sf][band] /= ratioSum; + } + inMeta->common_meta.diffuse_to_total_ratio[sf][band] /= ratioSum; + } + } + } + + for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + { + for ( band = 0; band < MASA_FREQUENCY_BANDS; band++ ) + { + outMeta->diffuseToTotalRatio[sf][band] = UINT8_MAX; + for ( dir = 0; dir < numDirs; dir++ ) + { + outMeta->directionIndex[dir][sf][band] = index_theta_phi_16( &inMeta->directional_meta[dir].elevation[sf][band], &inMeta->directional_meta[dir].azimuth[sf][band], masaInput->hMasaPrerend->sph_grid16 ); + outMeta->directToTotalRatio[dir][sf][band] = (uint8_t) floorf( inMeta->directional_meta[dir].energy_ratio[sf][band] * UINT8_MAX ); + outMeta->diffuseToTotalRatio[sf][band] -= outMeta->directToTotalRatio[dir][sf][band]; + outMeta->spreadCoherence[dir][sf][band] = (uint8_t) floorf( inMeta->directional_meta[dir].spread_coherence[sf][band] * UINT8_MAX ); + } + outMeta->surroundCoherence[sf][band] = (uint8_t) floorf( inMeta->common_meta.surround_coherence[sf][band] * UINT8_MAX ); + } + } + + copy_masa_descriptive_meta( &( outMeta->descriptiveMeta ), &( inMeta->descriptive_meta ) ); - push_wmops( "renderMcToMasa" ); - copyBufferTo2dArray( sbaInput->base.inputBuffer, tmpRendBuffer ); - ivas_dirac_ana( sbaInput->hDirAC, tmpRendBuffer, sbaInput->base.inputBuffer.config.numSamplesPerChannel, outAudio.config.numChannels ); - accumulate2dArrayToBuffer( tmpRendBuffer, &outAudio ); + accumulate2dArrayToBuffer( tmpBuffer, &outAudio ); - pop_wmops(); return; } -static ivas_error renderInputSba( - input_sba *sbaInput, +static ivas_error renderInputMasa( + input_masa *masaInput, const AUDIO_CONFIG outConfig, IVAS_REND_AudioBuffer outAudio ) { - ivas_error error; IVAS_REND_AudioBuffer inAudio; + int16_t ch; + int16_t maxBin; + float *tmpBuffer[MAX_OUTPUT_CHANNELS]; + float tmpBuffer_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - error = IVAS_ERR_OK; - inAudio = sbaInput->base.inputBuffer; + if ( !masaInput->metadataHasBeenFed ) + { + return IVAS_ERR_MISSING_METADATA; + } - if ( sbaInput->base.numNewSamplesPerChannel != outAudio.config.numSamplesPerChannel ) + inAudio = masaInput->base.inputBuffer; + if ( masaInput->base.numNewSamplesPerChannel != outAudio.config.numSamplesPerChannel ) { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Mismatch between the number of input samples vs number of requested output samples - currently not allowed" ); } - sbaInput->base.numNewSamplesPerChannel = 0; + masaInput->base.numNewSamplesPerChannel = 0; /* Apply input gain to new audio */ - v_multc( inAudio.data, sbaInput->base.gain, inAudio.data, inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); + v_multc( inAudio.data, masaInput->base.gain, inAudio.data, inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); - switch ( getAudioConfigType( outConfig ) ) + maxBin = (int16_t) ( *masaInput->base.ctx.pOutSampleRate * INV_CLDFB_BANDWIDTH ); + + /* set combined orientation subframe info to start info */ + ivas_combined_orientation_set_to_start_index( *( masaInput->base.ctx.pCombinedOrientationData ) ); + + if ( getAudioConfigType( outConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_MASA ) { - case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: - renderSbaToMc( sbaInput, outAudio ); - break; - case IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS: - renderSbaToSba( sbaInput, outAudio ); - break; - case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: - switch ( outConfig ) + /* MASA prerendering path for MASA -> MASA */ + renderMasaToMasa( masaInput, outAudio ); + } + else + { + /* MASA external renderer -> other formats */ + int16_t num_subframes; + for ( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) + { + tmpBuffer[ch] = tmpBuffer_buff[ch]; + } + + copyBufferTo2dArray( masaInput->base.inputBuffer, tmpBuffer_buff ); + + num_subframes = (int16_t) ( masaInput->base.inputBuffer.config.numSamplesPerChannel / ( *masaInput->base.ctx.pOutSampleRate / ( IVAS_NUM_FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ) ); + + switch ( masaInput->hMasaExtRend->renderer_type ) { - case IVAS_AUDIO_CONFIG_BINAURAL: - error = renderSbaToBinaural( sbaInput, outConfig, outAudio ); + case RENDERER_DIRAC: + copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->hMasaExtRend->hSpatParamRendCom, maxBin ); + ivas_masa_ext_dirac_render( masaInput->hMasaExtRend, tmpBuffer, num_subframes ); break; - case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: - case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: - error = renderSbaToBinauralRoom( sbaInput, outConfig, outAudio ); + case RENDERER_STEREO_PARAMETRIC: + case RENDERER_BINAURAL_PARAMETRIC: + case RENDERER_BINAURAL_PARAMETRIC_ROOM: + copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->hMasaExtRend->hSpatParamRendCom, maxBin ); + ivas_masa_ext_rend_parambin_render( masaInput->hMasaExtRend, *masaInput->base.ctx.pCombinedOrientationData, tmpBuffer, num_subframes ); break; + case RENDERER_DISABLE: + break; /* This happens for 1TC MASA to MONO where we just copy input transport to output */ default: - return IVAS_ERR_INVALID_OUTPUT_FORMAT; + return ( IVAS_ERROR( IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED, "Wrong output config for MASA input in external renderer\n" ) ); } - break; - case IVAS_REND_AUDIO_CONFIG_TYPE_MASA: - renderSbaToMasa( sbaInput, outAudio ); - break; - default: - return IVAS_ERR_INVALID_OUTPUT_FORMAT; + + accumulate2dArrayToBuffer( tmpBuffer_buff, &outAudio ); } - return error; + return IVAS_ERR_OK; } - - -static ivas_error renderActiveInputsSba( +static ivas_error renderActiveInputsMasa( IVAS_REND_HANDLE hIvasRend, IVAS_REND_AudioBuffer outAudio ) { int16_t i; - input_sba *pCurrentInput; + input_masa *pCurrentInput; ivas_error error; - for ( i = 0, pCurrentInput = hIvasRend->inputsSba; i < RENDERER_MAX_SBA_INPUTS; ++i, ++pCurrentInput ) + for ( i = 0, pCurrentInput = hIvasRend->inputsMasa; i < RENDERER_MAX_MASA_INPUTS; ++i, ++pCurrentInput ) { if ( pCurrentInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) { @@ -6160,7 +5989,7 @@ static ivas_error renderActiveInputsSba( continue; } - if ( ( error = renderInputSba( pCurrentInput, hIvasRend->outputConfig, outAudio ) ) != IVAS_ERR_OK ) + if ( ( error = renderInputMasa( pCurrentInput, hIvasRend->outputConfig, outAudio ) ) != IVAS_ERR_OK ) { return error; } @@ -6170,710 +5999,1080 @@ static ivas_error renderActiveInputsSba( } -static void copyMasaMetadataToDiracRenderer( - MASA_METADATA_FRAME *meta, - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom ) +/*---------------------------------------------------------------------* + * IVAS_REND_GetMasaMetadata( ) + * + * Get metadata of the estimated MASA frame + *---------------------------------------------------------------------*/ + +ivas_error IVAS_REND_GetMasaMetadata( + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + MASA_DECODER_EXT_OUT_META_HANDLE *hMasaExtOutMeta, /* o : pointer to handle, which will be set to point to analyzed MASA metadata */ + const IVAS_REND_AudioConfigType inputType /* i : Input type */ +) { - int16_t band, sf, bin; - int16_t meta_write_index; + if ( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - hSpatParamRendCom->numParametricDirections = meta->descriptive_meta.numberOfDirections + 1; - hSpatParamRendCom->numSimultaneousDirections = meta->descriptive_meta.numberOfDirections + 1; + /* Get the metadata handle */ + if ( inputType == IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED ) + { + *hMasaExtOutMeta = hIvasRend->inputsIsm->hOMasa->hMasaOut; + } + else if ( inputType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) + { + *hMasaExtOutMeta = hIvasRend->inputsMc->hMcMasa->hMasaOut; + } + else if ( inputType == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) + { + *hMasaExtOutMeta = hIvasRend->inputsSba->hDirAC->hMasaOut; + } + else + { + return IVAS_ERR_NOT_SUPPORTED_OPTION; + } - for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + return IVAS_ERR_OK; +} + + +/*---------------------------------------------------------------------* + * IVAS_REND_MergeMasaMetadata( ) + * + * Merge MASA metadata from two formats + *---------------------------------------------------------------------*/ + +ivas_error IVAS_REND_MergeMasaMetadata( + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + MASA_DECODER_EXT_OUT_META_HANDLE *hMasaExtOutMeta, /* o : pointer to handle, which will be set to point to merged metadata */ + const IVAS_REND_AudioConfigType inputType1, /* i : Input type 1 */ + const IVAS_REND_AudioConfigType inputType2 /* i : Input type 2 */ +) +{ + MASA_DECODER_EXT_OUT_META_HANDLE inMeta2; + float( *inEne1 )[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + float( *inEne2 )[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + + if ( hIvasRend == NULL ) { - meta_write_index = ( hSpatParamRendCom->dirac_bs_md_write_idx + sf ) % hSpatParamRendCom->dirac_md_buffer_length; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - for ( band = 0; band < MASA_MAXIMUM_CODING_SUBBANDS; band++ ) - { - for ( bin = MASA_band_grouping_24[band]; bin < MASA_band_grouping_24[band + 1]; bin++ ) - { - hSpatParamRendCom->azimuth[meta_write_index][bin] = (int16_t) meta->directional_meta[0].azimuth[sf][band]; - hSpatParamRendCom->elevation[meta_write_index][bin] = (int16_t) meta->directional_meta[0].elevation[sf][band]; - hSpatParamRendCom->energy_ratio1[meta_write_index][bin] = meta->directional_meta[0].energy_ratio[sf][band]; - hSpatParamRendCom->diffuseness_vector[meta_write_index][bin] = 1.0f - meta->directional_meta[0].energy_ratio[sf][band]; - hSpatParamRendCom->spreadCoherence[meta_write_index][bin] = meta->directional_meta[0].spread_coherence[sf][band]; - hSpatParamRendCom->surroundingCoherence[meta_write_index][bin] = meta->common_meta.surround_coherence[sf][band]; + /* Input1 metadata and energy */ + if ( inputType1 == IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED ) + { + *hMasaExtOutMeta = hIvasRend->inputsIsm->hOMasa->hMasaOut; + inEne1 = &( hIvasRend->inputsIsm->hOMasa->energy ); + } + else if ( inputType1 == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) + { + *hMasaExtOutMeta = hIvasRend->inputsMc->hMcMasa->hMasaOut; + inEne1 = &( hIvasRend->inputsMc->hMcMasa->energy ); + } + else if ( inputType1 == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) + { + *hMasaExtOutMeta = hIvasRend->inputsSba->hDirAC->hMasaOut; + inEne1 = &( hIvasRend->inputsSba->hDirAC->energy ); + } + else if ( inputType1 == IVAS_REND_AUDIO_CONFIG_TYPE_MASA ) + { + *hMasaExtOutMeta = hIvasRend->inputsMasa->hMasaPrerend->hMasaOut; + inEne1 = &( hIvasRend->inputsMasa->hMasaPrerend->energy ); + } + else + { + return IVAS_ERR_NOT_SUPPORTED_OPTION; + } - if ( hSpatParamRendCom->numSimultaneousDirections == 2 ) - { - hSpatParamRendCom->azimuth2[meta_write_index][bin] = (int16_t) meta->directional_meta[1].azimuth[sf][band]; - hSpatParamRendCom->elevation2[meta_write_index][bin] = (int16_t) meta->directional_meta[1].elevation[sf][band]; - hSpatParamRendCom->energy_ratio2[meta_write_index][bin] = meta->directional_meta[1].energy_ratio[sf][band]; - hSpatParamRendCom->diffuseness_vector[meta_write_index][bin] -= meta->directional_meta[1].energy_ratio[sf][band]; - hSpatParamRendCom->spreadCoherence2[meta_write_index][bin] = meta->directional_meta[1].spread_coherence[sf][band]; - } - } - } + /* Input2 metadata and energy */ + if ( inputType2 == IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED ) + { + inMeta2 = hIvasRend->inputsIsm->hOMasa->hMasaOut; + inEne2 = &( hIvasRend->inputsIsm->hOMasa->energy ); + } + else if ( inputType2 == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) + { + inMeta2 = hIvasRend->inputsMc->hMcMasa->hMasaOut; + inEne2 = &( hIvasRend->inputsMc->hMcMasa->energy ); + } + else if ( inputType2 == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) + { + inMeta2 = hIvasRend->inputsSba->hDirAC->hMasaOut; + inEne2 = &( hIvasRend->inputsSba->hDirAC->energy ); + } + else if ( inputType2 == IVAS_REND_AUDIO_CONFIG_TYPE_MASA ) + { + inMeta2 = hIvasRend->inputsMasa->hMasaPrerend->hMasaOut; + inEne2 = &( hIvasRend->inputsMasa->hMasaPrerend->energy ); + } + else + { + return IVAS_ERR_NOT_SUPPORTED_OPTION; + } + + /* Merge metadata */ + ivas_prerend_merge_masa_metadata( *hMasaExtOutMeta, *hMasaExtOutMeta, inputType1, *inEne1, inMeta2, inputType2, *inEne2 ); + ( *hMasaExtOutMeta )->descriptiveMeta.numberOfChannels = hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_MASA1 ? 0u : 1u; + + return IVAS_ERR_OK; +} + + +/*---------------------------------------------------------------------* + * IVAS_REND_SetTotalNumberOfObjects( ) + * + * Set the total number of objects to the first object data + *---------------------------------------------------------------------*/ + +ivas_error IVAS_REND_SetTotalNumberOfObjects( + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + const uint16_t total_num_objects /* i : total number of objects */ +) +{ + if ( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + hIvasRend->inputsIsm[0].total_num_objects = total_num_objects; + + return IVAS_ERR_OK; +} + + +/*---------------------------------------------------------------------* + * IVAS_REND_SetIsmMetadataDelay( ) + * + * Set the Metadata Delay in ms in order to sync with audio delay + *---------------------------------------------------------------------*/ + +ivas_error IVAS_REND_SetIsmMetadataDelay( + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + const float sync_md_delay /* i : ISM Metadata Delay in ms to sync with audio delay */ +) +{ + int16_t i; + + if ( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - hSpatParamRendCom->dirac_bs_md_write_idx = ( hSpatParamRendCom->dirac_bs_md_write_idx + MAX_PARAM_SPATIAL_SUBFRAMES ) % hSpatParamRendCom->dirac_md_buffer_length; + for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) + { + hIvasRend->inputsIsm[i].ism_metadata_delay_ms = sync_md_delay; + } - return; + return IVAS_ERR_OK; } -static void renderMasaToMc( - input_masa *masaInput, - IVAS_REND_AudioBuffer outAudio ) +/*-------------------------------------------------------------------* + * getSamplesInternal() + * + * + *-------------------------------------------------------------------*/ + +static ivas_error getSamplesInternal( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ +) { - int16_t ch; - float *tmpBuffer[MAX_OUTPUT_CHANNELS], tmpBuffer_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + ivas_error error; + int16_t numOutChannels; - for ( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) + /* Validate function arguments */ + if ( hIvasRend == NULL || outAudio.data == NULL ) { - tmpBuffer[ch] = tmpBuffer_buff[ch]; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - copyBufferTo2dArray( masaInput->base.inputBuffer, tmpBuffer_buff ); - copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->decDummy->hSpatParamRendCom ); + if ( outAudio.config.numSamplesPerChannel <= 0 || MAX_BUFFER_LENGTH_PER_CHANNEL < outAudio.config.numSamplesPerChannel ) + { + return IVAS_ERR_INVALID_BUFFER_SIZE; + } - if ( masaInput->decDummy->renderer_type == RENDERER_STEREO_PARAMETRIC ) + if ( outAudio.config.numChannels <= 0 || MAX_OUTPUT_CHANNELS < outAudio.config.numChannels ) { - ivas_dirac_dec_binaural( masaInput->decDummy, *masaInput->base.ctx.pCombinedOrientationData, tmpBuffer, masaInput->base.inputBuffer.config.numChannels, getNumSubframesInBuffer( &outAudio, *masaInput->base.ctx.pOutSampleRate ) ); + return IVAS_ERR_WRONG_NUM_CHANNELS; } - else + + if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL && + outAudio.config.numSamplesPerChannel * 1000 != ( hIvasRend->num_subframes * BINAURAL_RENDERING_FRAME_SIZE_MS ) * hIvasRend->sampleRateOut ) { - ivas_dirac_dec( masaInput->decDummy, tmpBuffer, masaInput->base.inputBuffer.config.numChannels, getNumSubframesInBuffer( &outAudio, *masaInput->base.ctx.pOutSampleRate ) ); + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" ); } - accumulate2dArrayToBuffer( tmpBuffer_buff, &outAudio ); + /* Check that there is allowed configuration for MASA format output */ + if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_MASA ) + { + int16_t i; + int16_t numMasaInputs = 0; + int16_t numOtherInputs = 0; - return; -} + for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; i++ ) + { + numMasaInputs += hIvasRend->inputsMasa[i].base.inConfig == IVAS_AUDIO_CONFIG_INVALID ? 0 : 1; + } + for ( i = 0; i < RENDERER_MAX_MC_INPUTS; i++ ) + { + numOtherInputs += hIvasRend->inputsMc[i].base.inConfig == IVAS_AUDIO_CONFIG_INVALID ? 0 : 1; + } -static void renderMasaToSba( - input_masa *masaInput, - IVAS_REND_AudioBuffer outAudio ) -{ - int16_t ch; - float *tmpBuffer[MAX_OUTPUT_CHANNELS], tmpBuffer_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; i++ ) + { + numOtherInputs += hIvasRend->inputsSba[i].base.inConfig == IVAS_AUDIO_CONFIG_INVALID ? 0 : 1; + } + + /* For ISM, we check only first as all ISMs are handled together via OMASA when merging to MASA. */ + numOtherInputs += hIvasRend->inputsIsm[0].base.inConfig == IVAS_AUDIO_CONFIG_INVALID ? 0 : 1; + + if ( numMasaInputs == 0 || numOtherInputs == 0 ) + { + return IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED; + } + } - for ( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) + if ( ( error = IVAS_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) { - tmpBuffer[ch] = tmpBuffer_buff[ch]; + return error; } - copyBufferTo2dArray( masaInput->base.inputBuffer, tmpBuffer_buff ); - copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->decDummy->hSpatParamRendCom ); + if ( numOutChannels != outAudio.config.numChannels ) + { + return IVAS_ERR_WRONG_NUM_CHANNELS; + } - ivas_dirac_dec( masaInput->decDummy, tmpBuffer, masaInput->base.inputBuffer.config.numChannels, getNumSubframesInBuffer( &outAudio, *masaInput->base.ctx.pOutSampleRate ) ); + /* Clear original output buffer */ + set_zero( outAudio.data, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel ); - accumulate2dArrayToBuffer( tmpBuffer_buff, &outAudio ); - return; -} + if ( ( error = renderActiveInputsIsm( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = renderActiveInputsMc( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } -static void renderMasaToBinaural( - input_masa *masaInput, - IVAS_REND_AudioBuffer outAudio -) -{ - int16_t ch; - float *tmpBuffer[MAX_OUTPUT_CHANNELS], tmpBuffer_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + if ( ( error = renderActiveInputsSba( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } - for ( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) + if ( ( error = renderActiveInputsMasa( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) { - tmpBuffer[ch] = tmpBuffer_buff[ch]; + return error; } - copyBufferTo2dArray( masaInput->base.inputBuffer, tmpBuffer_buff ); - copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->decDummy->hSpatParamRendCom ); +#ifndef DISABLE_LIMITER + limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD ); +#endif - ivas_dirac_dec_binaural( masaInput->decDummy, *masaInput->base.ctx.pCombinedOrientationData, tmpBuffer, masaInput->base.inputBuffer.config.numChannels, getNumSubframesInBuffer( &outAudio, *masaInput->base.ctx.pOutSampleRate ) ); - accumulate2dArrayToBuffer( tmpBuffer_buff, &outAudio ); + /* update global cominbed orientation start index */ + ivas_combined_orientation_update_start_index( hIvasRend->hCombinedOrientationData, outAudio.config.numSamplesPerChannel ); - return; + return IVAS_ERR_OK; } -static void renderMasaToMasa( - input_masa *masaInput, - IVAS_REND_AudioBuffer outAudio ) +/*-------------------------------------------------------------------* + * IVAS_REND_GetSamples() + * + * + *-------------------------------------------------------------------*/ + +ivas_error IVAS_REND_GetSamples( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ +) { - int16_t sf, band, dir, numDirs; - float ratioSum; - MASA_DECODER_EXT_OUT_META_HANDLE outMeta; - MASA_METADATA_FRAME *inMeta; - float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - int16_t ts, i, j, l_ts; - float Chan_RealBuffer[MASA_MAX_TRANSPORT_CHANNELS][CLDFB_NO_CHANNELS_MAX]; - float Chan_ImagBuffer[MASA_MAX_TRANSPORT_CHANNELS][CLDFB_NO_CHANNELS_MAX]; - int16_t band_m_idx, block_m_idx; - int16_t mrange[2]; - int16_t brange[2]; - int16_t numAnalysisChannels; - copyBufferTo2dArray( masaInput->base.inputBuffer, tmpBuffer ); + return getSamplesInternal( hIvasRend, outAudio ); +} - /* Calculate energy */ - l_ts = masaInput->base.inputBuffer.config.numSamplesPerChannel / CLDFB_NO_COL_MAX; - numAnalysisChannels = masaInput->hMasaPrerend->num_Cldfb_instances; - /* do processing over all CLDFB time slots */ - for ( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ ) - { - mrange[0] = DirAC_block_grouping[block_m_idx]; - mrange[1] = DirAC_block_grouping[block_m_idx + 1]; - set_zero( masaInput->hMasaPrerend->energy[block_m_idx], MASA_FREQUENCY_BANDS ); - for ( ts = mrange[0]; ts < mrange[1]; ts++ ) - { - for ( i = 0; i < numAnalysisChannels; i++ ) - { - cldfbAnalysis_ts( &( tmpBuffer[i][l_ts * ts] ), Chan_RealBuffer[i], Chan_ImagBuffer[i], l_ts, masaInput->hMasaPrerend->cldfbAnaEnc[i] ); - } +/*-------------------------------------------------------------------* + * IVAS_REND_Close() + * + * + *-------------------------------------------------------------------*/ - /* Compute channel energy for metadata processing */ - for ( band_m_idx = 0; band_m_idx < MASA_FREQUENCY_BANDS; band_m_idx++ ) - { - brange[0] = MASA_band_grouping_24[band_m_idx]; - brange[1] = MASA_band_grouping_24[band_m_idx + 1]; - for ( j = brange[0]; j < brange[1]; j++ ) - { - for ( i = 0; i < numAnalysisChannels; i++ ) - { - masaInput->hMasaPrerend->energy[block_m_idx][band_m_idx] += Chan_RealBuffer[0][j] * Chan_RealBuffer[0][j] + Chan_ImagBuffer[0][j] * Chan_ImagBuffer[0][j]; - } - } - } - } - } +void IVAS_REND_Close( + IVAS_REND_HANDLE *phIvasRend /* i/o: Pointer to renderer handle */ +) +{ + uint16_t i; + IVAS_REND_HANDLE hIvasRend; - /* Copy audio channels if mismatch in number of transports */ - if ( masaInput->base.inputBuffer.config.numChannels == 1 && outAudio.config.numChannels == 2 ) + /* Validate function arguments */ + if ( phIvasRend == NULL || *phIvasRend == NULL ) { - mvr2r( tmpBuffer[0], tmpBuffer[1], masaInput->base.inputBuffer.config.numSamplesPerChannel ); + return; } - else if ( masaInput->base.inputBuffer.config.numChannels == 2 && outAudio.config.numChannels == 1 ) + hIvasRend = *phIvasRend; + + if ( hIvasRend->efapOutWrapper.hEfap != NULL ) { - v_add( tmpBuffer[0], tmpBuffer[1], tmpBuffer[0], masaInput->base.inputBuffer.config.numSamplesPerChannel ); + efap_free_data( &hIvasRend->efapOutWrapper.hEfap ); } - /* Copy metadata */ - outMeta = masaInput->hMasaPrerend->hMasaOut; - inMeta = &masaInput->masaMetadata; - numDirs = inMeta->descriptive_meta.numberOfDirections + 1; - - for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + /* clear inputs */ + for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) { - for ( band = 0; band < MASA_FREQUENCY_BANDS; band++ ) - { - /* Remainder is always set to zero and energy removal is compensated in following steps - * to other ratios. */ - inMeta->common_meta.remainder_to_total_ratio[sf][band] = 0.0f; - - ratioSum = 0; - for ( dir = 0; dir < numDirs; dir++ ) - { - ratioSum += inMeta->directional_meta[dir].energy_ratio[sf][band]; - } - ratioSum += inMeta->common_meta.diffuse_to_total_ratio[sf][band]; - - if ( ratioSum == 0.0f ) - { - for ( dir = 0; dir < numDirs; dir++ ) - { - inMeta->directional_meta[dir].energy_ratio[sf][band] = 0.0f; - } - inMeta->common_meta.diffuse_to_total_ratio[sf][band] = 1.0f; - } - else if ( ratioSum != 1.0f ) - { - for ( dir = 0; dir < numDirs; dir++ ) - { - inMeta->directional_meta[dir].energy_ratio[sf][band] /= ratioSum; - } - inMeta->common_meta.diffuse_to_total_ratio[sf][band] /= ratioSum; - } - } + clearInputIsm( &hIvasRend->inputsIsm[i] ); } - - for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) { - for ( band = 0; band < MASA_FREQUENCY_BANDS; band++ ) - { - outMeta->diffuseToTotalRatio[sf][band] = UINT8_MAX; - for ( dir = 0; dir < numDirs; dir++ ) - { - outMeta->directionIndex[dir][sf][band] = index_theta_phi_16( &inMeta->directional_meta[dir].elevation[sf][band], &inMeta->directional_meta[dir].azimuth[sf][band], masaInput->hMasaPrerend->sph_grid16 ); - outMeta->directToTotalRatio[dir][sf][band] = (uint8_t) floorf( inMeta->directional_meta[dir].energy_ratio[sf][band] * UINT8_MAX ); - outMeta->diffuseToTotalRatio[sf][band] -= outMeta->directToTotalRatio[dir][sf][band]; - outMeta->spreadCoherence[dir][sf][band] = (uint8_t) floorf( inMeta->directional_meta[dir].spread_coherence[sf][band] * UINT8_MAX ); - } - outMeta->surroundCoherence[sf][band] = (uint8_t) floorf( inMeta->common_meta.surround_coherence[sf][band] * UINT8_MAX ); - } + clearInputMc( &hIvasRend->inputsMc[i] ); } + for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) + { + clearInputSba( &hIvasRend->inputsSba[i] ); + } + for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) + { + clearInputMasa( &hIvasRend->inputsMasa[i] ); + } + + /* clear Config. Renderer */ + ivas_render_config_close( &( hIvasRend->hRendererConfig ) ); + + ivas_limiter_close( &hIvasRend->hLimiter ); + + + closeHeadRotation( hIvasRend ); - copy_masa_descriptive_meta( &( outMeta->descriptiveMeta ), &( inMeta->descriptive_meta ) ); + ivas_external_orientation_close( &hIvasRend->hExternalOrientationData ); + ivas_combined_orientation_close( &hIvasRend->hCombinedOrientationData ); - accumulate2dArrayToBuffer( tmpBuffer, &outAudio ); + free( hIvasRend ); + *phIvasRend = NULL; return; } -static ivas_error renderInputMasa( - input_masa *masaInput, - const AUDIO_CONFIG outConfig, - IVAS_REND_AudioBuffer outAudio ) + + + +static ivas_error ivas_masa_ext_rend_dirac_rend_init( + input_masa *inputMasa ) { - IVAS_REND_AudioBuffer inAudio; + int16_t nchan_out_woLFE; + int16_t nchan_transport; + uint16_t i, j, k; + float ls_azimuth[MAX_OUTPUT_CHANNELS]; + float ls_elevation[MAX_OUTPUT_CHANNELS]; + int32_t output_Fs; + ivas_error error; + DIRAC_REND_HANDLE hDirACRend; + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; - if ( !masaInput->metadataHasBeenFed ) - { - return IVAS_ERR_MISSING_METADATA; - } + error = IVAS_ERR_OK; - inAudio = masaInput->base.inputBuffer; - if ( masaInput->base.numNewSamplesPerChannel != outAudio.config.numSamplesPerChannel ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Mismatch between the number of input samples vs number of requested output samples - currently not allowed" ); - } - masaInput->base.numNewSamplesPerChannel = 0; + hDirACRend = NULL; + output_Fs = *( inputMasa->base.ctx.pOutSampleRate ); - /* Apply input gain to new audio */ - v_multc( inAudio.data, masaInput->base.gain, inAudio.data, inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); + hSpatParamRendCom = inputMasa->hMasaExtRend->hSpatParamRendCom; - switch ( getAudioConfigType( outConfig ) ) - { - case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: - renderMasaToMc( masaInput, outAudio ); - break; - case IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS: - renderMasaToSba( masaInput, outAudio ); - break; - case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: - switch ( outConfig ) - { - case IVAS_AUDIO_CONFIG_BINAURAL: + /*-----------------------------------------------------------------* + * prepare library opening + *-----------------------------------------------------------------*/ - renderMasaToBinaural( masaInput, outAudio ); - break; - /* ToDo */ - // #ifdef FIX_196_REFACTOR_RENDERER_OUTPUT_CONFIG - // case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: - // case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: - // #else - // case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: - // #endif - // renderMasaToBinauralRoom( masaInput, outConfig, outAudio ); - // break; - default: - return IVAS_ERR_INVALID_OUTPUT_FORMAT; - } - break; - case IVAS_REND_AUDIO_CONFIG_TYPE_MASA: - renderMasaToMasa( masaInput, outAudio ); - break; - default: - return IVAS_ERR_INVALID_OUTPUT_FORMAT; + if ( ( hDirACRend = (DIRAC_REND_HANDLE) malloc( sizeof( DIRAC_REND_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC renderer\n" ) ); } - return IVAS_ERR_OK; -} + nchan_transport = inputMasa->base.inConfig == IVAS_AUDIO_CONFIG_MASA2 ? 2 : 1; + /*-----------------------------------------------------------------* + * output setup: for parametric binaural renderer, use output setup, otherwise internal setup + *-----------------------------------------------------------------*/ -static ivas_error renderActiveInputsMasa( - IVAS_REND_HANDLE hIvasRend, - IVAS_REND_AudioBuffer outAudio ) -{ - int16_t i; - input_masa *pCurrentInput; - ivas_error error; - int16_t sf_idx; + ivas_output_init( &hDirACRend->hOutSetup, *inputMasa->base.ctx.pOutConfig ); - for ( i = 0, pCurrentInput = hIvasRend->inputsMasa; i < RENDERER_MAX_MASA_INPUTS; ++i, ++pCurrentInput ) + if ( hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM ) { - if ( pCurrentInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) - { - /* Skip inactive inputs */ - continue; - } + /* Copy from ivas_ls_custom_setup */ + hDirACRend->hOutSetup.nchan_out_woLFE = inputMasa->base.ctx.pCustomLsOut->num_spk; + hDirACRend->hOutSetup.ls_azimuth = inputMasa->base.ctx.pCustomLsOut->ls_azimuth; + hDirACRend->hOutSetup.ls_elevation = inputMasa->base.ctx.pCustomLsOut->ls_elevation; - if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL && pCurrentInput->decDummy->hHeadTrackData != NULL ) - { - for ( sf_idx = 0; sf_idx < hIvasRend->num_subframes; ++sf_idx ) - { - pCurrentInput->decDummy->hHeadTrackData->Quaternions[sf_idx] = hIvasRend->headRotData.headPositions[sf_idx]; - pCurrentInput->decDummy->hHeadTrackData->Pos[sf_idx] = hIvasRend->headRotData.Pos[sf_idx]; - } - } + hDirACRend->hOutSetup.num_lfe = inputMasa->base.ctx.pCustomLsOut->num_lfe; + hDirACRend->hOutSetup.index_lfe[0] = inputMasa->base.ctx.pCustomLsOut->lfe_idx[0]; - if ( ( error = renderInputMasa( pCurrentInput, hIvasRend->outputConfig, outAudio ) ) != IVAS_ERR_OK ) - { - return error; - } + hDirACRend->hOutSetup.is_loudspeaker_setup = TRUE; + hDirACRend->hOutSetup.is_planar_setup = (int8_t) inputMasa->base.ctx.pCustomLsOut->is_planar_setup; } - return IVAS_ERR_OK; -} + nchan_out_woLFE = hDirACRend->hOutSetup.nchan_out_woLFE; + if ( hDirACRend->hOutSetup.ls_azimuth != NULL && hDirACRend->hOutSetup.ls_elevation != NULL ) + { + mvr2r( hDirACRend->hOutSetup.ls_azimuth, ls_azimuth, nchan_out_woLFE ); + mvr2r( hDirACRend->hOutSetup.ls_elevation, ls_elevation, nchan_out_woLFE ); + } -/*---------------------------------------------------------------------* - * IVAS_REND_GetMasaMetadata( ) - * - * Get metadata of the estimated MASA frame - *---------------------------------------------------------------------*/ - -ivas_error IVAS_REND_GetMasaMetadata( - IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ - MASA_DECODER_EXT_OUT_META_HANDLE *hMasaExtOutMeta, /* o : pointer to handle, which will be set to point to analyzed MASA metadata */ - const IVAS_REND_AudioConfigType inputType /* i : Input type */ -) -{ - if ( hIvasRend == NULL ) + if ( hDirACRend->hOutSetup.ambisonics_order == -1 ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + hDirACRend->hOutSetup.ambisonics_order = SBA_HOA3_ORDER; /* Order 3 is used by default in DirAC for SHD processing */ + if ( hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_MONO || hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_STEREO ) + { + hDirACRend->hOutSetup.ambisonics_order = SBA_FOA_ORDER; + } + } + else if ( hDirACRend->hOutSetup.ambisonics_order >= SBA_FOA_ORDER ) + { + mvr2r( ls_azimuth_4d4, ls_azimuth, DIRAC_HOA_RENDERING_NUM_VIRT_DECORR_LS ); + mvr2r( ls_elevation_4d4, ls_elevation, DIRAC_HOA_RENDERING_NUM_VIRT_DECORR_LS ); } - /* Get the metadata handle */ - if ( inputType == IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED ) + /*-----------------------------------------------------------------* + * set input parameters + *-----------------------------------------------------------------*/ + + if ( hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_MONO ) { - *hMasaExtOutMeta = hIvasRend->inputsIsm->hOMasa->hMasaOut; + hDirACRend->synthesisConf = DIRAC_SYNTHESIS_MONO; + hDirACRend->panningConf = DIRAC_PANNING_HOA3; + nchan_out_woLFE = 1; } - else if ( inputType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) + else if ( hDirACRend->hOutSetup.is_loudspeaker_setup ) { - *hMasaExtOutMeta = hIvasRend->inputsMc->hMcMasa->hMasaOut; + hDirACRend->synthesisConf = DIRAC_SYNTHESIS_PSD_LS; + hDirACRend->panningConf = DIRAC_PANNING_VBAP; } - else if ( inputType == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) + else if ( !hDirACRend->hOutSetup.is_loudspeaker_setup && nchan_transport > 1 ) { - *hMasaExtOutMeta = hIvasRend->inputsSba->hDirAC->hMasaOut; + hDirACRend->synthesisConf = DIRAC_SYNTHESIS_PSD_SHD; + hDirACRend->panningConf = DIRAC_PANNING_HOA3; } else { - return IVAS_ERR_NOT_SUPPORTED_OPTION; + hDirACRend->synthesisConf = DIRAC_SYNTHESIS_GAIN_SHD; + hDirACRend->panningConf = DIRAC_PANNING_HOA3; } - return IVAS_ERR_OK; -} - - -/*---------------------------------------------------------------------* - * IVAS_REND_MergeMasaMetadata( ) - * - * Merge MASA metadata from two formats - *---------------------------------------------------------------------*/ + if ( ( hDirACRend->frequency_axis = (float *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) ); + } + set_f( hDirACRend->frequency_axis, 0.0f, hSpatParamRendCom->num_freq_bands ); -ivas_error IVAS_REND_MergeMasaMetadata( - IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ - MASA_DECODER_EXT_OUT_META_HANDLE *hMasaExtOutMeta, /* o : pointer to handle, which will be set to point to merged metadata */ - const IVAS_REND_AudioConfigType inputType1, /* i : Input type 1 */ - const IVAS_REND_AudioConfigType inputType2 /* i : Input type 2 */ -) -{ - MASA_DECODER_EXT_OUT_META_HANDLE inMeta2; - float( *inEne1 )[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - float( *inEne2 )[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + ivas_dirac_dec_get_frequency_axis( hDirACRend->frequency_axis, output_Fs, hSpatParamRendCom->num_freq_bands ); - if ( hIvasRend == NULL ) + if ( hDirACRend->panningConf == DIRAC_PANNING_HOA3 && nchan_transport == 2 ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + if ( ( hDirACRend->masa_stereo_type_detect = (MASA_STEREO_TYPE_DETECT *) malloc( sizeof( MASA_STEREO_TYPE_DETECT ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) ); + } + ivas_masa_init_stereotype_detection( hDirACRend->masa_stereo_type_detect ); + } + else + { + hDirACRend->masa_stereo_type_detect = NULL; } - /* Input1 metadata and energy */ - if ( inputType1 == IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED ) + hSpatParamRendCom->numIsmDirections = 0; + + /*-----------------------------------------------------------------* + * (re)configure sub-modules + *-----------------------------------------------------------------*/ + + /* prototype signal computation */ + /* allocate output setup related arrays */ + if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_LS ) { - *hMasaExtOutMeta = hIvasRend->inputsIsm->hOMasa->hMasaOut; - inEne1 = &( hIvasRend->inputsIsm->hOMasa->energy ); + /* Directional and diffuses components in output LS format */ + hDirACRend->num_outputs_diff = nchan_out_woLFE; + hDirACRend->num_outputs_dir = nchan_out_woLFE; } - else if ( inputType1 == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) + else if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { - *hMasaExtOutMeta = hIvasRend->inputsMc->hMcMasa->hMasaOut; - inEne1 = &( hIvasRend->inputsMc->hMcMasa->energy ); + /* Directional and diffuses components in SHD */ + /* Diffuseness components up to 1st order */ + hDirACRend->num_outputs_diff = ( min( hDirACRend->hOutSetup.ambisonics_order, 1 ) + 1 ) * ( min( hDirACRend->hOutSetup.ambisonics_order, 1 ) + 1 ); + hDirACRend->num_outputs_dir = ivas_sba_get_nchan( hDirACRend->hOutSetup.ambisonics_order, 0 ); } - else if ( inputType1 == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) + else if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD ) { - *hMasaExtOutMeta = hIvasRend->inputsSba->hDirAC->hMasaOut; - inEne1 = &( hIvasRend->inputsSba->hDirAC->energy ); + hDirACRend->num_outputs_diff = DIRAC_HOA_RENDERING_NUM_VIRT_DECORR_LS; + hDirACRend->num_outputs_dir = nchan_out_woLFE; } - else if ( inputType1 == IVAS_REND_AUDIO_CONFIG_TYPE_MASA ) + else if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO ) { - *hMasaExtOutMeta = hIvasRend->inputsMasa->hMasaPrerend->hMasaOut; - inEne1 = &( hIvasRend->inputsMasa->hMasaPrerend->energy ); + hDirACRend->num_outputs_diff = 1; /* There is one output channel in mono */ + hDirACRend->num_outputs_dir = 2; /* Two channels are pre-rendered for stereo type detection */ } else { - return IVAS_ERR_NOT_SUPPORTED_OPTION; + assert( 0 && "DirAC: not existing synthesis methods!" ); } - /* Input2 metadata and energy */ - if ( inputType2 == IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED ) + if ( ( hDirACRend->proto_index_dir = (int16_t *) malloc( sizeof( int16_t ) * hDirACRend->num_outputs_dir ) ) == NULL ) { - inMeta2 = hIvasRend->inputsIsm->hOMasa->hMasaOut; - inEne2 = &( hIvasRend->inputsIsm->hOMasa->energy ); + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) ); } - else if ( inputType2 == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) + + if ( ( hDirACRend->proto_index_diff = (int16_t *) malloc( sizeof( int16_t ) * hDirACRend->num_outputs_diff ) ) == NULL ) { - inMeta2 = hIvasRend->inputsMc->hMcMasa->hMasaOut; - inEne2 = &( hIvasRend->inputsMc->hMcMasa->energy ); + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) ); } - else if ( inputType2 == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) + + set_s( hDirACRend->proto_index_dir, 0, hDirACRend->num_outputs_dir ); + set_s( hDirACRend->proto_index_diff, 0, hDirACRend->num_outputs_diff ); + + hDirACRend->sba_map_tc = sba_map_tc; + + if ( nchan_transport == 1 ) { - inMeta2 = hIvasRend->inputsSba->hDirAC->hMasaOut; - inEne2 = &( hIvasRend->inputsSba->hDirAC->energy ); + hDirACRend->num_protos_ambi = 1; + hDirACRend->num_protos_dir = 1; + hDirACRend->num_protos_diff = 1; } - else if ( inputType2 == IVAS_REND_AUDIO_CONFIG_TYPE_MASA ) + else if ( nchan_transport == 2 ) { - inMeta2 = hIvasRend->inputsMasa->hMasaPrerend->hMasaOut; - inEne2 = &( hIvasRend->inputsMasa->hMasaPrerend->energy ); + if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) + { + hDirACRend->num_protos_ambi = 2; + hDirACRend->num_protos_diff = 1; + hDirACRend->num_protos_dir = 2; + hDirACRend->proto_index_dir[1] = 1; + } + else if ( hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_MONO ) + { + /* Following the foa rendering for code compatibility */ + hDirACRend->num_protos_ambi = 2; + hDirACRend->num_protos_dir = 2; + hDirACRend->num_protos_diff = 3; + hDirACRend->proto_index_dir[0] = 0; + hDirACRend->proto_index_diff[0] = 0; + } + else + { + hDirACRend->num_protos_ambi = 2; + hDirACRend->num_protos_diff = 3; + + for ( k = 0; k < hDirACRend->num_outputs_diff; k++ ) + { + if ( ls_azimuth[k] > 0.0f ) + { + hDirACRend->proto_index_diff[k] = 1; + } + else if ( ls_azimuth[k] < 0.0f ) + { + hDirACRend->proto_index_diff[k] = 2; + } + else + { + hDirACRend->proto_index_diff[k] = 0; + } + } + + if ( hDirACRend->hOutSetup.is_loudspeaker_setup ) + { + hDirACRend->num_protos_dir = 3; + mvs2s( hDirACRend->proto_index_diff, hDirACRend->proto_index_dir, nchan_out_woLFE ); + } + else + { + hDirACRend->num_protos_dir = 2; + hDirACRend->proto_index_dir[1] = 1; + } + } + } + + /* direct/diffuse responses */ + if ( ( hDirACRend->diffuse_response_function = (float *) malloc( sizeof( float ) * hDirACRend->num_outputs_dir ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) ); + } + + if ( ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_LS ) || ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD ) || ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO ) ) + { + initDiffuseResponses( hDirACRend->diffuse_response_function, nchan_out_woLFE, hDirACRend->hOutSetup.output_config, + hDirACRend->hOutSetup, hDirACRend->hOutSetup.ambisonics_order, MASA_FORMAT, &hDirACRend->num_ele_spk_no_diffuse_rendering, IVAS_AUDIO_CONFIG_INVALID ); } else { - return IVAS_ERR_NOT_SUPPORTED_OPTION; + initDiffuseResponses( hDirACRend->diffuse_response_function, hDirACRend->num_outputs_dir, IVAS_AUDIO_CONFIG_FOA, + hDirACRend->hOutSetup, hDirACRend->hOutSetup.ambisonics_order, MASA_FORMAT, &hDirACRend->num_ele_spk_no_diffuse_rendering, IVAS_AUDIO_CONFIG_INVALID ); } - /* Merge metadata */ - ivas_prerend_merge_masa_metadata( *hMasaExtOutMeta, *hMasaExtOutMeta, inputType1, *inEne1, inMeta2, inputType2, *inEne2 ); - ( *hMasaExtOutMeta )->descriptiveMeta.numberOfChannels = hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_MASA1 ? 0u : 1u; + hDirACRend->hoa_encoder = NULL; + if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD ) + { + if ( ( hDirACRend->hoa_encoder = (float *) malloc( nchan_out_woLFE * hDirACRend->num_outputs_diff * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) ); + } - return IVAS_ERR_OK; -} + set_f( hDirACRend->hoa_encoder, 0.0f, nchan_out_woLFE * hDirACRend->num_outputs_diff ); + compute_hoa_encoder_mtx( ls_azimuth, ls_elevation, hDirACRend->hoa_encoder, hDirACRend->num_outputs_diff, hDirACRend->hOutSetup.ambisonics_order ); + } + /* VBAP */ + inputMasa->hMasaExtRend->hVBAPdata = NULL; -/*---------------------------------------------------------------------* - * IVAS_REND_SetTotalNumberOfObjects( ) - * - * Set the total number of objects to the first object data - *---------------------------------------------------------------------*/ + if ( hDirACRend->panningConf == DIRAC_PANNING_VBAP ) + { + if ( ( error = vbap_init_data( &( inputMasa->hMasaExtRend->hVBAPdata ), ls_azimuth, ls_elevation, nchan_out_woLFE, MASA_FORMAT ) ) != IVAS_ERR_OK ) + { + return error; + } + } -ivas_error IVAS_REND_SetTotalNumberOfObjects( - IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ - const uint16_t total_num_objects /* i : total number of objects */ -) -{ - if ( hIvasRend == NULL ) + /* HOA panning/dec */ + hDirACRend->hoa_decoder = NULL; + if ( hDirACRend->panningConf == DIRAC_PANNING_HOA3 ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + if ( hDirACRend->hOutSetup.is_loudspeaker_setup ) + { + if ( ( error = ivas_sba_get_hoa_dec_matrix( hDirACRend->hOutSetup, &inputMasa->hMasaExtRend->hoa_dec_mtx, hDirACRend->hOutSetup.ambisonics_order ) ) != IVAS_ERR_OK ) + { + return error; + } + + hDirACRend->hoa_decoder = inputMasa->hMasaExtRend->hoa_dec_mtx; + } } - hIvasRend->inputsIsm[0].total_num_objects = total_num_objects; + /* decorrelation */ + hDirACRend->proto_signal_decorr_on = 1; + if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO ) + { + hDirACRend->proto_signal_decorr_on = 0; + } - return IVAS_ERR_OK; -} + if ( hDirACRend->proto_signal_decorr_on ) + { + if ( ( error = ivas_dirac_dec_decorr_open( &( hDirACRend->h_freq_domain_decorr_ap_params ), + &( hDirACRend->h_freq_domain_decorr_ap_state ), + hSpatParamRendCom->num_freq_bands, + hDirACRend->num_outputs_diff, + hDirACRend->num_protos_diff, + hDirACRend->synthesisConf, + hDirACRend->frequency_axis, + nchan_transport, + output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + /* output synthesis */ + if ( ( ivas_dirac_dec_output_synthesis_open( hSpatParamRendCom, hDirACRend, RENDERER_DIRAC, nchan_transport, output_Fs, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + hDirACRend->h_output_synthesis_psd_params.use_onset_filters = hDirACRend->proto_signal_decorr_on; + + if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD || hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) + { + hDirACRend->h_output_synthesis_psd_params.use_onset_filters = 0; + } + + /*-----------------------------------------------------------------* + * memory allocation + *-----------------------------------------------------------------*/ + + if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) + { + hDirACRend->proto_frame_f = NULL; + } + else + { + if ( ( hDirACRend->proto_frame_f = (float *) malloc( sizeof( float ) * 2 * hDirACRend->num_protos_diff * hSpatParamRendCom->num_freq_bands ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) ); + } + } -/*---------------------------------------------------------------------* - * IVAS_REND_SetIsmMetadataDelay( ) - * - * Set the Metadata Delay in ms in order to sync with audio delay - *---------------------------------------------------------------------*/ -ivas_error IVAS_REND_SetIsmMetadataDelay( - IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ - const float sync_md_delay /* i : ISM Metadata Delay in ms to sync with audio delay */ -) -{ - int16_t i; + hDirACRend->buffer_energy = NULL; - if ( hIvasRend == NULL ) + for ( i = 0; i < DIRAC_NUM_DIMS; i++ ) { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; + for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ ) + { + hDirACRend->buffer_intensity_real[i][j] = NULL; + } } - for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) + /* output synthesis */ + ivas_dirac_dec_output_synthesis_init( hSpatParamRendCom, hDirACRend, nchan_out_woLFE, 0 ); + + /* Allocate stack memory */ + if ( ( error = ivas_dirac_alloc_mem( hDirACRend, RENDERER_DIRAC, hSpatParamRendCom->num_freq_bands, &( hDirACRend->stack_mem ), 0 ) ) != IVAS_ERR_OK ) { - hIvasRend->inputsIsm[i].ism_metadata_delay_ms = sync_md_delay; + return error; } - return IVAS_ERR_OK; -} - + inputMasa->hMasaExtRend->hDirACRend = hDirACRend; -/*-------------------------------------------------------------------* - * getSamplesInternal() - * - * - *-------------------------------------------------------------------*/ + return error; +} -static ivas_error getSamplesInternal( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ +static ivas_error ivas_masa_ext_rend_parambin_init( + input_masa *inputMasa /* i/o: MASA external renderer structure */ ) { + DIRAC_DEC_BIN_HANDLE hDiracDecBin; + HRTFS_PARAMBIN_HANDLE hHrtfParambin; + int16_t nBins; + int32_t output_Fs; + RENDERER_TYPE renderer_type; + int16_t j, k, bin; + float binCenterFreq, tmpFloat; ivas_error error; - int16_t numOutChannels; - - /* Validate function arguments */ - if ( hIvasRend == NULL || outAudio.data == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + float frequency_axis[CLDFB_NO_CHANNELS_MAX]; - if ( outAudio.config.numSamplesPerChannel <= 0 || MAX_BUFFER_LENGTH_PER_CHANNEL < outAudio.config.numSamplesPerChannel ) - { - return IVAS_ERR_INVALID_BUFFER_SIZE; - } + error = IVAS_ERR_OK; - if ( outAudio.config.numChannels <= 0 || MAX_OUTPUT_CHANNELS < outAudio.config.numChannels ) - { - return IVAS_ERR_WRONG_NUM_CHANNELS; - } + hHrtfParambin = inputMasa->hMasaExtRend->hHrtfParambin; - if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL && - outAudio.config.numSamplesPerChannel * 1000 != ( hIvasRend->num_subframes * BINAURAL_RENDERING_FRAME_SIZE_MS ) * hIvasRend->sampleRateOut ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" ); - } + /* Set common variables and defaults */ + output_Fs = *( inputMasa->base.ctx.pOutSampleRate ); + nBins = inputMasa->hMasaExtRend->hSpatParamRendCom->num_freq_bands; + renderer_type = inputMasa->hMasaExtRend->renderer_type; - /* Check that there is allowed configuration for MASA format output */ - if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_MASA ) - { - int16_t i; - int16_t numMasaInputs = 0; - int16_t numOtherInputs = 0; + hDiracDecBin = inputMasa->hMasaExtRend->hDiracDecBin; - for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; i++ ) + /* Init assumes that no reconfiguration is required in external renderer. Instead, free and rebuild whole rendering. */ + if ( ( hDiracDecBin = (DIRAC_DEC_BIN_HANDLE) malloc( sizeof( DIRAC_DEC_BIN_DATA ) ) ) == NULL ) { - numMasaInputs += hIvasRend->inputsMasa[i].base.inConfig == IVAS_AUDIO_CONFIG_INVALID ? 0 : 1; + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC binaural handle " ); } - for ( i = 0; i < RENDERER_MAX_MC_INPUTS; i++ ) + hDiracDecBin->hTdDecorr = NULL; + hDiracDecBin->hReverb = NULL; + hDiracDecBin->h_freq_domain_decorr_ap_params = NULL; + hDiracDecBin->h_freq_domain_decorr_ap_state = NULL; + hDiracDecBin->hDiffuseDist = NULL; /* Not used in external renderer */ + hDiracDecBin->useTdDecorr = 0; /* Always use frequency domain decorrelator in external renderer */ + + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) { - numOtherInputs += hIvasRend->inputsMc[i].base.inConfig == IVAS_AUDIO_CONFIG_INVALID ? 0 : 1; + for ( k = 0; k < BINAURAL_CHANNELS + MAX_NUM_OBJECTS; k++ ) + { + set_zero( hDiracDecBin->processMtxRe[j][k], nBins ); + set_zero( hDiracDecBin->processMtxIm[j][k], nBins ); + } + + for ( k = 0; k < BINAURAL_CHANNELS; k++ ) + { + set_zero( hDiracDecBin->processMtxDecRe[j][k], nBins ); + set_zero( hDiracDecBin->processMtxDecIm[j][k], nBins ); + } + set_zero( hDiracDecBin->ChEnePrev[j], nBins ); + set_zero( hDiracDecBin->ChEneOutPrev[j], nBins ); } + set_zero( hDiracDecBin->ChCrossRePrev, nBins ); + set_zero( hDiracDecBin->ChCrossImPrev, nBins ); + set_zero( hDiracDecBin->ChCrossReOutPrev, nBins ); + set_zero( hDiracDecBin->ChCrossImOutPrev, nBins ); + hDiracDecBin->renderStereoOutputInsteadOfBinaural = 0; - for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; i++ ) + for ( bin = 0; bin < nBins; bin++ ) { - numOtherInputs += hIvasRend->inputsSba[i].base.inConfig == IVAS_AUDIO_CONFIG_INVALID ? 0 : 1; + binCenterFreq = ( (float) bin + 0.5f ) / (float) nBins * ( (float) output_Fs / 2.0f ); + /* These formulas and values are from Christian Borss's publication for binaural diffuse field coherence */ + tmpFloat = max( 0.0f, 1.0f - binCenterFreq / 2700.0f ); + hDiracDecBin->diffuseFieldCoherence[bin] = tmpFloat * sinf( binCenterFreq * EVS_PI / 550.0f ) / ( binCenterFreq * EVS_PI / 550.0f ); } - /* For ISM, we check only first as all ISMs are handled together via OMASA when merging to MASA. */ - numOtherInputs += hIvasRend->inputsIsm[0].base.inConfig == IVAS_AUDIO_CONFIG_INVALID ? 0 : 1; + /* No SPAR in external renderer so set directive diffuse field coherence tables to zero */ + set_zero( hDiracDecBin->diffuseFieldCoherenceX, BINAURAL_COHERENCE_DIFFERENCE_BINS ); + set_zero( hDiracDecBin->diffuseFieldCoherenceY, BINAURAL_COHERENCE_DIFFERENCE_BINS ); + set_zero( hDiracDecBin->diffuseFieldCoherenceZ, BINAURAL_COHERENCE_DIFFERENCE_BINS ); - if ( numMasaInputs == 0 || numOtherInputs == 0 ) + if ( renderer_type == RENDERER_BINAURAL_PARAMETRIC ) /* Indication of binaural rendering without room effect */ { - return IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED; + set_f( hDiracDecBin->earlyPartEneCorrection, 1.0f, CLDFB_NO_CHANNELS_MAX ); + hDiracDecBin->hReverb = NULL; } - } + else if ( renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) /* Indication of binaural rendering with room effect */ + { + mvr2r( hHrtfParambin->parametricEarlyPartEneCorrection, hDiracDecBin->earlyPartEneCorrection, nBins ); - if ( ( error = IVAS_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) - { - return error; - } + if ( hDiracDecBin->hReverb == NULL ) + { + /* Todo Philips: Room acoustics should be passed here once the underlying part works. In this case, it probably should come from render context or somewhere else suitable. */ + if ( ( error = ivas_binaural_reverb_open_parambin( &hDiracDecBin->hReverb, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, NULL, output_Fs, hHrtfParambin ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + else if ( renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + set_f( hDiracDecBin->earlyPartEneCorrection, 1.0f, CLDFB_NO_CHANNELS_MAX ); + hDiracDecBin->hReverb = NULL; + hDiracDecBin->renderStereoOutputInsteadOfBinaural = 1; + } + else /* Not valid renderer type for this renderer */ + { + assert( false ); + } - if ( numOutChannels != outAudio.config.numChannels ) + /* Always open frequency domain decorrelator */ + ivas_dirac_dec_get_frequency_axis( frequency_axis, output_Fs, nBins ); + if ( ( error = ivas_dirac_dec_decorr_open( &( hDiracDecBin->h_freq_domain_decorr_ap_params ), + &( hDiracDecBin->h_freq_domain_decorr_ap_state ), + nBins, + BINAURAL_CHANNELS, + BINAURAL_CHANNELS, + DIRAC_SYNTHESIS_PSD_LS, + frequency_axis, + BINAURAL_CHANNELS, + output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + /* External renderer uses constant regularization factor */ + hDiracDecBin->reqularizationFactor = 0.4f; + + inputMasa->hMasaExtRend->hDiracDecBin = hDiracDecBin; + + return error; +} + +static ivas_error initMasaExtRenderer( + input_masa *inputMasa, + const AUDIO_CONFIG outConfig ) +{ + int16_t i; + ivas_error error; + MASA_EXT_REND_HANDLE hMasaExtRend; + + error = IVAS_ERR_OK; + + if ( ( hMasaExtRend = (MASA_EXT_REND_HANDLE) malloc( sizeof( MASA_EXT_REND_DATA ) ) ) == NULL ) { - return IVAS_ERR_WRONG_NUM_CHANNELS; + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA external renderer structure\n" ) ); } - /* Clear original output buffer */ - set_zero( outAudio.data, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel ); + inputMasa->hMasaExtRend = hMasaExtRend; + /* Default init */ + hMasaExtRend->renderer_type = RENDERER_DISABLE; + hMasaExtRend->hDirACRend = NULL; + hMasaExtRend->hSpatParamRendCom = NULL; + hMasaExtRend->hDiracDecBin = NULL; + hMasaExtRend->hReverb = NULL; + hMasaExtRend->hHrtfParambin = NULL; + hMasaExtRend->hVBAPdata = NULL; + hMasaExtRend->hoa_dec_mtx = NULL; - if ( ( error = renderActiveInputsIsm( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + if ( ( error = getAudioConfigNumChannels( inputMasa->base.inConfig, &hMasaExtRend->nchan_input ) ) != IVAS_ERR_OK ) { return error; } - if ( ( error = renderActiveInputsMc( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + if ( ( error = getAudioConfigNumChannels( outConfig, &hMasaExtRend->nchan_output ) ) != IVAS_ERR_OK ) { return error; } - if ( ( error = renderActiveInputsSba( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + switch ( outConfig ) { - return error; + case IVAS_AUDIO_CONFIG_MONO: + if ( inputMasa->base.inConfig == IVAS_AUDIO_CONFIG_MASA2 ) + { + hMasaExtRend->renderer_type = RENDERER_DIRAC; + } + else + { + /* 1TC MASA to mono does not need rendering. */ + hMasaExtRend->renderer_type = RENDERER_DISABLE; + } + break; + + case IVAS_AUDIO_CONFIG_STEREO: + hMasaExtRend->renderer_type = RENDERER_STEREO_PARAMETRIC; + break; + + case IVAS_AUDIO_CONFIG_5_1: + case IVAS_AUDIO_CONFIG_7_1: + case IVAS_AUDIO_CONFIG_5_1_2: + case IVAS_AUDIO_CONFIG_5_1_4: + case IVAS_AUDIO_CONFIG_7_1_4: + case IVAS_AUDIO_CONFIG_LS_CUSTOM: + case IVAS_AUDIO_CONFIG_FOA: + case IVAS_AUDIO_CONFIG_HOA2: + case IVAS_AUDIO_CONFIG_HOA3: + hMasaExtRend->renderer_type = RENDERER_DIRAC; + break; + + case IVAS_AUDIO_CONFIG_BINAURAL: + hMasaExtRend->renderer_type = RENDERER_BINAURAL_PARAMETRIC; + break; + + case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: + case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: + hMasaExtRend->renderer_type = RENDERER_BINAURAL_PARAMETRIC_ROOM; + break; + + default: + return ( IVAS_ERROR( IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED, "Wrong output config for MASA input in external renderer\n" ) ); } - if ( ( error = renderActiveInputsMasa( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + if ( hMasaExtRend->renderer_type != RENDERER_DISABLE ) { - return error; - } + int16_t subframe; + if ( ( error = ivas_spat_hSpatParamRendCom_config( &hMasaExtRend->hSpatParamRendCom, DIRAC_OPEN, 0, MASA_FORMAT, MC_MODE_NONE, *( inputMasa->base.ctx.pOutSampleRate ), 0, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } -#ifndef DISABLE_LIMITER - limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD ); -#endif + /* Simple population of the metadata index map as no adaptation is present */ + set_s( hMasaExtRend->hSpatParamRendCom->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME ); + for ( subframe = 0; subframe < MAX_PARAM_SPATIAL_SUBFRAMES; subframe++ ) + { + hMasaExtRend->hSpatParamRendCom->render_to_md_map[subframe] = subframe; + } + hMasaExtRend->hSpatParamRendCom->subframes_rendered = 0; + } + if ( hMasaExtRend->renderer_type == RENDERER_DIRAC ) + { + if ( ( error = ivas_masa_ext_rend_dirac_rend_init( inputMasa ) ) != IVAS_ERR_OK ) + { + return error; + } + } - return IVAS_ERR_OK; -} + if ( hMasaExtRend->renderer_type == RENDERER_BINAURAL_PARAMETRIC || hMasaExtRend->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || hMasaExtRend->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + if ( hMasaExtRend->renderer_type != RENDERER_STEREO_PARAMETRIC ) + { + if ( ( error = ivas_dirac_dec_binaural_copy_hrtfs( &inputMasa->hMasaExtRend->hHrtfParambin ) ) != IVAS_ERR_OK ) + { + return error; + } + } + if ( ( error = ivas_masa_ext_rend_parambin_init( inputMasa ) ) != IVAS_ERR_OK ) + { + return error; + } + } -/*-------------------------------------------------------------------* - * IVAS_REND_GetSamples() - * - * - *-------------------------------------------------------------------*/ + /* Init CLDFB for analysis & synthesis if renderer is used. Otherwise, NULL. */ + for ( i = 0; i < MASA_MAX_TRANSPORT_CHANNELS; i++ ) + { + hMasaExtRend->cldfbAnaRend[i] = NULL; + } -ivas_error IVAS_REND_GetSamples( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ -) -{ + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + hMasaExtRend->cldfbSynRend[i] = NULL; + } - return getSamplesInternal( hIvasRend, outAudio ); -} + if ( hMasaExtRend->renderer_type != RENDERER_DISABLE ) + { + for ( i = 0; i < hMasaExtRend->nchan_input; i++ ) + { + if ( ( error = openCldfb( &( hMasaExtRend->cldfbAnaRend[i] ), CLDFB_ANALYSIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + for ( i = 0; i < hMasaExtRend->nchan_output; i++ ) + { + if ( ( error = openCldfb( &( hMasaExtRend->cldfbSynRend[i] ), CLDFB_SYNTHESIS, *inputMasa->base.ctx.pOutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + inputMasa->hMasaExtRend = hMasaExtRend; + return IVAS_ERR_OK; +} -/*-------------------------------------------------------------------* - * IVAS_REND_Close() - * - * - *-------------------------------------------------------------------*/ -void IVAS_REND_Close( - IVAS_REND_HANDLE *phIvasRend /* i/o: Pointer to renderer handle */ -) +static void freeMasaExtRenderer( + MASA_EXT_REND_HANDLE *hMasaExtRendOut ) { - uint16_t i; - IVAS_REND_HANDLE hIvasRend; + MASA_EXT_REND_HANDLE hMasaExtRend; + int16_t i; - /* Validate function arguments */ - if ( phIvasRend == NULL || *phIvasRend == NULL ) + if ( hMasaExtRendOut == NULL || *hMasaExtRendOut == NULL ) { return; } - hIvasRend = *phIvasRend; - if ( hIvasRend->efapOutWrapper.hEfap != NULL ) + hMasaExtRend = *hMasaExtRendOut; + + if ( hMasaExtRend->hDirACRend != NULL ) { - efap_free_data( &hIvasRend->efapOutWrapper.hEfap ); + ivas_dirac_rend_close( &hMasaExtRend->hDirACRend ); } - /* clear inputs */ - for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) + if ( hMasaExtRend->hSpatParamRendCom != NULL ) { - clearInputIsm( &hIvasRend->inputsIsm[i] ); + ivas_spat_hSpatParamRendCom_close( &hMasaExtRend->hSpatParamRendCom ); } - for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) + + if ( hMasaExtRend->hDiracDecBin != NULL ) { - clearInputMc( &hIvasRend->inputsMc[i] ); + ivas_dirac_dec_close_binaural_data( &hMasaExtRend->hDiracDecBin ); } - for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) + + if ( hMasaExtRend->hReverb != NULL ) { - clearInputSba( &hIvasRend->inputsSba[i] ); + ivas_binaural_reverb_close( &hMasaExtRend->hReverb ); } - for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) + + if ( hMasaExtRend->hHrtfParambin != NULL ) { - clearInputMasa( &hIvasRend->inputsMasa[i] ); + ivas_HRTF_parambin_binary_close( &hMasaExtRend->hHrtfParambin ); } - /* clear Config. Renderer */ - ivas_render_config_close( &( hIvasRend->hRendererConfig ) ); - - ivas_limiter_close( &hIvasRend->hLimiter ); + if ( hMasaExtRend->hVBAPdata != NULL ) + { + vbap_free_data( &hMasaExtRend->hVBAPdata ); + } + if ( hMasaExtRend->hoa_dec_mtx != NULL ) + { + free( hMasaExtRend->hoa_dec_mtx ); + } - closeHeadRotation( hIvasRend ); + for ( i = 0; i < MASA_MAX_TRANSPORT_CHANNELS; i++ ) + { + if ( hMasaExtRend->cldfbAnaRend[i] != NULL ) + { + deleteCldfb( &hMasaExtRend->cldfbAnaRend[i] ); + } + } - ivas_external_orientation_close( &hIvasRend->hExternalOrientationData ); - ivas_combined_orientation_close( &hIvasRend->hCombinedOrientationData ); + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + if ( hMasaExtRend->cldfbSynRend[i] != NULL ) + { + deleteCldfb( &hMasaExtRend->cldfbSynRend[i] ); + } + } - free( hIvasRend ); - *phIvasRend = NULL; + free( hMasaExtRend ); + *hMasaExtRendOut = NULL; return; } - - - - diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index b76493b72..b8bc3a8a8 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -40,17 +40,18 @@ * Renderer constants *---------------------------------------------------------------------*/ -#define RENDERER_MAX_ISM_INPUTS 4 -#define RENDERER_MAX_MC_INPUTS 1 -#define RENDERER_MAX_SBA_INPUTS 1 -#define RENDERER_MAX_MASA_INPUTS 1 +#define RENDERER_MAX_ISM_INPUTS 4 +#define RENDERER_MAX_MC_INPUTS 1 +#define RENDERER_MAX_SBA_INPUTS 1 +#define RENDERER_MAX_MASA_INPUTS 1 +#define RENDERER_MAX_INPUT_LFE_CHANNELS 4 /*---------------------------------------------------------------------* * Renderer structures *---------------------------------------------------------------------*/ -typedef float IVAS_REND_LfePanMtx[IVAS_MAX_INPUT_LFE_CHANNELS][IVAS_MAX_OUTPUT_CHANNELS]; +typedef float IVAS_REND_LfePanMtx[RENDERER_MAX_INPUT_LFE_CHANNELS][IVAS_MAX_OUTPUT_CHANNELS]; typedef struct { diff --git a/lib_util/masa_file_writer.c b/lib_util/masa_file_writer.c index 8b063fe28..171eb4a2e 100644 --- a/lib_util/masa_file_writer.c +++ b/lib_util/masa_file_writer.c @@ -66,20 +66,21 @@ struct MasaFileWriter *-----------------------------------------------------------------------*/ static void getExtMasaMetadataFileName( - const char *outputWavFilename, /* i : name of the output audio file */ - char metadata_filename[IVAS_MAX_NUM_OBJECTS][FILENAME_MAX - 12] /* o : name of the output masa metadata file */ + const char *outputWavFilename, /* i : name of the output audio file */ + char *metadata_filename, /* o : name of the output MASA metadata file */ + int32_t max_name_len /* i : size of metadata_filename in chars */ ) { char ext_meta[5]; /* sizeof( ext_meta ) accounts for terminating NULL, don't subtract extra 1 */ - const int32_t maxNameLenWithoutExt = sizeof( metadata_filename[0] ) - sizeof( ext_meta ); - strncpy( metadata_filename[0], outputWavFilename, maxNameLenWithoutExt ); + const int32_t maxNameLenWithoutExt = max_name_len - (int32_t) sizeof( ext_meta ); + strncpy( metadata_filename, outputWavFilename, maxNameLenWithoutExt ); snprintf( ext_meta, sizeof( ext_meta ), ".met" ); /* strlen( metadata_filename[0] ) doesn't account for terminating NULL, subtract extra 1 */ - const int32_t maxNumCharactersToAppend = (int32_t) ( sizeof( metadata_filename[0] ) - strlen( metadata_filename[0] ) - 1 ); - strncat( metadata_filename[0], ext_meta, maxNumCharactersToAppend ); + const int32_t maxNumCharactersToAppend = max_name_len - (int32_t) strlen( metadata_filename ) - 1; + strncat( metadata_filename, ext_meta, maxNumCharactersToAppend ); return; } @@ -164,7 +165,7 @@ ivas_error MasaFileWriter_open( return IVAS_ERR_FAILED_FILE_OPEN; } - getExtMasaMetadataFileName( outputWavFilename, &filePath ); + getExtMasaMetadataFileName( outputWavFilename, filePath, FILENAME_MAX - 12 ); file = fopen( filePath, "wb" ); diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 99873dcd2..9661dcdf2 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -64,6 +64,11 @@ #define INPUTPREDELAY_MIN ( 0.0f ) #define INPUTPREDELAY_MAX ( 1.0e+2f ) +#define ER_MIN_ROOM_DIMENSION ( 1.0f ) +#define ER_MAX_ROOM_DIMENSION ( 999.0f ) +#define ER_MIN_ABS_COEFF ( 0.0f ) +#define ER_MAX_ABS_COEFF ( 1.0f ) + /*------------------------------------------------------------------------------------------* * Local Type definitions *------------------------------------------------------------------------------------------*/ @@ -1206,7 +1211,7 @@ ivas_error RenderConfigReader_checkValues( } /* Abs Coeff */ - for ( wall_idx = 0; wall_idx < ER_ABS_COEFF; wall_idx++ ) + for ( wall_idx = 0; wall_idx < IVAS_ROOM_ABS_COEFF; wall_idx++ ) { if ( pRoom_acoustics->AbsCoeff[wall_idx] < ER_MIN_ABS_COEFF ) { diff --git a/readme.txt b/readme.txt index 58efed4bb..e39174163 100644 --- a/readme.txt +++ b/readme.txt @@ -224,7 +224,7 @@ EVS mono is default, for IVAS choose one of the following: -stereo, -ism, -sba, -mime : Mime output bitstream file format The encoder produces TS26.445 Annex.2.6 Mime Storage Format, (not RFC4867 Mime Format). default output bitstream file format is G.192 --bypass mode : SBA PCA by-pass, mode = (1, 2), 1 = PCA off, 2 = signal adaptive, default is 1 +-pca : activate PCA in SBA format FOA at 256 kbps -level level : Complexity level, level = (1, 2, 3), will be defined after characterisation. Currently, all values default to level 3 (full functionality). -q : Quiet mode, limit printouts to terminal, default is deactivated @@ -257,7 +257,6 @@ Options: EVS RTP Payload Format. The SDP parameter hf_only is required. Reading RFC4867 AMR/AMR-WB RTP payload format is not supported. -Tracefile TF : VoIP mode: Generate trace file named TF --fr5 : option to perform rendering + head-tracking with 5ms frame size -fec_cfg_file : Optimal channel aware configuration computed by the JBM as described in Section 6.3.1 of TS26.448. The output is written into a .txt file. Each line contains the FER indicator @@ -268,6 +267,7 @@ Options: Format files, the magic word in the mime file is used to determine which of the two supported formats is in use. default bitstream file format is G.192 +-fr L : render frame size in ms L=(5,10,20), default is 20 -hrtf File : HRTF filter File used in BINAURAL rendering -T File : Head rotation specified by external trajectory File -otr tracking_type : Head orientation tracking type: 'none', 'ref', 'avg', 'ref_vec' @@ -276,8 +276,7 @@ Options: works only in combination with '-otr ref' mode -rvf File : Reference vector specified by external trajectory File works only in combination with '-otr ref_vec' and 'ref_vec_lev' modes --render_config File : Renderer configuration option with parameters specified in File --om File : Metadata output File for BINAURAL_SPLIT_PCM OutputConf +-render_config File : Binaural renderer configuration parameters in File (only for binaural outputs) -non_diegetic_pan P : panning mono non-diegetic sound to stereo -90<= P <=90, left or l or 90->left, right or r or -90->right, center or c or 0->middle -exof File : External orientation trajectory File for simulation of external orientations @@ -303,28 +302,28 @@ Options: -of Format : Audio Format of output file Alternatively, it can be a custom loudspeaker layout File -fs : Input sampling rate in kHz (16, 32, 48) - required only with raw PCM inputs --tf File : Head rotation trajectory File for simulation of head tracking (only for binaural outputs) +-fr L : render frame size in ms L=(5,10,20), default is 20 +-hrtf File : Custom HRTF File for binaural rendering (only for binaural outputs) +-T File : Head rotation trajectory File for simulation of head tracking (only for binaural outputs) +-otr tracking_type : Head orientation tracking type: 'none', 'ref', 'avg' or `ref_vec` or `ref_vec_lev` (only for binaural outputs) -rf File : Reference rotation trajectory File for simulation of head tracking (only for binaural outputs) -rvf File : Reference vector trajectory File for simulation of head tracking (only for binaural outputs) --hrtf File : Custom HRTF File for binaural rendering (only for binaural outputs) --rc File : Binaural renderer configuration File (only for binaural outputs) --ndp P : Panning mono non-diegetic sound to stereo -90<= P <= 90 +-render_config File : Binaural renderer configuration parameters in File (only for binaural outputs) +-non_diegetic_pan P : Panning mono non-diegetic sound to stereo -90<= P <= 90 left or l or 90->left, right or r or -90->right, center or c or 0 ->middle --otr tracking_type : Head orientation tracking type: 'none', 'ref', 'avg' or `ref_vec` or `ref_vec_lev` (only for binaural outputs) +-exof File : External orientation trajectory File for simulation of external orientations +-dpid ID : Directivity pattern ID(s) (space-separated list of up to 4 numbers can be + specified) for binaural output configuration +-aeid ID : Acoustic environment ID (number >= 0) for BINAURAL_ROOM_REVERB output config. -lp Position : Output LFE position. Comma-delimited triplet of [gain, azimuth, elevation] where gain is linear (like --gain, -g) and azimuth, elevation are in degrees. If specified, overrides the default behavior which attempts to map input to output LFE channel(s) -lm File : LFE panning matrix File (CSV table) containing a matrix of dimensions [ num_input_lfe x num_output_channels ] with elements specifying linear routing gain (like --gain, -g). If specified, overrides the output LFE position option and the default behavior which attempts to map input to output LFE channel(s) --ndc : Turn off delay compensation +-no_delay_cmp : Turn off delay compensation -g : Input gain (linear, not in dB) to be applied to input audio file -l : List supported audio formats --exof File : External orientation trajectory File for simulation of external orientations --dpid ID : Directivity pattern ID(s) (space-separated list of up to 4 numbers can be - specified) for binaural output configuration --aeid ID : Acoustic environment ID (number >= 0) for BINAURAL_ROOM_REVERB output config. --fr5 : render audio with 5 ms framing -smd : Metadata Synchronization Delay in ms, Default is 0. Quantized by 5ms subframes. -level level : Complexity level, level = (1, 2, 3), will be defined after characterisation. Currently, all values default to level 3 (full functionality). -- GitLab From 4c4f45bbb06af0f15a72436ae49d58eb17687a32 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Thu, 30 Nov 2023 15:29:15 +0100 Subject: [PATCH 2/4] Merge fixes --- Makefile | 9 +- lib_com/basop_util.c | 1 - lib_com/cnst.h | 1 + lib_debug/wmc_auto.c | 490 +++++++++++-------------------------------- lib_debug/wmc_auto.h | 423 +------------------------------------ lib_util/test_fft.c | 2 + 6 files changed, 146 insertions(+), 780 deletions(-) diff --git a/Makefile b/Makefile index bef5db441..b148e1a50 100644 --- a/Makefile +++ b/Makefile @@ -116,6 +116,9 @@ CFLAGS += $(foreach DIR,$(SRC_DIRS),-I$(DIR)) # Source file search paths VPATH = $(SRC_DIRS) +# Filter out files that are not part of the build +EXCLUDED_FILES = SNR_calc_fx.c + ############################################################################### SRCS_LIBCOM = $(foreach DIR,$(SRC_LIBCOM),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) @@ -125,6 +128,8 @@ SRCS_LIBENC = $(foreach DIR,$(SRC_LIBENC),$(patsubst $(DIR)/%,%,$(wildcard $(D SRCS_LIBREND = $(foreach DIR,$(SRC_LIBREND),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) SRCS_LIBUTIL = $(foreach DIR,$(SRC_LIBUTIL),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) +SRCS_LIBENC := $(filter-out $(EXCLUDED_FILES),$(SRCS_LIBENC)) + OBJS_LIBCOM = $(addprefix $(OBJDIR)/,$(SRCS_LIBCOM:.c=.o)) OBJS_LIBDEBUG = $(addprefix $(OBJDIR)/,$(SRCS_LIBDEBUG:.c=.o)) OBJS_LIBDEC = $(addprefix $(OBJDIR)/,$(SRCS_LIBDEC:.c=.o)) @@ -161,8 +166,8 @@ $(LIB_LIBENC): $(OBJS_LIBENC) $(LIB_LIBREND): $(OBJS_LIBREND) $(QUIET_AR)$(AR) rcs $@ $^ - -$(LIB_LIBUTIL): $(OBJS_LIBUTIL) +# Dependency on OBJS_LIBCOM added temporarily for unit-test to work +$(LIB_LIBUTIL): $(OBJS_LIBUTIL) $(OBJS_LIBCOM) $(QUIET_AR)$(AR) rcs $@ $^ $(CLI_APIENC): $(OBJS_CLI_APIENC) $(LIB_LIBENC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index 02fe14e5b..2061de6a3 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -42,7 +42,6 @@ #include "rom_com.h" #include "rom_basic_math.h" #include "basop_settings.h" -#include "basop_mpy.h" #include "control.h" #include "cnst.h" diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 26238754a..5933e0418 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -39,6 +39,7 @@ #include #include "options.h" +#include "stl.h" /* clang-format off */ diff --git a/lib_debug/wmc_auto.c b/lib_debug/wmc_auto.c index 0ff7786f0..029640a1d 100644 --- a/lib_debug/wmc_auto.c +++ b/lib_debug/wmc_auto.c @@ -28,6 +28,7 @@ #include "options.h" #include "wmc_auto.h" + #define WMC_TOOL_SKIP /* Skip the instrumentation of this file, if invoked by accident */ #ifdef WMOPS @@ -36,26 +37,23 @@ * Complexity counting tool *--------------------------------------------------------------------*/ -#define MAX_FUNCTION_NAME_LENGTH 50 /* Maximum length of the function name */ -#define MAX_PARAMS_LENGTH 50 /* Maximum length of the function parameter string */ -#define MAX_NUM_RECORDS 300 /* Initial maximum number of records -> mightb be increased during runtime, if needed */ -#define MAX_NUM_RECORDS_REALLOC_STEP 50 /* When re-allocating the list of records, increase the number of records by this number */ -#define MAX_CALL_TREE_DEPTH 100 /* maximum depth of the function call tree */ -#define DOUBLE_MAX 0x80000000 +#define MAX_RECORDS 1024 +#define MAX_CHAR 64 +#define MAX_STACK 64 +#define DOUBLE_MAX 0x80000000 -typedef struct +struct wmops_record { - char label[MAX_FUNCTION_NAME_LENGTH]; + char label[MAX_CHAR]; long call_number; long update_cnt; - int call_tree[MAX_CALL_TREE_DEPTH]; - long LastWOper; + int call_tree[MAX_RECORDS]; double start_selfcnt; double current_selfcnt; double max_selfcnt; double min_selfcnt; double tot_selfcnt; - double start_cnt; + double start_cnt; /* The following take into account the decendants */ double current_cnt; double max_cnt; double min_cnt; @@ -66,14 +64,16 @@ typedef struct double wc_selfcnt; int32_t wc_call_number; #endif -} wmops_record; +}; double ops_cnt; double prom_cnt; double inst_cnt[NUM_INST]; -static wmops_record *wmops = NULL; -static int num_wmops_records, max_num_wmops_records; +static struct wmops_record wmops[MAX_RECORDS]; +static int stack[MAX_STACK]; +static int sptr; +static int num_records; static int current_record; static long update_cnt; static double start_cnt; @@ -81,56 +81,20 @@ static double max_cnt; static double min_cnt; static double inst_cnt_wc[NUM_INST]; static long fnum_cnt_wc; -static int *wmops_caller_stack = NULL, wmops_caller_stack_index, max_wmops_caller_stack_index = 0; + static int *heap_allocation_call_tree = NULL, heap_allocation_call_tree_size = 0, heap_allocation_call_tree_max_size = 0; + void reset_wmops( void ) { int i, j; - unsigned int *ptr; - - num_wmops_records = 0; - max_num_wmops_records = MAX_NUM_RECORDS; - current_record = -1; - update_cnt = 0; - - max_cnt = 0.0; - min_cnt = DOUBLE_MAX; - start_cnt = 0.0; - ops_cnt = 0.0; - - /* allocate the list of wmops records */ - if ( wmops == NULL ) - { - wmops = (wmops_record *)malloc( max_num_wmops_records * sizeof( wmops_record ) ); - } - - if ( wmops == NULL ) - { - fprintf( stderr, "Error: Unable to Allocate List of WMOPS Records!" ); - exit( -1 ); - } - - /* allocate the BASOP WMOPS counter */ - if ( multiCounter == NULL ) - { - multiCounter = (BASIC_OP *) malloc( max_num_wmops_records * sizeof( BASIC_OP ) ); - } - if ( multiCounter == NULL ) - { - fprintf( stderr, "Error: Unable to Allocate the BASOP WMOPS counter!" ); - exit( -1 ); - } - - /* initilize the list of wmops records */ - /* initilize the BASOP WMOPS counters */ - for ( i = 0; i < max_num_wmops_records; i++ ) + for ( i = 0; i < MAX_RECORDS; i++ ) { strcpy( &wmops[i].label[0], "\0" ); wmops[i].call_number = 0; wmops[i].update_cnt = 0; - for ( j = 0; j < MAX_CALL_TREE_DEPTH; j++ ) + for ( j = 0; j < MAX_RECORDS; j++ ) { wmops[i].call_tree[j] = -1; } @@ -148,42 +112,22 @@ void reset_wmops( void ) wmops[i].wc_cnt = 0.0; wmops[i].wc_selfcnt = 0.0; wmops[i].current_call_number = 0; - wmops[i].wc_call_number = -1; #endif - - /* clear all BASOP operation counters */ - ptr = (unsigned int*) &multiCounter[i]; - for ( j = 0; j < (int) ( sizeof(BASIC_OP ) / sizeof( unsigned int ) ); j++ ) - { - *ptr++ = 0; - } - wmops[i].LastWOper = 0; } - /* allocate the list of wmops callers to track the sequence of function calls */ - wmops_caller_stack_index = 0; - max_wmops_caller_stack_index = MAX_NUM_RECORDS; - if ( wmops_caller_stack == NULL ) + for ( i = 0; i < MAX_STACK; i++ ) { - wmops_caller_stack = malloc( max_wmops_caller_stack_index * sizeof( int ) ); - } - - if ( wmops_caller_stack == NULL ) - { - fprintf( stderr, "Error: Unable to Allocate List of WMOPS Callers!" ); - exit( -1 ); + stack[i] = -1; } + sptr = 0; + num_records = 0; + current_record = -1; + update_cnt = 0; - for ( i = 0; i < max_wmops_caller_stack_index; i++ ) - { - wmops_caller_stack[i] = -1; - } - - /* initialize auxiliary BASOP WMOPS variables */ - call_occurred = 1; - funcId_where_last_call_to_else_occurred = INT_MAX; - - return; + max_cnt = 0.0; + min_cnt = DOUBLE_MAX; + start_cnt = 0.0; + ops_cnt = 0.0; } @@ -192,9 +136,9 @@ void push_wmops( const char *label ) int new_flag; int i, j; - /* Check, if this is a new function label */ + /* Check if new function record label */ new_flag = 1; - for ( i = 0; i < num_wmops_records; i++ ) + for ( i = 0; i < num_records; i++ ) { if ( strcmp( wmops[i].label, label ) == 0 ) { @@ -203,38 +147,33 @@ void push_wmops( const char *label ) } } - /* Create a new record in the list */ + /* Configure new record */ if ( new_flag ) { - if ( num_wmops_records >= max_num_wmops_records ) + if ( num_records >= MAX_RECORDS ) { - /* There is no room for a new wmops record -> reallocate the list */ - max_num_wmops_records += MAX_NUM_RECORDS_REALLOC_STEP; - wmops = realloc( wmops, max_num_wmops_records * sizeof( wmops_record ) ); - multiCounter = realloc( multiCounter, max_num_wmops_records * sizeof( BASIC_OP ) ); + fprintf( stdout, "push_wmops(): exceeded MAX_RECORDS count.\n\n" ); + exit( -1 ); } - strcpy( wmops[i].label, label ); - - num_wmops_records++; + num_records++; } - /* Push the current context info to the new record */ + /* Push current context onto stack */ if ( current_record >= 0 ) { - if ( wmops_caller_stack_index >= max_wmops_caller_stack_index ) + if ( sptr >= MAX_STACK ) { - /* There is no room for a new record -> reallocate the list */ - max_wmops_caller_stack_index += MAX_NUM_RECORDS_REALLOC_STEP; - wmops_caller_stack = realloc( wmops_caller_stack, max_wmops_caller_stack_index * sizeof( int ) ); + fprintf( stdout, "\r push_wmops(): stack exceeded, try inreasing MAX_STACK\n" ); + exit( -1 ); } - wmops_caller_stack[wmops_caller_stack_index++] = current_record; + stack[sptr++] = current_record; /* accumulate op counts */ wmops[current_record].current_selfcnt += ops_cnt - wmops[current_record].start_selfcnt; /* update call tree */ - for ( j = 0; j < MAX_CALL_TREE_DEPTH; j++ ) + for ( j = 0; j < MAX_RECORDS; j++ ) { if ( wmops[i].call_tree[j] == current_record ) { @@ -248,7 +187,7 @@ void push_wmops( const char *label ) } } - /* update the current context info */ + /* init current record */ current_record = i; wmops[current_record].start_selfcnt = ops_cnt; wmops[current_record].start_cnt = ops_cnt; @@ -257,16 +196,12 @@ void push_wmops( const char *label ) wmops[current_record].current_call_number++; #endif - /* set the ID of BASOP functions counters */ - Set_BASOP_WMOPS_counter( current_record ); - return; } void pop_wmops( void ) { - long tot; /* Check for underflow */ if ( current_record < 0 ) @@ -275,29 +210,21 @@ void pop_wmops( void ) exit( -1 ); } - /* add the BASOP complexity to the counter */ - tot = DeltaWeightedOperation(); - ops_cnt += tot; - - /* update count of current record */ + /* update count of current record */ wmops[current_record].current_selfcnt += ops_cnt - wmops[current_record].start_selfcnt; wmops[current_record].current_cnt += ops_cnt - wmops[current_record].start_cnt; /* Get back previous context from stack */ - if ( wmops_caller_stack_index > 0 ) + if ( sptr > 0 ) { - current_record = wmops_caller_stack[--wmops_caller_stack_index]; + current_record = stack[--sptr]; wmops[current_record].start_selfcnt = ops_cnt; - - /* set the ID of the previous BASOP counter */ - Set_BASOP_WMOPS_counter( current_record ); } else { current_record = -1; } - return; } @@ -312,9 +239,9 @@ void update_wmops( void ) float tmpF; #endif - if ( wmops_caller_stack_index != 0 ) + if ( sptr != 0 ) { - fprintf( stdout, "update_wmops(): WMOPS caller stack corrupted - check that all push_wmops() are matched with pop_wmops()!\n" ); + fprintf( stdout, "update_wmops(): Stack must be empty!\n" ); exit( -1 ); } @@ -339,7 +266,7 @@ void update_wmops( void ) #ifdef WMOPS_WC_FRAME_ANALYSIS if ( ops_cnt - start_cnt > max_cnt ) { - for ( i = 0; i < num_wmops_records; i++ ) + for ( i = 0; i < num_records; i++ ) { wmops[i].wc_cnt = wmops[i].current_cnt; wmops[i].wc_selfcnt = wmops[i].current_selfcnt; @@ -348,7 +275,7 @@ void update_wmops( void ) } #endif - for ( i = 0; i < num_wmops_records; i++ ) + for ( i = 0; i < num_records; i++ ) { wmops[i].tot_selfcnt += wmops[i].current_selfcnt; wmops[i].tot_cnt += wmops[i].current_cnt; @@ -375,7 +302,6 @@ void update_wmops( void ) wmops[i].max_cnt = wmops[i].current_cnt; } - if ( wmops[i].current_cnt < wmops[i].min_cnt ) { wmops[i].min_cnt = wmops[i].current_cnt; @@ -388,10 +314,6 @@ void update_wmops( void ) #ifdef WMOPS_WC_FRAME_ANALYSIS wmops[i].current_call_number = 0; #endif - - /* update the WC of all BASOP counters */ - Set_BASOP_WMOPS_counter( i ); - Reset_BASOP_WMOPS_counter(); } current_cnt = ops_cnt - start_cnt; @@ -428,40 +350,28 @@ void update_wmops( void ) void print_wmops( void ) { - int i, label_len, max_label_len; + int i; - char *sfmts = "%*s %8s %8s %7s %7s\n"; - char *dfmts = "%*s %8.2f %8.3f %7.3f %7.3f\n"; - char *sfmt = "%*s %8s %8s %7s %7s %7s %7s %7s\n"; - char *dfmt = "%*s %8.2f %8.3f %7.3f %7.3f %7.3f %7.3f %7.3f\n"; + char *sfmts = "%20s %8s %8s %7s %7s\n"; + char *dfmts = "%20s %8.2f %8.3f %7.3f %7.3f\n"; + char *sfmt = "%20s %8s %8s %7s %7s %7s %7s %7s\n"; + char *dfmt = "%20s %8.2f %8.3f %7.3f %7.3f %7.3f %7.3f %7.3f\n"; #ifdef WMOPS_WC_FRAME_ANALYSIS - int j; + int j, label_len, max_label_len; char *sfmtt = "%20s %4s %15s\n"; char *dfmtt = "%20s %4d "; #endif - /* calculate maximum label length for compact prinout */ - max_label_len = 0; - for ( i = 0; i < num_wmops_records; i++ ) - { - label_len = strlen( wmops[i].label ); - if ( label_len > max_label_len ) - { - max_label_len = label_len; - } - } - max_label_len += 4; - fprintf( stdout, "\n\n --- Complexity analysis [WMOPS] --- \n\n" ); - - fprintf( stdout, "%*s %33s %23s\n", max_label_len, "", "|------ SELF ------|", "|--- CUMULATIVE ---|" ); - fprintf( stdout, sfmt, max_label_len, " routine", " calls", " min ", " max ", " avg ", " min ", " max ", " avg " ); - fprintf( stdout, sfmt, max_label_len, "---------------", "------", "------", "------", "------", "------", "------", "------" ); - for ( i = 0; i < num_wmops_records; i++ ) + fprintf( stdout, "%54s %23s\n", "|------ SELF ------|", "|--- CUMULATIVE ---|" ); + fprintf( stdout, sfmt, " routine", " calls", " min ", " max ", " avg ", " min ", " max ", " avg " ); + fprintf( stdout, sfmt, "---------------", "------", "------", "------", "------", "------", "------", "------" ); + + for ( i = 0; i < num_records; i++ ) { - fprintf( stdout, dfmt, max_label_len, wmops[i].label, update_cnt == 0 ? 0 : (float) wmops[i].call_number / update_cnt, + fprintf( stdout, dfmt, wmops[i].label, update_cnt == 0 ? 0 : (float) wmops[i].call_number / update_cnt, wmops[i].min_selfcnt == DOUBLE_MAX ? 0 : FAC * wmops[i].min_selfcnt, FAC * wmops[i].max_selfcnt, wmops[i].update_cnt == 0 ? 0 : FAC * wmops[i].tot_selfcnt / wmops[i].update_cnt, @@ -470,47 +380,54 @@ void print_wmops( void ) wmops[i].update_cnt == 0 ? 0 : FAC * wmops[i].tot_cnt / wmops[i].update_cnt ); } - fprintf( stdout, sfmts, max_label_len, "---------------", "------", "------", "------", "------" ); - fprintf( stdout, dfmts, max_label_len, "total", (float) update_cnt, update_cnt == 0 ? 0 : FAC * min_cnt, FAC * max_cnt, update_cnt == 0 ? 0 : FAC * ops_cnt / update_cnt ); + fprintf( stdout, sfmts, "---------------", "------", "------", "------", "------" ); + fprintf( stdout, dfmts, "total", (float) update_cnt, update_cnt == 0 ? 0 : FAC * min_cnt, FAC * max_cnt, update_cnt == 0 ? 0 : FAC * ops_cnt / update_cnt ); fprintf( stdout, "\n" ); #ifdef WMOPS_WC_FRAME_ANALYSIS - fprintf( stdout, "\nComplexity analysis for the worst-case frame %ld:\n\n", fnum_cnt_wc ); - fprintf( stdout, "%*s %8s %10s %12s\n", max_label_len, " routine", " calls", " SELF", " CUMULATIVE" ); - fprintf( stdout, "%*s %8s %10s %10s\n", max_label_len, "---------------", "------", "------", "----------" ); - - for ( i = 0; i < num_wmops_records; i++ ) + /* calculate maximum label length for compact prinout */ + max_label_len = 0; + for ( i = 0; i < num_records; i++ ) { - if ( wmops[i].wc_call_number > 0 ) + label_len = strlen( wmops[i].label ); + if ( label_len > max_label_len ) { - fprintf( stdout, "%*s %8d %10.3f %12.3f\n", max_label_len, wmops[i].label, wmops[i].wc_call_number, FAC * wmops[i].wc_selfcnt, FAC * wmops[i].wc_cnt ); + max_label_len = label_len; } } + max_label_len += 4; - fprintf( stdout, "\nCall tree for the worst-case frame %ld:\n\n", fnum_cnt_wc ); - fprintf( stdout, sfmtt, " function", "num", "called by " ); + fprintf( stdout, "\nComplexity analysis for the worst-case frame %ld:\n", fnum_cnt_wc ); + fprintf( stdout, "%*s %8s %10s %12s\n", max_label_len, " routine", " calls", " SELF", " CUMULATIVE" ); + fprintf( stdout, "%*s %8s %10s %10s\n", max_label_len, "---------------", "------", "------", "----------" ); + + for ( i = 0; i < num_records; i++ ) + { + fprintf( stdout, "%*s %8d %10.3f %12.3f\n", max_label_len, wmops[i].label, wmops[i].wc_call_number, FAC * wmops[i].wc_selfcnt, FAC * wmops[i].wc_cnt ); + } + + fprintf( stdout, "\nCall Tree:\n\n" ); + fprintf( stdout, sfmtt, " function", "num", "called by: " ); fprintf( stdout, sfmtt, "---------------", "---", "--------------" ); - for ( i = 0; i < num_wmops_records; i++ ) + for ( i = 0; i < num_records; i++ ) { - if ( wmops[i].wc_call_number > 0 ) + fprintf( stdout, dfmtt, wmops[i].label, i ); + for ( j = 0; wmops[i].call_tree[j] != -1; j++ ) { - fprintf( stdout, dfmtt, wmops[i].label, i ); - for ( j = 0; wmops[i].call_tree[j] != -1 && j < MAX_CALL_TREE_DEPTH; j++ ) + if ( j != 0 ) { - if ( j != 0 ) - { - fprintf( stdout, ", " ); - } - fprintf( stdout, "%d", wmops[i].call_tree[j] ); + fprintf( stdout, ", " ); } - fprintf( stdout, "\n" ); + fprintf( stdout, "%d", wmops[i].call_tree[j] ); } + fprintf( stdout, "\n" ); } + fprintf( stdout, sfmtt, "---------------", "---", "--------------" ); fprintf( stdout, "\n\n" ); - fprintf( stdout, "\nInstruction type analysis for the worst-case frame %ld:\n\n", fnum_cnt_wc ); + fprintf( stdout, "\nInstruction type analysis for the worst-case frame %ld:\n\n", fnum_cnt_wc ); /* added -- JPA */ for ( i = 0; i < NUM_INST; i++ ) { switch ( (enum instructions) i ) @@ -581,24 +498,6 @@ void print_wmops( void ) } #endif - /* De-allocate the list of wmops record */ - if ( wmops != NULL ) - { - free( wmops ); - } - - /* De-allocate the list of wmops caller functions */ - if ( wmops_caller_stack != NULL ) - { - free( wmops_caller_stack ); - } - - /* De-allocate the BASOP WMOPS counter */ - if ( multiCounter != NULL ) - { - free( multiCounter ); - } - return; } @@ -625,6 +524,12 @@ void print_wmops( void ) * #define WMC_TOOL_SKIP ... #undef WMC_TOOL_SKIP macro pair around the malloc(), calloc() and free(). *--------------------------------------------------------------------*/ +#define MAX_RECORDABLE_CALLS 100 +#define MAX_FUNCTION_NAME_LENGTH 35 /* Maximum length that the function string will be truncated to */ +#define MAX_PARAMS_LENGTH 50 /* Maximum length that the parameter string will be truncated to */ +#define MAX_NUM_RECORDS 300 /* Initial maximum number of memory records -> mightb be increased during runtime, if needed */ +#define MAX_NUM_RECORDS_REALLOC_STEP 50 /* When re-allocating the list of memory records, increase the number of records by this number */ + /* This is the value (in bytes) towards which the block size is rounded. For example, a block of 123 bytes, when using a 32 bits system, will end up taking 124 bytes since the last unused byte cannot be used for another block. */ #ifdef MEM_ALIGN_64BITS @@ -634,13 +539,15 @@ void print_wmops( void ) #endif #define N_32BITS_BLOCKS ( BLOCK_ROUNDING / sizeof( int32_t ) ) -#define ROUND_BLOCK_SIZE( n ) ( ( ( n ) + BLOCK_ROUNDING - 1 ) & ~( BLOCK_ROUNDING - 1 ) ) #define MAGIC_VALUE_OOB 0x12A534F0 /* Signature value which is inserted before and after each allocated memory block, used to detect out-of-bound access */ #define MAGIC_VALUE_USED ( ~MAGIC_VALUE_OOB ) /* Value used to pre-fill allocated memory blocks, used to calculate actual memory usage */ #define OOB_START 0x1 /* Flag indicating out-of-bounds access before memory block */ #define OOB_END 0x2 /* Flag indicating out-of-bounds access after memory block */ +#define ROUND_BLOCK_SIZE( n ) ( ( ( n ) + BLOCK_ROUNDING - 1 ) & ~( BLOCK_ROUNDING - 1 ) ) +#define IS_CALLOC( str ) ( str[0] == 'c' ) + #ifdef MEM_COUNT_DETAILS const char *csv_filename = "mem_analysis.csv"; static FILE *fid_csv_filename = NULL; @@ -652,16 +559,8 @@ typedef struct int16_t *stack_ptr; } caller_info; -static caller_info *stack_callers[2] = {NULL, NULL}; +caller_info stack_callers[2][MAX_RECORDABLE_CALLS]; -static int16_t *ptr_base_stack = 0; /* Pointer to the bottom of stack (base pointer). Stack grows up. */ -static int16_t *ptr_current_stack = 0; /* Pointer to the current stack pointer */ -static int16_t *ptr_max_stack = 0; /* Pointer to the maximum stack pointer (the farest point from the bottom of stack) */ -static int32_t wc_stack_frame = 0; /* Frame corresponding to the worst-case stack usage */ -static int current_calls = 0, max_num_calls = MAX_NUM_RECORDS; -static char location_max_stack[256] = "undefined"; - -/* Heap-related variables */ typedef struct { char name[MAX_FUNCTION_NAME_LENGTH + 1]; /* +1 for NUL */ @@ -681,12 +580,18 @@ typedef struct allocator_record *allocation_list = NULL; +static int16_t *ptr_base_stack = 0; /* Pointer to the bottom of stack (base pointer). Stack grows up. */ +static int16_t *ptr_current_stack = 0; /* Pointer to the current stack pointer */ +static int16_t *ptr_max_stack = 0; /* Pointer to the maximum stack pointer (the farest point from the bottom of stack) */ +static int32_t wc_stack_frame = 0; /* Frame corresponding to the worst-case stack usage */ +static int32_t wc_ram_size, wc_ram_frame; +static int32_t current_heap_size; +static int current_calls = 0; +static char location_max_stack[256] = "undefined"; static int Num_Records, Max_Num_Records; static size_t Stat_Cnt_Size = USE_BYTES; -static const char *Count_Unit[] = { "bytes", "words", "words", "words" }; +static const char *Count_Unit[] = { "bytes", "words", "words" }; -static int32_t wc_ram_size, wc_ram_frame; -static int32_t current_heap_size; static int *list_wc_intra_frame_heap, n_items_wc_intra_frame_heap, max_items_wc_intra_frame_heap, size_wc_intra_frame_heap, location_wc_intra_frame_heap; static int *list_current_inter_frame_heap, n_items_current_inter_frame_heap, max_items_current_inter_frame_heap, size_current_inter_frame_heap; static int *list_wc_inter_frame_heap, n_items_wc_inter_frame_heap, max_items_wc_inter_frame_heap, size_wc_inter_frame_heap, location_wc_inter_frame_heap; @@ -707,28 +612,11 @@ void reset_mem( Counting_Size cnt_size ) int16_t something; size_t tmp_size; - /* initialize list of stack records */ - if ( stack_callers[0] == NULL ) - { - stack_callers[0] = malloc( MAX_NUM_RECORDS * sizeof( caller_info ) ); - stack_callers[1] = malloc( MAX_NUM_RECORDS * sizeof( caller_info ) ); - } - - if ( stack_callers[0] == NULL || stack_callers[1] == NULL ) - { - fprintf( stderr, "Error: Unable to Allocate List of Stack Records!" ); - exit( -1 ); - } - - current_calls = 0; - max_num_calls = MAX_NUM_RECORDS; - /* initialize stack pointers */ ptr_base_stack = &something; ptr_max_stack = ptr_base_stack; ptr_current_stack = ptr_base_stack; - /* initialize the unit of memory block size */ Stat_Cnt_Size = cnt_size; /* Check, if sizeof(int32_t) is 4 bytes */ @@ -854,12 +742,11 @@ int push_stack( const char *filename, const char *fctname ) (void) *filename; /* to avoid compilation warning */ - if ( current_calls >= max_num_calls ) - { - /* There is no room for a new record -> reallocate the list */ - max_num_calls += MAX_NUM_RECORDS_REALLOC_STEP; - stack_callers[0] = realloc( stack_callers[0], max_num_calls * sizeof( caller_info ) ); - stack_callers[1] = realloc( stack_callers[1], max_num_calls * sizeof( caller_info ) ); + /* Is there room to save the caller's information? */ + if ( current_calls >= MAX_RECORDABLE_CALLS ) + { /* No */ + fprintf( stderr, "No more room to store call stack info. Please increase MAX_RECORDABLE_CALLS" ); + exit( -1 ); } /* Valid Function Name? */ @@ -876,7 +763,7 @@ int push_stack( const char *filename, const char *fctname ) /* Save the Stack Pointer */ stack_callers[0][current_calls].stack_ptr = ptr_current_stack; - /* Increase the Number of Calls in the List */ + /* Increase Stack Calling Tree Level */ current_calls++; /* Is this the First Time or the Worst Case? */ @@ -885,17 +772,15 @@ int push_stack( const char *filename, const char *fctname ) /* Save Info about it */ ptr_max_stack = ptr_current_stack; - /* save the worst-case frame number */ - /* current frame number is stored in the variable update_cnt and updated in the function update_wmops() */ - wc_stack_frame = update_cnt; + wc_stack_frame = update_cnt; /* current frame number is stored in the variable update_cnt and updated in the function update_wmops() */ strncpy( location_max_stack, fctname, sizeof( location_max_stack ) - 1 ); location_max_stack[sizeof( location_max_stack ) - 1] = '\0'; /* Save Call Tree */ memmove( stack_callers[1], stack_callers[0], sizeof( caller_info ) * current_calls ); - /* Terminate the List with 0 (for printing purposes) */ - if ( current_calls < max_num_calls ) + /* Terminate the List (Unless Full) */ + if ( current_calls < MAX_RECORDABLE_CALLS ) { stack_callers[1][current_calls].function_name[0] = 0; } @@ -931,13 +816,13 @@ int pop_stack( const char *filename, const char *fctname ) (void) *filename; /* to avoid compilation warning */ - /* Decrease the Number of Records */ + /* Decrease Stack Calling */ current_calls--; /* Get Pointer to Caller Information */ caller_info_ptr = &stack_callers[0][current_calls]; - /* Check, if the Function Names Match */ + /* Check, if Names Match */ if ( strncmp( caller_info_ptr->function_name, fctname, MAX_FUNCTION_NAME_LENGTH ) != 0 ) { fprintf( stderr, "Invalid usage of pop_stack()" ); @@ -976,7 +861,7 @@ static void print_stack_call_tree( void ) fprintf( stdout, "\nList of functions when maximum stack size is reached:\n\n" ); caller_info_ptr = &stack_callers[1][0]; - for ( call_level = 0; call_level < max_num_calls; call_level++ ) + for ( call_level = 0; call_level < MAX_RECORDABLE_CALLS; call_level++ ) { /* Done? */ if ( caller_info_ptr->function_name[0] == 0 ) @@ -1175,7 +1060,7 @@ static void *mem_alloc_block( size_t size, const char *size_str ) /* Fill Memory Block with Magic Value or 0 */ fill_value = MAGIC_VALUE_USED; - if ( size_str[0] == 'c' ) + if ( IS_CALLOC( size_str ) ) { fill_value = 0x00000000; } @@ -1896,16 +1781,7 @@ void print_mem( ROM_Size_Lookup_Table Const_Data_PROM_Table[] ) for ( i = 0; i < nElem; i++ ) { - if ( Stat_Cnt_Size > 0 ) - { - /* words */ - fprintf( stdout, "Program ROM size (%s): %d words\n", Const_Data_PROM_Table[i].file_spec, Const_Data_PROM_Table[i].PROM_size ); - } - else - { - /* bytes */ - fprintf( stdout, "Program ROM size (%s): %d bytes\n", Const_Data_PROM_Table[i].file_spec, Const_Data_PROM_Table[i].PROM_size << Stat_Cnt_Size ); - } + fprintf( stdout, "Program ROM size (%s): %d instruction words\n", Const_Data_PROM_Table[i].file_spec, Const_Data_PROM_Table[i].PROM_size ); } for ( i = 0; i < nElem; i++ ) @@ -1994,12 +1870,11 @@ void print_mem( ROM_Size_Lookup_Table Const_Data_PROM_Table[] ) mem_count_summary(); #endif - if ( Stat_Cnt_Size == 0 ) + if ( Stat_Cnt_Size > 0 ) { - /* bytes */ - fprintf( stdout, "\nNote: The Program ROM size is calculated under the assumption that 1 instruction word is stored with %d bytes (%d bits)\n", 1 << Stat_Cnt_Size, 8 << Stat_Cnt_Size ); + fprintf( stdout, "\nNote: 1 word = %d bits\n", 8 << Stat_Cnt_Size ); + fprintf( stdout, "This is an optimistic estimate of memory consumption assuming that each variable type is stored with sizeof(type) bits\n" ); } - fprintf( stdout, "Note: The Data ROM size is calculated using the sizeof(type) built-in function\n" ); if ( n_items_wc_intra_frame_heap > 0 ) { @@ -2012,17 +1887,6 @@ void print_mem( ROM_Size_Lookup_Table Const_Data_PROM_Table[] ) free( allocation_list ); } - /* De-allocate list of stack records */ - if ( stack_callers[0] != NULL ) - { - free( stack_callers[0] ); - } - - if ( stack_callers[1] != NULL ) - { - free( stack_callers[1] ); - } - /* De-allocate heap allocation call tree */ if ( heap_allocation_call_tree != NULL ) { @@ -2060,105 +1924,3 @@ void print_mem( ROM_Size_Lookup_Table Const_Data_PROM_Table[] ) #ifndef WMOPS int cntr_push_pop = 0; /* global counter for checking balanced push_wmops()/pop_wmops() pairs when WMOPS is not activated */ #endif - -#ifdef WMOPS -/* Global counter for the calculation of BASOP complexity */ -BASIC_OP *multiCounter = NULL; -int currCounter = 0; -int funcId_where_last_call_to_else_occurred; -long funcid_total_wmops_at_last_call_to_else; -int call_occurred = 1; - -BASIC_OP op_weight = { - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 2, 2, 1, - 1, 1, 1, 3, 1, - - 1, 1, 1, 3, 1, - 4, 1, 18, 1, 1, - 2, 1, 2, 2, 1, - 1, 1, 1, 1, 1, - 3, 3, 3, 3, 1, - - 1, 1, 1, 1, 1, - 1, 1, 1, 2, - 1, 2, 2, 4, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 3, - 3, 3, 3, 3, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 4, 4, - 4, 8, 3, 4, 4, - - 5, 32, 3 -}; - -/* Set the counter group to use, default is zero */ -void Set_BASOP_WMOPS_counter( int counterId ) -{ - if ( ( counterId > num_wmops_records ) || ( counterId < 0 ) ) - { - currCounter = 0; - return; - } - currCounter = counterId; - call_occurred = 1; -} - -extern int32_t frame; - -long TotalWeightedOperation() -{ - int i; - unsigned int *ptr, *ptr2; - long tot; - - tot = 0; - ptr = (unsigned int *) &multiCounter[currCounter]; - ptr2 = (unsigned int *) &op_weight; - - for ( i = 0; i < ( int )( sizeof( multiCounter[currCounter] ) / sizeof( unsigned int ) ); i++ ) - { - tot += ( ( *ptr++ ) * ( *ptr2++ ) ); - } - - return ( tot ); -} - -long DeltaWeightedOperation( void ) -{ - long NewWOper, delta; - - NewWOper = TotalWeightedOperation(); - - delta = NewWOper - wmops[currCounter].LastWOper; - wmops[currCounter].LastWOper = NewWOper; - - return ( delta ); -} - -/* Resets the current BASOP WMOPS counter */ -void Reset_BASOP_WMOPS_counter( void ) -{ - int i; - long *ptr; - - /* clear the current BASOP operation counter before new frame begins */ - ptr = (long *) &multiCounter[currCounter]; - for ( i = 0; i < (int) ( sizeof( multiCounter[currCounter] ) / sizeof( long ) ); i++ ) - { - *ptr++ = 0; - } - - wmops[currCounter].LastWOper = 0; - - return; -} - -#endif - - diff --git a/lib_debug/wmc_auto.h b/lib_debug/wmc_auto.h index e2f2af4d8..9e20a4c7c 100644 --- a/lib_debug/wmc_auto.h +++ b/lib_debug/wmc_auto.h @@ -1,5 +1,5 @@ /* - * (C) 2023 copyright VoiceAge Corporation. All Rights Reserved. + * (C) 2022 copyright VoiceAge Corporation. All Rights Reserved. * * This software is protected by copyright law and by international treaties. The source code, and all of its derivations, * is provided by VoiceAge Corporation under the "ITU-T Software Tools' General Public License". Please, read the license file @@ -29,14 +29,13 @@ #pragma GCC system_header #endif -#ifndef INT_MAX -#define INT_MAX 32767 -#endif - /* Real-time relationships */ -#define FRAMES_PER_SECOND 50.0 +#define FRAMES_PER_SECOND 50.0 +#define MILLION_CYCLES 1e6 #define WMOPS_BOOST_FAC ( 1.0f ) /* scaling factor for equalizing the difference between automatic and manual instrumentation */ -#define FAC ( FRAMES_PER_SECOND / 1e6 * WMOPS_BOOST_FAC ) +#define FAC ( FRAMES_PER_SECOND / MILLION_CYCLES * WMOPS_BOOST_FAC ) +#define NUM_INST 20 /* Total number of instruction types (in enum below) */ + #ifdef WMOPS enum instructions @@ -60,8 +59,7 @@ enum instructions _TEST, _POWER, _LOG, - _MISC, - NUM_INST + _MISC }; #define _ADD_C 1 @@ -563,6 +561,7 @@ enum instructions extern double ops_cnt; extern double prom_cnt; extern double inst_cnt[NUM_INST]; +extern int ops_cnt_activ; void reset_wmops( void ); void push_wmops( const char *label ); @@ -981,8 +980,7 @@ typedef enum { USE_BYTES = 0, USE_16BITS = 1, - USE_32BITS = 2, - USE_64BITS = 3 + USE_32BITS = 2 } Counting_Size; #if ( defined( _WIN32 ) && ( _MSC_VER <= 1800 ) && ( _MSC_VER >= 1300 ) ) @@ -1014,7 +1012,7 @@ int push_stack( const char *filename, const char *fctname ); int pop_stack( const char *filename, const char *fctname ); #ifdef WMOPS_DETAIL -#define STACK_DEPTH_FCT_CALL ( push_wmops( __FUNCTION__ " [WMC_AUTO]" ), push_stack( __FILE__, __FUNCTION__ ) ) /* add push_wmops() in all function calls */ +#define STACK_DEPTH_FCT_CALL ( push_wmops( __FUNCTION__ ), push_stack( __FILE__, __FUNCTION__ ) ) /* add push_wmops() in all function calls */ #define STACK_DEPTH_FCT_RETURN ( pop_wmops(), pop_stack( __FILE__, __FUNCTION__ ) ) /* add pop_wmops() in all function returns */ #else #define STACK_DEPTH_FCT_CALL push_stack( __FILE__, __FUNCTION__ ) @@ -1038,405 +1036,4 @@ void reset_stack( void ); #endif - -/* Global counter variable for calculation of complexity weight */ -typedef struct -{ - unsigned int add; /* Complexity Weight of 1 */ - unsigned int sub; /* Complexity Weight of 1 */ - unsigned int abs_s; /* Complexity Weight of 1 */ - unsigned int shl; /* Complexity Weight of 1 */ - unsigned int shr; /* Complexity Weight of 1 */ - - unsigned int extract_h; /* Complexity Weight of 1 */ - unsigned int extract_l; /* Complexity Weight of 1 */ - unsigned int mult; /* Complexity Weight of 1 */ - unsigned int L_mult; /* Complexity Weight of 1 */ - unsigned int negate; /* Complexity Weight of 1 */ - - unsigned int round; /* Complexity Weight of 1 */ - unsigned int L_mac; /* Complexity Weight of 1 */ - unsigned int L_msu; /* Complexity Weight of 1 */ - unsigned int L_macNs; /* Complexity Weight of 1 */ - unsigned int L_msuNs; /* Complexity Weight of 1 */ - - unsigned int L_add; /* Complexity Weight of 1 */ - unsigned int L_sub; /* Complexity Weight of 1 */ - unsigned int L_add_c; /* Complexity Weight of 2 */ - unsigned int L_sub_c; /* Complexity Weight of 2 */ - unsigned int L_negate; /* Complexity Weight of 1 */ - - unsigned int L_shl; /* Complexity Weight of 1 */ - unsigned int L_shr; /* Complexity Weight of 1 */ - unsigned int mult_r; /* Complexity Weight of 1 */ - unsigned int shr_r; /* Complexity Weight of 3 */ - unsigned int mac_r; /* Complexity Weight of 1 */ - - unsigned int msu_r; /* Complexity Weight of 1 */ - unsigned int L_deposit_h; /* Complexity Weight of 1 */ - unsigned int L_deposit_l; /* Complexity Weight of 1 */ - unsigned int L_shr_r; /* Complexity Weight of 3 */ - unsigned int L_abs; /* Complexity Weight of 1 */ - - unsigned int L_sat; /* Complexity Weight of 4 */ - unsigned int norm_s; /* Complexity Weight of 1 */ - unsigned int div_s; /* Complexity Weight of 18 */ - unsigned int norm_l; /* Complexity Weight of 1 */ - unsigned int move16; /* Complexity Weight of 1 */ - - unsigned int move32; /* Complexity Weight of 2 */ - unsigned int Logic16; /* Complexity Weight of 1 */ - unsigned int Logic32; /* Complexity Weight of 2 */ - unsigned int Test; /* Complexity Weight of 2 */ - unsigned int s_max; /* Complexity Weight of 1 */ - - unsigned int s_min; /* Complexity Weight of 1 */ - unsigned int L_max; /* Complexity Weight of 1 */ - unsigned int L_min; /* Complexity Weight of 1 */ - unsigned int L40_max; /* Complexity Weight of 1 */ - unsigned int L40_min; /* Complexity Weight of 1 */ - - unsigned int shl_r; /* Complexity Weight of 3 */ - unsigned int L_shl_r; /* Complexity Weight of 3 */ - unsigned int L40_shr_r; /* Complexity Weight of 3 */ - unsigned int L40_shl_r; /* Complexity Weight of 3 */ - unsigned int norm_L40; /* Complexity Weight of 1 */ - - unsigned int L40_shl; /* Complexity Weight of 1 */ - unsigned int L40_shr; /* Complexity Weight of 1 */ - unsigned int L40_negate; /* Complexity Weight of 1 */ - unsigned int L40_add; /* Complexity Weight of 1 */ - unsigned int L40_sub; /* Complexity Weight of 1 */ - - unsigned int L40_abs; /* Complexity Weight of 1 */ - unsigned int L40_mult; /* Complexity Weight of 1 */ - unsigned int L40_mac; /* Complexity Weight of 1 */ - unsigned int mac_r40; /* Complexity Weight of 2 */ - - unsigned int L40_msu; /* Complexity Weight of 1 */ - unsigned int msu_r40; /* Complexity Weight of 2 */ - unsigned int Mpy_32_16_ss; /* Complexity Weight of 2 */ - unsigned int Mpy_32_32_ss; /* Complexity Weight of 4 */ - unsigned int L_mult0; /* Complexity Weight of 1 */ - - unsigned int L_mac0; /* Complexity Weight of 1 */ - unsigned int L_msu0; /* Complexity Weight of 1 */ - unsigned int lshl; /* Complexity Weight of 1 */ - unsigned int lshr; /* Complexity Weight of 1 */ - unsigned int L_lshl; /* Complexity Weight of 1 */ - - unsigned int L_lshr; /* Complexity Weight of 1 */ - unsigned int L40_lshl; /* Complexity Weight of 1 */ - unsigned int L40_lshr; /* Complexity Weight of 1 */ - unsigned int s_and; /* Complexity Weight of 1 */ - unsigned int s_or; /* Complexity Weight of 1 */ - - unsigned int s_xor; /* Complexity Weight of 1 */ - unsigned int L_and; /* Complexity Weight of 1 */ - unsigned int L_or; /* Complexity Weight of 1 */ - unsigned int L_xor; /* Complexity Weight of 1 */ - unsigned int rotl; /* Complexity Weight of 3 */ - - unsigned int rotr; /* Complexity Weight of 3 */ - unsigned int L_rotl; /* Complexity Weight of 3 */ - unsigned int L_rotr; /* Complexity Weight of 3 */ - unsigned int L40_set; /* Complexity Weight of 3 */ - unsigned int L40_deposit_h; /* Complexity Weight of 1 */ - - unsigned int L40_deposit_l; /* Complexity Weight of 1 */ - unsigned int L40_deposit32; /* Complexity Weight of 1 */ - unsigned int Extract40_H; /* Complexity Weight of 1 */ - unsigned int Extract40_L; /* Complexity Weight of 1 */ - unsigned int L_Extract40; /* Complexity Weight of 1 */ - - unsigned int L40_round; /* Complexity Weight of 1 */ - unsigned int L_saturate40; /* Complexity Weight of 1 */ - unsigned int round40; /* Complexity Weight of 1 */ - unsigned int If; /* Complexity Weight of 4 */ - unsigned int Goto; /* Complexity Weight of 4 */ - - unsigned int Break; /* Complexity Weight of 4 */ - unsigned int Switch; /* Complexity Weight of 8 */ - unsigned int For; /* Complexity Weight of 3 */ - unsigned int While; /* Complexity Weight of 4 */ - unsigned int Continue; /* Complexity Weight of 4 */ - - unsigned int L_mls; /* Complexity Weight of 6 */ - unsigned int div_l; /* Complexity Weight of 32 */ - unsigned int i_mult; /* Complexity Weight of 3 */ -} BASIC_OP; - -#ifdef WMOPS -extern BASIC_OP *multiCounter; -extern int currCounter; - -/* Technical note : - * The following 3 variables are only used for correct complexity - * evaluation of the following structure : - * IF{ - * ... - * } ELSE IF { - * ... - * } ELSE IF { - * ... - * } - * ... - * } ELSE { - * ... - * } - */ -extern int funcId_where_last_call_to_else_occurred; -extern long funcid_total_wmops_at_last_call_to_else; -extern int call_occurred; - -extern long TotalWeightedOperation( void ); -long DeltaWeightedOperation( void ); - -void Set_BASOP_WMOPS_counter( int counterId ); -void Reset_BASOP_WMOPS_counter( void ); - -#endif - -/***************************************************************************** - * - * Function Name : FOR - * - * Purpose : - * - * The macro FOR should be used instead of the 'for' C statement. - * The complexity is independent of the number of loop iterations that are - * performed. - * - * Complexity weight : 3 (regardless of number of iterations). - * - *****************************************************************************/ -#ifndef WMOPS -#define FOR( a) for( a) - -#else -#define FOR( a) if( incrFor(), 0); else for( a) - -static __inline void incrFor( void) { - multiCounter[currCounter].For++; -} -#endif - - -/***************************************************************************** - * - * Function Name : WHILE - * - * Purpose : - * - * The macro WHILE should be used instead of the 'while' C statement. - * The complexity is proportional to the number of loop iterations that - * are performed. - * - * Complexity weight : 4 x 'number of loop iterations'. - * - *****************************************************************************/ -#ifndef WMOPS -#define WHILE( a) while( a) - -#else -#define WHILE( a) while( incrWhile(), a) - -static __inline void incrWhile( void) { - multiCounter[currCounter].While++; -} -#endif - - -/***************************************************************************** - * - * Function Name : DO - * - * Purpose : - * - * The macro DO should be used instead of the 'do' C statement. - * - * Complexity weight : 0 (complexity counted by WHILE macro). - * - *****************************************************************************/ -#ifndef WMOPS -#define DO do - -#else -#define DO do - -#endif - - -/***************************************************************************** - * - * Function Name : IF - * - * Purpose : - * - * The macro IF should : - * - * - not be used when : - * - the 'if' structure does not have any 'else if' nor 'else' statement - * - and it conditions only one DSP basic operations. - * - * - be used instead of the 'if' C statement in every other case : - * - when there is an 'else' or 'else if' statement, - * - or when the 'if' conditions several DSP basic operations, - * - or when the 'if' conditions a function call. - * - * Complexity weight : 4 - * - *****************************************************************************/ -#ifndef WMOPS -#define IF( a) if( a) - -#else -#define IF( a) if( incrIf(), a) - -static __inline void incrIf( void) { - /* Technical note : - * If the "IF" operator comes just after an "ELSE", its counter - * must not be incremented. - */ - if ( ( currCounter != funcId_where_last_call_to_else_occurred ) || ( TotalWeightedOperation() != funcid_total_wmops_at_last_call_to_else ) || ( call_occurred == 1 ) ) - { - multiCounter[currCounter].If++; - } - - call_occurred = 0; - funcId_where_last_call_to_else_occurred = INT_MAX; -} -#endif - - -/***************************************************************************** - * - * Function Name : ELSE - * - * Purpose : - * - * The macro ELSE should be used instead of the 'else' C statement. - * - * Complexity weight : 4 - * - *****************************************************************************/ -#ifndef WMOPS -#define ELSE else - -#else -#define ELSE else if( incrElse(), 0) ; else - -static __inline void incrElse( void) { - multiCounter[currCounter].If++; - - /* We keep track of the funcId of the last function - * which used ELSE {...} structure. - */ - funcId_where_last_call_to_else_occurred = currCounter; - - /* We keep track of the number of WMOPS of this funcId - * when the ELSE macro was called. - */ - funcid_total_wmops_at_last_call_to_else = TotalWeightedOperation(); - - /* call_occurred is set to 0, in order to count the next IF (if necessary) - */ - call_occurred = 0; -} -#endif - - -/***************************************************************************** - * - * Function Name : SWITCH - * - * Purpose : - * - * The macro SWITCH should be used instead of the 'switch' C statement. - * - * Complexity weight : 8 - * - *****************************************************************************/ -#ifndef WMOPS -#define SWITCH( a) switch( a) - -#else -#define SWITCH( a) switch( incrSwitch(), a) - -static __inline void incrSwitch( void) { - multiCounter[currCounter].Switch++; -} -#endif - - -/***************************************************************************** - * - * Function Name : CONTINUE - * - * Purpose : - * - * The macro CONTINUE should be used instead of the 'continue' C statement. - * - * Complexity weight : 4 - * - *****************************************************************************/ -#ifndef WMOPS -#define CONTINUE continue - -#else -#define CONTINUE if( incrContinue(), 0); else continue - -static __inline void incrContinue( void) { - multiCounter[currCounter].Continue++; -} -#endif - - -/***************************************************************************** - * - * Function Name : BREAK - * - * Purpose : - * - * The macro BREAK should be used instead of the 'break' C statement. - * - * Complexity weight : 4 - * - *****************************************************************************/ -#ifndef WMOPS -#define BREAK break - -#else -#define BREAK if( incrBreak(), 0) break; else break - -static __inline void incrBreak( void) { - multiCounter[currCounter].Break++; -} -#endif - - -/***************************************************************************** - * - * Function Name : GOTO - * - * Purpose : - * - * The macro GOTO should be used instead of the 'goto' C statement. - * - * Complexity weight : 4 - * - *****************************************************************************/ -#ifndef WMOPS -#define GOTO goto - -#else -#define GOTO if( incrGoto(), 0); else goto - -static __inline void incrGoto( void) { - multiCounter[currCounter].Goto++; -} -#endif - #endif /* WMOPS_H */ - - diff --git a/lib_util/test_fft.c b/lib_util/test_fft.c index 6622b3396..264ea41b4 100644 --- a/lib_util/test_fft.c +++ b/lib_util/test_fft.c @@ -36,6 +36,8 @@ #include #include #include +#include "options.h" +#include "test_fft.h" typedef int Word32; typedef short Word16; -- GitLab From b0863acebe23557dc210568d284e131149cc0139 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Thu, 30 Nov 2023 15:29:45 +0100 Subject: [PATCH 3/4] Added missing file test_fft.h --- lib_util/test_fft.h | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 lib_util/test_fft.h diff --git a/lib_util/test_fft.h b/lib_util/test_fft.h new file mode 100644 index 000000000..14b9758fb --- /dev/null +++ b/lib_util/test_fft.h @@ -0,0 +1,41 @@ +/****************************************************************************************************** + + (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef __TEST_FFT_H +#define __TEST_FFT_H + +#include "options.h" + +void run_fft_unit_test(void); + + +#endif /* __TEST_FFT_H */ -- GitLab From 63ea6a06a4c152ac75803698b873fb8ce76c72a3 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Thu, 30 Nov 2023 15:39:26 +0100 Subject: [PATCH 4/4] Fixes in VS project files --- Workspace_msvc/lib_com.vcxproj | 1 + Workspace_msvc/lib_com.vcxproj.filters | 3 ++ Workspace_msvc/lib_rend.vcxproj.filters | 66 ------------------------- Workspace_msvc/lib_util.vcxproj | 1 + 4 files changed, 5 insertions(+), 66 deletions(-) diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 6fb8e705b..2fc3f8f56 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -322,6 +322,7 @@ + diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters index 27670198e..2d8a6c550 100644 --- a/Workspace_msvc/lib_com.vcxproj.filters +++ b/Workspace_msvc/lib_com.vcxproj.filters @@ -602,6 +602,9 @@ common_h + + common_h + common_h diff --git a/Workspace_msvc/lib_rend.vcxproj.filters b/Workspace_msvc/lib_rend.vcxproj.filters index 4707a48b2..170a82f88 100644 --- a/Workspace_msvc/lib_rend.vcxproj.filters +++ b/Workspace_msvc/lib_rend.vcxproj.filters @@ -32,15 +32,6 @@ rend_c - - rend_c - - - rend_c - - - rend_c - rend_c @@ -50,12 +41,6 @@ rend_c - - rend_c - - - rend_c - rend_c @@ -83,15 +68,6 @@ rend_c - - rend_c - - - rend_c - - - rend_c - rend_c @@ -113,9 +89,6 @@ rend_c - - rend_c - rend_c @@ -134,24 +107,6 @@ rend_c - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - rend_c @@ -161,30 +116,12 @@ rend_c - - rend_c - - - rend_c - - - rend_c - rend_c - - rend_h - - - rend_h - - - rend_h - rend_h @@ -206,9 +143,6 @@ rend_h - - rend_h - diff --git a/Workspace_msvc/lib_util.vcxproj b/Workspace_msvc/lib_util.vcxproj index 6696ee00a..86730b859 100644 --- a/Workspace_msvc/lib_util.vcxproj +++ b/Workspace_msvc/lib_util.vcxproj @@ -106,6 +106,7 @@ + -- GitLab