From c4a5465f152a7f1d8c6508c3f5ba6d751dd56407 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Tue, 25 Apr 2023 13:24:41 +0200 Subject: [PATCH 01/39] merged main and jitter dev branch, self_test runs through but not yet BE Squashed commit of the following: commit 2f8090f5da66a661a8716d84066f0556fc0e54d9 Author: Stefan Bayer Date: Mon Apr 24 07:15:05 2023 +0200 cleanup commit 9562e73adf70f41c8c4685a19c294778e9c057ae Author: Stefan Bayer Date: Fri Apr 21 06:31:29 2023 +0200 added bit rate switching, also added missing bit rate switching modes for MASA and ISM to ivas_modes.json commit 8f85e52948ee7667cfdddca0f9ac1c93563dfba5 Author: Stefan Bayer Date: Tue Apr 18 14:33:22 2023 +0200 fix bug in udpating of the JBM TC buffers, wrong offset into copying old samples due to prematurely resetting n_samples_rendered commit a0d60297f265bccfb317941387da9ef1841a6ec8 Author: Stefan Bayer Date: Mon Apr 17 13:24:44 2023 +0200 WSOLA TSM is now working with float in/out buffers (internally it was always float anyway), fixed a few rendering paths commit ababf3f40fb62deb98bab9a19975aa3bb11d1f0a Author: Stefan Bayer Date: Sun Apr 16 20:12:02 2023 +0200 fixed several renderer paths commit e51bd2e2d98aa7a1accd5872e6c286ab883b636a Author: Stefan Bayer Date: Fri Apr 14 16:51:22 2023 +0200 all possible render paths run now with variable speed decoding, audio quality only sparsely checked commit 6b919859ca8a5ec93818970ad29877e4885a9659 Author: Stefan Bayer Date: Tue Apr 11 09:36:06 2023 +0200 some cleanup, removed duplication of transport channel buffering commit 2c794eb6aa0bb814bec983fe7c1f4cfead1029f5 Author: Stefan Bayer Date: Thu Apr 6 09:45:51 2023 +0200 JITTER (work in progress) --- Workspace_msvc/lib_com.vcxproj | 2 +- Workspace_msvc/lib_debug.vcxproj | 2 +- Workspace_msvc/lib_dec.vcxproj | 3 +- Workspace_msvc/lib_enc.vcxproj | 2 +- Workspace_msvc/lib_rend.vcxproj | 2 +- Workspace_msvc/lib_util.vcxproj | 2 + apps/decoder.c | 712 +++++++- lib_com/fd_cng_com.c | 68 + lib_com/ivas_cnst.h | 23 + lib_com/ivas_error.h | 3 + lib_com/ivas_prot.h | 500 ++++- lib_com/ivas_stat_com.h | 6 +- lib_com/ivas_td_decorr.c | 22 +- lib_com/ivas_tools.c | 54 +- lib_com/options.h | 15 +- lib_com/prot.h | 17 +- lib_com/tools.c | 8 + lib_debug/debug.c | 105 +- lib_debug/debug.h | 15 + lib_debug/sba_debug.c | 26 +- lib_debug/sba_debug.h | 3 +- lib_dec/fd_cng_dec.c | 166 +- lib_dec/ivas_binRenderer_internal.c | 158 +- lib_dec/ivas_dec.c | 137 +- lib_dec/ivas_dirac_dec.c | 1479 ++++++++++----- lib_dec/ivas_dirac_output_synthesis_cov.c | 109 +- lib_dec/ivas_dirac_output_synthesis_dec.c | 377 +++- lib_dec/ivas_init_dec.c | 78 + lib_dec/ivas_ism_dec.c | 130 +- lib_dec/ivas_ism_dtx_dec.c | 5 +- lib_dec/ivas_ism_param_dec.c | 675 ++++++- lib_dec/ivas_ism_renderer.c | 114 +- lib_dec/ivas_jbm_dec.c | 1716 ++++++++++++++++++ lib_dec/ivas_masa_dec.c | 293 ++- lib_dec/ivas_mc_param_dec.c | 622 ++++++- lib_dec/ivas_mct_dec.c | 143 +- lib_dec/ivas_objectRenderer_internal.c | 90 + lib_dec/ivas_out_setup_conversion.c | 26 +- lib_dec/ivas_sba_dec.c | 199 +- lib_dec/ivas_sba_rendering_internal.c | 109 +- lib_dec/ivas_spar_decoder.c | 510 +++++- lib_dec/ivas_spar_md_dec.c | 5 + lib_dec/ivas_stat_dec.h | 74 +- lib_dec/jbm_jb4sb.h | 8 + lib_dec/jbm_pcmdsp_apa.c | 209 ++- lib_dec/jbm_pcmdsp_apa.h | 12 + lib_dec/jbm_pcmdsp_fifo.c | 52 + lib_dec/jbm_pcmdsp_fifo.h | 3 + lib_dec/jbm_pcmdsp_similarityestimation.c | 42 + lib_dec/jbm_pcmdsp_similarityestimation.h | 46 +- lib_dec/jbm_pcmdsp_window.c | 17 +- lib_dec/jbm_pcmdsp_window.h | 5 +- lib_dec/lib_dec.c | 968 +++++++++- lib_dec/lib_dec.h | 39 + lib_rend/ivas_crend.c | 154 ++ lib_rend/ivas_dirac_dec_binaural_functions.c | 1178 +++++++++++- lib_rend/ivas_limiter.c | 4 + lib_rend/ivas_objectRenderer.c | 54 +- lib_rend/ivas_prot_rend.h | 84 +- lib_rend/ivas_reverb.c | 175 ++ lib_rend/ivas_rotation.c | 36 +- lib_rend/ivas_sba_rendering.c | 156 ++ lib_rend/lib_rend.c | 97 + lib_util/tinywaveout_c.h | 43 + lib_util/tsm_scale_file_reader.c | 148 ++ lib_util/tsm_scale_file_reader.h | 67 + scripts/batch_comp_audio.py | 13 +- scripts/config/ivas_modes.json | 210 +++ scripts/runIvasCodec.py | 15 + 69 files changed, 11810 insertions(+), 830 deletions(-) create mode 100644 lib_dec/ivas_jbm_dec.c create mode 100644 lib_util/tsm_scale_file_reader.c create mode 100644 lib_util/tsm_scale_file_reader.h diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 23aa2ae3f0..bfe36b1f48 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -78,7 +78,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks diff --git a/Workspace_msvc/lib_debug.vcxproj b/Workspace_msvc/lib_debug.vcxproj index 3b648fae04..9b7b580661 100644 --- a/Workspace_msvc/lib_debug.vcxproj +++ b/Workspace_msvc/lib_debug.vcxproj @@ -73,7 +73,7 @@ Disabled - ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_util;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) false diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index e1c0f9ead1..1a1b8c26cf 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -89,7 +89,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -282,6 +282,7 @@ + diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index 15f0d53574..92aa6de4ce 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -89,7 +89,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj index 865652649a..4bd0ca9a93 100644 --- a/Workspace_msvc/lib_rend.vcxproj +++ b/Workspace_msvc/lib_rend.vcxproj @@ -89,7 +89,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks diff --git a/Workspace_msvc/lib_util.vcxproj b/Workspace_msvc/lib_util.vcxproj index 5b5e5f30cc..72ff2dfe61 100644 --- a/Workspace_msvc/lib_util.vcxproj +++ b/Workspace_msvc/lib_util.vcxproj @@ -158,6 +158,7 @@ + @@ -183,6 +184,7 @@ + diff --git a/apps/decoder.c b/apps/decoder.c index 22dc235fff..4b09ce7d36 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -45,6 +45,9 @@ #include "vector3_pair_file_reader.h" #include "jbm_file_writer.h" #include "evs_rtp_payload.h" +#ifdef VARIABLE_SPEED_DECODING +#include "tsm_scale_file_reader.h" +#endif #ifdef DEBUGGING #include "debug.h" #endif @@ -76,6 +79,14 @@ static #define IVAS_PUBLIC_ORIENT_TRK_REF_VEC ( 3 ) #define IVAS_PUBLIC_ORIENT_TRK_REF_VEC_LEV ( 4 ) +#ifdef VARIABLE_SPEED_DECODING +#define VARIABLE_SPEED_FETCH_FRAMESIZE_MS 20 +#endif +#ifdef JBM_TSM_ON_TCS +#define JBM_FRONTEND_FETCH_FRAMESIZE_MS 5 +#define FRAME_SIZE_NS 20000000L +#endif + typedef struct { char *inputBitstreamFilename; @@ -116,6 +127,20 @@ typedef struct FILE *agcBitstream; /* temporary */ #endif +#endif +#ifdef DEBUG_JBM_CMD_OPTION + bool noBadFrameDelay; +#endif +#ifdef VARIABLE_SPEED_DECODING + bool variableSpeedMode; + bool tsmScaleFileEnabled; + char *tsmScaleFileName; + uint16_t tsmScale; +#endif +#ifdef JBM_TSM_ON_TCS +#ifdef DEBUG_JBM_CMD_OPTION + uint16_t frontendFetchSizeMs; +#endif #endif } DecArguments; @@ -129,6 +154,9 @@ 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, HeadRotFileReader *headRotReader, HeadRotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HANDLE hIvasDec ); +#ifdef VARIABLE_SPEED_DECODING +static ivas_error decodeVariableSpeed( DecArguments arg, BS_READER_HANDLE hBsReader, HeadRotFileReader *headRotReader, HeadRotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec ); +#endif #ifdef DEBUGGING static ivas_error printBitstreamInfoVoip( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HANDLE hIvasDec ); static int16_t app_own_random( int16_t *seed ); @@ -555,8 +583,15 @@ int main( if ( arg.voipMode ) { - +#ifdef JBM_TSM_ON_TCS + if ( ( error = IVAS_DEC_EnableVoIP( hIvasDec, IVAS_DEC_VOIP_MODE_VOIP, 100, 60, arg.inputFormat ) ) != IVAS_ERR_OK ) +#else +#ifdef VARIABLE_SPEED_DECODING + if ( ( error = IVAS_DEC_EnableVoIP( hIvasDec, IVAS_DEC_VOIP_MODE_VOIP, 100, 60, arg.inputFormat ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_EnableVoIP( hIvasDec, 60, arg.inputFormat ) ) != IVAS_ERR_OK ) +#endif +#endif { fprintf( stderr, "\nCould not enable VOIP: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -564,6 +599,17 @@ int main( error = decodeVoIP( arg, hBsReader, hIvasDec ); } +#ifdef VARIABLE_SPEED_DECODING + else if ( arg.variableSpeedMode ) + { + if ( ( error = IVAS_DEC_EnableVoIP( hIvasDec, IVAS_DEC_VOIP_MODE_VARIABLE_SPEED, arg.tsmScale, 60, arg.inputFormat ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nCould not enable Variable Play Speed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + error = decodeVariableSpeed( arg, hBsReader, headRotReader, refRotReader, referenceVectorReader, hIvasDec ); + } +#endif else { error = decodeG192( arg, hBsReader, headRotReader, refRotReader, referenceVectorReader, hIvasDec, pcmBuf ); @@ -788,6 +834,20 @@ static bool parseCmdlIVAS_dec( arg->inputFormat = IVAS_DEC_INPUT_FORMAT_G192; arg->no_diegetic_pan = 0.f; +#ifdef VARIABLE_SPEED_DECODING + arg->variableSpeedMode = 0; + arg->tsmScale = 100; + arg->tsmScaleFileEnabled = false; + arg->tsmScaleFileName = NULL; +#endif +#ifdef JBM_TSM_ON_TCS +#ifdef DEBUG_JBM_CMD_OPTION + arg->frontendFetchSizeMs = JBM_FRONTEND_FETCH_FRAMESIZE_MS; +#endif +#endif +#ifdef DEBUG_JBM_CMD_OPTION + arg->noBadFrameDelay = false; +#endif /*-----------------------------------------------------------------* * Initialization @@ -914,6 +974,62 @@ static bool parseCmdlIVAS_dec( #endif /* #ifdef DEBUG_MODE_INFO_TWEAK */ #endif /* #ifdef DEBUG_MODE_INFO */ #endif /* #ifdef DEBUGGING */ +#ifdef DEBUG_JBM_CMD_OPTION + else if ( strcmp( argv_to_upper, "-VOIP_NO_BAD_FRAME" ) == 0 ) + { + arg->noBadFrameDelay = true; + i++; + } +#endif +#ifdef VARIABLE_SPEED_DECODING + + else if ( strcmp( argv_to_upper, "-VS" ) == 0 ) + { + i++; + int tmp = 100; + arg->variableSpeedMode = true; + if ( i < argc - 3 ) + { + if ( !is_digits_only( argv[i] ) ) + { + arg->tsmScaleFileEnabled = true; + arg->tsmScaleFileName = argv[i]; + i++; + } + + else + { + if ( ( sscanf( argv[i], "%d", &tmp ) > 0 ) ) + { + i++; + } + } + arg->tsmScale = (uint16_t) tmp; + } + } +#endif +#ifdef JBM_TSM_ON_TCS +#ifdef DEBUG_JBM_CMD_OPTION + else if ( strcmp( argv_to_upper, "-VOIP_FRAMESIZE" ) == 0 ) + { + i++; + int tmp; + if ( i < argc - 3 ) + { + if ( !is_digits_only( argv[i] ) ) + { + return false; + } + + if ( sscanf( argv[i], "%d", &tmp ) > 0 ) + { + i++; + } + arg->frontendFetchSizeMs = (uint16_t) tmp; + } + } +#endif +#endif else if ( strcmp( argv_to_upper, "-MIME" ) == 0 ) { @@ -1166,6 +1282,18 @@ static void usage_dec( void ) fprintf( stdout, "-VOIP : VoIP mode: RTP in G192\n" ); fprintf( stdout, "-VOIP_hf_only=0 : VoIP mode: EVS RTP Payload Format hf_only=0 in rtpdump\n" ); fprintf( stdout, "-VOIP_hf_only=1 : VoIP mode: EVS RTP Payload Format hf_only=1 in rtpdump\n" ); +#ifdef DEBUG_JBM_CMD_OPTION + fprintf( stdout, "-VOIP_no_bad_frame : VoIP mode: do not put out bad frames in the beginning as silence \n" ); +#endif +#ifdef VARIABLE_SPEED_DECODING + fprintf( stdout, "-VS fac : Varaible Speed mode: change speed of playout fac as integer in percent. fac<100 faster, fac>100 slower\n" ); +#endif +#ifdef JBM_TSM_ON_TCS +#ifdef DEBUG_JBM_CMD_OPTION + fprintf( stdout, "-VOIP_framesize : VoIP mode: acoustic frontend fetch frame size (must be multiples of 5!)\n" ); +#endif + +#endif fprintf( stdout, " The decoder may read rtpdump files containing TS26.445 Annex A.2.2\n" ); fprintf( stdout, " EVS RTP Payload Format. The SDP parameter hf_only is required.\n" ); fprintf( stdout, " Reading RFC4867 AMR/AMR-WB RTP payload format is not supported.\n" ); @@ -1853,8 +1981,14 @@ static ivas_error decodeVoIP( uint32_t nextPacketRcvTime_ms = 0; uint32_t systemTime_ms = 0; +#ifdef JBM_TSM_ON_TCS + uint32_t systemTimeInc_ms = (uint32_t) JBM_FRONTEND_FETCH_FRAMESIZE_MS; + int32_t nFramesWritten = 0; + int32_t nFrontendFramesPerIvasFrame = 0; +#endif int32_t nFramesFed = 0; + uint8_t au[( IVAS_MAX_BITS_PER_FRAME + 7 ) >> 3]; int16_t auSize; uint16_t rtpSequenceNumber; @@ -1987,10 +2121,30 @@ static ivas_error decodeVoIP( * Main receiving/decoding loop *------------------------------------------------------------------------------------------*/ +#ifdef JBM_TSM_ON_TCS +#ifdef DEBUG_JBM_CMD_OPTION + nFrontendFramesPerIvasFrame = FRAME_SIZE_NS / ( 1000L * arg.frontendFetchSizeMs ); + systemTimeInc_ms = arg.frontendFetchSizeMs; +#else + nFrontendFramesPerIvasFrame = FRAME_SIZE_NS / ( 1000L * JBM_FRONTEND_FETCH_FRAMESIZE_MS ); +#endif +#endif + while ( 1 ) { int16_t nOutSamples = 0; - +#if defined( JBM_TSM_ON_TCS ) || defined( VARIABLE_SPEED_DECODING ) + uint16_t nSamplesAvailableNext = 0; +#endif +#ifdef JBM_TSM_ON_TCS +#ifdef DEBUG_JBM_CMD_OPTION + nOutSamples = (int16_t) ( arg.output_Fs / 1000 * arg.frontendFetchSizeMs ); +#else + nOutSamples = (int16_t) ( arg.output_Fs / 1000 * JBM_FRONTEND_FETCH_FRAMESIZE_MS ); +#endif +#else + nOutSamples = (int16_t) ( arg.output_Fs / 50 ); +#endif /* read all packets with a receive time smaller than the system time */ while ( nextPacketRcvTime_ms <= systemTime_ms ) { @@ -2034,15 +2188,24 @@ static ivas_error decodeVoIP( /* we are finished when all packets have been received and jitter buffer is empty */ /* also stop when the input file contains less than two frames, because JBM cannot calculate a delay value and won't start decoding */ +#ifdef JBM_TSM_ON_TCS + /* last clause should make sure that for BE tests we end up with the same number of samples...*/ + if ( nextPacketRcvTime_ms == (uint32_t) ( -1 ) && ( IVAS_DEC_VoIP_IsEmpty( hIvasDec, nOutSamples ) || nFramesFed < 2 || ( nFramesWritten % nFrontendFramesPerIvasFrame == 0 ) ) ) +#else if ( nextPacketRcvTime_ms == (uint32_t) ( -1 ) && ( IVAS_DEC_VoIP_IsEmpty( hIvasDec ) || nFramesFed < 2 ) ) +#endif { break; } - nOutSamples = (int16_t) ( arg.output_Fs / 50 ); /* decode and get samples */ - if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, pcmBuf, systemTime_ms + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, + pcmBuf, systemTime_ms +#if defined( JBM_TSM_ON_TCS ) || defined( VARIABLE_SPEED_DECODING ) + , + &nSamplesAvailableNext +#endif #ifdef SUPPORT_JBM_TRACEFILE , writeJbmTraceFileFrameWrapper, @@ -2104,7 +2267,11 @@ static ivas_error decodeVoIP( goto cleanup; } } +#ifdef DEBUG_JBM_CMD_OPTION + else if ( arg.noBadFrameDelay == false ) +#else else +#endif { ++numInitialBadFrames; } @@ -2135,7 +2302,12 @@ static ivas_error decodeVoIP( } frame++; +#ifdef JBM_TSM_ON_TCS + systemTime_ms += systemTimeInc_ms; + nFramesWritten++; +#else systemTime_ms += 20; +#endif #ifdef WMOPS update_mem(); @@ -2193,6 +2365,538 @@ cleanup: } +#ifdef VARIABLE_SPEED_DECODING +/*---------------------------------------------------------------------* + * decodeVariableSpeed() + * + * Read G.192 or decode with variable Speed + *---------------------------------------------------------------------*/ + +static ivas_error decodeVariableSpeed( + DecArguments arg, + BS_READER_HANDLE hBsReader, + HeadRotFileReader *headRotReader, + HeadRotFileReader *refRotReader, + Vector3PairFileReader *referenceVectorReader, + IVAS_DEC_HANDLE hIvasDec ) + +{ + bool decodingFailed = true; /* Assume failure until cleanup is reached without errors */ + uint16_t bit_stream[IVAS_MAX_BITS_PER_FRAME + 4 * 8]; + int16_t i, num_bits; + int16_t bfi = 0; +#ifdef DEBUGGING + int16_t fec_seed = 12558; /* FEC_SEED */ +#endif + AudioFileWriter *afWriter = NULL; + MasaFileWriter *masaWriter = NULL; + bool decodedGoodFrame = false; + int16_t numInitialBadFrames = 0; /* Number of bad frames received until first good frame is decoded */ + int16_t nOutChannels = 0; + int16_t delayNumSamples = -1; + int16_t delayNumSamples_orig = 0; + int16_t nOutSamples = 0; + int32_t delayTimeScale = 0; + ivas_error error = IVAS_ERR_UNKNOWN; + uint16_t numObj = 0; + IVAS_DEC_BS_FORMAT bsFormat = IVAS_DEC_BS_UNKOWN; + uint16_t nSamplesAvailableNext; + int16_t pcmBuf[MAX_OUTPUT_PCM_BUFFER_SIZE]; +#ifdef SUPPORT_JBM_TRACEFILE + JbmTraceFileWriter *jbmTraceWriter = NULL; +#endif + TsmScaleFileReader *tsmScaleFileReader = NULL; + IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS]; + IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + int16_t scale; + for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i ) + { + ismWriters[i] = NULL; + } + + /*------------------------------------------------------------------------------------------* + * Open TSM scale file + *------------------------------------------------------------------------------------------*/ + + if ( arg.tsmScaleFileEnabled ) + { + if ( ( tsmScaleFileReader = TsmScaleFileReader_open( arg.tsmScaleFileName ) ) == NULL ) + { + fprintf( stderr, "\nError: Can't open TSM scale file %s \n\n", arg.tsmScaleFileName ); + goto cleanup; + } + } + + if ( !arg.quietModeEnabled ) + { + fprintf( stdout, "\n------ Running the decoder ------\n\n" ); + fprintf( stdout, "Frames processed: " ); + } + else + { + fprintf( stdout, "\n-- Start the decoder (quiet mode) --\n\n" ); + } + +#ifdef WMOPS + reset_stack(); + reset_wmops(); +#endif + nSamplesAvailableNext = 0; + nOutSamples = (int16_t) ( arg.output_Fs / 1000 * VARIABLE_SPEED_FETCH_FRAMESIZE_MS ); + /*------------------------------------------------------------------------------------------* + * Loop for every packet (frame) of bitstream data + * - Read the bitstream packet + * - Run the decoder + * - Write the synthesized signal into output file + *------------------------------------------------------------------------------------------*/ + + while ( 1 ) + { + /* Read next frame if not enough samples availble */ + + /* reference vector */ + if ( arg.enableReferenceVectorTracking ) + { + 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 ) + { + 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 ), HeadRotationFileReader_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; + } + } + /* Head-tracking input simulation */ + if ( arg.enableHeadRotation ) + { + IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + + for ( i = 0; i < IVAS_MAX_PARAM_SPATIAL_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 ), HeadRotationFileReader_getFilePath( headRotReader ) ); + goto cleanup; + } + } + + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions, Pos ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + + /* decode and get samples */ + do + { + error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, + pcmBuf, 0, + &nSamplesAvailableNext +#ifdef SUPPORT_JBM_TRACEFILE + , + writeJbmTraceFileFrameWrapper, + jbmTraceWriter +#endif + ); + if ( error != IVAS_ERR_OK && error != IVAS_ERR_VS_FRAME_NEEDED ) + + { + fprintf( stderr, "\nError in IVAS_DEC_VoIP_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + if ( error == IVAS_ERR_VS_FRAME_NEEDED ) + { + if ( arg.tsmScaleFileEnabled ) + { + if ( ( error = TsmScaleFileReader_readScale( tsmScaleFileReader, &scale ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: input bitstream file couldn't be read: %s \n\n", arg.inputBitstreamFilename ); + goto cleanup; + } + IVAS_DEC_VoIP_SetScale( hIvasDec, scale ); + } + + if ( ( error = BS_Reader_ReadFrame_short( hBsReader, bit_stream, &num_bits, &bfi ) ) != IVAS_ERR_OK ) + { + if ( error == IVAS_ERR_END_OF_FILE ) + { + break; + } + fprintf( stderr, "\nError: input bitstream file couldn't be read: %s \n\n", arg.inputBitstreamFilename ); + goto cleanup; + } + +#ifdef DEBUGGING + /* Random FEC simulation */ + if ( arg.FER > 0.0f ) + { + float ftmp = (float) app_own_random( &fec_seed ) + 32768.0f; + if ( ftmp <= arg.FER / 100.0f * 65535.0f ) + { + bfi = 1; + } + else + { + bfi = 0; + } + } +#endif + + /* Feed into decoder */ + if ( ( error = IVAS_DEC_FeedFrame_Serial( hIvasDec, bit_stream, num_bits, bfi ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: could not feed frame to decoder: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + error = IVAS_ERR_VS_FRAME_NEEDED; + } + } while ( error != IVAS_ERR_OK ); + + if ( error == IVAS_ERR_END_OF_FILE ) + { + break; + } + + /* Continue checking for first good frame until it is found */ + if ( !decodedGoodFrame ) + { + if ( ( error = IVAS_DEC_HasDecodedFirstGoodFrame( hIvasDec, &decodedGoodFrame ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_HasDecodedFirstGoodFrame, code: %d\n", error ); + goto cleanup; + } + + /* Once good frame decoded, catch up */ + if ( decodedGoodFrame ) + { + error = initOnFirstGoodFrame( + hIvasDec, + arg, + numInitialBadFrames, + nOutSamples, + &delayNumSamples_orig, + &delayNumSamples, + &delayTimeScale, + &bsFormat, + &afWriter, + &masaWriter, + ismWriters, + &nOutChannels, + &numObj ); + if ( error != IVAS_ERR_OK ) + { + goto cleanup; + } + } + else + { + ++numInitialBadFrames; + } + } + + + /* Write current frame */ + if ( decodedGoodFrame ) + { + if ( delayNumSamples < nOutSamples ) + { + if ( ( error = AudioFileWriter_write( afWriter, &pcmBuf[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + goto cleanup; + } + delayNumSamples = 0; + } + else + { + delayNumSamples -= nOutSamples; + } + } + + /* Write ISm metadata to external file(s) */ + if ( decodedGoodFrame && arg.outputFormat == IVAS_DEC_OUTPUT_EXT ) + { + if ( bsFormat == IVAS_DEC_BS_OBJ ) + { + if ( ( error = IVAS_DEC_GetNumObjects( hIvasDec, &numObj ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetNumObjects: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + for ( i = 0; i < numObj; ++i ) + { + IVAS_ISM_METADATA IsmMetadata; + + if ( ( error = IVAS_DEC_GetObjectMetadata( hIvasDec, &IsmMetadata, 0, i ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetObjectMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + if ( ( IsmFileWriter_writeFrame( IsmMetadata, ismWriters[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError writing ISM metadata to file %s\n", IsmFileWriter_getFilePath( ismWriters[i] ) ); + goto cleanup; + } + } + } + else if ( bsFormat == IVAS_DEC_BS_MASA ) + { + MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta; + if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + if ( ( error = MasaFileWriter_writeFrame( masaWriter, hMasaExtOutMeta ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError writing MASA metadata to file: %s\n", MasaFileWriter_getFilePath( masaWriter ) ); + goto cleanup; + } + } + } + + frame++; + if ( !arg.quietModeEnabled ) + { + fprintf( stdout, "%-8d\b\b\b\b\b\b\b\b", frame ); +#ifdef DEBUGGING + if ( IVAS_DEC_GetBerDetectFlag( hIvasDec ) ) + { + fprintf( stdout, "\n Decoding error: BER detected in frame %d !!!!!\n", frame - 1 ); + } +#endif + } +#ifdef WMOPS + update_wmops(); +#ifdef MEM_COUNT_DETAILS + export_mem( "mem_analysis.csv" ); +#endif +#endif + } + + + /*------------------------------------------------------------------------------------------* + * Flush what is still left in the VoIP Buffers.... + *------------------------------------------------------------------------------------------*/ + while ( nSamplesAvailableNext > 0 ) + { + int16_t nSamplesFlushed; + + /* Feed into decoder */ + + /* reference vector */ + if ( arg.enableReferenceVectorTracking ) + { + 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 ) + { + 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 ), HeadRotationFileReader_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; + } + } + /* Head-tracking input simulation */ + if ( arg.enableHeadRotation ) + { + IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + + for ( i = 0; i < IVAS_MAX_PARAM_SPATIAL_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 ), HeadRotationFileReader_getFilePath( headRotReader ) ); + goto cleanup; + } + } + + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions, Pos ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + } + + /* decode and get samples */ + if ( ( error = IVAS_DEC_VoIP_Flush( hIvasDec, nOutSamples, + pcmBuf, + &nSamplesAvailableNext, + &nSamplesFlushed ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_VoIP_Flush: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + + /* Write current frame */ + + if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, nSamplesFlushed * nOutChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + goto cleanup; + } + + + /* Write ISm metadata to external file(s) */ + if ( decodedGoodFrame && arg.outputFormat == IVAS_DEC_OUTPUT_EXT ) + { + if ( bsFormat == IVAS_DEC_BS_OBJ ) + { + if ( ( error = IVAS_DEC_GetNumObjects( hIvasDec, &numObj ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetNumObjects: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + for ( i = 0; i < numObj; ++i ) + { + IVAS_ISM_METADATA IsmMetadata; + + if ( ( error = IVAS_DEC_GetObjectMetadata( hIvasDec, &IsmMetadata, 0, i ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetObjectMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + if ( ( IsmFileWriter_writeFrame( IsmMetadata, ismWriters[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError writing ISM metadata to file %s\n", IsmFileWriter_getFilePath( ismWriters[i] ) ); + goto cleanup; + } + } + } + else if ( bsFormat == IVAS_DEC_BS_MASA ) + { + MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta; + if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + if ( ( error = MasaFileWriter_writeFrame( masaWriter, hMasaExtOutMeta ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError writing MASA metadata to file: %s\n", MasaFileWriter_getFilePath( masaWriter ) ); + goto cleanup; + } + } + } + + frame++; + if ( !arg.quietModeEnabled ) + { + fprintf( stdout, "%-8d\b\b\b\b\b\b\b\b", frame ); +#ifdef DEBUGGING + if ( IVAS_DEC_GetBerDetectFlag( hIvasDec ) ) + { + fprintf( stdout, "\n Decoding error: BER detected in frame %d !!!!!\n", frame - 1 ); + } +#endif + } + } + /*------------------------------------------------------------------------------------------* + * Printouts after decoding has finished + *------------------------------------------------------------------------------------------*/ + + if ( !arg.quietModeEnabled ) + { + fprintf( stdout, "\nDecoder delay: %-5u [samples] - Timescale: %5u\n", delayNumSamples_orig, delayTimeScale ); + } + + /* Print output metadata file name(s) */ + if ( arg.outputFormat == IVAS_DEC_OUTPUT_EXT ) + { + if ( bsFormat == IVAS_DEC_BS_OBJ ) + { + for ( i = 0; i < numObj; i++ ) + { + fprintf( stdout, "\nOutput metadata file: %s", IsmFileWriter_getFilePath( ismWriters[i] ) ); + } + fprintf( stdout, "\n" ); + } + else if ( bsFormat == IVAS_DEC_BS_MASA ) + { + fprintf( stdout, "\nOutput metadata file: %s\n", MasaFileWriter_getFilePath( masaWriter ) ); + } + } + + /* add zeros at the end to have equal length of synthesized signals */ + memset( pcmBuf, 0, delayNumSamples_orig * nOutChannels * sizeof( int16_t ) ); + if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig * nOutChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) ); + goto cleanup; + } + + /*------------------------------------------------------------------------------------------* + * Close files and deallocate resources + *------------------------------------------------------------------------------------------*/ + + decodingFailed = false; /* This will stay set to true if cleanup is reached via a goto due to an error */ + +cleanup: + + AudioFileWriter_close( &afWriter ); + MasaFileWriter_close( &masaWriter ); + for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; i++ ) + { + IsmFileWriter_close( &ismWriters[i] ); + } + + if ( decodingFailed && error == IVAS_ERR_OK ) + { + return IVAS_ERR_UNKNOWN; + } + + return error; +} + +#endif + #ifdef DEBUGGING /*---------------------------------------------------------------------* * parseForcedRendModeDec() diff --git a/lib_com/fd_cng_com.c b/lib_com/fd_cng_com.c index f2dbf746b6..6cb2e014ba 100644 --- a/lib_com/fd_cng_com.c +++ b/lib_com/fd_cng_com.c @@ -940,6 +940,74 @@ void SynthesisSTFT( return; } +#ifdef JBM_TSM_ON_TCS +/*------------------------------------------------------------------- + * SynthesisSTFT_dirac() + * + * STFT synthesis filterbank + *-------------------------------------------------------------------*/ + +void SynthesisSTFT_dirac( + float *fftBuffer, /* i : FFT bins */ + float *timeDomainOutput, + float *olapBuffer, + const float *olapWin, + const int16_t samples_out, + HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ +) +{ + int16_t i; + float buf[M + 1 + 320], tmp; + + /* Perform IFFT */ + RFFTN( fftBuffer, hFdCngCom->fftSineTab, hFdCngCom->fftlen, 1 ); + + /* Handle overlap in P/S domain for stereo */ + mvr2r( olapBuffer + hFdCngCom->frameSize, olapBuffer, hFdCngCom->frameSize ); + set_f( olapBuffer + hFdCngCom->frameSize, 0.0f, hFdCngCom->frameSize ); /*olapBuffer, fftBuffer, olapWin*/ + + + for ( i = hFdCngCom->frameSize / 4; i < 3 * hFdCngCom->frameSize / 4; i++ ) + { + olapBuffer[i] += fftBuffer[i] * olapWin[i - hFdCngCom->frameSize / 4]; + } + for ( ; i < 5 * hFdCngCom->frameSize / 4; i++ ) + { + olapBuffer[i] = fftBuffer[i]; + } + + for ( ; i < 7 * hFdCngCom->frameSize / 4; i++ ) + { + olapBuffer[i] = fftBuffer[i]; + } + + for ( ; i < hFdCngCom->fftlen; i++ ) + { + olapBuffer[i] = 0; + } + + /* Get time-domain signal */ + v_multc( olapBuffer + hFdCngCom->frameSize / 4, (float) ( hFdCngCom->fftlen / 2 ), timeDomainOutput, samples_out ); + + /* Get excitation */ + v_multc( olapBuffer + hFdCngCom->frameSize / 4 - ( M + 1 ), (float) ( hFdCngCom->fftlen / 2 ), buf, M + 1 + hFdCngCom->frameSize ); + tmp = buf[0]; + preemph( buf + 1, PREEMPH_FAC, M + hFdCngCom->frameSize, &tmp ); + residu( hFdCngCom->A_cng, M, buf + 1 + M, hFdCngCom->exc_cng, hFdCngCom->frameSize ); + + /* update and window olapBuf if we have a output frame that is shorter than the default frame size...*/ + if ( samples_out < hFdCngCom->frameSize ) + { + mvr2r( olapBuffer + samples_out, olapBuffer + hFdCngCom->frameSize, 3 * hFdCngCom->frameSize / 4 ); + } + for ( i = 5 * hFdCngCom->frameSize / 4; i < 7 * hFdCngCom->frameSize / 4; i++ ) + { + olapBuffer[i] *= olapWin[i - 3 * hFdCngCom->frameSize / 4]; + } + + return; +} +#endif /*------------------------------------------------------------------- * mhvals() diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index ec806148b2..496f1fd86c 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -192,6 +192,25 @@ typedef enum #define IVAS_NUM_SUPPORTED_FS 3 /* number of supported sampling-rates in IVAS */ +#ifdef JBM_TSM_ON_TCS +#define CLDFB_SLOT_NS 1250000L /* 1.25ms: CLDFB slot length */ +#define MAX_JBM_SUBFRAMES_5MS 8 +#define DEFAULT_JBM_SUBFRAMES_5MS 4 +#define JBM_CLDFB_SLOTS_IN_SUBFRAME 4 +#define MAX_JBM_CLDFB_TIMESLOTS 32 +#define DEFAULT_JBM_CLDFB_TIMESLOTS 16 +#define MAX_JBM_L_FRAME48k 1920 +#define MAX_JBM_L_FRAME_NS 40000000L +#define MAX_SPAR_INTERNAL_CHANNELS FOA_CHANNELS + 2* ( IVAS_MAX_SBA_ORDER -1 ) +#define MAX_CLDFB_DIGEST_CHANNELS 4 +typedef enum +{ + TC_BUFFER_MODE_NONE = 0, + TC_BUFFER_MODE_RENDERER, + TC_BUFFER_MODE_BUFFER +} TC_BUFFER_MODE; +#endif + /*----------------------------------------------------------------------------------* * IVAS Bitrates *----------------------------------------------------------------------------------*/ @@ -1280,7 +1299,11 @@ typedef enum #define PARAM_MC_REG_GHAT (0.001f) /* Regularization factor for mixing matrix calculation */ #define PARAM_MC_MAX_PARAMETER_BANDS 20 /* Maximum number of parameter bands */ #define PARAM_MC_MAX_PARAMETER_BANDS_RES 14 /* Maximum number of parameter bands with decorrelation */ +#ifdef JBM_TSM_ON_TCS +#define PARAM_MC_MAX_NSLOTS MAX_JBM_CLDFB_TIMESLOTS /* Maximum number of CLDFB slots in a frame */ +#else #define PARAM_MC_MAX_NSLOTS 16 /* Maximum number of CLDFB slots in a frame */ +#endif #define PARAM_MC_MAX_NSLOTS_IN_SUBFRAME 4 /* Maximum number of CLDFB slots in a subframe */ #define PARAM_MC_NSUBFRAMES_DEC 4 /* Number of subframes for the synthesis in the decoder */ #define PARAM_MC_MAX_BANDS_IN_PARAMETER_BAND 30 /* Maximum number of CLDFB frequency bands within a parameter band */ diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h index 9438ad44a1..ce51109207 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -87,6 +87,9 @@ typedef enum IVAS_ERR_ISM_INVALID_METADATA_VALUE, IVAS_ERR_INVALID_MASA_FORMAT_METADATA_FILE, IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED, +#ifdef VARIABLE_SPEED_DECODING + IVAS_ERR_VS_FRAME_NEEDED, +#endif #ifdef DEBUGGING IVAS_ERR_INVALID_FORCE_MODE, #ifdef DEBUG_AGC_ENCODER_CMD_OPTION diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 41d406ed1f..9869218a23 100755 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -251,12 +251,25 @@ ivas_error ivas_compute_core_buffers( /*! r: number of clipped samples */ uint32_t ivas_syn_output( - float synth[][L_FRAME48k], /* i/o: float synthesis signal */ +#ifdef JBM_TSM_ON_TCS + float *synth[], /* i/o: float synthesis signal */ +#else + float synth[][L_FRAME48k], /* i/o: float synthesis signal */ +#endif const int16_t output_frame, /* i : output frame length (one channel) */ const int16_t n_channels, /* i : number of output channels */ int16_t *synth_out /* o : integer 16 bits synthesis signal */ ); +#ifdef JBM_TSM_ON_TCS +void ivas_syn_output_f( + float *synth[], /* i/o: float synthesis signal */ + const int16_t output_frame, /* i : output frame length (one channel) */ + const int16_t n_channels, /* i : number of output channels */ + float *synth_out /* o : integer 16 bits synthesis signal */ + ); +#endif + void ivas_initialize_handles_enc( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ); @@ -299,6 +312,11 @@ ivas_error ivas_dec( ivas_error ivas_dec_setup( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ + #ifdef JBM_TSM_ON_TCS + , + uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ + int16_t *data /* o : flushed PCM samples */ +#endif ); ivas_error create_sce_dec( @@ -637,6 +655,11 @@ ivas_error ivas_mc_enc_config( ivas_error ivas_mc_dec_config( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const int16_t idx /* i : LS config. index */ + #ifdef JBM_TSM_ON_TCS + , + uint16_t *nSamplesRendered, /* o : samples flushed from last frame (JBM) */ + int16_t *data /* o : flushed samples (JBM) */ +#endif ); /*! r: MC format mode (MCT, McMASA, ParamMC) */ @@ -736,6 +759,104 @@ void dtx_read_padding_bits( const int16_t num_bits ); +#ifdef JBM_TSM_ON_TCS +/*----------------------------------------------------------------------------------* + * JBM prototypes + *----------------------------------------------------------------------------------*/ + +ivas_error ivas_jbm_dec_tc( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *data /* o : output synthesis signal */ +); + +ivas_error ivas_jbm_dec_render( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const uint16_t nSamplesAsked, /* i : number of samples wanted */ + uint16_t *nSamplesRendered, /* o : number of samples rendered */ + uint16_t *nSamplesAvailableNext, /* o : number of samples still available in the rendering pipeline */ + int16_t *data /* o : output synthesis signal */ +); + +ivas_error ivas_jbm_dec_flush_renderer( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const int16_t tc_granularity_new, /* i : new renderer granularity */ + const RENDERER_TYPE renderer_type_old, /* i : old renderer type */ + const AUDIO_CONFIG intern_config_old, /* i : old internal config */ + const IVAS_OUTPUT_SETUP_HANDLE hIntSetupOld, /* i : old internal output setup */ + const MC_MODE mc_mode_old, /* i : old MC mode */ + const ISM_MODE ism_mode_old, /* i : old ISM mode */ + uint16_t *nSamplesRendered, /* o : number of samples flushed */ + int16_t *data /* o : rendered samples */ +); + +ivas_error ivas_jbm_dec_feed_tc_to_renderer( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const int16_t nSamplesForRendering, /* i: : number of TC samples available for rendering */ + int16_t *nSamplesResidual, /* o: : number of samples not fitting into the renderer grid and buffer for the next call*/ + float *data /* i/o: transport channels/output synthesis signal */ +); + +ivas_error ivas_jbm_dec_set_discard_samples( + Decoder_Struct *st_ivas /* i/o: main IVAS decoder structre */ +); + +void ivas_jbm_dec_get_adapted_linear_interpolator( + const int16_t default_interp_length, /* i : default length of the (full-frame) interpolator */ + const int16_t interp_length, /* i : length of the interpolator to be created */ + float *interpolator /* o : the interpolator */ +); + +void ivas_jbm_dec_get_adapted_subframes( + const int16_t nCldfbTs, /* i : number of time slots in the current frame */ + int16_t *subframe_nbslots, /* i/o: subframe grid */ + int16_t *nb_subframes /* i/o: number of subframes in the frame */ +); + +void ivas_jbm_dec_get_md_map( + const int16_t default_len, /* i : default frame length in metadata slots */ + const int16_t len, /* i : length of the modfied frames in metadata slots */ + const int16_t subframe_len, /* i : default length of a subframe */ + const int16_t offset, /* i : current read offset into the md buffer */ + const int16_t buf_len, /* i : length of the metadata buffer */ + int16_t *map /* o : metadata index map */ +); + +int16_t ivas_jbm_dec_get_num_tc_channels( Decoder_Struct *st_ivas ); /* i : IVAS decoder handle */ + +TC_BUFFER_MODE ivas_jbm_dec_get_tc_buffer_mode( + Decoder_Struct *st_ivas /* i : IVAS decoder handle */ +); + +int16_t ivas_jbm_dec_get_render_granularity( /* o : render granularity */ + const RENDERER_TYPE rendererType, /* i : renderer type */ + const int32_t output_Fs /* i : sampling rate */ +); + +ivas_error ivas_jbm_dec_tc_buffer_open( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const TC_BUFFER_MODE tc_buffer_mode, /* i : buffer mode */ + const int16_t nchan_transport_jbm, /* i : number of real transport channels */ + const int16_t nchan_transport_internal, /* i : number of totally buffered channels */ + const int16_t nchan_full, /* i : nubmer of channels to fully store */ + const int16_t n_samples_granularity /* i : granularity of the renderer/buffer */ +); + +ivas_error ivas_jbm_dec_tc_buffer_reconfigure( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const TC_BUFFER_MODE tc_buffer_mode, /* i : new buffer mode */ + const int16_t nchan_transport_jbm, /* i : new number of real transport channels */ + const int16_t nchan_transport_internal, /* i : new number of totally buffered channels */ + const int16_t nchan_full, /* i : new number of channels to fully store */ + const int16_t n_samples_granularity /* i : new granularity of the renderer/buffer */ +); + +void ivas_jbm_dec_tc_buffer_close( + DECODER_TC_BUFFER_HANDLE *phTcBuffer /* i/o: TC buffer handle */ +); +void ivas_jbm_dec_td_renderers_adapt_subframes( + Decoder_Struct *st_ivas +); +#endif /*----------------------------------------------------------------------------------* * ISM prototypes @@ -887,6 +1008,11 @@ ivas_error ivas_ism_dec_config( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ , const ISM_MODE last_ism_mode /* i/o: last ISM mode */ +#ifdef JBM_TSM_ON_TCS + , + uint16_t *nSamplesRendered, /* o : number of samples flushed on renderer change */ + int16_t *data /* o : flushed PCM samples */ +#endif ); ivas_error ivas_param_ism_dec_open( @@ -903,6 +1029,26 @@ void ivas_param_ism_dec( float output_f[][L_FRAME48k] /* i/o: synthesized core-coder transport channels/DirAC output */ ); +#ifdef JBM_TSM_ON_TCS +void ivas_ism_dec_digest_tc( + Decoder_Struct *st_ivas +); + +void ivas_param_ism_dec_digest_tc( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint16_t nCldfbSlots, /* i : number of CLFBS slots in the transport channels */ + float *transport_channels_f[] /* i : synthesized core-coder transport channels/DirAC output */ +); + +void ivas_param_ism_dec_render( + 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 *nSamplesAvailable, /* o : number of CLDFB slots still to render */ + float *output_f[] /* o : rendered time signal */ +); +#endif + void ivas_param_ism_params_to_masa_param_mapping( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); @@ -2622,7 +2768,11 @@ float sumAbs( void mvc2c( const uint8_t x[], /* i : input vector */ uint8_t y[], /* o : output vector */ +#ifdef FIX_XXX_JBM_FIFO_BUFFER + const int32_t n +#else const int16_t n /* i : vector size */ +#endif ); /*! r: the dot product x'*A*A'*x */ @@ -3185,6 +3335,16 @@ ivas_error ivas_sba_dec_reconfigure( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); +#ifdef JBM_TSM_ON_TCS +ivas_error ivas_sba_digest_tc( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const int16_t nchan_transport, /* i : number of transport channels */ + const int16_t nCldfbSlots, /* i : number of CLDFB slots */ + const int16_t nSamplesForRendering, /* i : number of samples provided */ + float *data[] /* i : transport channel samples */ + ); +#endif + void ivas_init_dec_get_num_cldfb_instances( Decoder_Struct *st_ivas, /* i : IVAS decoder structure */ int16_t *numCldfbAnalyses, /* o : number of CLDFB analysis instances */ @@ -3274,6 +3434,9 @@ void ivas_sba2mc_cldfb( float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: cldfb imag part */ const int16_t nb_channels_out, /* i : nb of output channels */ const int16_t nb_bands, /* i : nb of CLDFB bands to process */ +#ifdef JBM_TSM_ON_TCS + const int16_t nb_timeslots, /* i : number of time slots to process */ +#endif const float *hoa_dec_mtx /* i : HOA decoding mtx */ ); @@ -3356,13 +3519,54 @@ void ivas_dirac_dec_read_BS( int16_t *dirac_to_spar_md_bands /* o : DirAC->SPAR MD bands */ ); +#ifdef JBM_TSM_ON_TCS +void generate_masking_noise_lb_dirac( + HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ + float *tdBuffer, /* i/o: time-domain signal, if NULL no LB-CNA */ + const int16_t nCldfbTs, /* i : number of CLDFB slots that will be rendered */ + const int16_t cna_flag /* i : CNA flag for LB and HB */ +); + +void ivas_dirac_dec_set_md_map( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + int16_t nCldfbTs ); + void ivas_dirac_dec( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ + const int16_t nchan_transport /* i : number of transport channels */ +); +#endif + +#ifdef JBM_TSM_ON_TCS +void ivas_dirac_dec_render( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const int16_t nchan_transport, /* i : number of transport channels */ + const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ + uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ + uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ + float *output_f[] /* o : rendered time signal */ +); +#endif + +#ifndef JBM_TSM_ON_TCS +void ivas_dirac_dec( +#else +void ivas_dirac_dec_render_sf( +#endif Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ +#ifdef JBM_TSM_ON_TCS + float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ +#else + float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ +#endif const int16_t nchan_transport, /* i : number of transport channels */ float *pppQMfFrame_ts_re[IVAS_MAX_FB_MIXER_IN_CH][CLDFB_NO_COL_MAX], - float *pppQMfFrame_ts_im[IVAS_MAX_FB_MIXER_IN_CH][CLDFB_NO_COL_MAX], + float *pppQMfFrame_ts_im[IVAS_MAX_FB_MIXER_IN_CH][CLDFB_NO_COL_MAX] +#ifndef JBM_TSM_ON_TCS + , const int16_t i_sf +#endif ); ivas_error ivas_dirac_dec_init_binaural_data( @@ -3462,13 +3666,26 @@ void ivas_dirac_dec_output_synthesis_close( ); void ivas_dirac_dec_output_synthesis_process_slot( - const float *reference_power, /* i : Estimated power */ - const float *onset, /* i : onset filter */ - DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */ - const float *p_Rmat, /* i : rotation matrix */ - const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ - const IVAS_OUTPUT_SETUP hOutSetup, /* i : output setup structure */ - const int16_t nchan_transport /* i : number of transport channels */ + const float *reference_power, /* i : Estimated power */ + const float *onset, /* i : onset filter */ +#ifdef JBM_TSM_ON_TCS + const int16_t *azimuth, + const int16_t *elevation, + const float *diffuseness, + const uint16_t coherence_flag, +#endif + DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */ +#ifdef JBM_TSM_ON_TCS + MASA_DECODER_HANDLE hMasa, + const int16_t sh_rot_max_order, +#endif + const float *p_Rmat, /* i : rotation matrix */ + const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ + const IVAS_OUTPUT_SETUP hOutSetup, /* i : output setup structure */ + const int16_t nchan_transport /* i : number of transport channels */ +#ifdef JBM_TSM_ON_TCS + ,const int16_t index_slot /* i : absolute slot index in the frame to process */ +#endif ); void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( @@ -3476,13 +3693,20 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */ DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */ const int16_t nchan_transport, /* i : number of transport channels */ +#ifdef JBM_TSM_ON_TCS + const int16_t nbslots, /* i : number of slots to process */ +#endif const float *onset_filter ); void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( - float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */ - float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */ - DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */ + float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */ + float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */ + DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */ +#ifdef JBM_TSM_ON_TCS + const int16_t nbslots, /* i : number of slots to process */ + const int16_t diff_md_idx, /* i : md slot idx of diffuseness to use */ +#endif float *reference_power_smooth, float qualityBasedSmFactor ); @@ -3521,9 +3745,14 @@ void ivas_dirac_dec_compute_directional_responses( DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */ const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ const MASA_DECODER_HANDLE hMasa, /* i : MASA decoder structure */ +#ifdef JBM_TSM_ON_TCS + const int16_t *azimuth, + const int16_t *elevation, + const int16_t md_idx, +#endif 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 shd_rot_max_order, /* i : split-order rotation method */ + const float *p_Rmat /* i : rotation matrix */ ); void ivas_dirac_dec_get_frequency_axis( @@ -3598,9 +3827,29 @@ void ivas_param_mc_dec_read_BS( int16_t *nb_bits /* o : number of bits written */ ); +#ifdef JBM_TSM_ON_TCS +void ivas_param_mc_dec_digest_tc( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint8_t nCldfbSlots, /* i : number of CLFBS slots in the transport channels */ + float *transport_channels_f[] /* i : synthesized core-coder transport channels/DirAC output */ +); + +void ivas_param_mc_dec_render( + 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 *nSamplesAvailable, /* o : number of CLDFB slots still to render */ + float *output_f[] /* o : rendered time signal */ +); +#endif + void ivas_param_mc_dec( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - float output_f[][L_FRAME48k] /* i/o: synthesized core-coder transport channels/DirAC output */ +#ifdef JBM_TSM_ON_TCS + float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ +#else + float output_f[][L_FRAME48k] /* i/o: synthesized core-coder transport channels/DirAC output */ +#endif ); void ivas_param_mc_default_icc_map( @@ -3731,6 +3980,12 @@ ivas_error ivas_dirac_dec_output_synthesis_cov_open( const float *proto_matrix /* i : the prototype (upmix) matrix (only used if mode == 1) */ ); +#ifdef JBM_TSM_ON_TCS +void ivas_dirac_dec_output_synthesis_get_interpolator( + DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params, /* i/o: handle for the covariance synthesis parameters */ + const uint16_t interp_length ); +#endif + void ivas_dirac_dec_output_synthesis_cov_init( DIRAC_OUTPUT_SYNTHESIS_COV_STATE *h_dirac_output_synthesis_state, /* i/o: pointer to the state of the covariance synthesis */ const int16_t nchan_in, /* i : number of input (tranport) channels */ @@ -3745,27 +4000,45 @@ void ivas_dirac_dec_output_synthesis_cov_close( ); void ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot( - float RealBuffer[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS][CLDFB_NO_CHANNELS_MAX], /* i : input channel filter bank samples (real part) */ - float ImagBuffer[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS][CLDFB_NO_CHANNELS_MAX], /* i : input channel filter bank samples (imaginary part */ - float cx[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], /* o : accumulated input covariance (real part) */ - float cx_imag[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], /* o : accumulated input covariance (imaginary part) */ - PARAM_MC_DEC_HANDLE hParamMC, /* i : handle to Parametric MC state */ - const int16_t nchan_in, /* i : number of input channels */ - const int16_t idx_slot /* i : index of the slot to be added to the input covariance */ -); - +#ifdef JBM_TSM_ON_TCS + float *RealBuffer, /* i : input channel filter bank samples (real part) */ + float *ImagBuffer, /* i : input channel filter bank samples (imaginary part */ +#else + float RealBuffer[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS][CLDFB_NO_CHANNELS_MAX], /* i : input channel filter bank samples (real part) */ + float ImagBuffer[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS][CLDFB_NO_CHANNELS_MAX], /* i : input channel filter bank samples (imaginary part */ +#endif + float cx[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], /* o : accumulated input covariance (real part) */ + float cx_imag[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], /* o : accumulated input covariance (imaginary part) */ + PARAM_MC_DEC_HANDLE hParamMC, /* i : handle to Parametric MC state */ + const int16_t nchan_in /* i : number of input channels */ +#ifndef JBM_TSM_ON_TCS + , + const int16_t idx_slot /* i : index of the slot to be added to the input covariance */ +#endif +); + void ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot( - float Cldfb_RealBuffer_in[][PARAM_MC_MAX_NSLOTS][CLDFB_NO_CHANNELS_MAX], /* i : input channel filter bank samples (real part) */ - float Cldfb_ImagBuffer_in[][PARAM_MC_MAX_NSLOTS][CLDFB_NO_CHANNELS_MAX], /* i : input channel filter bank samples (imaginary part) */ - float Cldfb_RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : output channel filter bank samples (real part) */ - float Cldfb_ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : output channel filter bank samples (imaginary part) */ - float mixing_matrix[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS], /* i : parameter band wise mixing matrices (direct part) */ - float mixing_matrix_res[PARAM_MC_MAX_PARAMETER_BANDS_RES][MAX_CICP_CHANNELS * MAX_CICP_CHANNELS], /* i : parameter band wise mixing matrices (residual part) */ - const uint16_t slot_idx_sfr, /* i : time slot index for the current slot within the current subframe */ - const uint16_t slot_idx_tot, /* i : time slot index for the current slot within the frame */ - const int16_t nX, /* i : number of input channels */ - const int16_t nY, /* i : number of output channels */ - PARAM_MC_DEC_HANDLE hMetadataPMC /* i : handle to the Parametric MC decoder state */ +#ifdef JBM_TSM_ON_TCS + float *Cldfb_RealBuffer_in, /* i : input channel filter bank samples (real part) */ + float *Cldfb_ImagBuffer_in, /* i : input channel filter bank samples (imaginary part) */ +#else + float Cldfb_RealBuffer_in[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_NSLOTS][CLDFB_NO_CHANNELS_MAX], /* i : CLDFB samples of the transport channels (real part) */ + float Cldfb_ImagBuffer_in[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_NSLOTS][CLDFB_NO_CHANNELS_MAX], /* i : CLDFB samples of the transport channels (imaginary part) */ +#endif + float Cldfb_RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : output channel filter bank samples (real part) */ + float Cldfb_ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : output channel filter bank samples (imaginary part) */ +#ifdef JBM_TSM_ON_TCS + float *mixing_matrix[], /* i : parameter band wise mixing matrices (direct part) */ + float *mixing_matrix_res[], /* i : parameter band wise mixing matrices (residual part) */ +#else + float mixing_matrix[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS], /* i : parameter band wise mixing matrices (direct part) */ + float mixing_matrix_res[PARAM_MC_MAX_PARAMETER_BANDS_RES][MAX_CICP_CHANNELS * MAX_CICP_CHANNELS], /* i : parameter band wise mixing matrices (residual part) */ +#endif + const uint16_t slot_idx_sfr, /* i : time slot index for the current slot within the current subframe */ + const uint16_t slot_idx_tot, /* i : time slot index for the current slot within the frame */ + const int16_t nX, /* i : number of input channels */ + const int16_t nY, /* i : number of output channels */ + PARAM_MC_DEC_HANDLE hParamMC /* i : handle to the Parametric MC decoder state */ ); int16_t computeMixingMatricesISM( @@ -3849,7 +4122,11 @@ void ivas_sba_upmixer_renderer( ); ivas_error ivas_sba_linear_renderer( +#ifdef JBM_TSM_ON_TCS + float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ +#else float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ +#endif const int16_t output_frame, /* i : output frame length per channel */ const int16_t nchan_in, /* i : number of input ambisonics channels */ const AUDIO_CONFIG output_config, /* i : output audio configuration */ @@ -3865,6 +4142,14 @@ void ivas_sba_mix_matrix_determiner( const int16_t output_frame /* i : output frame length */ ); +#ifdef JBM_TSM_ON_TCS +void ivas_sba_prototype_renderer_sf( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ + float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */ + float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /* i : Input audio in CLDFB domain, imag */ +); +#endif + /* AGC */ /*! r: AGC enable flag */ int16_t ivas_agc_enc_get_flag( @@ -4021,6 +4306,51 @@ int16_t ivas_is_res_channel( const int16_t nchan_transport /* i : number of transport channels (1-4) */ ); +#ifdef JBM_TSM_ON_TCS +void ivas_spar_dec_agc_pca( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + float output[][L_FRAME48k], /* i/o: input/output audio channels */ + const int16_t output_frame /* i : output frame length */ +); + +void ivas_spar_dec_set_render_map( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + int16_t nCldfbTs +); + +void ivas_spar_dec_set_render_params( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const int16_t n_cldfb_slots /* i : number of cldfb slots in this frame */ +); + +void ivas_spar_dec_digest_tc( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const int16_t nchan_transport, /* i : number of transport channels */ + const int16_t nCldfbSlots, /* i : number of CLDFB slots */ + const int16_t nSamplesForRendering /* i : number of samples provided */ +); + +ivas_error ivas_sba_dec_digest_tc( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const int16_t nCldfbSlots, /* i : number of CLDFB slots */ + const int16_t nSamplesForRendering /* i : number of samples provided */ +); + +void ivas_sba_dec_render( + 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 *nSamplesAvailable, /* o : number of CLDFB slots still to render */ + float *output_f[] /* o : rendered time signal */ +); + +void ivas_spar_dec_upmixer_sf( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + float *output[], /* o : output audio channels */ + const int16_t nchan_internal /* i : number of internal channels */ +); +#endif + void ivas_spar_dec_upmixer( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ float output[][L_FRAME48k], /* i/o: input/output audio channels */ @@ -4258,7 +4588,11 @@ void ivas_td_decorr_dec_close( void ivas_td_decorr_process( ivas_td_decorr_state_t *hTdDecorr, /* i/o: SPAR Covar. decoder handle */ +#ifdef JBM_TSM_ON_TCS + float *pcm_in[], /* i : input audio channels */ +#else float pcm_in[][L_FRAME48k], /* i : input audio channels */ +#endif float **ppOut_pcm, /* o : output audio channels */ const int16_t output_frame /* i : output frame length */ ); @@ -4593,6 +4927,19 @@ void ivas_masa_prerender( const int16_t output_frame /* i : output frame length per channel */ ); +#ifdef JBM_TSM_ON_TCS +void ivas_spar_param_to_masa_param_mapping_sf( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ + int16_t azimuth[][CLDFB_NO_CHANNELS_MAX], + int16_t elevation[][CLDFB_NO_CHANNELS_MAX], + float energy_ratio1[][CLDFB_NO_CHANNELS_MAX], + float spreadCoherence[][CLDFB_NO_CHANNELS_MAX], + float surroundingCoherence[][CLDFB_NO_CHANNELS_MAX], + float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */ + float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /* i : Input audio in CLDFB domain, imag */ +); +#endif + void ivas_spar_param_to_masa_param_mapping( Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ float inRe[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */ @@ -4617,12 +4964,28 @@ void ivas_binRenderer_close( #ifdef DEBUGGING void ivas_binaural_cldfb( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ +#ifdef JBM_TSM_ON_TCS + float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ +#else float output_f[][L_FRAME48k] /* i/o: synthesized core-coder transport channels/DirAC output */ +#endif +); + +#ifdef JBM_TSM_ON_TCS +void ivas_binaural_cldfb_sf( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const int16_t n_samples_to_render, + float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ ); +#endif + #endif void ivas_binRenderer( BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */ HEAD_TRACK_DATA_HANDLE hHeadTrackData, /* i/o: head track handle */ +#ifdef JBM_TSM_ON_TCS + const int16_t numTimeSlots, /* i: : number of time slots to process */ +#endif 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 */ @@ -4632,7 +4995,12 @@ void ivas_binRenderer( void ivas_binaural_add_LFE( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ int16_t output_frame, /* i : length of input frame */ +#ifdef JBM_TSM_ON_TCS + float *input_f[], /* i : transport channels */ + float *output_f[] /* o : synthesized core-coder transport channels/DirAC output */ +#else float output_f[][L_FRAME48k] /* i/o: synthesized core-coder transport channels/DirAC output */ +#endif ); @@ -4646,10 +5014,22 @@ ivas_error ivas_ism_renderer_open( void ivas_ism_render( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ +#ifdef JBM_TSM_ON_TCS + float *output_f[], /* i/o: core-coder transport channels/object output */ +#else float output_f[][L_FRAME48k], /* i/o: core-coder transport channels/object output */ +#endif const int16_t output_frame /* i : output frame length per channel */ ); +#ifdef JBM_TSM_ON_TCS +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 */ + const int16_t n_samples_to_render /* i : output frame length per channel */ +); +#endif + void ivas_ism_get_stereo_gains( const float azimuth, /* i : object azimuth */ const float elevation, /* i : object elevation */ @@ -4659,14 +5039,23 @@ void ivas_ism_get_stereo_gains( void ivas_mc2sba( IVAS_OUTPUT_SETUP hIntSetup, /* i : Format of decoder output */ - float buffer_td[][L_FRAME48k], /* i/o: MC signals (on input) and the HOA3 (on output) */ +#ifdef JBM_TSM_ON_TCS + float *in_buffer_td[], /* i : MC signals (on input) and the HOA3 (on output) */ + float *buffer_td[], /* o : MC signals (on input) and the HOA3 (on output) */ +#else + float buffer_td[][L_FRAME48k], /* i/o: MC signals (on input) and the HOA3 (on output) */ +#endif const int16_t output_frame, /* i : output frame length per channel */ const int16_t sba_order, /* i : SBA order */ const float gain_lfe /* i : gain for LFE, 0=ignore LFE */ ); void ivas_ism2sba( - float buffer_td[][L_FRAME48k], /* i/o: TD signal buffers */ +#ifdef JBM_TSM_ON_TCS + float *buffer_td[], /* i/o: TD signal buffers */ +#else + float buffer_td[][L_FRAME48k], /* i/o: TD signal buffers */ +#endif 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 */ @@ -4674,7 +5063,17 @@ void ivas_ism2sba( const int16_t sba_order /* i : SBA order */ ); - +#ifdef JBM_TSM_ON_TCS +void ivas_ism2sba_sf( + float *buffer_in[], /* i : TC buffer */ + float *buffer_out[], /* o : TD signal buffers */ + ISM_RENDERER_HANDLE hIsmRendererData, /* i/o: renderer data */ + const int16_t num_objects, /* i : number of objects */ + const int16_t n_samples_to_render, /* i : output frame length per channel */ + const int16_t offset, /* i : offset for the interpolatr */ + const int16_t sba_order /* i : Ambisonic (SBA) order */ +); +#endif /*----------------------------------------------------------------------------------* * Amplitude Panning VBAP prototypes *----------------------------------------------------------------------------------*/ @@ -4725,7 +5124,12 @@ void ivas_ls_setup_conversion_close( void ivas_ls_setup_conversion( Decoder_Struct *st_ivas, /* i : IVAS decoder structure */ const int16_t output_frame, /* i : frame length */ - float output[][L_FRAME48k] /* i/o: LS input/output synthesis signal */ +#ifdef JBM_TSM_ON_TCS + float *input[], /* i : LS input/output synthesis signal */ + float *output[] /* i/o: LS input/output synthesis signal */ +#else + float output[][L_FRAME48k] /* i/o: LS input/output synthesis signal */ +#endif ); void ivas_ls_setup_conversion_process_mdct( @@ -4740,6 +5144,9 @@ void ivas_ls_setup_conversion_process_mdct_param_mc( void ivas_lssetupconversion_process_param_mc( Decoder_Struct *st_ivas, /* i/o: LS setup conversion renderer handle */ +#ifdef JBM_TSM_ON_TCS + int16_t num_timeslots, /* i : number of time slots to process */ +#endif float Cldfb_RealBuffer_InOut[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i/o: LS signals */ float Cldfb_ImagBuffer_InOut[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i/o: LS signals */ int16_t channel_active[MAX_CICP_CHANNELS] /* i : bitmap indicating which output channels are active */ @@ -4966,10 +5373,21 @@ ivas_error ivas_td_binaural_open( ivas_error ivas_td_binaural_renderer( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float output[][L_FRAME48k], /* i/o: SCE channels / Binaural synthesis */ +#ifdef JBM_TSM_ON_TCS + float *output[], /* i/o: SCE channels / Binaural synthesis */ +#else + float output[][L_FRAME48k], /* i/o: SCE channels / Binaural synthesis */ +#endif const int16_t output_frame /* i : output frame length */ ); +#ifdef JBM_TSM_ON_TCS +void ObjRenderIVASSubframe( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output[], /* i/o: SCE channels / Binaural synthesis */ + const int16_t output_frame /* i : output frame length */ +); +#endif /*----------------------------------------------------------------------------------* * Filter-bank (FB) Mixer diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index 7fceb7941f..80f564e54a 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -335,7 +335,7 @@ typedef struct ivas_agc_chan_data_t typedef struct ivas_agc_com_state_t { float *winFunc; - int16_t in_delay; + int16_t in_delay; /* TODO: JBM check if this needs to be adjusted in the dec */ uint16_t absEmin; uint16_t betaE; uint16_t maxAttExp; @@ -689,6 +689,10 @@ typedef struct ivas_td_decorr_state_t int16_t num_apd_outputs; int16_t num_apd_sections; int16_t ducking_flag; + +#ifdef JBM_TSM_ON_TCS + int16_t offset; +#endif } ivas_td_decorr_state_t; diff --git a/lib_com/ivas_td_decorr.c b/lib_com/ivas_td_decorr.c index 23620b3b2d..59db50c443 100644 --- a/lib_com/ivas_td_decorr.c +++ b/lib_com/ivas_td_decorr.c @@ -127,7 +127,9 @@ ivas_error ivas_td_decorr_dec_open( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR COV decoder" ); } set_f( hTdDecorr_loc->look_ahead_buf, 0, (int16_t) ( output_Fs * IVAS_DECORR_PARM_LOOKAHEAD_TAU ) ); - +#ifdef JBM_TSM_ON_TCS + hTdDecorr_loc->offset = (int16_t) ( output_Fs * IVAS_DECORR_PARM_LOOKAHEAD_TAU ); +#endif hTdDecorr_loc->num_apd_sections = ivas_get_APD_filt_orders( num_out_chans, output_Fs, hTdDecorr_loc->APD_filt_state[0].order ); for ( j = 0; j < num_out_chans; j++ ) @@ -375,20 +377,32 @@ static void ivas_td_decorr_APD_sections( void ivas_td_decorr_process( ivas_td_decorr_state_t *hTdDecorr, /* i/o: SPAR Covar. decoder handle */ - float pcm_in[][L_FRAME48k], /* i : input audio channels */ - float **ppOut_pcm, /* o : output audio channels */ - const int16_t output_frame /* i : output frame length */ +#ifdef JBM_TSM_ON_TCS + float *pcm_in[], +#else + float pcm_in[][L_FRAME48k], /* i : input audio channels */ +#endif + float **ppOut_pcm, /* o : output audio channels */ + const int16_t output_frame /* i : output frame length */ ) { int16_t i, j; +#ifndef JBM_TSM_ON_TCS int16_t offset; +#endif float in_duck_gain[L_FRAME48k], out_duck_gain[L_FRAME48k]; +#ifndef JBM_TSM_ON_TCS offset = (int16_t) ( output_frame * FRAMES_PER_SEC * IVAS_DECORR_PARM_LOOKAHEAD_TAU ); +#endif /* Look-ahead delay */ mvr2r( pcm_in[0], ppOut_pcm[0], output_frame ); +#ifdef JBM_TSM_ON_TCS + delay_signal( ppOut_pcm[0], output_frame, hTdDecorr->look_ahead_buf, hTdDecorr->offset ); +#else delay_signal( ppOut_pcm[0], output_frame, hTdDecorr->look_ahead_buf, offset ); +#endif /* In ducking gains */ if ( hTdDecorr->ducking_flag ) diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index b75c083791..e348d8a241 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -75,10 +75,18 @@ float sumAbs( void mvc2c( const uint8_t x[], /* i : input vector */ uint8_t y[], /* o : output vector */ - const int16_t n /* i : vector size */ +#ifdef FIX_XXX_JBM_FIFO_BUFFER + const int32_t n +#else + const int16_t n /* i : vector size */ +#endif ) { +#ifdef FIX_XXX_JBM_FIFO_BUFFER + int32_t i; +#else int16_t i; +#endif if ( n <= 0 ) { @@ -114,14 +122,22 @@ void mvc2c( /*! r: number of clipped samples */ uint32_t ivas_syn_output( - float synth[][L_FRAME48k], /* i/o: float synthesis signal */ +#ifdef JBM_TSM_ON_TCS + float *synth[], /* i/o: float synthesis signal */ +#else + float synth[][L_FRAME48k], /* i/o: float synthesis signal */ +#endif const int16_t output_frame, /* i : output frame length (one channel) */ const int16_t n_channels, /* i : number of output channels */ int16_t *synth_out /* o : integer 16 bits synthesis signal */ ) { int16_t i, n; +#ifdef JBM_TSM_ON_TCS + int16_t synth_loc[MAX_JBM_L_FRAME48k]; +#else int16_t synth_loc[L_FRAME48k]; +#endif uint32_t noClipping = 0; /*-----------------------------------------------------------------* @@ -147,6 +163,40 @@ uint32_t ivas_syn_output( return noClipping; } +#ifdef JBM_TSM_ON_TCS +/*-------------------------------------------------------------------* + * ivas_syn_output_f() + * + * Output ivas synthesis signal with compensation for saturation + * returns number of clipped samples + *-------------------------------------------------------------------*/ + +/*! r: number of clipped samples */ +void ivas_syn_output_f( + float *synth[], /* i/o: float synthesis signal */ + const int16_t output_frame, /* i : output frame length (one channel) */ + const int16_t n_channels, /* i : number of output channels */ + float *synth_out /* o : integer 16 bits synthesis signal */ +) +{ + int16_t i, n; + + /*-----------------------------------------------------------------* + * float to integer conversion with saturation control + *-----------------------------------------------------------------*/ + + for ( n = 0; n < n_channels; n++ ) + { + for ( i = 0; i < output_frame; i++ ) + { + synth_out[i * n_channels + n] = synth[n][i]; + } + } + + return; +} +#endif + /*-------------------------------------------------------------------* * mvr2r_inc() * diff --git a/lib_com/options.h b/lib_com/options.h index c4ecc904db..e7ffeb2b7a 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -72,6 +72,7 @@ /*#define DEBUG_MODE_INFO_PLC */ /* define to output PLC related parameters */ /*#define DEBUG_MODE_INFO_ALLRAD*/ /* define to output generated HOA decoding mtx */ /*#define DEBUG_MODE_LFE */ /* define to output LFE relevant parameters */ +/*#define DEBUG_MODE_JBM */ /* define to output import JBM parameters */ #endif #ifdef DEBUG_MODE_MDCT @@ -112,9 +113,9 @@ /*#define TDREND_HRTF_TABLE_METHODS*/ /* Enable HRTF lookup from tables, for testing & evaluation. Supply file in table format to use. Note that a suitable HR filter lookup method should be written if the filters sample point grids are not in the formats. */ /*#define TDREND_STANDALONE*/ /* Used when renderer is built in standalone form, without IVAS encoding/decoding (see scripts/object_renderer_standalone). This is just here to ensure this is cleaned out by prepare_instrumentation.sh */ -/*#define DEBUG_SBA*/ /* debug DIRAC/SPAR in-out */ +#define DEBUG_SBA /* debug DIRAC/SPAR in-out */ #ifdef DEBUG_SBA -/*#define DEBUG_SBA_AUDIO_DUMP*/ /* SBA intermediate audio wav file dumping */ +/*#define DEBUG_SBA_AUDIO_DUMP */ /* SBA intermediate audio wav file dumping */ /*#define DEBUG_SBA_MD_DUMP*/ /* SBA metadata and variable file dumping */ /*#define DEBUG_SPAR_MD_TARGET_TUNING*/ /* SPAR MD target bitrate tuning debug code */ /*#define DEBUG_SPAR_BYPASS_EVS_CODEC*/ /* bypass EVS coding in float precision, emulating EVS encoder/decoder delay */ @@ -125,6 +126,8 @@ /*#define SPAR_HOA_DBG*/ /* SPAR HOA debug statements */ /*#define DEBUG_BINAURAL_FILTER_DESIGN*/ /* debugging of Crend binaural filter design */ #define DEBUG_AGC_ENCODER_CMD_OPTION /* Ability to force enable or disable AGC behaviour in DIRAC/SPAR via command line option */ +/*#define DEBUG_JBM*/ +#define DEBUG_JBM_CMD_OPTION /* ability for telling the decoder the frontend fetch size and to not delay compensate for bad frames at the beginning */ #endif /* #################### End DEBUGGING switches ############################ */ @@ -146,7 +149,15 @@ #define REND_DEBUGGING_REVISION /* VA: encapsulate rendering debugging options with DEBUGGING */ #define FIX_419_ISM_MD_FIX /* VA: Issue 419: fix the upper value limitation for parameter angle1_diff_cnt */ +#define FIX_XXX_JBM_FIFO_BUFFER /* FhG: prevent wraparound of a length identifier in cause of large frames and many channels*/ +#define VARIABLE_SPEED_DECODING /* FhG: variable speed decoding employing the JBM functioniality */ +#define JBM_TSM_ON_TCS /* FhG: run the TSM part of JBM on the TCs instead of the final output pcm waveforms */ +#ifdef JBM_TSM_ON_TCS +#define TEST_BIN_RENDERER_BE +#define TMP_FIX_ISM_BR_SWITCHING /* */ +/*#define JBM_DIRAC_DEBUG_BE*/ +#endif /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ #endif diff --git a/lib_com/prot.h b/lib_com/prot.h index 65f821e5fb..40e84a72ca 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -177,7 +177,11 @@ float sum2_f( void set_c( int8_t y[], /* i/o: Vector to set */ const int8_t a, /* i : Value to set the vector to */ - const int16_t N /* i : Lenght of the vector */ +#ifdef JBM_TSM_ON_TCS + const int32_t N /* i : Length of the vector */ +#else + const int16_t N /* i : Length of the vector */ +#endif ); void set_s( @@ -8543,6 +8547,17 @@ void generate_masking_noise_mdct( HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ ); +#ifdef JBM_TSM_ON_TCS +void SynthesisSTFT_dirac( + float *fftBuffer, /* i : FFT bins */ + float *timeDomainOutput, + float *olapBuffer, + const float *olapWin, + const int16_t samples_out, + HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ +); +#endif + void generate_masking_noise_dirac( HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */ diff --git a/lib_com/tools.c b/lib_com/tools.c index db7c5a3f8e..b9b8428a06 100644 --- a/lib_com/tools.c +++ b/lib_com/tools.c @@ -210,7 +210,11 @@ float sum2_f( void set_c( int8_t y[], /* i/o: Vector to set */ const int8_t a, /* i : Value to set the vector to */ +#ifdef JBM_TSM_ON_TCS + const int32_t N /* i : Length of the vector */ +#else const int16_t N /* i : Length of the vector */ +#endif ) { int16_t i; @@ -387,7 +391,11 @@ uint32_t mvr2s( return 0; } +#ifdef JBM_TSM_ON_TCS + if ( (void *) y <= (const void *) x ) +#else if ( (void *) y < (const void *) x ) +#endif { for ( i = 0; i < n; i++ ) { diff --git a/lib_debug/debug.c b/lib_debug/debug.c index 85e48e8bae..4e4cf1cf8b 100644 --- a/lib_debug/debug.c +++ b/lib_debug/debug.c @@ -54,6 +54,9 @@ #else #endif #include "wmc_auto.h" +#ifdef DEBUG_JBM +#include "tinywaveout_c.h" +#endif /*-------------------------------------------------------------------* @@ -93,6 +96,12 @@ static FILE *out_fileptr[N_FILEPTR]; static char *in_filename[N_FILEPTR]; static char *out_filename[N_FILEPTR]; +#ifdef DEBUG_MODE_JBM +static char *wav_out_filename[N_FILEPTR]; +static WAVEFILEOUT *wav_out_fileptr[N_FILEPTR]; +static int16_t wav_count; +#endif + static int16_t in_count = 0; static int16_t out_count = 0; @@ -201,6 +210,93 @@ int16_t dbgwrite( return 0; } +#ifdef DEBUG_MODE_JBM +/*-------------------------------------------------------------------* + * dbgwritewav() + * + * Writes the buffer content to the specified file. If the file is not in the + * debug file list, it is opened before write. + *--------------------------------------------------------------------*/ + +int16_t dbgwritewav( + const int16_t input_frame, + float **ppPcm, + float pcm_array[MAX_OUTPUT_CHANNELS][L_FRAME48k], + const int16_t no_channel, + const int32_t fs, +#ifdef DEBUG_MODE_INFO_TWEAK + const char *filename /* i : Output file name */ +#else + const char *const filename +#endif +) +{ + int16_t index, i; + +#ifdef DEBUG_MODE_INFO +#ifdef DEBUG_MODE_INFO_TWEAK + char filename_mod[FILENAME_MAX]; + int16_t textmode = 0; + memset( filename_mod, 0, FILENAME_MAX ); + tweakdbgfolder( filename, filename_mod, &textmode ); + if ( filename_mod[0] != 0 ) + { + filename = filename_mod; + } +#endif +#endif + + index = lookup( filename, (const char *const *) wav_out_filename, wav_count ); + + if ( index == -1 ) + { + if ( make_dirs( filename ) != 0 ) + { + fprintf( stderr, "dbgwrite: Could not create directory structure for %s. Exiting..\n", filename ); + exit( -1 ); + } + + index = wav_count; + wav_out_filename[index] = malloc( sizeof( char ) * ( strlen( filename ) + 1 ) ); + strcpy( wav_out_filename[index], filename ); + wav_out_fileptr[index] = CreateWav( (const char *) wav_out_filename[index], fs, no_channel, 32 /* const uint32_t writeWaveExt */ ); + + wav_count++; + } + + if ( wav_out_fileptr[index] != NULL ) + { + float debug_tmp[IVAS_SPAR_MAX_CH * L_FRAME48k * 2]; + int32_t j, k; + k = 0; + for ( j = 0; j < input_frame; j++ ) + { + for ( i = 0; i < no_channel; i++, k++ ) + { + float tmp_value; + if ( ppPcm ) + { + tmp_value = ppPcm[i][j]; + } + else + { + tmp_value = pcm_array[i][j]; + } + debug_tmp[k] = tmp_value; + } + } + WriteWavFloat( wav_out_fileptr[index], debug_tmp, ( no_channel * input_frame ) ); + } + else + { + fprintf( stderr, "dbgwrite: Could not write to file: %s. Exiting..\n", filename ); + exit( -1 ); + } + + return 0; +} +#endif + /*-------------------------------------------------------------------* * dbgwrite_mat_repeat() * @@ -406,7 +502,14 @@ void dbgclose() free( val_name[i] ); free( val[i] ); } - +#ifdef DEBUG_MODE_JBM + for ( i = 0; i < wav_count; i++ ) + { + CloseWav( wav_out_fileptr[i] ); + wav_out_fileptr[i] = NULL; + free( wav_out_filename[i] ); + } +#endif return; } diff --git a/lib_debug/debug.h b/lib_debug/debug.h index 3d59cb00a0..c89f245af6 100644 --- a/lib_debug/debug.h +++ b/lib_debug/debug.h @@ -98,6 +98,21 @@ int16_t dbgwrite( #endif ); +#ifdef DEBUG_MODE_JBM +int16_t dbgwritewav( + const int16_t input_frame, + float **ppPcm, + float pcm_array[MAX_OUTPUT_CHANNELS][L_FRAME48k], + const int16_t no_channel, + const int32_t fs, +#ifdef DEBUG_MODE_INFO_TWEAK + const char *filename /* i : Output file name */ +#else + const char *const filename +#endif +); +#endif + void dbgwrite_mat_repeat( float *buffer, /* i : write buffer */ int16_t nRow, /* i : matrix size (rows) */ diff --git a/lib_debug/sba_debug.c b/lib_debug/sba_debug.c index 040cadf887..3f9138e47f 100644 --- a/lib_debug/sba_debug.c +++ b/lib_debug/sba_debug.c @@ -51,11 +51,11 @@ #define MAX_IN_FILE_LEN ( 1000 ) #define MAX_PLUG_IN_FILE_LEN ( MAX_IN_FILE_LEN ) #define MAX_DEBUG_TAG_LEN ( 50 ) -#define NUM_DEBUG_FILES ( 4 ) +#define NUM_DEBUG_FILES ( 5 ) #define MAX_TAG_LEN ( 200 ) WAVEFILEOUT *spar_foa_enc_wav[3]; -WAVEFILEOUT *spar_foa_dec_wav[4]; +WAVEFILEOUT *spar_foa_dec_wav[NUM_DEBUG_FILES]; float max_diff = 0; int32_t dbg_frm_num; int32_t dbg_band; @@ -202,6 +202,7 @@ void ivas_spar_dump_signal_wav( { for ( i = 0; i < no_channel; i++, k++ ) { +#if 0 if ( ppPcm ) { tmp_value = roundf( ppPcm[i][j] * PCM16_TO_FLT_FAC ); @@ -210,6 +211,16 @@ void ivas_spar_dump_signal_wav( { tmp_value = roundf( pcm_array[i][j] * PCM16_TO_FLT_FAC ); } +#else + if ( ppPcm ) + { + tmp_value = roundf(ppPcm[i][j]); + } + else + { + tmp_value = roundf(pcm_array[i][j]); + } +#endif if ( tmp_value > MAX16B_FLT ) { largest_value = (float) fabs( tmp_value ) > largest_value ? (float) fabs( tmp_value ) : largest_value; @@ -272,6 +283,12 @@ void ivas_close_sba_decoder_debug_files( CloseWav( spar_foa_dec_wav[3] ); } + if ( spar_foa_dec_wav[4] != NULL ) + { + UpdateWave( fs, n_ch, 16, spar_foa_dec_wav[4] ); + CloseWav( spar_foa_dec_wav[4] ); + } + return; } @@ -315,7 +332,7 @@ void ivas_open_sba_decoder_debug_files( const int16_t n_ch, const int16_t n_transport ) { - int8_t fb_wav_dump_path[4][MAX_PLUG_IN_FILE_LEN] = { "", "", "", "" }; + int8_t fb_wav_dump_path[NUM_DEBUG_FILES][MAX_PLUG_IN_FILE_LEN] = { "", "", "", "", "" }; cstrcat( (char *) fb_wav_dump_path[0], sizeof( fb_wav_dump_path[0] ), "dec_out.wav" ); spar_foa_dec_wav[0] = CreateWav( (const char *) fb_wav_dump_path[0], fs, n_ch, 32 /* const uint32_t writeWaveExt */ ); @@ -329,6 +346,9 @@ void ivas_open_sba_decoder_debug_files( cstrcat( (char *) fb_wav_dump_path[3], sizeof( fb_wav_dump_path[3] ), "cldfbSynthesis.wav" ); spar_foa_dec_wav[3] = CreateWav( (const char *) fb_wav_dump_path[3], fs, n_transport, 16 /* const uint32_t writeWaveExt */ ); + cstrcat( (char *) fb_wav_dump_path[4], sizeof( fb_wav_dump_path[4] ), "cldfbAnalysis.wav" ); + spar_foa_dec_wav[4] = CreateWav( (const char *) fb_wav_dump_path[4], fs, n_transport, 16 /* const uint32_t writeWaveExt */ ); + return; } diff --git a/lib_debug/sba_debug.h b/lib_debug/sba_debug.h index cd4fd58c11..a314d1568c 100644 --- a/lib_debug/sba_debug.h +++ b/lib_debug/sba_debug.h @@ -41,9 +41,10 @@ #include "ivas_cnst.h" #include "tinywaveout_c.h" + #ifdef DEBUG_SBA_AUDIO_DUMP extern WAVEFILEOUT *spar_foa_enc_wav[3]; -extern WAVEFILEOUT *spar_foa_dec_wav[4]; +extern WAVEFILEOUT *spar_foa_dec_wav[5]; #endif #ifdef DEBUG_AGC diff --git a/lib_dec/fd_cng_dec.c b/lib_dec/fd_cng_dec.c index c75bc60f8e..bcf374382d 100644 --- a/lib_dec/fd_cng_dec.c +++ b/lib_dec/fd_cng_dec.c @@ -1780,6 +1780,163 @@ void generate_stereo_masking_noise( return; } +#ifdef JBM_TSM_ON_TCS +/*------------------------------------------------------------------- + * generate_masking_noise_hf_cldfb() + * + * Generate additional comfort noise (kind of noise filling) + *-------------------------------------------------------------------*/ + +void generate_masking_noise_lb_dirac( + HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ + float *tdBuffer, /* i/o: time-domain signal, if NULL no LB-CNA */ + const int16_t nCldfbTs, /* i : number of CLDFB slots that will be rendered */ + const int16_t cna_flag /* i : CNA flag for LB and HB */ +) +{ + int16_t i; + float *cngNoiseLevel = hFdCngCom->cngNoiseLevel; + float *fftBuffer = hFdCngCom->fftBuffer; + float *ptr_r; + float *ptr_i; + float *ptr_level; + int16_t *seed = &( hFdCngCom->seed ); + float scale; + int16_t n_samples_out, n_samples_start, n_samples_out_loop; + + push_wmops( "fd_cng_dirac" ); + + /* Init */ + scale = 0.f; + n_samples_out = hFdCngCom->frameSize / DEFAULT_JBM_CLDFB_TIMESLOTS * nCldfbTs; + n_samples_start = 0; + + + /*LB CLDFB - CNA from STFT*/ +#ifdef DEBUG_MODE_DIRAC + { + int16_t tmp_s; + tmp_s = (int16_t) ( 32768.f * 0.5f * hFdCngCom->likelihood_noisy_speech * cna_flag + 0.5f ); + dbgwrite( &tmp_s, sizeof( int16_t ), 1, hFdCngCom->frameSize / 16, "./res/ivas_dirac_likelihood_noisy.pcm" ); + } +#endif + if ( cna_flag ) + { + /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ + if ( hFdCngCom->likelihood_noisy_speech > DELTA_MASKING_NOISE ) + { + /* Compute additional CN level */ + for ( i = 0; i < 15; i++ ) + { + if ( ( hFdCngCom->CngBandwidth == scaleTable_cn_dirac[i].bwmode ) && + ( hFdCngCom->CngBitrate >= scaleTable_cn_dirac[i].bitrateFrom ) && + ( hFdCngCom->CngBitrate < scaleTable_cn_dirac[i].bitrateTo ) ) + { + break; + } + } + + scale = (float) pow( 10.f, -scaleTable_cn_dirac[i].scale / 10.f ) - 1.f; + scale *= hFdCngCom->likelihood_noisy_speech; + } + } + + /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/ + if ( cna_flag && tdBuffer != NULL ) + { + while ( n_samples_out > 0 ) + { + n_samples_out_loop = min( hFdCngCom->frameSize, n_samples_out ); + if ( scale != 0 ) + { + /*Generate LF comfort noise only at first slot, for the whole frame*/ + ptr_level = cngNoiseLevel; + + /* Generate Gaussian random noise in real and imaginary parts of the FFT bins + Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin */ + if ( hFdCngCom->startBand == 0 ) + { + rand_gauss( &fftBuffer[0], seed ); + ptr_r = fftBuffer + 2; + fftBuffer[0] *= (float) sqrt( scale * *ptr_level ); /* DC component in FFT */ + ptr_level++; + } + else + { + fftBuffer[0] = 0.f; + set_f( fftBuffer + 2, 0.0f, 2 * ( hFdCngCom->startBand - 1 ) ); + ptr_r = fftBuffer + 2 * hFdCngCom->startBand; + } + ptr_i = ptr_r + 1; + + for ( ; ptr_level < cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand; ptr_level++ ) + { + /* Real part in FFT bins */ + rand_gauss( ptr_r, seed ); + ( *ptr_r ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); + ptr_r += 2; + /* Imaginary part in FFT bins */ + rand_gauss( ptr_i, seed ); + ( *ptr_i ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); + ptr_i += 2; + } + + /* Remaining FFT bins are set to zero */ + set_f( fftBuffer + 2 * hFdCngCom->stopFFTbin, 0.0f, hFdCngCom->fftlen - 2 * hFdCngCom->stopFFTbin ); + /* Nyquist frequency is discarded */ + fftBuffer[1] = 0.f; + + /* Perform STFT synthesis */ + SynthesisSTFT_dirac( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2, hFdCngCom->olapWinSyn, n_samples_out_loop, hFdCngCom ); + +#ifdef DEBUG_MODE_DIRAC + { + int16_t tmp[1000]; + + for ( i = 0; i < hFdCngCom->frameSize; i++ ) + { + tmp[i] = (int16_t) ( tdBuffer[i] + 0.5f ); + } + dbgwrite( tmp, sizeof( int16_t ), hFdCngCom->frameSize, 1, "./res/ivas_dirac_cna_fft.pcm" ); + } +#endif + } + + else + { + /* very low level case - update random seeds */ + generate_masking_noise_update_seed( hFdCngCom ); + + set_f( fftBuffer, 0.f, hFdCngCom->fftlen ); + + /* Perform STFT synthesis */ + SynthesisSTFT_dirac( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2, hFdCngCom->olapWinSyn, n_samples_out_loop, hFdCngCom ); + +#ifdef DEBUG_MODE_DIRAC + { + int16_t tmp[1000]; + + for ( i = 0; i < hFdCngCom->frameSize; i++ ) + { + tmp[i] = (int16_t) ( tdBuffer[i] + 0.5f ); + } + dbgwrite( tmp, sizeof( int16_t ), hFdCngCom->frameSize, 1, "./res/ivas_dirac_cna_fft.pcm" ); + } +#endif + } + n_samples_out -= hFdCngCom->frameSize; + n_samples_start += hFdCngCom->frameSize; + + } + } + + pop_wmops(); + + return; +} + +#endif + /*------------------------------------------------------------------- * generate_masking_noise_hf_cldfb() @@ -1799,10 +1956,12 @@ void generate_masking_noise_dirac( ) { int16_t i; +#ifndef JBM_TSM_ON_TCS float *cngNoiseLevel = hFdCngCom->cngNoiseLevel; float *fftBuffer = hFdCngCom->fftBuffer; float *ptr_r; float *ptr_i; +#endif float *ptr_level; int16_t *seed = &( hFdCngCom->seed ); float scale; @@ -1849,12 +2008,12 @@ void generate_masking_noise_dirac( scale *= hFdCngCom->likelihood_noisy_speech; } } - /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/ if ( cna_flag && tdBuffer != NULL ) { if ( scale != 0 ) { +#ifndef JBM_TSM_ON_TCS /*Generate LF comfort noise only at first slot, for the whole frame*/ if ( slot_index == 0 ) { @@ -1909,12 +2068,13 @@ void generate_masking_noise_dirac( } #endif } - +#endif /* LF CLDFB*/ cldfbAnalysis_ts( &( tdBuffer[hFdCngCom->numCoreBands * slot_index] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, hFdCngCom->numCoreBands, h_cldfb ); } else { +#ifndef JBM_TSM_ON_TCS if ( slot_index == 0 ) { /* very low level case - update random seeds */ @@ -1937,7 +2097,7 @@ void generate_masking_noise_dirac( } #endif } - +#endif /* LB ana CLDFB*/ cldfbAnalysis_ts( &( tdBuffer[hFdCngCom->numCoreBands * slot_index] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, hFdCngCom->numCoreBands, h_cldfb ); } diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index 2db5602519..7e023fcaa6 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -59,7 +59,10 @@ static void ivas_binRenderer_filterModule( float out_Conv_CLDFB_imag[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : imag part of Binaural signals */ float CLDFB_real[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : real part of LS signals */ float CLDFB_imag[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : imag part of LS signals */ - BINAURAL_RENDERER_HANDLE hBinRenderer /* i/o: fastconv binaural renderer handle */ +#ifdef JBM_TSM_ON_TCS + const int16_t numTimeSlots, /* i : number of time slots to process */ +#endif + BINAURAL_RENDERER_HANDLE hBinRenderer /* i/o: fastconv binaural renderer handle */ ) { int16_t bandIdx, k, chIdx, tapIdx; @@ -78,7 +81,11 @@ static void ivas_binRenderer_filterModule( filterTapsRightRealPtr = hBinRenderer->hBinRenConvModule->filterTapsRightReal[bandIdx][chIdx]; filterTapsRightImagPtr = hBinRenderer->hBinRenConvModule->filterTapsRightImag[bandIdx][chIdx]; +#ifdef JBM_TSM_ON_TCS + for ( k = 0; k < numTimeSlots; k++ ) +#else for ( k = 0; k < MAX_PARAM_SPATIAL_SUBFRAMES; k++ ) +#endif { float outRealLeft = 0.0f, outRealRight = 0.0f, outImagLeft = 0.0f, outImagRight = 0.0f; @@ -847,9 +854,14 @@ void ivas_binRenderer_close( *-------------------------------------------------------------------------*/ void ivas_binaural_add_LFE( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - int16_t output_frame, /* i : length of input frame */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + int16_t output_frame, /* i : length of input frame */ +#ifdef JBM_TSM_ON_TCS + float *input_f[], /* i : transport channels */ + float *output_f[] /* o : synthesized core-coder transport channels/DirAC output */ +#else float output_f[][L_FRAME48k] /* i/o: synthesized core-coder transport channels/DirAC output */ +#endif ) { int16_t render_lfe, idx_lfe; @@ -876,10 +888,17 @@ void ivas_binaural_add_LFE( } for ( idx_lfe = 0; idx_lfe < st_ivas->hIntSetup.num_lfe; idx_lfe++ ) { +#ifdef JBM_TSM_ON_TCS + v_multc( input_f[st_ivas->hIntSetup.index_lfe[idx_lfe]], gain, input_f[st_ivas->hIntSetup.index_lfe[idx_lfe]], output_frame ); + /* copy LFE to left and right channels */ + v_add( output_f[0], input_f[st_ivas->hIntSetup.index_lfe[idx_lfe]], output_f[0], output_frame ); + v_add( output_f[1], input_f[st_ivas->hIntSetup.index_lfe[idx_lfe]], output_f[1], output_frame ); +#else v_multc( output_f[st_ivas->hIntSetup.index_lfe[idx_lfe]], gain, output_f[st_ivas->hIntSetup.index_lfe[idx_lfe]], output_frame ); /* copy LFE to left and right channels */ v_add( output_f[0], output_f[st_ivas->hIntSetup.index_lfe[idx_lfe]], output_f[0], output_frame ); v_add( output_f[1], output_f[st_ivas->hIntSetup.index_lfe[idx_lfe]], output_f[1], output_frame ); +#endif } } @@ -895,8 +914,12 @@ void ivas_binaural_add_LFE( *-------------------------------------------------------------------------*/ void ivas_binaural_cldfb( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ +#ifdef JBM_TSM_ON_TCS + float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ +#else float output_f[][L_FRAME48k] /* i/o: synthesized core-coder transport channels/DirAC output */ +#endif ) { float Cldfb_RealBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; @@ -939,8 +962,11 @@ void ivas_binaural_cldfb( } /* Implement binaural rendering */ +#ifdef JBM_TSM_ON_TCS + ivas_binRenderer( st_ivas->hBinRenderer, st_ivas->hHeadTrackData, JBM_CLDFB_SLOTS_IN_SUBFRAME, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); +#else ivas_binRenderer( st_ivas->hBinRenderer, st_ivas->hHeadTrackData, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); - +#endif /* Implement CLDFB synthesis */ for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { @@ -961,6 +987,99 @@ void ivas_binaural_cldfb( return; } +#ifdef JBM_TSM_ON_TCS +/*-------------------------------------------------------------------------* + * ivas_binaural_cldfb() + * + * Perform CLDFB analysis, fastconv binaural rendering and CLDFB synthesis + *-------------------------------------------------------------------------*/ + +void ivas_binaural_cldfb_sf( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const int16_t n_samples_to_render, + float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ +) +{ + float Cldfb_RealBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer[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]; + int16_t slot_idx, subframeIdx, index_slot, idx_in, idx_lfe, maxBand, ch; + int16_t slot_size, slots_to_render, first_sf, last_sf; + int16_t slot_index_start, slot_index_start_cldfb; + + /* Implement a 5 msec loops */ + maxBand = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * st_ivas->hDecoderConfig->output_Fs ) / 48000 ); + slot_size = st_ivas->hTcBuffer->nb_subframes; + /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ + slots_to_render = min( st_ivas->hTcBuffer->num_slots - st_ivas->hTcBuffer->slots_rendered, n_samples_to_render / slot_size ); + first_sf = st_ivas->hTcBuffer->subframes_rendered; + last_sf = first_sf; + slot_index_start = st_ivas->hTcBuffer->slots_rendered; + slot_index_start_cldfb = 0; + st_ivas->hTcBuffer->slots_rendered += slots_to_render; + while ( slots_to_render > 0 ) + { + slots_to_render -= st_ivas->hTcBuffer->subframe_nbslots[last_sf]; + last_sf++; + } + for ( subframeIdx = first_sf; subframeIdx < last_sf; subframeIdx++ ) + { + for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; slot_idx++ ) + { + index_slot = slot_index_start + slot_idx; + + /* Implement CLDFB analysis */ + idx_in = 0; + idx_lfe = 0; + + for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ ) + { + if ( ( st_ivas->hIntSetup.num_lfe > 0 ) && ( st_ivas->hIntSetup.index_lfe[idx_lfe] == ch ) ) + { + if ( idx_lfe < ( st_ivas->hIntSetup.num_lfe - 1 ) ) + { + idx_lfe++; + } + } + else + { + cldfbAnalysis_ts( &( st_ivas->hTcBuffer->tc[ch][maxBand * index_slot] ), + Cldfb_RealBuffer[idx_in][slot_idx], + Cldfb_ImagBuffer[idx_in][slot_idx], + maxBand, st_ivas->cldfbAnaDec[idx_in] ); + idx_in++; + } + } + } + + /* Implement binaural rendering */ +#ifdef JBM_TSM_ON_TCS + ivas_binRenderer( st_ivas->hBinRenderer, st_ivas->hHeadTrackData, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); +#else + ivas_binRenderer( st_ivas->hBinRenderer, st_ivas->hHeadTrackData, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); +#endif + /* 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 < st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; 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][slot_index_start_cldfb * maxBand] ), maxBand * st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], st_ivas->cldfbSynDec[ch] ); + } + slot_index_start += st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; + slot_index_start_cldfb += st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; + } + st_ivas->hTcBuffer->subframes_rendered = last_sf; + return; +} +#endif #endif @@ -971,8 +1090,11 @@ void ivas_binaural_cldfb( *-------------------------------------------------------------------------*/ void ivas_binRenderer( - BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ - HEAD_TRACK_DATA_HANDLE hHeadTrackData, /* i/o: head track handle */ + BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ + HEAD_TRACK_DATA_HANDLE hHeadTrackData, /* i/o: head track handle */ +#ifdef JBM_TSM_ON_TCS + const int16_t numTimeSlots, /* i : number of time slots to render*/ +#endif 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 */ @@ -980,7 +1102,9 @@ void ivas_binRenderer( ) { int16_t chIdx, k; +#ifndef JBM_TSM_ON_TCS int16_t numTimeSlots = MAX_PARAM_SPATIAL_SUBFRAMES; +#endif push_wmops( "fastconv_binaural_rendering" ); @@ -1004,27 +1128,47 @@ void ivas_binRenderer( if ( hHeadTrackData->shd_rot_max_order == -1 ) { QuatToRotMat( hHeadTrackData->Quaternions[hHeadTrackData->num_quaternions++], hHeadTrackData->Rmat ); +#ifdef JBM_TSM_ON_TCS + rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hHeadTrackData->Rmat, hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 ); +#else rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hHeadTrackData->Rmat, hBinRenderer->hInputSetup->nchan_out_woLFE, 3 ); +#endif } else if ( hHeadTrackData->shd_rot_max_order > 0 ) { +#ifdef JBM_TSM_ON_TCS + rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hHeadTrackData->Rmat, hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, hHeadTrackData->shd_rot_max_order ); +#else rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hHeadTrackData->Rmat, hBinRenderer->hInputSetup->nchan_out_woLFE, hHeadTrackData->shd_rot_max_order ); +#endif } } else { /* Rotation in SD (CICPx) */ +#ifdef JBM_TSM_ON_TCS + rotateFrame_sd_cldfb( hHeadTrackData, RealBuffer, ImagBuffer, hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band ); +#else rotateFrame_sd_cldfb( hHeadTrackData, RealBuffer, ImagBuffer, hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, hBinRenderer->conv_band ); +#endif } } /* HOA decoding to CICP19 if needed*/ if ( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 && hBinRenderer->nInChannels != 16 ) { +#ifdef JBM_TSM_ON_TCS + ivas_sba2mc_cldfb( *( hBinRenderer->hInputSetup ), RealBuffer, ImagBuffer, hBinRenderer->nInChannels, hBinRenderer->conv_band, numTimeSlots, hBinRenderer->hoa_dec_mtx ); +#else ivas_sba2mc_cldfb( *( hBinRenderer->hInputSetup ), RealBuffer, ImagBuffer, hBinRenderer->nInChannels, hBinRenderer->conv_band, hBinRenderer->hoa_dec_mtx ); +#endif } +#ifdef JBM_TSM_ON_TCS + ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer ); +#else ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, RealBuffer, ImagBuffer, hBinRenderer ); +#endif /* Obtain the binaural dmx and compute the reverb */ if ( hBinRenderer->hReverb != NULL ) diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index 88e631908c..98490a2ace 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -65,6 +65,9 @@ ivas_error ivas_dec( int32_t output_Fs, ivas_total_brate; AUDIO_CONFIG output_config; ivas_error error; +#ifdef JBM_TSM_ON_TCS + float *p_output[MAX_OUTPUT_CHANNELS]; +#endif error = IVAS_ERR_OK; @@ -80,7 +83,11 @@ ivas_error ivas_dec( if ( st_ivas->bfi == 0 ) { +#ifdef JBM_TSM_ON_TCS + if ( ( error = ivas_dec_setup( st_ivas, NULL, NULL ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_dec_setup( st_ivas ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -97,6 +104,13 @@ ivas_error ivas_dec( output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC ); +#ifdef JBM_TSM_ON_TCS + for ( n = 0; n < MAX_OUTPUT_CHANNELS; n++ ) + { + p_output[n] = &output[n][0]; + } +#endif + /*----------------------------------------------------------------* * Decoding + Rendering *----------------------------------------------------------------*/ @@ -134,7 +148,11 @@ ivas_error ivas_dec( /* Rendering */ if ( st_ivas->renderer_type == RENDERER_MC ) { +#ifdef JBM_TSM_ON_TCS + ivas_ls_setup_conversion( st_ivas, output_frame, p_output, p_output ); +#else ivas_ls_setup_conversion( st_ivas, output_frame, output ); +#endif } } else if ( st_ivas->ivas_format == ISM_FORMAT ) @@ -194,7 +212,11 @@ ivas_error ivas_dec( if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) { /* Convert CICP19 -> Ambisonics */ +#ifdef JBM_TSM_ON_TCS + ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, output_frame, st_ivas->hOutSetup.ambisonics_order, 0.f ); +#else ivas_mc2sba( st_ivas->hIntSetup, output, output_frame, st_ivas->hOutSetup.ambisonics_order, 0.f ); +#endif } } } @@ -208,7 +230,11 @@ ivas_error ivas_dec( 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 */ +#ifdef JBM_TSM_ON_TCS + ivas_ism_render( st_ivas, p_output, output_frame ); +#else ivas_ism_render( st_ivas, output, output_frame ); +#endif } #ifdef REND_DEBUGGING_REVISION #ifdef DEBUGGING @@ -221,29 +247,57 @@ ivas_error ivas_dec( #endif { /* Convert to Ambisonics; used also for ISM->HOA3->binaural rendering */ +#ifdef JBM_TSM_ON_TCS + ivas_ism2sba( p_output, st_ivas->hIsmRendererData, st_ivas->hIsmMetaData, st_ivas->nchan_ism, output_frame, st_ivas->hIntSetup.ambisonics_order ); +#else ivas_ism2sba( output, st_ivas->hIsmRendererData, st_ivas->hIsmMetaData, st_ivas->nchan_ism, output_frame, st_ivas->hIntSetup.ambisonics_order ); +#endif } /* Binaural rendering */ if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { +#ifdef JBM_TSM_ON_TCS + if ( ( ivas_td_binaural_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) +#else if ( ( ivas_td_binaural_renderer( st_ivas, output, output_frame ) ) != IVAS_ERR_OK ) +#endif { return error; } } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { - if ( ( error = ivas_rend_crendProcess( st_ivas->hCrendWrapper, AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_BINAURAL_ROOM, NULL, NULL, NULL, NULL, output, output_Fs ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcess( st_ivas->hCrendWrapper, + AUDIO_CONFIG_7_1_4, + AUDIO_CONFIG_BINAURAL_ROOM, + NULL, + NULL, + NULL, + NULL, +#ifdef JBM_TSM_ON_TCS + p_output, +#else + output, +#endif + output_Fs ) ) != IVAS_ERR_OK ) { return error; } +#ifdef JBM_TSM_ON_TCS + ivas_binaural_add_LFE( st_ivas, output_frame, p_output, p_output ); +#else ivas_binaural_add_LFE( st_ivas, output_frame, output ); +#endif } #ifdef DEBUGGING else if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { +#ifdef JBM_TSM_ON_TCS + ivas_binaural_cldfb( st_ivas, p_output ); +#else ivas_binaural_cldfb( st_ivas, output ); +#endif } #endif } @@ -314,6 +368,9 @@ ivas_error ivas_dec( #ifdef DEBUG_SBA_AUDIO_DUMP /* Dump audio signal after core-decoding */ ivas_spar_dump_signal_wav( output_frame, NULL, output, st_ivas->nchan_transport, spar_foa_dec_wav[0], "core-decoding" ); +#endif +#ifdef DEBUG_MODE_JBM + dbgwritewav( output_frame, NULL, output, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, "res/sba_tc.wav" ); #endif /* TCs remapping */ nchan_remapped = st_ivas->nchan_transport; @@ -355,6 +412,12 @@ ivas_error ivas_dec( { ivas_sba_mix_matrix_determiner( st_ivas->hSpar, output, st_ivas->bfi, nchan_remapped, output_frame ); } +#ifdef JBM_TSM_ON_TCS + else if ( st_ivas->sba_mode == SBA_MODE_SPAR ) + { + ivas_spar_dec_agc_pca( st_ivas, output, output_frame ); + } +#endif } if ( st_ivas->ivas_format == MASA_FORMAT ) @@ -380,14 +443,22 @@ ivas_error ivas_dec( { if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC ) { +#ifdef JBM_TSM_ON_TCS + if ( ( error = ivas_sba_linear_renderer( p_output, output_frame, nchan_remapped, output_config, st_ivas->hOutSetup, st_ivas->hoa_dec_mtx ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_sba_linear_renderer( output, output_frame, nchan_remapped, output_config, st_ivas->hOutSetup, st_ivas->hoa_dec_mtx ) ) != IVAS_ERR_OK ) +#endif { return error; } } else if ( st_ivas->renderer_type == RENDERER_DIRAC ) { +#ifdef JBM_TSM_ON_TCS + ivas_dirac_dec( st_ivas, output, nchan_remapped ); +#else ivas_dirac_dec( st_ivas, output, nchan_remapped, NULL, NULL, -1 ); +#endif } } else if ( !st_ivas->sba_dirac_stereo_flag && nchan_out != 1 ) @@ -425,35 +496,70 @@ ivas_error ivas_dec( if ( st_ivas->transport_config != st_ivas->intern_config && ( st_ivas->intern_config == AUDIO_CONFIG_FOA || st_ivas->intern_config == AUDIO_CONFIG_HOA2 || st_ivas->intern_config == AUDIO_CONFIG_HOA3 ) ) { +#ifdef JBM_TSM_ON_TCS + ivas_mc2sba( st_ivas->hTransSetup, p_output, p_output, output_frame, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE ); +#else ivas_mc2sba( st_ivas->hTransSetup, output, output_frame, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE ); +#endif } /* 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->hHeadTrackData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, output, output_Fs ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcess( st_ivas->hCrendWrapper, + st_ivas->intern_config, + st_ivas->hOutSetup.output_config, + st_ivas->hDecoderConfig, + st_ivas->hHeadTrackData, + &st_ivas->hIntSetup, + st_ivas->hEFAPdata, +#ifdef JBM_TSM_ON_TCS + p_output, +#else + output, +#endif + output_Fs ) ) != IVAS_ERR_OK ) { return error; } +#ifdef JBM_TSM_ON_TCS + ivas_binaural_add_LFE( st_ivas, output_frame, p_output, p_output ); +#else ivas_binaural_add_LFE( st_ivas, output_frame, output ); +#endif } else if ( st_ivas->renderer_type == RENDERER_MC ) { +#ifdef JBM_TSM_ON_TCS + ivas_ls_setup_conversion( st_ivas, output_frame, p_output, p_output ); +#else ivas_ls_setup_conversion( st_ivas, output_frame, output ); +#endif } else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) { +#ifdef JBM_TSM_ON_TCS + ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, output_frame, st_ivas->hOutSetup.ambisonics_order, 0.f ); +#else ivas_mc2sba( st_ivas->hIntSetup, output, output_frame, st_ivas->hOutSetup.ambisonics_order, 0.f ); +#endif } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { +#ifdef JBM_TSM_ON_TCS + 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 ( ( ivas_td_binaural_renderer( st_ivas, output, output_frame ) ) != IVAS_ERR_OK ) { return error; } - ivas_binaural_add_LFE( st_ivas, output_frame, output ); +#endif } } else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) @@ -485,11 +591,19 @@ ivas_error ivas_dec( /* Rendering */ if ( output_config == AUDIO_CONFIG_MONO || output_config == AUDIO_CONFIG_STEREO ) { +#ifdef JBM_TSM_ON_TCS + ivas_ls_setup_conversion( st_ivas, output_frame, p_output, p_output ); +#else ivas_ls_setup_conversion( st_ivas, output_frame, output ); +#endif } else { +#ifdef JBM_TSM_ON_TCS + ivas_param_mc_dec( st_ivas, p_output ); +#else ivas_param_mc_dec( st_ivas, output ); +#endif } } else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) @@ -571,11 +685,19 @@ ivas_error ivas_dec( } else if ( st_ivas->renderer_type == RENDERER_DIRAC || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) /* rendering to CICPxx and Ambisonics */ { +#ifdef JBM_TSM_ON_TCS + ivas_dirac_dec( st_ivas, output, st_ivas->nchan_transport ); +#else ivas_dirac_dec( st_ivas, output, st_ivas->nchan_transport, NULL, NULL, -1 ); +#endif if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) { +#ifdef JBM_TSM_ON_TCS + ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, output_frame, st_ivas->hOutSetup.ambisonics_order, 0.f ); +#else ivas_mc2sba( st_ivas->hIntSetup, output, output_frame, st_ivas->hOutSetup.ambisonics_order, 0.f ); +#endif } else if ( st_ivas->intern_config == AUDIO_CONFIG_5_1 && ( output_config == AUDIO_CONFIG_5_1_2 || output_config == AUDIO_CONFIG_5_1_4 || output_config == AUDIO_CONFIG_7_1 ) ) { @@ -598,14 +720,21 @@ ivas_error ivas_dec( * - compensation for saturation * - float to integer conversion *----------------------------------------------------------------*/ +#ifdef JBM_TSM_ON_TCS + ivas_limiter_dec( st_ivas->hLimiter, p_output, nchan_out, output_frame, st_ivas->BER_detect ); +#ifdef DEBUGGING + st_ivas->noClipping += +#endif + ivas_syn_output( p_output, output_frame, nchan_out, data ); +#else ivas_limiter_dec( st_ivas->hLimiter, output, nchan_out, output_frame, st_ivas->BER_detect ); #ifdef DEBUGGING st_ivas->noClipping += #endif ivas_syn_output( output, output_frame, nchan_out, data ); - +#endif /*----------------------------------------------------------------* * Common updates *----------------------------------------------------------------*/ diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index dfeb946a02..9bb43b39c9 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -139,6 +139,7 @@ ivas_error ivas_dirac_dec_config( output_Fs = st_ivas->hDecoderConfig->output_Fs; ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; + if ( flag_config == DIRAC_RECONFIGURE ) { hDirAC = st_ivas->hDirAC; @@ -159,7 +160,10 @@ ivas_error ivas_dirac_dec_config( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC Config\n" ) ); } nchan_transport_old = 0; - +#ifdef JBM_TSM_ON_TCS + hDirAC->hParamIsm = NULL; + hDirAC->hParamIsmRendering = NULL; +#endif st_ivas->hDirAC = hDirAC; } @@ -169,6 +173,10 @@ ivas_error ivas_dirac_dec_config( num_outputs_diff_old = 0; num_protos_diff_old = 0; +#ifdef JBM_DIRAC_DEBUG_BE + hDirAC->voip_active = st_ivas->hDecoderConfig->voip_active; +#endif + nchan_transport_orig = st_ivas->nchan_transport; if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR && !( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) { @@ -250,9 +258,18 @@ ivas_error ivas_dirac_dec_config( if ( flag_config == DIRAC_OPEN ) { hDirAC->slot_size = (int16_t) ( ( output_Fs / FRAMES_PER_SEC ) / CLDFB_NO_COL_MAX ); +#ifdef JBM_TSM_ON_TCS + set_s( hDirAC->subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS ); + set_s( hDirAC->subframe_nbslots, JBM_CLDFB_SLOTS_IN_SUBFRAME, DEFAULT_JBM_SUBFRAMES_5MS ); + hDirAC->nb_subframes = DEFAULT_JBM_SUBFRAMES_5MS; + hDirAC->subframes_rendered = 0; + hDirAC->slots_rendered = 0; + hDirAC->num_slots = DEFAULT_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME; +#else hDirAC->subframe_nbslots = (int16_t) ( CLDFB_NO_COL_MAX * 5.f / 20.f + 0.5f ); hDirAC->nb_subframes = CLDFB_NO_COL_MAX / hDirAC->subframe_nbslots; assert( hDirAC->nb_subframes <= MAX_PARAM_SPATIAL_SUBFRAMES ); +#endif } /* band config needed only for SPAR with FOA output */ @@ -824,6 +841,16 @@ ivas_error ivas_dirac_dec_config( if ( st_ivas->mc_mode == MC_MODE_MCMASA ) { hDirAC->dirac_md_buffer_length = MAX_PARAM_SPATIAL_SUBFRAMES; +#ifdef JBM_TSM_ON_TCS + { + int16_t map_idx; + set_s( hDirAC->render_to_md_slot_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME ); + for ( map_idx = 0; map_idx < DEFAULT_JBM_CLDFB_TIMESLOTS; map_idx++ ) + { + hDirAC->render_to_md_slot_map[map_idx] = map_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME; + } + } +#endif } else if ( st_ivas->ivas_format == MASA_FORMAT ) { @@ -851,6 +878,16 @@ ivas_error ivas_dirac_dec_config( hDirAC->dirac_read_idx = 0; hDirAC->dirac_estimator_idx = 0; } +#ifdef JBM_TSM_ON_TCS + { + int16_t map_idx; + set_s( hDirAC->render_to_md_slot_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME ); + for ( map_idx = 0; map_idx < DEFAULT_JBM_CLDFB_TIMESLOTS; map_idx++ ) + { + hDirAC->render_to_md_slot_map[map_idx] = hDirAC->dirac_read_idx + map_idx * num_slots_in_subfr / JBM_CLDFB_SLOTS_IN_SUBFRAME; + } + } +#endif } if ( ( hDirAC->azimuth = (int16_t **) malloc( hDirAC->dirac_md_buffer_length * sizeof( int16_t * ) ) ) == NULL ) @@ -985,7 +1022,31 @@ ivas_error ivas_dirac_dec_config( st_ivas->hDirAC = hDirAC; } - return error; +#ifdef JBM_TSM_ON_TCS + /* allocate transport channels*/ + if ( flag_config == DIRAC_OPEN ) + { + if ( st_ivas->hDecoderConfig->voip_active == 1 && st_ivas->hTcBuffer == NULL && 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->sba_mode == SBA_MODE_DIRAC ) + { + int16_t nchan_to_allocate; + nchan_to_allocate = nchan_transport; + if ( st_ivas->nchan_transport == 1 && ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirAC->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 ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_transport, nchan_to_allocate, nchan_to_allocate, hDirAC->slot_size ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + } + +#endif /* JBM_TMS_ON_TCS*/ + + return error; } @@ -1510,7 +1571,6 @@ void ivas_dirac_dec_read_BS( { int16_t i, j, b, dir, orig_dirac_bands; int16_t next_bit_pos_orig; - *nb_bits = 0; if ( !st->bfi && ivas_total_brate > IVAS_SID_5k2 ) { @@ -1793,6 +1853,7 @@ void ivas_qmetadata_to_dirac( int16_t tmp_write_idx_band; num_slots_in_subfr = hDirAC->hConfig->dec_param_estim ? CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES : 1; + /* ungroup */ seed_ptr = &hDirAC->dithering_seed; nblocks = q_direction->cfg.nblocks; @@ -1837,12 +1898,50 @@ void ivas_qmetadata_to_dirac( { band_start = band_grouping[band]; band_end = band_grouping[band + 1]; +#ifdef JBM_TSM_ON_TCS + tmp_write_idx_param_band = hDirAC->dirac_bs_md_write_idx; + for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) +#else for ( block = 0; block < hDirAC->nb_subframes; block++ ) +#endif { +#ifdef JBM_TSM_ON_TCS + ts_start = hDirAC->block_grouping[block]; + ts_end = hDirAC->block_grouping[block + 1]; +#endif for ( b = band_start; b < band_end; b++ ) { +#ifdef JBM_TSM_ON_TCS + tmp_write_idx_band = tmp_write_idx_param_band; +#endif hDirAC->spreadCoherence[block][b] = 0.0f; hDirAC->surroundingCoherence[block][b] = 0.0f; +#ifdef JBM_TSM_ON_TCS + if ( hDirAC->hConfig->dec_param_estim == FALSE ) + { + hDirAC->elevation[tmp_write_idx_band][b] = 0; + hDirAC->azimuth[tmp_write_idx_band][b] = 0; + hDirAC->diffuseness_vector[tmp_write_idx_band][b] = 0.f; + + hDirAC->spreadCoherence[tmp_write_idx_band][b] = 0.0f; + hDirAC->surroundingCoherence[tmp_write_idx_band][b] = 0.0f; + hDirAC->energy_ratio1[tmp_write_idx_band][b] = 0; + tmp_write_idx_band = ( tmp_write_idx_band + 1 ) % hDirAC->dirac_md_buffer_length; + } + else + { + for ( ts = ts_start; ts < ts_end; ts++ ) + { + hDirAC->elevation[tmp_write_idx_band][b] = 0; + hDirAC->azimuth[tmp_write_idx_band][b] = 0; + hDirAC->diffuseness_vector[tmp_write_idx_band][b] = 0.f; + hDirAC->spreadCoherence[tmp_write_idx_band][b] = 0.0f; + hDirAC->surroundingCoherence[tmp_write_idx_band][b] = 0.0f; + hDirAC->energy_ratio1[tmp_write_idx_band][b] = 0; + tmp_write_idx_band = ( tmp_write_idx_band + 1 ) % hDirAC->dirac_md_buffer_length; + } + } +#endif } } } @@ -1869,7 +1968,11 @@ void ivas_qmetadata_to_dirac( #endif diff_idx = q_direction->band_data[qBand_idx].energy_ratio_index[0]; +#ifdef JBM_TSM_ON_TCS + for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) +#else for ( block = 0; block < hDirAC->nb_subframes; block++ ) +#endif { int16_t block_qmetadata; @@ -1958,7 +2061,11 @@ void ivas_qmetadata_to_dirac( for ( b = band_grouping[band]; b < hDirAC->num_freq_bands; b++ ) { tmp_write_idx_band = hDirAC->dirac_bs_md_write_idx; +#ifdef JBM_TSM_ON_TCS + for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) +#else for ( block = 0; block < hDirAC->nb_subframes; block++ ) +#endif { ts_start = hDirAC->block_grouping[block]; ts_end = hDirAC->block_grouping[block + 1]; @@ -1972,6 +2079,11 @@ void ivas_qmetadata_to_dirac( hDirAC->elevation[tmp_write_idx_band][b] = 0; hDirAC->azimuth[tmp_write_idx_band][b] = 0; hDirAC->diffuseness_vector[tmp_write_idx_band][b] = 0.f; +#ifdef JBM_TSM_ON_TCS + hDirAC->spreadCoherence[tmp_write_idx_band][b] = 0.0f; + hDirAC->surroundingCoherence[tmp_write_idx_band][b] = 0.0f; + hDirAC->energy_ratio1[tmp_write_idx_band][b] = 0; +#endif tmp_write_idx_band = ( tmp_write_idx_band + 1 ) % hDirAC->dirac_md_buffer_length; } else @@ -1981,6 +2093,11 @@ void ivas_qmetadata_to_dirac( hDirAC->elevation[tmp_write_idx_band][b] = 0; hDirAC->azimuth[tmp_write_idx_band][b] = 0; hDirAC->diffuseness_vector[tmp_write_idx_band][b] = 0.f; +#ifdef JBM_TSM_ON_TCS + hDirAC->spreadCoherence[tmp_write_idx_band][b] = 0.0f; + hDirAC->surroundingCoherence[tmp_write_idx_band][b] = 0.0f; + hDirAC->energy_ratio1[tmp_write_idx_band][b] = 0; +#endif tmp_write_idx_band = ( tmp_write_idx_band + 1 ) % hDirAC->dirac_md_buffer_length; } } @@ -2002,29 +2119,209 @@ void ivas_qmetadata_to_dirac( } +#ifdef JBM_TSM_ON_TCS +void ivas_dirac_dec_set_md_map( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + int16_t nCldfbTs ) +{ + int16_t num_slots_in_subfr; + DIRAC_DEC_HANDLE hDirAC; + + hDirAC = st_ivas->hDirAC; +#ifdef DEBUGGING + assert( hDirAC ); +#endif + + /* adapt subframes */ + hDirAC->num_slots = nCldfbTs; + hDirAC->slots_rendered = 0; + if ( hDirAC->hParamIsm != NULL || hDirAC->hConfig->dec_param_estim == 0 ) + { + num_slots_in_subfr = CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; + } + else + { + num_slots_in_subfr = 1; + } + hDirAC->subframes_rendered = 0; + + ivas_jbm_dec_get_adapted_subframes( nCldfbTs, hDirAC->subframe_nbslots, &hDirAC->nb_subframes ); + + /* set mapping according to dirac_read_idx */ + + set_s( hDirAC->render_to_md_slot_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME ); + + ivas_jbm_dec_get_md_map( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbTs, num_slots_in_subfr, hDirAC->dirac_read_idx, hDirAC->dirac_md_buffer_length, hDirAC->render_to_md_slot_map ); + + + return; +} /*------------------------------------------------------------------------- * ivas_dirac_dec() * * DirAC decoding process *------------------------------------------------------------------------*/ +void ivas_dirac_dec( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ + const int16_t nchan_transport /* i : number of transport channels */ +) +{ + 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; + nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; + + n_samples_sf = JBM_CLDFB_SLOTS_IN_SUBFRAME * st_ivas->hDirAC->slot_size; + for ( n = 0; n < nchan_out; n++ ) + { + output_f_local[n] = &output_f[n][0]; + } + 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->sba_mode != SBA_MODE_SPAR ) + { + 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 < MAX_PARAM_SPATIAL_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 ) + { + st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % st_ivas->hDirAC->dirac_md_buffer_length; + } + else + { + st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % st_ivas->hDirAC->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->sba_mode != SBA_MODE_SPAR ) + { + st_ivas->hTcBuffer->tc[nchan_transport] = NULL; + } + + return; +} + +void ivas_dirac_dec_render( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const int16_t nchan_transport, /* i : number of transport channels */ + const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ + uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ + uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ + float *output_f[] /* o : rendered time signal */ +) +{ + int16_t slots_to_render, first_sf, last_sf, subframe_idx; + uint16_t slot_size, n_samples_sf, ch, nchan_intern; + DIRAC_DEC_HANDLE hDirAC; + float *output_f_local[MAX_OUTPUT_CHANNELS]; + + hDirAC = st_ivas->hDirAC; + + nchan_intern = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; +#ifdef DEBUGGING + assert( hDirAC ); +#endif + for ( ch = 0; ch < nchan_intern; ch++ ) + { + output_f_local[ch] = output_f[ch]; + } + slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); + /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ + slots_to_render = min( hDirAC->num_slots - hDirAC->slots_rendered, nSamplesAsked / slot_size ); + *nSamplesRendered = slots_to_render * slot_size; + first_sf = hDirAC->subframes_rendered; + last_sf = first_sf; + while ( slots_to_render > 0 ) + { + slots_to_render -= hDirAC->subframe_nbslots[last_sf]; + last_sf++; + } +#ifdef DEBUGGING + assert( slots_to_render == 0 ); +#endif + for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) + { + ivas_dirac_dec_render_sf( st_ivas, output_f_local, nchan_transport, NULL, NULL ); + n_samples_sf = hDirAC->subframe_nbslots[subframe_idx] * st_ivas->hDirAC->slot_size; + for ( ch = 0; ch < nchan_intern; ch++ ) + { + output_f_local[ch] += n_samples_sf; + } + } + if ( hDirAC->slots_rendered == hDirAC->num_slots ) + { + if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) + { + st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % st_ivas->hDirAC->dirac_md_buffer_length; + } + else + { + st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % st_ivas->hDirAC->dirac_md_buffer_length; + } + } + *nSamplesAvailable = ( hDirAC->num_slots - hDirAC->slots_rendered ) * slot_size; + return; +} +#endif + +/*------------------------------------------------------------------------- + * ivas_dirac_dec() + * + * DirAC decoding process + *------------------------------------------------------------------------*/ +#ifndef JBM_TSM_ON_TCS void ivas_dirac_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ +#else +void ivas_dirac_dec_render_sf( +#endif + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ +#ifdef JBM_TSM_ON_TCS + float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ +#else + float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ +#endif const int16_t nchan_transport, /* i : number of transport channels */ float *pppQMfFrame_ts_re[IVAS_MAX_FB_MIXER_IN_CH][CLDFB_NO_COL_MAX], - float *pppQMfFrame_ts_im[IVAS_MAX_FB_MIXER_IN_CH][CLDFB_NO_COL_MAX], - const int16_t i_sf ) + float *pppQMfFrame_ts_im[IVAS_MAX_FB_MIXER_IN_CH][CLDFB_NO_COL_MAX] +#ifndef JBM_TSM_ON_TCS + , + const int16_t i_sf +#endif +) { int16_t i, ch, idx_in, idx_lfe; DIRAC_DEC_HANDLE hDirAC; +#if defined( JBM_DIRAC_DEBUG_BE ) || !defined( JBM_TSM_ON_TCS ) float dirEne; float surCohEner; float surCohRatio[CLDFB_NO_CHANNELS_MAX]; +#endif int16_t subframe_idx; +#ifndef JBM_TSM_ON_TCS int16_t sf1, sf2; +#endif int16_t slot_idx, index_slot; float *p_Rmat; +#ifdef JBM_TSM_ON_TCS + int16_t slot_idx_start, slot_idx_start_cldfb_synth; +#endif /*CLDFB: last output channels reserved to LFT for CICPx*/ float Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; @@ -2033,12 +2330,23 @@ void ivas_dirac_dec( float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; int16_t index, num_freq_bands; +#ifdef JBM_TSM_ON_TCS + /* local copies of azi, ele, diffuseness */ + int16_t azimuth[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + int16_t elevation[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float diffuseness_vector[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; +#endif + 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; +#ifndef JBM_TSM_ON_TCS push_wmops( "ivas_dirac_dec" ); +#else + push_wmops( "ivas_dirac_dec_render" ); +#endif /* Initialize aux buffers */ hDirAC = st_ivas->hDirAC; @@ -2078,7 +2386,7 @@ void ivas_dirac_dec( #endif /* Subframe loop */ - +#ifndef JBM_TSM_ON_TCS if ( i_sf == -1 ) { sf1 = 0; @@ -2089,86 +2397,164 @@ void ivas_dirac_dec( sf1 = i_sf; sf2 = i_sf + 1; } +#endif +#ifdef JBM_TSM_ON_TCS + slot_idx_start = hDirAC->slots_rendered; + slot_idx_start_cldfb_synth = 0; +#endif +#ifdef JBM_TSM_ON_TCS + subframe_idx = hDirAC->subframes_rendered; +#else for ( subframe_idx = sf1; subframe_idx < sf2; subframe_idx++ ) { - if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD ) - { - set_zero( reference_power_smooth, hDirAC->num_freq_bands ); - } - else +#endif +#ifdef JBM_TSM_ON_TCS + + /* Another workaround for self test BE */ + if ( st_ivas->hHeadTrackData && st_ivas->hDecoderConfig->voip_active == 0 ) + { + QuatToRotMat( st_ivas->hHeadTrackData->Quaternions[st_ivas->hHeadTrackData->num_quaternions++], st_ivas->hHeadTrackData->Rmat ); + + p_Rmat = &st_ivas->hHeadTrackData->Rmat[0][0]; + + if ( st_ivas->hHeadTrackData->shd_rot_max_order == 0 ) { - set_zero( onset_filter_subframe, hDirAC->num_freq_bands ); + num_freq_bands = hDirAC->band_grouping[hDirAC->hConfig->enc_param_start_band]; + for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) + { + index_slot = slot_idx_start + slot_idx; + rotateAziEle_DirAC( hDirAC->azimuth[index_slot], hDirAC->elevation[index_slot], num_freq_bands, hDirAC->num_freq_bands, p_Rmat ); + } } + } + else + { + p_Rmat = 0; + } + /* copy parameters into local buffers*/ + for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) + { + mvs2s( hDirAC->azimuth[hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]], azimuth[slot_idx], hDirAC->num_freq_bands ); + mvs2s( hDirAC->elevation[hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]], elevation[slot_idx], hDirAC->num_freq_bands ); + mvr2r( hDirAC->diffuseness_vector[hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]], diffuseness_vector[slot_idx], hDirAC->num_freq_bands ); + } +#endif + if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD ) + { + set_zero( reference_power_smooth, hDirAC->num_freq_bands ); + } + else + { + set_zero( onset_filter_subframe, hDirAC->num_freq_bands ); + } + +#ifdef JBM_TSM_ON_TCS + if ( st_ivas->hHeadTrackData && st_ivas->hDecoderConfig->voip_active == 1 ) +#else if ( st_ivas->hHeadTrackData ) - { - QuatToRotMat( st_ivas->hHeadTrackData->Quaternions[st_ivas->hHeadTrackData->num_quaternions++], st_ivas->hHeadTrackData->Rmat ); +#endif + { + QuatToRotMat( st_ivas->hHeadTrackData->Quaternions[st_ivas->hHeadTrackData->num_quaternions++], st_ivas->hHeadTrackData->Rmat ); - p_Rmat = &st_ivas->hHeadTrackData->Rmat[0][0]; + p_Rmat = &st_ivas->hHeadTrackData->Rmat[0][0]; - if ( st_ivas->hHeadTrackData->shd_rot_max_order == 0 ) - { - num_freq_bands = hDirAC->band_grouping[hDirAC->hConfig->enc_param_start_band]; + if ( st_ivas->hHeadTrackData->shd_rot_max_order == 0 ) + { + num_freq_bands = hDirAC->band_grouping[hDirAC->hConfig->enc_param_start_band]; +#ifdef JBM_TSM_ON_TCS + for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) +#else for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots; slot_idx++ ) - { +#endif + { +#ifdef JBM_TSM_ON_TCS + rotateAziEle_DirAC( azimuth[slot_idx], elevation[slot_idx], num_freq_bands, hDirAC->num_freq_bands, p_Rmat ); + +#else + /* note, this seems wrong since it does not take the dirac read ptr into account */ index_slot = subframe_idx * hDirAC->subframe_nbslots + slot_idx; /* Todo: This access to azimuth & elevation may use wrong indices as access should probably be based on hDirAC->dirac_read_idx */ rotateAziEle_DirAC( hDirAC->azimuth[index_slot], hDirAC->elevation[index_slot], num_freq_bands, hDirAC->num_freq_bands, p_Rmat ); - } +#endif } } + } +#ifdef JBM_TSM_ON_TCS + else if ( !st_ivas->hHeadTrackData ) +#else else - { - p_Rmat = 0; - } +#endif + { + p_Rmat = 0; + } - if ( hDirAC->hConfig->dec_param_estim == FALSE ) +#if defined( JBM_DIRAC_DEBUG_BE ) || !defined( JBM_TSM_ON_TCS ) +#ifdef JBM_DIRAC_DEBUG_BE + if ( st_ivas->hDecoderConfig->voip_active == 0 && hDirAC->hConfig->dec_param_estim == FALSE ) +#else + if ( hDirAC->hConfig->dec_param_estim == FALSE ) +#endif + { +#ifdef JBM_TSM_ON_TCS + int16_t md_idx = hDirAC->render_to_md_slot_map[slot_idx_start]; +#endif + /* compute response */ + if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD ) { - /* compute response */ - if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD ) - { - ivas_dirac_dec_compute_power_factors( hDirAC->num_freq_bands, - hDirAC->diffuseness_vector[hDirAC->dirac_read_idx], - hDirAC->h_output_synthesis_psd_params.max_band_decorr, - hDirAC->h_output_synthesis_psd_state.direct_power_factor, - hDirAC->h_output_synthesis_psd_state.diffuse_power_factor ); + ivas_dirac_dec_compute_power_factors( hDirAC->num_freq_bands, +#ifdef JBM_TSM_ON_TCS + diffuseness_vector[0], +#else + hDirAC->diffuseness_vector[hDirAC->dirac_read_idx], +#endif + hDirAC->h_output_synthesis_psd_params.max_band_decorr, + hDirAC->h_output_synthesis_psd_state.direct_power_factor, + hDirAC->h_output_synthesis_psd_state.diffuse_power_factor ); - if ( coherence_flag ) + if ( coherence_flag ) + { + for ( i = 0; i < hDirAC->num_freq_bands; i++ ) { - for ( i = 0; i < hDirAC->num_freq_bands; i++ ) - { - dirEne = hDirAC->h_output_synthesis_psd_state.direct_power_factor[i]; - surCohEner = hDirAC->h_output_synthesis_psd_state.diffuse_power_factor[i] * hDirAC->surroundingCoherence[hDirAC->dirac_read_idx][i]; - hDirAC->h_output_synthesis_psd_state.diffuse_power_factor[i] -= surCohEner; - hDirAC->h_output_synthesis_psd_state.direct_power_factor[i] += surCohEner; + dirEne = hDirAC->h_output_synthesis_psd_state.direct_power_factor[i]; +#ifdef JBM_TSM_ON_TCS + surCohEner = hDirAC->h_output_synthesis_psd_state.diffuse_power_factor[i] * hDirAC->surroundingCoherence[md_idx][i]; +#else + surCohEner = hDirAC->h_output_synthesis_psd_state.diffuse_power_factor[i] * hDirAC->surroundingCoherence[hDirAC->dirac_read_idx][i]; +#endif + hDirAC->h_output_synthesis_psd_state.diffuse_power_factor[i] -= surCohEner; + hDirAC->h_output_synthesis_psd_state.direct_power_factor[i] += surCohEner; - surCohRatio[i] = surCohEner / ( 1e-12f + dirEne + surCohEner ); - } - } - else - { - set_zero( surCohRatio, hDirAC->num_freq_bands ); + surCohRatio[i] = surCohEner / ( 1e-12f + dirEne + surCohEner ); } } else { - ivas_dirac_dec_compute_gain_factors( hDirAC->num_freq_bands, - hDirAC->diffuseness_vector[hDirAC->dirac_read_idx], - hDirAC->h_output_synthesis_psd_params.max_band_decorr, - hDirAC->h_output_synthesis_psd_state.direct_power_factor, - hDirAC->h_output_synthesis_psd_state.diffuse_power_factor ); + set_zero( surCohRatio, hDirAC->num_freq_bands ); + } + } + else + { + ivas_dirac_dec_compute_gain_factors( hDirAC->num_freq_bands, +#ifdef JBM_TSM_ON_TCS + diffuseness_vector[0], +#else + hDirAC->diffuseness_vector[hDirAC->dirac_read_idx], +#endif + hDirAC->h_output_synthesis_psd_params.max_band_decorr, + hDirAC->h_output_synthesis_psd_state.direct_power_factor, + hDirAC->h_output_synthesis_psd_state.diffuse_power_factor ); - if ( coherence_flag ) - { - for ( i = 0; i < hDirAC->num_freq_bands; i++ ) - { - surCohRatio[i] = hDirAC->surroundingCoherence[hDirAC->dirac_read_idx][i]; - } - } - else + if ( coherence_flag ) + { + for ( i = 0; i < hDirAC->num_freq_bands; i++ ) { - set_zero( surCohRatio, hDirAC->num_freq_bands ); +#ifdef JBM_TSM_ON_TCS + surCohRatio[i] = hDirAC->surroundingCoherence[md_idx][i]; +#else + surCohRatio[i] = hDirAC->surroundingCoherence[hDirAC->dirac_read_idx][i]; +#endif } } @@ -2192,521 +2578,736 @@ void ivas_dirac_dec( } } - for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots; slot_idx++ ) + if ( st_ivas->hDecoderConfig->Opt_Headrotation && st_ivas->hHeadTrackData->shd_rot_max_order == 1 ) + { + ivas_dirac_dec_compute_directional_responses( hDirAC, + st_ivas->hVBAPdata, + st_ivas->hMasa, +#ifdef JBM_TSM_ON_TCS + azimuth[0], + elevation[0], + md_idx, +#else + subframe_idx, + subframe_idx, +#endif + surCohRatio, + st_ivas->hHeadTrackData->shd_rot_max_order, + p_Rmat ); + } + else { + ivas_dirac_dec_compute_directional_responses( hDirAC, + st_ivas->hVBAPdata, + st_ivas->hMasa, +#ifdef JBM_TSM_ON_TCS + azimuth[0], + elevation[0], + md_idx, +#else + subframe_idx, + subframe_idx, +#endif + surCohRatio, + 0, + 0 ); + } + } +#endif + +#ifdef JBM_TSM_ON_TCS + for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) +#else + for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots; slot_idx++ ) +#endif + { +#ifdef JBM_TSM_ON_TCS + index_slot = slot_idx_start + slot_idx; +#else index_slot = subframe_idx * hDirAC->subframe_nbslots + slot_idx; +#endif - if ( st_ivas->sba_mode == SBA_MODE_SPAR ) + if ( st_ivas->sba_mode == SBA_MODE_SPAR ) + { + for ( ch = 0; ch < nchan_transport; ch++ ) { - for ( ch = 0; ch < nchan_transport; ch++ ) - { - mvr2r( pppQMfFrame_ts_re[ch][slot_idx], Cldfb_RealBuffer[ch][0], hDirAC->num_freq_bands ); - mvr2r( pppQMfFrame_ts_im[ch][slot_idx], Cldfb_ImagBuffer[ch][0], hDirAC->num_freq_bands ); - } + mvr2r( pppQMfFrame_ts_re[ch][slot_idx], Cldfb_RealBuffer[ch][0], hDirAC->num_freq_bands ); + mvr2r( pppQMfFrame_ts_im[ch][slot_idx], Cldfb_ImagBuffer[ch][0], hDirAC->num_freq_bands ); } - else + } + else + { + /* CLDFB Analysis*/ + for ( ch = 0; ch < nchan_transport; ch++ ) { - /* CLDFB Analysis*/ - for ( ch = 0; ch < nchan_transport; ch++ ) - { +#ifdef JBM_TSM_ON_TCS + cldfbAnalysis_ts( &( st_ivas->hTcBuffer->tc[sba_map_tc[ch]][hDirAC->num_freq_bands * index_slot] ), + Cldfb_RealBuffer[ch][0], + Cldfb_ImagBuffer[ch][0], + hDirAC->num_freq_bands, + st_ivas->cldfbAnaDec[ch] ); +#else cldfbAnalysis_ts( &( output_f[sba_map_tc[ch]][hDirAC->num_freq_bands * index_slot] ), Cldfb_RealBuffer[ch][0], Cldfb_ImagBuffer[ch][0], hDirAC->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); - } +#endif } + } - /* CNG in DirAC, extra CLDFB ana for CNA*/ - if ( st_ivas->nchan_transport == 1 && st_ivas->hSCE[0]->hCoreCoder[0] != NULL && st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->sba_mode != SBA_MODE_SPAR ) - { - Decoder_State *st = st_ivas->hSCE[0]->hCoreCoder[0]; + /* CNG in DirAC, extra CLDFB ana for CNA*/ + if ( st_ivas->nchan_transport == 1 && st_ivas->hSCE[0]->hCoreCoder[0] != NULL && st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->sba_mode != SBA_MODE_SPAR ) + { + Decoder_State *st = st_ivas->hSCE[0]->hCoreCoder[0]; - generate_masking_noise_dirac( st->hFdCngDec->hFdCngCom, - st_ivas->cldfbAnaDec[1], + generate_masking_noise_dirac( st->hFdCngDec->hFdCngCom, + st_ivas->cldfbAnaDec[1], +#ifdef JBM_TSM_ON_TCS + st_ivas->hTcBuffer->tc[1], +#else &( output_f[1][L_FRAME48k - L_FRAME16k] ), - Cldfb_RealBuffer[1][0], - Cldfb_ImagBuffer[1][0], - index_slot, - st->cna_dirac_flag && st->flag_cna, - ( st->core_brate == FRAME_NO_DATA || st->core_brate == SID_2k40 ) && st->cng_type == FD_CNG && st->cng_sba_flag ); - } - - /* LFE synthesis */ - if ( st_ivas->mc_mode == MC_MODE_MCMASA && !hDirAC->hOutSetup.separateChannelEnabled && !( hDirAC->hOutSetup.output_config == AUDIO_CONFIG_LS_CUSTOM && hDirAC->hOutSetup.num_lfe == 0 ) ) - { - ivas_lfe_synth_with_cldfb( st_ivas->hMasa->hMasaLfeSynth, - Cldfb_RealBuffer, Cldfb_ImagBuffer, - Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS - 1], Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS - 1], - slot_idx, +#endif + Cldfb_RealBuffer[1][0], + Cldfb_ImagBuffer[1][0], + index_slot, + st->cna_dirac_flag && st->flag_cna, + ( st->core_brate == FRAME_NO_DATA || st->core_brate == SID_2k40 ) && st->cng_type == FD_CNG && st->cng_sba_flag ); + } + + /* LFE synthesis */ + if ( st_ivas->mc_mode == MC_MODE_MCMASA && !hDirAC->hOutSetup.separateChannelEnabled && !( hDirAC->hOutSetup.output_config == AUDIO_CONFIG_LS_CUSTOM && hDirAC->hOutSetup.num_lfe == 0 ) ) + { + ivas_lfe_synth_with_cldfb( st_ivas->hMasa->hMasaLfeSynth, + Cldfb_RealBuffer, Cldfb_ImagBuffer, + Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS - 1], Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS - 1], + slot_idx, +#ifdef JBM_TSM_ON_TCS + hDirAC->render_to_md_slot_map[index_slot], +#else subframe_idx, - nchan_transport ); - } +#endif + nchan_transport ); + } - /*-----------------------------------------------------------------* - * protoype signal computation - *-----------------------------------------------------------------*/ + /*-----------------------------------------------------------------* + * protoype signal computation + *-----------------------------------------------------------------*/ - if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) + if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) + { + if ( st_ivas->hDecoderConfig->Opt_Headrotation && st_ivas->hHeadTrackData->shd_rot_max_order == 0 ) { - if ( st_ivas->hDecoderConfig->Opt_Headrotation && st_ivas->hHeadTrackData->shd_rot_max_order == 0 ) - { - protoSignalComputation_shd( Cldfb_RealBuffer, Cldfb_ImagBuffer, - hDirAC->h_output_synthesis_psd_state.proto_direct_buffer_f, - hDirAC->h_output_synthesis_psd_state.proto_diffuse_buffer_f, - reference_power, slot_idx, nchan_transport, - hDirAC->num_outputs_diff, - hDirAC->num_freq_bands, - p_Rmat ); - } - else - { - protoSignalComputation_shd( Cldfb_RealBuffer, Cldfb_ImagBuffer, - hDirAC->h_output_synthesis_psd_state.proto_direct_buffer_f, - hDirAC->h_output_synthesis_psd_state.proto_diffuse_buffer_f, - reference_power, slot_idx, nchan_transport, - hDirAC->num_outputs_diff, - hDirAC->num_freq_bands, - 0 ); - } + protoSignalComputation_shd( Cldfb_RealBuffer, Cldfb_ImagBuffer, + hDirAC->h_output_synthesis_psd_state.proto_direct_buffer_f, + hDirAC->h_output_synthesis_psd_state.proto_diffuse_buffer_f, + reference_power, slot_idx, nchan_transport, + hDirAC->num_outputs_diff, + hDirAC->num_freq_bands, + p_Rmat ); } - else if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_MONO ) + else { - protoSignalComputation2( Cldfb_RealBuffer, Cldfb_ImagBuffer, hDirAC->proto_frame_f, - hDirAC->h_output_synthesis_psd_state.proto_direct_buffer_f, - reference_power, hDirAC->h_output_synthesis_psd_state.proto_power_smooth, - 0, slot_idx, hDirAC->num_freq_bands, hDirAC->masa_stereo_type_detect ); + protoSignalComputation_shd( Cldfb_RealBuffer, Cldfb_ImagBuffer, + hDirAC->h_output_synthesis_psd_state.proto_direct_buffer_f, + hDirAC->h_output_synthesis_psd_state.proto_diffuse_buffer_f, + reference_power, slot_idx, nchan_transport, + hDirAC->num_outputs_diff, + hDirAC->num_freq_bands, + 0 ); } - else + } + else if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_MONO ) + { + protoSignalComputation2( Cldfb_RealBuffer, Cldfb_ImagBuffer, hDirAC->proto_frame_f, + hDirAC->h_output_synthesis_psd_state.proto_direct_buffer_f, + reference_power, hDirAC->h_output_synthesis_psd_state.proto_power_smooth, + 0, slot_idx, hDirAC->num_freq_bands, hDirAC->masa_stereo_type_detect ); + } + else + { + switch ( nchan_transport ) { - switch ( nchan_transport ) - { - case 8: - case 6: - case 4: - protoSignalComputation4( Cldfb_RealBuffer, Cldfb_ImagBuffer, - hDirAC->proto_frame_f, - hDirAC->h_output_synthesis_psd_state.proto_direct_buffer_f, - reference_power, - hDirAC->h_output_synthesis_psd_state.proto_power_smooth, - slot_idx, hDirAC->num_outputs_diff, - hDirAC->num_freq_bands, - hDirAC->hoa_decoder, - nchan_transport ); - break; - case 2: - protoSignalComputation2( Cldfb_RealBuffer, Cldfb_ImagBuffer, - hDirAC->proto_frame_f, - hDirAC->h_output_synthesis_psd_state.proto_direct_buffer_f, - reference_power, - hDirAC->h_output_synthesis_psd_state.proto_power_smooth, - hDirAC->hOutSetup.is_loudspeaker_setup, - slot_idx, - hDirAC->num_freq_bands, - hDirAC->masa_stereo_type_detect ); - break; - case 1: - protoSignalComputation1( Cldfb_RealBuffer, Cldfb_ImagBuffer, - hDirAC->proto_frame_f, - hDirAC->h_output_synthesis_psd_state.proto_direct_buffer_f, - reference_power, - hDirAC->h_output_synthesis_psd_state.proto_power_smooth, - slot_idx, - hDirAC->num_protos_diff, - hDirAC->num_freq_bands ); - break; - default: - return; - } + case 8: + case 6: + case 4: + protoSignalComputation4( Cldfb_RealBuffer, Cldfb_ImagBuffer, + hDirAC->proto_frame_f, + hDirAC->h_output_synthesis_psd_state.proto_direct_buffer_f, + reference_power, + hDirAC->h_output_synthesis_psd_state.proto_power_smooth, + slot_idx, hDirAC->num_outputs_diff, + hDirAC->num_freq_bands, + hDirAC->hoa_decoder, + nchan_transport ); + break; + case 2: + protoSignalComputation2( Cldfb_RealBuffer, Cldfb_ImagBuffer, + hDirAC->proto_frame_f, + hDirAC->h_output_synthesis_psd_state.proto_direct_buffer_f, + reference_power, + hDirAC->h_output_synthesis_psd_state.proto_power_smooth, + hDirAC->hOutSetup.is_loudspeaker_setup, + slot_idx, + hDirAC->num_freq_bands, + hDirAC->masa_stereo_type_detect ); + break; + case 1: + protoSignalComputation1( Cldfb_RealBuffer, Cldfb_ImagBuffer, + hDirAC->proto_frame_f, + hDirAC->h_output_synthesis_psd_state.proto_direct_buffer_f, + reference_power, + hDirAC->h_output_synthesis_psd_state.proto_power_smooth, + slot_idx, + hDirAC->num_protos_diff, + hDirAC->num_freq_bands ); + break; + default: + return; } + } - /*-----------------------------------------------------------------* - * Compute DirAC parameters at decoder side - *-----------------------------------------------------------------*/ - - if ( hDirAC->hConfig->dec_param_estim == TRUE ) - { - hDirAC->index_buffer_intensity = ( hDirAC->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ) + 1; /* averaging_length = 32 */ + /*-----------------------------------------------------------------* + * Compute DirAC parameters at decoder side + *-----------------------------------------------------------------*/ - index = hDirAC->index_buffer_intensity; + if ( hDirAC->hConfig->dec_param_estim == TRUE ) + { + hDirAC->index_buffer_intensity = ( hDirAC->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ) + 1; /* averaging_length = 32 */ - num_freq_bands = hDirAC->band_grouping[hDirAC->hConfig->enc_param_start_band]; + index = hDirAC->index_buffer_intensity; - computeIntensityVector_dec( Cldfb_RealBuffer, - Cldfb_ImagBuffer, - num_freq_bands, - hDirAC->buffer_intensity_real[0][index - 1], - hDirAC->buffer_intensity_real[1][index - 1], - hDirAC->buffer_intensity_real[2][index - 1] ); + num_freq_bands = hDirAC->band_grouping[hDirAC->hConfig->enc_param_start_band]; - computeDirectionAngles( hDirAC->buffer_intensity_real[0][index - 1], - hDirAC->buffer_intensity_real[1][index - 1], - hDirAC->buffer_intensity_real[2][index - 1], + computeIntensityVector_dec( Cldfb_RealBuffer, + Cldfb_ImagBuffer, num_freq_bands, + hDirAC->buffer_intensity_real[0][index - 1], + hDirAC->buffer_intensity_real[1][index - 1], + hDirAC->buffer_intensity_real[2][index - 1] ); + computeDirectionAngles( hDirAC->buffer_intensity_real[0][index - 1], + hDirAC->buffer_intensity_real[1][index - 1], + hDirAC->buffer_intensity_real[2][index - 1], + num_freq_bands, +#ifdef JBM_TSM_ON_TCS + azimuth[slot_idx], + elevation[slot_idx] +#else hDirAC->azimuth[hDirAC->dirac_estimator_idx], - hDirAC->elevation[hDirAC->dirac_estimator_idx] ); + hDirAC->elevation[hDirAC->dirac_estimator_idx] +#endif + ); - mvr2r( reference_power, &( hDirAC->buffer_energy[( index - 1 ) * num_freq_bands] ), num_freq_bands ); + mvr2r( reference_power, &( hDirAC->buffer_energy[( index - 1 ) * num_freq_bands] ), num_freq_bands ); - computeDiffuseness( hDirAC->buffer_intensity_real, - hDirAC->buffer_energy, - num_freq_bands, - hDirAC->diffuseness_vector[hDirAC->dirac_estimator_idx] ); + computeDiffuseness( hDirAC->buffer_intensity_real, + hDirAC->buffer_energy, + num_freq_bands, +#ifdef JBM_TSM_ON_TCS + diffuseness_vector[slot_idx] +#else + hDirAC->diffuseness_vector[hDirAC->dirac_estimator_idx] +#endif + ); - hDirAC->dirac_estimator_idx = ( hDirAC->dirac_estimator_idx + 1 ) % hDirAC->dirac_md_buffer_length; - } +#ifndef JBM_TSM_ON_TCS + hDirAC->dirac_estimator_idx = ( hDirAC->dirac_estimator_idx + 1 ) % hDirAC->dirac_md_buffer_length; +#endif + } #ifdef DEBUG_MODE_DIRAC - { - static FILE *fp_direction_vector = NULL, *fp_diffuseness = NULL, *fp_referencePower = NULL; + { + static FILE *fp_direction_vector = NULL, *fp_diffuseness = NULL, *fp_referencePower = NULL; - if ( fp_direction_vector == NULL ) - fp_direction_vector = fopen( "./res/dbg_direction_vector_C_dec.bin", "wb" ); - if ( fp_diffuseness == NULL ) - fp_diffuseness = fopen( "./res/dbg_diffuseness_C_dec.bin", "wb" ); - if ( fp_referencePower == NULL ) - fp_referencePower = fopen( "./res/dbg_reference_power_C_dec.bin", "wb" ); + if ( fp_direction_vector == NULL ) + fp_direction_vector = fopen( "./res/dbg_direction_vector_C_dec.bin", "wb" ); + if ( fp_diffuseness == NULL ) + fp_diffuseness = fopen( "./res/dbg_diffuseness_C_dec.bin", "wb" ); + if ( fp_referencePower == NULL ) + fp_referencePower = fopen( "./res/dbg_reference_power_C_dec.bin", "wb" ); - for ( i = 0; i < hDirAC->num_freq_bands; i++ ) - { - float radius_length; - float dv[3]; + for ( i = 0; i < hDirAC->num_freq_bands; i++ ) + { + float radius_length; + float dv[3]; - if ( hDirAC->hConfig->dec_param_estim == FALSE ) - { - radius_length = cos( hDirAC->elevation[subframe_idx][i] * PI_OVER_180 ); - dv[0] = radius_length * cos( hDirAC->azimuth[subframe_idx][i] * PI_OVER_180 ); - dv[1] = radius_length * sin( hDirAC->azimuth[subframe_idx][i] * PI_OVER_180 ); - dv[2] = sin( hDirAC->elevation[subframe_idx][i] * PI_OVER_180 ); - - fwrite( dv, sizeof( float ), 3, fp_direction_vector ); - fwrite( &( hDirAC->diffuseness_vector[0][i] ), sizeof( float ), 1, fp_diffuseness ); - if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) - { - reference_power[i] = Cldfb_RealBuffer[0][0][i] * Cldfb_RealBuffer[0][0][i] + Cldfb_ImagBuffer[0][0][i] * Cldfb_ImagBuffer[0][0][i]; - } - fwrite( &( reference_power[i] ), sizeof( float ), 1, fp_referencePower ); - } - else + if ( hDirAC->hConfig->dec_param_estim == FALSE ) + { + radius_length = cos( hDirAC->elevation[subframe_idx][i] * PI_OVER_180 ); + dv[0] = radius_length * cos( hDirAC->azimuth[subframe_idx][i] * PI_OVER_180 ); + dv[1] = radius_length * sin( hDirAC->azimuth[subframe_idx][i] * PI_OVER_180 ); + dv[2] = sin( hDirAC->elevation[subframe_idx][i] * PI_OVER_180 ); + + fwrite( dv, sizeof( float ), 3, fp_direction_vector ); + fwrite( &( hDirAC->diffuseness_vector[0][i] ), sizeof( float ), 1, fp_diffuseness ); + if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { - radius_length = cos( hDirAC->elevation[index_slot][i] * PI_OVER_180 ); - dv[0] = radius_length * cos( hDirAC->azimuth[index_slot][i] * PI_OVER_180 ); - dv[1] = radius_length * sin( hDirAC->azimuth[index_slot][i] * PI_OVER_180 ); - dv[2] = sin( hDirAC->elevation[index_slot][i] * PI_OVER_180 ); - - fwrite( dv, sizeof( float ), 3, fp_direction_vector ); - fwrite( &( hDirAC->diffuseness_vector[index_slot][i] ), sizeof( float ), 1, fp_diffuseness ); - fwrite( &( reference_power[i] ), sizeof( float ), 1, fp_referencePower ); + reference_power[i] = Cldfb_RealBuffer[0][0][i] * Cldfb_RealBuffer[0][0][i] + Cldfb_ImagBuffer[0][0][i] * Cldfb_ImagBuffer[0][0][i]; } + fwrite( &( reference_power[i] ), sizeof( float ), 1, fp_referencePower ); + } + else + { + radius_length = cos( hDirAC->elevation[index_slot][i] * PI_OVER_180 ); + dv[0] = radius_length * cos( hDirAC->azimuth[index_slot][i] * PI_OVER_180 ); + dv[1] = radius_length * sin( hDirAC->azimuth[index_slot][i] * PI_OVER_180 ); + dv[2] = sin( hDirAC->elevation[index_slot][i] * PI_OVER_180 ); + + fwrite( dv, sizeof( float ), 3, fp_direction_vector ); + fwrite( &( hDirAC->diffuseness_vector[index_slot][i] ), sizeof( float ), 1, fp_diffuseness ); + fwrite( &( reference_power[i] ), sizeof( float ), 1, fp_referencePower ); } } + } #endif - /*-----------------------------------------------------------------* - * frequency domain decorrelation - *-----------------------------------------------------------------*/ + /*-----------------------------------------------------------------* + * frequency domain decorrelation + *-----------------------------------------------------------------*/ - if ( hDirAC->proto_signal_decorr_on == 1 ) + if ( hDirAC->proto_signal_decorr_on == 1 ) + { + /* decorrelate prototype frame */ + if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { - /* decorrelate prototype frame */ - if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) - { - ivas_dirac_dec_decorr_process( hDirAC->num_freq_bands, - hDirAC->num_outputs_diff, - hDirAC->num_protos_diff, - hDirAC->synthesisConf, - nchan_transport, - hDirAC->h_output_synthesis_psd_state.proto_diffuse_buffer_f + slot_idx * 2 * hDirAC->num_freq_bands * hDirAC->num_outputs_diff, - hDirAC->num_protos_diff, - hDirAC->proto_index_diff, - hDirAC->h_output_synthesis_psd_state.proto_diffuse_buffer_f + slot_idx * 2 * hDirAC->num_freq_bands * hDirAC->num_outputs_diff + 2 * hDirAC->num_freq_bands * min( 4, nchan_transport ), - onset_filter, - hDirAC->h_freq_domain_decorr_ap_params, - hDirAC->h_freq_domain_decorr_ap_state ); - - v_multc( onset_filter, 0.25f, onset_filter, hDirAC->num_freq_bands ); - v_add( onset_filter, onset_filter_subframe, onset_filter_subframe, hDirAC->num_freq_bands ); - p_onset_filter = onset_filter_subframe; - } - else - { - ivas_dirac_dec_decorr_process( hDirAC->num_freq_bands, - hDirAC->num_outputs_diff, - hDirAC->num_protos_diff, - hDirAC->synthesisConf, - nchan_transport, - hDirAC->proto_frame_f, - hDirAC->num_protos_diff, - hDirAC->proto_index_diff, - DirAC_mem.frame_dec_f, - onset_filter, - hDirAC->h_freq_domain_decorr_ap_params, - hDirAC->h_freq_domain_decorr_ap_state ); - - hDirAC->proto_frame_dec_f = DirAC_mem.frame_dec_f; - p_onset_filter = onset_filter; - } + ivas_dirac_dec_decorr_process( hDirAC->num_freq_bands, + hDirAC->num_outputs_diff, + hDirAC->num_protos_diff, + hDirAC->synthesisConf, + nchan_transport, + hDirAC->h_output_synthesis_psd_state.proto_diffuse_buffer_f + slot_idx * 2 * hDirAC->num_freq_bands * hDirAC->num_outputs_diff, + hDirAC->num_protos_diff, + hDirAC->proto_index_diff, + hDirAC->h_output_synthesis_psd_state.proto_diffuse_buffer_f + slot_idx * 2 * hDirAC->num_freq_bands * hDirAC->num_outputs_diff + 2 * hDirAC->num_freq_bands * min( 4, nchan_transport ), + onset_filter, + hDirAC->h_freq_domain_decorr_ap_params, + hDirAC->h_freq_domain_decorr_ap_state ); + + v_multc( onset_filter, 0.25f, onset_filter, hDirAC->num_freq_bands ); + v_add( onset_filter, onset_filter_subframe, onset_filter_subframe, hDirAC->num_freq_bands ); + p_onset_filter = onset_filter_subframe; } else { - if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) - { - set_f( onset_filter_subframe, 1.f, hDirAC->num_freq_bands ); - p_onset_filter = onset_filter_subframe; - } - else - { - /* no frequency domain decorrelation: use prototype frame */ - hDirAC->proto_frame_dec_f = hDirAC->proto_frame_f; - p_onset_filter = NULL; - } + ivas_dirac_dec_decorr_process( hDirAC->num_freq_bands, + hDirAC->num_outputs_diff, + hDirAC->num_protos_diff, + hDirAC->synthesisConf, + nchan_transport, + hDirAC->proto_frame_f, + hDirAC->num_protos_diff, + hDirAC->proto_index_diff, + DirAC_mem.frame_dec_f, + onset_filter, + hDirAC->h_freq_domain_decorr_ap_params, + hDirAC->h_freq_domain_decorr_ap_state ); + + hDirAC->proto_frame_dec_f = DirAC_mem.frame_dec_f; + p_onset_filter = onset_filter; } - - /*-----------------------------------------------------------------* - * output synthesis - *-----------------------------------------------------------------*/ - - if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_PSD_LS || hDirAC->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD ) + } + else + { + if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) + { + set_f( onset_filter_subframe, 1.f, hDirAC->num_freq_bands ); + p_onset_filter = onset_filter_subframe; + } + else { - /*Compute diffuse prototypes*/ - ivas_dirac_dec_compute_diffuse_proto( hDirAC, slot_idx ); + /* no frequency domain decorrelation: use prototype frame */ + hDirAC->proto_frame_dec_f = hDirAC->proto_frame_f; + p_onset_filter = NULL; } + } - /*Compute PSDs*/ - if ( st_ivas->hDecoderConfig->Opt_Headrotation && st_ivas->hHeadTrackData->shd_rot_max_order == 2 ) + /*-----------------------------------------------------------------* + * output synthesis + *-----------------------------------------------------------------*/ + + if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_PSD_LS || hDirAC->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD ) + { + /*Compute diffuse prototypes*/ + ivas_dirac_dec_compute_diffuse_proto( hDirAC, slot_idx ); + } + + /*Compute PSDs*/ +#ifndef JBM_TSM_ON_TCS + if ( st_ivas->hDecoderConfig->Opt_Headrotation && st_ivas->hHeadTrackData->shd_rot_max_order == 2 ) + { + ivas_dirac_dec_output_synthesis_process_slot( reference_power, + p_onset_filter, + hDirAC, + p_Rmat, + st_ivas->hVBAPdata, + hDirAC->hOutSetup, + nchan_transport, + index_slot ); + } + else + { + ivas_dirac_dec_output_synthesis_process_slot( reference_power, + p_onset_filter, + hDirAC, + 0, + st_ivas->hVBAPdata, + hDirAC->hOutSetup, + nchan_transport, + index_slot ); + } +#else + if ( st_ivas->hDecoderConfig->Opt_Headrotation && st_ivas->hHeadTrackData->shd_rot_max_order > 0 ) { ivas_dirac_dec_output_synthesis_process_slot( reference_power, p_onset_filter, + azimuth[slot_idx], + elevation[slot_idx], + diffuseness_vector[slot_idx], + coherence_flag, hDirAC, + st_ivas->hMasa, + st_ivas->hHeadTrackData->shd_rot_max_order, p_Rmat, st_ivas->hVBAPdata, hDirAC->hOutSetup, - nchan_transport ); + nchan_transport, + hDirAC->render_to_md_slot_map[index_slot] ); } else { ivas_dirac_dec_output_synthesis_process_slot( reference_power, p_onset_filter, + azimuth[slot_idx], + elevation[slot_idx], + diffuseness_vector[slot_idx], + coherence_flag, hDirAC, + st_ivas->hMasa, 0, + p_Rmat, st_ivas->hVBAPdata, hDirAC->hOutSetup, - nchan_transport ); - } - - if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD ) - { - v_add( reference_power, reference_power_smooth, reference_power_smooth, hDirAC->num_freq_bands ); + nchan_transport, + hDirAC->render_to_md_slot_map[index_slot] ); } +#endif - if ( hDirAC->hConfig->dec_param_estim ) - { - hDirAC->dirac_read_idx = ( hDirAC->dirac_read_idx + 1 ) % hDirAC->dirac_md_buffer_length; - } + if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD ) + { + v_add( reference_power, reference_power_smooth, reference_power_smooth, hDirAC->num_freq_bands ); } - if ( hDirAC->hConfig->dec_param_estim == 0 ) +#ifndef JBM_TSM_ON_TCS + if ( hDirAC->hConfig->dec_param_estim ) { hDirAC->dirac_read_idx = ( hDirAC->dirac_read_idx + 1 ) % hDirAC->dirac_md_buffer_length; } - - if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) +#endif + } +#ifndef JBM_TSM_ON_TCS + if ( hDirAC->hConfig->dec_param_estim == 0 ) + { + hDirAC->dirac_read_idx = ( hDirAC->dirac_read_idx + 1 ) % hDirAC->dirac_md_buffer_length; + } +#endif +#ifdef JBM_TSM_ON_TCS + ivas_dirac_dec_output_synthesis_get_interpolator( &hDirAC->h_output_synthesis_psd_params, hDirAC->subframe_nbslots[subframe_idx] ); +#endif + if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) + { + ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( Cldfb_RealBuffer, + Cldfb_ImagBuffer, + hDirAC, + nchan_transport, +#ifdef JBM_TSM_ON_TCS + hDirAC->subframe_nbslots[subframe_idx], +#endif + p_onset_filter ); + } + else + { + /* Determine encoding quality based additional smoothing factor */ + float qualityBasedSmFactor = 1.0f; +#ifdef JBM_TSM_ON_TCS + int16_t diff_md_idx; +#endif + if ( st_ivas->hMasa != NULL ) { - ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( Cldfb_RealBuffer, - Cldfb_ImagBuffer, - hDirAC, - nchan_transport, - p_onset_filter ); + qualityBasedSmFactor = st_ivas->hMasa->data.dir_decode_quality; + qualityBasedSmFactor *= qualityBasedSmFactor; } - else +#ifdef JBM_TSM_ON_TCS + /* Workaround for BE */ + if ( hDirAC->hConfig->dec_param_estim == 1 ) { - /* Determine encoding quality based additional smoothing factor */ - float qualityBasedSmFactor = 1.0f; - if ( st_ivas->hMasa != NULL ) + num_freq_bands = hDirAC->band_grouping[hDirAC->hConfig->enc_param_start_band]; + for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) { - qualityBasedSmFactor = st_ivas->hMasa->data.dir_decode_quality; - qualityBasedSmFactor *= qualityBasedSmFactor; + mvs2s( azimuth[slot_idx], hDirAC->azimuth[hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]], num_freq_bands ); + mvs2s( elevation[slot_idx], hDirAC->elevation[hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]], num_freq_bands ); + mvr2r( diffuseness_vector[slot_idx], hDirAC->diffuseness_vector[hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]], num_freq_bands ); } - - ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( Cldfb_RealBuffer, - Cldfb_ImagBuffer, - hDirAC, - reference_power_smooth, - qualityBasedSmFactor ); + } + /* get the correct md index for the direction smoothing, it is always the first slot of the next subframe*/ + if ( slot_idx_start + hDirAC->subframe_nbslots[subframe_idx] == hDirAC->num_slots ) + { + /* we are at the end, get the next one using the normal dirac read idx...*/ + if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) + { + diff_md_idx = ( hDirAC->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS + 1 ) % hDirAC->dirac_md_buffer_length; + } + else + { + diff_md_idx = ( hDirAC->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS + 1 ) % hDirAC->dirac_md_buffer_length; + } + } + else + { + diff_md_idx = hDirAC->render_to_md_slot_map[slot_idx_start + hDirAC->subframe_nbslots[subframe_idx]]; } - /*-----------------------------------------------------------------* - * CLDFB synthesis (and binaural rendering) - *-----------------------------------------------------------------*/ +#endif + ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( Cldfb_RealBuffer, + Cldfb_ImagBuffer, + hDirAC, +#ifdef JBM_TSM_ON_TCS + hDirAC->subframe_nbslots[subframe_idx], + diff_md_idx, +#endif + reference_power_smooth, + qualityBasedSmFactor ); + } + + /*-----------------------------------------------------------------* + * CLDFB synthesis (and binaural rendering) + *-----------------------------------------------------------------*/ +#ifdef JBM_TSM_ON_TCS + index_slot = slot_idx_start_cldfb_synth; +#else index_slot = subframe_idx * hDirAC->subframe_nbslots; +#endif - if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) - { - /* Perform binaural rendering */ - ivas_binRenderer( st_ivas->hBinRenderer, - st_ivas->hHeadTrackData, - Cldfb_RealBuffer_Binaural, - Cldfb_ImagBuffer_Binaural, - Cldfb_RealBuffer, - Cldfb_ImagBuffer ); + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + { + /* Perform binaural rendering */ + ivas_binRenderer( st_ivas->hBinRenderer, + st_ivas->hHeadTrackData, +#ifdef JBM_TSM_ON_TCS + hDirAC->subframe_nbslots[subframe_idx], +#endif + Cldfb_RealBuffer_Binaural, + Cldfb_ImagBuffer_Binaural, + Cldfb_RealBuffer, + Cldfb_ImagBuffer ); - /* Inverse CLDFB*/ - for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) - { - /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */ - float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; - float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; + /* Inverse CLDFB*/ + for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) + { + /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */ + float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; + float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; +#ifdef JBM_TSM_ON_TCS + for ( i = 0; i < hDirAC->subframe_nbslots[subframe_idx]; i++ ) +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) - { - RealBuffer[i] = Cldfb_RealBuffer_Binaural[ch][i]; - ImagBuffer[i] = Cldfb_ImagBuffer_Binaural[ch][i]; - } +#endif + { + RealBuffer[i] = Cldfb_RealBuffer_Binaural[ch][i]; + ImagBuffer[i] = Cldfb_ImagBuffer_Binaural[ch][i]; + } +#ifdef JBM_TSM_ON_TCS + cldfbSynthesis( RealBuffer, + ImagBuffer, + &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), + hDirAC->num_freq_bands * hDirAC->subframe_nbslots[subframe_idx], + st_ivas->cldfbSynDec[ch] ); +#else cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), hDirAC->num_freq_bands * hDirAC->subframe_nbslots, st_ivas->cldfbSynDec[ch] ); - } +#endif } - else if ( st_ivas->sba_mode == SBA_MODE_SPAR ) + } + else if ( st_ivas->sba_mode == SBA_MODE_SPAR ) + { + for ( ch = 0; ch < hDirAC->hOutSetup.nchan_out_woLFE; ch++ ) { - for ( ch = 0; ch < hDirAC->hOutSetup.nchan_out_woLFE; ch++ ) - { +#ifdef JBM_TSM_ON_TCS + for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) +#else for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots; slot_idx++ ) - { - mvr2r( Cldfb_RealBuffer[ch][slot_idx], pppQMfFrame_ts_re[ch][slot_idx], hDirAC->num_freq_bands ); - mvr2r( Cldfb_ImagBuffer[ch][slot_idx], pppQMfFrame_ts_im[ch][slot_idx], hDirAC->num_freq_bands ); - } +#endif + { + mvr2r( Cldfb_RealBuffer[ch][slot_idx], pppQMfFrame_ts_re[ch][slot_idx], hDirAC->num_freq_bands ); + mvr2r( Cldfb_ImagBuffer[ch][slot_idx], pppQMfFrame_ts_im[ch][slot_idx], hDirAC->num_freq_bands ); } } - else - { - float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; - float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; - int16_t outchannels; + } + else + { + float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; + float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; + int16_t outchannels; - idx_in = 0; - idx_lfe = 0; + idx_in = 0; + idx_lfe = 0; - outchannels = hDirAC->hOutSetup.nchan_out_woLFE + hDirAC->hOutSetup.num_lfe; - if ( hDirAC->hOutSetup.separateChannelEnabled && ( hDirAC->hOutSetup.output_config == AUDIO_CONFIG_5_1 || - hDirAC->hOutSetup.output_config == AUDIO_CONFIG_7_1 || - hDirAC->hOutSetup.output_config == AUDIO_CONFIG_5_1_2 || - hDirAC->hOutSetup.output_config == AUDIO_CONFIG_5_1_4 || - hDirAC->hOutSetup.output_config == AUDIO_CONFIG_7_1_4 || - ( hDirAC->hOutSetup.output_config == AUDIO_CONFIG_LS_CUSTOM && st_ivas->hLsSetupCustom->separate_ch_found ) ) ) - { - outchannels++; - } + outchannels = hDirAC->hOutSetup.nchan_out_woLFE + hDirAC->hOutSetup.num_lfe; + if ( hDirAC->hOutSetup.separateChannelEnabled && ( hDirAC->hOutSetup.output_config == AUDIO_CONFIG_5_1 || + hDirAC->hOutSetup.output_config == AUDIO_CONFIG_7_1 || + hDirAC->hOutSetup.output_config == AUDIO_CONFIG_5_1_2 || + hDirAC->hOutSetup.output_config == AUDIO_CONFIG_5_1_4 || + hDirAC->hOutSetup.output_config == AUDIO_CONFIG_7_1_4 || + ( hDirAC->hOutSetup.output_config == AUDIO_CONFIG_LS_CUSTOM && st_ivas->hLsSetupCustom->separate_ch_found ) ) ) + { + outchannels++; + } - if ( hDirAC->hOutSetup.separateChannelEnabled && hDirAC->hOutSetup.output_config == AUDIO_CONFIG_LS_CUSTOM ) - { - float tmp_separated[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; - float tmp_lfe[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; - const int16_t subframe_start_sample = index_slot * hDirAC->num_freq_bands; + if ( hDirAC->hOutSetup.separateChannelEnabled && hDirAC->hOutSetup.output_config == AUDIO_CONFIG_LS_CUSTOM ) + { + float tmp_separated[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; + float tmp_lfe[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; + const int16_t subframe_start_sample = index_slot * hDirAC->num_freq_bands; +#ifdef JBM_TSM_ON_TCS + const int16_t num_samples_subframe = hDirAC->num_freq_bands * hDirAC->subframe_nbslots[subframe_idx]; +#else const int16_t num_samples_subframe = hDirAC->num_freq_bands * hDirAC->subframe_nbslots; +#endif - /* Move the separated and the LFE channels to temporary variables as spatial synthesis may overwrite current channels */ - mvr2r( &( output_f[st_ivas->hOutSetup.separateChannelIndex][subframe_start_sample] ), tmp_separated, num_samples_subframe ); - mvr2r( &( output_f[LFE_CHANNEL][subframe_start_sample] ), tmp_lfe, num_samples_subframe ); + /* Move the separated and the LFE channels to temporary variables as spatial synthesis may overwrite current channels */ + mvr2r( &( output_f[st_ivas->hOutSetup.separateChannelIndex][subframe_start_sample] ), tmp_separated, num_samples_subframe ); + mvr2r( &( output_f[LFE_CHANNEL][subframe_start_sample] ), tmp_lfe, num_samples_subframe ); - for ( ch = 0; ch < outchannels; ch++ ) + for ( ch = 0; ch < outchannels; ch++ ) + { + if ( ( hDirAC->hOutSetup.num_lfe > 0 ) && ( hDirAC->hOutSetup.index_lfe[idx_lfe] == ch ) ) { - if ( ( hDirAC->hOutSetup.num_lfe > 0 ) && ( hDirAC->hOutSetup.index_lfe[idx_lfe] == ch ) ) - { - /* Move the LFE channel to the correct place */ - mvr2r( tmp_lfe, &( output_f[ch][subframe_start_sample] ), num_samples_subframe ); + /* Move the LFE channel to the correct place */ + mvr2r( tmp_lfe, &( output_f[ch][subframe_start_sample] ), num_samples_subframe ); - if ( idx_lfe < ( hDirAC->hOutSetup.num_lfe - 1 ) ) - { - idx_lfe++; - } - } - else if ( ( st_ivas->hLsSetupCustom->separate_ch_found ) && ( hDirAC->hOutSetup.separateChannelIndex == ch ) ) + if ( idx_lfe < ( hDirAC->hOutSetup.num_lfe - 1 ) ) { - /* Move the separated channel to the correct place. Thus, the separated channel is - * combined with the synthesized channels here when there is a matching channel. */ - mvr2r( tmp_separated, &( output_f[ch][subframe_start_sample] ), num_samples_subframe ); + idx_lfe++; } - else - { - /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */ + } + else if ( ( st_ivas->hLsSetupCustom->separate_ch_found ) && ( hDirAC->hOutSetup.separateChannelIndex == ch ) ) + { + /* Move the separated channel to the correct place. Thus, the separated channel is + * combined with the synthesized channels here when there is a matching channel. */ + mvr2r( tmp_separated, &( output_f[ch][subframe_start_sample] ), num_samples_subframe ); + } + else + { + /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */ +#ifdef JBM_TSM_ON_TCS + for ( i = 0; i < hDirAC->subframe_nbslots[subframe_idx]; i++ ) +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) - { - RealBuffer[i] = Cldfb_RealBuffer[idx_in][i]; - ImagBuffer[i] = Cldfb_ImagBuffer[idx_in][i]; - } - cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][subframe_start_sample] ), num_samples_subframe, st_ivas->cldfbSynDec[idx_in] ); - - if ( !st_ivas->hLsSetupCustom->separate_ch_found ) - { - /* Pan the separated channel and mix with the synthesized channels. Thus, the separated channel - * is combined with the synthesized channels here when there is no matching channel. */ - v_multc_acc( tmp_separated, st_ivas->hLsSetupCustom->separate_ch_gains[idx_in], &( output_f[ch][subframe_start_sample] ), num_samples_subframe ); - } +#endif + { + RealBuffer[i] = Cldfb_RealBuffer[idx_in][i]; + ImagBuffer[i] = Cldfb_ImagBuffer[idx_in][i]; + } + cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][subframe_start_sample] ), num_samples_subframe, st_ivas->cldfbSynDec[idx_in] ); - idx_in++; + if ( !st_ivas->hLsSetupCustom->separate_ch_found ) + { + /* Pan the separated channel and mix with the synthesized channels. Thus, the separated channel + * is combined with the synthesized channels here when there is no matching channel. */ + v_multc_acc( tmp_separated, st_ivas->hLsSetupCustom->separate_ch_gains[idx_in], &( output_f[ch][subframe_start_sample] ), num_samples_subframe ); } + + idx_in++; } } - else + } + else + { + for ( ch = 0; ch < outchannels; ch++ ) { - for ( ch = 0; ch < outchannels; ch++ ) + if ( ( hDirAC->hOutSetup.num_lfe > 0 ) && ( hDirAC->hOutSetup.index_lfe[idx_lfe] == ch ) ) { - if ( ( hDirAC->hOutSetup.num_lfe > 0 ) && ( hDirAC->hOutSetup.index_lfe[idx_lfe] == ch ) ) + if ( st_ivas->mc_mode == MC_MODE_MCMASA && !hDirAC->hOutSetup.separateChannelEnabled ) { - if ( st_ivas->mc_mode == MC_MODE_MCMASA && !hDirAC->hOutSetup.separateChannelEnabled ) - { +#ifdef JBM_TSM_ON_TCS + for ( i = 0; i < hDirAC->subframe_nbslots[subframe_idx]; i++ ) +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) - { - RealBuffer[i] = Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS - 1][i]; - ImagBuffer[i] = Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS - 1][i]; - } - cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), hDirAC->num_freq_bands * hDirAC->subframe_nbslots, st_ivas->cldfbSynDec[hDirAC->hOutSetup.nchan_out_woLFE + idx_lfe] ); - } - else if ( st_ivas->mc_mode == MC_MODE_MCMASA && hDirAC->hOutSetup.separateChannelEnabled ) - { - /* LFE has been synthesized in the time domain, do nothing. */ - } - else - { - set_zero( &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), hDirAC->subframe_nbslots * hDirAC->num_freq_bands ); - } - - if ( idx_lfe < ( hDirAC->hOutSetup.num_lfe - 1 ) ) +#endif { - idx_lfe++; + RealBuffer[i] = Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS - 1][i]; + ImagBuffer[i] = Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS - 1][i]; } +#ifdef JBM_TSM_ON_TCS + cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), hDirAC->num_freq_bands * hDirAC->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[hDirAC->hOutSetup.nchan_out_woLFE + idx_lfe] ); +#else + cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), hDirAC->num_freq_bands * hDirAC->subframe_nbslots, st_ivas->cldfbSynDec[hDirAC->hOutSetup.nchan_out_woLFE + idx_lfe] ); +#endif } - else if ( ( hDirAC->hOutSetup.separateChannelEnabled ) && ( hDirAC->hOutSetup.separateChannelIndex == ch ) ) + else if ( st_ivas->mc_mode == MC_MODE_MCMASA && hDirAC->hOutSetup.separateChannelEnabled ) { - /* The separated channel is already set to output_f[hOutSetup.separateChannelIndex]. Thus, the separated - * channel is combined with the synthesized channels here. */ + /* LFE has been synthesized in the time domain, do nothing. */ } else { - /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */ +#ifdef JBM_TSM_ON_TCS + set_zero( &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), hDirAC->subframe_nbslots[subframe_idx] * hDirAC->num_freq_bands ); +#else + set_zero( &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), hDirAC->subframe_nbslots * hDirAC->num_freq_bands ); +#endif + } + + if ( idx_lfe < ( hDirAC->hOutSetup.num_lfe - 1 ) ) + { + idx_lfe++; + } + } + else if ( ( hDirAC->hOutSetup.separateChannelEnabled ) && ( hDirAC->hOutSetup.separateChannelIndex == ch ) ) + { + /* The separated channel is already set to output_f[hOutSetup.separateChannelIndex]. Thus, the separated + * channel is combined with the synthesized channels here. */ + } + else + { + /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */ +#ifdef JBM_TSM_ON_TCS + for ( i = 0; i < hDirAC->subframe_nbslots[subframe_idx]; i++ ) +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) - { - RealBuffer[i] = Cldfb_RealBuffer[idx_in][i]; - ImagBuffer[i] = Cldfb_ImagBuffer[idx_in][i]; - } - cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), hDirAC->num_freq_bands * hDirAC->subframe_nbslots, st_ivas->cldfbSynDec[idx_in] ); - idx_in++; +#endif + { + RealBuffer[i] = Cldfb_RealBuffer[idx_in][i]; + ImagBuffer[i] = Cldfb_ImagBuffer[idx_in][i]; } +#ifdef JBM_TSM_ON_TCS + cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), hDirAC->num_freq_bands * hDirAC->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[idx_in] ); +#else + cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), hDirAC->num_freq_bands * hDirAC->subframe_nbslots, st_ivas->cldfbSynDec[idx_in] ); +#endif + idx_in++; } } } } +#ifdef JBM_TSM_ON_TCS + hDirAC->slots_rendered += hDirAC->subframe_nbslots[subframe_idx]; + hDirAC->subframes_rendered++; +#endif +#ifndef JBM_TSM_ON_TCS +} +#endif - pop_wmops(); - return; +pop_wmops(); + +return; } diff --git a/lib_dec/ivas_dirac_output_synthesis_cov.c b/lib_dec/ivas_dirac_output_synthesis_cov.c index a2fc9ee821..892cfe4acb 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov.c @@ -104,12 +104,19 @@ ivas_error ivas_dirac_dec_output_synthesis_cov_open( set_zero( h_dirac_output_synthesis_state->cx_old[idx], nchan_in * nchan_in ); set_zero( h_dirac_output_synthesis_state->cy_old[idx], nchan_out * nchan_out ); set_zero( h_dirac_output_synthesis_state->mixing_matrix_old[idx], nchan_out * nchan_in ); +#ifdef JBM_TSM_ON_TCS + h_dirac_output_synthesis_state->mixing_matrix[idx] = (float *) malloc( nchan_out * nchan_in * sizeof( float ) ); + set_zero( h_dirac_output_synthesis_state->mixing_matrix[idx], nchan_out * nchan_in ); +#endif } for ( ; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { h_dirac_output_synthesis_state->cx_old[idx] = NULL; h_dirac_output_synthesis_state->cy_old[idx] = NULL; h_dirac_output_synthesis_state->mixing_matrix_old[idx] = NULL; +#ifdef JBM_TSM_ON_TCS + h_dirac_output_synthesis_state->mixing_matrix[idx] = NULL; +#endif } for ( idx = 0; idx < num_param_bands_residual; idx++ ) { @@ -118,10 +125,17 @@ ivas_error ivas_dirac_dec_output_synthesis_cov_open( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis covariance\n" ) ); } set_zero( h_dirac_output_synthesis_state->mixing_matrix_res_old[idx], nchan_out * nchan_out ); +#ifdef JBM_TSM_ON_TCS + h_dirac_output_synthesis_state->mixing_matrix_res[idx] = (float *) malloc( nchan_out * nchan_out * sizeof( float ) ); + set_zero( h_dirac_output_synthesis_state->mixing_matrix_res[idx], nchan_out * nchan_out ); +#endif } for ( ; idx < CLDFB_NO_CHANNELS_MAX; idx++ ) { h_dirac_output_synthesis_state->mixing_matrix_res_old[idx] = NULL; +#ifdef JBM_TSM_ON_TCS + h_dirac_output_synthesis_state->mixing_matrix_res[idx] = NULL; +#endif } /*-----------------------------------------------------------------* @@ -144,6 +158,28 @@ ivas_error ivas_dirac_dec_output_synthesis_cov_open( return IVAS_ERR_OK; } +#ifdef JBM_TSM_ON_TCS +/*-------------------------------------------------------------------* + * ivas_dirac_dec_output_synthesis_cov_open() + * + * Sets up the state and parameters for the Covariance Synthesis + *-------------------------------------------------------------------*/ + +void ivas_dirac_dec_output_synthesis_get_interpolator( + DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params, /* i/o: handle for the covariance synthesis parameters */ + const uint16_t interp_length ) +{ + int16_t idx; + + for ( idx = 1; idx <= interp_length; ++idx ) + { + h_dirac_output_synthesis_params->interpolator[idx - 1] = (float) idx / (float) interp_length; + } + + return; +} +#endif + /*-------------------------------------------------------------------* * ivas_dirac_dec_output_synthesis_cov_init() @@ -168,11 +204,17 @@ void ivas_dirac_dec_output_synthesis_cov_init( set_zero( h_dirac_output_synthesis_state->cx_old[idx], nchan_in * nchan_in ); set_zero( h_dirac_output_synthesis_state->cy_old[idx], nchan_out * nchan_out ); set_zero( h_dirac_output_synthesis_state->mixing_matrix_old[idx], nchan_out * nchan_in ); +#ifdef JBM_TSM_ON_TCS + set_zero( h_dirac_output_synthesis_state->mixing_matrix[idx], nchan_out * nchan_in ); +#endif } for ( idx = 0; idx < n_param_bands_res; idx++ ) { set_zero( h_dirac_output_synthesis_state->mixing_matrix_res_old[idx], nchan_out * nchan_out ); +#ifdef JBM_TSM_ON_TCS + set_zero( h_dirac_output_synthesis_state->mixing_matrix_res[idx], nchan_out * nchan_out ); +#endif } return; @@ -243,6 +285,19 @@ void ivas_dirac_dec_output_synthesis_cov_close( free( h_dirac_output_synthesis_state->mixing_matrix_res_old[idx] ); h_dirac_output_synthesis_state->mixing_matrix_res_old[idx] = NULL; } +#ifdef JBM_TSM_ON_TCS + if ( h_dirac_output_synthesis_state->mixing_matrix[idx] != NULL ) + { + free( h_dirac_output_synthesis_state->mixing_matrix[idx] ); + h_dirac_output_synthesis_state->mixing_matrix[idx] = NULL; + } + + if ( h_dirac_output_synthesis_state->mixing_matrix_res[idx] != NULL ) + { + free( h_dirac_output_synthesis_state->mixing_matrix_res[idx] ); + h_dirac_output_synthesis_state->mixing_matrix_res[idx] = NULL; + } +#endif } return; @@ -256,13 +311,21 @@ void ivas_dirac_dec_output_synthesis_cov_close( *-------------------------------------------------------------------*/ void ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot( - float RealBuffer[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS][CLDFB_NO_CHANNELS_MAX], /* i : input channel filter bank samples (real part) */ - float ImagBuffer[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS][CLDFB_NO_CHANNELS_MAX], /* i : input channel filter bank samples (imaginary part */ +#ifdef JBM_TSM_ON_TCS + float *RealBuffer, /* i : input channel filter bank samples (real part) */ + float *ImagBuffer, /* i : input channel filter bank samples (imaginary part */ +#else + float RealBuffer[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS][CLDFB_NO_CHANNELS_MAX], /* i : input channel filter bank samples (real part) */ + float ImagBuffer[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS][CLDFB_NO_CHANNELS_MAX], /* i : input channel filter bank samples (imaginary part */ +#endif float cx[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], /* o : accumulated input covariance (real part) */ float cx_imag[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], /* o : accumulated input covariance (imaginary part) */ PARAM_MC_DEC_HANDLE hParamMC, /* i : handle to Parametric MC state */ - const int16_t nchan_in, /* i : number of input channels */ - const int16_t idx_slot /* i : index of the slot to be added to the input covariance */ + const int16_t nchan_in /* i : number of input channels */ +#ifndef JBM_TSM_ON_TCS + , + const int16_t idx_slot /* i : index of the slot to be added to the input covariance */ +#endif ) { int16_t param_band, band_idx, ch_idx; @@ -288,8 +351,13 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot( int16_t band = brange[0] + band_idx; for ( ch_idx = 0; ch_idx < nchan_in; ch_idx++ ) { +#ifdef JBM_TSM_ON_TCS + real_in_buffer[band_idx + num_bands * ch_idx] = RealBuffer[ch_idx * hParamMC->num_freq_bands + band]; + imag_in_buffer[band_idx + num_bands * ch_idx] = ImagBuffer[ch_idx * hParamMC->num_freq_bands + band]; +#else real_in_buffer[band_idx + num_bands * ch_idx] = RealBuffer[ch_idx][idx_slot][band]; imag_in_buffer[band_idx + num_bands * ch_idx] = ImagBuffer[ch_idx][idx_slot][band]; +#endif } } @@ -312,17 +380,27 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot( *-------------------------------------------------------------------*/ void ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot( - float Cldfb_RealBuffer_in[][PARAM_MC_MAX_NSLOTS][CLDFB_NO_CHANNELS_MAX], /* i : input channel filter bank samples (real part) */ - float Cldfb_ImagBuffer_in[][PARAM_MC_MAX_NSLOTS][CLDFB_NO_CHANNELS_MAX], /* i : input channel filter bank samples (imaginary part) */ - float Cldfb_RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : output channel filter bank samples (real part) */ - float Cldfb_ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : output channel filter bank samples (imaginary part) */ +#ifdef JBM_TSM_ON_TCS + float *Cldfb_RealBuffer_in, /* i : input channel filter bank samples (real part) */ + float *Cldfb_ImagBuffer_in, /* i : input channel filter bank samples (imaginary part) */ +#else + float Cldfb_RealBuffer_in[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_NSLOTS][CLDFB_NO_CHANNELS_MAX], /* i : CLDFB samples of the transport channels (real part) */ + float Cldfb_ImagBuffer_in[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_NSLOTS][CLDFB_NO_CHANNELS_MAX], /* i : CLDFB samples of the transport channels (imaginary part) */ +#endif + float Cldfb_RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : output channel filter bank samples (real part) */ + float Cldfb_ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : output channel filter bank samples (imaginary part) */ +#ifdef JBM_TSM_ON_TCS + float *mixing_matrix[], /* i : parameter band wise mixing matrices (direct part) */ + float *mixing_matrix_res[], /* i : parameter band wise mixing matrices (residual part) */ +#else float mixing_matrix[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS], /* i : parameter band wise mixing matrices (direct part) */ float mixing_matrix_res[PARAM_MC_MAX_PARAMETER_BANDS_RES][MAX_CICP_CHANNELS * MAX_CICP_CHANNELS], /* i : parameter band wise mixing matrices (residual part) */ - const uint16_t slot_idx_sfr, /* i : time slot index for the current slot within the current subframe */ - const uint16_t slot_idx_tot, /* i : time slot index for the current slot within the frame */ - const int16_t nX, /* i : number of input channels */ - const int16_t nY, /* i : number of output channels */ - PARAM_MC_DEC_HANDLE hParamMC /* i : handle to the Parametric MC decoder state */ +#endif + const uint16_t slot_idx_sfr, /* i : time slot index for the current slot within the current subframe */ + const uint16_t slot_idx_tot, /* i : time slot index for the current slot within the frame */ + const int16_t nX, /* i : number of input channels */ + const int16_t nY, /* i : number of output channels */ + PARAM_MC_DEC_HANDLE hParamMC /* i : handle to the Parametric MC decoder state */ ) { int16_t param_band_idx, band, ch_idx; @@ -407,8 +485,13 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot( /* collect input signals, still in cldfb buffers */ for ( ch_idx = 0; ch_idx < nX; ch_idx++ ) { +#ifdef JBM_TSM_ON_TCS + input_f_real[ch_idx] = Cldfb_RealBuffer_in[ch_idx * hParamMC->num_freq_bands + band]; + input_f_imag[ch_idx] = Cldfb_ImagBuffer_in[ch_idx * hParamMC->num_freq_bands + band]; +#else input_f_real[ch_idx] = Cldfb_RealBuffer_in[ch_idx][slot_idx_tot][band]; input_f_imag[ch_idx] = Cldfb_ImagBuffer_in[ch_idx][slot_idx_tot][band]; +#endif } /* apply mixing matrix */ diff --git a/lib_dec/ivas_dirac_output_synthesis_dec.c b/lib_dec/ivas_dirac_output_synthesis_dec.c index 362b63c04b..ffbff9014a 100644 --- a/lib_dec/ivas_dirac_output_synthesis_dec.c +++ b/lib_dec/ivas_dirac_output_synthesis_dec.c @@ -161,7 +161,11 @@ ivas_error ivas_dirac_dec_output_synthesis_open( } /* buffer length and interpolator */ +#ifdef JBM_TSM_ON_TCS + if ( ( dirac_output_synthesis_params->interpolator = (float *) malloc( JBM_CLDFB_SLOTS_IN_SUBFRAME * sizeof( float ) ) ) == NULL ) +#else if ( ( dirac_output_synthesis_params->interpolator = (float *) malloc( hDirAC->subframe_nbslots * sizeof( float ) ) ) == NULL ) +#endif { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) ); } @@ -272,9 +276,17 @@ ivas_error ivas_dirac_dec_output_synthesis_open( } /* compute interpolator */ +#ifdef JBM_TSM_ON_TCS + for ( idx = 1; idx <= JBM_CLDFB_SLOTS_IN_SUBFRAME; ++idx ) +#else for ( idx = 1; idx <= hDirAC->subframe_nbslots; ++idx ) +#endif { +#ifdef JBM_TSM_ON_TCS + dirac_output_synthesis_params->interpolator[idx - 1] = (float) idx / (float) JBM_CLDFB_SLOTS_IN_SUBFRAME; +#else dirac_output_synthesis_params->interpolator[idx - 1] = (float) idx / (float) hDirAC->subframe_nbslots; +#endif } /* prepare diffuse response function */ @@ -511,13 +523,27 @@ void ivas_dirac_dec_output_synthesis_close( *------------------------------------------------------------------------*/ void ivas_dirac_dec_output_synthesis_process_slot( - const float *reference_power, /* i : Estimated power */ - const float *onset, /* i : onset filter */ - DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */ - const float *p_Rmat, /* i : rotation matrix */ - const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ - const IVAS_OUTPUT_SETUP hOutSetup, /* i : output setup structure */ - const int16_t nchan_transport /* i : number of transport channels*/ + const float *reference_power, /* i : Estimated power */ + const float *onset, /* i : onset filter */ +#ifdef JBM_TSM_ON_TCS + const int16_t *azimuth, + const int16_t *elevation, + const float *diffuseness, + const uint16_t coherence_flag, +#endif + DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */ +#ifdef JBM_TSM_ON_TCS + MASA_DECODER_HANDLE hMasa, + const int16_t sh_rot_max_order, +#endif + const float *p_Rmat, /* i : rotation matrix */ + const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ + const IVAS_OUTPUT_SETUP hOutSetup, /* i : output setup structure */ + const int16_t nchan_transport /* i : number of transport channels */ +#ifdef JBM_TSM_ON_TCS + , + const int16_t index_slot /* i : absolute slot index in the frame to process */ +#endif ) { int16_t num_freq_bands, num_channels_dir; @@ -525,11 +551,21 @@ void ivas_dirac_dec_output_synthesis_process_slot( int16_t ch_idx; float aux_buf[CLDFB_NO_CHANNELS_MAX]; int16_t diff_start_band; +#ifndef JBM_TSM_ON_TCS const float *diffuseness; +#endif +#ifdef JBM_TSM_ON_TCS + float dirEne; + float surCohEner; + float surCohRatio[CLDFB_NO_CHANNELS_MAX]; + int16_t i, l; +#endif DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params; DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state; +#ifndef JBM_TSM_ON_TCS diffuseness = hDirAC->diffuseness_vector[hDirAC->dirac_read_idx]; +#endif h_dirac_output_synthesis_params = &( hDirAC->h_output_synthesis_psd_params ); h_dirac_output_synthesis_state = &( hDirAC->h_output_synthesis_psd_state ); @@ -550,71 +586,198 @@ void ivas_dirac_dec_output_synthesis_process_slot( num_channels_dir = hOutSetup.nchan_out_woLFE; } +#if defined( JBM_DIRAC_DEBUG_BE ) || !defined( JBM_TSM_ON_TCS ) +#ifdef JBM_DIRAC_DEBUG_BE + if ( hDirAC->hConfig->dec_param_estim == TRUE || hDirAC->voip_active == 1 ) +#else if ( hDirAC->hConfig->dec_param_estim == TRUE ) +#endif +#endif { + +#ifdef JBM_TSM_ON_TCS +#ifdef JBM_DIRAC_DEBUG_BE + if ( hDirAC->voip_active == 1 ) + { +#endif + if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) + { + ivas_dirac_dec_compute_gain_factors( num_freq_bands, + diffuseness, + h_dirac_output_synthesis_params->max_band_decorr, + h_dirac_output_synthesis_state->direct_power_factor, + h_dirac_output_synthesis_state->diffuse_power_factor ); + + v_multc( h_dirac_output_synthesis_state->direct_power_factor, + 0.25f, + h_dirac_output_synthesis_state->direct_power_factor, + num_freq_bands ); + v_multc( h_dirac_output_synthesis_state->diffuse_power_factor, + 0.25f, + h_dirac_output_synthesis_state->diffuse_power_factor, + num_freq_bands ); + if ( coherence_flag ) + { + for ( i = 0; i < hDirAC->num_freq_bands; i++ ) + { + surCohRatio[i] = hDirAC->surroundingCoherence[index_slot][i]; + } + } + else + { + set_zero( surCohRatio, hDirAC->num_freq_bands ); + } + } + else + { + + + /* compute reference and diffuse power factor for this frame */ + + ivas_dirac_dec_compute_power_factors( num_freq_bands, + diffuseness, + h_dirac_output_synthesis_params->max_band_decorr, + h_dirac_output_synthesis_state->direct_power_factor, + h_dirac_output_synthesis_state->diffuse_power_factor ); + + if ( coherence_flag ) + { + for ( i = 0; i < hDirAC->num_freq_bands; i++ ) + { + dirEne = hDirAC->h_output_synthesis_psd_state.direct_power_factor[i]; + surCohEner = hDirAC->h_output_synthesis_psd_state.diffuse_power_factor[i] * hDirAC->surroundingCoherence[index_slot][i]; + hDirAC->h_output_synthesis_psd_state.diffuse_power_factor[i] -= surCohEner; + hDirAC->h_output_synthesis_psd_state.direct_power_factor[i] += surCohEner; + + surCohRatio[i] = surCohEner / ( 1e-12f + dirEne + surCohEner ); + } + } + else + { + set_zero( surCohRatio, hDirAC->num_freq_bands ); + } + } +#ifdef JBM_DIRAC_DEBUG_BE + } +#endif +#endif /* compute direct responses */ +#ifdef JBM_TSM_ON_TCS + ivas_dirac_dec_compute_directional_responses( hDirAC, + hVBAPdata, + hMasa, + azimuth, + elevation, + index_slot, + coherence_flag ? surCohRatio : NULL, + sh_rot_max_order, + p_Rmat ); +#else ivas_dirac_dec_compute_directional_responses( hDirAC, hVBAPdata, NULL, NULL, 2, p_Rmat ); +#endif if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { - ivas_dirac_dec_compute_gain_factors( num_freq_bands, - diffuseness, - h_dirac_output_synthesis_params->max_band_decorr, - h_dirac_output_synthesis_state->direct_power_factor, - h_dirac_output_synthesis_state->diffuse_power_factor ); - - v_multc( h_dirac_output_synthesis_state->direct_power_factor, - 0.25f, - h_dirac_output_synthesis_state->direct_power_factor, - num_freq_bands ); - v_multc( h_dirac_output_synthesis_state->diffuse_power_factor, - 0.25f, - h_dirac_output_synthesis_state->diffuse_power_factor, - num_freq_bands ); +#if !defined( JBM_TSM_ON_TCS ) || defined( JBM_DIRAC_DEBUG_BE ) +#ifdef JBM_DIRAC_DEBUG_BE + if ( hDirAC->voip_active == 0 ) + { +#endif + ivas_dirac_dec_compute_gain_factors( num_freq_bands, + diffuseness, + h_dirac_output_synthesis_params->max_band_decorr, + h_dirac_output_synthesis_state->direct_power_factor, + h_dirac_output_synthesis_state->diffuse_power_factor ); + + + v_multc( h_dirac_output_synthesis_state->direct_power_factor, + 0.25f, + h_dirac_output_synthesis_state->direct_power_factor, + num_freq_bands ); + v_multc( h_dirac_output_synthesis_state->diffuse_power_factor, + 0.25f, + h_dirac_output_synthesis_state->diffuse_power_factor, + num_freq_bands ); +#ifdef JBM_DIRAC_DEBUG_BE + } +#endif +#endif /*Direct gain*/ - for ( ch_idx = 0; ch_idx < min( 4, nchan_transport ); ch_idx++ ) +#ifdef JBM_TSM_ON_TCS + if ( hDirAC->hConfig->dec_param_estim == TRUE ) { - int16_t k; - if ( ch_idx != 0 ) +#endif + for ( ch_idx = 0; ch_idx < min( 4, nchan_transport ); ch_idx++ ) { - float a, b, c; - - /*Directonal sound gain nrg compensation*/ - for ( k = 0; k < num_freq_bands_diff; k++ ) + int16_t k; + if ( ch_idx != 0 ) { - a = h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands + k]; - b = reference_power[k + num_freq_bands] / ( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] + EPSILON ); - c = 1.f + ( 1.f / 6.f ) * ( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f ); /*Diffuseness modellling nrg compensation*/ - h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( diffuseness[k] * c + ( ( 1.f - diffuseness[k] ) * a * a * b ) ); + float a, b, c; + + /*Directonal sound gain nrg compensation*/ + for ( k = 0; k < num_freq_bands_diff; k++ ) + { + a = h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands + k]; + b = reference_power[k + num_freq_bands] / ( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] + EPSILON ); + c = 1.f + ( 1.f / 6.f ) * ( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f ); /*Diffuseness modellling nrg compensation*/ + h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( diffuseness[k] * c + ( ( 1.f - diffuseness[k] ) * a * a * b ) ); + } + for ( ; k < num_freq_bands; k++ ) + { + a = h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands + k]; + b = reference_power[k + num_freq_bands] / ( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] + EPSILON ); + c = 1.f + ( 1.f / 6.f ) * ( h_dirac_output_synthesis_params->diffuse_compensation_factor - 1.f ); /*Diffuseness modellling nrg compensation*/ + h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( diffuseness[k] * c + ( ( 1.f - diffuseness[k] ) * a * a * b ) ); + } } - for ( ; k < num_freq_bands; k++ ) + else { - a = h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands + k]; - b = reference_power[k + num_freq_bands] / ( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] + EPSILON ); - c = 1.f + ( 1.f / 6.f ) * ( h_dirac_output_synthesis_params->diffuse_compensation_factor - 1.f ); /*Diffuseness modellling nrg compensation*/ - h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( diffuseness[k] * c + ( ( 1.f - diffuseness[k] ) * a * a * b ) ); + /*Diffuseness modellling nrg compensation*/ + for ( k = 0; k < num_freq_bands_diff; k++ ) + { + h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( 1.0f + diffuseness[k] * 0.5f * ( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f ) ); + } + for ( ; k < num_freq_bands; k++ ) + { + h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( 1.0f + diffuseness[k] * 0.5f * ( h_dirac_output_synthesis_params->diffuse_compensation_factor - 1.f ) ); + } } } - else +#ifdef JBM_TSM_ON_TCS + } + else + { + for ( ch_idx = 0; ch_idx < min( 4, nchan_transport ); ch_idx++ ) { - /*Diffuseness modellling nrg compensation*/ - for ( k = 0; k < num_freq_bands_diff; k++ ) - { - h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( 1.0f + diffuseness[k] * 0.5f * ( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f ) ); - } - for ( ; k < num_freq_bands; k++ ) + v_multc( h_dirac_output_synthesis_state->diffuse_power_factor, 4.0f, aux_buf, num_freq_bands ); + v_mult( aux_buf, + aux_buf, + aux_buf, + num_freq_bands ); + v_multc( aux_buf, + h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f, + aux_buf, + num_freq_bands_diff ); + v_multc( &aux_buf[num_freq_bands_diff], + h_dirac_output_synthesis_params->diffuse_compensation_factor - 1.f, + &aux_buf[num_freq_bands_diff], + num_freq_bands - num_freq_bands_diff ); + + for ( l = 0; l < num_freq_bands; l++ ) { - h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( 1.0f + diffuseness[k] * 0.5f * ( h_dirac_output_synthesis_params->diffuse_compensation_factor - 1.f ) ); + aux_buf[l] = 0.25f * sqrtf( 1.f + aux_buf[l] ); } + v_add( aux_buf, &h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands], &h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands], num_freq_bands ); } } +#endif /*Directional gain (panning)*/ for ( ch_idx = min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ ) { @@ -645,16 +808,25 @@ void ivas_dirac_dec_output_synthesis_process_slot( return; } +#if !defined( JBM_TSM_ON_TCS ) || defined( JBM_DIRAC_DEBUG_BE ) else { /* compute reference and diffuse power factor for this frame */ +#ifdef JBM_DIRAC_DEBUG_BE + if ( hDirAC->voip_active == 0 ) + { - ivas_dirac_dec_compute_power_factors( num_freq_bands, - diffuseness, - h_dirac_output_synthesis_params->max_band_decorr, - h_dirac_output_synthesis_state->direct_power_factor, - h_dirac_output_synthesis_state->diffuse_power_factor ); +#endif + ivas_dirac_dec_compute_power_factors( num_freq_bands, + diffuseness, + h_dirac_output_synthesis_params->max_band_decorr, + h_dirac_output_synthesis_state->direct_power_factor, + h_dirac_output_synthesis_state->diffuse_power_factor ); +#ifdef JBM_DIRAC_DEBUG_BE + } +#endif } +#endif } diff_start_band = 0; @@ -673,7 +845,9 @@ void ivas_dirac_dec_output_synthesis_process_slot( } /* process other PSDs only slot wise for 4 transport channels */ +#if !defined( JBM_TSM_ON_TCS ) || defined( JBM_DIRAC_DEBUG_BE ) if ( hDirAC->hConfig->dec_param_estim == TRUE ) +#endif { computeTargetPSDs_direct( num_channels_dir, num_freq_bands, h_dirac_output_synthesis_state->direct_power_factor, reference_power, h_dirac_output_synthesis_state->direct_responses, h_dirac_output_synthesis_state->direct_responses_square, h_dirac_output_synthesis_state->cy_auto_dir_smooth, h_dirac_output_synthesis_state->cy_cross_dir_smooth ); @@ -695,6 +869,9 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */ const int16_t nchan_transport, /* i : number of transport channels */ +#ifdef JBM_TSM_ON_TCS + const int16_t nbslots, /* i : number of slots to process */ +#endif const float *onset_filter ) { int16_t buf_idx, ch_idx, i, l; @@ -731,7 +908,12 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( * comput target Gains *-----------------------------------------------------------------*/ +#if !defined( JBM_TSM_ON_TCS ) || defined( JBM_DIRAC_DEBUG_BE ) +#ifdef JBM_DIRAC_DEBUG_BE + if ( hDirAC->voip_active == 0 && hDirAC->hConfig->dec_param_estim == FALSE ) +#else if ( hDirAC->hConfig->dec_param_estim == FALSE ) +#endif { /*Direct gain*/ for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ ) @@ -769,6 +951,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( v_multc( h_dirac_output_synthesis_state.diffuse_power_factor, hDirAC->diffuse_response_function[ch_idx], &h_dirac_output_synthesis_state.cy_auto_diff_smooth[ch_idx * num_freq_bands_diff], num_freq_bands_diff ); } } +#endif /*-----------------------------------------------------------------* * compute gains @@ -825,7 +1008,11 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( * gain interpolation and output streams *-----------------------------------------------------------------*/ +#ifdef JBM_TSM_ON_TCS + for ( buf_idx = 0; buf_idx < nbslots; ++buf_idx ) +#else for ( buf_idx = 0; buf_idx < hDirAC->subframe_nbslots; ++buf_idx ) +#endif { g1 = h_dirac_output_synthesis_params.interpolator[buf_idx]; g2 = 1.f - g1; @@ -970,10 +1157,17 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */ +#ifdef JBM_TSM_ON_TCS + const int16_t nbslots, /* i : number of slots to process */ + const int16_t diff_md_idx, /* i : md slot idx of diffuseness to use */ +#endif float *reference_power_smooth, float qualityBasedSmFactor ) { - int16_t buf_idx, num_freq_bands, diff_start_band; + int16_t buf_idx, num_freq_bands; +#ifndef JBM_TSM_ON_TCS + int16_t diff_start_band; +#endif int16_t k, l; int16_t nchan_out_woLFE; float *p_power_smooth_prev, *p_power_diff_smooth_prev; @@ -994,7 +1188,9 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( float subtract_target_ratio; float subtract_target_ratio_db; float a, b; +#ifndef JBM_TSM_ON_TCS uint16_t nchan_target_psds; +#endif float alpha[CLDFB_NO_CHANNELS_MAX]; float *alpha_synthesis; float *alpha_synthesis_fast; @@ -1015,7 +1211,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( /*-----------------------------------------------------------------* * compute target PSDs *-----------------------------------------------------------------*/ - +#ifndef JBM_TSM_ON_TCS if ( hDirAC->hConfig->enc_param_start_band == 0 ) { diff_start_band = h_dirac_output_synthesis_params->use_onset_filters == 1 ? h_dirac_output_synthesis_params->max_band_decorr : 0; @@ -1043,7 +1239,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( h_dirac_output_synthesis_state->diffuse_responses_square, h_dirac_output_synthesis_state->cy_auto_diff_smooth ); } - +#endif /*-----------------------------------------------------------------* * compute variables for stereo transport signal type detection *-----------------------------------------------------------------*/ @@ -1096,7 +1292,14 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( indexFast = min( l, alphaMaxBinFast ); /* Estimate the smoothness of the directions based on the diffuseness parameter */ + /* TODO: check this, seems buggy in the case of parame estim on the decoder side, + because the pointer here points already to the following subframe, ist this intended?*/ +#ifdef JBM_TSM_ON_TCS + /* Workaround for BE */ + instDirectionSmoothness = 1.0f - hDirAC->diffuseness_vector[diff_md_idx][l]; /* Currently, all subframes have same energy ratio value. */ +#else instDirectionSmoothness = 1.0f - hDirAC->diffuseness_vector[hDirAC->dirac_read_idx][l]; /* Currently, all subframes have same energy ratio value. */ +#endif instDirectionSmoothness = min( max( instDirectionSmoothness, 0.0f ), 1.0f ); /* Average the direction smoothness parameter over time */ @@ -1240,8 +1443,11 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( /*-----------------------------------------------------------------* * gain interpolation and output streams *-----------------------------------------------------------------*/ - +#ifdef JBM_TSM_ON_TCS + for ( buf_idx = 0; buf_idx < nbslots; ++buf_idx ) +#else for ( buf_idx = 0; buf_idx < hDirAC->subframe_nbslots; ++buf_idx ) +#endif { g1 = h_dirac_output_synthesis_params->interpolator[buf_idx]; g2 = 1.f - g1; @@ -1483,6 +1689,11 @@ void ivas_dirac_dec_compute_directional_responses( DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */ const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ const MASA_DECODER_HANDLE hMasa, /* i : MASA decoder structure */ +#ifdef JBM_TSM_ON_TCS + const int16_t *azimuth, + const int16_t *elevation, + const int16_t md_idx, +#endif const float *surCohRatio, const int16_t shd_rot_max_order, /* i : split-order rotation method */ const float *p_Rmat /* i : rotation matrix */ @@ -1494,7 +1705,9 @@ void ivas_dirac_dec_compute_directional_responses( float direct_response_ls[MAX_OUTPUT_CHANNELS]; float direct_response_square[MAX_OUTPUT_CHANNELS]; float *direct_response; +#ifndef JBM_TSM_ON_TCS const int16_t *azimuth, *elevation; +#endif const int16_t *azimuth2, *elevation2; float direct_response_dir2[MAX_OUTPUT_CHANNELS]; float directRatio[MASA_MAXIMUM_DIRECTIONS]; @@ -1515,6 +1728,13 @@ void ivas_dirac_dec_compute_directional_responses( } num_channels_dir = hDirAC->num_outputs_dir; +#ifdef JBM_TSM_ON_TCS + if ( hDirAC->numSimultaneousDirections == 2 ) + { + azimuth2 = hDirAC->azimuth2[md_idx]; + elevation2 = hDirAC->elevation2[md_idx]; + } +#else azimuth = hDirAC->azimuth[hDirAC->dirac_read_idx]; elevation = hDirAC->elevation[hDirAC->dirac_read_idx]; if ( hDirAC->numSimultaneousDirections == 2 ) @@ -1522,6 +1742,7 @@ void ivas_dirac_dec_compute_directional_responses( azimuth2 = hDirAC->azimuth2[hDirAC->dirac_read_idx]; elevation2 = hDirAC->elevation2[hDirAC->dirac_read_idx]; } +#endif codingBand = -1; assert( num_channels_dir <= MAX_OUTPUT_CHANNELS && "Number of channels is too high" ); @@ -1572,18 +1793,29 @@ void ivas_dirac_dec_compute_directional_responses( hDirAC->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD || hDirAC->synthesisConf == DIRAC_SYNTHESIS_MONO ) { /* Synthesize the first direction */ +#ifdef JBM_TSM_ON_TCS + spreadCoherencePanningHoa( azimuth[k], elevation[k], hDirAC->spreadCoherence[md_idx][k], direct_response_hoa, num_channels_dir, hDirAC->hOutSetup.ambisonics_order ); +#else spreadCoherencePanningHoa( azimuth[k], elevation[k], hDirAC->spreadCoherence[hDirAC->dirac_read_idx][k], direct_response_hoa, num_channels_dir, hDirAC->hOutSetup.ambisonics_order ); - +#endif /* Synthesize the second direction and combine the gains */ if ( hDirAC->numSimultaneousDirections == 2 ) { +#ifdef JBM_TSM_ON_TCS + spreadCoherencePanningHoa( azimuth2[k], elevation2[k], hDirAC->spreadCoherence2[md_idx][k], direct_response_dir2, num_channels_dir, hDirAC->hOutSetup.ambisonics_order ); +#else spreadCoherencePanningHoa( azimuth2[k], elevation2[k], hDirAC->spreadCoherence2[hDirAC->dirac_read_idx][k], direct_response_dir2, num_channels_dir, hDirAC->hOutSetup.ambisonics_order ); - +#endif /* Combine gains from the two directions */ - totalDirect = hDirAC->energy_ratio1[hDirAC->dirac_read_idx][k] + hDirAC->energy_ratio2[hDirAC->dirac_read_idx][k] + EPSILON; - directRatio[0] = hDirAC->energy_ratio1[hDirAC->dirac_read_idx][k] / totalDirect; - directRatio[1] = hDirAC->energy_ratio2[hDirAC->dirac_read_idx][k] / totalDirect; - +#ifdef JBM_TSM_ON_TCS + totalDirect = hDirAC->energy_ratio1[md_idx][k] + hDirAC->energy_ratio2[md_idx][k] + EPSILON; + directRatio[0] = hDirAC->energy_ratio1[md_idx][k] / totalDirect; + directRatio[1] = hDirAC->energy_ratio2[md_idx][k] / totalDirect; +#else + totalDirect = hDirAC->energy_ratio1[hDirAC->dirac_read_idx]][k] + hDirAC->energy_ratio2[hDirAC->dirac_read_idx]][k] + EPSILON; + directRatio[0] = hDirAC->energy_ratio1[hDirAC->dirac_read_idx]][k] / totalDirect; + directRatio[1] = hDirAC->energy_ratio2[hDirAC->dirac_read_idx]][k] / totalDirect; +#endif for ( l = 0; l < num_channels_dir; l++ ) { direct_response_hoa[l] *= directRatio[0]; @@ -1631,20 +1863,33 @@ void ivas_dirac_dec_compute_directional_responses( else if ( hDirAC->panningConf == DIRAC_PANNING_VBAP ) /*VBAP*/ { /* Synthesize the first direction */ - spreadCoherencePanningVbap( azimuth[k], elevation[k], hDirAC->spreadCoherence[hDirAC->dirac_read_idx][k], direct_response_ls, num_channels_dir, hVBAPdata ); +#ifdef JBM_TSM_ON_TCS + spreadCoherencePanningVbap( azimuth[k], elevation[k], hDirAC->spreadCoherence[md_idx][k], direct_response_ls, num_channels_dir, hVBAPdata ); +#else + spreadCoherencePanningVbap( azimuth[k], elevation[k], hDirAC->spreadCoherence[hDirAC->dirac_read_idx]][k], direct_response_ls, num_channels_dir, hVBAPdata ); +#endif normalizePanningGains( direct_response_ls, num_channels_dir ); /* Synthesize the second direction and combine the gains */ if ( hDirAC->numSimultaneousDirections == 2 ) { - spreadCoherencePanningVbap( azimuth2[k], elevation2[k], hDirAC->spreadCoherence2[hDirAC->dirac_read_idx][k], direct_response_dir2, num_channels_dir, hVBAPdata ); - +#ifdef JBM_TSM_ON_TCS + spreadCoherencePanningVbap( azimuth2[k], elevation2[k], hDirAC->spreadCoherence2[md_idx][k], direct_response_dir2, num_channels_dir, hVBAPdata ); +#else + spreadCoherencePanningVbap( azimuth2[k], elevation2[k], hDirAC->spreadCoherence2[hDirAC->dirac_read_idx]][k], direct_response_dir2, num_channels_dir, hVBAPdata ); +#endif normalizePanningGains( direct_response_dir2, num_channels_dir ); /* Combine gains from the two directions */ - totalDirect = hDirAC->energy_ratio1[hDirAC->dirac_read_idx][k] + hDirAC->energy_ratio2[hDirAC->dirac_read_idx][k] + EPSILON; - directRatio[0] = hDirAC->energy_ratio1[hDirAC->dirac_read_idx][k] / totalDirect; - directRatio[1] = hDirAC->energy_ratio2[hDirAC->dirac_read_idx][k] / totalDirect; +#ifdef JBM_TSM_ON_TCS + totalDirect = hDirAC->energy_ratio1[md_idx][k] + hDirAC->energy_ratio2[md_idx][k] + EPSILON; + directRatio[0] = hDirAC->energy_ratio1[md_idx][k] / totalDirect; + directRatio[1] = hDirAC->energy_ratio2[md_idx][k] / totalDirect; +#else + totalDirect = hDirAC->energy_ratio1[hDirAC->dirac_read_idx]][k] + hDirAC->energy_ratio2[hDirAC->dirac_read_idx]][k] + EPSILON; + directRatio[0] = hDirAC->energy_ratio1[hDirAC->dirac_read_idx]][k] / totalDirect; + directRatio[1] = hDirAC->energy_ratio2[hDirAC->dirac_read_idx]][k] / totalDirect; +#endif for ( l = 0; l < num_channels_dir; l++ ) { direct_response_ls[l] *= directRatio[0]; diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 3f3080c8f8..288e308619 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -63,6 +63,11 @@ static ivas_error doSanityChecks_IVAS( Decoder_Struct *st_ivas ); ivas_error ivas_dec_setup( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +#ifdef JBM_TSM_ON_TCS + , + uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ + int16_t *data /* o : flushed PCM samples */ +#endif ) { int16_t k, idx, num_bits_read; @@ -112,10 +117,17 @@ ivas_error ivas_dec_setup( st_ivas->nchan_ism = nchan_ism; +#ifdef JBM_TSM_ON_TCS + if ( ( error = ivas_ism_dec_config( st_ivas, st_ivas->ism_mode, nSamplesRendered, data ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( ( error = ivas_ism_dec_config( st_ivas, st_ivas->ism_mode ) ) != IVAS_ERR_OK ) { return error; } +#endif } else if ( st_ivas->ivas_format == SBA_FORMAT ) { @@ -189,7 +201,11 @@ ivas_error ivas_dec_setup( num_bits_read += MC_LS_SETUP_BITS; /* select MC format mode; reconfigure the MC format decoder */ +#ifdef JBM_TSM_ON_TCS + ivas_mc_dec_config( st_ivas, idx, nSamplesRendered, data ); +#else ivas_mc_dec_config( st_ivas, idx ); +#endif } /*-------------------------------------------------------------------* @@ -410,6 +426,7 @@ static ivas_error ivas_read_format( break; case SID_ISM: st_ivas->ivas_format = ISM_FORMAT; + break; case SID_MULTICHANNEL: st_ivas->ivas_format = MC_FORMAT; @@ -1223,6 +1240,7 @@ ivas_error ivas_init_decoder( } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { + if ( ( error = ivas_td_binaural_open( st_ivas ) ) != IVAS_ERR_OK ) { return error; @@ -1235,6 +1253,19 @@ ivas_error ivas_init_decoder( return error; } } +#ifdef JBM_TSM_ON_TCS + if ( st_ivas->hDecoderConfig->voip_active ) + { + int16_t granularity; + int16_t n_channels_transport_jbm; + 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 ); + if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, n_channels_transport_jbm, n_channels_transport_jbm, n_channels_transport_jbm, granularity ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif } else if ( st_ivas->renderer_type == RENDERER_MC ) { @@ -1267,6 +1298,19 @@ ivas_error ivas_init_decoder( } st_ivas->binaural_latency_ns = st_ivas->hCrendWrapper->binaural_latency_ns; +#ifdef JBM_TSM_ON_TCS + if ( st_ivas->hDecoderConfig->voip_active ) + { + int16_t granularity; + int16_t n_channels_transport_jbm; + 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 ); + if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, n_channels_transport_jbm, n_channels_transport_jbm, n_channels_transport_jbm, granularity ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif } if ( st_ivas->ivas_format == ISM_FORMAT && @@ -1357,9 +1401,32 @@ ivas_error ivas_init_decoder( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Failed to open limiter handle" ); } +#ifdef JBM_TSM_ON_TCS + if ( st_ivas->hDecoderConfig->voip_active && st_ivas->hTcBuffer == NULL ) + { + /* no module has yet open the TC buffer, open a default one */ + int16_t n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); + if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, ivas_jbm_dec_get_tc_buffer_mode( st_ivas ), n_channels_transport_jbm, n_channels_transport_jbm, n_channels_transport_jbm, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) + { + return error; + } + } + if ( st_ivas->hTcBuffer == NULL ) + { + /* we need the handle anyway, but without the buffer*/ + if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_NONE, 0, 0, 0, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif + return error; } +#ifdef JBM_TSM_ON_TCS + +#endif /*------------------------------------------------------------------------- * destroy_core_dec() @@ -1577,6 +1644,10 @@ void ivas_initialize_handles_dec( st_ivas->hLsSetupCustom = NULL; st_ivas->hRenderConfig = NULL; +#ifdef JBM_TSM_ON_TCS + st_ivas->hTcBuffer = NULL; +#endif + return; } @@ -1654,6 +1725,9 @@ void ivas_destroy_dec( /* ISM renderer handle */ if ( st_ivas->hIsmRendererData != NULL ) { +#ifdef JBM_TSM_ON_TCS + free( st_ivas->hIsmRendererData->interpolator ); +#endif free( st_ivas->hIsmRendererData ); st_ivas->hIsmRendererData = NULL; } @@ -1764,6 +1838,10 @@ void ivas_destroy_dec( st_ivas->hDecoderConfig = NULL; } +#ifdef JBM_TSM_ON_TCS + ivas_jbm_dec_tc_buffer_close( &st_ivas->hTcBuffer ); +#endif + /* main IVAS handle */ free( st_ivas ); diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index f50200e50f..15bdc3de97 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef JBM_TSM_ON_TCS +#include "prot.h" +#endif #include "ivas_prot.h" #include "ivas_prot_rend.h" #ifdef DEBUGGING @@ -50,17 +53,37 @@ static ivas_error ivas_ism_bitrate_switching( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const int16_t nchan_transport_old, /* i : last number of transport channels */ const ISM_MODE last_ism_mode /* i : last ISM mode */ +#ifdef JBM_TSM_ON_TCS + , + uint16_t *nSamplesRendered, + int16_t *data +#endif ) { ivas_error error; int32_t element_brate_tmp[MAX_NUM_OBJECTS]; int16_t nSCE_old, nCPE_old; - +#ifdef JBM_TSM_ON_TCS + TC_BUFFER_MODE tc_buffer_mode_new; + int16_t tc_nchan_tc_new; + int16_t tc_nchan_allocate_new; + int16_t tc_granularity_new; + AUDIO_CONFIG intern_config_old; + IVAS_OUTPUT_SETUP hIntSetupOld; + RENDERER_TYPE renderer_type_old; +#endif +#ifdef TMP_FIX_ISM_BR_SWITCHING + int16_t numCldfbAnalyses_old, numCldfbSyntheses_old; +#endif error = IVAS_ERR_OK; nCPE_old = st_ivas->nCPE; nSCE_old = st_ivas->nSCE; +#ifdef TMP_FIX_ISM_BR_SWITCHING + ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old ); +#endif + if ( ( error = ivas_ism_config( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->nchan_ism, NULL, NULL, NULL, element_brate_tmp, NULL, NULL ) ) != IVAS_ERR_OK ) { return error; @@ -86,6 +109,14 @@ static ivas_error ivas_ism_bitrate_switching( return error; } +#ifdef JBM_TSM_ON_TCS + /* save old IntSetup, might be needed for JBM flushing...*/ + intern_config_old = st_ivas->intern_config; + hIntSetupOld = st_ivas->hIntSetup; + tc_granularity_new = 1; + renderer_type_old = st_ivas->renderer_type; +#endif + /*-----------------------------------------------------------------* * Initialize the needed renderer struct and destroy the unnecessary renderer struct *-----------------------------------------------------------------*/ @@ -98,6 +129,39 @@ static ivas_error ivas_ism_bitrate_switching( ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->hDecoderConfig->output_config ); } +#ifdef JBM_TSM_ON_TCS + if ( st_ivas->hDecoderConfig->voip_active ) + { + /* transfer subframe info from DirAC or ParamMC to central tc buffer */ + if ( last_ism_mode == ISM_MODE_PARAM && st_ivas->hDirAC != NULL ) + { + st_ivas->hTcBuffer->nb_subframes = st_ivas->hDirAC->nb_subframes; + st_ivas->hTcBuffer->subframes_rendered = st_ivas->hDirAC->subframes_rendered; + st_ivas->hTcBuffer->num_slots = st_ivas->hDirAC->num_slots; + st_ivas->hTcBuffer->slots_rendered = st_ivas->hDirAC->slots_rendered; + mvs2s( st_ivas->hDirAC->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); + } + /* JBM: when granularity goes down (e.g. Discrete ISM with TD Obj Renderer -> ParamISM with binaural fastconv + render what still fits in the new granularity */ + tc_granularity_new = ivas_jbm_dec_get_render_granularity( st_ivas->renderer_type, 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, MC_MODE_NONE, last_ism_mode, nSamplesRendered, data ) ) != IVAS_ERR_OK ) + { + return error; + } + } + /* JBM: when granularity goes up set samples to discard at the beginning of the frame */ + else if ( tc_granularity_new > st_ivas->hTcBuffer->n_samples_granularity ) + { + if ( ( error = ivas_jbm_dec_set_discard_samples( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } +#endif + if ( st_ivas->ism_mode != last_ism_mode ) { /* EFAP handle */ @@ -221,6 +285,57 @@ static ivas_error ivas_ism_bitrate_switching( } } +#ifdef TMP_FIX_ISM_BR_SWITCHING + /*-----------------------------------------------------------------* + * CLDFB instances + *-----------------------------------------------------------------*/ + + ivas_cldfb_dec_reconfig( st_ivas, nchan_transport_old, numCldfbAnalyses_old, numCldfbSyntheses_old ); +#endif +#ifdef JBM_TSM_ON_TCS + /*-----------------------------------------------------------------* + * Reconfigure TC buffer + *-----------------------------------------------------------------*/ + if ( st_ivas->hDecoderConfig->voip_active == 1 ) + { + int16_t tc_nchan_full_new; + DECODER_TC_BUFFER_HANDLE hTcBuffer; + + hTcBuffer = st_ivas->hTcBuffer; + tc_buffer_mode_new = ivas_jbm_dec_get_tc_buffer_mode( st_ivas ); + tc_nchan_tc_new = ivas_jbm_dec_get_num_tc_channels( st_ivas ); + tc_nchan_allocate_new = tc_nchan_tc_new; + tc_nchan_full_new = tc_nchan_tc_new; + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + tc_nchan_allocate_new = 2 * BINAURAL_CHANNELS; + tc_nchan_full_new = tc_nchan_allocate_new; + } + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { + tc_nchan_full_new = 0; + } + /* reconfigure buffer */ + if ( hTcBuffer->tc_buffer_mode != tc_buffer_mode_new || hTcBuffer->nchan_transport_jbm != tc_nchan_tc_new || + hTcBuffer->nchan_buffer_full != tc_nchan_full_new || hTcBuffer->nchan_transport_internal != tc_nchan_allocate_new ) + { + if ( ( error = ivas_jbm_dec_tc_buffer_reconfigure( st_ivas, tc_buffer_mode_new, tc_nchan_tc_new, tc_nchan_allocate_new, tc_nchan_full_new, tc_granularity_new ) ) != IVAS_ERR_OK ) + { + return error; + } + } + /* transfer subframe info from central tc buffer to ParamMC or McMASA (DirAC) */ + if ( st_ivas->hDirAC != NULL ) + { + st_ivas->hDirAC->nb_subframes = st_ivas->hTcBuffer->nb_subframes; + st_ivas->hDirAC->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered; + st_ivas->hDirAC->num_slots = st_ivas->hTcBuffer->num_slots; + st_ivas->hDirAC->slots_rendered = st_ivas->hTcBuffer->slots_rendered; + mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hDirAC->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); + } + } +#endif + return error; } @@ -236,6 +351,11 @@ ivas_error ivas_ism_dec_config( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ , const ISM_MODE last_ism_mode /* i/o: last ISM mode */ +#ifdef JBM_TSM_ON_TCS + , + uint16_t *nSamplesRendered, /* o : number of samples flushed when the renderer granularity changes */ + int16_t *data +#endif ) { int32_t ivas_total_brate; @@ -276,7 +396,11 @@ ivas_error ivas_ism_dec_config( { if ( ( st_ivas->ism_mode != last_ism_mode ) || ( st_ivas->hDecoderConfig->ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate ) ) { +#ifdef JBM_TSM_ON_TCS + if ( ( error = ivas_ism_bitrate_switching( st_ivas, nchan_transport_old, last_ism_mode, nSamplesRendered, data ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_ism_bitrate_switching( st_ivas, nchan_transport_old, last_ism_mode ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -299,7 +423,11 @@ ivas_error ivas_ism_dec_config( /* ISM mode switching */ if ( st_ivas->ism_mode != last_ism_mode ) { +#ifdef JBM_TSM_ON_TCS + if ( ( error = ivas_ism_bitrate_switching( st_ivas, nchan_transport_old, last_ism_mode, nSamplesRendered, data ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_ism_bitrate_switching( st_ivas, nchan_transport_old, last_ism_mode ) ) != IVAS_ERR_OK ) +#endif { return error; } diff --git a/lib_dec/ivas_ism_dtx_dec.c b/lib_dec/ivas_ism_dtx_dec.c index 4e987c2920..da697aa8b2 100644 --- a/lib_dec/ivas_ism_dtx_dec.c +++ b/lib_dec/ivas_ism_dtx_dec.c @@ -130,8 +130,11 @@ ivas_error ivas_ism_dtx_dec( ism_mode_bstr = (ISM_MODE) ( idx + 1 ); st_ivas->ism_mode = ism_mode_bstr; } - +#ifdef JBM_TSM_ON_TCS + if ( ( error = ivas_ism_dec_config( st_ivas, last_ism_mode, NULL, NULL ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_ism_dec_config( st_ivas, last_ism_mode ) ) != IVAS_ERR_OK ) +#endif { return error; } diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 244bf1f398..16988f05aa 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -157,7 +157,133 @@ static void ivas_ism_get_proto_matrix( return; } +#ifdef JBM_TSM_ON_TCS +static void ivas_param_ism_collect_slot( + DIRAC_DEC_HANDLE hDirAC, /* i/o: decoder DirAC handle */ + float *Cldfb_RealBuffer_in, + float *Cldfb_ImagBuffer_in, + const int16_t ch, + float ref_power[], + float cx_diag[][PARAM_ISM_MAX_DMX] ) +{ + + int16_t band_idx, bin_idx; + int16_t brange[2]; + float tmp; + + /* loop over parameter bands to collect transport channel energies */ + for ( band_idx = 0; band_idx < hDirAC->hParamIsm->nbands; band_idx++ ) + { + brange[0] = hDirAC->hParamIsm->band_grouping[band_idx]; + brange[1] = hDirAC->hParamIsm->band_grouping[band_idx + 1]; + for ( bin_idx = brange[0]; bin_idx < brange[1]; bin_idx++ ) + { + tmp = 0.0f; + tmp += ( Cldfb_RealBuffer_in[bin_idx] * Cldfb_RealBuffer_in[bin_idx] ); + tmp += ( Cldfb_ImagBuffer_in[bin_idx] * Cldfb_ImagBuffer_in[bin_idx] ); + cx_diag[bin_idx][ch] += tmp; + ref_power[bin_idx] += tmp; + } + } + return; +} +static void ivas_param_ism_compute_mixing_matrix( + const int16_t nchan_ism, /* i : number of ISM channels */ + DIRAC_DEC_HANDLE hDirAC, /* i/o: decoder DirAC handle */ + ISM_DTX_DATA_DEC hISMDTX, /* i : ISM DTX handle */ + float direct_response[MAX_NUM_OBJECTS][PARAM_ISM_MAX_CHAN], + const int16_t nchan_transport, + const int16_t nchan_out_woLFE, + const float cx_diag[][PARAM_ISM_MAX_DMX], + const float ref_power[], + float mixing_matrix[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX] ) +{ + int16_t band_idx, bin_idx; + int16_t i, w, obj_indx; + int16_t brange[2]; + float direct_power[MAX_NUM_OBJECTS]; + float cy_diag[PARAM_ISM_MAX_CHAN]; + float cy_diag_tmp[MAX_NUM_OBJECTS][PARAM_ISM_MAX_CHAN]; + float *dir_res_ptr; + float *proto_matrix; + float response_matrix[PARAM_ISM_MAX_CHAN * MAX_NUM_OBJECTS]; + int16_t num_wave; + + proto_matrix = hDirAC->hParamIsmRendering->proto_matrix; + + assert( ( nchan_ism == 3 ) || ( nchan_ism == 4 ) ); + assert( nchan_transport == 2 ); + + if ( hDirAC->hParamIsm->flag_noisy_speech || hISMDTX.dtx_flag ) + { + num_wave = nchan_ism; + } + else + { + num_wave = MAX_PARAM_ISM_WAVE; + } + set_zero( response_matrix, PARAM_ISM_MAX_CHAN * MAX_NUM_OBJECTS ); + + /* loop over parameter bands to compute the mixing matrix */ + for ( band_idx = 0; band_idx < hDirAC->hParamIsm->nbands; band_idx++ ) + { + brange[0] = hDirAC->hParamIsm->band_grouping[band_idx]; + brange[1] = hDirAC->hParamIsm->band_grouping[band_idx + 1]; + + /* Compute covaraince matrix from direct response*/ + for ( w = 0; w < num_wave; w++ ) + { + set_zero( cy_diag_tmp[w], nchan_out_woLFE ); + + if ( hDirAC->hParamIsm->flag_noisy_speech || hISMDTX.dtx_flag ) + { + dir_res_ptr = direct_response[w]; + } + else + { + obj_indx = hDirAC->hParamIsm->obj_indices[band_idx][0][w]; + dir_res_ptr = direct_response[obj_indx]; + } + mvr2r( dir_res_ptr, response_matrix + w * nchan_out_woLFE, nchan_out_woLFE ); + /* we only need the diagonal of Cy*/ + matrix_product_diag( dir_res_ptr, nchan_out_woLFE, 1, 0, dir_res_ptr, 1, nchan_out_woLFE, 0, cy_diag_tmp[w] ); + } + + for ( bin_idx = brange[0]; bin_idx < brange[1]; bin_idx++ ) + { + + set_zero( cy_diag, nchan_out_woLFE ); + for ( w = 0; w < num_wave; w++ ) + { + if ( hDirAC->hParamIsm->flag_noisy_speech || hISMDTX.dtx_flag ) + { + direct_power[w] = ( 1.0f / nchan_ism ) * ref_power[bin_idx]; + } + else + { + direct_power[w] = hDirAC->power_ratios[band_idx][0][w] * ref_power[bin_idx]; + } + + if ( direct_power[w] != 0.f ) + { + for ( i = 0; i < nchan_out_woLFE; i++ ) + { + cy_diag[i] += direct_power[w] * cy_diag_tmp[w][i]; + } + } + direct_power[w] = sqrtf( direct_power[w] ); + } + /* Compute mixing matrix */ + computeMixingMatricesISM( nchan_transport, num_wave, nchan_out_woLFE, response_matrix, direct_power, cx_diag[bin_idx], cy_diag, proto_matrix, 1, + PARAM_MC_REG_SX, PARAM_MC_REG_GHAT, mixing_matrix[bin_idx] ); + } + } + + return; +} + +#else static void ivas_param_ism_compute_mixing_matrix( const int16_t nchan_ism, /* i : number of ISM channels */ DIRAC_DEC_HANDLE hDirAC, /* i/o: decoder DirAC handle */ @@ -276,7 +402,45 @@ static void ivas_param_ism_compute_mixing_matrix( return; } +#endif + +#ifdef JBM_TSM_ON_TCS +static void ivas_param_ism_render_slot( + DIRAC_DEC_HANDLE hDirAC, + float *Cldfb_RealBuffer_in[PARAM_ISM_MAX_DMX], + float *Cldfb_ImagBuffer_in[PARAM_ISM_MAX_DMX], + float Cldfb_RealBuffer[PARAM_ISM_MAX_CHAN][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer[PARAM_ISM_MAX_CHAN][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + float mixing_matrix[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX], + const int16_t interpolator_idx, + const int16_t out_slot_idx, + const int16_t num_ch_LS, + const int16_t nchan_transport ) +{ + int16_t outchIdx, inchIdx, bin_idx; + float tmp_1, mixing_matrix_smooth; + tmp_1 = hDirAC->hParamIsmRendering->interpolator[interpolator_idx]; + + for ( bin_idx = 0; bin_idx < hDirAC->num_freq_bands; bin_idx++ ) + { + /* smooth the mixing matrix */ + for ( outchIdx = 0; outchIdx < num_ch_LS; outchIdx++ ) + { + for ( inchIdx = 0; inchIdx < nchan_transport; inchIdx++ ) + { + mixing_matrix_smooth = tmp_1 * mixing_matrix[bin_idx][outchIdx + inchIdx * num_ch_LS] + + ( 1 - tmp_1 ) * hDirAC->hParamIsmRendering->mixing_matrix_lin_old[bin_idx][outchIdx + inchIdx * num_ch_LS]; + + Cldfb_RealBuffer[outchIdx][out_slot_idx][bin_idx] += mixing_matrix_smooth * Cldfb_RealBuffer_in[inchIdx][bin_idx]; + Cldfb_ImagBuffer[outchIdx][out_slot_idx][bin_idx] += mixing_matrix_smooth * Cldfb_ImagBuffer_in[inchIdx][bin_idx]; + } + } + } + + return; +} +#endif static void ivas_param_ism_rendering( DIRAC_DEC_HANDLE hDirAC, @@ -434,9 +598,19 @@ ivas_error ivas_param_ism_dec_open( *-----------------------------------------------------------------*/ hDirAC->slot_size = (int16_t) ( ( output_Fs / FRAMES_PER_SEC ) / CLDFB_NO_COL_MAX ); +#ifdef JBM_TSM_ON_TCS + hDirAC->hConfig = NULL; + set_s( hDirAC->subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS ); + set_s( hDirAC->subframe_nbslots, JBM_CLDFB_SLOTS_IN_SUBFRAME, DEFAULT_JBM_SUBFRAMES_5MS ); + hDirAC->nb_subframes = DEFAULT_JBM_SUBFRAMES_5MS; + hDirAC->subframes_rendered = 0; + hDirAC->slots_rendered = 0; + hDirAC->num_slots = DEFAULT_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME; +#else hDirAC->subframe_nbslots = (int16_t) ( CLDFB_NO_COL_MAX * 5.f / 20.f + 0.5f ); hDirAC->nb_subframes = CLDFB_NO_COL_MAX / hDirAC->subframe_nbslots; assert( hDirAC->nb_subframes <= MAX_PARAM_SPATIAL_SUBFRAMES ); +#endif hDirAC->num_freq_bands = (int16_t) ( output_Fs * INV_CLDFB_BANDWIDTH + 0.5f ); hDirAC->hParamIsm->nbands = MAX_PARAM_ISM_NBANDS; @@ -468,10 +642,24 @@ ivas_error ivas_param_ism_dec_open( if ( !( output_config == AUDIO_CONFIG_MONO || output_config == AUDIO_CONFIG_STEREO ) ) { /* Initialize Param ISM Rendering handle */ - if ( ( error = ivas_param_ism_rendering_init( hDirAC->hParamIsmRendering, hOutSetup, st_ivas->nchan_transport, CLDFB_NO_COL_MAX, output_config ) ) != IVAS_ERR_OK ) +#ifdef JBM_TSM_ON_TCS + if ( st_ivas->hDecoderConfig->voip_active ) { - return error; + if ( ( error = ivas_param_ism_rendering_init( hDirAC->hParamIsmRendering, hOutSetup, st_ivas->nchan_transport, MAX_JBM_CLDFB_TIMESLOTS, output_config ) ) != IVAS_ERR_OK ) + { + return error; + } } + else + { +#endif + if ( ( error = ivas_param_ism_rendering_init( hDirAC->hParamIsmRendering, hOutSetup, st_ivas->nchan_transport, CLDFB_NO_COL_MAX, output_config ) ) != IVAS_ERR_OK ) + { + return error; + } +#ifdef JBM_TSM_ON_TCS + } +#endif } if ( !( output_config == AUDIO_CONFIG_EXTERNAL || output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM || output_config == AUDIO_CONFIG_MONO || output_config == AUDIO_CONFIG_STEREO ) ) @@ -487,14 +675,20 @@ ivas_error ivas_param_ism_dec_open( set_zero( hDirAC->azimuth_values, MAX_NUM_OBJECTS ); set_zero( hDirAC->elevation_values, MAX_NUM_OBJECTS ); +#ifdef JBM_TSM_ON_TCS + hDirAC->dirac_md_buffer_length = MAX_PARAM_SPATIAL_SUBFRAMES; +#else hDirAC->dirac_md_buffer_length = 0; +#endif hDirAC->dirac_bs_md_write_idx = 0; hDirAC->dirac_read_idx = 0; hDirAC->spar_to_dirac_write_idx = 0; if ( ( output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM ) ) { +#ifndef JBM_TSM_ON_TCS hDirAC->dirac_md_buffer_length = MAX_PARAM_SPATIAL_SUBFRAMES; +#endif if ( ( hDirAC->azimuth = (int16_t **) malloc( hDirAC->dirac_md_buffer_length * sizeof( int16_t * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Param ISM Rendering handle\n" ) ); @@ -602,6 +796,29 @@ ivas_error ivas_param_ism_dec_open( st_ivas->hDirAC = hDirAC; +#ifdef JBM_TSM_ON_TCS + if ( st_ivas->hDecoderConfig->voip_active && st_ivas->renderer_type != RENDERER_MONO_DOWNMIX ) + { + int16_t nchan_transport = st_ivas->nchan_transport; + hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands * sizeof( float ) ); + set_zero( hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc, MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands ); + hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands * sizeof( float ) ); + set_zero( hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc, MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands ); + if ( st_ivas->hTcBuffer == NULL ) + { + if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_transport, nchan_transport, 0, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + else + { + hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = NULL; + hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc = NULL; + } +#endif + pop_wmops(); return error; } @@ -777,6 +994,19 @@ void ivas_param_ism_dec_close( } } +#ifdef JBM_TSM_ON_TCS + if ( hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc != NULL ) + { + free( hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc ); + hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = NULL; + } + if ( hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc != NULL ) + { + free( hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc ); + hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc = NULL; + } +#endif + if ( hDirAC->hParamIsmRendering != NULL ) { free( hDirAC->hParamIsmRendering ); @@ -804,7 +1034,10 @@ void ivas_param_ism_dec( int16_t ch, nchan_transport, nchan_out, nchan_out_woLFE, i; int16_t subframe_idx, slot_idx, index_slot, bin_idx; int32_t ivas_total_brate; - +#ifdef JBM_TSM_ON_TCS + float ref_power[CLDFB_NO_CHANNELS_MAX]; + float cx_diag[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; +#endif /* CLDFB Input Buffers */ float Cldfb_RealBuffer_in[PARAM_ISM_MAX_DMX][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_in[PARAM_ISM_MAX_DMX][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; @@ -846,6 +1079,15 @@ void ivas_param_ism_dec( push_wmops( "ivas_param_ism_dec" ); +#ifdef JBM_TSM_ON_TCS + /* set buffers to zero */ + for ( bin_idx = 0; bin_idx < CLDFB_NO_CHANNELS_MAX; bin_idx++ ) + { + set_zero( cx_diag[bin_idx], PARAM_ISM_MAX_DMX ); + } + set_zero( ref_power, CLDFB_NO_CHANNELS_MAX ); +#endif + /* Frame-level Processing */ /* De-quantization */ if ( !( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) ) @@ -910,6 +1152,10 @@ void ivas_param_ism_dec( for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) { cldfbAnalysis_ts( &( output_f[ch][hDirAC->num_freq_bands * slot_idx] ), Cldfb_RealBuffer_in[ch][slot_idx], Cldfb_ImagBuffer_in[ch][slot_idx], hDirAC->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); + +#ifdef JBM_TSM_ON_TCS + ivas_param_ism_collect_slot( hDirAC, Cldfb_RealBuffer_in[ch][slot_idx], Cldfb_ImagBuffer_in[ch][slot_idx], ch, ref_power, cx_diag ); +#endif } } @@ -920,26 +1166,42 @@ void ivas_param_ism_dec( } /* Compute mixing matrix */ +#ifdef JBM_TSM_ON_TCS + ivas_param_ism_compute_mixing_matrix( st_ivas->nchan_ism,hDirAC, st_ivas->hISMDTX, direct_response, nchan_transport, nchan_out_woLFE, cx_diag, ref_power, mixing_matrix ); +#else ivas_param_ism_compute_mixing_matrix( st_ivas->nchan_ism, hDirAC, st_ivas->hISMDTX, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, direct_response, nchan_transport, nchan_out_woLFE, 0, CLDFB_NO_COL_MAX, mixing_matrix ); - +#endif /* subframe loop for synthesis*/ for ( subframe_idx = 0; subframe_idx < hDirAC->nb_subframes; subframe_idx++ ) { +#ifdef JBM_TSM_ON_TCS + /* TODO: JBM just a quick fix to gewt SBA running, change to the right thing later...*/ + uint16_t slot_idx_start = subframe_idx * hDirAC->subframe_nbslots[subframe_idx]; +#else uint16_t slot_idx_start = subframe_idx * hDirAC->subframe_nbslots; +#endif uint16_t idx_in; uint16_t idx_lfe; /* Set some memories to zero */ for ( ch = 0; ch < nchan_out_woLFE; ch++ ) { +#ifdef JBM_TSM_ON_TCS + for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) +#else for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots; slot_idx++ ) +#endif { set_f( Cldfb_RealBuffer[ch][slot_idx], 0.0f, hDirAC->num_freq_bands ); set_f( Cldfb_ImagBuffer[ch][slot_idx], 0.0f, hDirAC->num_freq_bands ); } } +#ifdef JBM_TSM_ON_TCS + for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) +#else for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots; slot_idx++ ) +#endif { index_slot = slot_idx_start + slot_idx; @@ -957,8 +1219,11 @@ void ivas_param_ism_dec( { if ( ( hSetup.num_lfe > 0 ) && ( hSetup.index_lfe[idx_lfe] == ch ) ) { +#ifdef JBM_TSM_ON_TCS + set_zero( &( output_f[ch][slot_idx_start * hDirAC->num_freq_bands] ), hDirAC->subframe_nbslots[subframe_idx] * hDirAC->num_freq_bands ); +#else set_zero( &( output_f[ch][slot_idx_start * hDirAC->num_freq_bands] ), hDirAC->subframe_nbslots * hDirAC->num_freq_bands ); - +#endif if ( idx_lfe < ( hSetup.num_lfe - 1 ) ) { idx_lfe++; @@ -970,14 +1235,22 @@ void ivas_param_ism_dec( float *ImagBuffer[16]; /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */ +#ifdef JBM_TSM_ON_TCS + for ( i = 0; i < hDirAC->subframe_nbslots[subframe_idx]; i++ ) +#else for ( i = 0; i < hDirAC->subframe_nbslots; i++ ) +#endif { RealBuffer[i] = Cldfb_RealBuffer[idx_in][i]; ImagBuffer[i] = Cldfb_ImagBuffer[idx_in][i]; } - +#ifdef JBM_TSM_ON_TCS + cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][slot_idx_start * hDirAC->num_freq_bands] ), + hDirAC->num_freq_bands * hDirAC->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[ch] ); +#else cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][slot_idx_start * hDirAC->num_freq_bands] ), hDirAC->num_freq_bands * hDirAC->subframe_nbslots, st_ivas->cldfbSynDec[ch] ); +#endif idx_in++; } @@ -1008,6 +1281,396 @@ void ivas_param_ism_dec( return; } +#ifdef JBM_TSM_ON_TCS +void ivas_ism_dec_digest_tc( + Decoder_Struct *st_ivas ) +{ + + ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); + + if ( + st_ivas->renderer_type == RENDERER_TD_PANNING || + st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || + ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM && st_ivas->hDecoderConfig->Opt_Headrotation == 0 ) ) + { + int16_t i, num_objects; + int16_t azimuth, elevation; + /* we have a full frame interpolator, adapt it */ + /* for BE testing */ + if ( ( st_ivas->hDecoderConfig->output_Fs / (int32_t) FRAMES_PER_SECOND ) == st_ivas->hTcBuffer->n_samples_available ) + { + int16_t interpolator_length = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / (int32_t) FRAMES_PER_SECOND ); + for ( i = 0; i < interpolator_length; i++ ) + { + st_ivas->hIsmRendererData->interpolator[i] = (float) i / ( (float) interpolator_length - 1 ); + } + } + else + { + ivas_jbm_dec_get_adapted_linear_interpolator( (int16_t) ( st_ivas->hDecoderConfig->output_Fs / (int32_t) FRAMES_PER_SECOND ), + st_ivas->hTcBuffer->n_samples_available, + st_ivas->hIsmRendererData->interpolator ); + } + /* also get the gains here */ + num_objects = st_ivas->nchan_transport; + for ( i = 0; i < num_objects; i++ ) + { + mvr2r( st_ivas->hIsmRendererData->gains[i], st_ivas->hIsmRendererData->prev_gains[i], MAX_OUTPUT_CHANNELS ); + if ( st_ivas->intern_config == AUDIO_CONFIG_STEREO ) + { + ivas_ism_get_stereo_gains( st_ivas->hIsmMetaData[i]->azimuth, + st_ivas->hIsmMetaData[i]->elevation, + &st_ivas->hIsmRendererData->gains[i][0], + &st_ivas->hIsmRendererData->gains[i][1] ); + } + 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->renderer_type == RENDERER_TD_PANNING || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) && st_ivas->hHeadTrackData == NULL ) + { + + + 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, st_ivas->hIsmRendererData->gains[i], azimuth, elevation, EFAP_MODE_EFAP ); + } + } + else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) + { + /*get HOA gets for direction (ACN/SN3D)*/ + ivas_dirac_dec_get_response( azimuth, elevation, st_ivas->hIsmRendererData->gains[i], st_ivas->hIntSetup.ambisonics_order ); + } + } + } + } + return; +} + +void ivas_param_ism_dec_digest_tc( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint16_t nCldfbSlots, /* i : number of CLFBS slots in the transport channels */ + float *transport_channels_f[] /* i : synthesized core-coder transport channels/DirAC output */ +) +{ + int16_t ch, nchan_transport, nchan_out, nchan_out_woLFE, i; + int16_t slot_idx, bin_idx; + int32_t ivas_total_brate; + float ref_power[CLDFB_NO_CHANNELS_MAX]; + float cx_diag[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX]; + /* Direct Response/EFAP Gains */ + float direct_response[MAX_NUM_OBJECTS][PARAM_ISM_MAX_CHAN]; + + DIRAC_DEC_HANDLE hDirAC; + + IVAS_OUTPUT_SETUP hSetup; + + /* Initialization */ + hDirAC = st_ivas->hDirAC; + assert( hDirAC ); + + nchan_transport = st_ivas->nchan_transport; + ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; + + if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_EXTERNAL ) + { + nchan_out = st_ivas->nchan_ism; + nchan_out_woLFE = nchan_out; + st_ivas->hDecoderConfig->nchan_out = nchan_out; + } + else + { + nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; + nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; + } + + hSetup = st_ivas->hIntSetup; + + push_wmops( "ivas_param_ism_dec" ); + + /* general setup */ + ivas_jbm_dec_get_adapted_linear_interpolator( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbSlots, hDirAC->hParamIsmRendering->interpolator ); + + ivas_dirac_dec_set_md_map( st_ivas, nCldfbSlots ); + + /* set buffers to zero */ + for ( bin_idx = 0; bin_idx < CLDFB_NO_CHANNELS_MAX; bin_idx++ ) + { + set_zero( cx_diag[bin_idx], PARAM_ISM_MAX_DMX ); + } + set_zero( ref_power, CLDFB_NO_CHANNELS_MAX ); + + /* Frame-level Processing */ + /* De-quantization */ + if ( !( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) ) + { + ivas_param_ism_dec_dequant_DOA( hDirAC, st_ivas->nchan_ism ); + ivas_param_ism_dec_dequant_powrat( hDirAC ); + st_ivas->hISMDTX.dtx_flag = 0; + } + else + { + st_ivas->hISMDTX.dtx_flag = 1; + } + + /* obtain the direct response using EFAP */ + if ( !( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_EXTERNAL ) ) + { + for ( i = 0; i < st_ivas->nchan_ism; i++ ) + { + efap_determine_gains( st_ivas->hEFAPdata, direct_response[i], hDirAC->azimuth_values[i], hDirAC->elevation_values[i], EFAP_MODE_EFAP ); + } + } + else + { + int16_t j; + + for ( i = 0; i < st_ivas->nchan_ism; i++ ) + { + for ( j = 0; j < nchan_out_woLFE; j++ ) + { + if ( i == j ) + { + direct_response[i][j] = 1.0f; + } + else + { + direct_response[i][j] = 0.0f; + } + } + } + + for ( i = 0; i < nchan_transport; i++ ) + { + for ( j = 0; j < nchan_out_woLFE; j++ ) + { + if ( i == j ) + { + hDirAC->hParamIsmRendering->proto_matrix[( i * nchan_out_woLFE ) + j] = 1.0f; + } + else + { + hDirAC->hParamIsmRendering->proto_matrix[( i * nchan_out_woLFE ) + j] = 0.0f; + } + } + } + } + + for ( ch = 0; ch < nchan_transport; ch++ ) + { + /*-----------------------------------------------------------------* + * CLDFB Analysis + *-----------------------------------------------------------------*/ + for ( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) + { + float RealBuffer[CLDFB_NO_CHANNELS_MAX]; + float ImagBuffer[CLDFB_NO_CHANNELS_MAX]; + + cldfbAnalysis_ts( &( transport_channels_f[ch][hDirAC->num_freq_bands * slot_idx] ), RealBuffer, ImagBuffer, hDirAC->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); + mvr2r( RealBuffer, &hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc[slot_idx * hDirAC->num_freq_bands * nchan_transport + ch * hDirAC->num_freq_bands], hDirAC->num_freq_bands ); + mvr2r( ImagBuffer, &hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc[slot_idx * hDirAC->num_freq_bands * nchan_transport + ch * hDirAC->num_freq_bands], hDirAC->num_freq_bands ); + + ivas_param_ism_collect_slot( hDirAC, RealBuffer, ImagBuffer, ch, ref_power, cx_diag ); + } + } + + /* Obtain Mixing Matrix on a frame-level */ + for ( bin_idx = 0; bin_idx < hDirAC->num_freq_bands; bin_idx++ ) + { + set_f( hDirAC->hParamIsmRendering->mixing_matrix_lin[bin_idx], 0.0f, nchan_transport * nchan_out_woLFE ); + } + + /* Compute mixing matrix */ + ivas_param_ism_compute_mixing_matrix( st_ivas->nchan_ism, hDirAC, st_ivas->hISMDTX, direct_response, nchan_transport, nchan_out_woLFE, cx_diag, ref_power, hDirAC->hParamIsmRendering->mixing_matrix_lin ); + + + pop_wmops(); + + return; +} + +static void ivas_ism_param_dec_render_sf( Decoder_Struct *st_ivas, + IVAS_OUTPUT_SETUP hSetup, + const int16_t nchan_transport, + const int16_t nchan_out, + const int16_t nchan_out_woLFE, + float *output_f[] /* o : rendered time signal */ +) +{ + + int16_t ch, slot_idx, i, index_slot; + /* CLDFB Output Buffers */ + float Cldfb_RealBuffer[PARAM_ISM_MAX_CHAN][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer[PARAM_ISM_MAX_CHAN][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float *Cldfb_RealBuffer_in[PARAM_ISM_MAX_DMX]; + float *Cldfb_ImagBuffer_in[PARAM_ISM_MAX_DMX]; + DIRAC_DEC_HANDLE hDirAC; + + /* TODO: JBM just a quick fix to gewt SBA running, change to the right thing later...*/ + int16_t slot_idx_start; + int16_t idx_in; + int16_t idx_lfe; + int16_t subframe_idx; + + hDirAC = st_ivas->hDirAC; + slot_idx_start = hDirAC->slots_rendered; + subframe_idx = hDirAC->subframes_rendered; + + /* Set some memories to zero */ + for ( ch = 0; ch < nchan_out_woLFE; ch++ ) + { + for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) + { + set_f( Cldfb_RealBuffer[ch][slot_idx], 0.0f, hDirAC->num_freq_bands ); + set_f( Cldfb_ImagBuffer[ch][slot_idx], 0.0f, hDirAC->num_freq_bands ); + } + } + + for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) + { + index_slot = slot_idx_start + slot_idx; + + for ( ch = 0; ch < nchan_transport; ch++ ) + { + Cldfb_RealBuffer_in[ch] = &hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc[index_slot * hDirAC->num_freq_bands * nchan_transport + ch * hDirAC->num_freq_bands]; + Cldfb_ImagBuffer_in[ch] = &hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc[index_slot * hDirAC->num_freq_bands * nchan_transport + ch * hDirAC->num_freq_bands]; + } + + + /* Compute bandwise rendering to target LS using covariance rendering */ + ivas_param_ism_render_slot( hDirAC, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, + Cldfb_RealBuffer, Cldfb_ImagBuffer, hDirAC->hParamIsmRendering->mixing_matrix_lin, index_slot, slot_idx, + nchan_out_woLFE, nchan_transport ); + } + + /* CLDFB Synthesis */ + idx_in = 0; + idx_lfe = 0; + + for ( ch = 0; ch < nchan_out; ch++ ) + { + if ( ( hSetup.num_lfe > 0 ) && ( hSetup.index_lfe[idx_lfe] == ch ) ) + { + set_zero( output_f[ch], hDirAC->subframe_nbslots[subframe_idx] * hDirAC->num_freq_bands ); + if ( idx_lfe < ( hSetup.num_lfe - 1 ) ) + { + idx_lfe++; + } + } + else + { + float *RealBuffer[16]; + float *ImagBuffer[16]; + + /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */ + for ( i = 0; i < hDirAC->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], + hDirAC->num_freq_bands * hDirAC->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[ch] ); + idx_in++; + } + } + hDirAC->slots_rendered += hDirAC->subframe_nbslots[subframe_idx]; + hDirAC->subframes_rendered++; +} + +void ivas_param_ism_dec_render( + 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 *nSamplesAvailable, /* o : number of CLDFB slots still to render */ + float *output_f[] /* o : rendered time signal */ +) +{ + int16_t ch, slots_to_render, first_sf, last_sf, subframe_idx; + uint16_t slot_size, n_samples_sf; + DIRAC_DEC_HANDLE hDirAC; + IVAS_OUTPUT_SETUP hSetup; + int16_t nchan_transport, nchan_out, nchan_out_woLFE; + float *output_f_local[MAX_OUTPUT_CHANNELS]; + + hDirAC = st_ivas->hDirAC; + hSetup = st_ivas->hIntSetup; +#ifdef DEBUGGING + assert( hDirAC ); +#endif + nchan_transport = st_ivas->nchan_transport; + if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_EXTERNAL ) + { + nchan_out = st_ivas->nchan_ism; + nchan_out_woLFE = nchan_out; + st_ivas->hDecoderConfig->nchan_out = nchan_out; + } + else + { + nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; + nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; + } + slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); + /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ + slots_to_render = min( hDirAC->num_slots - hDirAC->slots_rendered, nSamplesAsked / slot_size ); + *nSamplesRendered = slots_to_render * slot_size; + first_sf = hDirAC->subframes_rendered; + last_sf = first_sf; + while ( slots_to_render > 0 ) + { + slots_to_render -= hDirAC->subframe_nbslots[last_sf]; + last_sf++; + } +#ifdef DEBUGGING + assert( slots_to_render == 0 ); +#endif + for ( ch = 0; ch < nchan_out; ch++ ) + { + output_f_local[ch] = &output_f[ch][0]; + } + for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) + { + ivas_ism_param_dec_render_sf( st_ivas, hSetup, nchan_transport, nchan_out, nchan_out_woLFE, output_f_local ); + n_samples_sf = hDirAC->subframe_nbslots[subframe_idx] * st_ivas->hDirAC->slot_size; + for ( ch = 0; ch < nchan_out; ch++ ) + { + output_f_local[ch] += n_samples_sf; + } + } + if ( hDirAC->slots_rendered == hDirAC->num_slots ) + { + /* copy the memories */ + /* store mixing matrix for next subframe */ + ivas_param_ism_update_mixing_matrix( hDirAC, hDirAC->hParamIsmRendering->mixing_matrix_lin, nchan_transport, nchan_out_woLFE ); + + /* store MetaData parameters */ + for ( ch = 0; ch < st_ivas->nchan_ism; ch++ ) + { + if ( st_ivas->hDirAC->azimuth_values[ch] > 180.0f ) + { + st_ivas->hIsmMetaData[ch]->azimuth = st_ivas->hDirAC->azimuth_values[ch] - 360.0f; + } + else + { + st_ivas->hIsmMetaData[ch]->azimuth = st_ivas->hDirAC->azimuth_values[ch]; + } + + st_ivas->hIsmMetaData[ch]->elevation = st_ivas->hDirAC->elevation_values[ch]; + } + } + *nSamplesAvailable = ( hDirAC->num_slots - hDirAC->slots_rendered ) * slot_size; + return; +} + +#endif + /*-------------------------------------------------------------------------* * ivas_param_ism_params_to_masa_param_mapping() diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c index 1e60143cb4..3882f656b7 100644 --- a/lib_dec/ivas_ism_renderer.c +++ b/lib_dec/ivas_ism_renderer.c @@ -58,6 +58,9 @@ ivas_error ivas_ism_renderer_open( { int16_t i; uint16_t interpolator_length; +#ifdef JBM_TSM_ON_TCS + uint16_t init_interpolator_length; +#endif ivas_error error; error = IVAS_ERR_OK; @@ -78,14 +81,34 @@ ivas_error ivas_ism_renderer_open( for ( i = 0; i < MAX_NUM_OBJECTS; i++ ) { set_f( st_ivas->hIsmRendererData->prev_gains[i], 0.0f, MAX_OUTPUT_CHANNELS ); +#ifdef JBM_TSM_ON_TCS + set_f( st_ivas->hIsmRendererData->gains[i], 0.0f, MAX_OUTPUT_CHANNELS ); +#endif } +#ifdef JBM_TSM_ON_TCS + if ( st_ivas->hDecoderConfig->voip_active ) + { + init_interpolator_length = NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_CLDFB_TIMESLOTS * CLDFB_SLOT_NS ); + interpolator_length = (uint16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); + } + else + { + init_interpolator_length = (uint16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); + interpolator_length = init_interpolator_length; + } + st_ivas->hIsmRendererData->interpolator = (float *) malloc( sizeof( float ) * init_interpolator_length ); + for ( i = 0; i < interpolator_length; i++ ) + { + st_ivas->hIsmRendererData->interpolator[i] = (float) i / ( (float) interpolator_length - 1 ); + } +#else interpolator_length = (uint16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); for ( i = 0; i < interpolator_length; i++ ) { st_ivas->hIsmRendererData->interpolator[i] = (float) i / ( (float) interpolator_length - 1 ); } - +#endif return error; } @@ -97,9 +120,13 @@ ivas_error ivas_ism_renderer_open( *-------------------------------------------------------------------------*/ void ivas_ism_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ +#ifdef JBM_TSM_ON_TCS + float *output_f[], /* i/o: core-coder transport channels/object output */ +#else float output_f[][L_FRAME48k], /* i/o: core-coder transport channels/object output */ - const int16_t output_frame /* i : output frame length per channel */ +#endif + const int16_t output_frame /* i : output frame length per channel */ ) { int16_t i, j, k, j2; @@ -201,6 +228,87 @@ void ivas_ism_render( return; } +#ifdef JBM_TSM_ON_TCS +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 */ + const int16_t n_samples_to_render /* i : output frame length per channel */ +) +{ + int16_t i, j, k, j2; + float *g1, g2, *tc; + int16_t num_objects, nchan_out_woLFE, lfe_index; + int16_t azimuth, elevation; + int16_t tc_offset; + int16_t interp_offset; + float Rmat[3][3]; + float gain, prev_gain; + + num_objects = st_ivas->nchan_transport; + nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; + + tc_offset = st_ivas->hTcBuffer->n_samples_rendered; + interp_offset = st_ivas->hTcBuffer->n_samples_rendered; + + 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->hHeadTrackData != NULL && st_ivas->hHeadTrackData->num_quaternions >= 0 ) + { + /* Calculate rotation matrix from the quaternion */ + QuatToRotMat( st_ivas->hHeadTrackData->Quaternions[st_ivas->hHeadTrackData->num_quaternions++], Rmat ); + ivas_jbm_dec_get_adapted_linear_interpolator( n_samples_to_render, + n_samples_to_render, + st_ivas->hIsmRendererData->interpolator ); + interp_offset = 0; + } + + for ( i = 0; i < num_objects; i++ ) + { + + /* Head rotation: rotate the object positions depending the head's orientation */ + if ( st_ivas->hHeadTrackData != NULL && st_ivas->hHeadTrackData->num_quaternions >= 0 ) + { + rotateAziEle( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &azimuth, &elevation, Rmat, 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 ); + } + } + + lfe_index = 0; + 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++; + } + + gain = st_ivas->hIsmRendererData->gains[i][j]; + prev_gain = st_ivas->hIsmRendererData->prev_gains[i][j]; + 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]; + for ( k = 0; k < n_samples_to_render; k++ ) + { + g2 = 1.0f - *g1; + output_f[j2][k] += ( *( g1++ ) * gain + g2 * prev_gain ) * *( tc++ ); + } + } + /* update here only in case of head rotation */ + if ( st_ivas->hHeadTrackData != NULL && st_ivas->hHeadTrackData->num_quaternions >= 0 ) + { + st_ivas->hIsmRendererData->prev_gains[i][j] = gain; + } + } + } + return; +} +#endif + /*-------------------------------------------------------------------------* * ivas_ism_get_stereo_gains() diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c new file mode 100644 index 0000000000..b579c10c96 --- /dev/null +++ b/lib_dec/ivas_jbm_dec.c @@ -0,0 +1,1716 @@ +/****************************************************************************************************** + + (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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#include "cnst.h" +#include "ivas_cnst.h" +#include "rom_com.h" +#include "prot.h" +#include "ivas_prot.h" +#include "ivas_prot_rend.h" +#include "ivas_rom_com.h" +#include +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + + +#ifdef JBM_TSM_ON_TCS + +/*-----------------------------------------------------------------------* + * Local function prototypes + *-----------------------------------------------------------------------*/ +static void ivas_jbm_dec_copy_tc( Decoder_Struct *st_ivas, const int16_t nSamplesForRendering, int16_t *nSamplesResidual, float *data, float *tc_digest_f[] ); +static void ivas_jbm_dec_tc_buffer_playout( Decoder_Struct *st_ivas, const uint16_t nSamplesAsked, uint16_t *nSamplesRendered, float *output[] ); + + +/*--------------------------------------------------------------------------* + * ivas_jbm_dec_tc() + * + * Principal IVAS decoder routine, decoding of metadata and transport channels + *--------------------------------------------------------------------------*/ +ivas_error ivas_jbm_dec_tc( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *data /* o : transport channel signal */ +) +{ + int16_t n, output_frame, nchan_out; + Decoder_State *st; /* used for bitstream handling */ + float output[MAX_TRANSPORT_CHANNELS][L_FRAME48k]; /* 'float' buffer for transport channels, MAX_TRANSPORT_CHANNELS channels */ /* IVAS_fmToDo: buffer can be allocated dynamically based on the actual number of output channels */ + int16_t nchan_remapped; + float output_lfe_ch[L_FRAME48k]; + int16_t nb_bits_metadata[MAX_SCE]; + int32_t output_Fs, ivas_total_brate; + AUDIO_CONFIG output_config; + ivas_error error; + float *p_output[MAX_TRANSPORT_CHANNELS]; + + error = IVAS_ERR_OK; + + push_wmops( "ivas_jbm_dec_tc" ); + + /*----------------------------------------------------------------* + * Initialization of local vars after struct has been set + *----------------------------------------------------------------*/ + + output_Fs = st_ivas->hDecoderConfig->output_Fs; + nchan_out = st_ivas->hTcBuffer->nchan_transport_jbm; + 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_TRANSPORT_CHANNELS; n++ ) + { + p_output[n] = &output[n][0]; + } + + /*----------------------------------------------------------------* + * Decoding + Rendering + *----------------------------------------------------------------*/ + + if ( st_ivas->bfi && st_ivas->ini_frame == 0 ) + { + /* zero output when first frame(s) is lost */ + for ( n = 0; n < nchan_out; n++ ) + { + set_f( output[n], 0.0f, output_frame ); + } + +#ifdef DEBUG_MODE_INFO + create_sce_dec( st_ivas, 0, ivas_total_brate ); + output_debug_mode_info_dec( st_ivas->hSCE[0]->hCoreCoder, 1, output_frame, NULL ); + destroy_sce_dec( st_ivas->hSCE[0] ); + st_ivas->hSCE[0] = NULL; +#endif + } + 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, output, output_frame, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* HP filtering */ + for ( n = 0; n < min( nchan_out, st_ivas->nchan_transport ); n++ ) + { + hp20( output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); + } + if ( st_ivas->renderer_type == RENDERER_MC && st_ivas->hDecoderConfig->nchan_out == 1 ) + { + ivas_ls_setup_conversion( st_ivas, 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; + } + } + else if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { + // VE: call ivas_ism_metadata_dec() with 'st_ivas' - TBD + 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->hDirAC->hParamIsm, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt ) ) != 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 ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + for ( n = 0; n < st_ivas->nchan_transport; n++ ) + { + if ( ( error = ivas_sce_dec( st_ivas, n, &output[n], output_frame, nb_bits_metadata[n] ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* HP filtering */ + hp20( output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); + } + if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX ) + { + ivas_mono_downmix_render_passive( st_ivas, output, output_frame ); + } + } + else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) + { + set_s( nb_bits_metadata, 0, MAX_SCE ); + + /* read parameters from the bitstream */ + if ( st_ivas->hQMetaData != NULL && st_ivas->sba_mode != SBA_MODE_SPAR ) + { + st = ( st_ivas->nSCE > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; + + if ( st_ivas->ivas_format == SBA_FORMAT ) + { + ivas_dirac_dec_read_BS( ivas_total_brate, st, st_ivas->hDirAC, st_ivas->hQMetaData, &nb_bits_metadata[0], st_ivas->sba_mode, 0 ); + } + else + { + if ( ( error = ivas_masa_decode( st_ivas, st, &nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + else if ( st_ivas->sba_mode == SBA_MODE_SPAR ) + { + if ( st_ivas->hQMetaData != NULL ) + { + st = ( st_ivas->nSCE > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; + ivas_dirac_dec_read_BS( ivas_total_brate, st, st_ivas->hDirAC, st_ivas->hQMetaData, &nb_bits_metadata[0], st_ivas->sba_mode, st_ivas->hSpar->dirac_to_spar_md_bands ); + } + + 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, &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, 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, output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + +#ifdef DEBUG_SBA_AUDIO_DUMP + /* Dump audio signal after core-decoding */ + ivas_spar_dump_signal_wav( output_frame, NULL, output, st_ivas->nchan_transport, spar_foa_dec_wav[0], "core-decoding" ); +#endif + /* TCs remapping */ + nchan_remapped = st_ivas->nchan_transport; + if ( st_ivas->sba_dirac_stereo_flag ) + { + nchan_remapped = nchan_out; + + if ( st_ivas->sba_mode == SBA_MODE_SPAR ) + { + ivas_agc_dec_process( st_ivas->hSpar->hAgcDec, output, 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, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, output ); + } + + ivas_spar_dec_gen_umx_mat( st_ivas->hSpar->hMdDec, st_ivas->nchan_transport, IVAS_MAX_NUM_BANDS, st_ivas->bfi ); + } + + ivas_sba_dirac_stereo_dec( st_ivas, 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 */ +#ifndef DEBUG_SPAR_BYPASS_EVS_CODEC + for ( n = 0; n < nchan_remapped; n++ ) + { + hp20( output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); + } +#endif + if ( st_ivas->ivas_format == SBA_FORMAT ) + { + nchan_remapped = ivas_sba_remapTCs( output, st_ivas, output_frame ); + + if ( st_ivas->sba_mode == SBA_MODE_SPAR && ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) + { + ivas_sba_mix_matrix_determiner( st_ivas->hSpar, output, st_ivas->bfi, nchan_remapped, output_frame ); + } + else if ( st_ivas->sba_mode == SBA_MODE_SPAR ) + { + ivas_spar_dec_agc_pca( st_ivas, output, output_frame ); + } + } + + if ( st_ivas->ivas_format == MASA_FORMAT ) + { + ivas_masa_prerender( st_ivas, output, output_frame ); + } + else if ( st_ivas->ivas_format == SBA_FORMAT && ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) + { + float gain = 0.8414f; /* Todo: Temporary gain for roughly matching the loudness. To be tuned later together with other outputs. */ + + for ( n = 0; n < nchan_remapped; n++ ) + { + v_multc( output[n], gain, 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]; + + /* LFE channel decoder */ + if ( st_ivas->mc_mode == MC_MODE_MCT ) + { + if ( st_ivas->hCPE[1]->hCoreCoder[1]->hTcxCfg == NULL ) + { + st_ivas->hCPE[1]->hCoreCoder[1]->hTcxCfg = st_ivas->hCPE[1]->hCoreCoder[0]->hTcxCfg; + } + ivas_lfe_dec( st_ivas->hLFE, st, output_frame, st_ivas->bfi, output_lfe_ch ); + } + + if ( st_ivas->mc_mode == MC_MODE_MCT ) + { + if ( ( error = ivas_mct_dec( st_ivas, output, output_frame, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + mvr2r( output_lfe_ch, output[LFE_CHANNEL], output_frame ); + + /* HP filtering */ + for ( n = 0; n < st_ivas->nchan_transport; n++ ) + { + if ( n != LFE_CHANNEL ) + { + hp20( 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 == AUDIO_CONFIG_FOA || st_ivas->intern_config == AUDIO_CONFIG_HOA2 || st_ivas->intern_config == AUDIO_CONFIG_HOA3 ) ) + { + if ( ( st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe ) <= ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ) ) + { + ivas_mc2sba( st_ivas->hTransSetup, p_output, p_output, output_frame, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE ); + } + } + if ( ( st_ivas->renderer_type == RENDERER_MC || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) && ( st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe ) >= ( st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ) ) + { + if ( st_ivas->renderer_type == RENDERER_MC ) + { + ivas_ls_setup_conversion( st_ivas, output_frame, p_output, p_output ); + } + else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) + { + ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, output_frame, st_ivas->hOutSetup.ambisonics_order, 0.f ); + } + } + } + else if ( st_ivas->mc_mode == MC_MODE_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, 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, output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* HP filtering */ + for ( n = 0; n < st_ivas->nchan_transport; n++ ) + { + hp20( output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); + } + + /* Rendering */ + if ( output_config == AUDIO_CONFIG_MONO || output_config == AUDIO_CONFIG_STEREO ) + { + ivas_ls_setup_conversion( st_ivas, output_frame, p_output, p_output ); + } + } + else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) + { + if ( st_ivas->hOutSetup.separateChannelEnabled ) + { + st = st_ivas->hCPE[0]->hCoreCoder[0]; /* Metadata is always with CPE in the case of separated channel */ + } + + /* read McMASA parameters from the bitstream */ + if ( ( error = ivas_masa_decode( st_ivas, st, &nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( st_ivas->hOutSetup.separateChannelEnabled ) + { + /* Decode the transport audio signals */ + if ( ( error = ivas_cpe_dec( st_ivas, 0, output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Identify the index of the separated channel, always LFE_CHANNEL-1 here */ + n = LFE_CHANNEL - 1; + + /* Decode the separated channel to output[n] to be combined with the synthesized channels */ + if ( ( error = ivas_sce_dec( st_ivas, 0, &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 == AUDIO_CONFIG_5_1 || output_config == AUDIO_CONFIG_7_1 || + output_config == AUDIO_CONFIG_5_1_4 || output_config == AUDIO_CONFIG_7_1_4 || + output_config == AUDIO_CONFIG_5_1_2 || ( output_config == AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe > 0 ) ) + { + ivas_lfe_synth_with_filters( st_ivas->hMasa->hMasaLfeSynth, output, output_frame, n, LFE_CHANNEL ); + } + else if ( output_config == AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe == 0 ) + { + /* Delay the separated channel to sync with the DirAC rendering */ + delay_signal( 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, 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, 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, output, output_frame, 1 ); + } + + /* HP filtering */ + for ( n = 0; n < getNumChanSynthesis( st_ivas ); n++ ) + { + hp20( output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); + } + + if ( st_ivas->renderer_type == RENDERER_MCMASA_MONO_STEREO ) + { + ivas_mono_stereo_downmix_mcmasa( st_ivas, output, output_frame ); + } + } + } + + + /*----------------------------------------------------------------* + * Write IVAS transport channels + *----------------------------------------------------------------*/ + + ivas_syn_output_f( p_output, output_frame, st_ivas->hTcBuffer->nchan_transport_jbm, 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; +#ifdef SBA_BR_SWITCHING + st_ivas->last_active_ivas_total_brate = ( ivas_total_brate <= IVAS_SID_5k2 ) ? st_ivas->last_active_ivas_total_brate : ivas_total_brate; +#endif + } + + 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++; + } + +#ifdef DEBUG_MODE_INFO + dbgwrite( &st_ivas->bfi, sizeof( int16_t ), 1, output_frame, "res/bfi" ); + dbgwrite( &st_ivas->BER_detect, sizeof( int16_t ), 1, output_frame, "res/BER_detect" ); + { + float tmpF = ivas_total_brate / 1000.0f; + dbgwrite( &tmpF, sizeof( float ), 1, output_frame, "res/ivas_total_brate.dec" ); + } +#endif + + pop_wmops(); + return error; +} + +/*--------------------------------------------------------------------------* + * ivas_jbm_dec_feed_tc_to_renderer() + * + * Feed decoded transport channels and metadata to the IVAS renderer routine + *--------------------------------------------------------------------------*/ + +ivas_error ivas_jbm_dec_feed_tc_to_renderer( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const int16_t nSamplesForRendering, /* i: : number of TC samples available for rendering */ + int16_t *nSamplesResidual, /* o: : number of samples not fitting into the renderer grid and buffer for the next call*/ + float *data /* i : transport channels */ +) +{ + + float data_f[MAX_CLDFB_DIGEST_CHANNELS][MAX_JBM_L_FRAME48k]; /* 'float' buffer for transport channels that will be directly converted with the CLDFB */ + float *p_data_f[MAX_CLDFB_DIGEST_CHANNELS]; + int16_t nCldfbTs; + int16_t n; + int16_t nchan_transport; + int32_t ivas_total_brate; + int32_t output_Fs; + ivas_error error; + AUDIO_CONFIG output_config; + + error = IVAS_ERR_OK; + + push_wmops( "ivas_jbm_dec_feed_tc_to_rendererer" ); + output_Fs = st_ivas->hDecoderConfig->output_Fs; + output_config = st_ivas->hDecoderConfig->output_config; + nchan_transport = st_ivas->hTcBuffer->nchan_transport_jbm; + ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; + + for ( n = 0; n < MAX_CLDFB_DIGEST_CHANNELS; n++ ) + { + p_data_f[n] = &data_f[n][0]; + } + ivas_jbm_dec_copy_tc( st_ivas, nSamplesForRendering, nSamplesResidual, data, p_data_f ); + nCldfbTs = st_ivas->hTcBuffer->n_samples_available / st_ivas->hTcBuffer->n_samples_granularity; + + if ( st_ivas->hTcBuffer->tc_buffer_mode == TC_BUFFER_MODE_BUFFER ) + { + ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); + } + else if ( st_ivas->ivas_format == STEREO_FORMAT ) + { + ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); + } + else if ( st_ivas->ivas_format == ISM_FORMAT ) + { + /* Rendering */ + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + ivas_dirac_dec_set_md_map( st_ivas, nCldfbTs ); + ivas_param_ism_params_to_masa_param_mapping( st_ivas ); + } + else if ( st_ivas->renderer_type == RENDERER_PARAM_ISM || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) + { + ivas_param_ism_dec_digest_tc( st_ivas, nCldfbTs, p_data_f ); + } + } + else /* ISM_MODE_DISC */ + { + ivas_ism_dec_digest_tc( st_ivas ); + } + } + else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) + { + ivas_sba_dec_digest_tc( st_ivas, nCldfbTs, st_ivas->hTcBuffer->n_samples_available ); + } + else if ( st_ivas->ivas_format == MC_FORMAT ) + { + if ( st_ivas->mc_mode == MC_MODE_MCT ) + { + ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); + } + else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) + { + ivas_param_mc_dec_digest_tc( st_ivas, (uint8_t) nCldfbTs, p_data_f ); + } + else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) + { + ivas_sba_dec_digest_tc( st_ivas, nCldfbTs, st_ivas->hTcBuffer->n_samples_available ); + } + } + + pop_wmops(); + + return error; +} + + +/*--------------------------------------------------------------------------* + * ivas_dec_render() + * + * Principal IVAS rendering routine + *--------------------------------------------------------------------------*/ +ivas_error ivas_jbm_dec_render( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const uint16_t nSamplesAsked, /* i : number of samples wanted */ + uint16_t *nSamplesRendered, /* o : number of samples rendered */ + uint16_t *nSamplesAvailableNext, /* o : number of samples still available in the rendering pipeline */ + int16_t *data /* o : output synthesis signal */ +) +{ + + int16_t n, nchan_out; + int16_t nchan_transport; + float output[MAX_OUTPUT_CHANNELS][L_FRAME48k]; /* 'float' buffer for output synthesis, MAX_OUTPUT_CHANNELS channels */ /* IVAS_fmToDo: buffer can be allocated dynamically based on the actual number of output channels */ + int16_t nchan_remapped; + int32_t output_Fs, ivas_total_brate; + AUDIO_CONFIG output_config; + int16_t nCldfbTs; + int16_t nSamplesAskedLocal; + ivas_error error; + float *p_output[MAX_OUTPUT_CHANNELS]; + float *p_tc[MAX_TRANSPORT_CHANNELS]; + + error = IVAS_ERR_OK; + + push_wmops( "ivas_dec_render" ); + + /*----------------------------------------------------------------* + * Initialization of local vars after struct has been set + *----------------------------------------------------------------*/ + + output_Fs = st_ivas->hDecoderConfig->output_Fs; + nchan_out = st_ivas->hDecoderConfig->nchan_out; + nchan_transport = st_ivas->hTcBuffer->nchan_transport_jbm; + output_config = st_ivas->hDecoderConfig->output_config; + ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; + nSamplesAskedLocal = nSamplesAsked + st_ivas->hTcBuffer->n_samples_discard; + nCldfbTs = nSamplesAskedLocal / NS2SA( output_Fs, CLDFB_SLOT_NS ); + for ( n = 0; n < MAX_OUTPUT_CHANNELS; n++ ) + { + p_output[n] = &output[n][0]; + } + + for ( n = 0; n < st_ivas->hTcBuffer->nchan_transport_internal; n++ ) + { + p_tc[n] = &st_ivas->hTcBuffer->tc[n][st_ivas->hTcBuffer->n_samples_rendered]; + } + + /*----------------------------------------------------------------* + * Rendering + *----------------------------------------------------------------*/ + + if ( st_ivas->ivas_format == UNDEFINED_FORMAT ) + { + assert( 0 ); + } + else if ( st_ivas->hTcBuffer->tc_buffer_mode == TC_BUFFER_MODE_BUFFER ) + { + ivas_jbm_dec_tc_buffer_playout( st_ivas, nSamplesAskedLocal, nSamplesRendered, p_output ); + } + else if ( st_ivas->ivas_format == STEREO_FORMAT ) + { + /* Rendering */ + if ( st_ivas->renderer_type == RENDERER_MC ) + { + *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); + ivas_ls_setup_conversion( st_ivas, *nSamplesRendered, p_tc, p_output ); + } + } + else if ( st_ivas->ivas_format == ISM_FORMAT ) + { + /* Rendering */ + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, st_ivas->nchan_transport, p_output ); + } + else if ( st_ivas->renderer_type == RENDERER_PARAM_ISM || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) + { + ivas_param_ism_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); + + if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) + { + /* Convert CICP19 -> Ambisonics */ + ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f ); + } + } + } + else /* ISM_MODE_DISC */ + { + *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); + /* Loudspeaker or Ambisonics rendering */ + if ( st_ivas->renderer_type == RENDERER_TD_PANNING || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) + { + /* Convert to CICPxx; used also for ISM->CICP19->binaural_room rendering */ + ivas_ism_render_sf( st_ivas, p_output, *nSamplesRendered ); + } + else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) + { + /* Convert to Ambisonics; used also for ISM->HOA3->binaural rendering */ + ivas_ism2sba_sf( st_ivas->hTcBuffer->tc, p_output, st_ivas->hIsmRendererData, st_ivas->nchan_transport, *nSamplesRendered, st_ivas->hTcBuffer->n_samples_rendered, st_ivas->hIntSetup.ambisonics_order ); + } + + /* Binaural rendering */ + if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) + { + ObjRenderIVASSubframe( st_ivas, p_output, *nSamplesRendered ); + } + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) + { + if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, + AUDIO_CONFIG_7_1_4, + AUDIO_CONFIG_BINAURAL_ROOM, + st_ivas->hDecoderConfig, + NULL, + NULL, + NULL, + st_ivas->hTcBuffer, + p_output, + p_output, + *nSamplesRendered, + output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_output, p_output ); + } +#ifdef DEBUGGING + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + { + ivas_binaural_cldfb_sf( st_ivas, *nSamplesRendered, p_output ); + } +#endif + } + } + else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) + { + nchan_remapped = nchan_transport; + /* Loudspeakers, Ambisonics or Binaural rendering */ + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output ); + } + else if ( st_ivas->sba_mode == SBA_MODE_DIRAC || st_ivas->ivas_format == MASA_FORMAT ) + { + if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC ) + { + *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); + for ( n = 0; n < nchan_remapped; n++ ) + { + mvr2r( st_ivas->hTcBuffer->tc[n] + st_ivas->hTcBuffer->n_samples_rendered, p_output[n], *nSamplesRendered ); + } + ivas_sba_linear_renderer( p_output, *nSamplesRendered, nchan_remapped, output_config, st_ivas->hOutSetup, st_ivas->hoa_dec_mtx ); + } + else if ( st_ivas->renderer_type == RENDERER_DIRAC ) + { + ivas_dirac_dec_render( st_ivas, nchan_remapped, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); + } + } + else /* SBA_MODE_SPAR */ + { + ivas_sba_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); + } + } + else if ( st_ivas->ivas_format == MC_FORMAT ) + { + if ( st_ivas->mc_mode == MC_MODE_MCT ) + { + *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); + if ( st_ivas->transport_config != st_ivas->intern_config && ( st_ivas->intern_config == AUDIO_CONFIG_FOA || st_ivas->intern_config == AUDIO_CONFIG_HOA2 || st_ivas->intern_config == AUDIO_CONFIG_HOA3 ) ) + { + ivas_mc2sba( st_ivas->hTransSetup, p_tc, p_output, *nSamplesRendered, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE ); + } + + /* Rendering */ + if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) + { + if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, + st_ivas->intern_config, + st_ivas->hOutSetup.output_config, + st_ivas->hDecoderConfig, + st_ivas->hHeadTrackData, + &st_ivas->hIntSetup, + st_ivas->hEFAPdata, + st_ivas->hTcBuffer, + p_tc, + p_output, + *nSamplesRendered, + output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, st_ivas->hTcBuffer->tc, p_output ); + } + else if ( st_ivas->renderer_type == RENDERER_MC ) + { + *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); + ivas_ls_setup_conversion( st_ivas, *nSamplesRendered, p_tc, p_output ); + } + else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) + { + ivas_mc2sba( st_ivas->hIntSetup, p_tc, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f ); + } + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) + { + ObjRenderIVASSubframe( st_ivas, p_output, *nSamplesRendered ); + ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, st_ivas->hTcBuffer->tc, p_output ); + } + } + else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) + { + ivas_param_mc_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); + } + else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) + { + + /* Rendering */ + int16_t offset = st_ivas->hDirAC->slots_rendered * st_ivas->hDirAC->slot_size; + nchan_remapped = st_ivas->nchan_transport; + + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output ); + } + else if ( st_ivas->renderer_type == RENDERER_DIRAC || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) /* rendering to CICPxx and Ambisonics */ + { + ivas_dirac_dec_render( st_ivas, nchan_remapped, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); + + + if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) + { + /* we still need to copy the separate channel if available */ + if ( st_ivas->hOutSetup.separateChannelEnabled ) + { + mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, 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 == AUDIO_CONFIG_5_1 && ( output_config == AUDIO_CONFIG_5_1_2 || output_config == AUDIO_CONFIG_5_1_4 || output_config == 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 ); + } + } + } + /* copy discrete C and TD LFE from internal TC to output */ + if ( st_ivas->hOutSetup.separateChannelEnabled ) + { + if ( output_config == AUDIO_CONFIG_5_1 || output_config == AUDIO_CONFIG_7_1 || + output_config == AUDIO_CONFIG_5_1_4 || output_config == AUDIO_CONFIG_7_1_4 || + output_config == AUDIO_CONFIG_5_1_2 || ( output_config == 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 ); + } + else if ( output_config == 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 ); + } + } + } + } + + /*----------------------------------------------------------------* + * Write IVAS output channels + * - compensation for saturation + * - float to integer conversion + *----------------------------------------------------------------*/ + st_ivas->hTcBuffer->n_samples_available -= *nSamplesRendered; + st_ivas->hTcBuffer->n_samples_rendered += *nSamplesRendered; + if ( st_ivas->hTcBuffer->n_samples_discard > 0 ) + { + for ( n = 0; n < MAX_OUTPUT_CHANNELS; n++ ) + { + p_output[n] += st_ivas->hTcBuffer->n_samples_discard; + } + *nSamplesRendered -= st_ivas->hTcBuffer->n_samples_discard; + st_ivas->hTcBuffer->n_samples_discard = 0; + } + + ivas_limiter_dec( st_ivas->hLimiter, p_output, nchan_out, *nSamplesRendered, st_ivas->BER_detect ); + +#ifdef DEBUGGING + st_ivas->noClipping += +#endif + ivas_syn_output( p_output, *nSamplesRendered, nchan_out, data ); + + *nSamplesAvailableNext = st_ivas->hTcBuffer->n_samples_available; + + pop_wmops(); + return error; +} + + +/*--------------------------------------------------------------------------* + * ivas_jbm_dec_dec_flush_renderer() + * + * Flush samples if renderer granularity changes on a bitrate change + *--------------------------------------------------------------------------*/ +ivas_error ivas_jbm_dec_flush_renderer( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const int16_t tc_granularity_new, /* i : new renderer granularity */ + const RENDERER_TYPE renderer_type_old, /* i : old renderer type */ + const AUDIO_CONFIG intern_config_old, /* i : old internal config */ + const IVAS_OUTPUT_SETUP_HANDLE hIntSetupOld, /* i : old internal output setup */ + const MC_MODE mc_mode_old, /* i : old MC mode */ + const ISM_MODE ism_mode_old, /* i : old ISM mode */ + uint16_t *nSamplesRendered, /* o : number of samples flushed */ + int16_t *data /* o : rendered samples */ +) +{ + ivas_error error; + int16_t n_samples_still_available; + int16_t n_slots_still_available; + int16_t n_samples_to_render; + DECODER_TC_BUFFER_HANDLE hTcBuffer; + float output[MAX_CICP_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; + float *p_output[MAX_CICP_CHANNELS]; + + error = IVAS_ERR_OK; + + *nSamplesRendered = 0; + hTcBuffer = st_ivas->hTcBuffer; + /* get number of possible slots in new granularity */ + n_samples_still_available = hTcBuffer->n_samples_buffered - hTcBuffer->n_samples_rendered; + n_slots_still_available = n_samples_still_available / tc_granularity_new; + *nSamplesRendered = n_slots_still_available * tc_granularity_new; + n_samples_to_render = *nSamplesRendered; + n_samples_still_available -= n_samples_to_render; + assert( n_samples_still_available < tc_granularity_new ); + if ( n_slots_still_available ) + { + int ch_idx; + /* render what is still there with zero padding */ + for ( ch_idx = 0; ch_idx < hTcBuffer->nchan_buffer_full; ch_idx++ ) + { + /* move it at the beginning of the TC buffer with zero padding */ + mvr2r( hTcBuffer->tc[ch_idx] + hTcBuffer->n_samples_rendered, hTcBuffer->tc[ch_idx], n_samples_to_render ); + set_zero( hTcBuffer->tc[ch_idx] + n_samples_to_render, hTcBuffer->n_samples_granularity - n_samples_to_render ); + mvr2r( hTcBuffer->tc[ch_idx] + hTcBuffer->n_samples_rendered + n_samples_to_render, hTcBuffer->tc[ch_idx] + hTcBuffer->n_samples_granularity, n_samples_still_available ); + } + /* simple change of the slot info */ + hTcBuffer->num_slots = 1; + hTcBuffer->nb_subframes = 1; + hTcBuffer->subframes_rendered = 0; + hTcBuffer->slots_rendered = 0; + hTcBuffer->subframe_nbslots[0] = 1; + hTcBuffer->n_samples_buffered = hTcBuffer->n_samples_granularity + n_samples_still_available; + hTcBuffer->n_samples_available = 0; + hTcBuffer->n_samples_flushed = n_samples_to_render; + hTcBuffer->n_samples_rendered = hTcBuffer->n_samples_granularity; + + for ( ch_idx = 0; ch_idx < MAX_CICP_CHANNELS; ch_idx++ ) + { + p_output[ch_idx] = output[ch_idx]; + } + + if ( st_ivas->ivas_format == ISM_FORMAT ) + { + if ( ism_mode_old == ISM_MODE_DISC ) + { + /* Binaural rendering */ + if ( renderer_type_old == RENDERER_BINAURAL_OBJECTS_TD ) + { + ObjRenderIVASSubframe( st_ivas, p_output, hTcBuffer->n_samples_granularity ); + } + else if ( renderer_type_old == RENDERER_BINAURAL_MIXER_CONV_ROOM ) + { + /* Convert to CICPxx; used also for ISM->CICP19->binaural_room rendering */ + set_f( st_ivas->hIsmRendererData->interpolator, 1.0f, hTcBuffer->n_samples_granularity ); + ivas_ism_render_sf( st_ivas, p_output, hTcBuffer->n_samples_granularity ); + if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, + AUDIO_CONFIG_7_1_4, + AUDIO_CONFIG_BINAURAL_ROOM, + 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 + { + return IVAS_ERROR( IVAS_ERR_WRONG_MODE, "Wrong ISM_MODE in VoIP renderer flushing!" ); + } + } + else if ( st_ivas->ivas_format == MC_FORMAT ) + { + if ( mc_mode_old == MC_MODE_MCT ) + { + if ( renderer_type_old == RENDERER_BINAURAL_MIXER_CONV || renderer_type_old == RENDERER_BINAURAL_MIXER_CONV_ROOM ) + { + if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, + intern_config_old, + st_ivas->hOutSetup.output_config, + st_ivas->hDecoderConfig, + st_ivas->hHeadTrackData, + hIntSetupOld, + st_ivas->hEFAPdata, + st_ivas->hTcBuffer, + hTcBuffer->tc, + 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, st_ivas->hTcBuffer->tc, p_output ); + } + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) + { + ObjRenderIVASSubframe( st_ivas, p_output, hTcBuffer->n_samples_granularity ); + ivas_binaural_add_LFE( st_ivas, hTcBuffer->n_samples_granularity, st_ivas->hTcBuffer->tc, p_output ); + } + } + else + { + return IVAS_ERROR( IVAS_ERR_WRONG_MODE, "Wrong MC_MODE in VoIP renderer flushing!" ); + } + } + else + { + return IVAS_ERROR( IVAS_ERR_WRONG_MODE, "Wrong IVAS format in VoIP renderer flushing!" ); + } + } + + /* Only write out the valid data*/ + ivas_limiter_dec( st_ivas->hLimiter, p_output, st_ivas->hDecoderConfig->nchan_out, *nSamplesRendered, st_ivas->BER_detect ); + +#ifdef DEBUGGING + st_ivas->noClipping += +#endif + ivas_syn_output( p_output, *nSamplesRendered, st_ivas->hDecoderConfig->nchan_out, data ); + + + return error; +} + +/*--------------------------------------------------------------------------* + * ivas_jbm_dec_set_discard_samples() + * + * Set number of samples to discard in the first subframe if the renderer granularity changes on a bitrate change + *--------------------------------------------------------------------------*/ +ivas_error ivas_jbm_dec_set_discard_samples( + Decoder_Struct *st_ivas /* i/o: main IVAS decoder structre */ +) +{ + int16_t nMaxSlotsPerSubframe, nSlotsInFirstSubframe; + ivas_error error; + + error = IVAS_ERR_OK; + + /* render first frame with front zero padding and discarding those samples */ + nMaxSlotsPerSubframe = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ) / st_ivas->hTcBuffer->n_samples_granularity; + nSlotsInFirstSubframe = nMaxSlotsPerSubframe - st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->nb_subframes - 1]; + if ( nSlotsInFirstSubframe > 0 ) + { + st_ivas->hTcBuffer->n_samples_discard = ( nMaxSlotsPerSubframe - nSlotsInFirstSubframe ) * st_ivas->hTcBuffer->n_samples_granularity; + /* set last subframes number to max to ensure correct continuation */ + st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->nb_subframes - 1] = nMaxSlotsPerSubframe; + } + return error; +} + +/*--------------------------------------------------------------------------* + * ivas_jbm_dec_get_adapted_linear_interpolator() + * + * Get an interpolator that is adapted to time scale modified IVAS frame + *--------------------------------------------------------------------------*/ + +void ivas_jbm_dec_get_adapted_linear_interpolator( + const int16_t default_interp_length, /* i : default length of the (full-frame) interpolator */ + const int16_t interp_length, /* i : length of the interpolator to be created */ + float *interpolator /* o : the interpolator */ +) +{ + int16_t jbm_segment_len, idx; + float dec; +#ifdef DEBUGGING + assert( default_interp_length % 2 == 0 ); +#endif + + jbm_segment_len = ( default_interp_length >> 1 ); + dec = 1.0f / default_interp_length; + + interpolator[interp_length - 1] = 1.0f; + for ( idx = interp_length - 2; idx >= jbm_segment_len; idx-- ) + { + interpolator[idx] = max( 0.0f, interpolator[idx + 1] - dec ); + } + if ( interpolator[idx + 1] > 0.0f ) + { + dec = interpolator[idx + 1] / ( jbm_segment_len + 1 ); + for ( ; idx >= 0; idx-- ) + { + interpolator[idx] = interpolator[idx + 1] - dec; + } + } + else + { + set_f( interpolator, 0.0f, idx + 1 ); + } +} + +/*--------------------------------------------------------------------------* + * ivas_jbm_dec_get_adapted_subframes() + * + * Get an interpolator that is adapted to time scale modified IVAS frame + *--------------------------------------------------------------------------*/ +void ivas_jbm_dec_get_adapted_subframes( + const int16_t nCldfbTs, /* i : number of time slots in the current frame */ + int16_t *subframe_nbslots, /* i/o: subframe grid */ + int16_t *nb_subframes /* i/o: number of subframes in the frame */ +) +{ + uint16_t nSlotsInLastSubframe, nSlotsInFirstSubframe; + uint16_t nCldfbSlotsLocal = nCldfbTs; + /* get last subframe size from previous frame, determine how many slots have to be processed + in the first subframe (i.e. potential leftover of a 5ms subframe) */ + nSlotsInFirstSubframe = ( PARAM_MC_MAX_NSLOTS_IN_SUBFRAME - subframe_nbslots[*nb_subframes - 1] ); + *nb_subframes = 0; + if ( nSlotsInFirstSubframe > 0 ) + { + *nb_subframes = 1; + nCldfbSlotsLocal -= nSlotsInFirstSubframe; + } + *nb_subframes += (int16_t) ceilf( (float) nCldfbSlotsLocal / (float) PARAM_MC_MAX_NSLOTS_IN_SUBFRAME ); + nSlotsInLastSubframe = nCldfbSlotsLocal % PARAM_MC_MAX_NSLOTS_IN_SUBFRAME; + set_s( subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS ); + set_s( subframe_nbslots, PARAM_MC_MAX_NSLOTS_IN_SUBFRAME, *nb_subframes ); + if ( nSlotsInFirstSubframe > 0 ) + { + subframe_nbslots[0] = nSlotsInFirstSubframe; + } + if ( nSlotsInLastSubframe > 0 ) + { + subframe_nbslots[*nb_subframes - 1] = nSlotsInLastSubframe; + } + return; +} + +/*--------------------------------------------------------------------------* + * ivas_jbm_dec_get_adapted_linear_interpolator() + * + * Get an meta data map adapted to a time scale modified IVAS frame + *--------------------------------------------------------------------------*/ +void ivas_jbm_dec_get_md_map( + const int16_t default_len, /* i : default frame length in metadata slots */ + const int16_t len, /* i : length of the modfied frames in metadata slots */ + const int16_t subframe_len, /* i : default length of a subframe */ + const int16_t offset, /* i : current read offset into the md buffer */ + const int16_t buf_len, /* i : length of the metadata buffer */ + int16_t *map /* o : metadata index map */ +) +{ + int16_t jbm_segment_len, map_idx, src_idx, src_idx_map; + float dec, src_idx_f; +#ifdef DEBUGGING + assert( default_len % 2 == 0 ); +#endif + + jbm_segment_len = ( default_len >> 1 ); + dec = 1.0f / default_len; + + + for ( map_idx = len - 1, src_idx = default_len - 1; map_idx >= jbm_segment_len; map_idx--, src_idx-- ) + { + src_idx_map = max( 0, src_idx / subframe_len ); + map[map_idx] = ( offset + src_idx_map ) % buf_len; + } + /* changed part (first segment), interpolate index to parameters + (we do not want to interpolate and smooth acutal direction/diffuseness values even more) */ + if ( src_idx >= 0 ) + { + dec = ( (float) ( src_idx + 1 ) ) / ( (float) jbm_segment_len ); + src_idx_f = (float) ( src_idx + 1 ) - dec; + for ( ; map_idx >= 0; map_idx-- ) + { + src_idx = max( 0, ( (int16_t) round_f( src_idx_f ) ) / subframe_len ); + map[map_idx] = ( offset + src_idx ) % buf_len; + src_idx_f -= dec; + } + } + else + { + set_s( map, offset, map_idx + 1 ); + } +} + +/*--------------------------------------------------------------------------* + * ivas_jbm_dec_get_num_tc_channels() + * + * Get the number of transport channels provided by the JBM transport channel decode function + *--------------------------------------------------------------------------*/ +int16_t ivas_jbm_dec_get_num_tc_channels( Decoder_Struct *st_ivas ) /* i : IVAS decoder handle */ +{ + int16_t num_tc; + int32_t ivas_total_brate; + AUDIO_CONFIG output_config; + + if ( st_ivas->renderer_type == RENDERER_DISABLE ) + { + num_tc = st_ivas->hDecoderConfig->nchan_out; + } + else + { + num_tc = st_ivas->nchan_transport; + } + output_config = st_ivas->hDecoderConfig->output_config; + + ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; + if ( st_ivas->ivas_format == STEREO_FORMAT && st_ivas->hDecoderConfig->nchan_out == 1 ) + { + num_tc = 1; + } + else if ( st_ivas->ivas_format == ISM_FORMAT ) + { + if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX ) + { + num_tc = 1; + } + } + else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) + { + if ( st_ivas->sba_dirac_stereo_flag ) + { + num_tc = CPE_CHANNELS; + } + else if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && ( ivas_total_brate > IVAS_SID_5k2 || ( ivas_total_brate <= IVAS_SID_5k2 && st_ivas->nCPE > 0 && st_ivas->hCPE[0]->nchan_out == 1 ) ) ) + { + num_tc = 1; /* Only one channel transported */ + } + + if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_EXTERNAL && st_ivas->nchan_transport == 2 && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_SID_5k2 ) + { + num_tc = CPE_CHANNELS; + } + if ( st_ivas->ivas_format == SBA_FORMAT ) + { + if ( ( st_ivas->sba_mode != SBA_MODE_SPAR && st_ivas->sba_planar && num_tc >= 3 ) || + ( ( st_ivas->sba_mode == SBA_MODE_SPAR ) && num_tc == 3 ) ) + { + num_tc++; + } + } + } + else if ( st_ivas->ivas_format == MC_FORMAT ) + { + if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_MONO ) + { + num_tc = 1; + } + else if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO ) + { + num_tc = 2; + } + else if ( st_ivas->mc_mode == MC_MODE_MCT ) + { + /* do all static dmx already in the TC decoder if less channels than transported... */ + if ( st_ivas->transport_config != st_ivas->intern_config && ( st_ivas->intern_config == AUDIO_CONFIG_FOA || st_ivas->intern_config == AUDIO_CONFIG_HOA2 || st_ivas->intern_config == AUDIO_CONFIG_HOA3 ) ) + { + if ( ( st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe ) > ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ) ) + { + num_tc = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; + } + } + else if ( ( st_ivas->renderer_type == RENDERER_MC || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) && ( st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe ) >= ( st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ) ) + { + num_tc = st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; + } + } + else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) + { + if ( st_ivas->hOutSetup.separateChannelEnabled ) + { + num_tc++; + } + if ( st_ivas->hOutSetup.separateChannelEnabled && ( output_config == AUDIO_CONFIG_5_1 || output_config == AUDIO_CONFIG_7_1 || + output_config == AUDIO_CONFIG_5_1_4 || output_config == AUDIO_CONFIG_7_1_4 || + output_config == AUDIO_CONFIG_5_1_2 || ( output_config == AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe > 0 ) ) ) + { + /* LFE is synthesized in TD with the TCs*/ + num_tc++; + } + } + } + + return num_tc; +} + +/*--------------------------------------------------------------------------* + * ivas_jbm_dec_copy_tc() + * + * Copy interleaved transport chnannels to the correct buffers, update the TC + * buffer handle + *--------------------------------------------------------------------------*/ +void ivas_jbm_dec_copy_tc( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const int16_t nSamplesForRendering, /* i : number of samples to digest */ + int16_t *nSamplesResidual, /* o : number of samples that will be left for the next frame */ + float *data, /* i : (interleaved) transport channel samples */ + float *tc_digest_f[] /* o : samples that will be directly digestest (eg. by CLDFB) */ +) +{ + int16_t ch; + DECODER_TC_BUFFER_HANDLE hTcBuffer; + int16_t n_samples_still_available, m; + int16_t n_ch_full_copy; + int16_t n_ch_res_copy; + + + hTcBuffer = st_ivas->hTcBuffer; + n_samples_still_available = hTcBuffer->n_samples_buffered - hTcBuffer->n_samples_rendered; + hTcBuffer->n_samples_buffered = n_samples_still_available + nSamplesForRendering + hTcBuffer->n_samples_discard; + hTcBuffer->n_samples_available = hTcBuffer->n_samples_granularity * ( hTcBuffer->n_samples_buffered / hTcBuffer->n_samples_granularity ); + *nSamplesResidual = hTcBuffer->n_samples_buffered - hTcBuffer->n_samples_available; + n_ch_full_copy = min( hTcBuffer->nchan_transport_jbm, hTcBuffer->nchan_buffer_full ); + n_ch_res_copy = hTcBuffer->nchan_transport_jbm - hTcBuffer->nchan_buffer_full; + + for ( ch = 0; ch < n_ch_full_copy; ch++ ) + { + set_zero( hTcBuffer->tc[ch], hTcBuffer->n_samples_discard ); + mvr2r( hTcBuffer->tc[ch] + hTcBuffer->n_samples_rendered, hTcBuffer->tc[ch] + hTcBuffer->n_samples_discard, n_samples_still_available ); + for ( m = 0; m < nSamplesForRendering; m++ ) + { + hTcBuffer->tc[ch][n_samples_still_available + hTcBuffer->n_samples_discard + m] = data[m * st_ivas->hTcBuffer->nchan_transport_jbm + ch]; + } + } + if ( n_ch_res_copy > 0 ) + { + for ( ; ch < hTcBuffer->nchan_transport_jbm; ch++ ) + { + mvr2r( hTcBuffer->tc[ch], tc_digest_f[ch], n_samples_still_available ); + for ( m = 0; m < nSamplesForRendering; m++ ) + { + tc_digest_f[ch][n_samples_still_available + m] = data[m * st_ivas->hTcBuffer->nchan_transport_jbm + ch]; + } + mvr2r( tc_digest_f[ch] + hTcBuffer->n_samples_available, hTcBuffer->tc[ch], *nSamplesResidual ); + } + } + hTcBuffer->n_samples_rendered = 0; + return; +} + + +int16_t ivas_jbm_dec_get_render_granularity( const RENDERER_TYPE rendererType, + const int32_t output_Fs ) +{ + int16_t render_granularity; + + if ( rendererType == RENDERER_BINAURAL_OBJECTS_TD || rendererType == RENDERER_BINAURAL_MIXER_CONV || rendererType == RENDERER_BINAURAL_MIXER_CONV_ROOM ) + { + render_granularity = NS2SA( output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); + } + else + { + render_granularity = NS2SA( output_Fs, CLDFB_SLOT_NS ); + } + + return render_granularity; +} + +/*--------------------------------------------------------------------------* + * ivas_jbm_dec_tc_buffer_open() + * + * open and initialize the transport channel buffer + *--------------------------------------------------------------------------*/ +ivas_error ivas_jbm_dec_tc_buffer_open( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const TC_BUFFER_MODE tc_buffer_mode, /* i : buffer mode */ + const int16_t nchan_transport_jbm, /* i : number of real transport channels */ + const int16_t nchan_transport_internal, /* i : number of totally buffered channels */ + const int16_t nchan_full, /* i : nubmer of channels to fully store */ + const int16_t n_samples_granularity /* i : granularity of the renderer/buffer */ +) +{ + int16_t nsamp_to_allocate; + DECODER_TC_BUFFER_HANDLE hTcBuffer; + ivas_error error; + int16_t nMaxSlotsPerSubframe; + int16_t nchan_residual; + int16_t ch_idx; + + error = IVAS_ERR_OK; + + /*-----------------------------------------------------------------* + * prepare library opening + *-----------------------------------------------------------------*/ + + if ( ( hTcBuffer = (DECODER_TC_BUFFER_HANDLE) malloc( sizeof( DECODER_TC_BUFFER ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TC Buffer\n" ) ); + } + hTcBuffer->tc_buffer_mode = tc_buffer_mode; + hTcBuffer->nchan_transport_jbm = nchan_transport_jbm; + hTcBuffer->nchan_transport_internal = nchan_transport_internal; + hTcBuffer->nchan_buffer_full = nchan_full; + nchan_residual = nchan_transport_internal - nchan_full; + hTcBuffer->n_samples_granularity = n_samples_granularity; + hTcBuffer->n_samples_available = 0; + hTcBuffer->n_samples_buffered = 0; + hTcBuffer->n_samples_rendered = 0; + hTcBuffer->slots_rendered = 0; + hTcBuffer->subframes_rendered = 0; + hTcBuffer->n_samples_discard = 0; + hTcBuffer->n_samples_flushed = 0; + hTcBuffer->nb_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; + nsamp_to_allocate = 0; + nMaxSlotsPerSubframe = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ) / hTcBuffer->n_samples_granularity; + hTcBuffer->num_slots = nMaxSlotsPerSubframe * MAX_PARAM_SPATIAL_SUBFRAMES; + set_s( hTcBuffer->subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS ); + set_s( hTcBuffer->subframe_nbslots, nMaxSlotsPerSubframe, MAX_PARAM_SPATIAL_SUBFRAMES ); + + if ( hTcBuffer->tc_buffer_mode == TC_BUFFER_MODE_NONE ) + { + hTcBuffer->tc_buffer = NULL; + for ( ch_idx = 0; ch_idx < MAX_TRANSPORT_CHANNELS; ch_idx++ ) + { + hTcBuffer->tc[ch_idx] = NULL; + } + } + else + { + int16_t n_samp_full = ( NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) + hTcBuffer->n_samples_granularity - 1 ); + int16_t n_samp_residual = hTcBuffer->n_samples_granularity - 1; + int32_t offset; + nsamp_to_allocate = hTcBuffer->nchan_buffer_full * n_samp_full; + nsamp_to_allocate += nchan_residual * n_samp_residual; + hTcBuffer->tc_buffer = (float *) malloc( nsamp_to_allocate * sizeof( float ) ); + 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; + } + for ( ; ch_idx < MAX_TRANSPORT_CHANNELS; ch_idx++ ) + { + hTcBuffer->tc[ch_idx] = NULL; + } + } + + st_ivas->hTcBuffer = hTcBuffer; + return error; +} + +/*--------------------------------------------------------------------------* + * ivas_jbm_dec_tc_buffer_reconfigure() + * + * open and initialize the transport channel buffer + *--------------------------------------------------------------------------*/ +ivas_error ivas_jbm_dec_tc_buffer_reconfigure( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const TC_BUFFER_MODE tc_buffer_mode, /* i : new buffer mode */ + const int16_t nchan_transport_jbm, /* i : new number of real transport channels */ + const int16_t nchan_transport_internal, /* i : new number of totally buffered channels */ + const int16_t nchan_full, /* i : new number of channels to fully store */ + const int16_t n_samples_granularity /* i : new granularity of the renderer/buffer */ +) +{ + ivas_error error; + int16_t nsamp_to_allocate, n_samp_full, n_samp_residual, offset, nchan_residual; + int16_t ch_idx; + DECODER_TC_BUFFER_HANDLE hTcBuffer; + + error = IVAS_ERR_OK; + + hTcBuffer = st_ivas->hTcBuffer; + + /* if granularity changes, adapt subframe_nb_slots */ + if ( n_samples_granularity != hTcBuffer->n_samples_granularity ) + { +#ifdef DEBUGGING + int16_t nMaxSlotsPerSubframeOld; +#endif + int16_t nMaxSlotsPerSubframeNew; + + nMaxSlotsPerSubframeNew = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ) / n_samples_granularity; +#ifdef DEBUGGING + nMaxSlotsPerSubframeOld = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ) / st_ivas->hTcBuffer->n_samples_granularity; + assert( hTcBuffer->subframe_nbslots[hTcBuffer->subframes_rendered - 1] == nMaxSlotsPerSubframeOld ); + if ( n_samples_granularity < hTcBuffer->n_samples_granularity ) + { + assert( ( hTcBuffer->n_samples_granularity % n_samples_granularity ) == 0 ); + } + else + { + assert( ( n_samples_granularity % hTcBuffer->n_samples_granularity ) == 0 ); + } +#endif + /* if samples were flushed, take that into account here */ + if ( n_samples_granularity < hTcBuffer->n_samples_granularity && hTcBuffer->n_samples_flushed > 0 ) + { + hTcBuffer->subframe_nbslots[hTcBuffer->subframes_rendered - 1] = hTcBuffer->n_samples_flushed / n_samples_granularity; + hTcBuffer->n_samples_flushed = 0; + } + else + { + hTcBuffer->subframe_nbslots[hTcBuffer->subframes_rendered - 1] = nMaxSlotsPerSubframeNew; + } + } + + hTcBuffer->tc_buffer_mode = tc_buffer_mode; + hTcBuffer->nchan_transport_jbm = nchan_transport_jbm; + hTcBuffer->nchan_transport_internal = nchan_transport_internal; + hTcBuffer->nchan_buffer_full = nchan_full; + nchan_residual = nchan_transport_internal - nchan_full; + hTcBuffer->n_samples_granularity = n_samples_granularity; + /* what is remaining from last frames needs always be smaller than n_samples_granularity */ + assert( ( hTcBuffer->n_samples_buffered - hTcBuffer->n_samples_rendered ) < n_samples_granularity ); + + /* realloc buffers */ + free( hTcBuffer->tc_buffer ); + n_samp_full = ( NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) + hTcBuffer->n_samples_granularity - 1 ); + n_samp_residual = hTcBuffer->n_samples_granularity - 1; + nsamp_to_allocate = hTcBuffer->nchan_buffer_full * n_samp_full; + nsamp_to_allocate += nchan_residual * n_samp_residual; + hTcBuffer->tc_buffer = (float *) malloc( nsamp_to_allocate * sizeof( float ) ); + 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; + } + for ( ; ch_idx < MAX_TRANSPORT_CHANNELS; ch_idx++ ) + { + hTcBuffer->tc[ch_idx] = NULL; + } + + return error; +} + +void ivas_jbm_dec_tc_buffer_playout( + Decoder_Struct *st_ivas, + const uint16_t nSamplesAsked, + uint16_t *nSamplesRendered, + float *output[] ) +{ + + int16_t ch_idx, slot_size, slots_to_render, first_sf, last_sf; + + slot_size = st_ivas->hTcBuffer->n_samples_granularity; + /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ + slots_to_render = min( st_ivas->hTcBuffer->num_slots - st_ivas->hTcBuffer->slots_rendered, nSamplesAsked / slot_size ); + st_ivas->hTcBuffer->slots_rendered += slots_to_render; + *nSamplesRendered = (uint16_t) slots_to_render * slot_size; + first_sf = st_ivas->hTcBuffer->subframes_rendered; + last_sf = first_sf; + while ( slots_to_render > 0 ) + { + slots_to_render -= st_ivas->hTcBuffer->subframe_nbslots[last_sf]; + last_sf++; + } + for ( ch_idx = 0; ch_idx < st_ivas->hTcBuffer->nchan_transport_jbm; ch_idx++ ) + { + mvr2r( st_ivas->hTcBuffer->tc[ch_idx] + st_ivas->hTcBuffer->n_samples_rendered, output[ch_idx], *nSamplesRendered ); + } + + st_ivas->hTcBuffer->subframes_rendered = last_sf; +} + +void ivas_jbm_dec_tc_buffer_close( + DECODER_TC_BUFFER_HANDLE *phTcBuffer /* i/o: TC buffer handle */ +) +{ + int16_t i; + + if ( *phTcBuffer != NULL ) + { + for ( i = 0; i < MAX_TRANSPORT_CHANNELS; i++ ) + { + ( *phTcBuffer )->tc[i] = NULL; + } + if ( ( *phTcBuffer )->tc_buffer != NULL ) + { + free( ( *phTcBuffer )->tc_buffer ); + ( *phTcBuffer )->tc_buffer = NULL; + } + + free( *phTcBuffer ); + *phTcBuffer = NULL; + } + return; +} + +void ivas_jbm_dec_td_renderers_adapt_subframes( + Decoder_Struct *st_ivas ) +{ + int16_t nMaxSlotsPerSubframe, nSlotsAvailable; + uint16_t nSlotsInLastSubframe, nSlotsInFirstSubframe; + nMaxSlotsPerSubframe = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ) / st_ivas->hTcBuffer->n_samples_granularity; + nSlotsAvailable = st_ivas->hTcBuffer->n_samples_available / st_ivas->hTcBuffer->n_samples_granularity; + st_ivas->hTcBuffer->num_slots = nSlotsAvailable; + st_ivas->hTcBuffer->n_samples_available = nSlotsAvailable * st_ivas->hTcBuffer->n_samples_granularity; + nSlotsInFirstSubframe = nMaxSlotsPerSubframe - st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->nb_subframes - 1]; + st_ivas->hTcBuffer->nb_subframes = 0; + if ( nSlotsInFirstSubframe > 0 ) + { + st_ivas->hTcBuffer->nb_subframes = 1; + nSlotsAvailable -= nSlotsInFirstSubframe; + } + st_ivas->hTcBuffer->nb_subframes += (int16_t) ceilf( (float) nSlotsAvailable / (float) nMaxSlotsPerSubframe ); + nSlotsInLastSubframe = nSlotsAvailable % nMaxSlotsPerSubframe; + set_s( st_ivas->hTcBuffer->subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS ); + set_s( st_ivas->hTcBuffer->subframe_nbslots, nMaxSlotsPerSubframe, st_ivas->hTcBuffer->nb_subframes ); + if ( nSlotsInFirstSubframe > 0 ) + { + st_ivas->hTcBuffer->subframe_nbslots[0] = nSlotsInFirstSubframe; + } + if ( nSlotsInLastSubframe > 0 ) + { + st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->nb_subframes - 1] = nSlotsInLastSubframe; + } + st_ivas->hTcBuffer->slots_rendered = 0; + st_ivas->hTcBuffer->subframes_rendered = 0; +} + +TC_BUFFER_MODE ivas_jbm_dec_get_tc_buffer_mode( Decoder_Struct *st_ivas ) +{ + TC_BUFFER_MODE buffer_mode; + buffer_mode = TC_BUFFER_MODE_BUFFER; + + /*:TODO: wrap this maybe nicer without directly accessing the st_ivas struct...*/ + switch ( st_ivas->renderer_type ) + { + /* all renderers where we are done after TC decoding (might include DMX to mono/stereo */ + case RENDERER_DISABLE: + case RENDERER_MCMASA_MONO_STEREO: + case RENDERER_MONO_DOWNMIX: + buffer_mode = TC_BUFFER_MODE_BUFFER; + break; + case RENDERER_TD_PANNING: + case RENDERER_BINAURAL_OBJECTS_TD: + case RENDERER_BINAURAL_FASTCONV: + case RENDERER_BINAURAL_FASTCONV_ROOM: + case RENDERER_BINAURAL_PARAMETRIC: + case RENDERER_BINAURAL_PARAMETRIC_ROOM: + case RENDERER_STEREO_PARAMETRIC: + case RENDERER_DIRAC: + case RENDERER_PARAM_ISM: + case RENDERER_BINAURAL_MIXER_CONV: + case RENDERER_BINAURAL_MIXER_CONV_ROOM: + buffer_mode = TC_BUFFER_MODE_RENDERER; + break; + case RENDERER_MC_PARAMMC: + if ( st_ivas->hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO ) + { + buffer_mode = TC_BUFFER_MODE_BUFFER; /* TCs are already the DMX to mono or stereo */ + } + else + { + buffer_mode = TC_BUFFER_MODE_RENDERER; + } + break; + case RENDERER_MC: + if ( ivas_jbm_dec_get_num_tc_channels( st_ivas ) != st_ivas->hDecoderConfig->nchan_out ) + { + buffer_mode = TC_BUFFER_MODE_RENDERER; + } + break; + case RENDERER_SBA_LINEAR_ENC: + if ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCT && ( st_ivas->renderer_type == RENDERER_MC || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) && ( st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe ) >= ( st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ) ) + { + buffer_mode = TC_BUFFER_MODE_BUFFER; + } + else + { + buffer_mode = TC_BUFFER_MODE_RENDERER; + } + break; + case RENDERER_SBA_LINEAR_DEC: + if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR && ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_MONO || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO ) ) + { + buffer_mode = TC_BUFFER_MODE_BUFFER; + } + else + { + buffer_mode = TC_BUFFER_MODE_RENDERER; + } + break; +#ifdef DEBUGGING + default: + assert( 0 ); +#endif + } + + + return buffer_mode; +} +#endif diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index 9cadbcc4fc..549cf48932 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -371,6 +371,21 @@ ivas_error ivas_masa_dec_open( st_ivas->hMasa = hMasa; +#ifdef JBM_TSM_ON_TCS + /* allocate transport channels*/ + if ( st_ivas->hDecoderConfig->voip_active == 1 && 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; + error; + + nchan_to_allocate = ivas_jbm_dec_get_num_tc_channels( st_ivas ); + if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_to_allocate, nchan_to_allocate, nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif /* JBM_TMS_ON_TCS*/ + return error; } @@ -1143,6 +1158,17 @@ ivas_error ivas_masa_dec_reconfigure( ivas_masa_set_elements( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &tmp, &tmp, &tmp ); + if ( st_ivas->hDecoderConfig->voip_active == 1 && 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 = ivas_jbm_dec_get_num_tc_channels( st_ivas ); + if ( nchan_to_allocate != st_ivas->hTcBuffer->nchan_transport_jbm ) + { + if ( ( error = ivas_jbm_dec_tc_buffer_reconfigure( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_to_allocate, nchan_to_allocate, nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) + { + } + } + } + return error; } @@ -1152,6 +1178,252 @@ ivas_error ivas_masa_dec_reconfigure( * * Determine MASA metadata from the SPAR metadata *-------------------------------------------------------------------*/ +#ifdef JBM_TSM_ON_TCS +void ivas_spar_param_to_masa_param_mapping_sf( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ + int16_t azimuth[][CLDFB_NO_CHANNELS_MAX], + int16_t elevation[][CLDFB_NO_CHANNELS_MAX], + float energy_ratio1[][CLDFB_NO_CHANNELS_MAX], + float spreadCoherence[][CLDFB_NO_CHANNELS_MAX], + float surroundingCoherence[][CLDFB_NO_CHANNELS_MAX], + float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */ + float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /* i : Input audio in CLDFB domain, imag */ +) +{ + int16_t i, j, sf, band, bin, slot, ch, nBins, nchan_transport; + int16_t mixer_mat_index; + DIRAC_DEC_HANDLE hDirAC; + SPAR_DEC_HANDLE hSpar; + DIFFUSE_DISTRIBUTION_HANDLE hDiffuseDist; + float mixer_mat_sf_bands_real[SPAR_DIRAC_SPLIT_START_BAND][FOA_CHANNELS][FOA_CHANNELS]; + float mixer_mat_sf_bins_real[CLDFB_NO_CHANNELS_MAX][FOA_CHANNELS][FOA_CHANNELS]; + int16_t *band_grouping; + int16_t band_start, band_end; + float transportSignalEnergies[2][CLDFB_NO_CHANNELS_MAX]; + float transportSignalCrossCorrelation[CLDFB_NO_CHANNELS_MAX]; + float instEne; + float inCovarianceMtx[FOA_CHANNELS][FOA_CHANNELS]; + float foaCovarianceMtx[FOA_CHANNELS][FOA_CHANNELS]; + float Iy, Iz, Ix, E, azi, ele, I, ratio; + float diffuseGainX, diffuseGainY, diffuseGainZ, diffuseGainSum; + int16_t slot_idx_start; + int16_t slot_idx; + float slot_fac; + int16_t subframe_idx; + + + /* Set values */ + hDirAC = st_ivas->hDirAC; + hSpar = st_ivas->hSpar; + hDirAC->numSimultaneousDirections = 1; + hDiffuseDist = st_ivas->hDirAC->hDiffuseDist; + nchan_transport = st_ivas->nchan_transport; + band_grouping = hDirAC->band_grouping; + subframe_idx = hSpar->subframes_rendered; + slot_idx_start = hSpar->slots_rendered; + + /* Init arrays */ + for ( i = 0; i < FOA_CHANNELS; i++ ) + { + set_zero( inCovarianceMtx[i], FOA_CHANNELS ); + } + for ( band = 0; band < SPAR_DIRAC_SPLIT_START_BAND; band++ ) + { + for ( i = 0; i < FOA_CHANNELS; i++ ) + { + for ( j = 0; j < FOA_CHANNELS; j++ ) + { + mixer_mat_sf_bands_real[band][i][j] = 0.0f; + } + } + } + + slot_fac = 1.0f / (float) hSpar->subframe_nbslots[subframe_idx]; + + /* Delay the SPAR mixing matrices to have them synced with the audio */ + for ( slot_idx = 0; slot_idx < hSpar->subframe_nbslots[subframe_idx]; slot_idx++ ) + { + sf = hSpar->render_to_md_slot_map[slot_idx + slot_idx_start] / JBM_CLDFB_SLOTS_IN_SUBFRAME; + if ( sf < SPAR_META_DELAY_SUBFRAMES ) + { + mixer_mat_index = sf + MAX_PARAM_SPATIAL_SUBFRAMES - SPAR_META_DELAY_SUBFRAMES + 1; + for ( band = 0; band < SPAR_DIRAC_SPLIT_START_BAND; band++ ) + { + for ( i = 0; i < FOA_CHANNELS; i++ ) + { + for ( j = 0; j < FOA_CHANNELS; j++ ) + { + mixer_mat_sf_bands_real[band][i][j] += slot_fac * st_ivas->hSpar->hMdDec->mixer_mat_prev[mixer_mat_index][i][j][band]; + } + } + } + } + else + { + mixer_mat_index = sf - SPAR_META_DELAY_SUBFRAMES; + for ( band = 0; band < SPAR_DIRAC_SPLIT_START_BAND; band++ ) + { + for ( i = 0; i < FOA_CHANNELS; i++ ) + { + for ( j = 0; j < FOA_CHANNELS; j++ ) + { + mixer_mat_sf_bands_real[band][i][j] += slot_fac * st_ivas->hSpar->hMdDec->mixer_mat[i][j][band + mixer_mat_index * IVAS_MAX_NUM_BANDS]; + } + } + } + } + } + + /* Map the mixing matrices from the frequency bands to frequency bins */ + bin = 0; + + for ( band = 0; band < SPAR_DIRAC_SPLIT_START_BAND; band++ ) + { + band_start = band_grouping[band]; + band_end = band_grouping[band + 1]; + for ( bin = band_start; bin < band_end; bin++ ) + { + for ( i = 0; i < FOA_CHANNELS; i++ ) + { + for ( j = 0; j < FOA_CHANNELS; j++ ) + { + mixer_mat_sf_bins_real[bin][i][j] = mixer_mat_sf_bands_real[band][i][j]; + } + } + } + } + + nBins = bin; + + + /* Determine MASA metadata */ + + /* Determine transport signal energies and cross correlations when more than 1 TC */ + if ( nchan_transport == 2 ) + { + set_zero( transportSignalEnergies[0], nBins ); + set_zero( transportSignalEnergies[1], nBins ); + set_zero( transportSignalCrossCorrelation, nBins ); + for ( slot = 0; slot < hDirAC->subframe_nbslots[subframe_idx]; slot++ ) + + { + for ( bin = 0; bin < nBins; bin++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + instEne = ( inRe[ch][slot][bin] * inRe[ch][slot][bin] ); + instEne += ( inIm[ch][slot][bin] * inIm[ch][slot][bin] ); + transportSignalEnergies[ch][bin] += instEne; + } + transportSignalCrossCorrelation[bin] += inRe[0][slot][bin] * inRe[1][slot][bin]; + transportSignalCrossCorrelation[bin] += inIm[0][slot][bin] * inIm[1][slot][bin]; + } + } + } + + if ( hDiffuseDist != NULL ) + { + set_zero( hDiffuseDist->diffuseRatioX[0], CLDFB_NO_CHANNELS_MAX ); + set_zero( hDiffuseDist->diffuseRatioY[0], CLDFB_NO_CHANNELS_MAX ); + set_zero( hDiffuseDist->diffuseRatioZ[0], CLDFB_NO_CHANNELS_MAX ); + } + + for ( bin = 0; bin < nBins; bin++ ) + { + /* Set the energy of the first transport signal */ + if ( nchan_transport == 1 ) + { + inCovarianceMtx[0][0] = 1.0f; /* In case of 1TC, fixed value can be used */ + } + else + { + inCovarianceMtx[0][0] = transportSignalEnergies[0][bin]; /* In case of 2TC, use actual energies */ + } + /* Decorrelated channels assumed to have the same energy as the source channel */ + inCovarianceMtx[1][1] = inCovarianceMtx[0][0]; + inCovarianceMtx[2][2] = inCovarianceMtx[0][0]; + inCovarianceMtx[3][3] = inCovarianceMtx[0][0]; + + /* In case residuals were transmitted, use their actual energies and cross correlations */ + if ( nchan_transport == 2 ) + { + inCovarianceMtx[1][1] = transportSignalEnergies[1][bin]; + inCovarianceMtx[0][1] = transportSignalCrossCorrelation[bin]; + inCovarianceMtx[1][0] = inCovarianceMtx[0][1]; + } + + compute_foa_cov_matrix( foaCovarianceMtx, inCovarianceMtx, mixer_mat_sf_bins_real[bin] ); + + /* Estimate MASA metadata */ + Iy = foaCovarianceMtx[0][1]; /* Intensity in Y direction */ + Iz = foaCovarianceMtx[0][2]; /* Intensity in Z direction */ + Ix = foaCovarianceMtx[0][3]; /* Intensity in X direction */ + I = sqrtf( Ix * Ix + Iy * Iy + Iz * Iz ); /* Intensity vector length */ + E = ( foaCovarianceMtx[0][0] + foaCovarianceMtx[1][1] + foaCovarianceMtx[2][2] + foaCovarianceMtx[3][3] ) / 2.0f; /* Overall energy */ + azi = atan2f( Iy, Ix ); /* Azimuth */ + ele = atan2f( Iz, sqrtf( Ix * Ix + Iy * Iy ) ); /* Elevation */ + ratio = I / fmaxf( 1e-12f, E ); /* Energy ratio */ + ratio = fmaxf( 0.0f, fminf( 1.0f, ratio ) ); + + azimuth[0][bin] = (int16_t) roundf( azi / PI_OVER_180 ); + elevation[0][bin] = (int16_t) roundf( ele / PI_OVER_180 ); + energy_ratio1[0][bin] = ratio; + + spreadCoherence[0][bin] = 0.0f; + surroundingCoherence[0][bin] = 0.0f; + + /* Determine directional distribution of the indirect audio based on the SPAR mixing matrices (and the transport audio signals when 2 TC) */ + if ( hDiffuseDist != NULL ) + { + if ( nchan_transport == 1 ) + { + diffuseGainY = fabsf( mixer_mat_sf_bins_real[bin][1][1] ); + diffuseGainX = fabsf( mixer_mat_sf_bins_real[bin][3][2] ); + diffuseGainZ = fabsf( mixer_mat_sf_bins_real[bin][2][3] ); + } + else if ( nchan_transport == 2 ) + { + diffuseGainY = fabsf( mixer_mat_sf_bins_real[bin][1][1] * transportSignalEnergies[1][bin] ); + diffuseGainX = fabsf( mixer_mat_sf_bins_real[bin][3][2] * transportSignalEnergies[0][bin] ) + fabsf( mixer_mat_sf_bins_real[bin][3][1] * transportSignalEnergies[1][bin] ); + diffuseGainZ = fabsf( mixer_mat_sf_bins_real[bin][2][3] * transportSignalEnergies[0][bin] ) + fabsf( mixer_mat_sf_bins_real[bin][2][1] * transportSignalEnergies[1][bin] ); + } + else + { + diffuseGainY = 1.0f; + diffuseGainX = 1.0f; + diffuseGainZ = 1.0f; + } + + diffuseGainSum = diffuseGainY + diffuseGainX + diffuseGainZ; + + if ( diffuseGainSum == 0.0f ) + { + hDiffuseDist->diffuseRatioX[0][bin] = 1.0f / 3.0f; + hDiffuseDist->diffuseRatioY[0][bin] = 1.0f / 3.0f; + hDiffuseDist->diffuseRatioZ[0][bin] = 1.0f / 3.0f; + } + else + { + hDiffuseDist->diffuseRatioX[0][bin] = diffuseGainX / ( diffuseGainSum + EPSILON ); + hDiffuseDist->diffuseRatioY[0][bin] = diffuseGainY / ( diffuseGainSum + EPSILON ); + hDiffuseDist->diffuseRatioZ[0][bin] = diffuseGainZ / ( diffuseGainSum + EPSILON ); + } + } + } + + for ( slot_idx = 1; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) + { + mvs2s( azimuth[0], azimuth[slot_idx], nBins ); + mvs2s( elevation[0], elevation[slot_idx], nBins ); + mvr2r( spreadCoherence[0], spreadCoherence[slot_idx], nBins ); + mvr2r( surroundingCoherence[0], surroundingCoherence[slot_idx], nBins ); + mvr2r( energy_ratio1[0], energy_ratio1[slot_idx], nBins ); + } + + + return; +} +#endif void ivas_spar_param_to_masa_param_mapping( Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ @@ -1177,6 +1449,9 @@ void ivas_spar_param_to_masa_param_mapping( float foaCovarianceMtx[FOA_CHANNELS][FOA_CHANNELS]; float Iy, Iz, Ix, E, azi, ele, I, ratio; float diffuseGainX, diffuseGainY, diffuseGainZ, diffuseGainSum; +#ifdef JBM_TSM_ON_TCS + int16_t slot_idx_start; +#endif /* Set values */ hDirAC = st_ivas->hDirAC; @@ -1247,6 +1522,10 @@ void ivas_spar_param_to_masa_param_mapping( } nBins = bin; +#ifdef JBM_TSM_ON_TCS + slot_idx_start = st_ivas->hSpar->slots_rendered; +#endif + /* Determine MASA metadata */ for ( sf = firstSubframe; sf < ( firstSubframe + nSubframes ); sf++ ) { @@ -1256,10 +1535,17 @@ void ivas_spar_param_to_masa_param_mapping( set_zero( transportSignalEnergies[0], nBins ); set_zero( transportSignalEnergies[1], nBins ); set_zero( transportSignalCrossCorrelation, nBins ); - - for ( slot = 0; slot < hDirAC->subframe_nbslots; slot++ ) +#ifdef JBM_TSM_ON_TCS + for ( slot = 0; slot < (uint8_t) hDirAC->subframe_nbslots[sf]; slot++ ) +#else + for ( slot = 0; slot < (uint8_t) hDirAC->subframe_nbslots; slot++ ) +#endif { +#ifdef JBM_TSM_ON_TCS + int16_t slotThis = slot + slot_idx_start; +#else int16_t slotThis = slot + ( hDirAC->subframe_nbslots * sf ); +#endif for ( bin = 0; bin < nBins; bin++ ) { @@ -1367,6 +1653,9 @@ void ivas_spar_param_to_masa_param_mapping( } dirac_write_idx = ( dirac_write_idx + 1 ) % hDirAC->dirac_md_buffer_length; +#ifdef JBM_TSM_ON_TCS + slot_idx_start += st_ivas->hSpar->subframe_nbslots[sf]; +#endif } return; diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index a6637ed1f2..f75c5fa830 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -76,7 +76,11 @@ typedef struct parameter_band_mapping_struct static void ivas_param_mc_dec_init( PARAM_MC_DEC_HANDLE hParamMC, const int16_t nchan_in, const int16_t nchan_out ); +#ifdef JBM_TSM_ON_TCS +static void param_mc_protoSignalComputation( float *RealBuffer, float *ImagBuffer, float *proto_frame_f, const PARAM_MC_DIFF_PROTO_INFO *diff_proto_info, const int16_t num_freq_bands ); +#else static void param_mc_protoSignalComputation( float RealBuffer[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_NSLOTS][CLDFB_NO_CHANNELS_MAX], float ImagBuffer[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_NSLOTS][CLDFB_NO_CHANNELS_MAX], float *proto_frame_f, const PARAM_MC_DIFF_PROTO_INFO *diff_proto_info, const int16_t slot_index, const int16_t num_freq_bands ); +#endif static void ivas_param_mc_dec_copy_diffuse_proto( PARAM_MC_DEC_HANDLE hParamMC, float Cldfb_buffer_real[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float Cldfb_buffer_imag[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t nY, const int16_t slot_idx ); @@ -86,13 +90,23 @@ static int16_t ivas_param_mc_uniform_decoder( float *seq, const int16_t sz_seq, static void ivas_param_mc_dequantize_cov( PARAM_MC_DEC_HANDLE hDirAC, float *ild_q, float *icc_q, const int16_t param_band_index, const int16_t nY_int, const PARAM_MC_SYNTHESIS_CONF synth_conf, const int16_t nY, const int16_t nX, float *Cx_state, float *Cproto, float *Cy_state ); +#ifdef JBM_TSM_ON_TCS +static void ivas_param_mc_get_mixing_matrices( PARAM_MC_DEC_HANDLE hParamMC, IVAS_OUTPUT_SETUP *hSynthesisOutputSetup, float Cx_in[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], float *mixing_matrix[], float *mixing_matrix_res[], const int16_t nY_int, const PARAM_MC_SYNTHESIS_CONF synth_conf, const int16_t nX, const int16_t nY ); + +static void ivas_param_mc_get_mono_stereo_mixing_matrices( PARAM_MC_DEC_HANDLE hParamMC, float Cx_in[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], float *mixing_matrix[], float *mixing_matrix_res[], const int16_t nY_intern, const int16_t nX, const int16_t nY_cov ); +#else static void ivas_param_mc_get_mixing_matrices( PARAM_MC_DEC_HANDLE hParamMC, IVAS_OUTPUT_SETUP *hSynthesisOutputSetup, float Cx_in[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], float mixing_matrix[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS], float mixing_matrix_res[PARAM_MC_MAX_PARAMETER_BANDS_RES][MAX_CICP_CHANNELS * MAX_CICP_CHANNELS], const int16_t nY_int, const PARAM_MC_SYNTHESIS_CONF synth_conf, const int16_t nX, const int16_t nY ); static void ivas_param_mc_get_mono_stereo_mixing_matrices( PARAM_MC_DEC_HANDLE hParamMC, float Cx_in[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], float mixing_matrix[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS], float mixing_matrix_res[PARAM_MC_MAX_PARAMETER_BANDS_RES][MAX_CICP_CHANNELS * MAX_CICP_CHANNELS], const int16_t nY_intern, const int16_t nX, const int16_t nY_cov ); +#endif +#ifdef JBM_TSM_ON_TCS +static void param_mc_update_mixing_matrices( PARAM_MC_DEC_HANDLE hParamMC, float *mixing_matrix[], float *mixing_matrix_res[], const uint16_t nX, const uint16_t nY ); +#else static void param_mc_update_mixing_matrices( PARAM_MC_DEC_HANDLE hParamMC, float mixing_matrix[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS], float mixing_matrix_res[PARAM_MC_MAX_PARAMETER_BANDS_RES][MAX_CICP_CHANNELS * MAX_CICP_CHANNELS], const uint16_t nX, const uint16_t nY ); +#endif -static void param_mc_compute_interpolator( const uint16_t bAttackPresent, const uint16_t attackPos, const uint16_t interp_length, float *interpolator ); +static void ivas_param_mc_dec_compute_interpolator( const uint16_t bAttackPresent, const uint16_t attackPos, const uint16_t interp_length, float *interpolator ); static void param_mc_set_num_synth_bands( const int32_t output_Fs, PARAM_MC_DEC_HANDLE hParamMC ); @@ -224,7 +238,13 @@ ivas_error ivas_param_mc_dec_open( *-----------------------------------------------------------------*/ hParamMC->slot_size = (int16_t) ( output_Fs / FRAMES_PER_SEC ) / CLDFB_NO_COL_MAX; +#ifdef JBM_TSM_ON_TCS + set_s( hParamMC->subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS ); + set_s( hParamMC->subframe_nbslots, PARAM_MC_MAX_NSLOTS_IN_SUBFRAME, DEFAULT_JBM_SUBFRAMES_5MS ); + hParamMC->nb_subframes = DEFAULT_JBM_SUBFRAMES_5MS; +#else hParamMC->subframe_nbslots = CLDFB_NO_COL_MAX / PARAM_MC_NSUBFRAMES_DEC; +#endif hParamMC->num_freq_bands = (int16_t) ( output_Fs * INV_CLDFB_BANDWIDTH + 0.5f ); hParamMC->max_band_energy_compensation = hParamMC->num_freq_bands; @@ -455,6 +475,30 @@ ivas_error ivas_param_mc_dec_open( ivas_param_mc_dec_init( hParamMC, nchan_transport, nchan_out_cov ); +#ifdef JBM_TSM_ON_TCS + if ( st_ivas->hDecoderConfig->voip_active && hParamMC->synthesis_conf != PARAM_MC_SYNTH_MONO_STEREO ) + { + hParamMC->Cldfb_RealBuffer_tc = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hParamMC->num_freq_bands * sizeof( float ) ); + set_zero( hParamMC->Cldfb_RealBuffer_tc, MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hParamMC->num_freq_bands ); + hParamMC->Cldfb_ImagBuffer_tc = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hParamMC->num_freq_bands * sizeof( float ) ); + set_zero( hParamMC->Cldfb_ImagBuffer_tc, MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hParamMC->num_freq_bands ); + if ( st_ivas->hTcBuffer == NULL ) + { + if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_transport, nchan_transport, 0, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + else + { + hParamMC->Cldfb_RealBuffer_tc = NULL; + hParamMC->Cldfb_ImagBuffer_tc = NULL; + } + hParamMC->subframes_rendered = 0; + hParamMC->slots_rendered = 0; +#endif + st_ivas->hParamMC = hParamMC; return error; @@ -597,12 +641,14 @@ ivas_error ivas_param_mc_dec_reconfig( #endif } - /*-----------------------------------------------------------------* - * set input parameters - *-----------------------------------------------------------------*/ + /*-----------------------------------------------------------------* + * set input parameters + *-----------------------------------------------------------------*/ +#ifndef JBM_TSM_ON_TCS hParamMC->slot_size = (int16_t) ( output_Fs / FRAMES_PER_SEC ) / CLDFB_NO_COL_MAX; hParamMC->subframe_nbslots = CLDFB_NO_COL_MAX / PARAM_MC_NSUBFRAMES_DEC; +#endif hParamMC->num_freq_bands = (int16_t) ( output_Fs * INV_CLDFB_BANDWIDTH + 0.5f ); hParamMC->max_band_energy_compensation = hParamMC->num_freq_bands; @@ -1124,6 +1170,19 @@ void ivas_param_mc_dec_close( hParamMC->hoa_encoder = NULL; } +#ifdef JBM_TSM_ON_TCS + 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; + } +#endif + free( *hParamMC_out ); *hParamMC_out = NULL; @@ -1241,7 +1300,9 @@ void ivas_param_mc_dec_read_BS( num_lfe_bands = 0; } - param_mc_compute_interpolator( hMetadataPMC->bAttackPresent, hMetadataPMC->attackIndex, PARAM_MC_MAX_NSLOTS, hParamMC->h_output_synthesis_params.interpolator ); +#ifndef JBM_TSM_ON_TCS + ivas_param_mc_dec_compute_interpolator( hMetadataPMC->bAttackPresent, hMetadataPMC->attackIndex, PARAM_MC_MAX_NSLOTS, hParamMC->h_output_synthesis_params.interpolator ); +#endif if ( hMetadataPMC->flag_use_adaptive_icc_map == 1 ) { @@ -1335,6 +1396,150 @@ void ivas_param_mc_dec_read_BS( return; } +#ifdef JBM_TSM_ON_TCS +void ivas_param_mc_dec_digest_tc( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint8_t nCldfbSlots, /* i : number of CLFBS slots in the transport channels */ + float *transport_channels_f[] /* i : synthesized core-coder transport channels/DirAC output */ +) +{ + PARAM_MC_DEC_HANDLE hParamMC; + int16_t i, ch; + int16_t slot_idx, param_band_idx; + int16_t nchan_transport, nchan_out_transport, nchan_out_cldfb; + int16_t nchan_out_cov; + /*CLDFB*/ + float cx[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + float cx_imag[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + float real_part, imag_part; + /* format converter */ + int16_t channel_active[MAX_OUTPUT_CHANNELS]; + uint16_t nchan_out_init; + IVAS_OUTPUT_SETUP *hSynthesisOutputSetup; + + hParamMC = st_ivas->hParamMC; + assert( hParamMC ); + + push_wmops( "param_mc_dec_digest_tc" ); + + set_s( channel_active, 0, MAX_CICP_CHANNELS ); + nchan_transport = st_ivas->nchan_transport; + nchan_out_transport = st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe; + nchan_out_init = nchan_out_transport; + + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + { + nchan_out_cldfb = BINAURAL_CHANNELS; + set_s( channel_active, 1, nchan_out_cldfb ); + if ( st_ivas->hHeadTrackData ) + { + nchan_out_init = MAX_INTERN_CHANNELS; + } + nchan_out_cov = st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe; + hSynthesisOutputSetup = &st_ivas->hTransSetup; + } + else if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_CLDFB ) + { + nchan_out_cov = nchan_out_transport; + nchan_out_cldfb = st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; + hSynthesisOutputSetup = &st_ivas->hTransSetup; + } + else if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_COV || hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO ) + { + nchan_out_cov = st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; + nchan_out_cldfb = nchan_out_cov; + set_s( channel_active, 1, nchan_out_cov ); + hSynthesisOutputSetup = &st_ivas->hOutSetup; + } + else + { + nchan_out_cov = nchan_out_transport; + nchan_out_cldfb = nchan_out_transport; + set_s( channel_active, 1, nchan_out_cov ); + hSynthesisOutputSetup = &st_ivas->hTransSetup; + } + + /* adapt transient position */ + if ( hParamMC->hMetadataPMC->bAttackPresent ) + { + hParamMC->hMetadataPMC->attackIndex = (int16_t) max( 0, hParamMC->hMetadataPMC->attackIndex + ( ( nCldfbSlots - DEFAULT_JBM_CLDFB_TIMESLOTS ) / 2 ) ); + } + /* adapt subframes */ + hParamMC->num_slots = nCldfbSlots; + hParamMC->slots_rendered = 0; + hParamMC->subframes_rendered = 0; + ivas_jbm_dec_get_adapted_subframes( nCldfbSlots, hParamMC->subframe_nbslots, &hParamMC->nb_subframes ); + ivas_param_mc_dec_compute_interpolator( hParamMC->hMetadataPMC->bAttackPresent, hParamMC->hMetadataPMC->attackIndex, nCldfbSlots, hParamMC->h_output_synthesis_params.interpolator ); + + for ( param_band_idx = 0; param_band_idx < PARAM_MC_MAX_PARAMETER_BANDS; param_band_idx++ ) + { + set_zero( cx[param_band_idx], PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + set_zero( cx_imag[param_band_idx], PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + } + + /* slot loop for gathering the input data */ + for ( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) + { + float RealBuffer[CLDFB_NO_CHANNELS_MAX]; + float ImagBuffer[CLDFB_NO_CHANNELS_MAX]; + + /* CLDFB Analysis*/ + for ( ch = 0; ch < nchan_transport; ch++ ) + { + cldfbAnalysis_ts( &( transport_channels_f[ch][hParamMC->num_freq_bands * slot_idx] ), RealBuffer, ImagBuffer, hParamMC->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); + + mvr2r( RealBuffer, &hParamMC->Cldfb_RealBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport + ch * hParamMC->num_freq_bands], hParamMC->num_freq_bands ); + mvr2r( ImagBuffer, &hParamMC->Cldfb_ImagBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport + ch * hParamMC->num_freq_bands], hParamMC->num_freq_bands ); + } + + if ( slot_idx >= 2 * hParamMC->hMetadataPMC->attackIndex ) + { + ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot( &hParamMC->Cldfb_RealBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport], &hParamMC->Cldfb_ImagBuffer_tc[slot_idx * hParamMC->num_freq_bands * nchan_transport], cx, cx_imag, hParamMC, nchan_transport ); + } + } + + /* map from complex input covariance to real values */ + for ( param_band_idx = 0; param_band_idx < hParamMC->num_param_bands_synth; param_band_idx++ ) + { + /* Cx for transport channels */ + for ( i = 0; i < nchan_transport * nchan_transport; i++ ) + { + real_part = cx[param_band_idx][i]; + imag_part = cx_imag[param_band_idx][i]; + + /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ + if ( param_band_idx < hParamMC->max_param_band_abs_cov ) + { + cx[param_band_idx][i] = sqrtf( real_part * real_part + imag_part * imag_part ); + } + else + { + cx[param_band_idx][i] = real_part; + } + } + } + + /* we have to do it similar to the encoder in case of attacks (i.e. accumulate two bands) to ensure correct DMX of the target covariance*/ + if ( hParamMC->hMetadataPMC->bAttackPresent && ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_COV || hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO ) ) + { + for ( param_band_idx = 0; param_band_idx < hParamMC->num_param_bands_synth; param_band_idx += 2 ) + { + v_add( cx[param_band_idx], cx[param_band_idx + 1], cx[param_band_idx], nchan_transport * nchan_transport ); + mvr2r( cx[param_band_idx], cx[param_band_idx + 1], nchan_transport * nchan_transport ); + } + } + + + if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO ) + { + ivas_param_mc_get_mono_stereo_mixing_matrices( hParamMC, cx, hParamMC->h_output_synthesis_cov_state.mixing_matrix, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res, nchan_out_transport, nchan_transport, nchan_out_cov ); + } + else + { + /* generate mixing matrices */ + ivas_param_mc_get_mixing_matrices( hParamMC, hSynthesisOutputSetup, cx, hParamMC->h_output_synthesis_cov_state.mixing_matrix, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res, nchan_out_transport, hParamMC->synthesis_conf, nchan_transport, nchan_out_cov ); + } +} /*------------------------------------------------------------------------- * ivas_param_mc_dec() @@ -1342,6 +1547,326 @@ void ivas_param_mc_dec_read_BS( * Parametric MC decoding process *------------------------------------------------------------------------*/ +void ivas_param_mc_dec_render( + 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 *nSamplesAvailable, /* o : number of CLDFB slots still to render */ + float *output_f[] /* o : rendered time signal */ +) +{ + PARAM_MC_DEC_HANDLE hParamMC; + int16_t i, ch; + int16_t subframe_idx; + int16_t slot_idx, slot_idx_start, slot_idx_start_cldfb_synth, first_sf, last_sf, slots_to_render; + int16_t nchan_transport, nchan_out_transport, nchan_out_cldfb; + int16_t nchan_out_cov; + /*CLDFB*/ + float Cldfb_RealBuffer[MAX_INTERN_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer[MAX_INTERN_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + /*Decorrelator*/ + float onset_filter[MAX_CICP_CHANNELS * CLDFB_NO_CHANNELS_MAX]; + /* format converter */ + int16_t channel_active[MAX_OUTPUT_CHANNELS]; + uint16_t nband_synth, nbands_to_zero; + uint16_t nchan_out_init; + uint32_t output_Fs; + IVAS_OUTPUT_SETUP *hSynthesisOutputSetup; + + hParamMC = st_ivas->hParamMC; + assert( hParamMC ); + + push_wmops( "param_mc_dec_render" ); + + set_s( channel_active, 0, MAX_CICP_CHANNELS ); + nchan_transport = st_ivas->nchan_transport; + nchan_out_transport = st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe; + nchan_out_init = nchan_out_transport; + output_Fs = st_ivas->hDecoderConfig->output_Fs; + + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + { + nchan_out_cldfb = BINAURAL_CHANNELS; + set_s( channel_active, 1, nchan_out_cldfb ); + if ( st_ivas->hHeadTrackData ) + { + nchan_out_init = MAX_INTERN_CHANNELS; + } + nchan_out_cov = st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe; + hSynthesisOutputSetup = &st_ivas->hTransSetup; + } + else if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_CLDFB ) + { + nchan_out_cov = nchan_out_transport; + nchan_out_cldfb = st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; + hSynthesisOutputSetup = &st_ivas->hTransSetup; + } + else if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_COV || hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO ) + { + nchan_out_cov = st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; + nchan_out_cldfb = nchan_out_cov; + set_s( channel_active, 1, nchan_out_cov ); + hSynthesisOutputSetup = &st_ivas->hOutSetup; + } + else + { + nchan_out_cov = nchan_out_transport; + nchan_out_cldfb = nchan_out_transport; + set_s( channel_active, 1, nchan_out_cov ); + hSynthesisOutputSetup = &st_ivas->hTransSetup; + } + + /* set everything to zero that will not be decoded */ + nband_synth = hParamMC->band_grouping[hParamMC->num_param_bands_synth]; + nbands_to_zero = hParamMC->num_freq_bands - nband_synth; + for ( ch = 0; ch < nchan_out_init; ch++ ) + { + for ( slot_idx = 0; slot_idx < JBM_CLDFB_SLOTS_IN_SUBFRAME; slot_idx++ ) + { + set_zero( &( Cldfb_RealBuffer[ch][slot_idx][nband_synth] ), nbands_to_zero ); + set_zero( &( Cldfb_ImagBuffer[ch][slot_idx][nband_synth] ), nbands_to_zero ); + } + } + + /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ + slots_to_render = min( hParamMC->num_slots - hParamMC->slots_rendered, nSamplesAsked / NS2SA( output_Fs, CLDFB_SLOT_NS ) ); + *nSamplesRendered = slots_to_render * NS2SA( output_Fs, CLDFB_SLOT_NS ); + first_sf = hParamMC->subframes_rendered; + last_sf = first_sf; + while ( slots_to_render > 0 ) + { + slots_to_render -= hParamMC->subframe_nbslots[last_sf]; + last_sf++; + } +#ifdef DEBUGGING + assert( slots_to_render == 0 ); +#endif + if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) + { + for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) + { + slots_to_render += hParamMC->subframe_nbslots[subframe_idx]; + } + } + slot_idx_start = hParamMC->slots_rendered; + slot_idx_start_cldfb_synth = 0; + for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) + { + for ( slot_idx = 0; slot_idx < hParamMC->subframe_nbslots[subframe_idx]; slot_idx++, hParamMC->slots_rendered++ ) + { + + if ( hParamMC->max_band_decorr > 0 ) + { + /*-----------------------------------------------------------------* + * protoype signal computation + *-----------------------------------------------------------------*/ + + param_mc_protoSignalComputation( &hParamMC->Cldfb_RealBuffer_tc[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], + &hParamMC->Cldfb_ImagBuffer_tc[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], + hParamMC->proto_frame_f, hParamMC->diff_proto_info, + hParamMC->num_freq_bands ); + + /*-----------------------------------------------------------------* + * frequency domain decorrelation + *-----------------------------------------------------------------*/ + + /* decorrelate prototype frame */ + ivas_dirac_dec_decorr_process( hParamMC->num_freq_bands, + hParamMC->num_outputs_diff, + hParamMC->diff_proto_info->num_protos_diff, + DIRAC_SYNTHESIS_COV_MC_LS, + nchan_transport, + hParamMC->proto_frame_f, + hParamMC->diff_proto_info->num_protos_diff, + hParamMC->diff_proto_info->proto_index_diff, + hParamMC->proto_frame_dec_f, + onset_filter, + hParamMC->h_freq_domain_decorr_ap_params, + hParamMC->h_freq_domain_decorr_ap_state ); + + /* copy decorrelated frame directly to output CLDFB buffer, acts also as intermediate */ + /* memory for the decorrelated signal */ + ivas_param_mc_dec_copy_diffuse_proto( hParamMC, Cldfb_RealBuffer, Cldfb_ImagBuffer, nchan_out_cov, slot_idx ); + } + + /*-----------------------------------------------------------------* + * output synthesis + *-----------------------------------------------------------------*/ + + ivas_dirac_dec_output_synthesis_cov_param_mc_synthesise_slot( &hParamMC->Cldfb_RealBuffer_tc[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], + &hParamMC->Cldfb_ImagBuffer_tc[hParamMC->slots_rendered * nchan_transport * hParamMC->num_freq_bands], + Cldfb_RealBuffer, Cldfb_ImagBuffer, + hParamMC->h_output_synthesis_cov_state.mixing_matrix, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res, slot_idx, slot_idx + slot_idx_start, + nchan_transport, nchan_out_cov, hParamMC ); + + if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) ) + { + if ( st_ivas->hHeadTrackData && st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) + { + ivas_param_mc_mc2sba_cldfb( st_ivas->hTransSetup, hParamMC->hoa_encoder, slot_idx, Cldfb_RealBuffer, Cldfb_ImagBuffer, nband_synth, GAIN_LFE ); + } + else + { + /* remove LFE */ + uint16_t idx_out; + uint16_t idx_lfe; + IVAS_OUTPUT_SETUP hLsSetup; + + hLsSetup = st_ivas->hTransSetup; + + /* If LFE should be rendered, add it to other channels before removing */ + if ( st_ivas->hBinRenderer->render_lfe ) + { + for ( idx_lfe = 0; idx_lfe < hLsSetup.num_lfe; idx_lfe++ ) + { + /* Copy just the first band of LFE*/ + v_multc( Cldfb_RealBuffer[hLsSetup.index_lfe[idx_lfe]][slot_idx], ( GAIN_LFE / hLsSetup.nchan_out_woLFE ), Cldfb_RealBuffer[hLsSetup.index_lfe[idx_lfe]][slot_idx], 1 ); + v_multc( Cldfb_ImagBuffer[hLsSetup.index_lfe[idx_lfe]][slot_idx], ( GAIN_LFE / hLsSetup.nchan_out_woLFE ), Cldfb_ImagBuffer[hLsSetup.index_lfe[idx_lfe]][slot_idx], 1 ); + + for ( ch = 0; ch < ( hLsSetup.nchan_out_woLFE + hLsSetup.num_lfe ); ch++ ) + { + if ( hLsSetup.index_lfe[idx_lfe] != ch ) + { + v_add( Cldfb_RealBuffer[ch][slot_idx], Cldfb_RealBuffer[hLsSetup.index_lfe[idx_lfe]][slot_idx], Cldfb_RealBuffer[ch][slot_idx], 1 ); + v_add( Cldfb_ImagBuffer[ch][slot_idx], Cldfb_ImagBuffer[hLsSetup.index_lfe[idx_lfe]][slot_idx], Cldfb_ImagBuffer[ch][slot_idx], 1 ); + } + } + } + } + + idx_out = 0; + idx_lfe = 0; + + for ( ch = 0; ch < ( hLsSetup.nchan_out_woLFE + hLsSetup.num_lfe ); ch++ ) + { + if ( ( hLsSetup.num_lfe > 0 ) && ( hLsSetup.index_lfe[idx_lfe] == ch ) ) + { + if ( idx_lfe < ( hLsSetup.num_lfe - 1 ) ) + { + idx_lfe++; + } + } + else if ( ch != idx_out ) + { + mvr2r( Cldfb_RealBuffer[ch][slot_idx], Cldfb_RealBuffer[idx_out][slot_idx], nband_synth ); + mvr2r( Cldfb_ImagBuffer[ch][slot_idx], Cldfb_ImagBuffer[idx_out][slot_idx], nband_synth ); + idx_out++; + } + else + { + idx_out++; + } + } + } + } + } + + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + { + ivas_binRenderer( st_ivas->hBinRenderer, st_ivas->hHeadTrackData, hParamMC->subframe_nbslots[subframe_idx], + Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); + } + else if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_CLDFB ) + { + /* format conversion*/ + ivas_lssetupconversion_process_param_mc( st_ivas, hParamMC->subframe_nbslots[subframe_idx], Cldfb_RealBuffer, Cldfb_ImagBuffer, channel_active ); + } + + /* CLDFB synthesis */ + for ( ch = 0; ch < nchan_out_cldfb; ch++ ) + { + float *RealBuffer[16]; + float *ImagBuffer[16]; + + if ( channel_active[ch] ) + { + /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */ + for ( i = 0; i < hParamMC->subframe_nbslots[subframe_idx]; i++ ) + { + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + { + RealBuffer[i] = Cldfb_RealBuffer_Binaural[ch][i]; + ImagBuffer[i] = Cldfb_ImagBuffer_Binaural[ch][i]; + } + else + { + RealBuffer[i] = Cldfb_RealBuffer[ch][i]; + ImagBuffer[i] = Cldfb_ImagBuffer[ch][i]; + } + } + cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][slot_idx_start_cldfb_synth * hParamMC->num_freq_bands] ), + hParamMC->num_freq_bands * hParamMC->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[ch] ); + } + else + { + set_f( &( output_f[ch][slot_idx_start_cldfb_synth * hParamMC->num_freq_bands] ), 0.0f, hParamMC->num_freq_bands * hParamMC->subframe_nbslots[subframe_idx] ); + } + } + slot_idx_start += hParamMC->subframe_nbslots[subframe_idx]; + slot_idx_start_cldfb_synth += hParamMC->subframe_nbslots[subframe_idx]; + } + + if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) + { + ivas_mc2sba( st_ivas->hIntSetup, output_f, output_f, hParamMC->num_freq_bands * slots_to_render, st_ivas->hOutSetup.ambisonics_order, 0.f ); + } + + /* update */ + if ( hParamMC->slots_rendered == hParamMC->num_slots ) + { + hParamMC->hMetadataPMC->last_coded_bwidth = hParamMC->hMetadataPMC->coded_bwidth; + param_mc_update_mixing_matrices( hParamMC, hParamMC->h_output_synthesis_cov_state.mixing_matrix, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res, nchan_transport, nchan_out_cov ); + } + hParamMC->subframes_rendered = last_sf; + *nSamplesAvailable = ( hParamMC->num_slots - hParamMC->slots_rendered ) * NS2SA( output_Fs, CLDFB_SLOT_NS ); + pop_wmops(); + + return; +} +#endif + +/*------------------------------------------------------------------------- + * ivas_param_mc_dec() + * + * Parametric MC decoding process + *------------------------------------------------------------------------*/ +#ifdef JBM_TSM_ON_TCS +void ivas_param_mc_dec( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ +) +{ + PARAM_MC_DEC_HANDLE hParamMC; + float Cldfb_RealBuffer_in[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_NSLOTS * CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_in[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_NSLOTS * CLDFB_NO_CHANNELS_MAX]; + uint16_t nSamplesAsked, nSamplesAvailable, nSamplesRendered; + + hParamMC = st_ivas->hParamMC; + assert( hParamMC ); + push_wmops( "param_mc_dec" ); + + /* set some handle pointers to the stack buffers */ + hParamMC->Cldfb_RealBuffer_tc = Cldfb_RealBuffer_in; + hParamMC->Cldfb_ImagBuffer_tc = Cldfb_ImagBuffer_in; + + nSamplesAsked = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); + ivas_param_mc_dec_digest_tc( st_ivas, DEFAULT_JBM_CLDFB_TIMESLOTS, output_f ); + ivas_param_mc_dec_render( st_ivas, nSamplesAsked, &nSamplesRendered, &nSamplesAvailable, output_f ); +#ifdef DEBUGGING + assert( nSamplesRendered == nSamplesAsked ); + assert( nSamplesAvailable == 0 ); +#endif + + /* set handle pointers back to NULL */ + hParamMC->Cldfb_RealBuffer_tc = NULL; + hParamMC->Cldfb_ImagBuffer_tc = NULL; + + pop_wmops(); + return; +} +#else void ivas_param_mc_dec( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ float output_f[][L_FRAME48k] /* i/o: synthesized core-coder transport channels/DirAC output */ @@ -1349,7 +1874,8 @@ void ivas_param_mc_dec( { PARAM_MC_DEC_HANDLE hParamMC; int16_t i, ch; - int16_t subframe_idx, num_subframes; + int16_t subframe_idx; + int16_t nb_subframes; int16_t slot_idx, param_band_idx, slot_idx_start; int16_t nchan_transport, nchan_out_transport, nchan_out_cldfb; int16_t nchan_out_cov; @@ -1496,12 +2022,13 @@ void ivas_param_mc_dec( ivas_param_mc_get_mixing_matrices( hParamMC, hSynthesisOutputSetup, cx, mixing_matrix, mixing_matrix_res, nchan_out_transport, hParamMC->synthesis_conf, nchan_transport, nchan_out_cov ); } + /*** split here... ***/ + /* subframe loop for synthesis*/ - num_subframes = CLDFB_NO_COL_MAX / hParamMC->subframe_nbslots; - for ( subframe_idx = 0; subframe_idx < num_subframes; subframe_idx++ ) + nb_subframes = CLDFB_NO_COL_MAX / hParamMC->subframe_nbslots; + for ( subframe_idx = 0; subframe_idx < nb_subframes; subframe_idx++ ) { slot_idx_start = subframe_idx * hParamMC->subframe_nbslots; - for ( slot_idx = 0; slot_idx < hParamMC->subframe_nbslots; slot_idx++ ) { @@ -1640,7 +2167,6 @@ void ivas_param_mc_dec( ImagBuffer[i] = Cldfb_ImagBuffer[ch][i]; } } - cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][slot_idx_start * hParamMC->num_freq_bands] ), hParamMC->num_freq_bands * hParamMC->subframe_nbslots, st_ivas->cldfbSynDec[ch] ); } @@ -1663,6 +2189,7 @@ void ivas_param_mc_dec( return; } +#endif /*------------------------------------------------------------------------- @@ -1737,12 +2264,19 @@ static void ivas_param_mc_dec_init( *------------------------------------------------------------------------*/ static void param_mc_protoSignalComputation( +#ifdef JBM_TSM_ON_TCS + float *RealBuffer, /* i : CLDFB samples of the transport channels (real part) */ + float *ImagBuffer, /* i : CLDFB samples of the transport channels (imaginary part) */ +#else float RealBuffer[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_NSLOTS][CLDFB_NO_CHANNELS_MAX], /* i : CLDFB samples of the transport channels (real part) */ float ImagBuffer[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_NSLOTS][CLDFB_NO_CHANNELS_MAX], /* i : CLDFB samples of the transport channels (imaginary part) */ - float *proto_frame_f, /* o : interleaved complex prototype CLDFB samples */ - const PARAM_MC_DIFF_PROTO_INFO *diff_proto_info, /* i : prototype generation information */ - const int16_t slot_index, /* i : current slot index */ - const int16_t num_freq_bands /* i : number of frequency bands for the prototypes */ +#endif + float *proto_frame_f, /* o : interleaved complex prototype CLDFB samples */ + const PARAM_MC_DIFF_PROTO_INFO *diff_proto_info, /* i : prototype generation information */ +#ifndef JBM_TSM_ON_TCS + const int16_t slot_index, /* i : current slot index */ +#endif + const int16_t num_freq_bands /* i : number of frequency bands for the prototypes */ ) { int16_t band; @@ -1763,8 +2297,13 @@ static void param_mc_protoSignalComputation( int16_t source_ch_idx = diff_proto_info->source_chan_idx[proto_ch_idx][source_ch_cnt]; p_proto_frame = &proto_frame_f[proto_ch_idx * num_freq_bands * 2]; +#ifdef JBM_TSM_ON_TCS + p_real_buffer = &RealBuffer[source_ch_idx * num_freq_bands]; + p_imag_buffer = &ImagBuffer[source_ch_idx * num_freq_bands]; +#else p_real_buffer = &RealBuffer[source_ch_idx][slot_index][0]; p_imag_buffer = &ImagBuffer[source_ch_idx][slot_index][0]; +#endif for ( band = 0; band < num_freq_bands; band++ ) { @@ -1936,15 +2475,18 @@ static int16_t ivas_param_mc_range_decoder_LC( * * compute the interpolator used in the final synthesis *------------------------------------------------------------------------*/ - -static void param_mc_compute_interpolator( +static void ivas_param_mc_dec_compute_interpolator( const uint16_t bAttackPresent, /* i : flag indicating if we have a transient in the current frame */ const uint16_t attackPos, /* i : position of the transient */ const uint16_t interp_length, /* i : number of interpolation values to be calculated */ float *interpolator /* o : interpolator */ ) { +#ifdef JBM_TSM_ON_TCS + int16_t idx; +#else uint16_t idx; +#endif if ( bAttackPresent ) { @@ -1959,10 +2501,14 @@ static void param_mc_compute_interpolator( } else { +#ifdef JBM_TSM_ON_TCS + ivas_jbm_dec_get_adapted_linear_interpolator( DEFAULT_JBM_CLDFB_TIMESLOTS, interp_length, interpolator ); +#else for ( idx = 1; idx <= interp_length; ++idx ) { interpolator[idx - 1] = (float) idx / (float) interp_length; } +#endif } return; @@ -2022,12 +2568,17 @@ static void ivas_param_mc_get_mixing_matrices( PARAM_MC_DEC_HANDLE hParamMC, /* i : Parametric MC handle */ IVAS_OUTPUT_SETUP *hSynthesisOutputSetup, float Cx_in[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], /* i : input covariance for all parameter bands */ - float mixing_matrix[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS], /* o : direct mixing matrices for all parameter bands */ - float mixing_matrix_res[PARAM_MC_MAX_PARAMETER_BANDS_RES][MAX_CICP_CHANNELS * MAX_CICP_CHANNELS], /* o : residual mixing matrices for all parameter bands */ - const int16_t nY_intern, /* i : number of channels in the transported format */ - const PARAM_MC_SYNTHESIS_CONF synth_config, /* i : Parametric MC synthesis config */ - const int16_t nX, /* i : number of transport channels */ - const int16_t nY_cov /* i : number of covariance synthesis output channels */ +#ifdef JBM_TSM_ON_TCS + float *mixing_matrix[], /* o : direct mixing matrices for all parameter bands */ + float *mixing_matrix_res[], /* o : residual mixing matrices for all parameter bands */ +#else + float mixing_matrix[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS], /* o : direct mixing matrices for all parameter bands */ + float mixing_matrix_res[PARAM_MC_MAX_PARAMETER_BANDS_RES][MAX_CICP_CHANNELS * MAX_CICP_CHANNELS], /* o : residual mixing matrices for all parameter bands */ +#endif + const int16_t nY_intern, /* i : number of channels in the transported format */ + const PARAM_MC_SYNTHESIS_CONF synth_config, /* i : Parametric MC synthesis config */ + const int16_t nX, /* i : number of transport channels */ + const int16_t nY_cov /* i : number of covariance synthesis output channels */ ) { int16_t param_band_idx; @@ -2276,11 +2827,16 @@ static void ivas_param_mc_get_mixing_matrices( static void ivas_param_mc_get_mono_stereo_mixing_matrices( PARAM_MC_DEC_HANDLE hParamMC, /* i : Parametric MC handle */ float Cx_in[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS], /* i : transport channel covariance for all parameter bands */ - float mixing_matrix[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS], /* o : direct mixing matrix */ - float mixing_matrix_res[PARAM_MC_MAX_PARAMETER_BANDS_RES][MAX_CICP_CHANNELS * MAX_CICP_CHANNELS], /* o : residual mixing matrix (set to zero) */ - const int16_t nY_intern, /* i : number of channels of the transport format */ - const int16_t nX, /* i : number of transport channels */ - const int16_t nY_cov ) /* i : number of output channels */ +#ifdef JBM_TSM_ON_TCS + float *mixing_matrix[], /* o : direct mixing matrices for all parameter bands */ + float *mixing_matrix_res[], /* o : residual mixing matrices for all parameter bands */ +#else + float mixing_matrix[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS], /* o : direct mixing matrix */ + float mixing_matrix_res[PARAM_MC_MAX_PARAMETER_BANDS_RES][MAX_CICP_CHANNELS * MAX_CICP_CHANNELS], /* o : residual mixing matrix (set to zero) */ +#endif + const int16_t nY_intern, /* i : number of channels of the transport format */ + const int16_t nX, /* i : number of transport channels */ + const int16_t nY_cov ) /* i : number of output channels */ { int16_t param_band_idx; float Cx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; @@ -2395,17 +2951,21 @@ static void ivas_param_mc_get_mono_stereo_mixing_matrices( *------------------------------------------------------------------------*/ static void param_mc_update_mixing_matrices( - PARAM_MC_DEC_HANDLE hParamMC, /* i/o: Parametric MC handle */ + PARAM_MC_DEC_HANDLE hParamMC, /* i/o: Parametric MC handle */ +#ifdef JBM_TSM_ON_TCS + float *mixing_matrix[], /* i : direct mixing matrices for the frame just processed */ + float *mixing_matrix_res[], /* i : residual mixing matrices for the frame just processed */ +#else float mixing_matrix[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS * PARAM_MC_MAX_TRANSPORT_CHANS], /* i : direct mixing matrices for the frame just processed */ float mixing_matrix_res[PARAM_MC_MAX_PARAMETER_BANDS_RES][MAX_CICP_CHANNELS * MAX_CICP_CHANNELS], /* i : residual mixing matrices for the frame just processed */ - const uint16_t nX, /* i : number of transport channels */ - const uint16_t nY ) /* i : number of synthesis channels */ +#endif + const uint16_t nX, /* i : number of transport channels */ + const uint16_t nY ) /* i : number of synthesis channels */ { uint16_t param_band_idx; for ( param_band_idx = 0; param_band_idx < hParamMC->hMetadataPMC->nbands_coded; param_band_idx++ ) { - /* final mixing */ int16_t brange[2]; brange[0] = hParamMC->band_grouping[param_band_idx]; diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 1ad01239cb..55a68c4475 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -54,8 +54,11 @@ * Local function prototypes *-----------------------------------------------------------------------*/ +#ifdef JBM_TSM_ON_TCS +static ivas_error ivas_mc_dec_reconfig( Decoder_Struct *st_ivas, uint16_t *nSamplesRendered, int16_t *data ); +#else static ivas_error ivas_mc_dec_reconfig( Decoder_Struct *st_ivas ); - +#endif /*--------------------------------------------------------------------------* * ivas_mct_dec() @@ -613,6 +616,11 @@ void ivas_mct_dec_close( ivas_error ivas_mc_dec_config( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const int16_t idx /* i : LS config. index */ +#ifdef JBM_TSM_ON_TCS + , + uint16_t *nSamplesRendered, /* o : samples flushed from last frame (JBM) */ + int16_t *data /* o : flushed samples (JBM) */ +#endif ) { AUDIO_CONFIG signaled_config; @@ -642,7 +650,11 @@ ivas_error ivas_mc_dec_config( { if ( st_ivas->hDecoderConfig->last_ivas_total_brate != st_ivas->hDecoderConfig->ivas_total_brate || st_ivas->transport_config != signaled_config || last_mc_mode != st_ivas->mc_mode ) { +#ifdef JBM_TSM_ON_TCS + ivas_mc_dec_reconfig( st_ivas, nSamplesRendered, data ); +#else ivas_mc_dec_reconfig( st_ivas ); +#endif } } @@ -661,6 +673,11 @@ ivas_error ivas_mc_dec_config( static ivas_error ivas_mc_dec_reconfig( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +#ifdef JBM_TSM_ON_TCS + , + uint16_t *nSamplesRendered, /* o : number of samples flushed from the last frame (JBM) */ + int16_t *data /* o : flushed samples (JBM) */ +#endif ) { int16_t nchan_transport_old, nSCE_old, nCPE_old, sba_dirac_stereo_flag_old, nchan_hp20_old; @@ -670,6 +687,14 @@ static ivas_error ivas_mc_dec_reconfig( Decoder_State *st; ivas_error error; MC_MODE mc_mode, last_mc_mode; +#ifdef JBM_TSM_ON_TCS + TC_BUFFER_MODE tc_buffer_mode_new; + int16_t tc_nchan_tc_new; + int16_t tc_nchan_allocate_new; + int16_t tc_granularity_new; + AUDIO_CONFIG intern_config_old; + IVAS_OUTPUT_SETUP hIntSetupOld; +#endif error = IVAS_ERR_OK; @@ -700,13 +725,63 @@ static ivas_error ivas_mc_dec_reconfig( } st_ivas->sba_dirac_stereo_flag = ivas_get_sba_dirac_stereo_flag( st_ivas ); +#ifdef JBM_TSM_ON_TCS + /* save old IntSetup, might be needed for JBM flushing...*/ + intern_config_old = st_ivas->intern_config; + hIntSetupOld = st_ivas->hIntSetup; + tc_granularity_new = 1; +#endif + /* renderer might have changed, reselect */ renderer_type_old = st_ivas->renderer_type; ivas_renderer_select( st_ivas ); + /* side effect of the renderer selection can be a changed internal config */ ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->intern_config ); +#ifdef JBM_TSM_ON_TCS + if ( st_ivas->hDecoderConfig->voip_active ) + { + /* transfer subframe info from DirAC or ParamMC to central tc buffer */ + if ( last_mc_mode == MC_MODE_PARAMMC ) + { + st_ivas->hTcBuffer->nb_subframes = st_ivas->hParamMC->nb_subframes; + st_ivas->hTcBuffer->subframes_rendered = st_ivas->hParamMC->subframes_rendered; + st_ivas->hTcBuffer->num_slots = st_ivas->hParamMC->num_slots; + st_ivas->hTcBuffer->slots_rendered = st_ivas->hParamMC->slots_rendered; + mvs2s( st_ivas->hParamMC->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); + } + else if ( last_mc_mode == MC_MODE_MCMASA && st_ivas->hDirAC != NULL ) + { + st_ivas->hTcBuffer->nb_subframes = st_ivas->hDirAC->nb_subframes; + st_ivas->hTcBuffer->subframes_rendered = st_ivas->hDirAC->subframes_rendered; + st_ivas->hTcBuffer->num_slots = st_ivas->hDirAC->num_slots; + st_ivas->hTcBuffer->slots_rendered = st_ivas->hDirAC->slots_rendered; + mvs2s( st_ivas->hDirAC->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); + } + /* JBM: when granularity goes down (e.g. MCT with CREND -> ParamMC with binaural fastconv + render what still fits in the new granularity */ + tc_granularity_new = ivas_jbm_dec_get_render_granularity( st_ivas->renderer_type, 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 ) + { + return error; + } + } + /* JBM: when granularity goes up set samples to discard at the beginning of the frame */ + else if ( tc_granularity_new > st_ivas->hTcBuffer->n_samples_granularity ) + { + if ( ( error = ivas_jbm_dec_set_discard_samples( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } +#endif + + if ( st_ivas->mc_mode == MC_MODE_MCT ) { st_ivas->nchan_transport = ivas_mc_ls_setup_get_num_channels( ivas_mc_map_output_config_to_mc_ls_setup( st_ivas->transport_config ) ); @@ -728,6 +803,13 @@ static ivas_error ivas_mc_dec_reconfig( ivas_masa_dec_close( &( st_ivas->hMasa ) ); ivas_qmetadata_close( &st_ivas->hQMetaData ); +#ifdef JBM_TSM_ON_TCS + if ( st_ivas->hDirAC != NULL ) + { + ivas_dirac_dec_close( &st_ivas->hDirAC ); + } +#endif + /* init LS conversion if the renderer type asks for it */ if ( st_ivas->renderer_type == RENDERER_MC && st_ivas->hLsSetUpConversion == NULL ) { @@ -765,6 +847,14 @@ static ivas_error ivas_mc_dec_reconfig( ivas_masa_dec_close( &( st_ivas->hMasa ) ); ivas_qmetadata_close( &st_ivas->hQMetaData ); +#ifdef JBM_TSM_ON_TCS + if ( st_ivas->hDirAC != NULL ) + { + ivas_dirac_dec_close( &st_ivas->hDirAC ); + } +#endif + + if ( last_mc_mode == MC_MODE_MCT ) { if ( st_ivas->hMCT != NULL && st_ivas->nchan_transport <= CPE_CHANNELS ) @@ -1121,5 +1211,56 @@ static ivas_error ivas_mc_dec_reconfig( #endif } +#ifdef JBM_TSM_ON_TCS + /*-----------------------------------------------------------------* + * Reconfigure TC buffer + *-----------------------------------------------------------------*/ + if ( st_ivas->hDecoderConfig->voip_active == 1 ) + { + int16_t tc_nchan_full_new; + DECODER_TC_BUFFER_HANDLE hTcBuffer; + + hTcBuffer = st_ivas->hTcBuffer; + tc_buffer_mode_new = ivas_jbm_dec_get_tc_buffer_mode( st_ivas ); + tc_nchan_tc_new = ivas_jbm_dec_get_num_tc_channels( st_ivas ); + tc_nchan_allocate_new = tc_nchan_tc_new; + tc_nchan_full_new = tc_nchan_tc_new; + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + tc_nchan_allocate_new = 2 * BINAURAL_CHANNELS; + tc_nchan_full_new = tc_nchan_allocate_new; + } + if ( st_ivas->mc_mode == MC_MODE_PARAMMC && st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_MONO && st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_STEREO ) + { + tc_nchan_full_new = 0; + } + /* reconfigure buffer */ + if ( hTcBuffer->tc_buffer_mode != tc_buffer_mode_new || hTcBuffer->nchan_transport_jbm != tc_nchan_tc_new || + hTcBuffer->nchan_buffer_full != tc_nchan_full_new || hTcBuffer->nchan_transport_internal != tc_nchan_allocate_new ) + { + if ( ( error = ivas_jbm_dec_tc_buffer_reconfigure( st_ivas, tc_buffer_mode_new, tc_nchan_tc_new, tc_nchan_allocate_new, tc_nchan_full_new, tc_granularity_new ) ) != IVAS_ERR_OK ) + { + return error; + } + } + /* transfer subframe info from central tc buffer to ParamMC or McMASA (DirAC) */ + if ( st_ivas->hDirAC != NULL ) + { + st_ivas->hDirAC->nb_subframes = st_ivas->hTcBuffer->nb_subframes; + st_ivas->hDirAC->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered; + st_ivas->hDirAC->num_slots = st_ivas->hTcBuffer->num_slots; + st_ivas->hDirAC->slots_rendered = st_ivas->hTcBuffer->slots_rendered; + mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hDirAC->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); + } + else if ( st_ivas->hParamMC != NULL ) + { + st_ivas->hParamMC->nb_subframes = st_ivas->hTcBuffer->nb_subframes; + st_ivas->hParamMC->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered; + st_ivas->hParamMC->num_slots = st_ivas->hTcBuffer->num_slots; + st_ivas->hParamMC->slots_rendered = st_ivas->hTcBuffer->slots_rendered; + mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hParamMC->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); + } + } +#endif return error; } diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index f1c1fc04f2..a7c804007d 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -67,7 +67,11 @@ ivas_error ivas_td_binaural_open( ivas_error ivas_td_binaural_renderer( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ +#ifdef JBM_TSM_ON_TCS + float *output[], /* i/o: SCE channels / Binaural synthesis */ +#else float output[][L_FRAME48k], /* i/o: SCE channels / Binaural synthesis */ +#endif const int16_t output_frame /* i : output frame length */ ) { @@ -78,3 +82,89 @@ ivas_error ivas_td_binaural_renderer( st_ivas->hIsmMetaData, st_ivas->hDecoderConfig->Opt_Headrotation, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->Quaternions : NULL, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->Pos : NULL, output, output_frame ); } + +#ifdef JBM_TSM_ON_TCS +/*---------------------------------------------------------------------* + * ObjRenderIVASFrame() + * + * Receives the current frames for the object streams, updates metadata + * and renders the current frame. + *---------------------------------------------------------------------*/ + +void ObjRenderIVASSubframe( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output[], /* i/o: SCE channels / Binaural synthesis */ + const int16_t n_samples_asked ) +{ + int16_t first_sf, last_sf, subframe_idx; + float reverb_signal[BINAURAL_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; + float *p_reverb_signal[BINAURAL_CHANNELS]; + float *output_f_local[BINAURAL_CHANNELS]; + float *tc_local[MAX_TRANSPORT_CHANNELS]; + int16_t ch, slot_size, slots_to_render, output_frame; + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + p_reverb_signal[ch] = reverb_signal[ch]; + } + for ( ch = 0; ch < st_ivas->hTcBuffer->nchan_transport_internal; ch++ ) + { + tc_local[ch] = st_ivas->hTcBuffer->tc[ch] + st_ivas->hTcBuffer->n_samples_rendered; + } + for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) + { + output_f_local[ch] = output[ch]; + } + slot_size = st_ivas->hTcBuffer->n_samples_granularity; + /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ + slots_to_render = min( st_ivas->hTcBuffer->num_slots - st_ivas->hTcBuffer->slots_rendered, n_samples_asked / slot_size ); + first_sf = st_ivas->hTcBuffer->subframes_rendered; + last_sf = first_sf; + st_ivas->hTcBuffer->slots_rendered += slots_to_render; + while ( slots_to_render > 0 ) + { + slots_to_render -= st_ivas->hTcBuffer->subframe_nbslots[last_sf]; + last_sf++; + } + + for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) + { + output_frame = st_ivas->hTcBuffer->subframe_nbslots[subframe_idx] * st_ivas->hTcBuffer->n_samples_granularity; + /* Update object position(s) */ + TDREND_Update_object_positions( st_ivas->hBinRendererTd, st_ivas->nchan_transport, LFE_CHANNEL, st_ivas->ivas_format, st_ivas->hIsmMetaData, tc_local ); + + /* Update the listener's location/orientation */ + TDREND_Update_listener_orientation( st_ivas->hBinRendererTd, + st_ivas->hDecoderConfig->Opt_Headrotation, + ( st_ivas->hHeadTrackData != NULL ) ? &st_ivas->hHeadTrackData->Quaternions[0] : NULL, + ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->Pos : NULL ); + + if ( ( st_ivas->hRenderConfig != NULL ) && ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) ) + { + ivas_reverb_process( st_ivas->hReverb, st_ivas->transport_config, 0, tc_local, p_reverb_signal, 0 ); + } + + /* Render subframe */ + TDREND_GetMix( st_ivas->hBinRendererTd, output_f_local, output_frame, 0 ); + + if ( st_ivas->hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */ + { + if ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) + { + /* add reverb to rendered signals */ + v_add( reverb_signal[0], output_f_local[0], output_f_local[0], output_frame ); + v_add( reverb_signal[1], output_f_local[1], output_f_local[1], output_frame ); + } + } + for ( ch = 0; ch < st_ivas->hTcBuffer->nchan_transport_internal; ch++ ) + { + tc_local[ch] += output_frame; + } + for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) + { + output_f_local[ch] += output_frame; + } + } + st_ivas->hTcBuffer->subframes_rendered = last_sf; + return; +} +#endif \ No newline at end of file diff --git a/lib_dec/ivas_out_setup_conversion.c b/lib_dec/ivas_out_setup_conversion.c index 2fb04af8d7..71b85a1dc9 100644 --- a/lib_dec/ivas_out_setup_conversion.c +++ b/lib_dec/ivas_out_setup_conversion.c @@ -466,7 +466,12 @@ void ivas_ls_setup_conversion_close( void ivas_ls_setup_conversion( Decoder_Struct *st_ivas, /* i : IVAS decoder structure */ const int16_t output_frame, /* i : frame length */ - float output[][L_FRAME48k] /* i/o: LS input/output synthesis signal */ +#ifdef JBM_TSM_ON_TCS + float *input[], /* i : LS input/output synthesis signal */ + float *output[] /* i/o: LS input/output synthesis signal */ +#else + float output[][L_FRAME48k] /* i/o: LS input/output synthesis signal */ +#endif ) { int16_t chInIdx, chOutIdx, idx; @@ -493,14 +498,22 @@ void ivas_ls_setup_conversion( { for ( idx = 0; idx < output_frame; idx++ ) { +#ifdef JBM_TSM_ON_TCS + output_tmp[chOutIdx][idx] += input[chInIdx][idx]; +#else output_tmp[chOutIdx][idx] += output[chInIdx][idx]; +#endif } } else { for ( idx = 0; idx < output_frame; idx++ ) { +#ifdef JBM_TSM_ON_TCS + tmpVal = dmxCoeff * input[chInIdx][idx]; +#else tmpVal = dmxCoeff * output[chInIdx][idx]; +#endif output_tmp[chOutIdx][idx] += tmpVal; } } @@ -1098,7 +1111,10 @@ void ivas_ls_setup_conversion_process_mdct_param_mc( *-------------------------------------------------------------------------*/ void ivas_lssetupconversion_process_param_mc( - Decoder_Struct *st_ivas, /* i/o: LS setup conversion renderer handle */ + Decoder_Struct *st_ivas, /* i/o: LS setup conversion renderer handle */ +#ifdef JBM_TSM_ON_TCS + int16_t num_timeslots, +#endif float Cldfb_RealBuffer_InOut[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i/o: LS signals */ float Cldfb_ImagBuffer_InOut[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i/o: LS signals */ int16_t channel_active[MAX_CICP_CHANNELS] /* i : bitmap indicating which output channels are active */ @@ -1125,8 +1141,12 @@ void ivas_lssetupconversion_process_param_mc( set_s( channel_active, 0, outChannels ); - /* Loop over each time slots and compute dmx for each time slot */ +/* Loop over each time slots and compute dmx for each time slot */ +#ifdef JBM_TSM_ON_TCS + for ( slotIdx = 0; slotIdx < num_timeslots; slotIdx++ ) +#else for ( slotIdx = 0; slotIdx < st_ivas->hParamMC->subframe_nbslots; slotIdx++ ) +#endif { /* copy buffers */ for ( chInIdx = 0; chInIdx < inChannels; chInIdx++ ) diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index af7281a578..098a90aed7 100755 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -111,6 +111,7 @@ ivas_error ivas_sba_dec_reconfigure( SBA_MODE sba_mode_old; int32_t ivas_total_brate, last_ivas_total_brate; RENDERER_TYPE old_renderer_type; + DECODER_CONFIG_HANDLE hDecoderConfig; ivas_error error; int16_t band_grouping[IVAS_MAX_NUM_BANDS + 1]; @@ -128,7 +129,6 @@ ivas_error ivas_sba_dec_reconfigure( * Set SBA high-level parameters * Save old SBA high-level parameters *-----------------------------------------------------------------*/ - ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old ); nchan_hp20_old = getNumChanSynthesis( st_ivas ); nSCE_old = st_ivas->nSCE; @@ -139,19 +139,39 @@ ivas_error ivas_sba_dec_reconfigure( st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( ivas_total_brate, st_ivas->sba_order ); st_ivas->sba_mode = ivas_sba_mode_select( ivas_total_brate ); +#ifdef JBM_TSM_ON_TCS + /* save old */ + if ( st_ivas->hDirAC == NULL && st_ivas->hSpar != NULL ) + { + st_ivas->hTcBuffer->num_slots = st_ivas->hSpar->num_slots; + st_ivas->hTcBuffer->nb_subframes = st_ivas->hSpar->nb_subframes; + st_ivas->hTcBuffer->slots_rendered = st_ivas->hSpar->slots_rendered; + st_ivas->hTcBuffer->subframes_rendered = st_ivas->hSpar->subframes_rendered; + mvs2s( st_ivas->hSpar->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); + } + else if ( st_ivas->hDirAC != NULL ) + { + st_ivas->hTcBuffer->num_slots = st_ivas->hDirAC->num_slots; + st_ivas->hTcBuffer->nb_subframes = st_ivas->hDirAC->nb_subframes; + st_ivas->hTcBuffer->slots_rendered = st_ivas->hDirAC->slots_rendered; + st_ivas->hTcBuffer->subframes_rendered = st_ivas->hDirAC->subframes_rendered; + mvs2s( st_ivas->hDirAC->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); + } +#endif + /*-----------------------------------------------------------------* * Allocate, initialize, and configure SBA handles *-----------------------------------------------------------------*/ if ( st_ivas->sba_mode != SBA_MODE_SPAR ) { + ivas_spar_dec_close( &( st_ivas->hSpar ), hDecoderConfig->output_Fs, 0 ); if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_mode, -1 ) ) != IVAS_ERR_OK ) { return error; } - st_ivas->sba_dirac_stereo_flag = ivas_get_sba_dirac_stereo_flag( st_ivas ); } else @@ -163,6 +183,7 @@ ivas_error ivas_sba_dec_reconfigure( if ( hSpar != NULL ) { + if ( ( hSpar->hPCA != NULL ) && ( ( hDecoderConfig->ivas_total_brate != PCA_BRATE ) || ( sba_order_internal != 1 ) ) ) { free( st_ivas->hSpar->hPCA ); @@ -171,7 +192,6 @@ ivas_error ivas_sba_dec_reconfigure( if ( nchan_transport_old != ivas_get_sba_num_TCs( ivas_total_brate, sba_order_internal ) ) { - ivas_spar_dec_close( &( st_ivas->hSpar ), hDecoderConfig->output_Fs, 1 ); if ( ( error = ivas_spar_dec_open( st_ivas, 1 ) ) != IVAS_ERR_OK ) @@ -192,6 +212,14 @@ ivas_error ivas_sba_dec_reconfigure( hSpar = st_ivas->hSpar; st_ivas->sba_dirac_stereo_flag = ivas_get_sba_dirac_stereo_flag( st_ivas ); +#ifdef JBM_TSM_ON_TCS + /* synchronize subframe info */ + st_ivas->hSpar->num_slots = st_ivas->hTcBuffer->num_slots; + st_ivas->hSpar->nb_subframes = st_ivas->hTcBuffer->nb_subframes; + st_ivas->hSpar->slots_rendered = st_ivas->hTcBuffer->slots_rendered; + st_ivas->hSpar->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered; + mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hSpar->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); +#endif } if ( st_ivas->nchan_transport == 1 ) @@ -276,6 +304,14 @@ ivas_error ivas_sba_dec_reconfigure( { return error; } +#ifdef JBM_TSM_ON_TCS + /* synchronize subframe info */ + st_ivas->hDirAC->num_slots = st_ivas->hTcBuffer->num_slots; + st_ivas->hDirAC->nb_subframes = st_ivas->hTcBuffer->nb_subframes; + st_ivas->hDirAC->slots_rendered = st_ivas->hTcBuffer->slots_rendered; + st_ivas->hDirAC->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered; + mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hDirAC->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); +#endif } if ( st_ivas->sba_mode == SBA_MODE_SPAR ) @@ -336,5 +372,162 @@ ivas_error ivas_sba_dec_reconfigure( return error; } +#ifdef JBM_TSM_ON_TCS + /*-----------------------------------------------------------------* + * TC buffer + *-----------------------------------------------------------------*/ + if ( st_ivas->hDecoderConfig->voip_active == 1 && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC ) + { + int16_t tc_nchan_to_allocate; + int16_t tc_nchan_tc; + TC_BUFFER_MODE tc_buffer_mode; + int16_t sba_order_internal; + + sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); + + tc_buffer_mode = TC_BUFFER_MODE_RENDERER; + tc_nchan_tc = ivas_jbm_dec_get_num_tc_channels( st_ivas ); + + tc_nchan_to_allocate = ivas_sba_get_nchan_metadata( sba_order_internal ); + tc_nchan_tc = st_ivas->nchan_transport; + tc_nchan_to_allocate = tc_nchan_tc; + if ( st_ivas->nchan_transport == 1 && ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) || ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) ) + { + tc_nchan_to_allocate++; /* we need a channel for the CNG in this case*/ + } + if ( tc_nchan_tc != st_ivas->hTcBuffer->nchan_transport_jbm || tc_nchan_to_allocate != st_ivas->hTcBuffer->nchan_transport_internal || tc_buffer_mode != st_ivas->hTcBuffer->tc_buffer_mode ) + { + if ( ( error = ivas_jbm_dec_tc_buffer_reconfigure( st_ivas, tc_buffer_mode, tc_nchan_tc, tc_nchan_to_allocate, tc_nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } +#endif return error; } + +#ifdef JBM_TSM_ON_TCS +ivas_error ivas_sba_dec_digest_tc( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const int16_t nCldfbSlots, /* i : number of CLDFB slots */ + const int16_t nSamplesForRendering /* i : number of samples provided */ +) +{ + + int16_t ch_idx; + ivas_error error; + + error = IVAS_ERR_OK; + + /* set the md map */ + if ( st_ivas->hDirAC && !( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC && st_ivas->sba_mode == SBA_MODE_DIRAC ) ) + { + ivas_dirac_dec_set_md_map( st_ivas, nCldfbSlots ); + } + if ( st_ivas->sba_mode == SBA_MODE_SPAR ) + { + ivas_spar_dec_digest_tc( st_ivas, st_ivas->nchan_transport, nCldfbSlots, nSamplesForRendering ); + } + if ( st_ivas->hDiracDecBin != NULL && ( st_ivas->hDiracDecBin->useTdDecorr ) ) + { + int16_t nSamplesLeftForTD, default_frame; + float *decorr_signal[BINAURAL_CHANNELS]; + float *p_tc[2 * BINAURAL_CHANNELS]; + default_frame = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); + nSamplesLeftForTD = nSamplesForRendering; + for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + { + decorr_signal[ch_idx] = st_ivas->hTcBuffer->tc[ch_idx + BINAURAL_CHANNELS]; + p_tc[ch_idx] = st_ivas->hTcBuffer->tc[ch_idx]; + } + while ( nSamplesLeftForTD ) + { + int16_t nSamplesToDecorr = min( nSamplesLeftForTD, default_frame ); + ivas_td_decorr_process( st_ivas->hDiracDecBin->hTdDecorr, p_tc, decorr_signal, nSamplesToDecorr ); + for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + { + decorr_signal[ch_idx] += nSamplesToDecorr; + p_tc[ch_idx] += nSamplesToDecorr; + } + nSamplesLeftForTD -= nSamplesToDecorr; + } + } + /* if we have a late CNG generation, do it here */ + if ( st_ivas->nchan_transport == 1 && st_ivas->hSCE[0]->hCoreCoder[0] != NULL && st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->sba_mode != SBA_MODE_SPAR ) + { + Decoder_State *st = st_ivas->hSCE[0]->hCoreCoder[0]; + generate_masking_noise_lb_dirac( st->hFdCngDec->hFdCngCom, st_ivas->hTcBuffer->tc[1], nCldfbSlots, st->cna_dirac_flag && st->flag_cna ); + } + return error; +} + +void ivas_sba_dec_render( + 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 *nSamplesAvailable, /* o : number of CLDFB slots still to render */ + float *output_f[] /* o : rendered time signal */ +) +{ + int16_t slots_to_render, first_sf, last_sf, subframe_idx; + uint16_t slot_size, ch; + uint16_t nchan_internal, sba_order_internal, nchan_out; + SPAR_DEC_HANDLE hSpar; + float *output_f_local[MAX_OUTPUT_CHANNELS]; + + hSpar = st_ivas->hSpar; + sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); + nchan_internal = ivas_sba_get_nchan_metadata( sba_order_internal ); + nchan_out = nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; +#ifdef DEBUGGING + assert( hSpar ); +#endif + for ( ch = 0; ch < nchan_out; ch++ ) + { + output_f_local[ch] = output_f[ch]; + } + slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); + /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ + slots_to_render = min( hSpar->num_slots - hSpar->slots_rendered, nSamplesAsked / slot_size ); + *nSamplesRendered = slots_to_render * slot_size; + first_sf = hSpar->subframes_rendered; + last_sf = first_sf; + while ( slots_to_render > 0 ) + { + slots_to_render -= hSpar->subframe_nbslots[last_sf]; + last_sf++; + } +#ifdef DEBUGGING + assert( slots_to_render == 0 ); +#endif + for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) + { + int16_t n_samples_sf = slot_size * hSpar->subframe_nbslots[subframe_idx]; + ivas_spar_dec_upmixer_sf( st_ivas, output_f_local, nchan_internal ); + for ( ch = 0; ch < nchan_out; ch++ ) + { + output_f_local[ch] += n_samples_sf; + } + } + + if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC ) + { + ivas_sba_linear_renderer( output_f, *nSamplesRendered, st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hDecoderConfig->output_config, st_ivas->hOutSetup, st_ivas->hoa_dec_mtx ); + } + if ( st_ivas->hDirAC != NULL && hSpar->slots_rendered == hSpar->num_slots ) + { + if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) + { + st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % st_ivas->hDirAC->dirac_md_buffer_length; + } + else + { + st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % st_ivas->hDirAC->dirac_md_buffer_length; + } + } + *nSamplesAvailable = ( hSpar->num_slots - hSpar->slots_rendered ) * slot_size; + + return; +} +#endif diff --git a/lib_dec/ivas_sba_rendering_internal.c b/lib_dec/ivas_sba_rendering_internal.c index a80986b39e..bc9b4cb7cb 100644 --- a/lib_dec/ivas_sba_rendering_internal.c +++ b/lib_dec/ivas_sba_rendering_internal.c @@ -65,6 +65,9 @@ void ivas_sba2mc_cldfb( float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: cldfb imag part */ const int16_t nb_channels_out, /* i : nb of output channels */ const int16_t nb_bands, /* i : nb of CLDFB bands to process */ +#ifdef JBM_TSM_ON_TCS + const int16_t nb_timeslots, /* i : number of time slots to process */ +#endif const float *hoa_dec_mtx /* i : HOA decoding mtx */ ) { @@ -89,7 +92,11 @@ void ivas_sba2mc_cldfb( g = hoa_dec_mtx[SBA_NHARM_HOA3 * n + m]; p_realOut = realOut[n]; p_imagOut = imagOut[n]; +#ifdef JBM_TSM_ON_TCS + for ( iBlock = 0; iBlock < nb_timeslots; iBlock++ ) +#else for ( iBlock = 0; iBlock < MAX_PARAM_SPATIAL_SUBFRAMES; iBlock++ ) +#endif { p_real = RealBuffer[m][iBlock]; p_imag = ImagBuffer[m][iBlock]; @@ -108,7 +115,11 @@ void ivas_sba2mc_cldfb( { p_realOut = realOut[n]; p_imagOut = imagOut[n]; +#ifdef JBM_TSM_ON_TCS + for ( iBlock = 0; iBlock < nb_timeslots; iBlock++ ) +#else for ( iBlock = 0; iBlock < MAX_PARAM_SPATIAL_SUBFRAMES; iBlock++ ) +#endif { p_real = RealBuffer[n][iBlock]; p_imag = ImagBuffer[n][iBlock]; @@ -134,7 +145,12 @@ void ivas_sba2mc_cldfb( void ivas_mc2sba( IVAS_OUTPUT_SETUP hIntSetup, /* i : Format of decoder output */ +#ifdef JBM_TSM_ON_TCS + float *in_buffer_td[], /* i : MC signals (on input) and the HOA3 (on output) */ + float *buffer_td[], /* i/o: MC signals (on input) and the HOA3 (on output) */ +#else float buffer_td[][L_FRAME48k], /* i/o: MC signals (on input) and the HOA3 (on output) */ +#endif const int16_t output_frame, /* i : output frame length per channel */ const int16_t sba_order, /* i : Ambisonic (SBA) order */ const float gain_lfe /* i : gain for LFE, 0 = ignore LFE */ @@ -168,7 +184,11 @@ void ivas_mc2sba( /* Add LFE to omni W with gain*/ for ( k = 0; k < output_frame; k++ ) { +#ifdef JBM_TSM_ON_TCS + buffer_tmp[0][k] += gain_lfe * in_buffer_td[i][k]; +#else buffer_tmp[0][k] += gain_lfe * buffer_td[i][k]; +#endif } } @@ -194,7 +214,11 @@ void ivas_mc2sba( { for ( k = 0; k < output_frame; k++ ) { +#ifdef JBM_TSM_ON_TCS + buffer_tmp[j][k] += gains[j] * in_buffer_td[i][k]; +#else buffer_tmp[j][k] += gains[j] * buffer_td[i][k]; +#endif } } } @@ -279,7 +303,11 @@ int16_t ivas_sba_remapTCs( *-------------------------------------------------------------------------*/ void ivas_ism2sba( - float buffer_td[][L_FRAME48k], /* i/o: TD signal buffers */ +#ifdef JBM_TSM_ON_TCS + float *buffer_td[], /* i/o: TD signal buffers */ +#else + float buffer_td[][L_FRAME48k], /* i/o: TD signal buffers */ +#endif 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 */ @@ -335,6 +363,59 @@ void ivas_ism2sba( return; } +#ifdef JBM_TSM_ON_TCS +/*-------------------------------------------------------------------------* + * ivas_ism2sba() + * + * ISM transformed into SBA in TD domain. + *-------------------------------------------------------------------------*/ + +void ivas_ism2sba_sf( + float *buffer_in[], /* i : TC buffer */ + float *buffer_out[], /* o : TD signal buffers */ + ISM_RENDERER_HANDLE hIsmRendererData, /* i/o: renderer data */ + const int16_t num_objects, /* i : number of objects */ + const int16_t n_samples_to_render, /* i : output frame length per channel */ + const int16_t offset, /* i : offset for the interpolatr */ + const int16_t sba_order /* i : Ambisonic (SBA) order */ +) +{ + int16_t i, j, k; + float g1, *g2, *tc, *out, gain, prev_gain; + 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 ); + } + + for ( i = 0; i < num_objects; i++ ) + { + for ( j = 0; j < sba_num_chans; j++ ) + { + g2 = hIsmRendererData->interpolator + offset; + g1 = 1 - *g2; + tc = buffer_in[i] + offset; + out = buffer_out[j]; + gain = hIsmRendererData->gains[i][j]; + prev_gain = hIsmRendererData->prev_gains[i][j]; + for ( k = 0; k < n_samples_to_render; k++ ) + { + *( out++ ) += ( ( *( g2++ ) ) * gain + g1 * prev_gain ) * ( *( tc++ ) ); + g1 = 1.0f - *g2; + } + } + } + + return; +} +#endif /*-------------------------------------------------------------------* * ivas_sba_upmixer_renderer() @@ -348,6 +429,7 @@ void ivas_sba_upmixer_renderer( const int16_t output_frame /* i : output frame length */ ) { + int16_t i, nchan_internal; float temp; @@ -369,10 +451,17 @@ void ivas_sba_upmixer_renderer( /* Upmixer + Renderer */ ivas_spar_dec_upmixer( st_ivas, output, nchan_internal, output_frame ); - if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC ) - { +#ifdef JBM_TSM_ON_TCS + float *output_f[MAX_OUTPUT_CHANNELS]; + int16_t ch; + for (ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++) + { + output_f[ch] = output[ch]; + } + ivas_sba_linear_renderer( output_f, output_frame, st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hDecoderConfig->output_config, st_ivas->hOutSetup, st_ivas->hoa_dec_mtx ); +#else ivas_sba_linear_renderer( output, output_frame, st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hDecoderConfig->output_config, st_ivas->hOutSetup, st_ivas->hoa_dec_mtx ); - } +#endif pop_wmops(); @@ -387,7 +476,11 @@ void ivas_sba_upmixer_renderer( *-------------------------------------------------------------------*/ static void ivas_sba_mtx_mult( - float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ +#ifdef JBM_TSM_ON_TCS + float *output_f[], /* i/o: synthesized core-corder transport channels/DirAC output */ +#else + float output_f[][L_FRAME48k], /* i/o: synthesized core-corder transport channels/DirAC output */ +#endif const int16_t output_frame, /* i : output frame length per channel */ const int16_t nchan_in, /* i : Number of ambisonic channels */ const IVAS_OUTPUT_SETUP output_setup, /* i : Output configuration */ @@ -447,7 +540,11 @@ static void ivas_sba_mtx_mult( *-------------------------------------------------------------------*/ ivas_error ivas_sba_linear_renderer( - float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ +#ifdef JBM_TSM_ON_TCS + float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ +#else + float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ +#endif const int16_t output_frame, /* i : output frame length per channel */ const int16_t nchan_in, /* i : number of input ambisonics channels */ const AUDIO_CONFIG output_config, /* i : output audio configuration */ diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index 01e4db2ed4..4f74ae0c7a 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -173,6 +173,34 @@ ivas_error ivas_spar_dec_open( ivas_output_init( &( st_ivas->hTransSetup ), st_ivas->transport_config ); +#ifdef JBM_TSM_ON_TCS + set_s( hSpar->subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS ); + set_s( hSpar->subframe_nbslots, JBM_CLDFB_SLOTS_IN_SUBFRAME, DEFAULT_JBM_SUBFRAMES_5MS ); + hSpar->nb_subframes = DEFAULT_JBM_SUBFRAMES_5MS; + hSpar->subframes_rendered = 0; + hSpar->slots_rendered = 0; + hSpar->num_slots = DEFAULT_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME; + /* init render timeslot mapping */ + { + int16_t map_idx; + set_s( hSpar->render_to_md_slot_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME ); + for ( map_idx = 0; map_idx < DEFAULT_JBM_CLDFB_TIMESLOTS; map_idx++ ) + { + hSpar->render_to_md_slot_map[map_idx] = map_idx; + } + } + /* allocate transport channels*/ + if ( st_ivas->hDecoderConfig->voip_active == 1 && st_ivas->hTcBuffer == NULL && 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_to_allocate = num_channels_internal; /*st_ivas->nchan_transport;*/ + if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, ivas_jbm_dec_get_num_tc_channels( st_ivas ), nchan_to_allocate,nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif + st_ivas->hSpar = hSpar; return error; @@ -891,19 +919,306 @@ static void ivas_spar_get_skip_mat( return; } +#ifdef JBM_TSM_ON_TCS +void ivas_spar_dec_agc_pca( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + float output[][L_FRAME48k], /* i/o: input/output audio channels */ + const int16_t output_frame /* i : output frame length */ +) + +{ + + int16_t nchan_transport; + int16_t num_in_ingest; + DECODER_CONFIG_HANDLE hDecoderConfig; + SPAR_DEC_HANDLE hSpar; + + push_wmops( "ivas_spar_dec_agc_pca" ); + + hSpar = st_ivas->hSpar; + hDecoderConfig = st_ivas->hDecoderConfig; + nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport; + + if ( st_ivas->nchan_transport >= 3 ) + { + float temp; + int16_t i; + /*convert WYZX downmix to WYXZ*/ + for ( i = 0; i < output_frame; i++ ) + { + temp = output[2][i]; + output[2][i] = output[3][i]; + output[3][i] = temp; + } + } + + if ( hSpar->hMdDec->td_decorr_flag ) + { + num_in_ingest = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order ); + } + else + { + num_in_ingest = nchan_transport; + } + /*---------------------------------------------------------------------* + * AGC + *---------------------------------------------------------------------*/ + + ivas_agc_dec_process( hSpar->hAgcDec, output, output, nchan_transport, output_frame ); +#ifdef DEBUG_SBA_AUDIO_DUMP + /* Dump audio signal after ivas_agc_dec_process */ + ivas_spar_dump_signal_wav( output_frame, NULL, output, st_ivas->nchan_transport, spar_foa_dec_wav[1], "ivas_agc_dec_process()" ); +#endif +#ifdef DEBUG_MODE_JBM + { + int k; + dbgwritewav( output_frame, NULL, output, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, "res/spar_dec_agc_process.wav" ); + for ( k = 0; k < st_ivas->nchan_transport; k++ ) + { + char filename[100]; + sprintf( filename, "res/spar_dec_agc_process_%d.dat", k ); + dbgwrite( output[k], sizeof( float ), output_frame, 1, filename ); + } + } +#endif + if ( hSpar->hPCA != NULL ) + { + ivas_pca_dec( hSpar->hPCA, output_frame, num_in_ingest, hDecoderConfig->ivas_total_brate, hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, output ); +#ifdef DEBUG_SBA_AUDIO_DUMP + /* Dump audio signal after ivas_pca_dec */ + ivas_spar_dump_signal_wav( output_frame, NULL, output, num_in_ingest, spar_foa_dec_wav[2], "ivas_pca_dec()" ); +#endif +#ifdef DEBUG_MODE_JBM + { + int k; + dbgwritewav( output_frame, NULL, output, num_in_ingest, st_ivas->hDecoderConfig->output_Fs, "res/spar_pca_dec.wav" ); + for ( k = 0; k < num_in_ingest; k++ ) + { + char filename[100]; + sprintf( filename, "res/spar_pca_dec_%d.dat", k ); + dbgwrite( output[k], sizeof( float ), output_frame, 1, filename ); + } + } +#endif + } + pop_wmops(); + return; +} +void ivas_spar_dec_set_render_map( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + int16_t nCldfbTs ) +{ + SPAR_DEC_HANDLE hSpar; + + hSpar = st_ivas->hSpar; +#ifdef DEBUGGING + assert( hSpar ); +#endif + + /* adapt subframes */ + hSpar->num_slots = nCldfbTs; + hSpar->slots_rendered = 0; + hSpar->subframes_rendered = 0; + set_s( hSpar->render_to_md_slot_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME ); + ivas_jbm_dec_get_adapted_subframes( nCldfbTs, hSpar->subframe_nbslots, &hSpar->nb_subframes ); + ivas_jbm_dec_get_md_map( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbTs, 1, 0, DEFAULT_JBM_CLDFB_TIMESLOTS, hSpar->render_to_md_slot_map ); + + return; +} /*-------------------------------------------------------------------* * ivas_spar_dec_upmixer() * * IVAS SPAR upmixer *-------------------------------------------------------------------*/ +void ivas_spar_dec_set_render_params( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const int16_t n_cldfb_slots /* i : number of cldfb slots in this frame */ +) +{ + SPAR_DEC_HANDLE hSpar; + int16_t nchan_transport; + int16_t num_bands_out; + + hSpar = st_ivas->hSpar; + /*---------------------------------------------------------------------* + * Gen umx mat + *---------------------------------------------------------------------*/ + nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport; + num_bands_out = hSpar->hFbMixer->pFb->filterbank_num_bands; + ivas_spar_dec_gen_umx_mat( hSpar->hMdDec, nchan_transport, num_bands_out, st_ivas->bfi ); + + ivas_spar_dec_set_render_map( st_ivas, n_cldfb_slots ); + + return; +} + +void ivas_spar_dec_digest_tc( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const int16_t nchan_transport, /* i : number of transport channels */ + const int16_t nCldfbSlots, /* i : number of CLDFB slots */ + const int16_t nSamplesForRendering /* i : number of samples provided */ +) +{ + SPAR_DEC_HANDLE hSpar; + + hSpar = st_ivas->hSpar; + if ( hSpar->hMdDec->td_decorr_flag && !( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) + { + float Pcm_tmp[MAX_SPAR_INTERNAL_CHANNELS][L_FRAME48k]; + float *pPcm_tmp[MAX_SPAR_INTERNAL_CHANNELS]; + float *p_tc[MAX_SPAR_INTERNAL_CHANNELS]; + int16_t nchan_internal, ch, sba_order_internal; + int16_t nSamplesLeftForTD, default_frame; + /* TD decorrelator */ + default_frame = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); + nSamplesLeftForTD = nSamplesForRendering; + sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); + nchan_internal = ivas_sba_get_nchan_metadata( sba_order_internal ); + for ( ch = 0; ch < nchan_internal; ch++ ) + { + pPcm_tmp[ch] = Pcm_tmp[ch]; + p_tc[ch] = st_ivas->hTcBuffer->tc[ch]; + } + + while ( nSamplesLeftForTD ) + { + int16_t nSamplesToDecorr = min( nSamplesLeftForTD, default_frame ); + ivas_td_decorr_process( hSpar->hTdDecorr, p_tc, pPcm_tmp, nSamplesToDecorr ); + for ( ch = 0; ch < nchan_internal - nchan_transport; ch++ ) + { + mvr2r( pPcm_tmp[hSpar->hTdDecorr->num_apd_outputs - 1 - ch], p_tc[nchan_internal - 1 - ch], nSamplesToDecorr ); + } + for ( ch = 0; ch < nchan_internal; ch++ ) + { + p_tc[ch] += nSamplesToDecorr; + } + nSamplesLeftForTD -= nSamplesToDecorr; + } +#ifdef DEBUG_MODE_JBM + dbgwritewav( nSamplesForRendering, st_ivas->tc, NULL, nchan_internal, st_ivas->hDecoderConfig->output_Fs, "res/spar_dec_td_decorr.wav" ); +#endif + } + + ivas_spar_dec_set_render_params( st_ivas, nCldfbSlots ); + + + return; +} + +void ivas_spar_dec_upmixer( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + float output[][L_FRAME48k], /* i/o: input/output audio channels */ + const int16_t nchan_internal, /* i : number of internal channels */ + const int16_t output_frame /* i : output frame length */ +) +{ + SPAR_DEC_HANDLE hSpar; + int16_t nchan_transport, nchan_out; + int16_t subframe_idx, n, i; + int16_t n_samples_sf; + float *output_f_local[MAX_OUTPUT_CHANNELS]; + float Pcm_tmp[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + float *pPcm_tmp[MAX_OUTPUT_CHANNELS]; + + hSpar = st_ivas->hSpar; + nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport; + nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; + n_samples_sf = JBM_CLDFB_SLOTS_IN_SUBFRAME * NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); + for ( n = 0; n < MAX_OUTPUT_CHANNELS; n++ ) + { + output_f_local[n] = &output[n][0]; + } + for ( n = 0; n < nchan_internal; n++ ) + { + st_ivas->hTcBuffer->tc[n] = output[n]; + } + + /*---------------------------------------------------------------------* + * TD decorrelation + *---------------------------------------------------------------------*/ + for ( i = 0; i < nchan_internal; i++ ) + { + pPcm_tmp[i] = Pcm_tmp[i]; + } + if ( hSpar->hMdDec->td_decorr_flag ) + { + ivas_td_decorr_process( hSpar->hTdDecorr, st_ivas->hTcBuffer->tc, pPcm_tmp, output_frame ); + for ( i = 0; i < nchan_internal - nchan_transport; i++ ) + { + mvr2r( pPcm_tmp[hSpar->hTdDecorr->num_apd_outputs - 1 - i], st_ivas->hTcBuffer->tc[nchan_internal - 1 - i], output_frame ); + } +#ifdef DEBUG_MODE_JBM + { + int k; + dbgwritewav( output_frame, st_ivas->tc, output, nchan_internal, st_ivas->hDecoderConfig->output_Fs, "res/spar_dec_td_decorr.wav" ); + for ( k = 0; k < nchan_internal; k++ ) + { + char filename[100]; + sprintf( filename, "res/spar_dec__tdcorr_%d.dat", k ); + dbgwrite( st_ivas->tc[k], sizeof( float ), output_frame, 1, filename ); + } + } +#endif + } + + + ivas_spar_dec_set_render_params( st_ivas, DEFAULT_JBM_CLDFB_TIMESLOTS ); + + if ( st_ivas->hDirAC != 0 ) + { + ivas_dirac_dec_set_md_map( st_ivas, DEFAULT_JBM_CLDFB_TIMESLOTS ); + } + + for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) + { + ivas_spar_dec_upmixer_sf( st_ivas, output_f_local, nchan_internal ); + for ( n = 0; n < nchan_out; n++ ) + { + output_f_local[n] += n_samples_sf; + } + } + for ( n = 0; n < nchan_internal; n++ ) + { + st_ivas->hTcBuffer->tc[n] = NULL; + } + if ( st_ivas->hDirAC != 0 ) + { + if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) + { + st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % st_ivas->hDirAC->dirac_md_buffer_length; + } + else + { + st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % st_ivas->hDirAC->dirac_md_buffer_length; + } + } + return; +} +#endif + + +#ifdef JBM_TSM_ON_TCS +/*-------------------------------------------------------------------* + * ivas_spar_dec_upmixer_sf() + * + * IVAS SPAR upmixer + *-------------------------------------------------------------------*/ +void ivas_spar_dec_upmixer_sf( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + float *output[], /* o : output audio channels */ + const int16_t nchan_internal /* i : number of internal channels */ +) +#else void ivas_spar_dec_upmixer( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ float output[][L_FRAME48k], /* i/o: input/output audio channels */ const int16_t nchan_internal, /* i : number of internal channels */ const int16_t output_frame /* i : output frame length */ ) +#endif { int16_t cldfb_band, num_cldfb_bands, numch_in, numch_out; float *cldfb_in_ts_re[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX]; @@ -911,6 +1226,11 @@ void ivas_spar_dec_upmixer( int16_t i, b, ts, out_ch, in_ch; int16_t num_spar_bands, spar_band, nchan_transport; int16_t num_in_ingest, num_bands_out, split_band; +#ifdef JBM_TSM_ON_TCS + int16_t output_frame, slot_size, slot_idx_start, slot_idx_start_cldfb; + float *p_tc[MAX_OUTPUT_CHANNELS]; + int16_t md_idx; +#endif float Pcm_tmp[MAX_OUTPUT_CHANNELS][L_FRAME48k]; int16_t numch_out_dirac; float *pPcm_tmp[MAX_OUTPUT_CHANNELS]; @@ -919,7 +1239,11 @@ void ivas_spar_dec_upmixer( DECODER_CONFIG_HANDLE hDecoderConfig; SPAR_DEC_HANDLE hSpar; +#ifdef JBM_TSM_ON_TCS + push_wmops( "ivas_spar_dec_upmixer_sf" ); +#else push_wmops( "ivas_spar_dec_upmixer" ); +#endif hSpar = st_ivas->hSpar; hDecoderConfig = st_ivas->hDecoderConfig; @@ -930,6 +1254,17 @@ void ivas_spar_dec_upmixer( numch_in = hSpar->hFbMixer->fb_cfg->num_in_chans; numch_out = hSpar->hFbMixer->fb_cfg->num_out_chans; +#ifdef JBM_TSM_ON_TCS + slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); + output_frame = hSpar->subframe_nbslots[hSpar->subframes_rendered] * slot_size; + slot_idx_start = hSpar->slots_rendered; + slot_idx_start_cldfb = 0; + for ( i = 0; i < nchan_internal; i++ ) + { + p_tc[i] = st_ivas->hTcBuffer->tc[i] + slot_idx_start * slot_size; + } +#endif + #ifdef DEBUG_SPAR_BYPASS_EVS_CODEC /* by-pass core-coder */ /*write the core coder output to a file for debugging*/ @@ -967,17 +1302,22 @@ void ivas_spar_dec_upmixer( } #endif +#ifndef JBM_TSM_ON_TCS /*---------------------------------------------------------------------* * AGC *---------------------------------------------------------------------*/ ivas_agc_dec_process( hSpar->hAgcDec, output, output, nchan_transport, output_frame ); + #ifdef DEBUG_SBA_AUDIO_DUMP /* Dump audio signal after ivas_agc_dec_process */ ivas_spar_dump_signal_wav( output_frame, NULL, output, st_ivas->nchan_transport, spar_foa_dec_wav[1], "ivas_agc_dec_process()" ); #endif - +#ifdef DEBUG_MODE_JBM + dbgwritewav( output_frame, NULL, output, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, "res/spar_dec_agc_process.wav" ); +#endif +#endif /*---------------------------------------------------------------------* * TD Decorr and pcm ingest *---------------------------------------------------------------------*/ @@ -1003,16 +1343,30 @@ void ivas_spar_dec_upmixer( hSpar->pca_ingest_channels = num_in_ingest; #endif +#ifndef JBM_TSM_ON_TCS /* will already happen in the TC decoding */ if ( hSpar->hPCA != NULL ) { ivas_pca_dec( hSpar->hPCA, output_frame, num_in_ingest, hDecoderConfig->ivas_total_brate, hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, output ); #ifdef DEBUG_SBA_AUDIO_DUMP /* Dump audio signal after ivas_pca_dec */ ivas_spar_dump_signal_wav( output_frame, NULL, output, num_in_ingest, spar_foa_dec_wav[2], "ivas_pca_dec()" ); +#endif +#ifdef DEBUG_MODE_JBM + dbgwritewav( output_frame, NULL, output, num_in_ingest, st_ivas->hDecoderConfig->output_Fs, "res/spar_pca_dec.wav" ); + { + int k; + for ( k = 0; k < num_in_ingest; k++ ) + { + char filename[100]; + sprintf( filename, "res/spar_pca_dec_%d.dat", k ); + dbgwrite( output[k], sizeof( float ), output_frame, 1, filename ); + } + } #endif } +#endif - +#ifndef JBM_TSM_ON_TCS /*---------------------------------------------------------------------* * TD decorrelation *---------------------------------------------------------------------*/ @@ -1020,13 +1374,24 @@ void ivas_spar_dec_upmixer( if ( hSpar->hMdDec->td_decorr_flag ) { ivas_td_decorr_process( hSpar->hTdDecorr, output, pPcm_tmp, output_frame ); - for ( i = 0; i < nchan_internal - nchan_transport; i++ ) { mvr2r( pPcm_tmp[hSpar->hTdDecorr->num_apd_outputs - 1 - i], output[nchan_internal - 1 - i], output_frame ); } +#ifdef DEBUG_MODE_JBM + dbgwritewav( output_frame, NULL, output, nchan_internal, st_ivas->hDecoderConfig->output_Fs, "res/spar_dec_td_decorr.wav" ); + { + int k; + for ( k = 0; k < nchan_internal; k++ ) + { + char filename[100]; + sprintf( filename, "res/spar_dec__tdcorr_%d.dat", k ); + dbgwrite( output[k], sizeof( float ), output_frame, 1, filename ); + } + } +#endif } - +#endif hSpar->hFbMixer->fb_cfg->num_in_chans = num_in_ingest; @@ -1059,12 +1424,13 @@ void ivas_spar_dec_upmixer( } } +#ifndef JBM_TSM_ON_TCS /*---------------------------------------------------------------------* * Gen umx mat *---------------------------------------------------------------------*/ ivas_spar_dec_gen_umx_mat( hSpar->hMdDec, nchan_transport, num_bands_out, st_ivas->bfi ); - +#endif /*---------------------------------------------------------------------* * CLDFB Processing and Synthesis @@ -1078,15 +1444,55 @@ void ivas_spar_dec_upmixer( numch_out_dirac = hDecoderConfig->nchan_out; +#ifdef DEBUG_SBA_AUDIO_DUMP + /* Dump audio signal after ivas_agc_dec_process */ +#ifdef JBM_TSM_ON_TCS + ivas_spar_dump_signal_wav( output_frame, p_tc, NULL, numch_in, spar_foa_dec_wav[4], "ivas_spar_upmixer()" ); +#else + ivas_spar_dump_signal_wav( output_frame, NULL, output, numch_in, spar_foa_dec_wav[4], "ivas_spar_upmixer()" ); +#endif +#endif +#ifdef DEBUG_MODE_JBM + { + + int k; +#ifdef JBM_TSM_ON_TCS + dbgwritewav( output_frame, p_tc, output, numch_in, st_ivas->hDecoderConfig->output_Fs, "res/spar_cldfb_input.wav" ); +#else + dbgwritewav( output_frame, NULL, output, numch_in, st_ivas->hDecoderConfig->output_Fs, "res/spar_cldfb_input.wav" ); +#endif + for ( k = 0; k < numch_in; k++ ) + { + char filename[100]; + sprintf( filename, "res/spar_upmixer_in_%d.dat", k ); +#ifdef JBM_TSM_ON_TCS + dbgwrite( p_tc[k], sizeof( float ), output_frame, 1, filename ); +#else + dbgwrite( output[k], sizeof( float ), output_frame, 1, filename ); +#endif + } + } +#endif + +#ifndef JBM_TSM_ON_TCS for ( int16_t i_sf = 0; i_sf < MAX_PARAM_SPATIAL_SUBFRAMES; i_sf++ ) { +#endif /* CLDFB analysis of incoming frame */ for ( in_ch = 0; in_ch < numch_in; in_ch++ ) { - for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) +#ifdef JBM_TSM_ON_TCS + for ( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) +#else + for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) +#endif { cldfbAnalysis_ts( - &output[in_ch][( ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES ) * num_cldfb_bands], +#ifdef JBM_TSM_ON_TCS + &p_tc[in_ch][ts * num_cldfb_bands], +#else + &output[in_ch][( ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES ) * num_cldfb_bands], +#endif cldfb_in_ts_re[in_ch][ts], cldfb_in_ts_im[in_ch][ts], num_cldfb_bands, @@ -1094,11 +1500,19 @@ void ivas_spar_dec_upmixer( } } - for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) +#ifdef JBM_TSM_ON_TCS + for ( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) +#else + for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) +#endif { - /* determine SPAR parameters for this time slots */ - ivas_spar_get_parameters( hSpar, hDecoderConfig, ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES, numch_out, numch_in, num_spar_bands, mixer_mat ); - +#ifdef JBM_TSM_ON_TCS + md_idx = hSpar->render_to_md_slot_map[ts + slot_idx_start]; + ivas_spar_get_parameters( hSpar, hDecoderConfig, md_idx, numch_out, numch_in, num_spar_bands, mixer_mat ); +#else + /* determine SPAR parameters for this time slots */ + ivas_spar_get_parameters( hSpar, hDecoderConfig, ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES, numch_out, numch_in, num_spar_bands, mixer_mat ); +#endif for ( cldfb_band = 0; cldfb_band < num_cldfb_bands; cldfb_band++ ) { float out_re[IVAS_SPAR_MAX_CH]; @@ -1144,11 +1558,43 @@ void ivas_spar_dec_upmixer( cldfb_in_ts_im[out_ch][ts][cldfb_band] = out_im[out_ch]; } } +#ifdef JBM_TSM_ON_TCS + if ( ( ( slot_idx_start + ts + 1 ) == hSpar->num_slots ) || ( ( md_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME ) != ( hSpar->render_to_md_slot_map[ts + slot_idx_start + 1] / JBM_CLDFB_SLOTS_IN_SUBFRAME ) ) ) + { + /* we have crossed an unadapted parameter sf border, update previous mixing matrices */ + int16_t md_sf = md_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME; + split_band = SPAR_DIRAC_SPLIT_START_BAND; + if ( split_band < IVAS_MAX_NUM_BANDS ) + { + mvr2r( hSpar->hMdDec->mixer_mat_prev[1][0][0], hSpar->hMdDec->mixer_mat_prev[0][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); + mvr2r( hSpar->hMdDec->mixer_mat_prev[2][0][0], hSpar->hMdDec->mixer_mat_prev[1][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); + mvr2r( hSpar->hMdDec->mixer_mat_prev[3][0][0], hSpar->hMdDec->mixer_mat_prev[2][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); + mvr2r( hSpar->hMdDec->mixer_mat_prev[4][0][0], hSpar->hMdDec->mixer_mat_prev[3][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); + + for ( out_ch = 0; out_ch < numch_out; out_ch++ ) + { + for ( in_ch = 0; in_ch < numch_in; in_ch++ ) + { + for ( b = 0; b < num_spar_bands; b++ ) + { + hSpar->hMdDec->mixer_mat_prev[4][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat[out_ch][in_ch][b + md_sf * IVAS_MAX_NUM_BANDS]; + } + } + } + hSpar->i_subframe++; + hSpar->i_subframe = min( hSpar->i_subframe, MAX_PARAM_SPATIAL_SUBFRAMES ); + } + } +#endif } if ( hDecoderConfig->output_config != AUDIO_CONFIG_FOA && hDecoderConfig->output_config != AUDIO_CONFIG_STEREO && hDecoderConfig->output_config != AUDIO_CONFIG_MONO ) { - ivas_dirac_dec( st_ivas, output, nchan_internal, cldfb_in_ts_re, cldfb_in_ts_im, i_sf ); +#ifdef JBM_TSM_ON_TCS + ivas_dirac_dec_render_sf( st_ivas, output, nchan_internal, cldfb_in_ts_re, cldfb_in_ts_im ); +#else + ivas_dirac_dec( st_ivas, output, nchan_internal, cldfb_in_ts_re, cldfb_in_ts_im, i_sf ); +#endif } if ( st_ivas->hDirAC != NULL ) @@ -1162,8 +1608,11 @@ void ivas_spar_dec_upmixer( { if ( ( st_ivas->hOutSetup.num_lfe > 0 ) && ( st_ivas->hOutSetup.index_lfe[idx_lfe] == ch ) ) { - set_zero( &( output[ch][i_sf * MAX_PARAM_SPATIAL_SUBFRAMES * num_cldfb_bands] ), MAX_PARAM_SPATIAL_SUBFRAMES * num_cldfb_bands ); - +#ifdef JBM_TSM_ON_TCS + set_zero( output[ch], hSpar->subframe_nbslots[hSpar->subframes_rendered] * num_cldfb_bands ); +#else + set_zero( &( output[ch][i_sf * MAX_PARAM_SPATIAL_SUBFRAMES * num_cldfb_bands] ), MAX_PARAM_SPATIAL_SUBFRAMES * num_cldfb_bands ); +#endif if ( idx_lfe < ( st_ivas->hDirAC->hOutSetup.num_lfe - 1 ) ) { idx_lfe++; @@ -1173,12 +1622,20 @@ void ivas_spar_dec_upmixer( { if ( hDecoderConfig->output_config == AUDIO_CONFIG_FOA || !( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL || st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM ) ) { - for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) +#ifdef JBM_TSM_ON_TCS + for ( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) +#else + for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) +#endif { cldfbSynthesis( &cldfb_in_ts_re[idx_in][ts], &cldfb_in_ts_im[idx_in][ts], - &output[ch][( ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES ) * num_cldfb_bands], +#ifdef JBM_TSM_ON_TCS + &output[ch][ts * num_cldfb_bands], +#else + &output[ch][( ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES ) * num_cldfb_bands], +#endif num_cldfb_bands, st_ivas->cldfbSynDec[idx_in] ); } @@ -1195,12 +1652,20 @@ void ivas_spar_dec_upmixer( /* CLDFB to time synthesis (overwrite mixer output) */ for ( out_ch = 0; out_ch < numch_out_dirac; out_ch++ ) { - for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) +#ifdef JBM_TSM_ON_TCS + for ( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) +#else + for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) +#endif { cldfbSynthesis( &cldfb_in_ts_re[out_ch][ts], &cldfb_in_ts_im[out_ch][ts], - &output[out_ch][( ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES ) * num_cldfb_bands], +#ifdef JBM_TSM_ON_TCS + &output[out_ch][ts * num_cldfb_bands], +#else + &output[out_ch][( ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES ) * num_cldfb_bands], +#endif num_cldfb_bands, st_ivas->cldfbSynDec[out_ch] ); } @@ -1214,6 +1679,7 @@ void ivas_spar_dec_upmixer( ivas_spar_dump_signal_wav( output_frame, NULL, output, hSpar->numOutChannels, spar_foa_dec_wav[3], "cldfbSynthesis()" ); #endif +#ifndef JBM_TSM_ON_TCS split_band = SPAR_DIRAC_SPLIT_START_BAND; if ( split_band < IVAS_MAX_NUM_BANDS ) { @@ -1235,8 +1701,14 @@ void ivas_spar_dec_upmixer( } } } +#endif +#ifndef JBM_TSM_ON_TCS } - +#endif +#ifdef JBM_TSM_ON_TCS + hSpar->slots_rendered += hSpar->subframe_nbslots[hSpar->subframes_rendered]; + hSpar->subframes_rendered++; +#endif pop_wmops(); return; diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec.c index 3b47d6500e..7f5d51f582 100644 --- a/lib_dec/ivas_spar_md_dec.c +++ b/lib_dec/ivas_spar_md_dec.c @@ -2661,7 +2661,11 @@ void ivas_spar_to_dirac( qmf_band_start = band_grouping[band]; qmf_band_end = band_grouping[band + 1]; +#ifdef JBM_TSM_ON_TCS + for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) +#else for ( block = 0; block < hDirAC->nb_subframes; block++ ) +#endif { int16_t ts_start, ts_end, ts; @@ -2683,6 +2687,7 @@ void ivas_spar_to_dirac( hDirAC->energy_ratio1[block][b] = en_ratio; tmp_write_idx_band = tmp_write_idx_param_band; + /* TODO: JBM */ if ( hDirAC->hConfig->dec_param_estim == FALSE ) { hDirAC->elevation[tmp_write_idx_band][b] = ele_dith; diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 4a17c75dda..276959a03b 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -435,7 +435,11 @@ typedef struct param_ism_rendering float *proto_matrix; float *interpolator; float mixing_matrix_lin_old[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX]; - +#ifdef JBM_TSM_ON_TCS + float mixing_matrix_lin[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX]; + float *Cldfb_RealBuffer_tc; + float *Cldfb_ImagBuffer_tc; +#endif } PARAM_ISM_RENDERING_DATA, *PARAM_ISM_RENDERING_HANDLE; @@ -571,6 +575,10 @@ typedef struct dirac_output_synthesis_cov_state_structure float *cy_old[CLDFB_NO_CHANNELS_MAX]; float *mixing_matrix_old[CLDFB_NO_CHANNELS_MAX]; float *mixing_matrix_res_old[CLDFB_NO_CHANNELS_MAX]; +#ifdef JBM_TSM_ON_TCS + float *mixing_matrix[CLDFB_NO_CHANNELS_MAX]; + float *mixing_matrix_res[CLDFB_NO_CHANNELS_MAX]; +#endif } DIRAC_OUTPUT_SYNTHESIS_COV_STATE; @@ -626,7 +634,18 @@ typedef struct ivas_dirac_dec_data_structure IVAS_OUTPUT_SETUP hOutSetup; int16_t slot_size; +#ifdef JBM_TSM_ON_TCS + int16_t subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; + int16_t subframes_rendered; + int16_t slots_rendered; + int16_t num_slots; + int16_t render_to_md_slot_map[MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME]; +#ifdef JBM_DIRAC_DEBUG_BE + int16_t voip_active; +#endif +#else int16_t subframe_nbslots; +#endif int16_t nb_subframes; int16_t num_freq_bands; @@ -734,7 +753,17 @@ typedef struct ivas_param_mc_dec_data_structure { int16_t slot_size; +#ifdef JBM_TSM_ON_TCS + float *Cldfb_RealBuffer_tc; + float *Cldfb_ImagBuffer_tc; + int16_t subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; + int16_t nb_subframes; + int16_t subframes_rendered; + int16_t slots_rendered; + int16_t num_slots; +#else int16_t subframe_nbslots; +#endif int16_t num_freq_bands; int16_t num_param_bands_synth; @@ -858,6 +887,14 @@ typedef struct ivas_spar_dec_lib_t int16_t numOutChannels; int16_t pca_ingest_channels; #endif +#ifdef JBM_TSM_ON_TCS + int16_t subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; + int16_t render_to_md_slot_map[MAX_JBM_CLDFB_TIMESLOTS]; + int16_t nb_subframes; + int16_t subframes_rendered; + int16_t slots_rendered; + int16_t num_slots; +#endif } SPAR_DEC_DATA, *SPAR_DEC_HANDLE; @@ -1027,7 +1064,12 @@ typedef struct vbap_data_structure typedef struct renderer_struct { float prev_gains[MAX_CICP_CHANNELS - 1][MAX_OUTPUT_CHANNELS]; +#ifdef JBM_TSM_ON_TCS + float *interpolator; + float gains[MAX_CICP_CHANNELS - 1][MAX_OUTPUT_CHANNELS]; +#else float interpolator[L_FRAME48k]; +#endif } ISM_RENDERER_DATA, *ISM_RENDERER_HANDLE; @@ -1148,9 +1190,35 @@ typedef struct decoder_config_structure #ifdef DEBUGGING int16_t force_rend; /* forced TD/CLDFB binaural renderer (for ISM and MC) */ #endif +#ifdef JBM_TSM_ON_TCS + int16_t voip_active; +#endif } DECODER_CONFIG, *DECODER_CONFIG_HANDLE; + +#ifdef JBM_TSM_ON_TCS +typedef struct decoder_tc_buffer_structure +{ + float *tc_buffer; /* the buffer itself */ + float *tc[MAX_TRANSPORT_CHANNELS]; /* 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 */ + int16_t n_samples_flushed; + int16_t subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; + int16_t nb_subframes; + int16_t subframes_rendered; + int16_t slots_rendered; + int16_t num_slots; + int16_t n_samples_discard; /* number of samples to discard from the beginning of the output */ +} DECODER_TC_BUFFER, *DECODER_TC_BUFFER_HANDLE; +#endif /*----------------------------------------------------------------------------------* * * Main IVAS decoder structure @@ -1244,6 +1312,10 @@ typedef struct Decoder_Struct int16_t ism_extmeta_active; /* Extended metadata active in decoder */ int16_t ism_extmeta_cnt; /* Change frame counter for extended metadata */ + +#ifdef JBM_TSM_ON_TCS + DECODER_TC_BUFFER_HANDLE hTcBuffer; +#endif } Decoder_Struct; /* clang-format on */ diff --git a/lib_dec/jbm_jb4sb.h b/lib_dec/jbm_jb4sb.h index 54b873b006..a2d85eddb6 100644 --- a/lib_dec/jbm_jb4sb.h +++ b/lib_dec/jbm_jb4sb.h @@ -78,6 +78,14 @@ struct JB4_DATAUNIT int16_t nextCoderType; }; +#ifdef JBM_TSM_ON_TCS +typedef enum +{ + JBM_RENDERER_NONE, + JBM_RENDERER_IVAS, +} JBM_RENDERER_TYPE; +#endif + typedef struct JB4_DATAUNIT *JB4_DATAUNIT_HANDLE; diff --git a/lib_dec/jbm_pcmdsp_apa.c b/lib_dec/jbm_pcmdsp_apa.c index c816a9d9c8..61b3256d58 100644 --- a/lib_dec/jbm_pcmdsp_apa.c +++ b/lib_dec/jbm_pcmdsp_apa.c @@ -66,7 +66,11 @@ struct apa_state_t { /* output buffer */ +#ifdef JBM_TSM_ON_TCS + float *buf_out; +#else int16_t *buf_out; +#endif uint16_t buf_out_capacity; uint16_t l_buf_out; @@ -86,6 +90,14 @@ struct apa_state_t /* total number of processed input samples since apa_reset() */ uint32_t l_in_total; +#ifdef JBM_TSM_ON_TCS + /* time resolution in samples of the IVAS renderer*/ + uint16_t l_ts; + + /* samples already available in the renderer buffer */ + uint16_t l_r_buf; +#endif + /* sum of inserted/removed samples since last apa_set_scale() */ int32_t diffSinceSetScale; /* number of input frames since last apa_set_scale() */ @@ -123,6 +135,17 @@ static float apa_corrEnergy2dB( float energy, uint16_t corr_len ); static float apa_getQualityIncreaseForLowEnergy( float energydB ); +#ifdef JBM_TSM_ON_TCS +static bool logarithmic_search( const apa_state_t *ps, const float *signal, int16_t s_start, uint16_t inlen, uint16_t offset, uint16_t fixed_pos, uint16_t corr_len, uint16_t wss, uint16_t css, int16_t *synchpos ); + +static bool find_synch( apa_state_t *ps, const float *in, uint16_t l_in, int16_t s_start, uint16_t s_len, int16_t fixed_pos, uint16_t corr_len, uint16_t offset, float *energy, float *quality, int16_t *synch_pos ); + +static bool copy_frm( apa_state_t *ps, const float frm_in[], float frm_out[], uint16_t *l_frm_out ); + +static bool shrink_frm( apa_state_t *ps, const float frm_in[], uint16_t maxScaling, float frm_out[], uint16_t *l_frm_out ); + +static bool extend_frm( apa_state_t *ps, const float frm_in[], float frm_out[], uint16_t *l_frm_out ); +#else static bool logarithmic_search( const apa_state_t *ps, const int16_t *signal, int16_t s_start, uint16_t inlen, uint16_t offset, uint16_t fixed_pos, uint16_t corr_len, uint16_t wss, uint16_t css, int16_t *synchpos ); static bool find_synch( apa_state_t *ps, const int16_t *in, uint16_t l_in, int16_t s_start, uint16_t s_len, int16_t fixed_pos, uint16_t corr_len, uint16_t offset, float *energy, float *quality, int16_t *synch_pos ); @@ -132,7 +155,7 @@ static bool copy_frm( apa_state_t *ps, const int16_t frm_in[], int16_t frm_out[] static bool shrink_frm( apa_state_t *ps, const int16_t frm_in[], uint16_t maxScaling, int16_t frm_out[], uint16_t *l_frm_out ); static bool extend_frm( apa_state_t *ps, const int16_t frm_in[], int16_t frm_out[], uint16_t *l_frm_out ); - +#endif /*---------------------------------------------------------------------* * Public functions @@ -196,9 +219,58 @@ void apa_reset( ps->bad_frame_count = 0; ps->good_frame_count = 0; +#ifdef JBM_TSM_ON_TCS + ps->l_ts = 1; + ps->l_r_buf = 0; +#endif return; } +#ifdef JBM_TSM_ON_TCS +uint8_t apa_reconfigure( + apa_state_t *ps, + uint16_t num_channels, + uint16_t l_ts ) +{ + + /* realloc buffer */ + free( ps->buf_out ); + ps->num_channels = (uint16_t) num_channels; + ps->buf_out_capacity = (uint16_t) ( APA_BUF_PER_CHANNEL * num_channels ); + ps->buf_out = (float *) malloc( sizeof( float ) * ps->buf_out_capacity ); + if ( !ps->buf_out ) + { + return 2; + } + ps->l_buf_out = 0; + ps->l_in_total = 0; + ps->l_ts = ps->num_channels * l_ts; + + /* set everything else dependent on the number of channels */ + /* set segment size */ + /* in the order of a pitch, set to 160 samples at 16 kHz */ + /* used for windowing and as the correlation length, i.e., */ + /* the size of the template segment. */ + ps->l_seg = ( ps->rate / 100 ) * ps->num_channels; + + /* set frame size */ + /* set to 320 samples at 16 kHz */ + ps->l_frm = ( ps->rate / FRAMES_PER_SEC ) * ps->num_channels; + + /* set minimum pitch */ + /* set to 40 samples at 16 kHz */ + /* (defines min change in number of samples, i.e., abs(l_in-l_out) >= p_min) */ + ps->p_min = ( ps->rate / 400 ) * ps->num_channels; + + /* set search length */ + /* must cover one pitch, set to 200 samples at 16 kHz */ + /* (the resulting maximum pitch is then p_min+l_search = 240 samples at 16 kHz) */ + ps->l_search = ( ps->rate / 80 ) * ps->num_channels; + + return 0; +} + +#endif /* Sets the audio configuration. */ bool apa_set_rate( @@ -302,6 +374,39 @@ bool apa_set_scale( return 0; } +#ifdef JBM_TSM_ON_TCS +bool apa_set_renderer_granularity( + apa_state_t *ps, + uint16_t l_ts ) +{ + /* make sure pointer is valid */ + if ( ps == NULL ) + { + return 1; + } + + + /* copy to state struct */ + ps->l_ts = l_ts * ps->num_channels; + return 0; +} + +bool apa_set_renderer_residual_samples( + apa_state_t *ps, + uint16_t l_r_buf ) +{ + /* make sure pointer is valid */ + if ( ps == NULL ) + { + return 1; + } + + + /* copy to state struct */ + ps->l_r_buf = l_r_buf * ps->num_channels; + return 0; +} +#endif /* ******************************************************************************** @@ -454,16 +559,28 @@ bool apa_exit( ******************************************************************************** */ uint8_t apa_exec( - apa_state_t *ps, /* i/o: state struct */ - const int16_t a_in[], /* i : input samples */ - uint16_t l_in, /* i : number of input samples */ - uint16_t maxScaling, /* i : allowed number of inserted/removed samples */ - int16_t a_out[], /* o : output samples */ - uint16_t *l_out /* o : number of output samples */ + apa_state_t *ps, /* i/o: state struct */ +#ifdef JBM_TSM_ON_TCS + const float a_in[], /* i : input samples */ +#else + const int16_t a_in[], /* i : input samples */ +#endif + uint16_t l_in, /* i : number of input samples */ + uint16_t maxScaling, /* i : allowed number of inserted/removed samples */ +#ifdef JBM_TSM_ON_TCS + float a_out[], /* o : output samples */ +#else + int16_t a_out[], /* o : output samples */ +#endif + uint16_t *l_out /* o : number of output samples */ ) { uint16_t i; +#ifdef JBM_TSM_ON_TCS + float frm_in[APA_BUF]; /* TODO(mcjbm): this buffer could be smaller - always allocates space for 16 channels */ +#else int16_t frm_in[APA_BUF]; /* TODO(mcjbm): this buffer could be smaller - always allocates space for 16 channels */ +#endif uint16_t l_frm_out; int16_t l_rem; int32_t dl_scaled, dl_copied, l_frm_out_target; @@ -525,8 +642,13 @@ uint8_t apa_exec( } else { +#ifdef JBM_TSM_ON_TCS + float *buf_out_ptr = &( ps->buf_out[ps->l_buf_out - ps->l_frm] ); + float *frm_in_ptr = &( frm_in[ps->l_frm] ); +#else int16_t *buf_out_ptr = &( ps->buf_out[ps->l_buf_out - ps->l_frm] ); int16_t *frm_in_ptr = &( frm_in[ps->l_frm] ); +#endif /* fill input frame */ /* 1st input frame: previous output samples */ @@ -581,8 +703,13 @@ uint8_t apa_exec( /* discard old samples; always keep at least most recent l_frm samples */ if ( ( ps->l_buf_out + l_frm_out ) > ps->buf_out_capacity ) { +#ifdef JBM_TSM_ON_TCS + float *buf_out_ptr1 = ps->buf_out; + float *buf_out_ptr2; +#else int16_t *buf_out_ptr1 = ps->buf_out; int16_t *buf_out_ptr2; +#endif l_rem = ( ps->l_frm - l_frm_out ); if ( l_rem < 0 ) @@ -602,7 +729,11 @@ uint8_t apa_exec( return 5; } { +#ifdef JBM_TSM_ON_TCS + float *buf_out_ptr = &( ps->buf_out[ps->l_buf_out] ); +#else int16_t *buf_out_ptr = &( ps->buf_out[ps->l_buf_out] ); +#endif for ( i = 0; i < l_frm_out; i++ ) { buf_out_ptr[i] = a_out[i]; @@ -660,7 +791,11 @@ uint8_t apa_exec( */ static void get_scaling_quality( const apa_state_t *ps, +#ifdef JBM_TSM_ON_TCS + const float *signal, +#else const int16_t *signal, +#endif uint16_t s_len, uint16_t offset, uint16_t corr_len, @@ -813,7 +948,11 @@ static float apa_getQualityIncreaseForLowEnergy( */ static bool logarithmic_search( const apa_state_t *ps, +#ifdef JBM_TSM_ON_TCS + const float *signal, +#else const int16_t *signal, +#endif int16_t s_start, uint16_t inlen, uint16_t offset, @@ -926,7 +1065,11 @@ static bool logarithmic_search( */ static bool find_synch( apa_state_t *ps, +#ifdef JBM_TSM_ON_TCS + const float *in, +#else const int16_t *in, +#endif uint16_t l_in, int16_t s_start, uint16_t s_len, @@ -981,8 +1124,13 @@ static bool find_synch( */ static bool copy_frm( apa_state_t *ps, +#ifdef JBM_TSM_ON_TCS + const float frm_in[], + float frm_out[], +#else const int16_t frm_in[], int16_t frm_out[], +#endif uint16_t *l_frm_out ) { uint16_t i; @@ -1029,9 +1177,17 @@ static bool copy_frm( */ static bool shrink_frm( apa_state_t *ps, +#ifdef JBM_TSM_ON_TCS + const float frm_in[], +#else const int16_t frm_in[], +#endif uint16_t maxScaling, +#ifdef JBM_TSM_ON_TCS + float frm_out[], +#else int16_t frm_out[], +#endif uint16_t *l_frm_out ) { bool findSynchResult = 0; @@ -1062,6 +1218,22 @@ static bool shrink_frm( /* maximum scaling */ energy = -65; quality = 5; +#ifdef JBM_TSM_ON_TCS + xtract = maxScaling; + /* take samples already in the renderer buf into account */ + xtract += ps->l_r_buf; + /* snap to renderer time slot borders */ + xtract -= ( ps->l_ts - ( l_frm - xtract + ps->l_r_buf ) % ps->l_ts ); + while ( xtract < 0 ) + { + xtract += ps->l_ts; + } + while ( xtract > ( s_end - ps->num_channels ) ) + { + /* exceeded the possible shrinking, go back one renderer ts*/ + xtract -= ps->l_ts; + } +#else if ( maxScaling != 0U && s_end > maxScaling + 1 ) { xtract = maxScaling; @@ -1071,6 +1243,7 @@ static bool shrink_frm( /* set to last valid element (i.e. element[len - 1] but note for stereo last element is last pair of samples) */ xtract = s_end - ps->num_channels; } +#endif } else { @@ -1165,8 +1338,13 @@ static bool shrink_frm( */ static bool extend_frm( apa_state_t *ps, +#ifdef JBM_TSM_ON_TCS + const float frm_in[], + float frm_out[], +#else const int16_t frm_in[], int16_t frm_out[], +#endif uint16_t *l_frm_out ) { bool findSynchResult = 0; @@ -1180,8 +1358,14 @@ static bool extend_frm( int16_t s_start = 0; float energy, quality = 0.0f; uint16_t l_frm, l_seg; +#ifdef JBM_TSM_ON_TCS + const float *fadeOut, *fadeIn; + float *out; +#else const int16_t *fadeOut, *fadeIn; int16_t *out; +#endif + l_frm = ps->l_frm; l_seg = ps->l_seg; @@ -1271,6 +1455,12 @@ static bool extend_frm( energy = -65; quality = 5; xtract[n] = s_start + ps->num_channels; +#ifdef JBM_TSM_ON_TCS + /* take renderer buffer samples into accout */ + xtract[n] += ps->l_r_buf; + /* snap to next renderer time slot border to resynchronize */ + xtract[n] -= ( ( N - 1 ) * l_seg - xtract[n] + ps->l_r_buf ) % ps->l_ts; +#endif } else { @@ -1332,8 +1522,13 @@ static bool extend_frm( else { /* just copy down 1st half of current segment (= 2nd half of previous segment) */ +#ifdef JBM_TSM_ON_TCS + float *frm_out_ptr; + const float *frm_in_ptr; +#else int16_t *frm_out_ptr; const int16_t *frm_in_ptr; +#endif frm_out_ptr = &( frm_out[( n - 2 ) * l_seg] ); frm_in_ptr = &( frm_in[l_frm + xtract[n]] ); for ( i = 0; i < l_seg; i++ ) diff --git a/lib_dec/jbm_pcmdsp_apa.h b/lib_dec/jbm_pcmdsp_apa.h index 543042f53b..6a2b02e13c 100644 --- a/lib_dec/jbm_pcmdsp_apa.h +++ b/lib_dec/jbm_pcmdsp_apa.h @@ -114,12 +114,24 @@ bool apa_set_rate( apa_state_t *ps, const int32_t output_Fs ); * @return 0 on success, 1 on failure */ bool apa_set_scale( apa_state_t *s, uint16_t scale ); +#ifdef JBM_TSM_ON_TCS +bool apa_set_renderer_granularity( apa_state_t *ps, uint16_t l_ts ); + +bool apa_set_renderer_residual_samples( apa_state_t *ps, uint16_t l_r_buf ); + +uint8_t apa_reconfigure( apa_state_t *ps, uint16_t num_channels, uint16_t l_ts ); +#endif + bool apa_set_complexity_options( apa_state_t *s, uint16_t wss, uint16_t css ); bool apa_set_quality( apa_state_t *s, float quality, uint16_t qualityred, uint16_t qualityrise ); bool apa_exit( apa_state_t **s ); +#ifdef JBM_TSM_ON_TCS +uint8_t apa_exec( apa_state_t *s, const float a_in[], uint16_t l_in, uint16_t maxScaling, float a_out[], uint16_t *l_out ); +#else uint8_t apa_exec( apa_state_t *s, const int16_t a_in[], uint16_t l_in, uint16_t maxScaling, int16_t a_out[], uint16_t *l_out ); +#endif #endif /* JBM_PCMDSP_APA_H */ diff --git a/lib_dec/jbm_pcmdsp_fifo.c b/lib_dec/jbm_pcmdsp_fifo.c index 81e833e5e5..fd0df04ca8 100644 --- a/lib_dec/jbm_pcmdsp_fifo.c +++ b/lib_dec/jbm_pcmdsp_fifo.c @@ -116,6 +116,15 @@ ivas_error pcmdsp_fifo_init( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for JBM\n" ) ); } +#ifdef DEBUGGING + { + uint32_t i; + for ( i = 0; i < nDataBytes; i++ ) + { + h->dataBegin[i] = 0; + } + } +#endif h->dataEnd = h->dataBegin + nDataBytes; h->dataWriteIterator = h->dataBegin; h->dataReadIterator = h->dataBegin; @@ -166,6 +175,49 @@ int16_t pcmdsp_fifo_write( return 0; } +#ifdef JBM_TSM_ON_TCS +/* Writes the given audio data to the FIFO. */ +int16_t pcmdsp_fifo_write_zero( + PCMDSP_FIFO_HANDLE h, + uint16_t nSamplesPerChannel ) +{ + uint16_t nBytesToWrite; + + /* check for empty input buffer */ + if ( nSamplesPerChannel == 0U ) + { + return 0; + } + + /* check, if enough space left */ + if ( nSamplesPerChannel > h->capacity - h->size ) + { + return -1; + } + + nBytesToWrite = nSamplesPerChannel * h->nBytesPerSampleSet; + if ( h->dataWriteIterator + nBytesToWrite > h->dataEnd ) + { + /* wrap around: writing two parts */ + uint16_t bytesOfFirstPart, secondSize; + bytesOfFirstPart = (uint16_t) ( h->dataEnd - h->dataWriteIterator ); + secondSize = nBytesToWrite - bytesOfFirstPart; + set_c( (int8_t *) h->dataWriteIterator, 0, bytesOfFirstPart ); + set_c( (int8_t *) h->dataBegin, 0, secondSize ); + h->dataWriteIterator = h->dataBegin + secondSize; + } + else + { + /* no wrap around: simple write */ + set_c( (int8_t *) h->dataWriteIterator, 0, nBytesToWrite ); + h->dataWriteIterator += nBytesToWrite; + } + h->size += nSamplesPerChannel; + + return 0; +} +#endif + /* Reads the given number of audio samples from the FIFO. */ int16_t pcmdsp_fifo_read( PCMDSP_FIFO_HANDLE h, diff --git a/lib_dec/jbm_pcmdsp_fifo.h b/lib_dec/jbm_pcmdsp_fifo.h index 13ffd146f8..e6c64dc9e8 100644 --- a/lib_dec/jbm_pcmdsp_fifo.h +++ b/lib_dec/jbm_pcmdsp_fifo.h @@ -73,6 +73,9 @@ void pcmdsp_fifo_destroy( PCMDSP_FIFO_HANDLE *ph ); ivas_error pcmdsp_fifo_init( PCMDSP_FIFO_HANDLE h, uint16_t nSamplesPerChannel, uint16_t nChannels, uint16_t nBytesPerSample ); int16_t pcmdsp_fifo_write( PCMDSP_FIFO_HANDLE h, const uint8_t *samples, uint16_t nSamplesPerChannel ); +#ifdef JBM_TSM_ON_TCS +int16_t pcmdsp_fifo_write_zero( PCMDSP_FIFO_HANDLE h, uint16_t nSamplesPerChannel ); +#endif int16_t pcmdsp_fifo_read( PCMDSP_FIFO_HANDLE h, uint16_t nSamplesPerChannel, uint8_t *samples ); diff --git a/lib_dec/jbm_pcmdsp_similarityestimation.c b/lib_dec/jbm_pcmdsp_similarityestimation.c index f575acc7ad..e83d1f7c37 100644 --- a/lib_dec/jbm_pcmdsp_similarityestimation.c +++ b/lib_dec/jbm_pcmdsp_similarityestimation.c @@ -52,7 +52,11 @@ /* Calculates cross correlation coefficient for template segment. */ float cross_correlation_self( +#ifdef JBM_TSM_ON_TCS + const float *signal, +#else const int16_t *signal, +#endif uint16_t x, uint16_t y, uint16_t corr_len ) @@ -63,7 +67,11 @@ float cross_correlation_self( c_c = 0.0f; for ( j = 0; j < corr_len; j++ ) { +#ifdef JBM_TSM_ON_TCS + c_c += ( signal[j + x] * signal[j + y] ); +#else c_c += ( (float) signal[j + x] * (float) signal[j + y] ); +#endif } return c_c; @@ -71,7 +79,11 @@ float cross_correlation_self( /* Calculates cross correlation coefficient for template segment. */ float cross_correlation_subsampled_self( +#ifdef JBM_TSM_ON_TCS + const float *signal, +#else const int16_t *signal, +#endif uint16_t x, uint16_t y, uint16_t corr_len, @@ -83,7 +95,11 @@ float cross_correlation_subsampled_self( c_c = 0.0f; for ( j = 0; j < corr_len; j += subsampling ) { +#ifdef JBM_TSM_ON_TCS + c_c += ( signal[j + x] * signal[j + y] ); +#else c_c += ( (float) signal[j + x] * (float) signal[j + y] ); +#endif } return c_c; @@ -92,7 +108,11 @@ float cross_correlation_subsampled_self( /* Calculates normalized cross correlation coefficient for template segment. */ float normalized_cross_correlation_self( +#ifdef JBM_TSM_ON_TCS + const float *signal, +#else const int16_t *signal, +#endif uint16_t x, uint16_t y, uint16_t corr_len, @@ -102,7 +122,11 @@ float normalized_cross_correlation_self( float c_c; float energy_xy, energy_x, energy_y; uint16_t j; +#ifdef JBM_TSM_ON_TCS + const float *signal_a, *signal_b; +#else const int16_t *signal_a, *signal_b; +#endif c_c = 0.0f; energy_x = 0.0f; @@ -111,11 +135,21 @@ float normalized_cross_correlation_self( signal_b = &signal[y]; for ( j = 0; j < corr_len; j += subsampling ) { +#ifdef JBM_TSM_ON_TCS + c_c += ( signal_a[j] * signal_b[j] ); + energy_x += ( signal_a[j] ) * ( signal_a[j] ); + energy_y += ( signal_b[j] ) * ( signal_b[j] ); +#else c_c += ( (float) signal_a[j] * (float) signal_b[j] ); energy_x += ( (float) signal_a[j] ) * ( (float) signal_a[j] ); energy_y += ( (float) signal_b[j] ) * ( (float) signal_b[j] ); +#endif } +#ifdef JBM_TSM_ON_TCS + energy_xy = sqrtf( energy_x * energy_y ); +#else energy_xy = (float) sqrt( (float) energy_x * (float) energy_y ); +#endif if ( energy_xy < 1.0f ) { energy_xy = 1.0f; /* conceal silent frames */ @@ -130,7 +164,11 @@ float normalized_cross_correlation_self( /* Splits the signal into segments and checks if all of them have very low energy. */ bool isSilence( +#ifdef JBM_TSM_ON_TCS + const float *signal, +#else const int16_t *signal, +#endif uint32_t len, uint32_t segments ) { @@ -145,7 +183,11 @@ bool isSilence( if ( ( i != 0U && i % samplesPerSegment == 0U ) || i + 1 == len ) { /* check energy of current segment */ +#ifdef JBM_TSM_ON_TCS + energy = 10 * log10f( energy / (float) samplesPerSegment ); +#else energy = 10 * (float) log10( energy / samplesPerSegment ); +#endif if ( energy > -65 ) { return false; diff --git a/lib_dec/jbm_pcmdsp_similarityestimation.h b/lib_dec/jbm_pcmdsp_similarityestimation.h index 4dc92f27b7..7078580047 100644 --- a/lib_dec/jbm_pcmdsp_similarityestimation.h +++ b/lib_dec/jbm_pcmdsp_similarityestimation.h @@ -67,7 +67,16 @@ * ******************************************************************************** */ -float cross_correlation_self( const int16_t *signal, uint16_t x, uint16_t y, uint16_t corr_len ); +float cross_correlation_self( +#ifdef JBM_TSM_ON_TCS + const float *signal, +#else + const int16_t *signal, +#endif + uint16_t x, + uint16_t y, + uint16_t corr_len +); /* ******************************************************************************** @@ -94,7 +103,17 @@ float cross_correlation_self( const int16_t *signal, uint16_t x, uint16_t y, uin * ******************************************************************************** */ -float cross_correlation_subsampled_self( const int16_t *signal, uint16_t x, uint16_t y, uint16_t corr_len, uint16_t subsampling ); +float cross_correlation_subsampled_self( +#ifdef JBM_TSM_ON_TCS + const float *signal, +#else + const int16_t *signal, +#endif + uint16_t x, + uint16_t y, + uint16_t corr_len, + uint16_t subsampling +); /* ******************************************************************************** @@ -132,9 +151,28 @@ float cross_correlation_subsampled_self( const int16_t *signal, uint16_t x, uint * ******************************************************************************** */ -float normalized_cross_correlation_self( const int16_t *signal, uint16_t x, uint16_t y, uint16_t corr_len, uint16_t subsampling, float *energy ); +float normalized_cross_correlation_self( +#ifdef JBM_TSM_ON_TCS + const float *signal, +#else + const int16_t *signal, +#endif + uint16_t x, + uint16_t y, + uint16_t corr_len, + uint16_t subsampling, + float *energy +); /* Splits the signal into segments and checks if all of them have very low energy. */ -bool isSilence( const int16_t *signal, uint32_t len, uint32_t segments ); +bool isSilence( +#ifdef JBM_TSM_ON_TCS + const float *signal, +#else + const int16_t *signal, +#endif + uint32_t len, + uint32_t segments +); #endif /* JBM_PCMDSP_SIMILARITYESTIMATION_H */ diff --git a/lib_dec/jbm_pcmdsp_window.c b/lib_dec/jbm_pcmdsp_window.c index f9f71ac802..fa0ea6f724 100644 --- a/lib_dec/jbm_pcmdsp_window.c +++ b/lib_dec/jbm_pcmdsp_window.c @@ -80,9 +80,15 @@ void hannWindow( *-----------------------------------------------------------------------*/ void overlapAdd( +#ifdef JBM_TSM_ON_TCS + const float *fadeOut, + const float *fadeIn, + float *out, +#else const int16_t *fadeOut, const int16_t *fadeIn, int16_t *out, +#endif uint16_t n, uint16_t nChannels, const float *fadeOutWin, @@ -90,7 +96,11 @@ void overlapAdd( { float fdOutVal, fdInVal; int16_t i, j, hannIter; +#ifdef JBM_TSM_ON_TCS + float combinedVal; +#else int32_t combinedVal; +#endif for ( j = 0; j < nChannels; j++ ) { @@ -101,8 +111,11 @@ void overlapAdd( fdOutVal = fadeOut[i] * fadeOutWin[hannIter]; fdInVal = fadeIn[i] * fadeInWin[hannIter]; /* round combinedVal value (taking care of sign) */ +#ifdef JBM_TSM_ON_TCS + combinedVal = fdInVal + fdOutVal; + out[i] = combinedVal; +#else combinedVal = (int32_t) ( ( fdInVal + fdOutVal ) + 0.5 ); - if ( fdInVal + fdOutVal < 0.0 ) { combinedVal = (int32_t) ( ( fdInVal + fdOutVal ) - 0.5 ); @@ -117,7 +130,9 @@ void overlapAdd( { combinedVal = MIN16B; } + out[i] = (int16_t) combinedVal; +#endif hannIter++; } } diff --git a/lib_dec/jbm_pcmdsp_window.h b/lib_dec/jbm_pcmdsp_window.h index 67759e9738..2f8cd462b5 100644 --- a/lib_dec/jbm_pcmdsp_window.h +++ b/lib_dec/jbm_pcmdsp_window.h @@ -61,6 +61,9 @@ void hannWindow( uint16_t n, float *w ); * @param[in] nChannels number of channels * @param[in] fadeOutWin window for fade out * @param[in] fadeInWin window for fade in */ +#ifdef JBM_TSM_ON_TCS +void overlapAdd( const float *fadeOut, const float *fadeIn, float *out, uint16_t n, uint16_t nChannels, const float *fadeOutWin, const float *fadeInWin ); +#else void overlapAdd( const int16_t *fadeOut, const int16_t *fadeIn, int16_t *out, uint16_t n, uint16_t nChannels, const float *fadeOutWin, const float *fadeInWin ); - +#endif #endif /* JBM_PCMDSP_WINDOW_H */ diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index ee315bf399..b3767b3556 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -54,11 +54,27 @@ struct IVAS_DEC_VOIP uint16_t nSamplesFrame; /* Total number of samples in a frame (includes number of channels) */ JB4_HANDLE hJBM; PCMDSP_APA_HANDLE hTimeScaler; - PCMDSP_FIFO_HANDLE hFifoAfterTimeScaler; uint16_t lastDecodedWasActive; - int16_t *apaExecBuffer; /* Buffer for APA scaling */ +#ifdef JBM_TSM_ON_TCS + float *apaExecBuffer; /* Buffer for APA scaling */ +#else + int16_t *apaExecBuffer; /* Buffer for APA scaling */ +#endif JB4_DATAUNIT_HANDLE hCurrentDataUnit; /* Points to the currently processed data unit */ uint16_t *bs_conversion_buf; /* Buffer for bitstream conversion from packed to serial */ +#ifdef VARIABLE_SPEED_DECODING + uint8_t mode; + uint16_t speedFac; + bool needNewFrame; +#endif +#ifdef JBM_TSM_ON_TCS + JBM_RENDERER_TYPE rendererType; + PCMDSP_FIFO_HANDLE hFifoOut; + uint8_t nTransportChannelsOld; + uint16_t nSamplesAvailableNext; +#else + PCMDSP_FIFO_HANDLE hFifoAfterTimeScaler; +#endif #ifdef SUPPORT_JBM_TRACEFILE IVAS_JBM_TRACE_DATA JbmTraceData; #endif @@ -93,10 +109,22 @@ static void IVAS_DEC_Close_VoIP( IVAS_DEC_VOIP *hVoIP ); #ifdef SUPPORT_JBM_TRACEFILE static void store_JbmData( IVAS_DEC_VOIP *hVoIP, JB4_DATAUNIT_HANDLE dataUnit, const uint32_t systemTimestamp_ms, const uint16_t extBufferedSamples, const int32_t output_Fs ); #endif +#ifdef JBM_TSM_ON_TCS +static ivas_error evs_dec_main( Decoder_Struct *st_ivas, const int16_t nOutSamples, float *floatBuf, int16_t *pcmBuf ); +#else static ivas_error evs_dec_main( Decoder_Struct *st_ivas, const int16_t nOutSamples, int16_t *pcmBuf ); +#endif 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, const int16_t orientation_tracking, const float no_diegetic_pan ); - +#ifdef JBM_TSM_ON_TCS +static int16_t IVAS_DEC_VoIP_GetRenderGranularity( Decoder_Struct *st_ivas ); +static JBM_RENDERER_TYPE IVAS_DEC_VoIP_GetRendererConfig( IVAS_DEC_HANDLE hIvasDec ); +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 ); +#endif /*---------------------------------------------------------------------* * IVAS_DEC_Open() @@ -226,7 +254,9 @@ static void init_decoder_config( hDecoderConfig->Opt_RendConfigCustom = 0; hDecoderConfig->orientation_tracking = orientation_tracking; hDecoderConfig->no_diegetic_pan = no_diegetic_pan; - +#ifdef JBM_TSM_ON_TCS + hDecoderConfig->voip_active = 0; +#endif return; } @@ -463,7 +493,11 @@ ivas_error IVAS_DEC_Configure( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_EnableVoIP( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ +#ifdef VARIABLE_SPEED_DECODING + const IVAS_DEC_VOIP_MODE voipMode, /* i : VoIP or varable speed */ + const uint16_t speedFac, /* i : speed factor for varable speed */ +#endif const int16_t jbmSafetyMargin, /* i : allowed delay reserve for JBM, in milliseconds */ const IVAS_DEC_INPUT_FORMAT inputFormat /* i : format of the input bitstream */ ) @@ -473,8 +507,10 @@ ivas_error IVAS_DEC_EnableVoIP( error = IVAS_ERR_OK; +#ifndef JBM_TSM_ON_TCS /* initialize time scaler and FIFO after time scaler */ uint16_t wss, css; +#endif if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { @@ -486,7 +522,12 @@ ivas_error IVAS_DEC_EnableVoIP( hIvasDec->Opt_VOIP = 1; +#ifdef JBM_TSM_ON_TCS + hDecoderConfig->voip_active = 1; +#endif + hDecoderConfig->nchan_out = audioCfg2channels( hDecoderConfig->output_config ); + assert( hDecoderConfig->nchan_out > 0 && "EXT output not yet supported in VoIP mode" ); if ( ( error = input_format_API_to_internal( inputFormat, &hIvasDec->bitstreamformat, &hIvasDec->sdp_hf_only, true ) ) != IVAS_ERR_OK ) @@ -501,13 +542,31 @@ ivas_error IVAS_DEC_EnableVoIP( hIvasDec->hVoIP->lastDecodedWasActive = 0; hIvasDec->hVoIP->hCurrentDataUnit = NULL; +#ifdef VARIABLE_SPEED_DECODING + hIvasDec->hVoIP->mode = voipMode; + hIvasDec->hVoIP->speedFac = speedFac; + hIvasDec->hVoIP->needNewFrame = false; +#endif +#ifdef JBM_TSM_ON_TCS + hIvasDec->hVoIP->nSamplesFrame = (uint16_t) ( hDecoderConfig->output_Fs / FRAMES_PER_SEC ); + hIvasDec->hVoIP->nSamplesAvailableNext = 0; + hIvasDec->hVoIP->rendererType = JBM_RENDERER_NONE; + hIvasDec->hVoIP->hFifoOut = NULL; +#else hIvasDec->hVoIP->nSamplesFrame = (uint16_t) ( hDecoderConfig->output_Fs * hDecoderConfig->nchan_out / FRAMES_PER_SEC ); +#endif +#ifdef JBM_TSM_ON_TCS + /* postpone init of the buffers until we know the real number of TCs*/ + hIvasDec->hVoIP->apaExecBuffer = NULL; + hIvasDec->hVoIP->nTransportChannelsOld = 0; +#else hIvasDec->hVoIP->apaExecBuffer = malloc( sizeof( int16_t ) * APA_BUF_PER_CHANNEL * hDecoderConfig->nchan_out ); if ( hIvasDec->hVoIP->apaExecBuffer == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); } +#endif #define WMC_TOOL_SKIP /* Bitstream conversion is not counted towards complexity and memory usage */ @@ -520,15 +579,27 @@ ivas_error IVAS_DEC_EnableVoIP( } /* initialize JBM */ - if ( ( error = JB4_Create( &hIvasDec->hVoIP->hJBM ) != IVAS_ERR_OK ) != IVAS_ERR_OK ) +#ifdef VARIABLE_SPEED_DECODING + hIvasDec->hVoIP->hJBM = NULL; + if ( hIvasDec->hVoIP->mode == IVAS_DEC_VOIP_MODE_VOIP ) { - return error; +#endif + if ( ( error = JB4_Create( &hIvasDec->hVoIP->hJBM ) != IVAS_ERR_OK ) != IVAS_ERR_OK ) + { + return error; + } + if ( JB4_Init( hIvasDec->hVoIP->hJBM, jbmSafetyMargin ) != 0 ) + { + return IVAS_ERR_FAILED_ALLOC; + } +#ifdef VARIABLE_SPEED_DECODING } if ( ( error = JB4_Init( hIvasDec->hVoIP->hJBM, jbmSafetyMargin ) ) != IVAS_ERR_OK ) { return error; } - +#endif +#ifndef JBM_TSM_ON_TCS if ( hDecoderConfig->output_Fs == 8000 ) { wss = 1; @@ -553,8 +624,41 @@ ivas_error IVAS_DEC_EnableVoIP( { return IVAS_ERR_INIT_ERROR; } +#endif + +#ifdef JBM_TSM_ON_TCS + + /* postpone init of time scaler until we know the real number of TCs */ + hIvasDec->hVoIP->hTimeScaler = NULL; + /* create output pcm fifo*/ + /* :TODO: also provide CLDFB output FIFO if things work out */ + if ( hIvasDec->hVoIP->mode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED ) + { + if ( pcmdsp_fifo_create( &hIvasDec->hVoIP->hFifoOut ) != 0 || + pcmdsp_fifo_init( hIvasDec->hVoIP->hFifoOut, (uint16_t) ( hDecoderConfig->output_Fs * 4 / FRAMES_PER_SEC ) /* 4 frames */, hDecoderConfig->nchan_out, sizeof( int16_t ) ) != 0 ) + { + return IVAS_ERR_INIT_ERROR; + } + } - if ( apa_init( &hIvasDec->hVoIP->hTimeScaler, hDecoderConfig->nchan_out ) != IVAS_ERR_OK || +#else +#ifdef VARIABLE_SPEED_DECODING + { + float startQuality = hIvasDec->hVoIP->mode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED ? -2.0f : 1.0f; + if ( apa_init( &hIvasDec->hVoIP->hTimeScaler, + hDecoderConfig->nchan_out ) != IVAS_ERR_OK || + apa_set_rate( hIvasDec->hVoIP->hTimeScaler, hDecoderConfig->output_Fs ) != 0 || + apa_set_complexity_options( hIvasDec->hVoIP->hTimeScaler, wss, css ) != 0 || + apa_set_quality( hIvasDec->hVoIP->hTimeScaler, startQuality, 4, 4 ) != 0 || + pcmdsp_fifo_create( &hIvasDec->hVoIP->hFifoAfterTimeScaler ) != 0 || + pcmdsp_fifo_init( hIvasDec->hVoIP->hFifoAfterTimeScaler, (uint16_t) ( hDecoderConfig->output_Fs * 4 / FRAMES_PER_SEC ) /* 4 frames */, hDecoderConfig->nchan_out, sizeof( int16_t ) ) != 0 ) + { + return IVAS_ERR_INIT_ERROR; + } + } +#else + if ( apa_init( &hIvasDec->hVoIP->hTimeScaler, + hDecoderConfig->nchan_out ) !=IVAS_ERR_OK || apa_set_rate( hIvasDec->hVoIP->hTimeScaler, hDecoderConfig->output_Fs ) != 0 || apa_set_complexity_options( hIvasDec->hVoIP->hTimeScaler, wss, css ) != 0 || apa_set_quality( hIvasDec->hVoIP->hTimeScaler, 1, 4, 4 ) != 0 || @@ -563,6 +667,8 @@ ivas_error IVAS_DEC_EnableVoIP( { return IVAS_ERR_INIT_ERROR; } +#endif +#endif return error; } @@ -651,6 +757,13 @@ ivas_error IVAS_DEC_FeedFrame_Serial( st->use_partial_copy = 1; } +#ifdef VARIABLE_SPEED_DECODING + if ( hIvasDec->hVoIP != NULL && hIvasDec->hVoIP->mode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED ) + { + hIvasDec->hVoIP->needNewFrame = false; + } +#endif + return error; } @@ -683,7 +796,11 @@ ivas_error IVAS_DEC_GetSamples( if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) { +#ifdef JBM_TSM_ON_TCS + if ( ( error = evs_dec_main( st_ivas, *nOutSamples, NULL, pcmBuf ) ) != IVAS_ERR_OK ) +#else if ( ( error = evs_dec_main( st_ivas, *nOutSamples, pcmBuf ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -708,6 +825,188 @@ ivas_error IVAS_DEC_GetSamples( } +#ifdef JBM_TSM_ON_TCS +/*---------------------------------------------------------------------* + * IVAS_DEC_Setup( ) + * + * Main function to decode to PCM data of the transport channels + *---------------------------------------------------------------------*/ + +static ivas_error IVAS_DEC_Setup( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint16_t *nTcBufferGranularity, /* o : granularity of the TC Buffer */ + uint8_t *nTransportChannels, /* o : number of decoded transport PCM channels */ + uint8_t *nOutChannels, /* o : number of decoded out channels (PCM or CLDFB) */ + uint16_t *nSamplesRendered, /* o : number of samples flushed from the last frame */ + int16_t *data /* o : flushed samples */ +) +{ + ivas_error error; + + error = IVAS_ERR_OK; + + *nSamplesRendered = 0; + + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + { + *nTransportChannels = 1; + *nOutChannels = 1; + } + else + { + Decoder_Struct *st_ivas; + + st_ivas = hIvasDec->st_ivas; + /*----------------------------------------------------------------* + * IVAS decoder setup + * - read IVAS format signaling + * - read IVAS format specific signaling + * - initialize decoder in the first frame based on IVAS format and number of transport channels + * - reconfigure the decoder when the number of TC or IVAS total bitrate change + *----------------------------------------------------------------*/ + + if ( st_ivas->bfi == 0 ) + { + if ( ( error = ivas_dec_setup( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) + { + return error; + } + } + /* TODO: JBM replace with a function that gets the real number of TCs generated, + depending of remapping, td rendering already done in the TC decoding part, ....*/ + *nTransportChannels = (uint8_t) st_ivas->hTcBuffer->nchan_transport_jbm; + *nTcBufferGranularity = (uint16_t) st_ivas->hTcBuffer->n_samples_granularity; + *nOutChannels = (uint8_t) st_ivas->hDecoderConfig->nchan_out; + } + + return error; +} + +/*---------------------------------------------------------------------* + * IVAS_DEC_GetTcSamples( ) + * + * Main function to decode to PCM data of the transport channels + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_GetTcSamples( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + float *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; + + error = IVAS_ERR_OK; + + 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, pcmBuf, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else if ( hIvasDec->mode == IVAS_DEC_MODE_IVAS ) + { + /* run the main IVAS decoding routine */ + if ( ( error = ivas_jbm_dec_tc( st_ivas, pcmBuf ) ) != IVAS_ERR_OK ) + { + return error; + } + + hIvasDec->isInitialized = true; /* Initialization done in ivas_dec() */ + } + + if ( hIvasDec->hasBeenFedFirstGoodFrame ) + { + hIvasDec->hasDecodedFirstGoodFrame = true; + } + + return error; +} + +/*---------------------------------------------------------------------* + * IVAS_DEC_Rendered_FeedTcSamples( ) + * + * Main function to decode to PCM data of the transport channels + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_RendererFeedTcSamples( + IVAS_DEC_HANDLE hIvasDec, /* i/o : IVAS decoder handle */ + const int16_t nSamplesForRendering, /* i: : number of TC samples wanted from the renderer */ + int16_t *nSamplesResidual, /* o: : number of samples not fitting into the renderer grid and buffer for the next call*/ + float *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 */ +) +{ + Decoder_Struct *st_ivas; + + ivas_error error; + + error = IVAS_ERR_OK; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + st_ivas = hIvasDec->st_ivas; + + /* feed the TCs to the IVAS renderer */ + if ( ( error = ivas_jbm_dec_feed_tc_to_renderer( st_ivas, nSamplesForRendering, nSamplesResidual, pcmBuf ) ) != IVAS_ERR_OK ) + { + return error; + } + + return error; +} + +/*---------------------------------------------------------------------* + * IVAS_DEC_GetRenderedSamples( ) + * + * Main function to decode to PCM data of the transport channels + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_GetRenderedSamples( + IVAS_DEC_HANDLE hIvasDec, /* i/o : IVAS decoder handle */ + const uint16_t nSamplesForRendering, /* i: : number of TC samples wanted from the renderer */ + uint16_t *nSamplesRendered, /* o : number of samples rendered */ + uint16_t *nSamplesAvailableNext, /* o : number of samples still available in the renerer pipeline */ + 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 */ +) +{ + Decoder_Struct *st_ivas; + ivas_error error; + + error = IVAS_ERR_OK; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + st_ivas = hIvasDec->st_ivas; + + /* run the main IVAS decoding routine */ + if ( ( error = ivas_jbm_dec_render( st_ivas, nSamplesForRendering, nSamplesRendered, nSamplesAvailableNext, pcmBuf ) ) != IVAS_ERR_OK ) + { + return error; + } + + + return error; +} +#endif + + /*---------------------------------------------------------------------* * IVAS_DEC_GetNumObjects( ) * @@ -1429,6 +1728,27 @@ ivas_error IVAS_DEC_VoIP_FeedFrame( return IVAS_ERR_OK; } +#ifdef VARIABLE_SPEED_DECODING +/*---------------------------------------------------------------------* + * IVAS_DEC_VoIP_SetScale( ) + * + * Set the TSM scale + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_VoIP_SetScale( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t scale /* i : TSM scale to set */ +) +{ + ivas_error error; + + error = IVAS_ERR_OK; + + hIvasDec->hVoIP->speedFac = scale; + + return error; +} +#endif /*---------------------------------------------------------------------* * IVAS_DEC_VoIP_GetSamples( ) @@ -1441,11 +1761,16 @@ ivas_error IVAS_DEC_VoIP_GetSamples( uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ 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 */ const uint32_t systemTimestamp_ms /* i : current system timestamp */ +#if defined( JBM_TSM_ON_TCS ) || defined( VARIABLE_SPEED_DECODING ) + , + uint16_t *sampleAvailableNext /* o : samples available for the next call */ +#endif #ifdef SUPPORT_JBM_TRACEFILE , JbmTraceFileWriterFn jbmWriterFn, void *jbmWriter #endif + ) { Decoder_Struct *st_ivas; @@ -1459,6 +1784,12 @@ ivas_error IVAS_DEC_VoIP_GetSamples( int16_t timeScalingDone; int16_t result; ivas_error error; +#ifdef JBM_TSM_ON_TCS + int16_t nSamplesRendered; + uint16_t nSamplesTcsScaled; + uint8_t nTransportChannels; + uint8_t nOutChannels; +#endif error = IVAS_ERR_OK; @@ -1467,133 +1798,454 @@ ivas_error IVAS_DEC_VoIP_GetSamples( hVoIP = hIvasDec->hVoIP; timeScalingDone = 0; +#ifdef JBM_TSM_ON_TCS + nOutChannels = (uint8_t) st_ivas->hDecoderConfig->nchan_out; + nTransportChannels = 0; + nSamplesTcsScaled = hVoIP->nSamplesFrame; + nSamplesRendered = 0; +#endif +#ifdef VARIABLE_SPEED_DECODING + scale = hVoIP->speedFac; + maxScaling = hVoIP->speedFac; +#endif + /* TODO(mcjbm): ringbuffer capacity should be configurable by user */ +#ifdef JBM_TSM_ON_TCS + if ( ( hVoIP->hFifoOut != NULL && nSamplesPerChannel > hVoIP->hFifoOut->capacity ) || nSamplesPerChannel == 0 ) +#else if ( nSamplesPerChannel > hVoIP->hFifoAfterTimeScaler->capacity || nSamplesPerChannel == 0 ) +#endif { return IVAS_ERR_WRONG_PARAMS; } /* make sure that the FIFO after decoder/scaler contains at least one sound card frame (i.e. 20ms) */ +#ifdef JBM_TSM_ON_TCS + while ( ( hVoIP->hFifoOut != NULL && pcmdsp_fifo_nReadableSamplesPerChannel( hVoIP->hFifoOut ) < nSamplesPerChannel ) || ( hVoIP->hFifoOut == NULL && nSamplesRendered < nSamplesPerChannel ) ) +#else while ( pcmdsp_fifo_nReadableSamplesPerChannel( hVoIP->hFifoAfterTimeScaler ) < nSamplesPerChannel ) +#endif { - extBufferedSamples = pcmdsp_fifo_nReadableSamplesPerChannel( hVoIP->hFifoAfterTimeScaler ); - extBufferedTime_ms = extBufferedSamples * 1000 / hDecoderConfig->output_Fs; - dataUnit = NULL; - /* pop one access unit from the jitter buffer */ - result = JB4_PopDataUnit( hVoIP->hJBM, systemTimestamp_ms, extBufferedTime_ms, &dataUnit, &scale, &maxScaling ); - if ( result != 0 ) +#ifdef VARIABLE_SPEED_DECODING + if ( hVoIP->mode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED && hVoIP->needNewFrame ) { - return IVAS_ERR_UNKNOWN; + /* we need another bs frame fed into the decoder...*/ + *sampleAvailableNext = 0; + return IVAS_ERR_VS_FRAME_NEEDED; } - - maxScaling = maxScaling * hDecoderConfig->output_Fs / 1000; - /* avoid time scaling multiple times in one sound card slot */ - if ( scale != 100U ) +#endif +#ifdef JBM_TSM_ON_TCS + if ( hVoIP->nSamplesAvailableNext == 0 ) { - if ( timeScalingDone ) + if ( hVoIP->hFifoOut ) { - scale = 100; + extBufferedSamples = pcmdsp_fifo_nReadableSamplesPerChannel( hVoIP->hFifoOut ); + nSamplesRendered = extBufferedSamples; } else { - timeScalingDone = 1; + extBufferedSamples = nSamplesRendered; /* TODO: JBM use renderer residual samples here */ } - } +#else + extBufferedSamples = pcmdsp_fifo_nReadableSamplesPerChannel( hVoIP->hFifoAfterTimeScaler ); +#endif + extBufferedTime_ms = extBufferedSamples * 1000 / hDecoderConfig->output_Fs; - /* copy bitstream into decoder state */ - if ( dataUnit ) - { - hIvasDec->hVoIP->hCurrentDataUnit = dataUnit; + dataUnit = NULL; +#ifdef VARIABLE_SPEED_DECODING + if ( hVoIP->mode == IVAS_DEC_VOIP_MODE_VOIP ) + { +#endif + /* pop one access unit from the jitter buffer */ + result = JB4_PopDataUnit( hVoIP->hJBM, systemTimestamp_ms, extBufferedTime_ms, &dataUnit, &scale, &maxScaling ); + if ( result != 0 ) + { + return IVAS_ERR_UNKNOWN; + } +#ifdef VARIABLE_SPEED_DECODING + } + else if ( hVoIP->mode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED ) + { + scale = hVoIP->speedFac; + maxScaling = hVoIP->speedFac; + } +#ifdef DEBUGGING + else + { + assert( "Wrong VoIP mode!\n" && 0 ); + } +#endif +#endif - bsCompactToSerial( dataUnit->data, hIvasDec->hVoIP->bs_conversion_buf, dataUnit->dataSize ); - IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, dataUnit->dataSize, 0 ); - } - else if ( hIvasDec->hasDecodedFirstGoodFrame ) - { - /* Decoder has been initialized with first good frame - do PLC */ - IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, 0, 1 ); - } + maxScaling = maxScaling * hDecoderConfig->output_Fs / 1000; + /* avoid time scaling multiple times in one sound card slot */ + if ( scale != 100U ) + { + if ( timeScalingDone ) + { + scale = 100; + } + else + { + timeScalingDone = 1; + } + } - /* decode */ - if ( !hIvasDec->hasBeenFedFirstGoodFrame ) - { - /* codec mode to use not known yet - simply output silence */ +#ifdef VARIABLE_SPEED_DECODING + if ( hVoIP->mode == IVAS_DEC_VOIP_MODE_VOIP ) + { +#endif + /* copy bitstream into decoder state */ + if ( dataUnit ) + { + hIvasDec->hVoIP->hCurrentDataUnit = dataUnit; + + bsCompactToSerial( dataUnit->data, hIvasDec->hVoIP->bs_conversion_buf, dataUnit->dataSize ); + IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, dataUnit->dataSize, 0 ); + } + else if ( hIvasDec->hasDecodedFirstGoodFrame ) + { + /* Decoder has been initialized with first good frame - do PLC */ + IVAS_DEC_FeedFrame_Serial( hIvasDec, hIvasDec->hVoIP->bs_conversion_buf, 0, 1 ); + } +#ifdef VARIABLE_SPEED_DECODING + } +#endif + /* decode */ + if ( !hIvasDec->hasBeenFedFirstGoodFrame ) + { + /* codec mode to use not known yet - simply output silence */ +#ifdef JBM_TSM_ON_TCS + nSamplesTcsScaled = hVoIP->nSamplesFrame; + if ( hVoIP->hFifoOut != NULL ) + { + /* feed zeros to FIFO */ + if ( pcmdsp_fifo_write_zero( hVoIP->hFifoOut, nSamplesTcsScaled ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + } + else + { + /* directly set output zero */ + set_s( pcmBuf, 0, nSamplesPerChannel * nOutChannels ); + } + nSamplesRendered = nSamplesTcsScaled; +#else set_s( hVoIP->apaExecBuffer, 0, hVoIP->nSamplesFrame ); /* TODO(mcjbm): Could be optimized: just write directly to output buffer */ - } - else - { +#endif + } + else + { + +#ifdef JBM_TSM_ON_TCS + uint16_t l_ts = 1; + uint16_t nSamplesRendered_loop; + /* setup ivas decoder and get the number of TCs */ + /* might render some remaining samples from the previous frame too if the renderer granularity changed */ + if ( hVoIP->hFifoOut ) + { + int16_t rendererPcmBuf[( MAX_OUTPUT_CHANNELS * L_FRAME_MAX * APA_MAX_SCALE ) / 100]; + if ( ( error = IVAS_DEC_Setup( hIvasDec, &l_ts, &nTransportChannels, &nOutChannels, &nSamplesRendered_loop, rendererPcmBuf ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( pcmdsp_fifo_write( hVoIP->hFifoOut, (uint8_t *) rendererPcmBuf, nSamplesRendered_loop ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + } + else + { + if ( ( error = IVAS_DEC_Setup( hIvasDec, &l_ts, &nTransportChannels, &nOutChannels, &nSamplesRendered_loop, pcmBuf + nSamplesRendered * nOutChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + } + nSamplesRendered += nSamplesRendered_loop; + if ( nTransportChannels != hVoIP->nTransportChannelsOld ) + { + IVAS_DEC_VoIP_reconfigure( hIvasDec, nTransportChannels, l_ts ); + } + /* decode TCs only */ + if ( ( error = IVAS_DEC_GetTcSamples( hIvasDec, hVoIP->apaExecBuffer, &nOutSamplesElse ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( ( error = IVAS_DEC_GetSamples( hIvasDec, hVoIP->apaExecBuffer, &nOutSamplesElse ) ) != IVAS_ERR_OK ) { return error; } - } +#endif + } - if ( dataUnit ) - { - if ( dataUnit->partial_frame != 0 ) +#ifdef VARIABLE_SPEED_DECODING + if ( hVoIP->mode == IVAS_DEC_VOIP_MODE_VOIP ) { - hVoIP->lastDecodedWasActive = 1; +#endif + if ( dataUnit ) + { + if ( dataUnit->partial_frame != 0 ) + { + hVoIP->lastDecodedWasActive = 1; + } + else + { + hVoIP->lastDecodedWasActive = !dataUnit->silenceIndicator; + } + /* data unit memory is no longer used */ + JB4_FreeDataUnit( hVoIP->hJBM, dataUnit ); + } +#ifdef VARIABLE_SPEED_DECODING } else { - hVoIP->lastDecodedWasActive = !dataUnit->silenceIndicator; + hVoIP->lastDecodedWasActive = 1; + } +#endif + /* limit scale to range supported by time scaler */ + if ( scale < APA_MIN_SCALE ) + { + scale = APA_MIN_SCALE; + } + else if ( scale > APA_MAX_SCALE ) + { + scale = APA_MAX_SCALE; } - /* data unit memory is no longer used */ - JB4_FreeDataUnit( hVoIP->hJBM, dataUnit ); - } - - /* limit scale to range supported by time scaler */ - if ( scale < APA_MIN_SCALE ) - { - scale = APA_MIN_SCALE; - } - else if ( scale > APA_MAX_SCALE ) - { - scale = APA_MAX_SCALE; - } - /* apply time scaling on decoded/concealed samples */ - if ( apa_set_scale( hVoIP->hTimeScaler, (uint16_t) scale ) != 0 ) - { - return IVAS_ERR_UNKNOWN; - } + /* apply time scaling on decoded/concealed samples */ +#ifdef JBM_TSM_ON_TCS + if ( hIvasDec->hasBeenFedFirstGoodFrame ) + { +#endif + if ( apa_set_scale( hVoIP->hTimeScaler, (uint16_t) scale ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } +#ifdef JBM_TSM_ON_TCS + result = apa_exec( hVoIP->hTimeScaler, hVoIP->apaExecBuffer, hVoIP->nSamplesFrame * nTransportChannels, (uint16_t) maxScaling, hVoIP->apaExecBuffer, &nTimeScalerOutSamples ); +#else result = apa_exec( hVoIP->hTimeScaler, hVoIP->apaExecBuffer, hVoIP->nSamplesFrame, (uint16_t) maxScaling, hVoIP->apaExecBuffer, &nTimeScalerOutSamples ); - if ( result != 0 ) - { - return IVAS_ERR_UNKNOWN; - } - assert( nTimeScalerOutSamples <= APA_BUF ); +#endif + if ( result != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + assert( nTimeScalerOutSamples <= APA_BUF ); +#ifdef JBM_TSM_ON_TCS + nSamplesTcsScaled = nTimeScalerOutSamples / nTransportChannels; +#else /* append scaled samples to FIFO */ if ( pcmdsp_fifo_write( hVoIP->hFifoAfterTimeScaler, (uint8_t *) hVoIP->apaExecBuffer, (uint16_t) ( nTimeScalerOutSamples / hDecoderConfig->nchan_out ) ) != 0 ) { return IVAS_ERR_UNKNOWN; } +#endif +#ifdef JBM_TSM_ON_TCS + if ( hIvasDec->hasBeenFedFirstGoodFrame && hVoIP->rendererType != JBM_RENDERER_NONE ) + { + /* render IVAS frames */ + int16_t nResidualSamples; + if ( ( error = IVAS_DEC_RendererFeedTcSamples( hIvasDec, nSamplesTcsScaled, &nResidualSamples, hVoIP->apaExecBuffer ) ) != IVAS_ERR_OK ) + { + return error; + } + /* feed residual samples to TSM for the next call */ + if ( apa_set_renderer_residual_samples( hVoIP->hTimeScaler, (uint16_t) nResidualSamples ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + } + else + { + /* inplace float->int16_t conversion*/ +#ifdef DEBUGGING + st_ivas->noClipping += +#endif + syn_output( hVoIP->apaExecBuffer, nTimeScalerOutSamples, (int16_t *) hVoIP->apaExecBuffer ); +#endif + if ( pcmdsp_fifo_write( hVoIP->hFifoOut, (uint8_t *) hVoIP->apaExecBuffer, nSamplesTcsScaled ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + nSamplesRendered = nSamplesTcsScaled; + } + } #ifdef SUPPORT_JBM_TRACEFILE - /* jbmWriterFn and jbmWriter may be NULL if tracefile writing was not requested on CLI */ - if ( jbmWriterFn != NULL && jbmWriter != NULL ) + /* jbmWriterFn and jbmWriter may be NULL if tracefile writing was not requested on CLI */ + if ( jbmWriterFn != NULL && jbmWriter != NULL ) + { + /* write JBM trace data entry */ + store_JbmData( hVoIP, dataUnit, systemTimestamp_ms, extBufferedSamples, hDecoderConfig->output_Fs ); + if ( ( jbmWriterFn( &hVoIP->JbmTraceData, jbmWriter ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError writing JBM Trace data to file\n" ); + return IVAS_ERR_UNKNOWN; + } + } +#endif +#ifdef JBM_TSM_ON_TCS + } + if ( hIvasDec->hasBeenFedFirstGoodFrame && hVoIP->rendererType != JBM_RENDERER_NONE ) + { + uint16_t nSamplesRendered_loop; + int16_t nSamplesToRender; + if ( hVoIP->hFifoOut ) + { + int16_t rendererPcmBuf[( MAX_OUTPUT_CHANNELS * L_FRAME_MAX * APA_MAX_SCALE ) / 100]; + nSamplesToRender = nSamplesPerChannel - pcmdsp_fifo_nReadableSamplesPerChannel( hVoIP->hFifoOut ); + /* render IVAS frames */ + if ( ( error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesRendered_loop, &hVoIP->nSamplesAvailableNext, rendererPcmBuf ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( pcmdsp_fifo_write( hVoIP->hFifoOut, (uint8_t *) rendererPcmBuf, nSamplesRendered_loop ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + } + else + { + nSamplesToRender = nSamplesPerChannel - nSamplesRendered; + /* render IVAS frames directly to the output buffer */ + if ( ( error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesRendered_loop, &hVoIP->nSamplesAvailableNext, pcmBuf + nSamplesRendered * nOutChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + } + nSamplesRendered += nSamplesRendered_loop; +#ifdef VARIABLE_SPEED_DECODING + if ( hVoIP->mode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED && hVoIP->nSamplesAvailableNext == 0 ) + { + hVoIP->needNewFrame = true; + } +#endif + } + else if ( !hIvasDec->hasBeenFedFirstGoodFrame && hVoIP->hFifoOut == NULL ) { - /* write JBM trace data entry */ - store_JbmData( hVoIP, dataUnit, systemTimestamp_ms, extBufferedSamples, hDecoderConfig->output_Fs ); - if ( ( jbmWriterFn( &hVoIP->JbmTraceData, jbmWriter ) ) != IVAS_ERR_OK ) + hVoIP->nSamplesAvailableNext = 0; + } + else + { + hVoIP->nSamplesAvailableNext = max( 0, pcmdsp_fifo_nReadableSamplesPerChannel( hVoIP->hFifoOut ) - nSamplesPerChannel ); +#ifdef VARIABLE_SPEED_DECODING + if ( hVoIP->mode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED && hVoIP->nSamplesAvailableNext < nSamplesPerChannel ) { - fprintf( stderr, "\nError writing JBM Trace data to file\n" ); - return IVAS_ERR_UNKNOWN; + hVoIP->needNewFrame = true; } +#endif + hVoIP->nSamplesAvailableNext = 0; } #endif } /* fetch a user-specified number of samples from FIFO */ +#if defined( JBM_TSM_ON_TCS ) + if ( hVoIP->hFifoOut ) + { + if ( pcmdsp_fifo_read( hVoIP->hFifoOut, nSamplesPerChannel, (uint8_t *) pcmBuf ) != 0 ) +#else if ( pcmdsp_fifo_read( hVoIP->hFifoAfterTimeScaler, nSamplesPerChannel, (uint8_t *) pcmBuf ) != 0 ) +#endif + { + return IVAS_ERR_UNKNOWN; + } +#ifdef JBM_TSM_ON_TCS + } +#endif + +#if defined( JBM_TSM_ON_TCS ) || defined( VARIABLE_SPEED_DECODING ) +#ifdef JBM_TSM_ON_TCS + *sampleAvailableNext = hVoIP->nSamplesAvailableNext; +#else + *sampleAvailableNext = max( 0, pcmdsp_fifo_nReadableSamplesPerChannel( hVoIP->hFifoAfterTimeScaler ) ); +#endif +#endif + + return error; +} + +/*---------------------------------------------------------------------* + * IVAS_DEC_VoIP_Flush( ) + * + * Function to flush remaining audio in VoIP + *---------------------------------------------------------------------*/ + +#if defined( VARIABLE_SPEED_DECODING ) || defined( JBM_TSM_ON_TCS ) +ivas_error IVAS_DEC_VoIP_Flush( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ + 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 */ + uint16_t *nSamplesAvailableNext, /* o : number of samples still available */ + int16_t *nSamplesFlushed /* o : number of samples flushed */ +) +{ + ivas_error error; + Decoder_Struct *st_ivas; + DECODER_CONFIG_HANDLE hDecoderConfig; + IVAS_DEC_VOIP *hVoIP; + int16_t rendererPcmBuf[( MAX_OUTPUT_CHANNELS * L_FRAME_MAX * APA_MAX_SCALE ) / 100]; + uint16_t nSamplesToRender; + uint16_t nSamplesFlushedLocal; + error = IVAS_ERR_OK; + + st_ivas = hIvasDec->st_ivas; + hDecoderConfig = st_ivas->hDecoderConfig; + hVoIP = hIvasDec->hVoIP; +#if defined( JBM_TSM_ON_TCS ) + *nSamplesFlushed = min( nSamplesPerChannel, hVoIP->nSamplesAvailableNext ); +#else + *nSamplesFlushed = min( nSamplesPerChannel, pcmdsp_fifo_nReadableSamplesPerChannel( hVoIP->hFifoAfterTimeScaler ) ); +#endif +#ifdef JBM_TSM_ON_TCS + if ( hVoIP->rendererType == JBM_RENDERER_NONE ) { - return IVAS_ERR_UNKNOWN; +#endif + /* fetch a user-specified number of samples from FIFO */ +#if defined( JBM_TSM_ON_TCS ) + if ( pcmdsp_fifo_read( hVoIP->hFifoOut, *nSamplesFlushed, (uint8_t *) pcmBuf ) != 0 ) +#else + if ( pcmdsp_fifo_read( hVoIP->hFifoAfterTimeScaler, *nSamplesFlushed, (uint8_t *) pcmBuf ) != 0 ) +#endif + { + return IVAS_ERR_UNKNOWN; + } +#if defined( JBM_TSM_ON_TCS ) + hVoIP->nSamplesAvailableNext -= *nSamplesFlushed; + *nSamplesAvailableNext = hVoIP->nSamplesAvailableNext; +#else + *nSamplesAvailableNext = pcmdsp_fifo_nReadableSamplesPerChannel( hVoIP->hFifoAfterTimeScaler ); +#endif +#ifdef JBM_TSM_ON_TCS } + else + { + nSamplesToRender = (uint16_t) *nSamplesFlushed; + /* render IVAS frames */ + if ( ( error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesFlushedLocal, &hVoIP->nSamplesAvailableNext, rendererPcmBuf ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( pcmdsp_fifo_write( hVoIP->hFifoOut, (uint8_t *) rendererPcmBuf, nSamplesFlushedLocal ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + if ( pcmdsp_fifo_read( hVoIP->hFifoOut, nSamplesFlushedLocal, (uint8_t *) pcmBuf ) != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + *nSamplesAvailableNext = hVoIP->nSamplesAvailableNext; + *nSamplesFlushed = (int16_t) nSamplesFlushedLocal; + } +#endif return error; } +#endif /*---------------------------------------------------------------------* @@ -1604,9 +2256,17 @@ ivas_error IVAS_DEC_VoIP_GetSamples( bool IVAS_DEC_VoIP_IsEmpty( IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +#ifdef JBM_TSM_ON_TCS + , + int16_t nSamplesAsked +#endif ) { +#ifdef JBM_TSM_ON_TCS + return ( ( JB4_bufferedDataUnits( hIvasDec->hVoIP->hJBM ) == 0 ) && ( hIvasDec->hVoIP->nSamplesAvailableNext < nSamplesAsked ) ); +#else return JB4_bufferedDataUnits( hIvasDec->hVoIP->hJBM ) == 0; +#endif } @@ -1647,8 +2307,11 @@ static void IVAS_DEC_Close_VoIP( apa_exit( &hVoIP->hTimeScaler ); +#ifdef JBM_TSM_ON_TCS + pcmdsp_fifo_destroy( &hVoIP->hFifoOut ); +#else pcmdsp_fifo_destroy( &hVoIP->hFifoAfterTimeScaler ); - +#endif if ( hVoIP->apaExecBuffer != NULL ) { free( hVoIP->apaExecBuffer ); @@ -2103,6 +2766,9 @@ void IVAS_DEC_PrintDisclaimer( void ) static ivas_error evs_dec_main( Decoder_Struct *st_ivas, const int16_t nOutSamples, +#ifdef JBM_TSM_ON_TCS + float *floatBuf, +#endif int16_t *pcmBuf ) { DEC_CORE_HANDLE *hCoreCoder; @@ -2161,12 +2827,23 @@ static ivas_error evs_dec_main( st_ivas->BER_detect = hCoreCoder[0]->BER_detect; - /* convert 'float' output data to 'short' */ +#ifdef JBM_TSM_ON_TCS + if ( floatBuf != NULL ) + { + mvr2r( output, floatBuf, nOutSamples ); + } + else + { + +#endif + /* convert 'float' output data to 'short' */ #ifdef DEBUGGING - st_ivas->noClipping += + st_ivas->noClipping += +#endif + syn_output( output, nOutSamples, pcmBuf ); +#ifdef JBM_TSM_ON_TCS + } #endif - syn_output( output, nOutSamples, pcmBuf ); - return error; } @@ -2357,3 +3034,124 @@ static ivas_error input_format_API_to_internal( return IVAS_ERR_OK; } + +#ifdef JBM_TSM_ON_TCS +static int16_t IVAS_DEC_VoIP_GetRenderGranularity( Decoder_Struct *st_ivas ) +{ + + return st_ivas->hTcBuffer->n_samples_granularity; +} + +static JBM_RENDERER_TYPE IVAS_DEC_VoIP_GetRendererConfig( IVAS_DEC_HANDLE hIvasDec ) +{ + JBM_RENDERER_TYPE rendererType; + rendererType = JBM_RENDERER_NONE; + + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + { + rendererType = JBM_RENDERER_NONE; + } + else + { + rendererType = JBM_RENDERER_IVAS; + } + + return rendererType; +} + +ivas_error IVAS_DEC_VoIP_reconfigure( IVAS_DEC_HANDLE hIvasDec, const uint16_t nTransportChannels, const uint16_t l_ts ) +{ + + IVAS_DEC_VOIP *hVoIP; + ivas_error error; + + + hVoIP = hIvasDec->hVoIP; + + if ( hIvasDec->hVoIP->hTimeScaler == NULL ) + { + + uint16_t wss, css; + float startQuality; + DECODER_CONFIG_HANDLE hDecoderConfig; + +#ifdef VARIABLE_SPEED_DECODING + startQuality = hVoIP->mode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED ? -2.0f : 1.0f; +#else + startQuality = 1.0f; +#endif + /* get current renderer type*/ + hVoIP->rendererType = IVAS_DEC_VoIP_GetRendererConfig( hIvasDec ); + hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; + if ( hDecoderConfig->output_Fs == 8000 ) + { + wss = 1; + css = 1; + } + else if ( hDecoderConfig->output_Fs == 16000 ) + { + wss = 2; + css = 1; + } + else if ( hDecoderConfig->output_Fs == 32000 ) + { + wss = 4; + css = 2; + } + else if ( hDecoderConfig->output_Fs == 48000 ) + { + wss = 6; + css = 3; + } + else + { + return IVAS_ERR_INIT_ERROR; + } + hIvasDec->hVoIP->apaExecBuffer = malloc( sizeof( float ) * APA_BUF_PER_CHANNEL * nTransportChannels ); + set_zero( hIvasDec->hVoIP->apaExecBuffer, APA_BUF_PER_CHANNEL * nTransportChannels ); + if ( hIvasDec->hVoIP->apaExecBuffer == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); + } + if ( apa_init( &hIvasDec->hVoIP->hTimeScaler, + nTransportChannels ) != IVAS_ERR_OK || + apa_set_rate( hIvasDec->hVoIP->hTimeScaler, hDecoderConfig->output_Fs ) != 0 || + apa_set_complexity_options( hIvasDec->hVoIP->hTimeScaler, wss, css ) != 0 || + apa_set_quality( hIvasDec->hVoIP->hTimeScaler, startQuality, 4, 4 ) != 0 || + apa_set_renderer_granularity( hIvasDec->hVoIP->hTimeScaler, l_ts ) != 0 ) + { + return IVAS_ERR_INIT_ERROR; + } + if ( hVoIP->hFifoOut == NULL && hVoIP->rendererType == JBM_RENDERER_NONE ) + { + /* we still need the FIFO out buffer */ + if ( pcmdsp_fifo_create( &hIvasDec->hVoIP->hFifoOut ) != 0 || + pcmdsp_fifo_init( hIvasDec->hVoIP->hFifoOut, (uint16_t) ( hDecoderConfig->output_Fs * 4 / FRAMES_PER_SEC ) /* 4 frames */, hDecoderConfig->nchan_out, sizeof( int16_t ) ) != 0 ) + { + return IVAS_ERR_INIT_ERROR; + } + } + } + else + { + if ( apa_reconfigure( hVoIP->hTimeScaler, nTransportChannels, l_ts ) != 0 ) + { + return IVAS_ERR_INIT_ERROR; + } + + /* realloc apa_exe_buffer */ + free( hIvasDec->hVoIP->apaExecBuffer ); + hIvasDec->hVoIP->apaExecBuffer = malloc( sizeof( float ) * APA_BUF_PER_CHANNEL * nTransportChannels ); + set_zero( hIvasDec->hVoIP->apaExecBuffer, APA_BUF_PER_CHANNEL * nTransportChannels ); + if ( hIvasDec->hVoIP->apaExecBuffer == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); + } + } + hIvasDec->hVoIP->nTransportChannelsOld = (uint8_t) nTransportChannels; + + error = IVAS_ERR_OK; + + return error; +} +#endif diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 17af564295..8178aa6262 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -77,6 +77,15 @@ typedef enum IVAS_DEC_INPUT_FORMAT_RTPDUMP_HF = 4, /* RTP payload: only Header-Full format without zero padding for size collision avoidance */ } IVAS_DEC_INPUT_FORMAT; + +#ifdef VARIABLE_SPEED_DECODING +typedef enum +{ + IVAS_DEC_VOIP_MODE_VOIP = 0, + IVAS_DEC_VOIP_MODE_VARIABLE_SPEED = 1 +} IVAS_DEC_VOIP_MODE; +#endif + #ifdef DEBUGGING typedef enum _IVAS_DEC_FORCED_REND_MODE { @@ -199,23 +208,49 @@ ivas_error IVAS_DEC_VoIP_FeedFrame( const bool qBit /* i : Q bit for AMR-WB IO */ ); +#ifdef VARIABLE_SPEED_DECODING +/*! r: error code */ +ivas_error IVAS_DEC_VoIP_SetScale( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t scale /* i : TSM scale to set */ +); +#endif + /*! r: error code */ ivas_error IVAS_DEC_VoIP_GetSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ 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 */ const uint32_t systemTimestamp_ms /* i : current system timestamp */ +#if defined( JBM_TSM_ON_TCS ) || defined(VARIABLE_SPEED_DECODING ) + , + uint16_t *sampleAvailableNext /* o : samples available for the next call */ +#endif #ifdef SUPPORT_JBM_TRACEFILE , JbmTraceFileWriterFn jbmWriterFn, void* jbmWriter #endif ); +#if defined( JBM_TSM_ON_TCS ) || defined(VARIABLE_SPEED_DECODING ) +ivas_error IVAS_DEC_VoIP_Flush( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ + 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 */ + uint16_t *nSamplesAvailableNext, /* o : number of samples still available */ + int16_t *nSamplesFlushed /* o : number of samples flushed */ +); +#endif + /* Setter functions - apply changes to decoder configuration */ /*! r: error code */ ivas_error IVAS_DEC_EnableVoIP( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ +#ifdef VARIABLE_SPEED_DECODING + const IVAS_DEC_VOIP_MODE voipMode, /* i : VoIP or varable speed */ + const uint16_t speedFac, /* i : speed factor for varable speed */ +#endif const int16_t jbmSafetyMargin, /* i : allowed delay reserve for JBM, in milliseconds */ const IVAS_DEC_INPUT_FORMAT inputFormat /* i : format of the input bitstream */ ); @@ -331,6 +366,10 @@ ivas_error IVAS_DEC_GetPcmFrameSize( /*! r: true if decoder has no data in VoIP jitter buffer */ bool IVAS_DEC_VoIP_IsEmpty( IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +#ifdef JBM_TSM_ON_TCS + , + int16_t nSamplesAsked +#endif ); ivas_error IVAS_DEC_VoIP_Get_CA_offset( diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index c05ae7c262..8dc6fa6783 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -939,8 +939,13 @@ static ivas_error ivas_rend_crendConvolver( const CREND_WRAPPER *pCrend, IVAS_REND_AudioConfig inConfig, IVAS_REND_AudioConfig outConfig, +#ifdef JBM_TSM_ON_TCS + float *pcm_in[], + float *pcm_out[], +#else float pcm_in[][L_FRAME48k], float pcm_out[][L_FRAME48k], +#endif const int32_t output_Fs, const int16_t i_ts ) { @@ -1105,12 +1110,19 @@ ivas_error ivas_rend_crendProcess( HEAD_TRACK_DATA_HANDLE hHeadTrackData, IVAS_OUTPUT_SETUP_HANDLE hIntSetup, EFAP_HANDLE hEFAPdata, +#ifdef JBM_TSM_ON_TCS + float *output[], /* i/o: input/output audio channels */ +#else float output[][L_FRAME48k], /* i/o: input/output audio channels */ +#endif const int32_t output_Fs ) { int16_t i, subframe_idx, output_frame, subframe_len; int16_t nchan_out; float pcm_tmp[BINAURAL_CHANNELS][L_FRAME48k]; +#ifdef JBM_TSM_ON_TCS + float *p_pcm_tmp[BINAURAL_CHANNELS]; +#endif AUDIO_CONFIG in_config; IVAS_REND_AudioConfigType inConfigType; ivas_error error; @@ -1133,6 +1145,12 @@ ivas_error ivas_rend_crendProcess( output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC ); subframe_len = output_frame / MAX_PARAM_SPATIAL_SUBFRAMES; +#ifdef JBM_TSM_ON_TCS + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + p_pcm_tmp[i] = pcm_tmp[i]; + } +#endif for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { if ( hDecoderConfig && hDecoderConfig->Opt_Headrotation && hHeadTrackData && hHeadTrackData->num_quaternions >= 0 ) @@ -1156,14 +1174,22 @@ ivas_error ivas_rend_crendProcess( if ( ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) || ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) ) { +#ifdef JBM_TSM_ON_TCS + if ( ( error = ivas_rend_crendConvolver( pCrend, inRendConfig, outRendConfig, output, p_pcm_tmp, output_Fs, subframe_idx ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendConvolver( pCrend, inRendConfig, outRendConfig, output, pcm_tmp, output_Fs, subframe_idx ) ) != IVAS_ERR_OK ) +#endif { return error; } if ( pCrend->hCrend->hReverb != NULL ) { +#ifdef JBM_TSM_ON_TCS + if ( ( error = ivas_reverb_process( pCrend->hCrend->hReverb, in_config, 1, output, p_pcm_tmp, subframe_idx ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_reverb_process( pCrend->hCrend->hReverb, in_config, 1, output, pcm_tmp, subframe_idx ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1185,3 +1211,131 @@ ivas_error ivas_rend_crendProcess( return IVAS_ERR_OK; } + +#ifdef JBM_TSM_ON_TCS +ivas_error ivas_rend_crendProcessSubframe( + const CREND_WRAPPER *pCrend, + const AUDIO_CONFIG inConfig, + const AUDIO_CONFIG outConfig, + DECODER_CONFIG_HANDLE hDecoderConfig, + HEAD_TRACK_DATA_HANDLE hHeadTrackData, + IVAS_OUTPUT_SETUP_HANDLE hIntSetup, + EFAP_HANDLE hEFAPdata, + DECODER_TC_BUFFER_HANDLE hTcBuffer, + float *input_f[], + float *output[], /* i/o: input/output audio channels */ + const int16_t n_samples_to_render, + const int32_t output_Fs ) +{ + int16_t subframe_idx, subframe_len; + int16_t nchan_out, nchan_in, ch, first_sf, last_sf, slot_size, slots_to_render; + float *tc_local[MAX_TRANSPORT_CHANNELS]; + float pcm_tmp[BINAURAL_CHANNELS][L_FRAME48k]; + float *p_pcm_tmp[BINAURAL_CHANNELS]; + AUDIO_CONFIG in_config; + IVAS_REND_AudioConfigType inConfigType; + ivas_error error; + IVAS_REND_AudioConfig inRendConfig; + IVAS_REND_AudioConfig outRendConfig; + + push_wmops( "ivas_rend_crendProcessSubframe" ); + + inRendConfig = getRendAudioConfigFromIvasAudioConfig( inConfig ); + outRendConfig = getRendAudioConfigFromIvasAudioConfig( outConfig ); + + in_config = getIvasAudioConfigFromRendAudioConfig( inRendConfig ); + inConfigType = getAudioConfigType( inRendConfig ); + if ( ( error = getAudioConfigNumChannels( outRendConfig, &nchan_out ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = getAudioConfigNumChannels( inRendConfig, &nchan_in ) ) != IVAS_ERR_OK ) + { + return error; + } + + for ( ch = 0; ch < nchan_in; ch++ ) + { + tc_local[ch] = input_f[ch]; + } + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + p_pcm_tmp[ch] = pcm_tmp[ch]; + } + + slot_size = hTcBuffer->n_samples_granularity; + /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ + slots_to_render = min( hTcBuffer->num_slots - hTcBuffer->slots_rendered, n_samples_to_render / slot_size ); + first_sf = hTcBuffer->subframes_rendered; + last_sf = first_sf; + hTcBuffer->slots_rendered += slots_to_render; + while ( slots_to_render > 0 ) + { + slots_to_render -= hTcBuffer->subframe_nbslots[last_sf]; + last_sf++; + } + + for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) + { + subframe_len = hTcBuffer->subframe_nbslots[subframe_idx] * hTcBuffer->n_samples_granularity; + if ( hDecoderConfig && hDecoderConfig->Opt_Headrotation && hHeadTrackData && hHeadTrackData->num_quaternions >= 0 ) + { + + /* Rotation in SHD for: + MC with elevation (5_1_2 / 5_1_4 / 7_1_4) -> BINAURAL + SBA SPAR -> BINAURAL or BINAURAL_ROOM + */ + if ( in_config == AUDIO_CONFIG_FOA || in_config == AUDIO_CONFIG_HOA2 || in_config == AUDIO_CONFIG_HOA3 ) + { + rotateFrame_shd( hHeadTrackData, tc_local, subframe_len, *hIntSetup, 0 ); + } + /* Rotation in SD for MC -> BINAURAL_ROOM */ + else if ( ( hIntSetup != NULL ) && hIntSetup->is_loudspeaker_setup ) + { + rotateFrame_sd( hHeadTrackData, tc_local, subframe_len, *hIntSetup, hEFAPdata, 0 ); + } + } + + if ( ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) || ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) ) + { + if ( ( error = ivas_rend_crendConvolver( pCrend, inRendConfig, outRendConfig, tc_local, p_pcm_tmp, output_Fs, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( pCrend->hCrend->hReverb != NULL ) + { + if ( ( error = ivas_reverb_process( pCrend->hCrend->hReverb, in_config, 1, tc_local, p_pcm_tmp, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + } + for ( ch = 0; ch < nchan_in; ch++ ) + { + tc_local[ch] += subframe_len; + } + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + p_pcm_tmp[ch] += subframe_len; + } + } + else + { + return IVAS_ERR_INVALID_INPUT_FORMAT; + } + } + + /* move to output */ + for ( ch = 0; ch < nchan_out; ch++ ) + { + mvr2r( pcm_tmp[ch], output[ch], n_samples_to_render ); + } + + + hTcBuffer->subframes_rendered = last_sf; + pop_wmops(); + + return IVAS_ERR_OK; +} +#endif + diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 35819cf8cb..17969865e9 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -94,6 +94,17 @@ static void matrixTransp2Mul( float Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS], f static float configure_reqularization_factor( const IVAS_FORMAT ivas_format, const int32_t ivas_brate ); +#ifdef JBM_TSM_ON_TCS +static void ivas_dirac_dec_binaural_process_output_sf( Decoder_Struct *st_ivas, float *output_f[], float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t max_band_decorr, const uint8_t numInChannels ); + +static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked_sf( HEAD_TRACK_DATA_HANDLE hHeadTrackData, float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const uint8_t slotEnd, const uint8_t nBins, float Rmat[3][3] ); + +static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_sf( Decoder_Struct *st_ivas, float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], int16_t azimuth[][CLDFB_NO_CHANNELS_MAX], int16_t elevation[][CLDFB_NO_CHANNELS_MAX], float energy_ratio1[][CLDFB_NO_CHANNELS_MAX], float spreadCoherence[][CLDFB_NO_CHANNELS_MAX], float surroundingCoherence[][CLDFB_NO_CHANNELS_MAX], float Rmat[3][3] ); + +static void ivas_dirac_dec_binaural_internal_sf( Decoder_Struct *st_ivas, float *output_f[], const int16_t nchan_transport ); + +static void ivas_dirac_dec_decorrelate_slot_sf( DIRAC_DEC_HANDLE hDirAC, const int8_t slot, float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float decRe[][CLDFB_NO_CHANNELS_MAX], float decIm[][CLDFB_NO_CHANNELS_MAX] ); +#endif /*------------------------------------------------------------------------- * ivas_dirac_dec_init_binaural_data() * @@ -112,6 +123,9 @@ ivas_error ivas_dirac_dec_init_binaural_data( int16_t j, k, bin; float binCenterFreq, tmpFloat; ivas_error error; +#ifdef JBM_TSM_ON_TCS + int16_t reverbBlockSize; +#endif hBinaural = st_ivas->hDiracDecBin; @@ -213,6 +227,18 @@ ivas_error ivas_dirac_dec_init_binaural_data( { if ( hBinaural->useSubframeMode ) { +#ifdef JBM_TSM_ON_TCS + reverbBlockSize = st_ivas->hDecoderConfig->voip_active ? 1 : CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; + if ( ( error = ivas_binaural_reverb_open( &hBinaural->hReverb, + nBins, + reverbBlockSize, NULL, + st_ivas->hIntSetup.output_config, + output_Fs, + RENDERER_BINAURAL_PARAMETRIC_ROOM, + st_ivas->hHrtfFastConv, + st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK ) + +#else if ( ( error = ivas_binaural_reverb_open( &hBinaural->hReverb, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, NULL, @@ -221,6 +247,7 @@ ivas_error ivas_dirac_dec_init_binaural_data( RENDERER_BINAURAL_PARAMETRIC_ROOM, st_ivas->hHrtfFastConv, st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -285,6 +312,21 @@ ivas_error ivas_dirac_dec_init_binaural_data( st_ivas->hDiracDecBin = hBinaural; +#ifdef JBM_TSM_ON_TCS + /* allocate transport channels*/ + if ( st_ivas->hDecoderConfig->voip_active == 1 && st_ivas->hTcBuffer == NULL ) + { + int16_t nchan_to_allocate; + + nchan_to_allocate = 2 * BINAURAL_CHANNELS; + if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, ivas_jbm_dec_get_num_tc_channels( st_ivas ), nchan_to_allocate, nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) + { + return error; + } + } + +#endif /* JBM_TMS_ON_TCS*/ + return IVAS_ERR_OK; } @@ -363,6 +405,71 @@ ivas_error ivas_dirac_dec_binaural_copy_hrtfs( return IVAS_ERR_OK; } +#ifdef JBM_TSM_ON_TCS +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 */ + uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ + uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ + const int16_t nchan_transport, + float *output_f[] /* o : rendered time signal */ +) +{ + int16_t slots_to_render, first_sf, last_sf, subframe_idx; + uint16_t slot_size, ch; + uint16_t nchan_out; + DIRAC_DEC_HANDLE hDirAC; + float *output_f_local[MAX_OUTPUT_CHANNELS]; + + hDirAC = st_ivas->hDirAC; + nchan_out = BINAURAL_CHANNELS; +#ifdef DEBUGGING + assert( hDirAC ); +#endif + for ( ch = 0; ch < nchan_out; ch++ ) + { + output_f_local[ch] = output_f[ch]; + } + slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); + /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ + slots_to_render = min( hDirAC->num_slots - hDirAC->slots_rendered, nSamplesAsked / slot_size ); + *nSamplesRendered = slots_to_render * slot_size; + first_sf = hDirAC->subframes_rendered; + last_sf = first_sf; + while ( slots_to_render > 0 ) + { + slots_to_render -= hDirAC->subframe_nbslots[last_sf]; + last_sf++; + } +#ifdef DEBUGGING + assert( slots_to_render == 0 ); +#endif + for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) + { + int16_t n_samples_sf = slot_size * hDirAC->subframe_nbslots[subframe_idx]; + ivas_dirac_dec_binaural_internal_sf( st_ivas, output_f_local, nchan_transport ); + for ( ch = 0; ch < nchan_out; ch++ ) + { + output_f_local[ch] += n_samples_sf; + } + } + if ( hDirAC->slots_rendered == hDirAC->num_slots ) + { + if ( st_ivas->hDirAC->hConfig != NULL && st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) + { + st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % st_ivas->hDirAC->dirac_md_buffer_length; + } + else + { + st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % st_ivas->hDirAC->dirac_md_buffer_length; + } + } + *nSamplesAvailable = ( hDirAC->num_slots - hDirAC->slots_rendered ) * slot_size; + + return; +} +#endif + /*------------------------------------------------------------------------- * ivas_dirac_dec_binaural() * @@ -375,34 +482,96 @@ void ivas_dirac_dec_binaural( const int16_t nchan_transport /* i : number of transport channels */ ) { +#ifdef JBM_TSM_ON_TCS + float cng_td_buffer[L_FRAME16k]; + float *p_output[MAX_OUTPUT_CHANNELS]; + int16_t ch, n_samples_sf; + + n_samples_sf = JBM_CLDFB_SLOTS_IN_SUBFRAME * st_ivas->hDirAC->slot_size; + + for ( ch = 0; ch < 2 * BINAURAL_CHANNELS; ch++ ) + { + p_output[ch] = &output_f[ch][0]; + } + for ( ch = 0; ch < nchan_transport; 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->sba_mode == SBA_MODE_SPAR ) + { + ivas_spar_dec_set_render_map( st_ivas, DEFAULT_JBM_CLDFB_TIMESLOTS ); + } + +#endif +#ifdef DEBUG_MODE_JBM + dbgwritewav( st_ivas->hDirAC->slot_size * 16, NULL, output_f, nchan_transport, st_ivas->hDecoderConfig->output_Fs, "res/dirac_dec_binaural_tc.wav" ); +#endif if ( st_ivas->hDiracDecBin->useTdDecorr ) { float *decorr_signal[BINAURAL_CHANNELS]; +#ifndef JBM_TSM_ON_TCS int16_t ch; +#endif int16_t output_frame; for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { decorr_signal[ch] = (float *) &( output_f[ch + BINAURAL_CHANNELS][0] ); +#ifdef JBM_TSM_ON_TCS + st_ivas->hTcBuffer->tc[ch + BINAURAL_CHANNELS] = decorr_signal[ch]; +#endif } output_frame = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); - +#ifdef JBM_TSM_ON_TCS + { + ivas_td_decorr_process( st_ivas->hDiracDecBin->hTdDecorr, p_output, decorr_signal, output_frame ); + } +#else ivas_td_decorr_process( st_ivas->hDiracDecBin->hTdDecorr, output_f, decorr_signal, output_frame ); +#endif +#ifdef DEBUG_MODE_JBM + dbgwritewav( st_ivas->hDirAC->slot_size * 16, decorr_signal, output_f, BINAURAL_CHANNELS, st_ivas->hDecoderConfig->output_Fs, "res/dirac_dec_binaural_tddecorr.wav" ); +#endif + } +#ifdef JBM_TSM_ON_TCS + 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 ); +#ifdef DEBUG_MODE_JBM + dbgwritewav( st->hFdCngDec->hFdCngCom->frameSize, &( st_ivas->hTcBuffer->tc[nchan_transport] ), output_f, 1, st->hFdCngDec->hFdCngCom->frameSize * FRAMES_PER_SEC, "res/dirac_dec_binaural_cng.wav" ); +#endif } +#endif if ( st_ivas->hDiracDecBin->useSubframeMode ) { uint8_t subframe; for ( subframe = 0; subframe < MAX_PARAM_SPATIAL_SUBFRAMES; subframe++ ) { +#ifdef DEBUG_JBM + ivas_dirac_dec_binaural_internal_sf( st_ivas, p_output, nchan_transport ); + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + p_output[ch] += n_samples_sf; + } +#else ivas_dirac_dec_binaural_internal( st_ivas, output_f, nchan_transport, subframe, 1u ); +#endif } } else { ivas_dirac_dec_binaural_internal( st_ivas, output_f, nchan_transport, 0u, (uint8_t) MAX_PARAM_SPATIAL_SUBFRAMES ); } - +#ifdef JBM_TSM_ON_TCS + for ( ch = 0; ch < 2 * BINAURAL_CHANNELS; ch++ ) + { + st_ivas->hTcBuffer->tc[ch] = NULL; + } +#endif return; } @@ -410,6 +579,209 @@ void ivas_dirac_dec_binaural( /*------------------------------------------------------------------------- * Local functions *------------------------------------------------------------------------*/ +#ifdef JBM_TSM_ON_TCS +static void ivas_dirac_dec_binaural_internal_sf( + Decoder_Struct *st_ivas, + float *output_f[], + const int16_t nchan_transport ) +{ + DIRAC_DEC_HANDLE hDirAC; + uint8_t slot, ch, nBins, numInChannels; + float Cldfb_RealBuffer_in[2 * BINAURAL_CHANNELS][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_in[2 * BINAURAL_CHANNELS][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + /* local copies of azi, ele, diffuseness */ + int16_t azimuth[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + int16_t elevation[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float spreadCoherence[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float surroundingCoherence[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float energy_ratio1[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float Rmat[3][3]; + uint16_t slot_idx, slot_idx_start, subframe_idx; + int16_t max_band_decorr; + DIFFUSE_DISTRIBUTION_DATA diffuseDistData; + + + hDirAC = st_ivas->hDirAC; + nBins = (uint8_t) hDirAC->num_freq_bands; + + /* The input channel number at this processing function (not nchan_transport) */ + numInChannels = BINAURAL_CHANNELS; + if ( st_ivas->hOutSetup.separateChannelEnabled ) + { + numInChannels++; + } + + 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; + + slot_idx_start = hDirAC->slots_rendered; + subframe_idx = hDirAC->subframes_rendered; + + /* copy parameters into local buffers*/ + for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) + { + mvs2s( hDirAC->azimuth[hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]], azimuth[slot_idx], hDirAC->num_freq_bands ); + mvs2s( hDirAC->elevation[hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]], elevation[slot_idx], hDirAC->num_freq_bands ); + mvr2r( hDirAC->spreadCoherence[hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]], spreadCoherence[slot_idx], hDirAC->num_freq_bands ); + mvr2r( hDirAC->surroundingCoherence[hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]], surroundingCoherence[slot_idx], hDirAC->num_freq_bands ); + mvr2r( hDirAC->energy_ratio1[hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]], energy_ratio1[slot_idx], hDirAC->num_freq_bands ); + } + + /* CLDFB Analysis of input */ + for ( slot = 0; slot < hDirAC->subframe_nbslots[hDirAC->subframes_rendered]; slot++ ) + { + for ( ch = 0; ch < numInChannels; ch++ ) + { + if ( ch == 0 || nchan_transport == 2 ) + { + cldfbAnalysis_ts( &( st_ivas->hTcBuffer->tc[ch][nBins * ( slot + slot_idx_start )] ), + Cldfb_RealBuffer_in[ch][slot], + Cldfb_ImagBuffer_in[ch][slot], + nBins, st_ivas->cldfbAnaDec[ch] ); + } + else if ( st_ivas->nchan_transport == 2 ) /* Stereo signal transmitted as mono with DFT stereo */ + { + /* At mono input duplicate the channel to dual-mono */ + mvr2r( Cldfb_RealBuffer_in[0][slot], Cldfb_RealBuffer_in[1][slot], nBins ); + mvr2r( Cldfb_ImagBuffer_in[0][slot], Cldfb_ImagBuffer_in[1][slot], nBins ); + } + else /* when nchan_transport == 1 and ch == 1 */ + { + /* CNA and HB FD-CNG*/ + if ( st_ivas->hSCE[0]->hCoreCoder[0] != NULL && st_ivas->hSCE[0]->hCoreCoder[0]->cng_sba_flag ) + { + int16_t numCoreBands, b; + + numCoreBands = st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->numCoreBands; + + + generate_masking_noise_dirac( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom, + st_ivas->cldfbAnaDec[1], + st_ivas->hTcBuffer->tc[nchan_transport], + Cldfb_RealBuffer_in[2][slot], Cldfb_ImagBuffer_in[2][slot], + slot + slot_idx_start, + st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->hSCE[0]->hCoreCoder[0]->flag_cna, + ( st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == FRAME_NO_DATA || st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == SID_2k40 ) && ( st_ivas->hSCE[0]->hCoreCoder[0]->cng_type == FD_CNG ) && st_ivas->hSCE[0]->hCoreCoder[0]->cng_sba_flag ); + + generate_masking_noise_dirac( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom, + st_ivas->cldfbAnaDec[1], /*nothing will be analyzed, just get cnst*/ + NULL, + Cldfb_RealBuffer_in[1][slot], Cldfb_ImagBuffer_in[1][slot], + slot + slot_idx_start, + st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->hSCE[0]->hCoreCoder[0]->flag_cna, + ( st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == FRAME_NO_DATA || st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == SID_2k40 ) && ( st_ivas->hSCE[0]->hCoreCoder[0]->cng_type == FD_CNG ) && st_ivas->hSCE[0]->hCoreCoder[0]->cng_sba_flag ); + + /* LB: Copy first channel + LB-CNG to first and second channels with same scaling (dual-mono)*/ + for ( b = 0; b < numCoreBands; b++ ) + { + Cldfb_RealBuffer_in[0][slot][b] = INV_SQRT2 * ( Cldfb_RealBuffer_in[0][slot][b] + Cldfb_RealBuffer_in[2][slot][b] ); + Cldfb_RealBuffer_in[1][slot][b] = Cldfb_RealBuffer_in[0][slot][b]; + Cldfb_ImagBuffer_in[0][slot][b] = INV_SQRT2 * ( Cldfb_ImagBuffer_in[0][slot][b] + Cldfb_ImagBuffer_in[2][slot][b] ); + Cldfb_ImagBuffer_in[1][slot][b] = Cldfb_ImagBuffer_in[0][slot][b]; + } + + /* HB: Copy first channel to second channel and add HB-CNGs with different scalings*/ + for ( ; b < nBins; b++ ) + { + Cldfb_RealBuffer_in[0][slot][b] *= INV_SQRT2; + Cldfb_RealBuffer_in[1][slot][b] = Cldfb_RealBuffer_in[0][slot][b] + 0.5f * Cldfb_RealBuffer_in[1][slot][b] + Cldfb_RealBuffer_in[0][slot][b]; + Cldfb_RealBuffer_in[0][slot][b] += 0.5f * Cldfb_RealBuffer_in[2][slot][b]; + + Cldfb_ImagBuffer_in[0][slot][b] *= INV_SQRT2; + Cldfb_ImagBuffer_in[1][slot][b] = Cldfb_ImagBuffer_in[0][slot][b] + 0.5f * Cldfb_ImagBuffer_in[1][slot][b]; + Cldfb_ImagBuffer_in[0][slot][b] += 0.5f * Cldfb_ImagBuffer_in[2][slot][b]; + } + } + else + { + /* 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 ( st_ivas->hDiracDecBin->useTdDecorr ) + { + for ( ch = BINAURAL_CHANNELS; ch < ( 2 * BINAURAL_CHANNELS ); ch++ ) + { + cldfbAnalysis_ts( &( st_ivas->hTcBuffer->tc[ch][nBins * ( slot + slot_idx_start )] ), + Cldfb_RealBuffer_in[ch][slot], + Cldfb_ImagBuffer_in[ch][slot], + nBins, st_ivas->cldfbAnaDec[ch] ); + + if ( st_ivas->nchan_transport == 1 && st_ivas->ivas_format == SBA_FORMAT ) + { + v_multc( Cldfb_RealBuffer_in[ch][slot], INV_SQRT_2, Cldfb_RealBuffer_in[ch][slot], nBins ); + v_multc( Cldfb_ImagBuffer_in[ch][slot], INV_SQRT_2, Cldfb_ImagBuffer_in[ch][slot], nBins ); + } + } + } + } + + if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR ) + { + st_ivas->hDirAC->hDiffuseDist = &diffuseDistData; + ivas_spar_param_to_masa_param_mapping_sf( st_ivas, azimuth, elevation, energy_ratio1, spreadCoherence, surroundingCoherence, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in ); + + ivas_sba_prototype_renderer_sf( st_ivas, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in ); + + /* we are done with SPAR, update SPAR info*/ + st_ivas->hSpar->slots_rendered += st_ivas->hSpar->subframe_nbslots[st_ivas->hSpar->subframes_rendered]; + st_ivas->hSpar->subframes_rendered++; + } + + if ( st_ivas->hHeadTrackData && st_ivas->hHeadTrackData->num_quaternions >= 0 ) + { + QuatToRotMat( st_ivas->hHeadTrackData->Quaternions[subframe_idx], Rmat ); + + if ( nchan_transport == 2 ) + { + ivas_dirac_dec_binaural_check_and_switch_transports_headtracked_sf( st_ivas->hHeadTrackData, Cldfb_ImagBuffer_in, Cldfb_RealBuffer_in, (uint8_t) hDirAC->subframe_nbslots[subframe_idx], nBins, Rmat ); + } + } + + ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_sf( st_ivas, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, azimuth, elevation, energy_ratio1, spreadCoherence, surroundingCoherence, Rmat ); + + if ( st_ivas->ivas_format == ISM_FORMAT ) + { + max_band_decorr = 0; + } + else if ( st_ivas->hDiracDecBin->useTdDecorr ) + { + max_band_decorr = CLDFB_NO_CHANNELS_MAX; + } + else + { + max_band_decorr = st_ivas->hDirAC->h_freq_domain_decorr_ap_params->max_band_decorr; + } + + ivas_dirac_dec_binaural_determine_processing_matrices( st_ivas, max_band_decorr, Rmat ); + + ivas_dirac_dec_binaural_process_output_sf( st_ivas, output_f, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, max_band_decorr, numInChannels ); + + /* we are done with DirAC, update DirAC info*/ + st_ivas->hDirAC->slots_rendered += st_ivas->hDirAC->subframe_nbslots[st_ivas->hDirAC->subframes_rendered]; + st_ivas->hDirAC->subframes_rendered++; + + st_ivas->hDirAC->hDiffuseDist = NULL; + + return; +} +#endif static void ivas_dirac_dec_binaural_internal( Decoder_Struct *st_ivas, @@ -481,7 +853,11 @@ static void ivas_dirac_dec_binaural_internal( generate_masking_noise_dirac( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom, st_ivas->cldfbAnaDec[1], +#ifdef JBM_TSM_ON_TCS + st_ivas->hTcBuffer->tc[1], +#else &( output_f[1][L_FRAME48k - L_FRAME16k] ), /*used as temporary static buffer for the whole frame*/ +#endif Cldfb_RealBuffer_in[2][slot], Cldfb_ImagBuffer_in[2][slot], slot, st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->hSCE[0]->hCoreCoder[0]->flag_cna, @@ -494,7 +870,18 @@ static void ivas_dirac_dec_binaural_internal( slot, st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->hSCE[0]->hCoreCoder[0]->flag_cna, ( st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == FRAME_NO_DATA || st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == SID_2k40 ) && ( st_ivas->hSCE[0]->hCoreCoder[0]->cng_type == FD_CNG ) && st_ivas->hSCE[0]->hCoreCoder[0]->cng_sba_flag ); - +#ifdef DEBUG_MODE_JBM + if ( slot == 0 ) + { +#ifdef JBM_TSM_ON_TCS + dbgwritewav( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->frameSize, &( st_ivas->tc[nchan_transport] ), output_f, 1, st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->frameSize * FRAMES_PER_SEC, "res/dirac_dec_binaural_cng.wav" ); +#else + float *tc[1]; + tc[0] = &( output_f[1][L_FRAME48k - L_FRAME16k] ); + dbgwritewav( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->frameSize, tc, output_f, 1, st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->frameSize * FRAMES_PER_SEC, "res/dirac_dec_binaural_cng.wav" ); +#endif + } +#endif /* LB: Copy first channel + LB-CNG to first and second channels with same scaling (dual-mono)*/ for ( b = 0; b < numCoreBands; b++ ) { @@ -533,10 +920,15 @@ static void ivas_dirac_dec_binaural_internal( { for ( ch = BINAURAL_CHANNELS; ch < ( 2 * BINAURAL_CHANNELS ); ch++ ) { - cldfbAnalysis_ts( &( output_f[ch][nBins * slot] ), - Cldfb_RealBuffer_in[ch][slot], - Cldfb_ImagBuffer_in[ch][slot], - nBins, st_ivas->cldfbAnaDec[ch] ); + cldfbAnalysis_ts( +#ifdef JBM_TSM_ON_TCS + &( st_ivas->hTcBuffer->tc[ch][nBins * slot] ), +#else + &( output_f[ch][nBins * slot] ), +#endif + Cldfb_RealBuffer_in[ch][slot], + Cldfb_ImagBuffer_in[ch][slot], + nBins, st_ivas->cldfbAnaDec[ch] ); if ( st_ivas->nchan_transport == 1 && st_ivas->ivas_format == SBA_FORMAT ) { @@ -589,6 +981,11 @@ static void ivas_dirac_dec_binaural_internal( st_ivas->hDirAC->hDiffuseDist = NULL; +#ifdef JBM_TSM_ON_TCS + st_ivas->hDirAC->slots_rendered += ( slotEnd - firstSlot ); + st_ivas->hDirAC->subframes_rendered += nSubframes; +#endif + return; } @@ -605,44 +1002,513 @@ static void ivas_dirac_dec_decorrelate_slot( float onset_filter[BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, 60 bins */ float decorrelatedFrameInterleaved[2 * BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, real + imag, 60 bins */ - /* Decorrelation needs interleaved data. Copy left and right signals to proto_frame_f */ - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - offset = hDirAC->num_freq_bands * BINAURAL_CHANNELS * ch; - for ( bin = 0; bin < hDirAC->num_freq_bands; bin++ ) + /* Decorrelation needs interleaved data. Copy left and right signals to proto_frame_f */ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + offset = hDirAC->num_freq_bands * BINAURAL_CHANNELS * ch; + for ( bin = 0; bin < hDirAC->num_freq_bands; bin++ ) + { + hDirAC->proto_frame_f[( bin * BINAURAL_CHANNELS ) + offset] = inRe[ch][slot][bin]; + hDirAC->proto_frame_f[( bin * BINAURAL_CHANNELS ) + offset + 1] = inIm[ch][slot][bin]; + } + } + + /* Decorrelate proto signal to decorrelatedFrameInterleaved */ + ivas_dirac_dec_decorr_process( hDirAC->num_freq_bands, + hDirAC->num_outputs_diff, + hDirAC->num_protos_diff, + hDirAC->synthesisConf, + BINAURAL_CHANNELS, + hDirAC->proto_frame_f, + hDirAC->num_protos_diff, + hDirAC->proto_index_diff, + decorrelatedFrameInterleaved, + onset_filter, + hDirAC->h_freq_domain_decorr_ap_params, + hDirAC->h_freq_domain_decorr_ap_state ); + + /* De-interleave decorrelated signals*/ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + offset = hDirAC->num_freq_bands * BINAURAL_CHANNELS * ch; + for ( bin = 0; bin < hDirAC->num_freq_bands; bin++ ) + { + decRe[ch][bin] = decorrelatedFrameInterleaved[( bin * BINAURAL_CHANNELS ) + offset]; + decIm[ch][bin] = decorrelatedFrameInterleaved[( bin * BINAURAL_CHANNELS ) + offset + 1]; + } + } + + return; +} + +#ifdef JBM_TSM_ON_TCS +static void ivas_dirac_dec_decorrelate_slot_sf( + DIRAC_DEC_HANDLE hDirAC, + const int8_t slot, + float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + float decRe[][CLDFB_NO_CHANNELS_MAX], + float decIm[][CLDFB_NO_CHANNELS_MAX] ) +{ + int16_t offset, ch, bin; + float onset_filter[BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, 60 bins */ + float decorrelatedFrameInterleaved[2 * BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, real + imag, 60 bins */ + + /* Decorrelation needs interleaved data. Copy left and right signals to proto_frame_f */ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + offset = hDirAC->num_freq_bands * BINAURAL_CHANNELS * ch; + for ( bin = 0; bin < hDirAC->num_freq_bands; bin++ ) + { + hDirAC->proto_frame_f[( bin * BINAURAL_CHANNELS ) + offset] = inRe[ch][slot][bin]; + hDirAC->proto_frame_f[( bin * BINAURAL_CHANNELS ) + offset + 1] = inIm[ch][slot][bin]; + } + } + + /* Decorrelate proto signal to decorrelatedFrameInterleaved */ + ivas_dirac_dec_decorr_process( hDirAC->num_freq_bands, + hDirAC->num_outputs_diff, + hDirAC->num_protos_diff, + hDirAC->synthesisConf, + BINAURAL_CHANNELS, + hDirAC->proto_frame_f, + hDirAC->num_protos_diff, + hDirAC->proto_index_diff, + decorrelatedFrameInterleaved, + onset_filter, + hDirAC->h_freq_domain_decorr_ap_params, + hDirAC->h_freq_domain_decorr_ap_state ); + + /* De-interleave decorrelated signals*/ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + offset = hDirAC->num_freq_bands * BINAURAL_CHANNELS * ch; + for ( bin = 0; bin < hDirAC->num_freq_bands; bin++ ) + { + decRe[ch][bin] = decorrelatedFrameInterleaved[( bin * BINAURAL_CHANNELS ) + offset]; + decIm[ch][bin] = decorrelatedFrameInterleaved[( bin * BINAURAL_CHANNELS ) + offset + 1]; + } + } + + return; +} + + +static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_sf( + Decoder_Struct *st_ivas, + float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + int16_t azimuth[][CLDFB_NO_CHANNELS_MAX], + int16_t elevation[][CLDFB_NO_CHANNELS_MAX], + float energy_ratio1[][CLDFB_NO_CHANNELS_MAX], + float spreadCoherence[][CLDFB_NO_CHANNELS_MAX], + float surroundingCoherence[][CLDFB_NO_CHANNELS_MAX], + float Rmat[3][3] ) +{ + uint8_t ch, bin; + uint8_t separateCenterChannelRendering; + int16_t nBins, idx; + float frameMeanDiffusenessEneWeight[CLDFB_NO_CHANNELS_MAX]; + DIRAC_DEC_HANDLE hDirAC; + DIRAC_DEC_BIN_HANDLE h; + float IIReneLimiterFactor; + float qualityBasedSmFactor; + float lowBitRateEQ[CLDFB_NO_CHANNELS_MAX]; + uint8_t applyLowBitRateEQ; + int16_t slot_idx_start, slot_idx, subframe_idx; + float subFrameTotalEne[CLDFB_NO_CHANNELS_MAX]; + int16_t md_idx; + float slot_ratio; + + hDirAC = st_ivas->hDirAC; + h = st_ivas->hDiracDecBin; + separateCenterChannelRendering = st_ivas->hOutSetup.separateChannelEnabled; + nBins = hDirAC->num_freq_bands; /* Actually bins */ + slot_idx_start = hDirAC->slots_rendered; + subframe_idx = hDirAC->subframes_rendered; + slot_ratio = 1.0f / (float) hDirAC->subframe_nbslots[subframe_idx]; + + set_zero( h->ChCrossRe, nBins ); + set_zero( h->ChCrossIm, nBins ); + set_zero( h->ChCrossReOut, nBins ); + set_zero( h->ChCrossImOut, nBins ); + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + set_zero( h->ChEne[ch], nBins ); + set_zero( h->ChEneOut[ch], nBins ); + } + set_zero( h->frameMeanDiffuseness, nBins ); + + set_zero( frameMeanDiffusenessEneWeight, CLDFB_NO_CHANNELS_MAX ); + + /* Determine EQ for low bit rates (13.2 and 16.4 kbps) */ + applyLowBitRateEQ = 0; + if ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MC_FORMAT ) && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE ) + { + applyLowBitRateEQ = 1; + if ( st_ivas->hDecoderConfig->ivas_total_brate == IVAS_16k4 ) + { + for ( bin = 0; bin < LOW_BIT_RATE_BINAURAL_EQ_BINS; bin++ ) + { + lowBitRateEQ[bin + LOW_BIT_RATE_BINAURAL_EQ_OFFSET] = lowBitRateBinauralEQ[bin] * 0.5f + 0.5f; + } + } + else + { + for ( bin = 0; bin < LOW_BIT_RATE_BINAURAL_EQ_BINS; bin++ ) + { + lowBitRateEQ[bin + LOW_BIT_RATE_BINAURAL_EQ_OFFSET] = lowBitRateBinauralEQ[bin]; + } + } + } + + + set_zero( subFrameTotalEne, CLDFB_NO_CHANNELS_MAX ); + /* Formulate input and target covariance matrices combining all subframes */ + for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) + { + + + /* Calculate input covariance matrix */ + + + for ( bin = 0; bin < nBins; bin++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + float instEne; + + instEne = ( inRe[ch][slot_idx][bin] * inRe[ch][slot_idx][bin] ); + instEne += ( inIm[ch][slot_idx][bin] * inIm[ch][slot_idx][bin] ); + h->ChEne[ch][bin] += instEne; + subFrameTotalEne[bin] += instEne; + } + h->ChCrossRe[bin] += inRe[0][slot_idx][bin] * inRe[1][slot_idx][bin]; + h->ChCrossRe[bin] += inIm[0][slot_idx][bin] * inIm[1][slot_idx][bin]; + h->ChCrossIm[bin] += inRe[0][slot_idx][bin] * inIm[1][slot_idx][bin]; + h->ChCrossIm[bin] -= inIm[0][slot_idx][bin] * inRe[1][slot_idx][bin]; + } + } + + /* Apply EQ at low bit rates */ + if ( applyLowBitRateEQ ) + { + int16_t lastEqBin = LOW_BIT_RATE_BINAURAL_EQ_OFFSET + LOW_BIT_RATE_BINAURAL_EQ_BINS - 1; + + for ( bin = LOW_BIT_RATE_BINAURAL_EQ_OFFSET; bin < lastEqBin; bin++ ) + { + subFrameTotalEne[bin] *= lowBitRateEQ[bin]; + } + for ( ; bin < nBins; bin++ ) + { + subFrameTotalEne[bin] *= lowBitRateEQ[lastEqBin]; + } + } + + if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->nchan_transport == 2 ) + { + float tempRe, tempIm; + + set_zero( subFrameTotalEne, CLDFB_NO_CHANNELS_MAX ); + + for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) + { + + + for ( bin = 0; bin < nBins; bin++ ) + { + tempRe = inRe[0][slot_idx][bin] + inRe[1][slot_idx][bin]; + tempIm = inIm[0][slot_idx][bin] + inIm[1][slot_idx][bin]; + subFrameTotalEne[bin] += tempRe * tempRe + tempIm * tempIm; + } + } + } + + for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) + { + md_idx = hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]; + /* Determine target covariance matrix containing target binaural properties */ + for ( bin = 0; bin < nBins; bin++ ) + { + float diffuseness = 1.0f; /* ratio1 and ratio2 are subtracted from diffuseness further below */ + float surCoh = 0.0f, spreadCoh = 0.0f; /* Default values if spreadSurroundCoherenceApplied == false */ + float diffEne, dirEne, meanEnePerCh; + uint16_t dirIndex; + + /* When BINAURAL_ROOM is not indicated, hBinaural->earlyPartEneCorrection[bin] values are all 1.0f. + * When BINAURAL_ROOM is indicated, the binaural audio output is based on combined use of the + * HRTF data set and a BRIR-based data set. The HRTF data set is spectrally corrected to match + * the early spectrum of the BRIR data, using the spectral correction data in + * hBinaural->earlyPartEneCorrection[bin], based on the BRIR set. */ + meanEnePerCh = h->earlyPartEneCorrection[bin] * subFrameTotalEne[bin] / 2.0f; + + /* Determine direct part target covariance matrix (for 1 or 2 directions) */ + for ( dirIndex = 0; dirIndex < hDirAC->numSimultaneousDirections; dirIndex++ ) + { + int16_t aziDeg, eleDeg; + float lRealp, lImagp, rRealp, rImagp; + float lRealpTmp, lImagpTmp, rRealpTmp, rImagpTmp; + float hrtfEne[BINAURAL_CHANNELS], hrtfCrossRe, hrtfCrossIm, ratio; + + if ( dirIndex == 0 ) /* For first of the two simultaneous directions */ + { + aziDeg = azimuth[slot_idx][bin]; + eleDeg = elevation[slot_idx][bin]; + ratio = energy_ratio1[slot_idx][bin]; + spreadCoh = spreadCoherence[slot_idx][bin]; + } + else /* For second of the two simultaneous directions */ + { + aziDeg = hDirAC->azimuth2[md_idx][bin]; + eleDeg = hDirAC->elevation2[md_idx][bin]; + ratio = hDirAC->energy_ratio2[md_idx][bin]; + spreadCoh = hDirAC->spreadCoherence2[md_idx][bin]; + } + diffuseness -= ratio; /* diffuseness = 1 - ratio1 - ratio2 */ + + if ( separateCenterChannelRendering ) + { + /* In masa + mono rendering mode, the center directions originate from phantom sources, so the + * spread coherence is increased */ + float aziRad, eleRad, doaVectorX, spatialAngleDeg, altSpreadCoh; + + aziRad = (float) aziDeg * PI_OVER_180; + eleRad = (float) eleDeg * PI_OVER_180; + doaVectorX = cosf( aziRad ) * cosf( eleRad ); + spatialAngleDeg = acosf( doaVectorX ) * _180_OVER_PI; + altSpreadCoh = 1.0f - ( spatialAngleDeg / 30.0f ); + spreadCoh = max( spreadCoh, altSpreadCoh ); + } + + getDirectPartGains( bin, aziDeg, eleDeg, &lRealp, &lImagp, &rRealp, &rImagp, h->renderStereoOutputInsteadOfBinaural, Rmat ); + + if ( h->renderStereoOutputInsteadOfBinaural ) + { + /* Synthesizing spread coherence is not needed for stereo loudspeaker output, + * as directional sound is reproduced with two loudspeakers in any case */ + spreadCoh = 0.0f; + } + + if ( spreadCoh > 0.0f ) + { + float centerMul, sidesMul; + float hrtfEneCenter, hrtfEneSides, hrtfEneRealized, eneCorrectionFactor; + float w1, w2, w3, eq; + + hrtfEneCenter = ( lRealp * lRealp ) + ( lImagp * lImagp ) + ( rRealp * rRealp ) + ( rImagp * rImagp ); + + /* Spread coherence is synthesized as coherent sources at 30 degree horizontal spacing. + * The following formulas determine the gains for these sources. + * spreadCoh = 0: Only panning + * spreadCoh = 0.5: Three sources coherent panning (e.g. 30 0 -30 deg azi) + * spreadCoh = 1.0: Two sources coherent panning with gap (as above, but center is silent) */ + if ( spreadCoh < 0.5f ) + { + /* 0.0f < spreadCoh < 0.5f */ + sidesMul = 0.5774f * spreadCoh * 2.0f; /* sqrt(1/3) = 0.5774f */ + centerMul = 1.0f - ( spreadCoh * 2.0f ) + sidesMul; + } + else + { + /* 0.5f <= spreadCoh < 1.0f */ + centerMul = 2.0f - ( 2.0f * spreadCoh ); + sidesMul = inv_sqrt( centerMul + 2.0f ); + centerMul *= sidesMul; + } + + /* Apply the gain for the center source of the three coherent sources */ + lRealp *= centerMul; + lImagp *= centerMul; + rRealp *= centerMul; + rImagp *= centerMul; + + /* Apply the gain for the left source of the three coherent sources */ + getDirectPartGains( bin, aziDeg + 30, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, h->renderStereoOutputInsteadOfBinaural, Rmat ); + + hrtfEneSides = ( lRealpTmp * lRealpTmp ) + ( lImagpTmp * lImagpTmp ) + ( rRealpTmp * rRealpTmp ) + ( rImagpTmp * rImagpTmp ); + lRealp += sidesMul * lRealpTmp; + lImagp += sidesMul * lImagpTmp; + rRealp += sidesMul * rRealpTmp; + rImagp += sidesMul * rImagpTmp; + + /* Apply the gain for the right source of the three coherent sources. + * -30 degrees to 330 wrapping due to internal functions. */ + getDirectPartGains( bin, aziDeg + 330, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, h->renderStereoOutputInsteadOfBinaural, Rmat ); + + hrtfEneSides += ( lRealpTmp * lRealpTmp ) + ( lImagpTmp * lImagpTmp ) + ( rRealpTmp * rRealpTmp ) + ( rImagpTmp * rImagpTmp ); + lRealp += sidesMul * lRealpTmp; + lImagp += sidesMul * lImagpTmp; + rRealp += sidesMul * rRealpTmp; + rImagp += sidesMul * rImagpTmp; + + /* Formulate an eneCorrectionFactor that compensates for the coherent summation of the HRTFs */ + hrtfEneRealized = ( lRealp * lRealp ) + ( lImagp * lImagp ) + ( rRealp * rRealp ) + ( rImagp * rImagp ); + eneCorrectionFactor = ( ( hrtfEneSides * sidesMul * sidesMul ) + + ( hrtfEneCenter * centerMul * centerMul ) ) / + max( 1e-12f, hrtfEneRealized ); + + /* Weighting factors to determine appropriate target spectrum for spread coherent sound */ + if ( spreadCoh < 0.5 ) + { + w1 = 1.0f - 2.0f * spreadCoh; + w2 = 2.0f * spreadCoh; + w3 = 0.0f; + } + else + { + w1 = 0.0f; + w2 = 2.0f - 2.0f * spreadCoh; + w3 = 2.0f * spreadCoh - 1.0f; + } + + if ( ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) ) + { + idx = min( bin, MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS - 1 ); + + /* Apply the target spectrum to the eneCorrectionFactor */ + if ( separateCenterChannelRendering ) /* spreadCoh mostly originates from phantom sources in separate channel rendering mode */ + { + eneCorrectionFactor *= w1 * 1.0f + ( w2 + w3 ) * spreadCohEne1[idx]; + } + else + { + eneCorrectionFactor *= w1 * 1.0f + w2 * spreadCohEne05[idx] + w3 * spreadCohEne1[idx]; + } + } + + /* Equalize the spread coherent combined HRTFs */ + eq = min( 4.0f, sqrtf( eneCorrectionFactor ) ); + lRealp *= eq; + lImagp *= eq; + rRealp *= eq; + rImagp *= eq; + } + + hrtfEne[0] = ( lRealp * lRealp ) + ( lImagp * lImagp ); + hrtfEne[1] = ( rRealp * rRealp ) + ( rImagp * rImagp ); + hrtfCrossRe = ( lRealp * rRealp ) + ( lImagp * rImagp ); + hrtfCrossIm = ( -lImagp * rRealp ) + ( lRealp * rImagp ); + + /* Add direct part (1 or 2) covariance matrix */ + dirEne = slot_ratio * ratio * meanEnePerCh; + h->ChEneOut[0][bin] += dirEne * hrtfEne[0]; /* Dir ene part*/ + h->ChEneOut[1][bin] += dirEne * hrtfEne[1]; + h->ChCrossReOut[bin] += dirEne * hrtfCrossRe; /* Dir cross re */ + h->ChCrossImOut[bin] += dirEne * hrtfCrossIm; /* Dir cross im */ + } + + /* Add diffuse / ambient part covariance matrix */ + diffuseness = max( 0.0f, diffuseness ); + diffEne = slot_ratio * diffuseness * meanEnePerCh; + surCoh = surroundingCoherence[slot_idx][bin]; + if ( ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) ) + { + if ( !h->renderStereoOutputInsteadOfBinaural ) + { + idx = min( bin, MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS - 1 ); + /* Apply target spectrum that emphasizes low frequencies when the sound is surround coherent */ + diffEne *= ( 1.0f - surCoh ) + surCoh * surCohEne[idx]; + } + } + h->ChEneOut[0][bin] += diffEne; /* Diff ene part*/ + h->ChEneOut[1][bin] += diffEne; + + if ( h->renderStereoOutputInsteadOfBinaural ) + { + /* When rendering stereo, ambience (except for surround coherent sound) has zero ICC. */ + h->ChCrossReOut[bin] += surCoh * diffEne; + } + else /* When rendering binaural, ambience has frequency dependent ICC. */ + { + if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR && bin < BINAURAL_COHERENCE_DIFFERENCE_BINS ) + { + float diffuseFieldCoherence; + diffuseFieldCoherence = hDirAC->hDiffuseDist->diffuseRatioX[0][bin] * h->diffuseFieldCoherenceX[bin] + hDirAC->hDiffuseDist->diffuseRatioY[0][bin] * h->diffuseFieldCoherenceY[bin] + hDirAC->hDiffuseDist->diffuseRatioZ[0][bin] * h->diffuseFieldCoherenceZ[bin]; + h->ChCrossReOut[bin] += ( ( 1.0f - surCoh ) * diffuseFieldCoherence + surCoh ) * diffEne; + } + else + { + h->ChCrossReOut[bin] += ( ( 1.0f - surCoh ) * h->diffuseFieldCoherence[bin] + surCoh ) * diffEne; + } + } + + /* Store parameters for formulating average diffuseness over frame */ + h->frameMeanDiffuseness[bin] += diffEne; + frameMeanDiffusenessEneWeight[bin] += slot_ratio * meanEnePerCh; + } + } + + /* Formulate average diffuseness over frame */ + for ( bin = 0; bin < nBins; bin++ ) + { + h->frameMeanDiffuseness[bin] /= fmaxf( 1e-12f, frameMeanDiffusenessEneWeight[bin] ); + } + + /* Determine encoding quality based additional smoothing factor */ + qualityBasedSmFactor = 1.0f; + if ( st_ivas->hMasa != NULL ) + { + qualityBasedSmFactor = st_ivas->hMasa->data.dir_decode_quality; + qualityBasedSmFactor *= qualityBasedSmFactor; + } + + /* Temporal IIR-type smoothing of covariance matrices */ + if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE ) + { + IIReneLimiterFactor = 16.0f + ( 1.0f - qualityBasedSmFactor ); + } + else + { + IIReneLimiterFactor = 8.0f + ( 1.0f - qualityBasedSmFactor ); + } + for ( bin = 0; bin < nBins; bin++ ) + { + float eneRatio, IIReneLimiter; + + /* Temporally smooth cov mtx estimates for resulting mixing matrix stability. The design principle is that + * the energy history (IIR) must not be more than double of the current frame energy. This provides more + * robust performance at energy offsets when compared to typical IIR averaging. */ + eneRatio = ( h->ChEne[0][bin] + h->ChEne[1][bin] ) / fmaxf( 1e-12f, ( h->ChEnePrev[0][bin] + h->ChEnePrev[1][bin] ) ); + IIReneLimiter = fminf( 1.0f, eneRatio * IIReneLimiterFactor ); + + h->ChCrossRe[bin] *= qualityBasedSmFactor; + h->ChCrossIm[bin] *= qualityBasedSmFactor; + h->ChCrossReOut[bin] *= qualityBasedSmFactor; + h->ChCrossImOut[bin] *= qualityBasedSmFactor; + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - hDirAC->proto_frame_f[( bin * BINAURAL_CHANNELS ) + offset] = inRe[ch][slot][bin]; - hDirAC->proto_frame_f[( bin * BINAURAL_CHANNELS ) + offset + 1] = inIm[ch][slot][bin]; + h->ChEne[ch][bin] *= qualityBasedSmFactor; + h->ChEneOut[ch][bin] *= qualityBasedSmFactor; } - } - /* Decorrelate proto signal to decorrelatedFrameInterleaved */ - ivas_dirac_dec_decorr_process( hDirAC->num_freq_bands, - hDirAC->num_outputs_diff, - hDirAC->num_protos_diff, - hDirAC->synthesisConf, - BINAURAL_CHANNELS, - hDirAC->proto_frame_f, - hDirAC->num_protos_diff, - hDirAC->proto_index_diff, - decorrelatedFrameInterleaved, - onset_filter, - hDirAC->h_freq_domain_decorr_ap_params, - hDirAC->h_freq_domain_decorr_ap_state ); + h->ChCrossRe[bin] += IIReneLimiter * h->ChCrossRePrev[bin]; + h->ChCrossIm[bin] += IIReneLimiter * h->ChCrossImPrev[bin]; + h->ChCrossReOut[bin] += IIReneLimiter * h->ChCrossReOutPrev[bin]; + h->ChCrossImOut[bin] += IIReneLimiter * h->ChCrossImOutPrev[bin]; - /* De-interleave decorrelated signals*/ - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - offset = hDirAC->num_freq_bands * BINAURAL_CHANNELS * ch; - for ( bin = 0; bin < hDirAC->num_freq_bands; bin++ ) + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - decRe[ch][bin] = decorrelatedFrameInterleaved[( bin * BINAURAL_CHANNELS ) + offset]; - decIm[ch][bin] = decorrelatedFrameInterleaved[( bin * BINAURAL_CHANNELS ) + offset + 1]; + h->ChEne[ch][bin] += IIReneLimiter * h->ChEnePrev[ch][bin]; + h->ChEneOut[ch][bin] += IIReneLimiter * h->ChEneOutPrev[ch][bin]; + } + + /* Store energy values and coefficients for next round */ + h->ChCrossRePrev[bin] = h->ChCrossRe[bin]; + h->ChCrossImPrev[bin] = h->ChCrossIm[bin]; + h->ChCrossReOutPrev[bin] = h->ChCrossReOut[bin]; + h->ChCrossImOutPrev[bin] = h->ChCrossImOut[bin]; + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + h->ChEnePrev[ch][bin] = h->ChEne[ch][bin]; + h->ChEneOutPrev[ch][bin] = h->ChEneOut[ch][bin]; } } return; } +#endif static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( @@ -664,6 +1530,9 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric float lowBitRateEQ[CLDFB_NO_CHANNELS_MAX]; uint8_t applyLowBitRateEQ; int16_t dirac_read_idx; +#ifdef JBM_TSM_ON_TCS + int16_t slot_idx_start; +#endif hDirAC = st_ivas->hDirAC; h = st_ivas->hDiracDecBin; @@ -704,18 +1573,32 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric } } +#ifdef JBM_TSM_ON_TCS + slot_idx_start = hDirAC->slots_rendered; +#endif + /* Formulate input and target covariance matrices combining all subframes */ for ( subframe = firstSubframe; subframe < ( firstSubframe + nSubframes ); subframe++ ) { float subFrameTotalEne[CLDFB_NO_CHANNELS_MAX]; set_zero( subFrameTotalEne, CLDFB_NO_CHANNELS_MAX ); + dirac_read_idx = hDirAC->dirac_read_idx; /* Calculate input covariance matrix */ +#ifdef JBM_TSM_ON_TCS + for ( slot = 0; slot < (uint8_t) hDirAC->subframe_nbslots[subframe]; slot++ ) +#else for ( slot = 0; slot < (uint8_t) hDirAC->subframe_nbslots; slot++ ) +#endif { +#ifdef JBM_TSM_ON_TCS + /* TODO: JBM this needs to be adapted to the variable size subframes */ + int16_t slotThis = slot + slot_idx_start; +#else int16_t slotThis = slot + ( hDirAC->subframe_nbslots * subframe ); +#endif for ( bin = 0; bin < nBins; bin++ ) { @@ -756,9 +1639,17 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric set_zero( subFrameTotalEne, CLDFB_NO_CHANNELS_MAX ); +#ifdef JBM_TSM_ON_TCS + for ( slot = 0; slot < (uint8_t) hDirAC->subframe_nbslots[subframe]; slot++ ) +#else for ( slot = 0; slot < (uint8_t) hDirAC->subframe_nbslots; slot++ ) +#endif { +#ifdef JBM_TSM_ON_TCS + int16_t slotThis = slot + slot_idx_start; +#else int16_t slotThis = slot + ( hDirAC->subframe_nbslots * subframe ); +#endif for ( bin = 0; bin < nBins; bin++ ) { @@ -978,8 +1869,10 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric h->frameMeanDiffuseness[bin] += diffEne; frameMeanDiffusenessEneWeight[bin] += meanEnePerCh; } - hDirAC->dirac_read_idx = ( hDirAC->dirac_read_idx + 1 ) % hDirAC->dirac_md_buffer_length; +#ifdef JBM_TSM_ON_TCS + slot_idx_start += hDirAC->subframe_nbslots[subframe]; +#endif } /* Formulate average diffuseness over frame */ @@ -1221,6 +2114,117 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices( return; } +#ifdef JBM_TSM_ON_TCS +static void ivas_dirac_dec_binaural_process_output_sf( + Decoder_Struct *st_ivas, + float *output_f[], + float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + const int16_t max_band_decorr, + const uint8_t numInChannels ) +{ + uint8_t slot, bin, chA, chB; + int16_t nBins; + float outSlotRe[CLDFB_NO_CHANNELS_MAX], outSlotIm[CLDFB_NO_CHANNELS_MAX]; + float decSlotRe[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX], decSlotIm[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; + float reverbRe[BINAURAL_CHANNELS][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float reverbIm[BINAURAL_CHANNELS][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + uint16_t numSlots; + DIRAC_DEC_BIN_HANDLE h; + float interpVal; + float *decSlotRePointer; + float *decSlotImPointer; + + numSlots = st_ivas->hDirAC->subframe_nbslots[st_ivas->hDirAC->subframes_rendered]; + h = st_ivas->hDiracDecBin; + nBins = st_ivas->hDirAC->num_freq_bands; + + + interpVal = 0.0f; + for ( slot = 0; slot < numSlots; slot++ ) + { + interpVal += 1.0f / (float) numSlots; + + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) + { + /* Process second / room effect part of binaural output when needed */ + ivas_binaural_reverb_processSlot( st_ivas->hDiracDecBin->hReverb, numInChannels, inRe, inIm, reverbRe, reverbIm, slot ); + } + if ( !st_ivas->hDiracDecBin->useTdDecorr && max_band_decorr > 0 ) + { + ivas_dirac_dec_decorrelate_slot_sf( st_ivas->hDirAC, slot, inRe, inIm, decSlotRe, decSlotIm ); + } + + for ( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) + { + float *outSlotRePr, *outSlotImPr; /* Pointers needed for function call compatibility */ + + set_zero( outSlotRe, CLDFB_NO_CHANNELS_MAX ); + set_zero( outSlotIm, CLDFB_NO_CHANNELS_MAX ); + + /* Processing of the first / HRTF part of the binaural output. */ + for ( chB = 0; chB < numInChannels; chB++ ) + { + if ( st_ivas->hDiracDecBin->useTdDecorr ) + { + decSlotRePointer = inRe[chB + 2][slot]; + decSlotImPointer = inIm[chB + 2][slot]; + } + else + { + decSlotRePointer = decSlotRe[chB]; + decSlotImPointer = decSlotIm[chB]; + } + + for ( bin = 0; bin < nBins; bin++ ) + { + float gain; + + /* Mixing using the formulated processing matrix M */ + gain = ( 1.0f - interpVal ) * h->processMtxRePrev[chA][chB][bin] + + interpVal * h->processMtxRe[chA][chB][bin]; + outSlotRe[bin] += gain * inRe[chB][slot][bin]; + outSlotIm[bin] += gain * inIm[chB][slot][bin]; + + gain = ( 1.0f - interpVal ) * h->processMtxImPrev[chA][chB][bin] + + interpVal * h->processMtxIm[chA][chB][bin]; + outSlotRe[bin] -= gain * inIm[chB][slot][bin]; + outSlotIm[bin] += gain * inRe[chB][slot][bin]; + + /* Mixing decorrelated signals using the formulated residual processing matrix Mdec */ + if ( bin < max_band_decorr && chB < 2 ) + { + gain = ( 1.0f - interpVal ) * h->processMtxDecRePrev[chA][chB][bin] + + interpVal * h->processMtxDecRe[chA][chB][bin]; + outSlotRe[bin] += gain * decSlotRePointer[bin]; + outSlotIm[bin] += gain * decSlotImPointer[bin]; + + gain = ( 1.0f - interpVal ) * h->processMtxDecImPrev[chA][chB][bin] + + interpVal * h->processMtxDecIm[chA][chB][bin]; + outSlotRe[bin] -= gain * decSlotImPointer[bin]; + outSlotIm[bin] += gain * decSlotRePointer[bin]; + } + } + } + + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) + { + /* Combine second (reverb) part with the first (HRTF) part to obtain binaural output signal with room effect */ + v_add( outSlotRe, reverbRe[chA][slot], outSlotRe, CLDFB_NO_CHANNELS_MAX ); + v_add( outSlotIm, reverbIm[chA][slot], outSlotIm, CLDFB_NO_CHANNELS_MAX ); + } + + outSlotRePr = &( outSlotRe[0] ); + outSlotImPr = &( outSlotIm[0] ); + + /* Inverse filter bank */ + cldfbSynthesis( &outSlotRePr, &outSlotImPr, &( output_f[chA][nBins * slot] ), nBins, st_ivas->cldfbSynDec[chA] ); + } + } + + return; +} +#endif static void ivas_dirac_dec_binaural_process_output( Decoder_Struct *st_ivas, @@ -1333,7 +2337,109 @@ static void ivas_dirac_dec_binaural_process_output( return; } +#ifdef JBM_TSM_ON_TCS +static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked_sf( + HEAD_TRACK_DATA_HANDLE hHeadTrackData, + float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + const uint8_t slotEnd, + const uint8_t nBins, + float Rmat[3][3] ) +{ + uint8_t slot, bin, ch; + float tmpVal; + + /* When not currently in prototype signal left-right switching procedure, check if such switching is needed */ + if ( hHeadTrackData->lrSwitchedNext == hHeadTrackData->lrSwitchedCurrent ) + { + float thresholdDotProduct = 0.17f; /* Corresponds to 10-degree switching threshold */ + if ( ( hHeadTrackData->lrSwitchedCurrent == 0 ) && ( Rmat[1][1] < -thresholdDotProduct ) ) + { + hHeadTrackData->lrSwitchedNext = 1; + } + if ( ( hHeadTrackData->lrSwitchedCurrent == 1 ) && ( Rmat[1][1] > thresholdDotProduct ) ) + { + hHeadTrackData->lrSwitchedNext = 0; + } + } + + /* When currently in interpolation */ + if ( hHeadTrackData->lrSwitchedNext != hHeadTrackData->lrSwitchedCurrent ) + { + for ( slot = 0; slot < slotEnd; slot++ ) + { + float switchOrderFactor, origOrderFactor; + + hHeadTrackData->lrSwitchInterpVal += 0.0025f; /* Corresponds to 0.5 seconds interpolation time */ + + if ( hHeadTrackData->lrSwitchInterpVal > 0.999f ) + { + /* Stop interpolation, reset values */ + hHeadTrackData->lrSwitchInterpVal = 0.0f; + hHeadTrackData->lrSwitchedCurrent = hHeadTrackData->lrSwitchedNext; + } + + /* Gains for determining portion of switched channel order and original channel order */ + tmpVal = (float) hHeadTrackData->lrSwitchedNext * hHeadTrackData->lrSwitchInterpVal; + tmpVal += (float) hHeadTrackData->lrSwitchedCurrent * ( 1.0f - hHeadTrackData->lrSwitchInterpVal ); + switchOrderFactor = sqrtf( tmpVal ); + origOrderFactor = sqrtf( 1.0f - tmpVal ); + + for ( bin = 0; bin < nBins; bin++ ) + { + /* determine original order (1) signals and switched order (2) signals */ + float re1[BINAURAL_CHANNELS], re2[BINAURAL_CHANNELS], im1[BINAURAL_CHANNELS], im2[BINAURAL_CHANNELS]; + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + re1[ch] = inRe[ch][slot][bin] * origOrderFactor; + re2[ch] = inRe[1 - ch][slot][bin] * switchOrderFactor; + im1[ch] = inIm[ch][slot][bin] * origOrderFactor; + im2[ch] = inIm[1 - ch][slot][bin] * switchOrderFactor; + } + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + float eneRef, ene, eq; + + /* Interpolate / mix original and switched order signals */ + inRe[ch][slot][bin] = re1[ch] + re2[ch]; + inIm[ch][slot][bin] = im1[ch] + im2[ch]; + + /* Equalize interpolated signals to preserve energy per bin */ + eneRef = ( re1[ch] * re1[ch] ) + ( re2[ch] * re2[ch] ) + ( im1[ch] * im1[ch] ) + ( im2[ch] * im2[ch] ); + ene = ( inRe[ch][slot][bin] * inRe[ch][slot][bin] ) + ( inIm[ch][slot][bin] * inIm[ch][slot][bin] ); + eq = sqrtf( eneRef / fmaxf( 1e-12f, ene ) ); + eq = fminf( 4.0f, eq ); + inRe[ch][slot][bin] *= eq; + inIm[ch][slot][bin] *= eq; + } + } + } + } + else + { + /* If not in interpolation, but in switched prototype situation, then switch left and right channels */ + if ( hHeadTrackData->lrSwitchedCurrent == 1 ) + { + for ( slot = 0; slot < slotEnd; slot++ ) + { + for ( bin = 0; bin < nBins; bin++ ) + { + tmpVal = inRe[0][slot][bin]; + inRe[0][slot][bin] = inRe[1][slot][bin]; + inRe[1][slot][bin] = tmpVal; + tmpVal = inIm[0][slot][bin]; + inIm[0][slot][bin] = inIm[1][slot][bin]; + inIm[1][slot][bin] = tmpVal; + } + } + } + } + return; +} +#endif static void adaptTransportSignalsHeadtracked( HEAD_TRACK_DATA_HANDLE hHeadTrackData, float inIm[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], diff --git a/lib_rend/ivas_limiter.c b/lib_rend/ivas_limiter.c index 28c272bc0c..17c5a94ff8 100644 --- a/lib_rend/ivas_limiter.c +++ b/lib_rend/ivas_limiter.c @@ -172,7 +172,11 @@ void ivas_limiter_close( void ivas_limiter_dec( IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ +#ifdef JBM_TSM_ON_TCS + float *output[MAX_OUTPUT_CHANNELS], /* i/o: input/output buffer */ +#else float output[MAX_OUTPUT_CHANNELS][L_FRAME48k], /* i/o: input/output buffer */ +#endif const int16_t num_channels, /* i : number of channels to be processed */ const int16_t output_frame, /* i : number of samples per channel in the buffer */ const int16_t BER_detect /* i : BER detect flag */ diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 0618534448..bf167259f3 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -47,6 +47,7 @@ * Local function prototypes *---------------------------------------------------------------------*/ + static void TDREND_Clear_Update_flags( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd ); static void angles_to_vec( const float radius, const float azimuth, const float elevation, float *vec ); @@ -259,14 +260,27 @@ ivas_error ivas_td_binaural_renderer_unwrap( const int16_t Opt_Headrotation, /* i : Head rotation flag */ const IVAS_QUATERNION *Quaternions, /* i : Head tracking data per subframe */ const IVAS_VECTOR3 *Pos, /* i : Listener position data per subframe */ - float output[][L_FRAME48k], /* i/o: SCE channels / Binaural synthesis */ - const int16_t output_frame /* i : output frame length */ +#ifdef JBM_TSM_ON_TCS + float *output[], /* i/o: SCE channels / Binaural synthesis */ +#else + float output[][L_FRAME48k], /* i/o: SCE channels / Binaural synthesis */ +#endif + const int16_t output_frame /* i : output frame length */ ) { int16_t subframe_length; int16_t subframe_idx; float reverb_signal[BINAURAL_CHANNELS][L_FRAME48k]; ivas_error error; +#ifdef JBM_TSM_ON_TCS + float *p_reverb_signal[BINAURAL_CHANNELS]; + int16_t ch; + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + p_reverb_signal[ch] = reverb_signal[ch]; + } +#endif subframe_length = output_frame / MAX_PARAM_SPATIAL_SUBFRAMES; @@ -280,7 +294,11 @@ ivas_error ivas_td_binaural_renderer_unwrap( if ( hReverb != NULL && hReverb->pConfig.roomAcoustics.late_reverb_on ) { +#ifdef JBM_TSM_ON_TCS + if ( ( error = ivas_reverb_process( hReverb, transport_config, 0, output, p_reverb_signal, subframe_idx ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_reverb_process( hReverb, transport_config, 0, output, reverb_signal, subframe_idx ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -313,9 +331,13 @@ ivas_error ivas_td_binaural_renderer_unwrap( ivas_error TDREND_GetMix( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ - float output[][L_FRAME48k], /* i/o: ISM object synth / rendered output in 0,1 */ - const int16_t subframe_length, /* i/o: subframe length */ - const int16_t subframe_idx /* i : Subframe index to 5 ms subframe */ +#ifdef JBM_TSM_ON_TCS + float *output[], /* i/o: ISM object synth / rendered output in 0,1 */ +#else + float output[][L_FRAME48k], /* i/o: ISM object synth / rendered output in 0,1 */ +#endif + const int16_t subframe_length, /* i/o: subframe length */ + const int16_t subframe_idx /* i : Subframe index to 5 ms subframe */ ) { int16_t i; @@ -406,7 +428,11 @@ void TDREND_Update_object_positions( const int16_t lfe_idx, /* i : Input LFE index */ const IVAS_FORMAT in_format, /* i : Format of input sources */ const ISM_METADATA_HANDLE *hIsmMetaData, /* i : Input metadata for ISM objects */ - float output[][L_FRAME48k] /* i/o: SCE/MC channels */ +#ifdef JBM_TSM_ON_TCS + float *output[] +#else + float output[][L_FRAME48k] /* i/o: SCE/MC channels */ +#endif ) { TDREND_DirAtten_t *DirAtten_p; @@ -583,6 +609,15 @@ ivas_error ivas_td_binaural_renderer_ext( IVAS_REND_AudioConfigType inConfigType; AUDIO_CONFIG transport_config; ivas_error error; +#ifdef JBM_TSM_ON_TCS + float *p_output[MAX_OUTPUT_CHANNELS]; + int16_t ch; + + for ( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) + { + p_output[ch] = output[ch]; + } +#endif push_wmops( "ivas_td_binaural_renderer_ext" ); @@ -620,9 +655,16 @@ ivas_error ivas_td_binaural_renderer_ext( hIsmMetaData[0]->radius = currentPos->radius; } +#ifdef JBM_TSM_ON_TCS + if ( ( error = ivas_td_binaural_renderer_unwrap( hReverb, transport_config, pTDRend->hBinRendererTd, num_src, lfe_idx, ivas_format, hIsmMetaData, headRotData->headRotEnabled, + ( headRotData != NULL ) ? headRotData->headPositions : NULL, + ( headRotData != NULL ) ? headRotData->Pos : NULL, p_output, output_frame ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_td_binaural_renderer_unwrap( hReverb, transport_config, pTDRend->hBinRendererTd, num_src, lfe_idx, ivas_format, hIsmMetaData, headRotData->headRotEnabled, ( headRotData != NULL ) ? headRotData->headPositions : NULL, ( headRotData != NULL ) ? headRotData->Pos : NULL, output, output_frame ) ) != IVAS_ERR_OK ) + +#endif { return error; } diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index b810ed09d8..21a31f529a 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -92,7 +92,11 @@ void ivas_limiter_close( void ivas_limiter_dec ( IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ +#ifdef JBM_TSM_ON_TCS + float *output[MAX_OUTPUT_CHANNELS], /* i/o: input/output buffer */ +#else float output[MAX_OUTPUT_CHANNELS][L_FRAME48k], /* i/o: input/output buffer */ +#endif const int16_t num_channels, /* i : number of channels to be processed */ const int16_t output_frame, /* i : number of samples per channel in the buffer */ const int16_t BER_detect /* i : BER detect flag */ @@ -156,6 +160,17 @@ void ivas_dirac_dec_binaural( const int16_t nchan_transport /* i : number of transport channels */ ); +#ifdef JBM_TSM_ON_TCS +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 */ + uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ + uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ + const int16_t nchan_transport, + float *output_f[] /* o : rendered time signal */ +); +#endif + 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 */ @@ -222,7 +237,11 @@ ivas_error ivas_td_binaural_renderer_unwrap( const int16_t Opt_Headrotation, /* i : Head rotation flag */ const IVAS_QUATERNION *Quaternions, /* i : Head tracking data per subframe */ const IVAS_VECTOR3 *Pos, /* i : Listener position data per subframe */ - float output[][L_FRAME48k], /* i/o: SCE channels / Binaural synthesis */ +#ifdef JBM_TSM_ON_TCS + float *output[], /* i/o: SCE channels / Binaural synthesis */ +#else + float output[][L_FRAME48k], /* i/o: SCE channels / Binaural synthesis */ +#endif const int16_t output_frame /* i : output frame length */ ); @@ -264,7 +283,11 @@ void ivas_td_binaural_close( ivas_error TDREND_GetMix( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ +#ifdef JBM_TSM_ON_TCS + float *output[], /* i/o: ISM object synth / rendered output in 0,1 */ +#else float output[][L_FRAME48k], /* i/o: ISM object synth / rendered output in 0,1 */ +#endif const int16_t subframe_length, /* i/o: subframe length */ const int16_t subframe_idx /* i : Subframe index to 5 ms subframe */ ); @@ -282,7 +305,11 @@ void TDREND_Update_object_positions( const int16_t lfe_idx, /* i : Input LFE index */ const IVAS_FORMAT in_format, /* i : Format of input sources */ const ISM_METADATA_HANDLE *hIsmMetaData, /* i : Input metadata for ISM objects */ +#ifdef JBM_TSM_ON_TCS + float *output[] /* i/o: SCE/MC channels */ +#else float output[][L_FRAME48k] /* i/o: SCE/MC channels */ +#endif ); void BSplineModelEvalDealloc( @@ -493,11 +520,29 @@ ivas_error ivas_rend_crendProcess( HEAD_TRACK_DATA_HANDLE hHeadTrackData, IVAS_OUTPUT_SETUP_HANDLE hIntSetup, EFAP_HANDLE hEFAPdata, +#ifdef JBM_TSM_ON_TCS + float *output[], /* i/o: input/output audio channels */ +#else float output[][L_FRAME48k], /* i/o: input/output audio channels */ +#endif const int32_t output_Fs ); - +#ifdef JBM_TSM_ON_TCS +ivas_error ivas_rend_crendProcessSubframe( + const CREND_WRAPPER *pCrend, + const AUDIO_CONFIG inConfig, + const AUDIO_CONFIG outConfig, + DECODER_CONFIG_HANDLE hDecoderConfig, + HEAD_TRACK_DATA_HANDLE hHeadTrackData, + IVAS_OUTPUT_SETUP_HANDLE hIntSetup, + EFAP_HANDLE hEFAPdata, + DECODER_TC_BUFFER_HANDLE hTcBuffer, + float *input_f[], + float *output[], /* i/o: input/output audio channels */ + const int16_t n_samples_to_render, + const int32_t output_Fs ); +#endif ivas_error ivas_crend_init_from_rom( @@ -547,6 +592,18 @@ void ivas_binaural_reverb_processFrame( const uint8_t offsetSamplesIO /* i : number of offset samples */ ); +#ifdef JBM_TSM_ON_TCS +void ivas_binaural_reverb_processSlot( + REVERB_STRUCT_HANDLE hReverb, /* i/o: binaural reverb handle */ + const int16_t numInChannels, /* i : num inputs to be processed */ + float inReal[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : input CLDFB data real, Comment: This change swaps two first dimensions as first dimension is not constant. */ + float inImag[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : input CLDFB data imag */ + float outReal[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* o : output CLDFB data real */ + float outImag[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* o : output CLDFB data imag */ + const uint8_t offsetSamplesIO /* i : number of offset samples */ +); +#endif + ivas_error ivas_reverb_open( REVERB_HANDLE *hReverb, /* i/o: Reverberator handle */ const AUDIO_CONFIG input_audio_config, /* i : reverb. input audio configuration */ @@ -563,8 +620,13 @@ ivas_error ivas_reverb_process( const REVERB_HANDLE hReverb, /* i : Reverberator handle */ const AUDIO_CONFIG input_audio_config, /* i : reverb. input audio configuration */ const int16_t mix_signals, /* i : add reverb to output signal */ +#ifdef JBM_TSM_ON_TCS + float *pcm_in[], /* i : the PCM audio to apply reverb on */ + float *pcm_out[], /* o : the PCM audio with reverb applied */ +#else float pcm_in[][L_FRAME48k], /* i : the PCM audio to apply reverb on */ float pcm_out[][L_FRAME48k], /* o : the PCM audio with reverb applied */ +#endif const int16_t i_ts /* i : subframe index */ ); @@ -787,7 +849,11 @@ void SHrotmatgen( void rotateFrame_shd( HEAD_TRACK_DATA_HANDLE hHeadTrackData, /* i : head track handle */ - float output[][L_FRAME48k], /* i/o: unrotated HOA3 signal buffer in TD */ +#ifdef JBM_TSM_ON_TCS + float *output[], /* i/o: unrotated HOA3 signal buffer in TD */ +#else + float output[][L_FRAME48k], /* i/o: unrotated HOA3 signal buffer in TD */ +#endif const int16_t subframe_len, /* i : subframe length per channel */ const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ const int16_t subframe_idx /* i : subframe index */ @@ -795,7 +861,11 @@ void rotateFrame_shd( void rotateFrame_sd( HEAD_TRACK_DATA_HANDLE hHeadTrackData, /* i : head track handle */ - float output[][L_FRAME48k], /* i/o: unrotated SD signal buffer in TD */ +#ifdef JBM_TSM_ON_TCS + float *output[], /* i/o: unrotated SD signal buffer in TD */ +#else + float output[][L_FRAME48k], /* i/o: unrotated SD signal buffer in TD */ +#endif const int16_t subframe_len, /* i : subframe length per channel */ const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ const EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ @@ -807,6 +877,9 @@ void rotateFrame_shd_cldfb( float Cldfb_ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: unrotated HOA3 signal buffer in cldfb domain imag part */ float Rmat[3][3], /* i : real-space rotation matrix */ const int16_t nInChannels, /* i : number of channels */ +#ifdef JBM_TSM_ON_TCS + const int16_t numTimeSlots, /* i : number of time slots to process */ +#endif const int16_t shd_rot_max_order /* i : split-order rotation method */ ); @@ -816,6 +889,9 @@ void rotateFrame_sd_cldfb( float Cldfb_ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: unrotated HOA3 signal buffer in cldfb domain imag part */ const IVAS_OUTPUT_SETUP_HANDLE hOutputSetup, /* i : output format setup number of channels */ const EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ +#ifdef JBM_TSM_ON_TCS + const int16_t numTimeSlots, /* i : number of time slots to process */ +#endif const int16_t nb_band /* i : number of CLDFB bands to process */ ); diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb.c index 65a7c60ed9..7239f4825b 100644 --- a/lib_rend/ivas_reverb.c +++ b/lib_rend/ivas_reverb.c @@ -1437,7 +1437,11 @@ static void reverb_block( static ivas_error downmix_input_block( const REVERB_HANDLE hReverb, +#ifdef JBM_TSM_ON_TCS + float *pcm_in[], +#else float pcm_in[][L_FRAME48k], +#endif const AUDIO_CONFIG input_audio_config, float *pPcm_out, const int16_t input_offset ) @@ -1579,8 +1583,13 @@ ivas_error ivas_reverb_process( const REVERB_HANDLE hReverb, /* i : Reverberator handle */ const AUDIO_CONFIG input_audio_config, /* i : reverb. input audio configuration */ const int16_t mix_signals, /* i : add reverb to output signal */ +#ifdef JBM_TSM_ON_TCS + float *pcm_in[], /* i : the PCM audio to apply reverb on */ + float *pcm_out[], /* o : the PCM audio with reverb applied */ +#else float pcm_in[][L_FRAME48k], /* i : the PCM audio to apply reverb on */ float pcm_out[][L_FRAME48k], /* o : the PCM audio with reverb applied */ +#endif const int16_t i_ts /* i : subframe index */ ) { @@ -1771,6 +1780,172 @@ void ivas_binaural_reverb_processFrame( return; } +#ifdef JBM_TSM_ON_TCS +/*------------------------------------------------------------------------- + * ivas_binaural_reverb_processSlot() + * + * Compute the reverberation - room effect + *------------------------------------------------------------------------*/ + +void ivas_binaural_reverb_processSlot( + REVERB_STRUCT_HANDLE hReverb, /* i/o: binaural reverb handle */ + const int16_t numInChannels, /* i : num inputs to be processed */ + float inReal[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : input CLDFB data real, Comment: This change swaps two first dimensions as first dimension is not constant. */ + float inImag[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : input CLDFB data imag */ + float outReal[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* o : output CLDFB data real */ + float outImag[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* o : output CLDFB data imag */ + const uint8_t offsetSamplesIO /* i : number of offset samples */ +) +{ + /* Declare the required variables */ + int16_t idx, bin, ch, sample, invertSampleIndex, tapIdx, *phaseShiftTypePr; + float **tapRealPr, **tapImagPr; + +#ifdef DEBUGGING + assert( hReverb->blockSize == 1 ); +#endif + + /* 1) Rotate the data in the loop buffer of the reverberator. + * Notice that the audio at the loop buffers is at time-inverted order + * for convolution purposes later on. */ + for ( bin = 0; bin < hReverb->numBins; bin++ ) + { + /* Move the data forwards by blockSize (i.e. by the frame size of 16 CLDFB slots) */ + mvr2r( hReverb->loopBufReal[bin], hReverb->loopBufReal[bin] + hReverb->blockSize, hReverb->loopBufLength[bin] ); + mvr2r( hReverb->loopBufImag[bin], hReverb->loopBufImag[bin] + hReverb->blockSize, hReverb->loopBufLength[bin] ); + + /* Add the data from the end of the loop to the beginning, with an attenuation factor + * according to RT60. This procedure generates an IIR decaying response. The response + * is decorrelated later on. */ + v_multc( hReverb->loopBufReal[bin] + hReverb->loopBufLength[bin], hReverb->loopAttenuationFactor[bin], hReverb->loopBufReal[bin], hReverb->blockSize ); + v_multc( hReverb->loopBufImag[bin] + hReverb->loopBufLength[bin], hReverb->loopAttenuationFactor[bin], hReverb->loopBufImag[bin], hReverb->blockSize ); + } + + /* 2) Apply the determined pre-delay to the input audio, and add the delayed audio to the loop. */ + idx = hReverb->preDelayBufferIndex; + for ( sample = 0; sample < hReverb->blockSize; sample++ ) + { + uint16_t sampleWithOffset; + sampleWithOffset = sample + offsetSamplesIO; + invertSampleIndex = hReverb->blockSize - sample - 1; + for ( bin = 0; bin < hReverb->numBins; bin++ ) + { + /* Add from pre-delay buffer a sample to the loop buffer, in a time-inverted order. + * Also apply the spectral gains determined for the reverberation */ + hReverb->loopBufReal[bin][invertSampleIndex] += hReverb->preDelayBufferReal[idx][bin] * hReverb->reverbEqGains[bin]; + hReverb->loopBufImag[bin][invertSampleIndex] += hReverb->preDelayBufferImag[idx][bin] * hReverb->reverbEqGains[bin]; + hReverb->preDelayBufferReal[idx][bin] = 0.0f; + hReverb->preDelayBufferImag[idx][bin] = 0.0f; + } + + /* Add every second input channel as is to the pre-delay buffer, and every second input channel with + * 90 degrees phase shift to reduce energy imbalances between coherent and incoherent sounds */ + for ( ch = 0; ch < numInChannels; ch++ ) + { + if ( ch % 2 ) + { + v_add( hReverb->preDelayBufferReal[idx], inReal[ch][sampleWithOffset], hReverb->preDelayBufferReal[idx], hReverb->numBins ); + v_add( hReverb->preDelayBufferImag[idx], inImag[ch][sampleWithOffset], hReverb->preDelayBufferImag[idx], hReverb->numBins ); + } + else + { + v_sub( hReverb->preDelayBufferReal[idx], inImag[ch][sampleWithOffset], hReverb->preDelayBufferReal[idx], hReverb->numBins ); + v_add( hReverb->preDelayBufferImag[idx], inReal[ch][sampleWithOffset], hReverb->preDelayBufferImag[idx], hReverb->numBins ); + } + } + idx = ( idx + 1 ) % hReverb->preDelayBufferLength; + } + hReverb->preDelayBufferIndex = idx; + + /* 3) Perform the filtering/decorrelating, using complex and sparse FIR filtering */ + for ( bin = 0; bin < hReverb->numBins; bin++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + /* These tap pointers have been determined to point to the loop buffer at sparse locations */ + tapRealPr = hReverb->tapPointersReal[bin][ch]; + tapImagPr = hReverb->tapPointersImag[bin][ch]; + phaseShiftTypePr = hReverb->tapPhaseShiftType[bin][ch]; + + /* Flush output */ + set_f( hReverb->outputBufferReal[bin][ch], 0.0f, hReverb->blockSize ); + set_f( hReverb->outputBufferImag[bin][ch], 0.0f, hReverb->blockSize ); + + /* Add from temporally decaying sparse tap locations the audio to the output. */ + for ( tapIdx = 0; tapIdx < hReverb->taps[bin][ch]; tapIdx++ ) + { + switch ( phaseShiftTypePr[tapIdx] ) + { + case 0: /* 0 degrees phase */ + v_add( hReverb->outputBufferReal[bin][ch], tapRealPr[tapIdx], hReverb->outputBufferReal[bin][ch], hReverb->blockSize ); + v_add( hReverb->outputBufferImag[bin][ch], tapImagPr[tapIdx], hReverb->outputBufferImag[bin][ch], hReverb->blockSize ); + break; + case 1: /* 90 degrees phase */ + v_sub( hReverb->outputBufferReal[bin][ch], tapImagPr[tapIdx], hReverb->outputBufferReal[bin][ch], hReverb->blockSize ); + v_add( hReverb->outputBufferImag[bin][ch], tapRealPr[tapIdx], hReverb->outputBufferImag[bin][ch], hReverb->blockSize ); + break; + case 2: /* 180 degrees phase */ + v_sub( hReverb->outputBufferReal[bin][ch], tapRealPr[tapIdx], hReverb->outputBufferReal[bin][ch], hReverb->blockSize ); + v_sub( hReverb->outputBufferImag[bin][ch], tapImagPr[tapIdx], hReverb->outputBufferImag[bin][ch], hReverb->blockSize ); + break; + default: /* 270 degrees phase */ + v_add( hReverb->outputBufferReal[bin][ch], tapImagPr[tapIdx], hReverb->outputBufferReal[bin][ch], hReverb->blockSize ); + v_sub( hReverb->outputBufferImag[bin][ch], tapRealPr[tapIdx], hReverb->outputBufferImag[bin][ch], hReverb->blockSize ); + break; + } + } + } + + /* Generate diffuse field binaural coherence by mixing the incoherent reverberated channels with pre-defined gains */ + if ( bin <= hReverb->highestBinauralCoherenceBin ) + { + if ( hReverb->useBinauralCoherence ) + { + for ( sample = 0; sample < hReverb->blockSize; sample++ ) + { + float leftRe, rightRe, leftIm, rightIm; + + leftRe = hReverb->binauralCoherenceDirectGains[bin] * hReverb->outputBufferReal[bin][0][sample] + hReverb->binauralCoherenceCrossmixGains[bin] * hReverb->outputBufferReal[bin][1][sample]; + rightRe = hReverb->binauralCoherenceDirectGains[bin] * hReverb->outputBufferReal[bin][1][sample] + hReverb->binauralCoherenceCrossmixGains[bin] * hReverb->outputBufferReal[bin][0][sample]; + leftIm = hReverb->binauralCoherenceDirectGains[bin] * hReverb->outputBufferImag[bin][0][sample] + hReverb->binauralCoherenceCrossmixGains[bin] * hReverb->outputBufferImag[bin][1][sample]; + rightIm = hReverb->binauralCoherenceDirectGains[bin] * hReverb->outputBufferImag[bin][1][sample] + hReverb->binauralCoherenceCrossmixGains[bin] * hReverb->outputBufferImag[bin][0][sample]; + + hReverb->outputBufferReal[bin][0][sample] = leftRe; + hReverb->outputBufferReal[bin][1][sample] = rightRe; + hReverb->outputBufferImag[bin][0][sample] = leftIm; + hReverb->outputBufferImag[bin][1][sample] = rightIm; + } + } + } + } + + /* 4) Write data to output */ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + for ( sample = 0; sample < hReverb->blockSize; sample++ ) + { + uint16_t sampleWithOffset; + + sampleWithOffset = sample + offsetSamplesIO; + /* Audio was in the temporally inverted order for convolution, re-invert audio to output */ + invertSampleIndex = hReverb->blockSize - sample - 1; + + for ( bin = 0; bin < hReverb->numBins; bin++ ) + { + outReal[ch][sampleWithOffset][bin] = hReverb->outputBufferReal[bin][ch][invertSampleIndex]; + outImag[ch][sampleWithOffset][bin] = hReverb->outputBufferImag[bin][ch][invertSampleIndex]; + } + for ( ; bin < CLDFB_NO_CHANNELS_MAX; bin++ ) + { + outReal[ch][sampleWithOffset][bin] = 0.0f; + outImag[ch][sampleWithOffset][bin] = 0.0f; + } + } + } + + return; +} +#endif /*------------------------------------------------------------------------- * ivas_binaural_reverb_open() diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index ddfdcb6763..0736bd4003 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -251,10 +251,14 @@ void rotateAziEle( void rotateFrame_shd( HEAD_TRACK_DATA_HANDLE hHeadTrackData, /* i : head track handle */ - float output[][L_FRAME48k], /* i/o: unrotated HOA3 signal buffer in TD */ - const int16_t subframe_len, /* i : subframe length per channel */ - const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ - const int16_t subframe_idx /* i : subframe index */ +#ifdef JBM_TSM_ON_TCS + float *output[], /* i/o: unrotated HOA3 signal buffer in TD */ +#else + float output[][L_FRAME48k], /* i/o: unrotated HOA3 signal buffer in TD */ +#endif + const int16_t subframe_len, /* i : subframe length per channel */ + const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ + const int16_t subframe_idx /* i : subframe index */ ) { int16_t i, l, n, m; @@ -354,7 +358,11 @@ void rotateFrame_shd( void rotateFrame_sd( HEAD_TRACK_DATA_HANDLE hHeadTrackData, /* i : head track handle */ +#ifdef JBM_TSM_ON_TCS + float *output[], /* i/o: unrotated SD signal buffer in TD */ +#else float output[][L_FRAME48k], /* i/o: unrotated SD signal buffer in TD */ +#endif const int16_t subframe_len, /* i : subframe length per channel */ const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ const EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ @@ -492,7 +500,10 @@ void rotateFrame_shd_cldfb( float Cldfb_ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: unrotated HOA3 signal buffer in cldfb domain imag part */ float Rmat[3][3], /* i : real-space rotation matrix */ const int16_t nInChannels, /* i : number of channels */ - const int16_t shd_rot_max_order /* i : split-order rotation method */ +#ifdef JBM_TSM_ON_TCS + const int16_t numTimeSlots, +#endif + const int16_t shd_rot_max_order /* i : split-order rotation method */ ) { int16_t n = 0; @@ -515,7 +526,11 @@ void rotateFrame_shd_cldfb( SHrotmatgen( SHrotmat, Rmat, shd_rot_max_order ); /* rotation by mtx multiplication */ +#ifdef JBM_TSM_ON_TCS + for ( i = 0; i < numTimeSlots; i++ ) +#else for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) +#endif { for ( iBand = 0; iBand < CLDFB_NO_CHANNELS_MAX; iBand++ ) { @@ -586,6 +601,9 @@ void rotateFrame_sd_cldfb( float Cldfb_ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: unrotated HOA3 signal buffer in cldfb domain imag part */ const IVAS_OUTPUT_SETUP_HANDLE hOutputSetup, /* i : output format setup number of channels */ const EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ +#ifdef JBM_TSM_ON_TCS + const int16_t numTimeSlots, /* i : number of time slots to process */ +#endif const int16_t nb_band /* i : number of CLDFB bands to process */ ) { @@ -644,7 +662,11 @@ void rotateFrame_sd_cldfb( p_imagRot = imagRot[n]; if ( g1 > 0.f ) { +#ifdef JBM_TSM_ON_TCS + for ( iBlock = 0; iBlock < numTimeSlots; iBlock++ ) +#else for ( iBlock = 0; iBlock < MAX_PARAM_SPATIAL_SUBFRAMES; iBlock++ ) +#endif { p_real = Cldfb_RealBuffer[m][iBlock]; p_imag = Cldfb_ImagBuffer[m][iBlock]; @@ -664,7 +686,11 @@ void rotateFrame_sd_cldfb( { p_realRot = realRot[n]; p_imagRot = imagRot[n]; +#ifdef JBM_TSM_ON_TCS + for ( iBlock = 0; iBlock < numTimeSlots; iBlock++ ) +#else for ( iBlock = 0; iBlock < MAX_PARAM_SPATIAL_SUBFRAMES; iBlock++ ) +#endif { p_real = Cldfb_RealBuffer[n][iBlock]; p_imag = Cldfb_ImagBuffer[n][iBlock]; diff --git a/lib_rend/ivas_sba_rendering.c b/lib_rend/ivas_sba_rendering.c index 8fd10d83ba..f316f2885f 100644 --- a/lib_rend/ivas_sba_rendering.c +++ b/lib_rend/ivas_sba_rendering.c @@ -50,6 +50,158 @@ * Render prototype audio signals using SBA mixing matrices *-------------------------------------------------------------------*/ +#ifdef JBM_TSM_ON_TCS +void ivas_sba_prototype_renderer_sf( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ + float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */ + float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /* i : Input audio in CLDFB domain, imag */ +) +{ + float mixer_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; + SPAR_DEC_HANDLE hSpar; + DECODER_CONFIG_HANDLE hDecoderConfig; + int16_t num_spar_bands, spar_band; + int16_t b, ts; + int16_t num_cldfb_bands, numch_in, numch_out; + int16_t cldfb_band; + int16_t out_ch, in_ch; + int16_t firstInCh, inChEnd, firstOutCh, outChEnd; + int16_t slot_idx_start; + + push_wmops( "ivas_sba_prototype_renderer" ); + + hSpar = st_ivas->hSpar; + hDecoderConfig = st_ivas->hDecoderConfig; + num_spar_bands = hSpar->hFbMixer->pFb->filterbank_num_bands; + + num_cldfb_bands = hSpar->hFbMixer->pFb->fb_bin_to_band.num_cldfb_bands; + numch_in = hSpar->hFbMixer->fb_cfg->num_in_chans; + numch_out = hSpar->hFbMixer->fb_cfg->num_out_chans; + + if ( st_ivas->nchan_transport == 1 ) + { + firstInCh = 0; + inChEnd = 1; + firstOutCh = 0; + outChEnd = 1; + } + else /* 2 TC */ + { + firstInCh = 0; + inChEnd = 2; + firstOutCh = 1; + outChEnd = 2; + } + slot_idx_start = hSpar->slots_rendered; + /* Apply mixing matrix */ + for ( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) + { + int16_t md_idx = hSpar->render_to_md_slot_map[ts + slot_idx_start]; + /* determine SPAR parameters for this time slot */ + ivas_spar_get_parameters( hSpar, hDecoderConfig, md_idx, numch_out, numch_in, num_spar_bands, mixer_mat ); + + for ( cldfb_band = 0; cldfb_band < num_cldfb_bands; cldfb_band++ ) + { + float out_re[IVAS_SPAR_MAX_CH]; + float out_im[IVAS_SPAR_MAX_CH]; + float cldfb_par; + ivas_fb_bin_to_band_data_t *bin2band = &hSpar->hFbMixer->pFb->fb_bin_to_band; + + for ( out_ch = firstOutCh; out_ch < outChEnd; out_ch++ ) + { + out_re[out_ch] = 0.0f; + out_im[out_ch] = 0.0f; + + for ( in_ch = firstInCh; in_ch < inChEnd; in_ch++ ) + { + if ( cldfb_band < CLDFB_PAR_WEIGHT_START_BAND ) /* tuning parameter, depends on how much SPAR Filters overlap for the CLDFB bands */ + { + spar_band = bin2band->p_cldfb_map_to_spar_band[cldfb_band]; + cldfb_par = mixer_mat[out_ch][in_ch][spar_band]; + } + else + { + cldfb_par = 0.0f; + for ( spar_band = bin2band->p_spar_start_bands[cldfb_band]; spar_band < num_spar_bands; spar_band++ ) + { + /* accumulate contributions from all SPAR bands */ + cldfb_par += mixer_mat[out_ch][in_ch][spar_band] * bin2band->pp_cldfb_weights_per_spar_band[cldfb_band][spar_band]; + } + } + + out_re[out_ch] += inRe[in_ch][ts][cldfb_band] * cldfb_par; + out_im[out_ch] += inIm[in_ch][ts][cldfb_band] * cldfb_par; + } + } + + /*update CLDFB data with the parameter-modified data*/ + for ( out_ch = firstOutCh; out_ch < outChEnd; out_ch++ ) + { + inRe[out_ch][ts][cldfb_band] = out_re[out_ch]; + inIm[out_ch][ts][cldfb_band] = out_im[out_ch]; + } + } + + /* Update mixing matrices */ + if ( ( ( slot_idx_start + ts + 1 ) == hSpar->num_slots ) || ( ( md_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME ) != ( hSpar->render_to_md_slot_map[ts + slot_idx_start + 1] / JBM_CLDFB_SLOTS_IN_SUBFRAME ) ) ) + { + /* we have crossed an unadapted parameter sf border, update previous mixing matrices */ + int16_t md_sf = md_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME; + hSpar->i_subframe++; + hSpar->i_subframe = min( hSpar->i_subframe, MAX_PARAM_SPATIAL_SUBFRAMES ); + mvr2r( hSpar->hMdDec->mixer_mat_prev[1][0][0], hSpar->hMdDec->mixer_mat_prev[0][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); + mvr2r( hSpar->hMdDec->mixer_mat_prev[2][0][0], hSpar->hMdDec->mixer_mat_prev[1][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); + mvr2r( hSpar->hMdDec->mixer_mat_prev[3][0][0], hSpar->hMdDec->mixer_mat_prev[2][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); + mvr2r( hSpar->hMdDec->mixer_mat_prev[4][0][0], hSpar->hMdDec->mixer_mat_prev[3][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); + + for ( out_ch = 0; out_ch < numch_out; out_ch++ ) + { + for ( in_ch = 0; in_ch < numch_in; in_ch++ ) + { + for ( b = 0; b < num_spar_bands; b++ ) + { + hSpar->hMdDec->mixer_mat_prev[4][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat[out_ch][in_ch][b + md_sf * IVAS_MAX_NUM_BANDS]; + } + } + } + } + } + + /* Create prototypes */ + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) + { + for ( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) + { + if ( st_ivas->nchan_transport == 1 ) /* Dual mono */ + { + mvr2r( inRe[0][ts], inRe[1][ts], CLDFB_NO_CHANNELS_MAX ); + mvr2r( inIm[0][ts], inIm[1][ts], CLDFB_NO_CHANNELS_MAX ); + } + else if ( st_ivas->nchan_transport == 2 ) /* Opposing cardioids */ + { + float temp_signal[CLDFB_NO_CHANNELS_MAX]; + + v_add( inRe[0][ts], inRe[1][ts], temp_signal, CLDFB_NO_CHANNELS_MAX ); + v_sub( inRe[0][ts], inRe[1][ts], inRe[1][ts], CLDFB_NO_CHANNELS_MAX ); + mvr2r( temp_signal, inRe[0][ts], CLDFB_NO_CHANNELS_MAX ); + v_multc( inRe[0][ts], 0.5f, inRe[0][ts], CLDFB_NO_CHANNELS_MAX ); + v_multc( inRe[1][ts], 0.5f, inRe[1][ts], CLDFB_NO_CHANNELS_MAX ); + + v_add( inIm[0][ts], inIm[1][ts], temp_signal, CLDFB_NO_CHANNELS_MAX ); + v_sub( inIm[0][ts], inIm[1][ts], inIm[1][ts], CLDFB_NO_CHANNELS_MAX ); + mvr2r( temp_signal, inIm[0][ts], CLDFB_NO_CHANNELS_MAX ); + v_multc( inIm[0][ts], 0.5f, inIm[0][ts], CLDFB_NO_CHANNELS_MAX ); + v_multc( inIm[1][ts], 0.5f, inIm[1][ts], CLDFB_NO_CHANNELS_MAX ); + } + } + } + + pop_wmops(); + + return; +} +#endif + void ivas_sba_prototype_renderer( Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ float inRe[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */ @@ -198,6 +350,10 @@ void ivas_sba_prototype_renderer( } } +#ifdef JBM_TSM_ON_TCS + hSpar->subframes_rendered += nSubframes; + hSpar->slots_rendered += slotEnd - firstSlot; +#endif pop_wmops(); return; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 7744a6582b..6ef18946ca 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -4350,6 +4350,13 @@ static ivas_error renderIsmToBinauralRoom( IVAS_REND_AudioBuffer tmpMcBuffer; IVAS_REND_AudioObjectPosition rotatedPos; const IVAS_REND_HeadRotData *headRotData; +#ifdef JBM_TSM_ON_TCS + float *p_tmpRendBuffer[MAX_OUTPUT_CHANNELS]; + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + p_tmpRendBuffer[i] = tmpRendBuffer[i]; + } +#endif push_wmops( "renderIsmToBinauralRoom" ); @@ -4449,8 +4456,13 @@ static ivas_error renderIsmToBinauralRoom( copyBufferTo2dArray( tmpMcBuffer, tmpRendBuffer ); +#ifdef JBM_TSM_ON_TCS + if ( ( error = ivas_rend_crendProcess( ismInput->crendWrapper, AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_BINAURAL_ROOM, + NULL, NULL, NULL, NULL, p_tmpRendBuffer, *ismInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendProcess( ismInput->crendWrapper, AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_BINAURAL_ROOM, NULL, NULL, NULL, NULL, tmpRendBuffer, *ismInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -4710,6 +4722,15 @@ static ivas_error renderMcToBinaural( ivas_error error; IVAS_REND_AudioBuffer tmpRotBuffer; +#ifdef JBM_TSM_ON_TCS + float *p_tmpRendBuffer[MAX_OUTPUT_CHANNELS]; + int16_t i; + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + p_tmpRendBuffer[i] = tmpRendBuffer[i]; + } +#endif + push_wmops( "renderMcToBinaural" ); headRotEnabled = mcInput->base.ctx.pHeadRotData->headRotEnabled; @@ -4749,8 +4770,13 @@ static ivas_error renderMcToBinaural( } /* call CREND */ +#ifdef JBM_TSM_ON_TCS + if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, getIvasAudioConfigFromRendAudioConfig( mcInput->base.inConfig ), getIvasAudioConfigFromRendAudioConfig( outConfig ), + NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, getIvasAudioConfigFromRendAudioConfig( mcInput->base.inConfig ), getIvasAudioConfigFromRendAudioConfig( outConfig ), NULL, NULL, NULL, NULL, tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -4780,6 +4806,15 @@ static ivas_error renderMcToBinauralRoom( ivas_error error; IVAS_REND_AudioBuffer tmpRotBuffer; +#ifdef JBM_TSM_ON_TCS + float *p_tmpRendBuffer[MAX_OUTPUT_CHANNELS]; + int16_t i; + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + p_tmpRendBuffer[i] = tmpRendBuffer[i]; + } +#endif + push_wmops( "renderMcToBinauralRoom" ); headRotEnabled = mcInput->base.ctx.pHeadRotData->headRotEnabled; @@ -4819,8 +4854,13 @@ static ivas_error renderMcToBinauralRoom( } /* call CREND */ +#ifdef JBM_TSM_ON_TCS + if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, getIvasAudioConfigFromRendAudioConfig( mcInput->base.inConfig ), getIvasAudioConfigFromRendAudioConfig( outConfig ), + NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, getIvasAudioConfigFromRendAudioConfig( mcInput->base.inConfig ), getIvasAudioConfigFromRendAudioConfig( outConfig ), NULL, NULL, NULL, NULL, tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -4853,12 +4893,23 @@ static ivas_error renderMcCustomLsToBinauralRoom( IVAS_REND_AudioBuffer tmpMcBuffer; IVAS_REND_AudioBuffer *tmpBufPtr; +#ifdef JBM_TSM_ON_TCS + float *p_tmpCrendBuffer[MAX_OUTPUT_CHANNELS]; +#endif + push_wmops( "renderMcCustomLsToBinauralRoom" ); tmpRotBuffer = outAudio; /* avoid compilation warning */ headRotEnabled = mcInput->base.ctx.pHeadRotData->headRotEnabled; +#ifdef JBM_TSM_ON_TCS + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + p_tmpCrendBuffer[i] = tmpCrendBuffer[i]; + } +#endif + /* apply rotation */ if ( headRotEnabled ) { @@ -4892,8 +4943,13 @@ static ivas_error renderMcCustomLsToBinauralRoom( copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); /* call CREND */ +#ifdef JBM_TSM_ON_TCS + if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, AUDIO_CONFIG_7_1_4, getIvasAudioConfigFromRendAudioConfig( outConfig ), NULL, NULL, NULL, NULL, + p_tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, AUDIO_CONFIG_7_1_4, getIvasAudioConfigFromRendAudioConfig( outConfig ), NULL, NULL, NULL, NULL, tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -5096,8 +5152,20 @@ static ivas_error renderSbaToBinaural( ivas_error error; IVAS_REND_AudioBuffer tmpRotBuffer; +#ifdef JBM_TSM_ON_TCS + float *p_tmpCrendBuffer[MAX_OUTPUT_CHANNELS]; + int16_t i; +#endif + push_wmops( "renderSbaToBinaural" ); +#ifdef JBM_TSM_ON_TCS + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + p_tmpCrendBuffer[i] = tmpCrendBuffer[i]; + } +#endif + /* apply rotation */ if ( sbaInput->base.ctx.pHeadRotData->headRotEnabled ) { @@ -5121,8 +5189,13 @@ static ivas_error renderSbaToBinaural( } /* call CREND */ +#ifdef JBM_TSM_ON_TCS + if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, getIvasAudioConfigFromRendAudioConfig( sbaInput->base.inConfig ), getIvasAudioConfigFromRendAudioConfig( outConfig ), + NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, getIvasAudioConfigFromRendAudioConfig( sbaInput->base.inConfig ), getIvasAudioConfigFromRendAudioConfig( outConfig ), NULL, NULL, NULL, NULL, tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -5148,10 +5221,21 @@ static ivas_error renderSbaToBinauralRoom( IVAS_REND_AudioBuffer tmpMcBuffer; IVAS_REND_AudioBuffer *tmpBufPtr; +#ifdef JBM_TSM_ON_TCS + float *p_tmpCrendBuffer[MAX_OUTPUT_CHANNELS]; +#endif + tmpRotBuffer = outAudio; /* avoid compilation warning */ push_wmops( "renderSbaToBinauralRoom" ); +#ifdef JBM_TSM_ON_TCS + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + p_tmpCrendBuffer[i] = tmpCrendBuffer[i]; + } +#endif + headRotEnabled = sbaInput->base.ctx.pHeadRotData->headRotEnabled; /* apply rotation */ @@ -5190,8 +5274,13 @@ static ivas_error renderSbaToBinauralRoom( copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); /* call CREND */ +#ifdef JBM_TSM_ON_TCS + if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, AUDIO_CONFIG_7_1_4, getIvasAudioConfigFromRendAudioConfig( outConfig ), + NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, AUDIO_CONFIG_7_1_4, getIvasAudioConfigFromRendAudioConfig( outConfig ), NULL, NULL, NULL, NULL, tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -5344,7 +5433,11 @@ static void renderMasaToMc( } else { +#ifdef JBM_TSM_ON_TCS + ivas_dirac_dec( masaInput->decDummy, tmpBuffer, masaInput->base.inputBuffer.config.numChannels ); +#else ivas_dirac_dec( masaInput->decDummy, tmpBuffer, masaInput->base.inputBuffer.config.numChannels, NULL, NULL, -1 ); +#endif } accumulate2dArrayToBuffer( tmpBuffer, &outAudio ); @@ -5361,7 +5454,11 @@ static void renderMasaToSba( copyBufferTo2dArray( masaInput->base.inputBuffer, tmpBuffer ); copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->decDummy->hDirAC ); +#ifdef JBM_TSM_ON_TCS + ivas_dirac_dec( masaInput->decDummy, tmpBuffer, masaInput->base.inputBuffer.config.numChannels ); +#else ivas_dirac_dec( masaInput->decDummy, tmpBuffer, masaInput->base.inputBuffer.config.numChannels, NULL, NULL, -1 ); +#endif accumulate2dArrayToBuffer( tmpBuffer, &outAudio ); diff --git a/lib_util/tinywaveout_c.h b/lib_util/tinywaveout_c.h index d0531eb665..aab62a4dd3 100644 --- a/lib_util/tinywaveout_c.h +++ b/lib_util/tinywaveout_c.h @@ -490,6 +490,49 @@ static int32_t WriteWavShort( return __TWO_SUCCESS; } +#ifdef DEBUG_JBM +/* this function expects values in the 16 bit range +-32767/8 */ +static int32_t WriteWavFloat( + WAVEFILEOUT *self, + float sampleBuffer[], + uint32_t nSamples ) +{ + uint32_t i; + int32_t err = __TWO_SUCCESS; + + if ( !self ) + { + return __TWO_ERROR; + } + if ( !sampleBuffer ) + { + return __TWO_ERROR; + } + if ( __dataSizeChk( self, nSamples * sizeof( float ) ) ) + { + return __TWO_ERROR; + } + + for ( i = 0; i < nSamples; i++ ) + { + if ( self->bps == 32 ) + { + err = __WriteSample32( self, sampleBuffer[i]/32768.0f); + } + else + { + err = __TWO_ERROR; + } + if ( err != __TWO_SUCCESS ) + { + return err; + } + } + + return __TWO_SUCCESS; +} +#endif + static int32_t CloseWav( WAVEFILEOUT *self ) { diff --git a/lib_util/tsm_scale_file_reader.c b/lib_util/tsm_scale_file_reader.c new file mode 100644 index 0000000000..5c2e51edfa --- /dev/null +++ b/lib_util/tsm_scale_file_reader.c @@ -0,0 +1,148 @@ +/****************************************************************************************************** + + (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. + +*******************************************************************************************************/ + +#include "tsm_scale_file_reader.h" +#include "cmdl_tools.h" +#include +#include +#include + +struct TsmScaleFileReader +{ + FILE *file; + char *file_path; + bool fileRewind; +}; + + +/*---------------------------------------------------------------------* + * TsmScaleFileReader_open() + * + * Allocates memory for an TsmScaleFileReader and opens the file at given path for reading. + *---------------------------------------------------------------------*/ + +/*! r: JbmFileReader handle */ +TsmScaleFileReader *TsmScaleFileReader_open( + const char *filePath /* i : path to CA config file */ +) +{ + TsmScaleFileReader *self; + FILE *file; + + if ( !filePath ) + { + return NULL; + } + + file = fopen( filePath, "rb" ); + + if ( !file ) + { + return NULL; + } + + self = calloc( sizeof( TsmScaleFileReader ), 1 ); + self->file = file; + self->file_path = calloc( sizeof( char ), strlen( filePath ) + 1 ); + strcpy( self->file_path, filePath ); + + return self; +} + + +/*---------------------------------------------------------------------* + * TsmScaleFileReader_readScale() + * + * Read TSM scale entry + *---------------------------------------------------------------------*/ + +ivas_error TsmScaleFileReader_readScale( + TsmScaleFileReader *self, /* i/o: TsmScaleFileReader handle */ + int16_t *scale /* o : scale */ +) +{ + int tmp; + if ( 1 != fscanf( self->file, "%d", &tmp ) ) + { + if ( feof( self->file ) ) + { + rewind( self->file ); + self->fileRewind = true; + return TsmScaleFileReader_readScale( self, scale ); + } + return IVAS_ERR_FAILED_FILE_PARSE; + } + *scale = (int16_t) tmp; + return IVAS_ERR_OK; +} + + +/*---------------------------------------------------------------------* + * JbmFileReader_close() + * + * De-allocates all underlying memory of an JbmFileReader. + *---------------------------------------------------------------------*/ + +void TsmScaleFileReader_close( + TsmScaleFileReader **selfPtr /* i/o: pointer to JbmFileReader handle */ +) +{ + if ( selfPtr == NULL || *selfPtr == NULL ) + { + return; + } + + fclose( ( *selfPtr )->file ); + free( ( *selfPtr )->file_path ); + free( *selfPtr ); + *selfPtr = NULL; + + return; +} + + +/*---------------------------------------------------------------------* + * JbmFileReader_getFilePath() + * + *---------------------------------------------------------------------*/ + +const char *TsmScaleFileReader_getFilePath( + TsmScaleFileReader *self /* i/o: JbmFileReader handle */ +) +{ + if ( self == NULL ) + { + return NULL; + } + + return self->file_path; +} diff --git a/lib_util/tsm_scale_file_reader.h b/lib_util/tsm_scale_file_reader.h new file mode 100644 index 0000000000..7a795a25cb --- /dev/null +++ b/lib_util/tsm_scale_file_reader.h @@ -0,0 +1,67 @@ +/****************************************************************************************************** + + (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_TSM_SCALE_FILE_READER_H +#define IVAS_TSM_SCALE_FILE_READER_H + +#include +#include "common_api_types.h" +#include "ivas_error.h" + +/* clang-format off */ + +typedef struct TsmScaleFileReader TsmScaleFileReader; + + +/*! r: TsmScaleFileReader handle */ +TsmScaleFileReader *TsmScaleFileReader_open( + const char *filePath /* i : path to TSM scale file */ +); + +ivas_error TsmScaleFileReader_readScale( + TsmScaleFileReader* self, /* i/o: TsmScaleFileReader handle */ + int16_t *scale /* o : next scale */ +); + +void TsmScaleFileReader_close( + TsmScaleFileReader **selfPtr /* i/o: pointer to TsmScaleFileReader handle */ +); + +/*! r: path to the currently opened file or NULL if `self` is NULL */ +const char *TsmScaleFileReader_getFilePath( + TsmScaleFileReader* self /* i/o: TsmScaleFileReader handle */ +); + + +/* clang-format on */ + +#endif /* IVAS_TSM_SCALE_FILE_READER_H */ diff --git a/scripts/batch_comp_audio.py b/scripts/batch_comp_audio.py index 72ae3fcc7d..97e9f8f548 100755 --- a/scripts/batch_comp_audio.py +++ b/scripts/batch_comp_audio.py @@ -96,10 +96,9 @@ def main(args): if not args.diffs_only or diff > 0: if diff == 0.0: - label = "\033[00;32m[OKAY]\033[00;00m" + label = "[OKAY]" else: - label = "\033[00;31m[FAIL]\033[00;00m" - + label = "[FAIL]" result = f"{label} Max. diff (PCM) for file {f}: {diff}" if args.verbose and diff != 0.0: @@ -108,10 +107,10 @@ def main(args): print(result, file=out_file) - if num_files_diff > 0: - print(f"{num_files_diff} files differ/don't exist", file=out_file) - else: - print(f"All files are bitexact", file=out_file) + if num_files_diff > 0: + print(f"{num_files_diff} files differ/don't exist", file=out_file) + else: + print(f"All files are bitexact", file=out_file) def compare_files(f, fol1, fol2, outputs_dict): diff --git a/scripts/config/ivas_modes.json b/scripts/config/ivas_modes.json index 0e4ef469d9..b384a2ea5e 100644 --- a/scripts/config/ivas_modes.json +++ b/scripts/config/ivas_modes.json @@ -964,6 +964,44 @@ ] } }, + "MASA_1TC_1DIR_b{bitrate}_{bandwidth}_rs": { + "encmodeoption": [ + "-masa", + "1" + ], + "encoptions": [ + "-max_band", + "{bandwidth}" + ], + "dec": { + "7_1_4": [], + "HOA3": [], + "mono": [], + "stereo": [], + "EXT": [] + }, + "in_config": "MASA1TC1DIR", + "table_name": "MASA 1TC 1DIR@{table_bitrate} kbps RS {bandwidth}", + "nummetadata": 1, + "metadatafilenames": [ + "{item}.met" + ], + "rs": true, + "amr": false, + "mono": false, + "bitrates": { + "wb": { + "all": "{sw_files_path}/sw_13k2_512k.bin" + }, + "swb": { + "all": "{sw_files_path}/sw_13k2_512k.bin" + }, + "fb": { + "all": "{sw_files_path}/sw_13k2_512k.bin" + } + } + + }, "MASA_2TC_1DIR_b{bitrate}_{bandwidth}_cbr": { "encmodeoption": [ "-masa", @@ -1034,6 +1072,46 @@ ] } }, + "MASA_2TC_1DIR_b{bitrate}_{bandwidth}_cbr": { + "encmodeoption": [ + "-masa", + "2" + ], + "encoptions": [ + "-max_band", + "{bandwidth}" + ], + "dec": { + "7_1_4": [], + "HOA3": [], + "mono": [], + "stereo": [], + "EXT": [] + }, + "in_config": "MASA2TC1DIR", + "table_name": "MASA 2TC 1DIR@{table_bitrate} kbps {bandwidth}", + "nummetadata": 1, + "metadatafilenames": [ + "{item}.met" + ], + "rs": false, + "amr": false, + "mono": false, + "rs": true, + "amr": false, + "mono": false, + "bitrates": { + "wb": { + "all": "{sw_files_path}/sw_13k2_512k.bin" + }, + "swb": { + "all": "{sw_files_path}/sw_13k2_512k.bin" + }, + "fb": { + "all": "{sw_files_path}/sw_13k2_512k.bin" + } + } + }, "MASA_1TC_2DIR_b{bitrate}_{bandwidth}_cbr": { "encmodeoption": [ "-masa", @@ -1851,6 +1929,39 @@ ] } }, + "ISM1_b{bitrate}_{bandwidth}_rs": { + "encmodeoption": [ + "-ism", + "1" + ], + "encoptions": [ + "-max_band", + "{bandwidth}" + ], + "dec": { + "EXT": [] + }, + "in_config": "ISM1", + "table_name": "ISM1@{table_bitrate} RS kbps {bandwidth}", + "nummetadata": 1, + "metadatafilenames": [ + "test_ISM_trajectory{mdi}.csv" + ], + "rs": true, + "amr": false, + "mono": false, + "bitrates": { + "wb": { + "all": "{sw_files_path}/sw_13k2_256k.bin" + }, + "swb": { + "all": "{sw_files_path}/sw_13k2_256k.bin" + }, + "fb": { + "all": "{sw_files_path}/sw_32k_256k.bin" + } + } + }, "ISM1_b{bitrate}_dtx_{bandwidth}_cbr": { "encmodeoption": [ "-ism", @@ -2030,6 +2141,39 @@ 256000 ] } + }, + "ISM2_b{bitrate}_{bandwidth}_rs": { + "encmodeoption": [ + "-ism", + "2" + ], + "encoptions": [ + "-max_band", + "{bandwidth}" + ], + "dec": { + "EXT": [] + }, + "in_config": "ISM2", + "table_name": "ISM2@{table_bitrate} kbps RS {bandwidth}", + "nummetadata": 2, + "metadatafilenames": [ + "test_ISM_trajectory{mdi}.csv" + ], + "rs": true, + "amr": false, + "mono": false, + "bitrates": { + "wb": { + "all": "{sw_files_path}/sw_16k4_256k.bin" + }, + "swb": { + "all": "{sw_files_path}/sw_16k4_256k.bin" + }, + "fb": { + "all": "{sw_files_path}/sw_32k_256k.bin" + } + } } }, "ISM3": { @@ -2157,6 +2301,39 @@ 384000 ] } + }, + "ISM3_b{bitrate}_{bandwidth}_rs": { + "encmodeoption": [ + "-ism", + "3" + ], + "encoptions": [ + "-max_band", + "{bandwidth}" + ], + "dec": { + "EXT": [] + }, + "in_config": "ISM3", + "table_name": "ISM3@{table_bitrate} kbps {bandwidth}", + "nummetadata": 3, + "metadatafilenames": [ + "test_ISM_trajectory{mdi}.csv" + ], + "rs": true, + "amr": false, + "mono": false, + "bitrates": { + "wb": { + "all": "{sw_files_path}/sw_24k4_256k_1.bin" + }, + "swb": { + "all": "{sw_files_path}/sw_24k4_256k_1.bin" + }, + "fb": { + "all": "{sw_files_path}/sw_32k_256k.bin" + } + } } }, "ISM4": { @@ -2290,6 +2467,39 @@ 512000 ] } + }, + "ISM4_b{bitrate}_{bandwidth}_rs": { + "encmodeoption": [ + "-ism", + "4" + ], + "encoptions": [ + "-max_band", + "{bandwidth}" + ], + "dec": { + "EXT": [] + }, + "in_config": "ISM4", + "table_name": "ISM4@{table_bitrate} kbps RS {bandwidth}", + "nummetadata": 4, + "metadatafilenames": [ + "test_ISM_trajectory{mdi}.csv" + ], + "rs": true, + "amr": false, + "mono": false, + "bitrates": { + "wb": { + "all": "{sw_files_path}/sw_24k4_256k_1.bin" + }, + "swb": { + "all": "{sw_files_path}/sw_24k4_256k_1.bin" + }, + "fb": { + "all": "{sw_files_path}/sw_32k_256k.bin" + } + } } }, "stereo": { diff --git a/scripts/runIvasCodec.py b/scripts/runIvasCodec.py index 070fb8e4f0..f96758e5be 100755 --- a/scripts/runIvasCodec.py +++ b/scripts/runIvasCodec.py @@ -34,6 +34,7 @@ import os.path import platform import sys import logging +import shutil from pyivastest import IvasScriptsCommon, IvasModeRunner import pyivastest.constants as constants @@ -81,6 +82,11 @@ class RunIvasCodec(IvasScriptsCommon.IvasScript): help="Decoder binary name (default {})".format(default_dec), default=default_dec, ) + self.parser.add_argument( + "--fail_log_dir", + help="Move logs of failed modes to dir (default none)", + default=None, + ) def run(self): self.parse_args() @@ -137,10 +143,19 @@ class RunIvasCodec(IvasScriptsCommon.IvasScript): self.logger.console(" Encoder: {}".format(bin_enc), logging.INFO) self.logger.console(" Decoder: {}".format(bin_dec), logging.INFO) + runner.run() self.logger.console(" ") + fail_log_dir=None + if self.args["fail_log_dir"] is not None: + fail_log_dir = os.path.realpath(self.args["fail_log_dir"]) + if not(os.path.exists(fail_log_dir)): + os.makedirs(fail_log_dir) for r in runner.results: self.logger.console(r[0]) + if fail_log_dir is not None: + shutil.copy(r[3],fail_log_dir) + self.logger.console(" ") -- GitLab From 6568718f765d9ae27c1eb332f9bb25775d64b343 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Wed, 26 Apr 2023 10:27:49 +0200 Subject: [PATCH 02/39] Fixed most BE problems --- lib_com/options.h | 4 +- lib_dec/ivas_dirac_dec.c | 48 ++++++----------------- lib_dec/ivas_dirac_output_synthesis_dec.c | 14 +++++-- lib_dec/ivas_mc_param_dec.c | 7 +++- lib_dec/ivas_sba_rendering_internal.c | 27 ++++++++----- 5 files changed, 48 insertions(+), 52 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index e7ffeb2b7a..a9d34de2c1 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -113,7 +113,7 @@ /*#define TDREND_HRTF_TABLE_METHODS*/ /* Enable HRTF lookup from tables, for testing & evaluation. Supply file in table format to use. Note that a suitable HR filter lookup method should be written if the filters sample point grids are not in the formats. */ /*#define TDREND_STANDALONE*/ /* Used when renderer is built in standalone form, without IVAS encoding/decoding (see scripts/object_renderer_standalone). This is just here to ensure this is cleaned out by prepare_instrumentation.sh */ -#define DEBUG_SBA /* debug DIRAC/SPAR in-out */ +/*#define DEBUG_SBA*/ /* debug DIRAC/SPAR in-out */ #ifdef DEBUG_SBA /*#define DEBUG_SBA_AUDIO_DUMP */ /* SBA intermediate audio wav file dumping */ /*#define DEBUG_SBA_MD_DUMP*/ /* SBA metadata and variable file dumping */ @@ -156,7 +156,7 @@ #ifdef JBM_TSM_ON_TCS #define TEST_BIN_RENDERER_BE #define TMP_FIX_ISM_BR_SWITCHING /* */ -/*#define JBM_DIRAC_DEBUG_BE*/ +#define JBM_DIRAC_DEBUG_BE #endif /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 9bb43b39c9..1a831d3103 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -1043,10 +1043,10 @@ ivas_error ivas_dirac_dec_config( } } } - + #endif /* JBM_TMS_ON_TCS*/ - return error; + return error; } @@ -1934,7 +1934,9 @@ void ivas_qmetadata_to_dirac( { hDirAC->elevation[tmp_write_idx_band][b] = 0; hDirAC->azimuth[tmp_write_idx_band][b] = 0; +#if 0 hDirAC->diffuseness_vector[tmp_write_idx_band][b] = 0.f; +#endif hDirAC->spreadCoherence[tmp_write_idx_band][b] = 0.0f; hDirAC->surroundingCoherence[tmp_write_idx_band][b] = 0.0f; hDirAC->energy_ratio1[tmp_write_idx_band][b] = 0; @@ -2557,39 +2559,16 @@ void ivas_dirac_dec_render_sf( #endif } } - - if ( st_ivas->hDecoderConfig->Opt_Headrotation && st_ivas->hHeadTrackData->shd_rot_max_order == 1 ) - { - ivas_dirac_dec_compute_directional_responses( hDirAC, - st_ivas->hVBAPdata, - st_ivas->hMasa, - surCohRatio, - st_ivas->hHeadTrackData->shd_rot_max_order, - p_Rmat ); - } - else - { - ivas_dirac_dec_compute_directional_responses( hDirAC, - st_ivas->hVBAPdata, - st_ivas->hMasa, - surCohRatio, - 0, - 0 ); - } } - if ( st_ivas->hDecoderConfig->Opt_Headrotation && st_ivas->hHeadTrackData->shd_rot_max_order == 1 ) { ivas_dirac_dec_compute_directional_responses( hDirAC, st_ivas->hVBAPdata, st_ivas->hMasa, #ifdef JBM_TSM_ON_TCS - azimuth[0], - elevation[0], + hDirAC->azimuth[md_idx], + hDirAC->elevation[md_idx], md_idx, -#else - subframe_idx, - subframe_idx, #endif surCohRatio, st_ivas->hHeadTrackData->shd_rot_max_order, @@ -2601,12 +2580,9 @@ void ivas_dirac_dec_render_sf( st_ivas->hVBAPdata, st_ivas->hMasa, #ifdef JBM_TSM_ON_TCS - azimuth[0], - elevation[0], + hDirAC->azimuth[md_idx], + hDirAC->elevation[md_idx], md_idx, -#else - subframe_idx, - subframe_idx, #endif surCohRatio, 0, @@ -2986,7 +2962,7 @@ void ivas_dirac_dec_render_sf( hDirAC, st_ivas->hMasa, 0, - p_Rmat, + 0, st_ivas->hVBAPdata, hDirAC->hOutSetup, nchan_transport, @@ -3039,7 +3015,7 @@ void ivas_dirac_dec_render_sf( qualityBasedSmFactor *= qualityBasedSmFactor; } #ifdef JBM_TSM_ON_TCS - /* Workaround for BE */ + /* Workaround for BE (should be gone when #393 is adressed) */ if ( hDirAC->hConfig->dec_param_estim == 1 ) { num_freq_bands = hDirAC->band_grouping[hDirAC->hConfig->enc_param_start_band]; @@ -3056,11 +3032,11 @@ void ivas_dirac_dec_render_sf( /* we are at the end, get the next one using the normal dirac read idx...*/ if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) { - diff_md_idx = ( hDirAC->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS + 1 ) % hDirAC->dirac_md_buffer_length; + diff_md_idx = ( hDirAC->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % hDirAC->dirac_md_buffer_length; } else { - diff_md_idx = ( hDirAC->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS + 1 ) % hDirAC->dirac_md_buffer_length; + diff_md_idx = ( hDirAC->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % hDirAC->dirac_md_buffer_length; } } else diff --git a/lib_dec/ivas_dirac_output_synthesis_dec.c b/lib_dec/ivas_dirac_output_synthesis_dec.c index ffbff9014a..670bd0072b 100644 --- a/lib_dec/ivas_dirac_output_synthesis_dec.c +++ b/lib_dec/ivas_dirac_output_synthesis_dec.c @@ -846,7 +846,11 @@ void ivas_dirac_dec_output_synthesis_process_slot( /* process other PSDs only slot wise for 4 transport channels */ #if !defined( JBM_TSM_ON_TCS ) || defined( JBM_DIRAC_DEBUG_BE ) +#if defined( JBM_DIRAC_DEBUG_BE ) + if ( hDirAC->hConfig->dec_param_estim == TRUE || hDirAC->voip_active == 1) +#else if ( hDirAC->hConfig->dec_param_estim == TRUE ) +#endif #endif { computeTargetPSDs_direct( num_channels_dir, num_freq_bands, h_dirac_output_synthesis_state->direct_power_factor, reference_power, h_dirac_output_synthesis_state->direct_responses, h_dirac_output_synthesis_state->direct_responses_square, h_dirac_output_synthesis_state->cy_auto_dir_smooth, h_dirac_output_synthesis_state->cy_cross_dir_smooth ); @@ -1165,7 +1169,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( float qualityBasedSmFactor ) { int16_t buf_idx, num_freq_bands; -#ifndef JBM_TSM_ON_TCS +#if !defined( JBM_TSM_ON_TCS ) || defined( JBM_DIRAC_DEBUG_BE ) int16_t diff_start_band; #endif int16_t k, l; @@ -1188,7 +1192,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( float subtract_target_ratio; float subtract_target_ratio_db; float a, b; -#ifndef JBM_TSM_ON_TCS +#if !defined( JBM_TSM_ON_TCS ) || defined( JBM_DIRAC_DEBUG_BE ) uint16_t nchan_target_psds; #endif float alpha[CLDFB_NO_CHANNELS_MAX]; @@ -1211,8 +1215,12 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( /*-----------------------------------------------------------------* * compute target PSDs *-----------------------------------------------------------------*/ -#ifndef JBM_TSM_ON_TCS +#if !defined( JBM_TSM_ON_TCS ) || defined( JBM_DIRAC_DEBUG_BE ) +#ifdef JBM_DIRAC_DEBUG_BE + if ( hDirAC->hConfig->enc_param_start_band == 0 && hDirAC->voip_active == 0 ) +#else if ( hDirAC->hConfig->enc_param_start_band == 0 ) +#endif { diff_start_band = h_dirac_output_synthesis_params->use_onset_filters == 1 ? h_dirac_output_synthesis_params->max_band_decorr : 0; diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index f75c5fa830..a7e2611225 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -1469,7 +1469,12 @@ void ivas_param_mc_dec_digest_tc( hParamMC->slots_rendered = 0; hParamMC->subframes_rendered = 0; ivas_jbm_dec_get_adapted_subframes( nCldfbSlots, hParamMC->subframe_nbslots, &hParamMC->nb_subframes ); - ivas_param_mc_dec_compute_interpolator( hParamMC->hMetadataPMC->bAttackPresent, hParamMC->hMetadataPMC->attackIndex, nCldfbSlots, hParamMC->h_output_synthesis_params.interpolator ); + + /* BE Workaround */ + if ( !st_ivas->bfi && st_ivas->hDecoderConfig->voip_active == 0 ) + { + ivas_param_mc_dec_compute_interpolator( hParamMC->hMetadataPMC->bAttackPresent, hParamMC->hMetadataPMC->attackIndex, nCldfbSlots, hParamMC->h_output_synthesis_params.interpolator ); + } for ( param_band_idx = 0; param_band_idx < PARAM_MC_MAX_PARAMETER_BANDS; param_band_idx++ ) { diff --git a/lib_dec/ivas_sba_rendering_internal.c b/lib_dec/ivas_sba_rendering_internal.c index bc9b4cb7cb..3c463f68c0 100644 --- a/lib_dec/ivas_sba_rendering_internal.c +++ b/lib_dec/ivas_sba_rendering_internal.c @@ -68,7 +68,7 @@ void ivas_sba2mc_cldfb( #ifdef JBM_TSM_ON_TCS const int16_t nb_timeslots, /* i : number of time slots to process */ #endif - const float *hoa_dec_mtx /* i : HOA decoding mtx */ + const float *hoa_dec_mtx /* i : HOA decoding mtx */ ) { int16_t iBlock, iBand, n, m; @@ -144,16 +144,16 @@ void ivas_sba2mc_cldfb( *-------------------------------------------------------------------------*/ void ivas_mc2sba( - IVAS_OUTPUT_SETUP hIntSetup, /* i : Format of decoder output */ + IVAS_OUTPUT_SETUP hIntSetup, /* i : Format of decoder output */ #ifdef JBM_TSM_ON_TCS float *in_buffer_td[], /* i : MC signals (on input) and the HOA3 (on output) */ float *buffer_td[], /* i/o: MC signals (on input) and the HOA3 (on output) */ #else float buffer_td[][L_FRAME48k], /* i/o: MC signals (on input) and the HOA3 (on output) */ #endif - const int16_t output_frame, /* i : output frame length per channel */ - const int16_t sba_order, /* i : Ambisonic (SBA) order */ - const float gain_lfe /* i : gain for LFE, 0 = ignore LFE */ + const int16_t output_frame, /* i : output frame length per channel */ + const int16_t sba_order, /* i : Ambisonic (SBA) order */ + const float gain_lfe /* i : gain for LFE, 0 = ignore LFE */ ) { int16_t i, j, k; @@ -430,13 +430,17 @@ void ivas_sba_upmixer_renderer( ) { - int16_t i, nchan_internal; + int16_t nchan_internal; +#ifndef JBM_TSM_ON_TCS + int16_t i; float temp; +#endif push_wmops( "ivas_sba_upmixer_renderer" ); nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order ); +#ifndef JBM_TSM_ON_TCS if ( st_ivas->nchan_transport >= 3 ) { /*convert WYZX downmix to WYXZ*/ @@ -447,14 +451,17 @@ void ivas_sba_upmixer_renderer( output[3][i] = temp; } } +#endif /* Upmixer + Renderer */ ivas_spar_dec_upmixer( st_ivas, output, nchan_internal, output_frame ); + if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC ) + { #ifdef JBM_TSM_ON_TCS float *output_f[MAX_OUTPUT_CHANNELS]; int16_t ch; - for (ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++) + for ( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) { output_f[ch] = output[ch]; } @@ -462,7 +469,7 @@ void ivas_sba_upmixer_renderer( #else ivas_sba_linear_renderer( output, output_frame, st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hDecoderConfig->output_config, st_ivas->hOutSetup, st_ivas->hoa_dec_mtx ); #endif - + } pop_wmops(); return; @@ -479,7 +486,7 @@ static void ivas_sba_mtx_mult( #ifdef JBM_TSM_ON_TCS float *output_f[], /* i/o: synthesized core-corder transport channels/DirAC output */ #else - float output_f[][L_FRAME48k], /* i/o: synthesized core-corder transport channels/DirAC output */ + float output_f[][L_FRAME48k], /* i/o: synthesized core-corder transport channels/DirAC output */ #endif const int16_t output_frame, /* i : output frame length per channel */ const int16_t nchan_in, /* i : Number of ambisonic channels */ @@ -543,7 +550,7 @@ ivas_error ivas_sba_linear_renderer( #ifdef JBM_TSM_ON_TCS float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ #else - float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ + float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ #endif const int16_t output_frame, /* i : output frame length per channel */ const int16_t nchan_in, /* i : number of input ambisonics channels */ -- GitLab From 4793a158bc70984534bda4ad54ae3dc791b73f12 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Wed, 26 Apr 2023 12:55:35 +0200 Subject: [PATCH 03/39] fixed decoder app for variable speed decoding, added br switch profiles for ISM, cleanup --- apps/decoder.c | 19 +++- lib_com/options.h | 5 +- lib_debug/debug.c | 104 +------------------ lib_debug/debug.h | 15 --- lib_dec/ivas_dec.c | 4 +- lib_dec/ivas_spar_decoder.c | 88 +--------------- lib_dec/lib_dec.c | 6 +- lib_rend/ivas_dirac_dec_binaural_functions.c | 31 +----- scripts/switchPaths/sw_13k2_256k.bin | 3 + scripts/switchPaths/sw_16k4_256k.bin | 3 + scripts/switchPaths/sw_24k4_256k_1.bin | 3 + scripts/switchPaths/sw_32k_256k.bin | 3 + 12 files changed, 34 insertions(+), 250 deletions(-) create mode 100644 scripts/switchPaths/sw_13k2_256k.bin create mode 100644 scripts/switchPaths/sw_16k4_256k.bin create mode 100644 scripts/switchPaths/sw_24k4_256k_1.bin create mode 100644 scripts/switchPaths/sw_32k_256k.bin diff --git a/apps/decoder.c b/apps/decoder.c index 4b09ce7d36..05b8862735 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -2394,7 +2394,7 @@ static ivas_error decodeVariableSpeed( int16_t numInitialBadFrames = 0; /* Number of bad frames received until first good frame is decoded */ int16_t nOutChannels = 0; int16_t delayNumSamples = -1; - int16_t delayNumSamples_orig = 0; + int16_t delayNumSamples_orig[3]; int16_t nOutSamples = 0; int32_t delayTimeScale = 0; ivas_error error = IVAS_ERR_UNKNOWN; @@ -2437,6 +2437,8 @@ static ivas_error decodeVariableSpeed( fprintf( stdout, "\n-- Start the decoder (quiet mode) --\n\n" ); } + delayNumSamples_orig[0] = -1; + #ifdef WMOPS reset_stack(); reset_wmops(); @@ -2595,7 +2597,7 @@ static ivas_error decodeVariableSpeed( arg, numInitialBadFrames, nOutSamples, - &delayNumSamples_orig, + delayNumSamples_orig, &delayNumSamples, &delayTimeScale, &bsFormat, @@ -2844,7 +2846,13 @@ static ivas_error decodeVariableSpeed( if ( !arg.quietModeEnabled ) { - fprintf( stdout, "\nDecoder delay: %-5u [samples] - Timescale: %5u\n", delayNumSamples_orig, delayTimeScale ); + printf( "\n\nDecoder+renderer delay: %4.2f ms (%3u samples at timescale %5u)\n", 1000.f * delayNumSamples_orig[1] / (float) delayTimeScale, delayNumSamples_orig[1], delayTimeScale ); + + if ( delayNumSamples_orig[2] > 0 ) + { + printf( "HRIR/BRIR delay: %4.2f ms (%3u samples at timescale %5u)\n", 1000.f * delayNumSamples_orig[2] / (float) delayTimeScale, delayNumSamples_orig[2], delayTimeScale ); + printf( "Total delay: %4.2f ms (%3u samples at timescale %5u)\n", 1000.f * ( delayNumSamples_orig[1] + delayNumSamples_orig[2] ) / (float) delayTimeScale, delayNumSamples_orig[1] + delayNumSamples_orig[2], delayTimeScale ); + } } /* Print output metadata file name(s) */ @@ -2865,8 +2873,8 @@ static ivas_error decodeVariableSpeed( } /* add zeros at the end to have equal length of synthesized signals */ - memset( pcmBuf, 0, delayNumSamples_orig * nOutChannels * sizeof( int16_t ) ); - if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig * nOutChannels ) ) != IVAS_ERR_OK ) + memset( pcmBuf, 0, delayNumSamples_orig[0] * nOutChannels * sizeof( int16_t ) ); + if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) ); goto cleanup; @@ -2882,6 +2890,7 @@ cleanup: AudioFileWriter_close( &afWriter ); MasaFileWriter_close( &masaWriter ); + TsmScaleFileReader_close( &tsmScaleFileReader ); for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; i++ ) { IsmFileWriter_close( &ismWriters[i] ); diff --git a/lib_com/options.h b/lib_com/options.h index a9d34de2c1..f1a4d6ecce 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -72,7 +72,6 @@ /*#define DEBUG_MODE_INFO_PLC */ /* define to output PLC related parameters */ /*#define DEBUG_MODE_INFO_ALLRAD*/ /* define to output generated HOA decoding mtx */ /*#define DEBUG_MODE_LFE */ /* define to output LFE relevant parameters */ -/*#define DEBUG_MODE_JBM */ /* define to output import JBM parameters */ #endif #ifdef DEBUG_MODE_MDCT @@ -113,7 +112,7 @@ /*#define TDREND_HRTF_TABLE_METHODS*/ /* Enable HRTF lookup from tables, for testing & evaluation. Supply file in table format to use. Note that a suitable HR filter lookup method should be written if the filters sample point grids are not in the formats. */ /*#define TDREND_STANDALONE*/ /* Used when renderer is built in standalone form, without IVAS encoding/decoding (see scripts/object_renderer_standalone). This is just here to ensure this is cleaned out by prepare_instrumentation.sh */ -/*#define DEBUG_SBA*/ /* debug DIRAC/SPAR in-out */ +#define DEBUG_SBA /* debug DIRAC/SPAR in-out */ #ifdef DEBUG_SBA /*#define DEBUG_SBA_AUDIO_DUMP */ /* SBA intermediate audio wav file dumping */ /*#define DEBUG_SBA_MD_DUMP*/ /* SBA metadata and variable file dumping */ @@ -126,7 +125,6 @@ /*#define SPAR_HOA_DBG*/ /* SPAR HOA debug statements */ /*#define DEBUG_BINAURAL_FILTER_DESIGN*/ /* debugging of Crend binaural filter design */ #define DEBUG_AGC_ENCODER_CMD_OPTION /* Ability to force enable or disable AGC behaviour in DIRAC/SPAR via command line option */ -/*#define DEBUG_JBM*/ #define DEBUG_JBM_CMD_OPTION /* ability for telling the decoder the frontend fetch size and to not delay compensate for bad frames at the beginning */ #endif @@ -154,7 +152,6 @@ #define VARIABLE_SPEED_DECODING /* FhG: variable speed decoding employing the JBM functioniality */ #define JBM_TSM_ON_TCS /* FhG: run the TSM part of JBM on the TCs instead of the final output pcm waveforms */ #ifdef JBM_TSM_ON_TCS -#define TEST_BIN_RENDERER_BE #define TMP_FIX_ISM_BR_SWITCHING /* */ #define JBM_DIRAC_DEBUG_BE #endif diff --git a/lib_debug/debug.c b/lib_debug/debug.c index 4e4cf1cf8b..ce10231876 100644 --- a/lib_debug/debug.c +++ b/lib_debug/debug.c @@ -54,9 +54,6 @@ #else #endif #include "wmc_auto.h" -#ifdef DEBUG_JBM -#include "tinywaveout_c.h" -#endif /*-------------------------------------------------------------------* @@ -96,12 +93,6 @@ static FILE *out_fileptr[N_FILEPTR]; static char *in_filename[N_FILEPTR]; static char *out_filename[N_FILEPTR]; -#ifdef DEBUG_MODE_JBM -static char *wav_out_filename[N_FILEPTR]; -static WAVEFILEOUT *wav_out_fileptr[N_FILEPTR]; -static int16_t wav_count; -#endif - static int16_t in_count = 0; static int16_t out_count = 0; @@ -210,92 +201,6 @@ int16_t dbgwrite( return 0; } -#ifdef DEBUG_MODE_JBM -/*-------------------------------------------------------------------* - * dbgwritewav() - * - * Writes the buffer content to the specified file. If the file is not in the - * debug file list, it is opened before write. - *--------------------------------------------------------------------*/ - -int16_t dbgwritewav( - const int16_t input_frame, - float **ppPcm, - float pcm_array[MAX_OUTPUT_CHANNELS][L_FRAME48k], - const int16_t no_channel, - const int32_t fs, -#ifdef DEBUG_MODE_INFO_TWEAK - const char *filename /* i : Output file name */ -#else - const char *const filename -#endif -) -{ - int16_t index, i; - -#ifdef DEBUG_MODE_INFO -#ifdef DEBUG_MODE_INFO_TWEAK - char filename_mod[FILENAME_MAX]; - int16_t textmode = 0; - memset( filename_mod, 0, FILENAME_MAX ); - tweakdbgfolder( filename, filename_mod, &textmode ); - if ( filename_mod[0] != 0 ) - { - filename = filename_mod; - } -#endif -#endif - - index = lookup( filename, (const char *const *) wav_out_filename, wav_count ); - - if ( index == -1 ) - { - if ( make_dirs( filename ) != 0 ) - { - fprintf( stderr, "dbgwrite: Could not create directory structure for %s. Exiting..\n", filename ); - exit( -1 ); - } - - index = wav_count; - wav_out_filename[index] = malloc( sizeof( char ) * ( strlen( filename ) + 1 ) ); - strcpy( wav_out_filename[index], filename ); - wav_out_fileptr[index] = CreateWav( (const char *) wav_out_filename[index], fs, no_channel, 32 /* const uint32_t writeWaveExt */ ); - - wav_count++; - } - - if ( wav_out_fileptr[index] != NULL ) - { - float debug_tmp[IVAS_SPAR_MAX_CH * L_FRAME48k * 2]; - int32_t j, k; - k = 0; - for ( j = 0; j < input_frame; j++ ) - { - for ( i = 0; i < no_channel; i++, k++ ) - { - float tmp_value; - if ( ppPcm ) - { - tmp_value = ppPcm[i][j]; - } - else - { - tmp_value = pcm_array[i][j]; - } - debug_tmp[k] = tmp_value; - } - } - WriteWavFloat( wav_out_fileptr[index], debug_tmp, ( no_channel * input_frame ) ); - } - else - { - fprintf( stderr, "dbgwrite: Could not write to file: %s. Exiting..\n", filename ); - exit( -1 ); - } - - return 0; -} -#endif /*-------------------------------------------------------------------* * dbgwrite_mat_repeat() @@ -502,14 +407,7 @@ void dbgclose() free( val_name[i] ); free( val[i] ); } -#ifdef DEBUG_MODE_JBM - for ( i = 0; i < wav_count; i++ ) - { - CloseWav( wav_out_fileptr[i] ); - wav_out_fileptr[i] = NULL; - free( wav_out_filename[i] ); - } -#endif + return; } diff --git a/lib_debug/debug.h b/lib_debug/debug.h index c89f245af6..3d59cb00a0 100644 --- a/lib_debug/debug.h +++ b/lib_debug/debug.h @@ -98,21 +98,6 @@ int16_t dbgwrite( #endif ); -#ifdef DEBUG_MODE_JBM -int16_t dbgwritewav( - const int16_t input_frame, - float **ppPcm, - float pcm_array[MAX_OUTPUT_CHANNELS][L_FRAME48k], - const int16_t no_channel, - const int32_t fs, -#ifdef DEBUG_MODE_INFO_TWEAK - const char *filename /* i : Output file name */ -#else - const char *const filename -#endif -); -#endif - void dbgwrite_mat_repeat( float *buffer, /* i : write buffer */ int16_t nRow, /* i : matrix size (rows) */ diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index 98490a2ace..c126d1243d 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -369,9 +369,7 @@ ivas_error ivas_dec( /* Dump audio signal after core-decoding */ ivas_spar_dump_signal_wav( output_frame, NULL, output, st_ivas->nchan_transport, spar_foa_dec_wav[0], "core-decoding" ); #endif -#ifdef DEBUG_MODE_JBM - dbgwritewav( output_frame, NULL, output, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, "res/sba_tc.wav" ); -#endif + /* TCs remapping */ nchan_remapped = st_ivas->nchan_transport; if ( st_ivas->sba_dirac_stereo_flag ) diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index 4f74ae0c7a..52cfc7910b 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -969,36 +969,13 @@ void ivas_spar_dec_agc_pca( /* Dump audio signal after ivas_agc_dec_process */ ivas_spar_dump_signal_wav( output_frame, NULL, output, st_ivas->nchan_transport, spar_foa_dec_wav[1], "ivas_agc_dec_process()" ); #endif -#ifdef DEBUG_MODE_JBM - { - int k; - dbgwritewav( output_frame, NULL, output, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, "res/spar_dec_agc_process.wav" ); - for ( k = 0; k < st_ivas->nchan_transport; k++ ) - { - char filename[100]; - sprintf( filename, "res/spar_dec_agc_process_%d.dat", k ); - dbgwrite( output[k], sizeof( float ), output_frame, 1, filename ); - } - } -#endif + if ( hSpar->hPCA != NULL ) { ivas_pca_dec( hSpar->hPCA, output_frame, num_in_ingest, hDecoderConfig->ivas_total_brate, hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, output ); #ifdef DEBUG_SBA_AUDIO_DUMP /* Dump audio signal after ivas_pca_dec */ ivas_spar_dump_signal_wav( output_frame, NULL, output, num_in_ingest, spar_foa_dec_wav[2], "ivas_pca_dec()" ); -#endif -#ifdef DEBUG_MODE_JBM - { - int k; - dbgwritewav( output_frame, NULL, output, num_in_ingest, st_ivas->hDecoderConfig->output_Fs, "res/spar_pca_dec.wav" ); - for ( k = 0; k < num_in_ingest; k++ ) - { - char filename[100]; - sprintf( filename, "res/spar_pca_dec_%d.dat", k ); - dbgwrite( output[k], sizeof( float ), output_frame, 1, filename ); - } - } #endif } pop_wmops(); @@ -1096,9 +1073,6 @@ void ivas_spar_dec_digest_tc( } nSamplesLeftForTD -= nSamplesToDecorr; } -#ifdef DEBUG_MODE_JBM - dbgwritewav( nSamplesForRendering, st_ivas->tc, NULL, nchan_internal, st_ivas->hDecoderConfig->output_Fs, "res/spar_dec_td_decorr.wav" ); -#endif } ivas_spar_dec_set_render_params( st_ivas, nCldfbSlots ); @@ -1149,18 +1123,6 @@ void ivas_spar_dec_upmixer( { mvr2r( pPcm_tmp[hSpar->hTdDecorr->num_apd_outputs - 1 - i], st_ivas->hTcBuffer->tc[nchan_internal - 1 - i], output_frame ); } -#ifdef DEBUG_MODE_JBM - { - int k; - dbgwritewav( output_frame, st_ivas->tc, output, nchan_internal, st_ivas->hDecoderConfig->output_Fs, "res/spar_dec_td_decorr.wav" ); - for ( k = 0; k < nchan_internal; k++ ) - { - char filename[100]; - sprintf( filename, "res/spar_dec__tdcorr_%d.dat", k ); - dbgwrite( st_ivas->tc[k], sizeof( float ), output_frame, 1, filename ); - } - } -#endif } @@ -1314,9 +1276,6 @@ void ivas_spar_dec_upmixer( /* Dump audio signal after ivas_agc_dec_process */ ivas_spar_dump_signal_wav( output_frame, NULL, output, st_ivas->nchan_transport, spar_foa_dec_wav[1], "ivas_agc_dec_process()" ); #endif -#ifdef DEBUG_MODE_JBM - dbgwritewav( output_frame, NULL, output, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, "res/spar_dec_agc_process.wav" ); -#endif #endif /*---------------------------------------------------------------------* * TD Decorr and pcm ingest @@ -1350,18 +1309,6 @@ void ivas_spar_dec_upmixer( #ifdef DEBUG_SBA_AUDIO_DUMP /* Dump audio signal after ivas_pca_dec */ ivas_spar_dump_signal_wav( output_frame, NULL, output, num_in_ingest, spar_foa_dec_wav[2], "ivas_pca_dec()" ); -#endif -#ifdef DEBUG_MODE_JBM - dbgwritewav( output_frame, NULL, output, num_in_ingest, st_ivas->hDecoderConfig->output_Fs, "res/spar_pca_dec.wav" ); - { - int k; - for ( k = 0; k < num_in_ingest; k++ ) - { - char filename[100]; - sprintf( filename, "res/spar_pca_dec_%d.dat", k ); - dbgwrite( output[k], sizeof( float ), output_frame, 1, filename ); - } - } #endif } #endif @@ -1378,18 +1325,6 @@ void ivas_spar_dec_upmixer( { mvr2r( pPcm_tmp[hSpar->hTdDecorr->num_apd_outputs - 1 - i], output[nchan_internal - 1 - i], output_frame ); } -#ifdef DEBUG_MODE_JBM - dbgwritewav( output_frame, NULL, output, nchan_internal, st_ivas->hDecoderConfig->output_Fs, "res/spar_dec_td_decorr.wav" ); - { - int k; - for ( k = 0; k < nchan_internal; k++ ) - { - char filename[100]; - sprintf( filename, "res/spar_dec__tdcorr_%d.dat", k ); - dbgwrite( output[k], sizeof( float ), output_frame, 1, filename ); - } - } -#endif } #endif hSpar->hFbMixer->fb_cfg->num_in_chans = num_in_ingest; @@ -1452,27 +1387,6 @@ void ivas_spar_dec_upmixer( ivas_spar_dump_signal_wav( output_frame, NULL, output, numch_in, spar_foa_dec_wav[4], "ivas_spar_upmixer()" ); #endif #endif -#ifdef DEBUG_MODE_JBM - { - - int k; -#ifdef JBM_TSM_ON_TCS - dbgwritewav( output_frame, p_tc, output, numch_in, st_ivas->hDecoderConfig->output_Fs, "res/spar_cldfb_input.wav" ); -#else - dbgwritewav( output_frame, NULL, output, numch_in, st_ivas->hDecoderConfig->output_Fs, "res/spar_cldfb_input.wav" ); -#endif - for ( k = 0; k < numch_in; k++ ) - { - char filename[100]; - sprintf( filename, "res/spar_upmixer_in_%d.dat", k ); -#ifdef JBM_TSM_ON_TCS - dbgwrite( p_tc[k], sizeof( float ), output_frame, 1, filename ); -#else - dbgwrite( output[k], sizeof( float ), output_frame, 1, filename ); -#endif - } - } -#endif #ifndef JBM_TSM_ON_TCS for ( int16_t i_sf = 0; i_sf < MAX_PARAM_SPATIAL_SUBFRAMES; i_sf++ ) diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index b3767b3556..4b59d4d3c5 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -594,10 +594,6 @@ ivas_error IVAS_DEC_EnableVoIP( } #ifdef VARIABLE_SPEED_DECODING } - if ( ( error = JB4_Init( hIvasDec->hVoIP->hJBM, jbmSafetyMargin ) ) != IVAS_ERR_OK ) - { - return error; - } #endif #ifndef JBM_TSM_ON_TCS if ( hDecoderConfig->output_Fs == 8000 ) @@ -639,6 +635,8 @@ ivas_error IVAS_DEC_EnableVoIP( { return IVAS_ERR_INIT_ERROR; } + /* we instantly need a new frame */ + hIvasDec->hVoIP->needNewFrame = true; } #else diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 17969865e9..78f49da735 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -504,9 +504,7 @@ void ivas_dirac_dec_binaural( } #endif -#ifdef DEBUG_MODE_JBM - dbgwritewav( st_ivas->hDirAC->slot_size * 16, NULL, output_f, nchan_transport, st_ivas->hDecoderConfig->output_Fs, "res/dirac_dec_binaural_tc.wav" ); -#endif + if ( st_ivas->hDiracDecBin->useTdDecorr ) { float *decorr_signal[BINAURAL_CHANNELS]; @@ -529,9 +527,6 @@ void ivas_dirac_dec_binaural( } #else ivas_td_decorr_process( st_ivas->hDiracDecBin->hTdDecorr, output_f, decorr_signal, output_frame ); -#endif -#ifdef DEBUG_MODE_JBM - dbgwritewav( st_ivas->hDirAC->slot_size * 16, decorr_signal, output_f, BINAURAL_CHANNELS, st_ivas->hDecoderConfig->output_Fs, "res/dirac_dec_binaural_tddecorr.wav" ); #endif } #ifdef JBM_TSM_ON_TCS @@ -540,9 +535,6 @@ void ivas_dirac_dec_binaural( 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 ); -#ifdef DEBUG_MODE_JBM - dbgwritewav( st->hFdCngDec->hFdCngCom->frameSize, &( st_ivas->hTcBuffer->tc[nchan_transport] ), output_f, 1, st->hFdCngDec->hFdCngCom->frameSize * FRAMES_PER_SEC, "res/dirac_dec_binaural_cng.wav" ); -#endif } #endif @@ -551,15 +543,7 @@ void ivas_dirac_dec_binaural( uint8_t subframe; for ( subframe = 0; subframe < MAX_PARAM_SPATIAL_SUBFRAMES; subframe++ ) { -#ifdef DEBUG_JBM - ivas_dirac_dec_binaural_internal_sf( st_ivas, p_output, nchan_transport ); - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - p_output[ch] += n_samples_sf; - } -#else ivas_dirac_dec_binaural_internal( st_ivas, output_f, nchan_transport, subframe, 1u ); -#endif } } else @@ -870,18 +854,7 @@ static void ivas_dirac_dec_binaural_internal( slot, st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->hSCE[0]->hCoreCoder[0]->flag_cna, ( st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == FRAME_NO_DATA || st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == SID_2k40 ) && ( st_ivas->hSCE[0]->hCoreCoder[0]->cng_type == FD_CNG ) && st_ivas->hSCE[0]->hCoreCoder[0]->cng_sba_flag ); -#ifdef DEBUG_MODE_JBM - if ( slot == 0 ) - { -#ifdef JBM_TSM_ON_TCS - dbgwritewav( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->frameSize, &( st_ivas->tc[nchan_transport] ), output_f, 1, st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->frameSize * FRAMES_PER_SEC, "res/dirac_dec_binaural_cng.wav" ); -#else - float *tc[1]; - tc[0] = &( output_f[1][L_FRAME48k - L_FRAME16k] ); - dbgwritewav( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->frameSize, tc, output_f, 1, st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->frameSize * FRAMES_PER_SEC, "res/dirac_dec_binaural_cng.wav" ); -#endif - } -#endif + /* LB: Copy first channel + LB-CNG to first and second channels with same scaling (dual-mono)*/ for ( b = 0; b < numCoreBands; b++ ) { diff --git a/scripts/switchPaths/sw_13k2_256k.bin b/scripts/switchPaths/sw_13k2_256k.bin new file mode 100644 index 0000000000..1d0c3fac28 --- /dev/null +++ b/scripts/switchPaths/sw_13k2_256k.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05fd8870e43b0eb349d5e9b3bb939574b71d3e7630940a10d6767cae2c6c4a3c +size 60000 diff --git a/scripts/switchPaths/sw_16k4_256k.bin b/scripts/switchPaths/sw_16k4_256k.bin new file mode 100644 index 0000000000..47bc9c9aa3 --- /dev/null +++ b/scripts/switchPaths/sw_16k4_256k.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7dedd5a20cbc5594ec869b13b3e9774efd6394ad5d5b64a4e98210447c3a75ba +size 60000 diff --git a/scripts/switchPaths/sw_24k4_256k_1.bin b/scripts/switchPaths/sw_24k4_256k_1.bin new file mode 100644 index 0000000000..e285261926 --- /dev/null +++ b/scripts/switchPaths/sw_24k4_256k_1.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bf5b303299209bdd4f7e007d1190c7957b17ab3ee399570f1bb87d27f3fec092 +size 60000 diff --git a/scripts/switchPaths/sw_32k_256k.bin b/scripts/switchPaths/sw_32k_256k.bin new file mode 100644 index 0000000000..46b1e17cd4 --- /dev/null +++ b/scripts/switchPaths/sw_32k_256k.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:61dacf79a7582edb83c151c300392efb719f08762a963da29f9b7665305a8c5f +size 60000 -- GitLab From 66fbb204deda4c371c3c21b1a718c23397129067 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Wed, 26 Apr 2023 17:17:34 +0200 Subject: [PATCH 04/39] fixed several bugs, mainly for SBA JBM, ISM JBM --- Workspace_msvc/lib_dec.vcxproj.filters | 3 ++ lib_dec/ivas_dec.c | 2 +- lib_dec/ivas_ism_dec.c | 4 +-- lib_dec/ivas_ism_param_dec.c | 39 +++++++++++++++----------- lib_dec/ivas_jbm_dec.c | 2 -- lib_dec/ivas_masa_dec.c | 9 ++++-- lib_dec/ivas_sba_dec.c | 24 +++++++++++----- lib_dec/ivas_spar_decoder.c | 15 ++++++++-- 8 files changed, 66 insertions(+), 32 deletions(-) diff --git a/Workspace_msvc/lib_dec.vcxproj.filters b/Workspace_msvc/lib_dec.vcxproj.filters index d1dedc413c..b5b7bd9e5b 100644 --- a/Workspace_msvc/lib_dec.vcxproj.filters +++ b/Workspace_msvc/lib_dec.vcxproj.filters @@ -518,6 +518,9 @@ dec_ivas_c + + dec_ivas_c + diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index c126d1243d..b44ddf262b 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -411,7 +411,7 @@ ivas_error ivas_dec( ivas_sba_mix_matrix_determiner( st_ivas->hSpar, output, st_ivas->bfi, nchan_remapped, output_frame ); } #ifdef JBM_TSM_ON_TCS - else if ( st_ivas->sba_mode == SBA_MODE_SPAR ) + else if ( st_ivas->sba_mode == SBA_MODE_SPAR && st_ivas->renderer_type != RENDERER_DISABLE ) { ivas_spar_dec_agc_pca( st_ivas, output, output_frame ); } diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index 15bdc3de97..cc8eb94cea 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -133,7 +133,7 @@ static ivas_error ivas_ism_bitrate_switching( if ( st_ivas->hDecoderConfig->voip_active ) { /* transfer subframe info from DirAC or ParamMC to central tc buffer */ - if ( last_ism_mode == ISM_MODE_PARAM && st_ivas->hDirAC != NULL ) + if ( last_ism_mode == ISM_MODE_PARAM && st_ivas->hDirAC != NULL && (st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE) ) { st_ivas->hTcBuffer->nb_subframes = st_ivas->hDirAC->nb_subframes; st_ivas->hTcBuffer->subframes_rendered = st_ivas->hDirAC->subframes_rendered; @@ -311,7 +311,7 @@ static ivas_error ivas_ism_bitrate_switching( tc_nchan_allocate_new = 2 * BINAURAL_CHANNELS; tc_nchan_full_new = tc_nchan_allocate_new; } - if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + if ( st_ivas->ism_mode == ISM_MODE_PARAM && (st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE) ) { tc_nchan_full_new = 0; } diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 16988f05aa..e13b7e70d2 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -795,28 +795,35 @@ ivas_error ivas_param_ism_dec_open( st_ivas->hISMDTX.dtx_flag = 0; st_ivas->hDirAC = hDirAC; - + hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = NULL; + hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc = NULL; #ifdef JBM_TSM_ON_TCS - if ( st_ivas->hDecoderConfig->voip_active && st_ivas->renderer_type != RENDERER_MONO_DOWNMIX ) - { - int16_t nchan_transport = st_ivas->nchan_transport; - hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands * sizeof( float ) ); - set_zero( hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc, MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands ); - hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands * sizeof( float ) ); - set_zero( hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc, MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands ); - if ( st_ivas->hTcBuffer == NULL ) + if ( st_ivas->hDecoderConfig->voip_active && st_ivas->hTcBuffer == NULL ) + { + if ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE ) { - if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_transport, nchan_transport, 0, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) + int16_t nchan_transport = st_ivas->nchan_transport; + hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands * sizeof( float ) ); + set_zero( hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc, MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands ); + hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands * sizeof( float ) ); + set_zero( hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc, MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands ); + if ( st_ivas->hTcBuffer == NULL ) + { + if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_transport, nchan_transport, 0, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + else + { + int16_t nchan_to_allocate = st_ivas->hDecoderConfig->nchan_out; + if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_BUFFER, nchan_to_allocate, nchan_to_allocate, nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) { return error; } } } - else - { - hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = NULL; - hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc = NULL; - } #endif pop_wmops(); @@ -1167,7 +1174,7 @@ void ivas_param_ism_dec( /* Compute mixing matrix */ #ifdef JBM_TSM_ON_TCS - ivas_param_ism_compute_mixing_matrix( st_ivas->nchan_ism,hDirAC, st_ivas->hISMDTX, direct_response, nchan_transport, nchan_out_woLFE, cx_diag, ref_power, mixing_matrix ); + ivas_param_ism_compute_mixing_matrix( st_ivas->nchan_ism, hDirAC, st_ivas->hISMDTX, direct_response, nchan_transport, nchan_out_woLFE, cx_diag, ref_power, mixing_matrix ); #else ivas_param_ism_compute_mixing_matrix( st_ivas->nchan_ism, hDirAC, st_ivas->hISMDTX, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, direct_response, nchan_transport, nchan_out_woLFE, 0, CLDFB_NO_COL_MAX, mixing_matrix ); #endif diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index b579c10c96..3f4cb18b1a 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -478,9 +478,7 @@ ivas_error ivas_jbm_dec_tc( 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; -#ifdef SBA_BR_SWITCHING st_ivas->last_active_ivas_total_brate = ( ivas_total_brate <= IVAS_SID_5k2 ) ? st_ivas->last_active_ivas_total_brate : ivas_total_brate; -#endif } 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 */ diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index 549cf48932..af4997f25c 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -377,9 +377,14 @@ ivas_error ivas_masa_dec_open( { int16_t nchan_to_allocate; error; - + TC_BUFFER_MODE buffer_mode; + buffer_mode = TC_BUFFER_MODE_RENDERER; + if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_MONO ) + { + buffer_mode = TC_BUFFER_MODE_BUFFER; + } nchan_to_allocate = ivas_jbm_dec_get_num_tc_channels( st_ivas ); - if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_to_allocate, nchan_to_allocate, nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, buffer_mode, nchan_to_allocate, nchan_to_allocate, nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 098a90aed7..80ab861055 100755 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -383,18 +383,28 @@ ivas_error ivas_sba_dec_reconfigure( TC_BUFFER_MODE tc_buffer_mode; int16_t sba_order_internal; - sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); - tc_buffer_mode = TC_BUFFER_MODE_RENDERER; tc_nchan_tc = ivas_jbm_dec_get_num_tc_channels( st_ivas ); - - tc_nchan_to_allocate = ivas_sba_get_nchan_metadata( sba_order_internal ); - tc_nchan_tc = st_ivas->nchan_transport; tc_nchan_to_allocate = tc_nchan_tc; - if ( st_ivas->nchan_transport == 1 && ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) || ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) ) + if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_MONO ) { - tc_nchan_to_allocate++; /* we need a channel for the CNG in this case*/ + tc_buffer_mode = TC_BUFFER_MODE_BUFFER; + tc_nchan_tc = st_ivas->hDecoderConfig->nchan_out; + tc_nchan_to_allocate = tc_nchan_tc; } + else if ( st_ivas->sba_mode == SBA_MODE_SPAR ) + { + sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); + tc_nchan_to_allocate = ivas_sba_get_nchan_metadata( sba_order_internal ); + } + else + { + if ( st_ivas->nchan_transport == 1 && ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) || ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) ) + { + tc_nchan_to_allocate++; /* we need a channel for the CNG in this case*/ + } + } + if ( tc_nchan_tc != st_ivas->hTcBuffer->nchan_transport_jbm || tc_nchan_to_allocate != st_ivas->hTcBuffer->nchan_transport_internal || tc_buffer_mode != st_ivas->hTcBuffer->tc_buffer_mode ) { if ( ( error = ivas_jbm_dec_tc_buffer_reconfigure( st_ivas, tc_buffer_mode, tc_nchan_tc, tc_nchan_to_allocate, tc_nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index 52cfc7910b..6ac368ee0f 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -193,8 +193,19 @@ ivas_error ivas_spar_dec_open( if ( st_ivas->hDecoderConfig->voip_active == 1 && st_ivas->hTcBuffer == NULL && 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_to_allocate = num_channels_internal; /*st_ivas->nchan_transport;*/ - if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, ivas_jbm_dec_get_num_tc_channels( st_ivas ), nchan_to_allocate,nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) + int16_t nchan_tc; + TC_BUFFER_MODE buffer_mode; + + buffer_mode = TC_BUFFER_MODE_RENDERER; + nchan_tc = ivas_jbm_dec_get_num_tc_channels( st_ivas ); + nchan_to_allocate = num_channels_internal; + if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_MONO ) + { + buffer_mode = TC_BUFFER_MODE_BUFFER; + nchan_tc = st_ivas->hDecoderConfig->nchan_out; + nchan_to_allocate = nchan_tc; + } + if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, buffer_mode, nchan_tc, nchan_to_allocate, nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) { return error; } -- GitLab From 7297642cbf9fb5b70b65ad35107dbf04ff383602 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Thu, 27 Apr 2023 10:50:59 +0200 Subject: [PATCH 05/39] fixed asan,msan problems, clang format, fixed Linux compiler warnings --- apps/decoder.c | 2 +- lib_com/fd_cng_com.c | 2 +- lib_com/ivas_stat_com.h | 2 +- lib_com/ivas_tools.c | 4 +-- lib_com/options.h | 4 +-- lib_debug/sba_debug.c | 4 +-- lib_dec/fd_cng_dec.c | 1 - lib_dec/ivas_dirac_dec.c | 4 +++ lib_dec/ivas_dirac_output_synthesis_dec.c | 2 +- lib_dec/ivas_ism_dec.c | 10 +++++-- lib_dec/ivas_ism_param_dec.c | 10 +++---- lib_dec/ivas_jbm_dec.c | 27 ++++++------------- lib_dec/ivas_masa_dec.c | 1 - lib_dec/ivas_mc_param_dec.c | 11 -------- lib_dec/ivas_mct_dec.c | 7 +++++ lib_dec/ivas_objectRenderer_internal.c | 8 +++--- lib_dec/ivas_out_setup_conversion.c | 4 +-- lib_dec/ivas_sba_dec.c | 2 +- lib_dec/ivas_spar_decoder.c | 14 ++++++---- lib_dec/ivas_stat_dec.h | 2 +- lib_dec/jbm_jb4sb.h | 2 +- lib_dec/jbm_pcmdsp_similarityestimation.h | 28 +++++++++----------- lib_dec/lib_dec.c | 10 +++---- lib_rend/ivas_crend.c | 1 - lib_rend/ivas_dirac_dec_binaural_functions.c | 4 +-- lib_rend/ivas_limiter.c | 10 +++---- lib_rend/ivas_reverb.c | 6 ++--- lib_rend/ivas_rotation.c | 20 +++++++------- lib_util/tinywaveout_c.h | 2 +- lib_util/tsm_scale_file_reader.c | 4 +-- 30 files changed, 95 insertions(+), 113 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 05b8862735..f2134a29f4 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -2890,7 +2890,7 @@ cleanup: AudioFileWriter_close( &afWriter ); MasaFileWriter_close( &masaWriter ); - TsmScaleFileReader_close( &tsmScaleFileReader ); + TsmScaleFileReader_close( &tsmScaleFileReader ); for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; i++ ) { IsmFileWriter_close( &ismWriters[i] ); diff --git a/lib_com/fd_cng_com.c b/lib_com/fd_cng_com.c index 6cb2e014ba..99ae9894f4 100644 --- a/lib_com/fd_cng_com.c +++ b/lib_com/fd_cng_com.c @@ -998,7 +998,7 @@ void SynthesisSTFT_dirac( /* update and window olapBuf if we have a output frame that is shorter than the default frame size...*/ if ( samples_out < hFdCngCom->frameSize ) { - mvr2r( olapBuffer + samples_out, olapBuffer + hFdCngCom->frameSize, 3 * hFdCngCom->frameSize / 4 ); + mvr2r( olapBuffer + samples_out, olapBuffer + hFdCngCom->frameSize, 3 * hFdCngCom->frameSize / 4 ); } for ( i = 5 * hFdCngCom->frameSize / 4; i < 7 * hFdCngCom->frameSize / 4; i++ ) { diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index 80f564e54a..3c9b59df42 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -689,7 +689,7 @@ typedef struct ivas_td_decorr_state_t int16_t num_apd_outputs; int16_t num_apd_sections; int16_t ducking_flag; - + #ifdef JBM_TSM_ON_TCS int16_t offset; #endif diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index e348d8a241..ce4abafeb5 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -173,10 +173,10 @@ uint32_t ivas_syn_output( /*! r: number of clipped samples */ void ivas_syn_output_f( - float *synth[], /* i/o: float synthesis signal */ + float *synth[], /* i/o: float synthesis signal */ const int16_t output_frame, /* i : output frame length (one channel) */ const int16_t n_channels, /* i : number of output channels */ - float *synth_out /* o : integer 16 bits synthesis signal */ + float *synth_out /* o : integer 16 bits synthesis signal */ ) { int16_t i, n; diff --git a/lib_com/options.h b/lib_com/options.h index 935cc1f33e..df74f066f3 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -112,7 +112,7 @@ /*#define TDREND_HRTF_TABLE_METHODS*/ /* Enable HRTF lookup from tables, for testing & evaluation. Supply file in table format to use. Note that a suitable HR filter lookup method should be written if the filters sample point grids are not in the formats. */ /*#define TDREND_STANDALONE*/ /* Used when renderer is built in standalone form, without IVAS encoding/decoding (see scripts/object_renderer_standalone). This is just here to ensure this is cleaned out by prepare_instrumentation.sh */ -#define DEBUG_SBA /* debug DIRAC/SPAR in-out */ +/*#define DEBUG_SBA */ /* debug DIRAC/SPAR in-out */ #ifdef DEBUG_SBA /*#define DEBUG_SBA_AUDIO_DUMP */ /* SBA intermediate audio wav file dumping */ /*#define DEBUG_SBA_MD_DUMP*/ /* SBA metadata and variable file dumping */ @@ -148,7 +148,7 @@ #define FIX_419_ISM_MD_FIX /* VA: Issue 419: fix the upper value limitation for parameter angle1_diff_cnt */ #define SNS_MSVQ /* FhG: contribution 33 - MSVQ for SNS parameters at stereo mid bitrates */ -#define FIX_XXX_JBM_FIFO_BUFFER /* FhG: prevent wraparound of a length identifier in cause of large frames and many channels*/ +/*#define FIX_XXX_JBM_FIFO_BUFFER */ /* FhG: prevent wraparound of a length identifier in cause of large frames and many channels*/ #define FIX_379_GAININTP /* Eri: Adds a gain interpolation for directional/distance gain to handle abrupt changes in metadata (Non BE) */ diff --git a/lib_debug/sba_debug.c b/lib_debug/sba_debug.c index 3f9138e47f..73bb630b5f 100644 --- a/lib_debug/sba_debug.c +++ b/lib_debug/sba_debug.c @@ -214,11 +214,11 @@ void ivas_spar_dump_signal_wav( #else if ( ppPcm ) { - tmp_value = roundf(ppPcm[i][j]); + tmp_value = roundf( ppPcm[i][j] ); } else { - tmp_value = roundf(pcm_array[i][j]); + tmp_value = roundf( pcm_array[i][j] ); } #endif if ( tmp_value > MAX16B_FLT ) diff --git a/lib_dec/fd_cng_dec.c b/lib_dec/fd_cng_dec.c index 715fc46452..c8997fa4ee 100644 --- a/lib_dec/fd_cng_dec.c +++ b/lib_dec/fd_cng_dec.c @@ -1950,7 +1950,6 @@ void generate_masking_noise_lb_dirac( } n_samples_out -= hFdCngCom->frameSize; n_samples_start += hFdCngCom->frameSize; - } } diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 1a831d3103..b85120afa1 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2559,6 +2559,10 @@ void ivas_dirac_dec_render_sf( #endif } } + else + { + set_zero( surCohRatio, hDirAC->num_freq_bands ); + } } if ( st_ivas->hDecoderConfig->Opt_Headrotation && st_ivas->hHeadTrackData->shd_rot_max_order == 1 ) { diff --git a/lib_dec/ivas_dirac_output_synthesis_dec.c b/lib_dec/ivas_dirac_output_synthesis_dec.c index 670bd0072b..03c512dfd8 100644 --- a/lib_dec/ivas_dirac_output_synthesis_dec.c +++ b/lib_dec/ivas_dirac_output_synthesis_dec.c @@ -847,7 +847,7 @@ void ivas_dirac_dec_output_synthesis_process_slot( /* process other PSDs only slot wise for 4 transport channels */ #if !defined( JBM_TSM_ON_TCS ) || defined( JBM_DIRAC_DEBUG_BE ) #if defined( JBM_DIRAC_DEBUG_BE ) - if ( hDirAC->hConfig->dec_param_estim == TRUE || hDirAC->voip_active == 1) + if ( hDirAC->hConfig->dec_param_estim == TRUE || hDirAC->voip_active == 1 ) #else if ( hDirAC->hConfig->dec_param_estim == TRUE ) #endif diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index 357d8b51ba..04c9504cc1 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -135,7 +135,7 @@ static ivas_error ivas_ism_bitrate_switching( if ( st_ivas->hDecoderConfig->voip_active ) { /* transfer subframe info from DirAC or ParamMC to central tc buffer */ - if ( last_ism_mode == ISM_MODE_PARAM && st_ivas->hDirAC != NULL && (st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE) ) + if ( last_ism_mode == ISM_MODE_PARAM && st_ivas->hDirAC != NULL && ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE ) ) { st_ivas->hTcBuffer->nb_subframes = st_ivas->hDirAC->nb_subframes; st_ivas->hTcBuffer->subframes_rendered = st_ivas->hDirAC->subframes_rendered; @@ -196,6 +196,9 @@ static ivas_error ivas_ism_bitrate_switching( /* close the ISM renderer and reinitialize */ if ( st_ivas->hIsmRendererData != NULL ) { +#ifdef JBM_TSM_ON_TCS + free( st_ivas->hIsmRendererData->interpolator ); +#endif free( st_ivas->hIsmRendererData ); st_ivas->hIsmRendererData = NULL; } @@ -264,6 +267,9 @@ static ivas_error ivas_ism_bitrate_switching( /* Close the ISM renderer */ if ( st_ivas->hIsmRendererData != NULL ) { +#ifdef JBM_TSM_ON_TCS + free( st_ivas->hIsmRendererData->interpolator ); +#endif free( st_ivas->hIsmRendererData ); st_ivas->hIsmRendererData = NULL; } @@ -317,7 +323,7 @@ static ivas_error ivas_ism_bitrate_switching( tc_nchan_allocate_new = 2 * BINAURAL_CHANNELS; tc_nchan_full_new = tc_nchan_allocate_new; } - if ( st_ivas->ism_mode == ISM_MODE_PARAM && (st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE) ) + if ( st_ivas->ism_mode == ISM_MODE_PARAM && ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE ) ) { tc_nchan_full_new = 0; } diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index e13b7e70d2..d82ee7b8dd 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -195,8 +195,8 @@ static void ivas_param_ism_compute_mixing_matrix( float direct_response[MAX_NUM_OBJECTS][PARAM_ISM_MAX_CHAN], const int16_t nchan_transport, const int16_t nchan_out_woLFE, - const float cx_diag[][PARAM_ISM_MAX_DMX], - const float ref_power[], + float cx_diag[][PARAM_ISM_MAX_DMX], + float ref_power[], float mixing_matrix[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX] ) { int16_t band_idx, bin_idx; @@ -815,7 +815,7 @@ ivas_error ivas_param_ism_dec_open( } } } - else + else { int16_t nchan_to_allocate = st_ivas->hDecoderConfig->nchan_out; if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_BUFFER, nchan_to_allocate, nchan_to_allocate, nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) @@ -1378,8 +1378,6 @@ void ivas_param_ism_dec_digest_tc( DIRAC_DEC_HANDLE hDirAC; - IVAS_OUTPUT_SETUP hSetup; - /* Initialization */ hDirAC = st_ivas->hDirAC; assert( hDirAC ); @@ -1399,8 +1397,6 @@ void ivas_param_ism_dec_digest_tc( nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; } - hSetup = st_ivas->hIntSetup; - push_wmops( "ivas_param_ism_dec" ); /* general setup */ diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 3f4cb18b1a..f4b0e3630f 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -520,28 +520,20 @@ ivas_error ivas_jbm_dec_feed_tc_to_renderer( float data_f[MAX_CLDFB_DIGEST_CHANNELS][MAX_JBM_L_FRAME48k]; /* 'float' buffer for transport channels that will be directly converted with the CLDFB */ float *p_data_f[MAX_CLDFB_DIGEST_CHANNELS]; - int16_t nCldfbTs; + int16_t n_render_timeslots; int16_t n; - int16_t nchan_transport; - int32_t ivas_total_brate; - int32_t output_Fs; ivas_error error; - AUDIO_CONFIG output_config; error = IVAS_ERR_OK; push_wmops( "ivas_jbm_dec_feed_tc_to_rendererer" ); - output_Fs = st_ivas->hDecoderConfig->output_Fs; - output_config = st_ivas->hDecoderConfig->output_config; - nchan_transport = st_ivas->hTcBuffer->nchan_transport_jbm; - ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; for ( n = 0; n < MAX_CLDFB_DIGEST_CHANNELS; n++ ) { p_data_f[n] = &data_f[n][0]; } ivas_jbm_dec_copy_tc( st_ivas, nSamplesForRendering, nSamplesResidual, data, p_data_f ); - nCldfbTs = st_ivas->hTcBuffer->n_samples_available / st_ivas->hTcBuffer->n_samples_granularity; + n_render_timeslots = st_ivas->hTcBuffer->n_samples_available / st_ivas->hTcBuffer->n_samples_granularity; if ( st_ivas->hTcBuffer->tc_buffer_mode == TC_BUFFER_MODE_BUFFER ) { @@ -558,12 +550,12 @@ ivas_error ivas_jbm_dec_feed_tc_to_renderer( { 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_set_md_map( st_ivas, nCldfbTs ); + ivas_dirac_dec_set_md_map( st_ivas, n_render_timeslots ); ivas_param_ism_params_to_masa_param_mapping( st_ivas ); } else if ( st_ivas->renderer_type == RENDERER_PARAM_ISM || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) { - ivas_param_ism_dec_digest_tc( st_ivas, nCldfbTs, p_data_f ); + ivas_param_ism_dec_digest_tc( st_ivas, n_render_timeslots, p_data_f ); } } else /* ISM_MODE_DISC */ @@ -573,7 +565,7 @@ ivas_error ivas_jbm_dec_feed_tc_to_renderer( } else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) { - ivas_sba_dec_digest_tc( st_ivas, nCldfbTs, st_ivas->hTcBuffer->n_samples_available ); + ivas_sba_dec_digest_tc( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); } else if ( st_ivas->ivas_format == MC_FORMAT ) { @@ -583,11 +575,11 @@ ivas_error ivas_jbm_dec_feed_tc_to_renderer( } else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) { - ivas_param_mc_dec_digest_tc( st_ivas, (uint8_t) nCldfbTs, p_data_f ); + ivas_param_mc_dec_digest_tc( st_ivas, (uint8_t) n_render_timeslots, p_data_f ); } else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) { - ivas_sba_dec_digest_tc( st_ivas, nCldfbTs, st_ivas->hTcBuffer->n_samples_available ); + ivas_sba_dec_digest_tc( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); } } @@ -615,9 +607,8 @@ ivas_error ivas_jbm_dec_render( int16_t nchan_transport; float output[MAX_OUTPUT_CHANNELS][L_FRAME48k]; /* 'float' buffer for output synthesis, MAX_OUTPUT_CHANNELS channels */ /* IVAS_fmToDo: buffer can be allocated dynamically based on the actual number of output channels */ int16_t nchan_remapped; - int32_t output_Fs, ivas_total_brate; + int32_t output_Fs; AUDIO_CONFIG output_config; - int16_t nCldfbTs; int16_t nSamplesAskedLocal; ivas_error error; float *p_output[MAX_OUTPUT_CHANNELS]; @@ -635,9 +626,7 @@ ivas_error ivas_jbm_dec_render( nchan_out = st_ivas->hDecoderConfig->nchan_out; nchan_transport = st_ivas->hTcBuffer->nchan_transport_jbm; output_config = st_ivas->hDecoderConfig->output_config; - ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; nSamplesAskedLocal = nSamplesAsked + st_ivas->hTcBuffer->n_samples_discard; - nCldfbTs = nSamplesAskedLocal / NS2SA( output_Fs, CLDFB_SLOT_NS ); for ( n = 0; n < MAX_OUTPUT_CHANNELS; n++ ) { p_output[n] = &output[n][0]; diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index af4997f25c..dbb7e11572 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -376,7 +376,6 @@ ivas_error ivas_masa_dec_open( if ( st_ivas->hDecoderConfig->voip_active == 1 && 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; - error; TC_BUFFER_MODE buffer_mode; buffer_mode = TC_BUFFER_MODE_RENDERER; if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_MONO ) diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index a7e2611225..7767cae99e 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -1414,7 +1414,6 @@ void ivas_param_mc_dec_digest_tc( float real_part, imag_part; /* format converter */ int16_t channel_active[MAX_OUTPUT_CHANNELS]; - uint16_t nchan_out_init; IVAS_OUTPUT_SETUP *hSynthesisOutputSetup; hParamMC = st_ivas->hParamMC; @@ -1425,16 +1424,11 @@ void ivas_param_mc_dec_digest_tc( set_s( channel_active, 0, MAX_CICP_CHANNELS ); nchan_transport = st_ivas->nchan_transport; nchan_out_transport = st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe; - nchan_out_init = nchan_out_transport; if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { nchan_out_cldfb = BINAURAL_CHANNELS; set_s( channel_active, 1, nchan_out_cldfb ); - if ( st_ivas->hHeadTrackData ) - { - nchan_out_init = MAX_INTERN_CHANNELS; - } nchan_out_cov = st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe; hSynthesisOutputSetup = &st_ivas->hTransSetup; } @@ -1578,7 +1572,6 @@ void ivas_param_mc_dec_render( uint16_t nband_synth, nbands_to_zero; uint16_t nchan_out_init; uint32_t output_Fs; - IVAS_OUTPUT_SETUP *hSynthesisOutputSetup; hParamMC = st_ivas->hParamMC; assert( hParamMC ); @@ -1600,27 +1593,23 @@ void ivas_param_mc_dec_render( nchan_out_init = MAX_INTERN_CHANNELS; } nchan_out_cov = st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe; - hSynthesisOutputSetup = &st_ivas->hTransSetup; } else if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_CLDFB ) { nchan_out_cov = nchan_out_transport; nchan_out_cldfb = st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; - hSynthesisOutputSetup = &st_ivas->hTransSetup; } else if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_COV || hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO ) { nchan_out_cov = st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; nchan_out_cldfb = nchan_out_cov; set_s( channel_active, 1, nchan_out_cov ); - hSynthesisOutputSetup = &st_ivas->hOutSetup; } else { nchan_out_cov = nchan_out_transport; nchan_out_cldfb = nchan_out_transport; set_s( channel_active, 1, nchan_out_cov ); - hSynthesisOutputSetup = &st_ivas->hTransSetup; } /* set everything to zero that will not be decoded */ diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 55a68c4475..f979942a9a 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -807,6 +807,7 @@ static ivas_error ivas_mc_dec_reconfig( if ( st_ivas->hDirAC != NULL ) { ivas_dirac_dec_close( &st_ivas->hDirAC ); + vbap_free_data( &( st_ivas->hVBAPdata ) ); } #endif @@ -851,6 +852,8 @@ static ivas_error ivas_mc_dec_reconfig( if ( st_ivas->hDirAC != NULL ) { ivas_dirac_dec_close( &st_ivas->hDirAC ); + + vbap_free_data( &( st_ivas->hVBAPdata ) ); } #endif @@ -1085,6 +1088,10 @@ static ivas_error ivas_mc_dec_reconfig( else if ( st_ivas->renderer_type == RENDERER_DISABLE && st_ivas->hDirAC != NULL ) { ivas_dirac_dec_close( &( st_ivas->hDirAC ) ); + +#ifdef JBM_TSM_ON_TCS + vbap_free_data( &( st_ivas->hVBAPdata ) ); +#endif } } diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index a7c804007d..873c75938a 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -66,13 +66,13 @@ ivas_error ivas_td_binaural_open( *---------------------------------------------------------------------*/ ivas_error ivas_td_binaural_renderer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ #ifdef JBM_TSM_ON_TCS - float *output[], /* i/o: SCE channels / Binaural synthesis */ + float *output[], /* i/o: SCE channels / Binaural synthesis */ #else float output[][L_FRAME48k], /* i/o: SCE channels / Binaural synthesis */ #endif - const int16_t output_frame /* i : output frame length */ + const int16_t output_frame /* i : output frame length */ ) { return ivas_td_binaural_renderer_unwrap( @@ -167,4 +167,4 @@ void ObjRenderIVASSubframe( st_ivas->hTcBuffer->subframes_rendered = last_sf; return; } -#endif \ No newline at end of file +#endif diff --git a/lib_dec/ivas_out_setup_conversion.c b/lib_dec/ivas_out_setup_conversion.c index 71b85a1dc9..abd34d9b75 100644 --- a/lib_dec/ivas_out_setup_conversion.c +++ b/lib_dec/ivas_out_setup_conversion.c @@ -467,8 +467,8 @@ void ivas_ls_setup_conversion( Decoder_Struct *st_ivas, /* i : IVAS decoder structure */ const int16_t output_frame, /* i : frame length */ #ifdef JBM_TSM_ON_TCS - float *input[], /* i : LS input/output synthesis signal */ - float *output[] /* i/o: LS input/output synthesis signal */ + float *input[], /* i : LS input/output synthesis signal */ + float *output[] /* i/o: LS input/output synthesis signal */ #else float output[][L_FRAME48k] /* i/o: LS input/output synthesis signal */ #endif diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 80ab861055..c945e3f68b 100755 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -489,7 +489,7 @@ void ivas_sba_dec_render( hSpar = st_ivas->hSpar; sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); nchan_internal = ivas_sba_get_nchan_metadata( sba_order_internal ); - nchan_out = nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; + nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; #ifdef DEBUGGING assert( hSpar ); #endif diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index 6ac368ee0f..d3067b0e46 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -1198,15 +1198,18 @@ void ivas_spar_dec_upmixer( float *cldfb_in_ts_im[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX]; int16_t i, b, ts, out_ch, in_ch; int16_t num_spar_bands, spar_band, nchan_transport; - int16_t num_in_ingest, num_bands_out, split_band; + int16_t num_in_ingest, split_band; #ifdef JBM_TSM_ON_TCS - int16_t output_frame, slot_size, slot_idx_start, slot_idx_start_cldfb; + int16_t slot_size, slot_idx_start; float *p_tc[MAX_OUTPUT_CHANNELS]; int16_t md_idx; #endif float Pcm_tmp[MAX_OUTPUT_CHANNELS][L_FRAME48k]; int16_t numch_out_dirac; +#ifndef JBM_TSM_ON_TCS float *pPcm_tmp[MAX_OUTPUT_CHANNELS]; + int16_t num_bands_out; +#endif float mixer_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; int16_t b_skip_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; DECODER_CONFIG_HANDLE hDecoderConfig; @@ -1220,7 +1223,9 @@ void ivas_spar_dec_upmixer( hSpar = st_ivas->hSpar; hDecoderConfig = st_ivas->hDecoderConfig; +#ifndef JBM_TSM_ON_TCS num_bands_out = hSpar->hFbMixer->pFb->filterbank_num_bands; +#endif nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport; num_cldfb_bands = hSpar->hFbMixer->pFb->fb_bin_to_band.num_cldfb_bands; @@ -1229,9 +1234,7 @@ void ivas_spar_dec_upmixer( #ifdef JBM_TSM_ON_TCS slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); - output_frame = hSpar->subframe_nbslots[hSpar->subframes_rendered] * slot_size; slot_idx_start = hSpar->slots_rendered; - slot_idx_start_cldfb = 0; for ( i = 0; i < nchan_internal; i++ ) { p_tc[i] = st_ivas->hTcBuffer->tc[i] + slot_idx_start * slot_size; @@ -1301,11 +1304,12 @@ void ivas_spar_dec_upmixer( num_in_ingest = nchan_transport; } +#ifndef JBM_TSM_ON_TCS for ( i = 0; i < nchan_internal; i++ ) { pPcm_tmp[i] = Pcm_tmp[i]; } - +#endif /*---------------------------------------------------------------------* * PCA decoder *---------------------------------------------------------------------*/ diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 276959a03b..debc90219e 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1216,7 +1216,7 @@ typedef struct decoder_tc_buffer_structure int16_t subframes_rendered; int16_t slots_rendered; int16_t num_slots; - int16_t n_samples_discard; /* number of samples to discard from the beginning of the output */ + int16_t n_samples_discard; /* number of samples to discard from the beginning of the output */ } DECODER_TC_BUFFER, *DECODER_TC_BUFFER_HANDLE; #endif /*----------------------------------------------------------------------------------* diff --git a/lib_dec/jbm_jb4sb.h b/lib_dec/jbm_jb4sb.h index a2d85eddb6..7954358595 100644 --- a/lib_dec/jbm_jb4sb.h +++ b/lib_dec/jbm_jb4sb.h @@ -84,7 +84,7 @@ typedef enum JBM_RENDERER_NONE, JBM_RENDERER_IVAS, } JBM_RENDERER_TYPE; -#endif +#endif typedef struct JB4_DATAUNIT *JB4_DATAUNIT_HANDLE; diff --git a/lib_dec/jbm_pcmdsp_similarityestimation.h b/lib_dec/jbm_pcmdsp_similarityestimation.h index 7078580047..44b4fd246a 100644 --- a/lib_dec/jbm_pcmdsp_similarityestimation.h +++ b/lib_dec/jbm_pcmdsp_similarityestimation.h @@ -67,7 +67,7 @@ * ******************************************************************************** */ -float cross_correlation_self( +float cross_correlation_self( #ifdef JBM_TSM_ON_TCS const float *signal, #else @@ -75,8 +75,7 @@ float cross_correlation_self( #endif uint16_t x, uint16_t y, - uint16_t corr_len -); + uint16_t corr_len ); /* ******************************************************************************** @@ -112,8 +111,7 @@ float cross_correlation_subsampled_self( uint16_t x, uint16_t y, uint16_t corr_len, - uint16_t subsampling -); + uint16_t subsampling ); /* ******************************************************************************** @@ -151,28 +149,26 @@ float cross_correlation_subsampled_self( * ******************************************************************************** */ -float normalized_cross_correlation_self( +float normalized_cross_correlation_self( #ifdef JBM_TSM_ON_TCS const float *signal, #else const int16_t *signal, #endif - uint16_t x, - uint16_t y, - uint16_t corr_len, - uint16_t subsampling, - float *energy -); + uint16_t x, + uint16_t y, + uint16_t corr_len, + uint16_t subsampling, + float *energy ); /* Splits the signal into segments and checks if all of them have very low energy. */ -bool isSilence( +bool isSilence( #ifdef JBM_TSM_ON_TCS const float *signal, #else const int16_t *signal, #endif - uint32_t len, - uint32_t segments -); + uint32_t len, + uint32_t segments ); #endif /* JBM_PCMDSP_SIMILARITYESTIMATION_H */ diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 4b59d4d3c5..33a4ed7526 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -656,7 +656,7 @@ ivas_error IVAS_DEC_EnableVoIP( } #else if ( apa_init( &hIvasDec->hVoIP->hTimeScaler, - hDecoderConfig->nchan_out ) !=IVAS_ERR_OK || + hDecoderConfig->nchan_out ) != IVAS_ERR_OK || apa_set_rate( hIvasDec->hVoIP->hTimeScaler, hDecoderConfig->output_Fs ) != 0 || apa_set_complexity_options( hIvasDec->hVoIP->hTimeScaler, wss, css ) != 0 || apa_set_quality( hIvasDec->hVoIP->hTimeScaler, 1, 4, 4 ) != 0 || @@ -942,7 +942,7 @@ ivas_error IVAS_DEC_RendererFeedTcSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o : IVAS decoder handle */ const int16_t nSamplesForRendering, /* i: : number of TC samples wanted from the renderer */ int16_t *nSamplesResidual, /* o: : number of samples not fitting into the renderer grid and buffer for the next call*/ - float *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 */ + float *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 */ ) { Decoder_Struct *st_ivas; @@ -2147,7 +2147,7 @@ ivas_error IVAS_DEC_VoIP_GetSamples( { if ( pcmdsp_fifo_read( hVoIP->hFifoOut, nSamplesPerChannel, (uint8_t *) pcmBuf ) != 0 ) #else - if ( pcmdsp_fifo_read( hVoIP->hFifoAfterTimeScaler, nSamplesPerChannel, (uint8_t *) pcmBuf ) != 0 ) +if ( pcmdsp_fifo_read( hVoIP->hFifoAfterTimeScaler, nSamplesPerChannel, (uint8_t *) pcmBuf ) != 0 ) #endif { return IVAS_ERR_UNKNOWN; @@ -2183,16 +2183,12 @@ ivas_error IVAS_DEC_VoIP_Flush( ) { ivas_error error; - Decoder_Struct *st_ivas; - DECODER_CONFIG_HANDLE hDecoderConfig; IVAS_DEC_VOIP *hVoIP; int16_t rendererPcmBuf[( MAX_OUTPUT_CHANNELS * L_FRAME_MAX * APA_MAX_SCALE ) / 100]; uint16_t nSamplesToRender; uint16_t nSamplesFlushedLocal; error = IVAS_ERR_OK; - st_ivas = hIvasDec->st_ivas; - hDecoderConfig = st_ivas->hDecoderConfig; hVoIP = hIvasDec->hVoIP; #if defined( JBM_TSM_ON_TCS ) *nSamplesFlushed = min( nSamplesPerChannel, hVoIP->nSamplesAvailableNext ); diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index 8dc6fa6783..a7572aea3f 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1338,4 +1338,3 @@ ivas_error ivas_rend_crendProcessSubframe( return IVAS_ERR_OK; } #endif - diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 78f49da735..78cc924052 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -485,9 +485,7 @@ void ivas_dirac_dec_binaural( #ifdef JBM_TSM_ON_TCS float cng_td_buffer[L_FRAME16k]; float *p_output[MAX_OUTPUT_CHANNELS]; - int16_t ch, n_samples_sf; - - n_samples_sf = JBM_CLDFB_SLOTS_IN_SUBFRAME * st_ivas->hDirAC->slot_size; + int16_t ch; for ( ch = 0; ch < 2 * BINAURAL_CHANNELS; ch++ ) { diff --git a/lib_rend/ivas_limiter.c b/lib_rend/ivas_limiter.c index 17c5a94ff8..7875165e51 100644 --- a/lib_rend/ivas_limiter.c +++ b/lib_rend/ivas_limiter.c @@ -171,15 +171,15 @@ void ivas_limiter_close( *-------------------------------------------------------------------*/ void ivas_limiter_dec( - IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ + IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ #ifdef JBM_TSM_ON_TCS - float *output[MAX_OUTPUT_CHANNELS], /* i/o: input/output buffer */ + float *output[MAX_OUTPUT_CHANNELS], /* i/o: input/output buffer */ #else float output[MAX_OUTPUT_CHANNELS][L_FRAME48k], /* i/o: input/output buffer */ #endif - const int16_t num_channels, /* i : number of channels to be processed */ - const int16_t output_frame, /* i : number of samples per channel in the buffer */ - const int16_t BER_detect /* i : BER detect flag */ + const int16_t num_channels, /* i : number of channels to be processed */ + const int16_t output_frame, /* i : number of samples per channel in the buffer */ + const int16_t BER_detect /* i : BER detect flag */ ) { int16_t c; diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb.c index 7239f4825b..3975a74559 100644 --- a/lib_rend/ivas_reverb.c +++ b/lib_rend/ivas_reverb.c @@ -1587,10 +1587,10 @@ ivas_error ivas_reverb_process( float *pcm_in[], /* i : the PCM audio to apply reverb on */ float *pcm_out[], /* o : the PCM audio with reverb applied */ #else - float pcm_in[][L_FRAME48k], /* i : the PCM audio to apply reverb on */ - float pcm_out[][L_FRAME48k], /* o : the PCM audio with reverb applied */ + float pcm_in[][L_FRAME48k], /* i : the PCM audio to apply reverb on */ + float pcm_out[][L_FRAME48k], /* o : the PCM audio with reverb applied */ #endif - const int16_t i_ts /* i : subframe index */ + const int16_t i_ts /* i : subframe index */ ) { float tmp0[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES], tmp1[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES], tmp2[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 0736bd4003..3191e943aa 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -254,7 +254,7 @@ void rotateFrame_shd( #ifdef JBM_TSM_ON_TCS float *output[], /* i/o: unrotated HOA3 signal buffer in TD */ #else - float output[][L_FRAME48k], /* i/o: unrotated HOA3 signal buffer in TD */ + float output[][L_FRAME48k], /* i/o: unrotated HOA3 signal buffer in TD */ #endif const int16_t subframe_len, /* i : subframe length per channel */ const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ @@ -359,14 +359,14 @@ void rotateFrame_shd( void rotateFrame_sd( HEAD_TRACK_DATA_HANDLE hHeadTrackData, /* i : head track handle */ #ifdef JBM_TSM_ON_TCS - float *output[], /* i/o: unrotated SD signal buffer in TD */ + float *output[], /* i/o: unrotated SD signal buffer in TD */ #else - float output[][L_FRAME48k], /* i/o: unrotated SD signal buffer in TD */ -#endif - const int16_t subframe_len, /* i : subframe length per channel */ - const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ - const EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ - const int16_t subframe_idx /* i : subframe index */ + float output[][L_FRAME48k], /* i/o: unrotated SD signal buffer in TD */ +#endif + const int16_t subframe_len, /* i : subframe length per channel */ + const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ + const EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ + const int16_t subframe_idx /* i : subframe index */ ) { int16_t i, j; @@ -602,9 +602,9 @@ void rotateFrame_sd_cldfb( const IVAS_OUTPUT_SETUP_HANDLE hOutputSetup, /* i : output format setup number of channels */ const EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ #ifdef JBM_TSM_ON_TCS - const int16_t numTimeSlots, /* i : number of time slots to process */ + const int16_t numTimeSlots, /* i : number of time slots to process */ #endif - const int16_t nb_band /* i : number of CLDFB bands to process */ + const int16_t nb_band /* i : number of CLDFB bands to process */ ) { int16_t iBlock, iBand, m, n; diff --git a/lib_util/tinywaveout_c.h b/lib_util/tinywaveout_c.h index aab62a4dd3..b82c0cd131 100644 --- a/lib_util/tinywaveout_c.h +++ b/lib_util/tinywaveout_c.h @@ -517,7 +517,7 @@ static int32_t WriteWavFloat( { if ( self->bps == 32 ) { - err = __WriteSample32( self, sampleBuffer[i]/32768.0f); + err = __WriteSample32( self, sampleBuffer[i] / 32768.0f ); } else { diff --git a/lib_util/tsm_scale_file_reader.c b/lib_util/tsm_scale_file_reader.c index 5c2e51edfa..fbd1824d9d 100644 --- a/lib_util/tsm_scale_file_reader.c +++ b/lib_util/tsm_scale_file_reader.c @@ -86,8 +86,8 @@ TsmScaleFileReader *TsmScaleFileReader_open( *---------------------------------------------------------------------*/ ivas_error TsmScaleFileReader_readScale( - TsmScaleFileReader *self, /* i/o: TsmScaleFileReader handle */ - int16_t *scale /* o : scale */ + TsmScaleFileReader *self, /* i/o: TsmScaleFileReader handle */ + int16_t *scale /* o : scale */ ) { int tmp; -- GitLab From 3d4c2b6f79b4f52ba9f3696e2e0a58c0c3949d46 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Thu, 27 Apr 2023 11:26:14 +0200 Subject: [PATCH 06/39] added missing TC Buffer to dummy decoder struct in the standalone renderer --- lib_rend/lib_rend.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 6ef18946ca..038b083654 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -2458,6 +2458,9 @@ static DecoderDummy *initDecoderDummy( decDummy->hMasa = NULL; decDummy->hDiracDecBin = NULL; decDummy->hQMetaData = NULL; +#ifdef JBM_TSM_ON_TCS + decDummy->hTcBuffer = NULL; +#endif decDummy->hDecoderConfig->output_config = getIvasAudioConfigFromRendAudioConfig( outConfig ); decDummy->nchan_transport = numTransChannels; @@ -2494,6 +2497,11 @@ static DecoderDummy *initDecoderDummy( decDummy->hRenderConfig = NULL; } +#ifdef JBM_TSM_ON_TCS + /* get a default TC buffer, needed for some renderers */ + ivas_jbm_dec_tc_buffer_open( decDummy, TC_BUFFER_MODE_NONE, 0, 0, 0, 1 ); +#endif + decDummy->renderer_type = RENDERER_DISABLE; return decDummy; @@ -2601,6 +2609,11 @@ static void freeDecoderDummy( /* Parametric binaural renderer handle */ ivas_dirac_dec_close_binaural_data( &pDecDummy->hDiracDecBin ); +#ifdef JBM_TSM_ON_TCS + /* TC buffer */ + ivas_jbm_dec_tc_buffer_close( &pDecDummy->hTcBuffer ); +#endif + free( pDecDummy ); pDecDummy = NULL; -- GitLab From 92f6c9b489e2ca898bcec3e93413b806cc3f8c8f Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Thu, 27 Apr 2023 12:08:57 +0200 Subject: [PATCH 07/39] fix renderer msan error, fix ParamMC smoke test issue --- lib_dec/ivas_mc_param_dec.c | 5 +++++ lib_rend/lib_rend.c | 3 +++ 2 files changed, 8 insertions(+) diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 7767cae99e..89e4d8c136 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -1538,6 +1538,11 @@ void ivas_param_mc_dec_digest_tc( /* generate mixing matrices */ ivas_param_mc_get_mixing_matrices( hParamMC, hSynthesisOutputSetup, cx, hParamMC->h_output_synthesis_cov_state.mixing_matrix, hParamMC->h_output_synthesis_cov_state.mixing_matrix_res, nchan_out_transport, hParamMC->synthesis_conf, nchan_transport, nchan_out_cov ); } + + pop_wmops(); + + return; + } /*------------------------------------------------------------------------- diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 038b083654..ad33b7fc86 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -2447,6 +2447,9 @@ static DecoderDummy *initDecoderDummy( decDummy->hDecoderConfig->output_Fs = sampleRate; decDummy->hDecoderConfig->nchan_out = numOutChannels; decDummy->hDecoderConfig->Opt_Headrotation = 0; +#ifdef JBM_TSM_ON_TCS + decDummy->hDecoderConfig->voip_active = 0; +#endif decDummy->hBinRenderer = NULL; decDummy->hEFAPdata = NULL; -- GitLab From 3e3f82233f82564a9d1a5bd211fce0e5cf4261a9 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Thu, 27 Apr 2023 13:21:57 +0200 Subject: [PATCH 08/39] fixed ParamISM open function --- lib_dec/ivas_ism_param_dec.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index d82ee7b8dd..33f094f3b5 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -795,10 +795,8 @@ ivas_error ivas_param_ism_dec_open( st_ivas->hISMDTX.dtx_flag = 0; st_ivas->hDirAC = hDirAC; - hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = NULL; - hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc = NULL; #ifdef JBM_TSM_ON_TCS - if ( st_ivas->hDecoderConfig->voip_active && st_ivas->hTcBuffer == NULL ) + if ( st_ivas->hDecoderConfig->voip_active ) { if ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE ) { @@ -817,10 +815,15 @@ ivas_error ivas_param_ism_dec_open( } else { - int16_t nchan_to_allocate = st_ivas->hDecoderConfig->nchan_out; - if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_BUFFER, nchan_to_allocate, nchan_to_allocate, nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) + hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = NULL; + hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc = NULL; + if ( st_ivas->hTcBuffer == NULL ) { - return error; + int16_t nchan_to_allocate = st_ivas->hDecoderConfig->nchan_out; + if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_BUFFER, nchan_to_allocate, nchan_to_allocate, nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) + { + return error; + } } } } -- GitLab From c288c4c2bd60e4f387287e08f5fdb942d54dfe75 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Thu, 27 Apr 2023 14:02:43 +0200 Subject: [PATCH 09/39] another init fix for ParamISM --- lib_dec/ivas_ism_param_dec.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 33f094f3b5..1d80767e77 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -827,6 +827,11 @@ ivas_error ivas_param_ism_dec_open( } } } + else + { + hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = NULL; + hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc = NULL; + } #endif pop_wmops(); -- GitLab From 898cf3cc49b77d8fb16f0aacc78df0a7dde29c4c Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Thu, 27 Apr 2023 14:38:48 +0200 Subject: [PATCH 10/39] another fix for ISM br switching, clang-format --- lib_dec/ivas_ism_dec.c | 8 +++++++- lib_dec/ivas_mc_param_dec.c | 1 - 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index 04c9504cc1..e4c22ebba2 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -83,7 +83,13 @@ static ivas_error ivas_ism_bitrate_switching( nSCE_old = st_ivas->nSCE; #ifdef FIX_416_ISM_BR_SWITCHING - ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old ); + /* we need to set to the old ism mode here, otherwise we are not getting the correct numbers*/ + { + ISM_MODE new_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 = new_ism_mode; + } #endif if ( ( error = ivas_ism_config( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->nchan_ism, NULL, NULL, NULL, element_brate_tmp, NULL, NULL ) ) != IVAS_ERR_OK ) diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 89e4d8c136..eea9bd5b56 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -1542,7 +1542,6 @@ void ivas_param_mc_dec_digest_tc( pop_wmops(); return; - } /*------------------------------------------------------------------------- -- GitLab From f475b4ea795565e4649e79408a11fb0c5a8ff9d6 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Thu, 27 Apr 2023 15:16:36 +0200 Subject: [PATCH 11/39] add correct bit rate switch profiles for ISM --- scripts/config/ivas_modes.json | 26 +++++++++++++------------- scripts/switchPaths/sw_13k2_128k.bin | 3 +++ scripts/switchPaths/sw_16k4_128k.bin | 3 +++ scripts/switchPaths/sw_24k4_384k.bin | 3 +++ scripts/switchPaths/sw_24k4_512k.bin | 3 +++ scripts/switchPaths/sw_32k_128k.bin | 3 +++ scripts/switchPaths/sw_32k_384k.bin | 3 +++ scripts/switchPaths/sw_32k_512k.bin | 3 +++ 8 files changed, 34 insertions(+), 13 deletions(-) create mode 100644 scripts/switchPaths/sw_13k2_128k.bin create mode 100644 scripts/switchPaths/sw_16k4_128k.bin create mode 100644 scripts/switchPaths/sw_24k4_384k.bin create mode 100644 scripts/switchPaths/sw_24k4_512k.bin create mode 100644 scripts/switchPaths/sw_32k_128k.bin create mode 100644 scripts/switchPaths/sw_32k_384k.bin create mode 100644 scripts/switchPaths/sw_32k_512k.bin diff --git a/scripts/config/ivas_modes.json b/scripts/config/ivas_modes.json index a4f9ef7fc6..77f87a2a39 100644 --- a/scripts/config/ivas_modes.json +++ b/scripts/config/ivas_modes.json @@ -1945,20 +1945,20 @@ "table_name": "ISM1@{table_bitrate} RS kbps {bandwidth}", "nummetadata": 1, "metadatafilenames": [ - "test_ISM_trajectory{mdi}.csv" + "stvISM{mdi}.csv" ], "rs": true, "amr": false, "mono": false, "bitrates": { "wb": { - "all": "{sw_files_path}/sw_13k2_256k.bin" + "all": "{sw_files_path}/sw_13k2_128k.bin" }, "swb": { - "all": "{sw_files_path}/sw_13k2_256k.bin" + "all": "{sw_files_path}/sw_13k2_128k.bin" }, "fb": { - "all": "{sw_files_path}/sw_32k_256k.bin" + "all": "{sw_files_path}/sw_32k_128k.bin" } } }, @@ -2158,7 +2158,7 @@ "table_name": "ISM2@{table_bitrate} kbps RS {bandwidth}", "nummetadata": 2, "metadatafilenames": [ - "test_ISM_trajectory{mdi}.csv" + "stvISM{mdi}.csv.csv" ], "rs": true, "amr": false, @@ -2318,20 +2318,20 @@ "table_name": "ISM3@{table_bitrate} kbps {bandwidth}", "nummetadata": 3, "metadatafilenames": [ - "test_ISM_trajectory{mdi}.csv" + "stvISM{mdi}.csv.csv" ], "rs": true, "amr": false, "mono": false, "bitrates": { "wb": { - "all": "{sw_files_path}/sw_24k4_256k_1.bin" + "all": "{sw_files_path}/sw_24k4_384k.bin" }, "swb": { - "all": "{sw_files_path}/sw_24k4_256k_1.bin" + "all": "{sw_files_path}/sw_24k4_384k.bin" }, "fb": { - "all": "{sw_files_path}/sw_32k_256k.bin" + "all": "{sw_files_path}/sw_32k_384k.bin" } } } @@ -2484,20 +2484,20 @@ "table_name": "ISM4@{table_bitrate} kbps RS {bandwidth}", "nummetadata": 4, "metadatafilenames": [ - "test_ISM_trajectory{mdi}.csv" + "stvISM{mdi}.csv" ], "rs": true, "amr": false, "mono": false, "bitrates": { "wb": { - "all": "{sw_files_path}/sw_24k4_256k_1.bin" + "all": "{sw_files_path}/sw_24k4_384k.bin" }, "swb": { - "all": "{sw_files_path}/sw_24k4_256k_1.bin" + "all": "{sw_files_path}/sw_24k4_384k.bin" }, "fb": { - "all": "{sw_files_path}/sw_32k_256k.bin" + "all": "{sw_files_path}/sw_32k_384k.bin" } } } diff --git a/scripts/switchPaths/sw_13k2_128k.bin b/scripts/switchPaths/sw_13k2_128k.bin new file mode 100644 index 0000000000..7309ee26ab --- /dev/null +++ b/scripts/switchPaths/sw_13k2_128k.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9ddf71b27bcd47d5f37abb6c62146ff4fb5a848cd85605d4df87a9cc4b1d1e0 +size 60000 diff --git a/scripts/switchPaths/sw_16k4_128k.bin b/scripts/switchPaths/sw_16k4_128k.bin new file mode 100644 index 0000000000..1e85a18b77 --- /dev/null +++ b/scripts/switchPaths/sw_16k4_128k.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3e07f8c6be0e08ed96b15c9a3daa2811ef0b596dc08cc687bce1f0ca8e49969b +size 60000 diff --git a/scripts/switchPaths/sw_24k4_384k.bin b/scripts/switchPaths/sw_24k4_384k.bin new file mode 100644 index 0000000000..781e3023b2 --- /dev/null +++ b/scripts/switchPaths/sw_24k4_384k.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6e3e7599638d3792d851a5bdc13b85d6b401ebc9724795562b1a5d25fc2c3bc6 +size 60000 diff --git a/scripts/switchPaths/sw_24k4_512k.bin b/scripts/switchPaths/sw_24k4_512k.bin new file mode 100644 index 0000000000..dcc58dbdc6 --- /dev/null +++ b/scripts/switchPaths/sw_24k4_512k.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2369edc21bdf3440ceaf21de16698e38cf50c246ddf04878a5961538dded11ad +size 60000 diff --git a/scripts/switchPaths/sw_32k_128k.bin b/scripts/switchPaths/sw_32k_128k.bin new file mode 100644 index 0000000000..fc4b81e0c3 --- /dev/null +++ b/scripts/switchPaths/sw_32k_128k.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fdb0da661cb08cc546c3761afa1d778d2c7aa04df61b608ae4301e31867dcc2e +size 60000 diff --git a/scripts/switchPaths/sw_32k_384k.bin b/scripts/switchPaths/sw_32k_384k.bin new file mode 100644 index 0000000000..088edfacbf --- /dev/null +++ b/scripts/switchPaths/sw_32k_384k.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77f6e7b141b16bd21005c5169cd9bc8b7b2c96df379ce9e74788717c66b9130f +size 60000 diff --git a/scripts/switchPaths/sw_32k_512k.bin b/scripts/switchPaths/sw_32k_512k.bin new file mode 100644 index 0000000000..d385f3a890 --- /dev/null +++ b/scripts/switchPaths/sw_32k_512k.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a6eb4080fce3bc1a7ba20cfc8ef3e8ff981ebce5de7c8e45bbc12edf7f21d0c +size 60000 -- GitLab From f8052edad270f91c25c25d5137b6949799462702 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Thu, 27 Apr 2023 15:30:21 +0200 Subject: [PATCH 12/39] fixed MASA RS mode config --- scripts/config/ivas_modes.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/config/ivas_modes.json b/scripts/config/ivas_modes.json index 77f87a2a39..dc2a93be9d 100644 --- a/scripts/config/ivas_modes.json +++ b/scripts/config/ivas_modes.json @@ -1072,7 +1072,7 @@ ] } }, - "MASA_2TC_1DIR_b{bitrate}_{bandwidth}_cbr": { + "MASA_2TC_1DIR_b{bitrate}_{bandwidth}_rs": { "encmodeoption": [ "-masa", "2" @@ -1094,7 +1094,7 @@ "metadatafilenames": [ "{item}.met" ], - "rs": false, + "rs": true, "amr": false, "mono": false, "rs": true, -- GitLab From 665014b27ba7131f5a33d3029081b455a9d0f5bf Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Fri, 28 Apr 2023 12:53:29 +0200 Subject: [PATCH 13/39] several fixes for the JBM path --- lib_dec/ivas_dirac_output_synthesis_dec.c | 43 +++++++++++++++++------ lib_dec/ivas_masa_dec.c | 19 +++++++--- lib_dec/ivas_mc_param_dec.c | 9 ++++- lib_dec/ivas_mct_dec.c | 3 +- lib_dec/ivas_sba_dec.c | 6 +++- 5 files changed, 62 insertions(+), 18 deletions(-) diff --git a/lib_dec/ivas_dirac_output_synthesis_dec.c b/lib_dec/ivas_dirac_output_synthesis_dec.c index 03c512dfd8..8271749e21 100644 --- a/lib_dec/ivas_dirac_output_synthesis_dec.c +++ b/lib_dec/ivas_dirac_output_synthesis_dec.c @@ -1503,21 +1503,44 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( *-----------------------------------------------------------------*/ /* store estimates for next synthesis block */ - mvr2r( gains_dir, h_dirac_output_synthesis_state->gains_dir_prev, num_freq_bands * nchan_out_woLFE ); - mvr2r( gains_diff, h_dirac_output_synthesis_state->gains_diff_prev, num_freq_bands * nchan_out_woLFE ); +#ifdef JBM_TSM_ON_TCS + if ( hDirAC->voip_active == 1 ) + { + mvr2r( gains_dir, h_dirac_output_synthesis_state->gains_dir_prev, num_freq_bands * hDirAC->num_outputs_dir ); + mvr2r( gains_diff, h_dirac_output_synthesis_state->gains_diff_prev, num_freq_bands * hDirAC->num_outputs_dir ); - /* reset values */ - set_zero( h_dirac_output_synthesis_state->proto_power_smooth, num_freq_bands * num_protos_dir ); + /* reset values */ + set_zero( h_dirac_output_synthesis_state->proto_power_smooth, num_freq_bands * hDirAC->num_outputs_dir ); - if ( h_dirac_output_synthesis_state->proto_power_diff_smooth != NULL ) - { - set_zero( h_dirac_output_synthesis_state->proto_power_diff_smooth, h_dirac_output_synthesis_params->max_band_decorr * nchan_out_woLFE ); + if ( h_dirac_output_synthesis_state->proto_power_diff_smooth != NULL ) + { + set_zero( h_dirac_output_synthesis_state->proto_power_diff_smooth, h_dirac_output_synthesis_params->max_band_decorr * hDirAC->num_outputs_dir ); + } + + set_zero( h_dirac_output_synthesis_state->cy_auto_dir_smooth, num_freq_bands * hDirAC->num_outputs_dir ); + set_zero( h_dirac_output_synthesis_state->cy_cross_dir_smooth, num_freq_bands * hDirAC->num_outputs_dir ); + set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth, num_freq_bands * hDirAC->num_outputs_dir ); } + else + { +#endif + mvr2r( gains_dir, h_dirac_output_synthesis_state->gains_dir_prev, num_freq_bands * nchan_out_woLFE ); + mvr2r( gains_diff, h_dirac_output_synthesis_state->gains_diff_prev, num_freq_bands * nchan_out_woLFE ); - set_zero( h_dirac_output_synthesis_state->cy_auto_dir_smooth, num_freq_bands * nchan_out_woLFE ); - set_zero( h_dirac_output_synthesis_state->cy_cross_dir_smooth, num_freq_bands * nchan_out_woLFE ); - set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth, num_freq_bands * nchan_out_woLFE ); + /* reset values */ + set_zero( h_dirac_output_synthesis_state->proto_power_smooth, num_freq_bands * num_protos_dir ); + + if ( h_dirac_output_synthesis_state->proto_power_diff_smooth != NULL ) + { + set_zero( h_dirac_output_synthesis_state->proto_power_diff_smooth, h_dirac_output_synthesis_params->max_band_decorr * nchan_out_woLFE ); + } + set_zero( h_dirac_output_synthesis_state->cy_auto_dir_smooth, num_freq_bands * nchan_out_woLFE ); + set_zero( h_dirac_output_synthesis_state->cy_cross_dir_smooth, num_freq_bands * nchan_out_woLFE ); + set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth, num_freq_bands * nchan_out_woLFE ); +#ifdef JBM_TSM_ON_TCS + } +#endif pop_wmops(); return; diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index dbb7e11572..ac92d7eaf5 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -378,7 +378,7 @@ ivas_error ivas_masa_dec_open( int16_t nchan_to_allocate; TC_BUFFER_MODE buffer_mode; buffer_mode = TC_BUFFER_MODE_RENDERER; - if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_MONO ) + if ( st_ivas->mc_mode == MC_MODE_MCMASA && (st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_MONO) ) { buffer_mode = TC_BUFFER_MODE_BUFFER; } @@ -1162,13 +1162,22 @@ ivas_error ivas_masa_dec_reconfigure( ivas_masa_set_elements( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &tmp, &tmp, &tmp ); - if ( st_ivas->hDecoderConfig->voip_active == 1 && 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->hDecoderConfig->voip_active == 1 && st_ivas->renderer_type != RENDERER_DISABLE ) { - int16_t nchan_to_allocate = ivas_jbm_dec_get_num_tc_channels( st_ivas ); - if ( nchan_to_allocate != st_ivas->hTcBuffer->nchan_transport_jbm ) + int16_t tc_nchan_to_allocate; + int16_t tc_nchan_transport; + + tc_nchan_transport = ivas_jbm_dec_get_num_tc_channels( st_ivas ); + tc_nchan_to_allocate = tc_nchan_transport; + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + tc_nchan_to_allocate = 2 * BINAURAL_CHANNELS; + } + if ( tc_nchan_transport != st_ivas->hTcBuffer->nchan_transport_jbm || tc_nchan_to_allocate != st_ivas->hTcBuffer->nchan_transport_internal ) { - if ( ( error = ivas_jbm_dec_tc_buffer_reconfigure( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_to_allocate, nchan_to_allocate, nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_jbm_dec_tc_buffer_reconfigure( st_ivas, TC_BUFFER_MODE_RENDERER, tc_nchan_transport, tc_nchan_to_allocate, tc_nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) { + return error; } } } diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index eea9bd5b56..0ed6a0a94e 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -440,6 +440,9 @@ ivas_error ivas_param_mc_dec_open( return error; } +#ifdef JBM_TSM_ON_TCS + ivas_param_mc_dec_compute_interpolator( 0, 0, DEFAULT_JBM_CLDFB_TIMESLOTS, hParamMC->h_output_synthesis_params.interpolator ); +#endif /* Head rotation */ if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) && st_ivas->hDecoderConfig->Opt_Headrotation ) @@ -960,6 +963,10 @@ ivas_error ivas_param_mc_dec_reconfig( return error; } +#ifdef JBM_TSM_ON_TCS + ivas_param_mc_dec_compute_interpolator( 0, 0, DEFAULT_JBM_CLDFB_TIMESLOTS, hParamMC->h_output_synthesis_params.interpolator ); +#endif + ivas_dirac_dec_output_synthesis_cov_init( &( hParamMC->h_output_synthesis_cov_state ), nchan_transport, nchan_out_cov, hParamMC->hMetadataPMC->num_parameter_bands, max_param_band_residual ); @@ -1465,7 +1472,7 @@ void ivas_param_mc_dec_digest_tc( ivas_jbm_dec_get_adapted_subframes( nCldfbSlots, hParamMC->subframe_nbslots, &hParamMC->nb_subframes ); /* BE Workaround */ - if ( !st_ivas->bfi && st_ivas->hDecoderConfig->voip_active == 0 ) + if ( !st_ivas->bfi && st_ivas->hDecoderConfig->voip_active == 1 ) { ivas_param_mc_dec_compute_interpolator( hParamMC->hMetadataPMC->bAttackPresent, hParamMC->hMetadataPMC->attackIndex, nCldfbSlots, hParamMC->h_output_synthesis_params.interpolator ); } diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index f979942a9a..92a48859ce 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -1243,7 +1243,8 @@ static ivas_error ivas_mc_dec_reconfig( } /* reconfigure buffer */ if ( hTcBuffer->tc_buffer_mode != tc_buffer_mode_new || hTcBuffer->nchan_transport_jbm != tc_nchan_tc_new || - hTcBuffer->nchan_buffer_full != tc_nchan_full_new || hTcBuffer->nchan_transport_internal != tc_nchan_allocate_new ) + hTcBuffer->nchan_buffer_full != tc_nchan_full_new || hTcBuffer->nchan_transport_internal != tc_nchan_allocate_new || + tc_granularity_new != hTcBuffer->n_samples_granularity ) { if ( ( error = ivas_jbm_dec_tc_buffer_reconfigure( st_ivas, tc_buffer_mode_new, tc_nchan_tc_new, tc_nchan_allocate_new, tc_nchan_full_new, tc_granularity_new ) ) != IVAS_ERR_OK ) { diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index c945e3f68b..a3adfa3ff1 100755 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -376,7 +376,7 @@ ivas_error ivas_sba_dec_reconfigure( /*-----------------------------------------------------------------* * TC buffer *-----------------------------------------------------------------*/ - if ( st_ivas->hDecoderConfig->voip_active == 1 && 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->hDecoderConfig->voip_active == 1 ) { int16_t tc_nchan_to_allocate; int16_t tc_nchan_tc; @@ -392,6 +392,10 @@ ivas_error ivas_sba_dec_reconfigure( tc_nchan_tc = st_ivas->hDecoderConfig->nchan_out; tc_nchan_to_allocate = tc_nchan_tc; } + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + tc_nchan_to_allocate = 2 * BINAURAL_CHANNELS; + } else if ( st_ivas->sba_mode == SBA_MODE_SPAR ) { sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); -- GitLab From 1c3b4f06a9e6ed2b4cb7012a1f30e1bf9619f5b2 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Tue, 2 May 2023 08:54:59 +0200 Subject: [PATCH 14/39] fix EVS JBM BE, fix JBM bit rate switching for SBA, clang-format --- apps/decoder.c | 2 +- lib_dec/ivas_dirac_dec.c | 7 +++++- lib_dec/ivas_masa_dec.c | 2 +- lib_dec/ivas_spar_decoder.c | 6 ++++- lib_dec/jbm_pcmdsp_apa.c | 44 ++++++++++++++++++++++++++++++++-- lib_dec/jbm_pcmdsp_apa.h | 2 ++ lib_dec/jbm_pcmdsp_window.c | 48 +++++++++++++++++++++++++++++++++++++ lib_dec/jbm_pcmdsp_window.h | 1 + lib_dec/lib_dec.c | 15 +++++++++++- 9 files changed, 120 insertions(+), 7 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index f2134a29f4..31f38ec1f3 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -83,7 +83,7 @@ static #define VARIABLE_SPEED_FETCH_FRAMESIZE_MS 20 #endif #ifdef JBM_TSM_ON_TCS -#define JBM_FRONTEND_FETCH_FRAMESIZE_MS 5 +#define JBM_FRONTEND_FETCH_FRAMESIZE_MS 20 #define FRAME_SIZE_NS 20000000L #endif diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index b85120afa1..2d527a8e5d 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -1026,16 +1026,21 @@ ivas_error ivas_dirac_dec_config( /* allocate transport channels*/ if ( flag_config == DIRAC_OPEN ) { - if ( st_ivas->hDecoderConfig->voip_active == 1 && st_ivas->hTcBuffer == NULL && 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->hDecoderConfig->voip_active == 1 && st_ivas->hTcBuffer == NULL ) { if ( st_ivas->sba_mode == SBA_MODE_DIRAC ) { int16_t nchan_to_allocate; + nchan_to_allocate = nchan_transport; if ( st_ivas->nchan_transport == 1 && ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirAC->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 || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + 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, hDirAC->slot_size ) ) != IVAS_ERR_OK ) { return error; diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index ac92d7eaf5..71ae7c5022 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -378,7 +378,7 @@ ivas_error ivas_masa_dec_open( int16_t nchan_to_allocate; TC_BUFFER_MODE buffer_mode; buffer_mode = TC_BUFFER_MODE_RENDERER; - if ( st_ivas->mc_mode == MC_MODE_MCMASA && (st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_MONO) ) + if ( st_ivas->mc_mode == MC_MODE_MCMASA && ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_MONO ) ) { buffer_mode = TC_BUFFER_MODE_BUFFER; } diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index d3067b0e46..7c1c70bf87 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -190,7 +190,7 @@ ivas_error ivas_spar_dec_open( } } /* allocate transport channels*/ - if ( st_ivas->hDecoderConfig->voip_active == 1 && st_ivas->hTcBuffer == NULL && 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->hDecoderConfig->voip_active == 1 && st_ivas->hTcBuffer == NULL ) { int16_t nchan_to_allocate; int16_t nchan_tc; @@ -205,6 +205,10 @@ ivas_error ivas_spar_dec_open( nchan_tc = st_ivas->hDecoderConfig->nchan_out; nchan_to_allocate = nchan_tc; } + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + nchan_to_allocate = 2 * BINAURAL_CHANNELS; + } if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, buffer_mode, nchan_tc, nchan_to_allocate, nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) { return error; diff --git a/lib_dec/jbm_pcmdsp_apa.c b/lib_dec/jbm_pcmdsp_apa.c index 61b3256d58..713c2327a0 100644 --- a/lib_dec/jbm_pcmdsp_apa.c +++ b/lib_dec/jbm_pcmdsp_apa.c @@ -67,6 +67,7 @@ struct apa_state_t { /* output buffer */ #ifdef JBM_TSM_ON_TCS + bool evs_compat_mode; float *buf_out; #else int16_t *buf_out; @@ -187,6 +188,10 @@ ivas_error apa_init( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for JBM\n" ) ); } +#ifdef JBM_TSM_ON_TCS + ps->evs_compat_mode = false; +#endif + apa_reset( ps ); *pps = ps; @@ -406,6 +411,19 @@ bool apa_set_renderer_residual_samples( ps->l_r_buf = l_r_buf * ps->num_channels; return 0; } + +bool apa_set_evs_compat_mode( apa_state_t *ps, bool mode ) +{ + /* make sure pointer is valid */ + if ( ps == NULL ) + { + return 1; + } + + ps->evs_compat_mode = mode; + + return 0; +} #endif /* @@ -1291,7 +1309,18 @@ static bool shrink_frm( { return 1; } - overlapAdd( frm_in, frm_in + xtract, frm_out, l_seg, ps->num_channels, ps->win + ps->l_halfwin, ps->win ); +#ifdef JBM_TSM_ON_TCS + if ( ps->evs_compat_mode == true ) + { + overlapAddEvs( frm_in, frm_in + xtract, frm_out, l_seg, ps->num_channels, ps->win + ps->l_halfwin, ps->win ); + } + else + { +#endif + overlapAdd( frm_in, frm_in + xtract, frm_out, l_seg, ps->num_channels, ps->win + ps->l_halfwin, ps->win ); +#ifdef JBM_TSM_ON_TCS + } +#endif } else { @@ -1517,7 +1546,18 @@ static bool extend_frm( fadeOut = frm_in + l_frm + xtract[n - 1] + l_seg; fadeIn = frm_in + l_frm + xtract[n]; out = frm_out + ( n - 2 ) * l_seg; - overlapAdd( fadeOut, fadeIn, out, l_seg, ps->num_channels, ps->win + ps->l_halfwin, ps->win ); +#ifdef JBM_TSM_ON_TCS + if ( ps->evs_compat_mode == true ) + { + overlapAddEvs( fadeOut, fadeIn, out, l_seg, ps->num_channels, ps->win + ps->l_halfwin, ps->win ); + } + else + { +#endif + overlapAdd( fadeOut, fadeIn, out, l_seg, ps->num_channels, ps->win + ps->l_halfwin, ps->win ); +#ifdef JBM_TSM_ON_TCS + } +#endif } else { diff --git a/lib_dec/jbm_pcmdsp_apa.h b/lib_dec/jbm_pcmdsp_apa.h index 6a2b02e13c..a5e7cb7d61 100644 --- a/lib_dec/jbm_pcmdsp_apa.h +++ b/lib_dec/jbm_pcmdsp_apa.h @@ -119,6 +119,8 @@ bool apa_set_renderer_granularity( apa_state_t *ps, uint16_t l_ts ); bool apa_set_renderer_residual_samples( apa_state_t *ps, uint16_t l_r_buf ); +bool apa_set_evs_compat_mode( apa_state_t *ps, bool mode ); + uint8_t apa_reconfigure( apa_state_t *ps, uint16_t num_channels, uint16_t l_ts ); #endif diff --git a/lib_dec/jbm_pcmdsp_window.c b/lib_dec/jbm_pcmdsp_window.c index fa0ea6f724..a31d368c91 100644 --- a/lib_dec/jbm_pcmdsp_window.c +++ b/lib_dec/jbm_pcmdsp_window.c @@ -139,3 +139,51 @@ void overlapAdd( return; } + +void overlapAddEvs( + const float *fadeOut, + const float *fadeIn, + float *out, + uint16_t n, + uint16_t nChannels, + const float *fadeOutWin, + const float *fadeInWin ) +{ + float fdOutVal, fdInVal; + int16_t i, j, hannIter; + float combinedVal; + + for ( j = 0; j < nChannels; j++ ) + { + /* reset Hann window iterator to beginning (both channels use same window) */ + hannIter = 0; + for ( i = j; i < n; i += nChannels ) + { + fdOutVal = fadeOut[i] * fadeOutWin[hannIter]; + fdInVal = fadeIn[i] * fadeInWin[hannIter]; + /* round combinedVal value (taking care of sign) */ + + combinedVal = floorf( ( fdInVal + fdOutVal ) + 0.5f ); + if ( fdInVal + fdOutVal < 0.0 ) + { + combinedVal = ceilf( ( fdInVal + fdOutVal ) - 0.5f ); + } + + /* saturate value */ + if ( combinedVal > MAX16B_FLT ) + { + combinedVal = MAX16B_FLT; + } + else if ( combinedVal < MIN16B_FLT ) + { + combinedVal = MIN16B_FLT; + } + + out[i] = combinedVal; + + hannIter++; + } + } + + return; +} diff --git a/lib_dec/jbm_pcmdsp_window.h b/lib_dec/jbm_pcmdsp_window.h index 2f8cd462b5..8c1823867a 100644 --- a/lib_dec/jbm_pcmdsp_window.h +++ b/lib_dec/jbm_pcmdsp_window.h @@ -63,6 +63,7 @@ void hannWindow( uint16_t n, float *w ); * @param[in] fadeInWin window for fade in */ #ifdef JBM_TSM_ON_TCS void overlapAdd( const float *fadeOut, const float *fadeIn, float *out, uint16_t n, uint16_t nChannels, const float *fadeOutWin, const float *fadeInWin ); +void overlapAddEvs( const float *fadeOut, const float *fadeIn, float *out, uint16_t n, uint16_t nChannels, const float *fadeOutWin, const float *fadeInWin ); #else void overlapAdd( const int16_t *fadeOut, const int16_t *fadeIn, int16_t *out, uint16_t n, uint16_t nChannels, const float *fadeOutWin, const float *fadeInWin ); #endif diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 33a4ed7526..9429c1bd89 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -2824,7 +2824,13 @@ static ivas_error evs_dec_main( #ifdef JBM_TSM_ON_TCS if ( floatBuf != NULL ) { - mvr2r( output, floatBuf, nOutSamples ); + /* BE workaround */ + int16_t pcm_buf_local[L_FRAME48k]; +#ifdef DEBUGGING + st_ivas->noClipping += +#endif + syn_output( output, nOutSamples, pcm_buf_local ); + mvs2r( pcm_buf_local, floatBuf, nOutSamples ); } else { @@ -3125,6 +3131,13 @@ ivas_error IVAS_DEC_VoIP_reconfigure( IVAS_DEC_HANDLE hIvasDec, const uint16_t n return IVAS_ERR_INIT_ERROR; } } + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + { + if ( apa_set_evs_compat_mode( hIvasDec->hVoIP->hTimeScaler, true ) != 0 ) + { + return IVAS_ERR_INIT_ERROR; + } + } } else { -- GitLab From e255694c1e47f9ef80a45df435e7972e54f0721b Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Mon, 8 May 2023 09:08:40 +0200 Subject: [PATCH 15/39] fix compile error, clang-format --- lib_dec/ivas_mc_param_dec.c | 8 +++----- lib_dec/ivas_sba_dec.c | 4 ---- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 5f0b0e03eb..37c8f181aa 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -1396,8 +1396,10 @@ void ivas_param_mc_dec_read_BS( /* for PLC, use the saved ILDs and ICCs from the past and set the transient flag and transient position to zero */ hMetadataPMC->bAttackPresent = 0; hMetadataPMC->attackIndex = 0; +#ifndef JBM_TSM_ON_TCS #ifdef FIX_431_PARAMMC_PLC_INTERPOLATOR param_mc_compute_interpolator( hMetadataPMC->bAttackPresent, hMetadataPMC->attackIndex, PARAM_MC_MAX_NSLOTS, hParamMC->h_output_synthesis_params.interpolator ); +#endif #endif } @@ -1474,11 +1476,7 @@ void ivas_param_mc_dec_digest_tc( hParamMC->subframes_rendered = 0; ivas_jbm_dec_get_adapted_subframes( nCldfbSlots, hParamMC->subframe_nbslots, &hParamMC->nb_subframes ); - /* BE Workaround */ - if ( !st_ivas->bfi || st_ivas->hDecoderConfig->voip_active == 1 ) - { - ivas_param_mc_dec_compute_interpolator( hParamMC->hMetadataPMC->bAttackPresent, hParamMC->hMetadataPMC->attackIndex, nCldfbSlots, hParamMC->h_output_synthesis_params.interpolator ); - } + ivas_param_mc_dec_compute_interpolator( hParamMC->hMetadataPMC->bAttackPresent, hParamMC->hMetadataPMC->attackIndex, nCldfbSlots, hParamMC->h_output_synthesis_params.interpolator ); for ( param_band_idx = 0; param_band_idx < PARAM_MC_MAX_PARAMETER_BANDS; param_band_idx++ ) { diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index d135c2663e..91038ca927 100755 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -178,8 +178,6 @@ ivas_error ivas_sba_dec_reconfigure( } ivas_spar_config( ivas_total_brate, sba_order_internal, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &hSpar->core_nominal_brate, st_ivas->sid_format ); - - } else { @@ -351,7 +349,6 @@ ivas_error ivas_sba_dec_reconfigure( int16_t tc_nchan_to_allocate; int16_t tc_nchan_tc; TC_BUFFER_MODE tc_buffer_mode; - int16_t sba_order_internal; tc_buffer_mode = TC_BUFFER_MODE_RENDERER; tc_nchan_tc = ivas_jbm_dec_get_num_tc_channels( st_ivas ); @@ -368,7 +365,6 @@ ivas_error ivas_sba_dec_reconfigure( } else if ( st_ivas->sba_mode == SBA_MODE_SPAR ) { - sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); tc_nchan_to_allocate = ivas_sba_get_nchan_metadata( sba_order_internal ); } else -- GitLab From 51413506987d0bea58d7113a3dc4b0005a1a4e9c Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Mon, 8 May 2023 16:44:00 +0200 Subject: [PATCH 16/39] JBM MASA and binaural renderer optimization, under subdefine MASA_PARAMBIN_SF_MAP --- lib_com/ivas_prot.h | 12 + lib_com/options.h | 2 +- lib_dec/ivas_dirac_dec.c | 185 ++++++-- lib_dec/ivas_dirac_output_synthesis_dec.c | 81 ++-- lib_dec/ivas_masa_dec.c | 27 +- lib_dec/ivas_mc_param_dec.c | 4 +- lib_dec/ivas_spar_decoder.c | 12 +- lib_dec/ivas_stat_dec.h | 6 +- lib_dec/lib_dec.c | 28 +- lib_rend/ivas_dirac_dec_binaural_functions.c | 443 ++++++++++++++++++- lib_rend/ivas_sba_rendering.c | 4 +- 11 files changed, 698 insertions(+), 106 deletions(-) diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 58122739ba..92dc25bef2 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -3758,11 +3758,15 @@ void ivas_dirac_dec_output_synthesis_process_slot( const int16_t *azimuth, const int16_t *elevation, const float *diffuseness, +#ifndef MASA_PARAMBIN_SF_MAP const uint16_t coherence_flag, +#endif #endif DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */ #ifdef JBM_TSM_ON_TCS +#ifndef MASA_PARAMBIN_SF_MAP MASA_DECODER_HANDLE hMasa, +#endif const int16_t sh_rot_max_order, #endif const float *p_Rmat, /* i : rotation matrix */ @@ -5028,11 +5032,19 @@ void ivas_masa_prerender( #ifdef JBM_TSM_ON_TCS void ivas_spar_param_to_masa_param_mapping_sf( Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ +#ifdef MASA_PARAMBIN_SF_MAP + int16_t azimuth[CLDFB_NO_CHANNELS_MAX], + int16_t elevation[CLDFB_NO_CHANNELS_MAX], + float energy_ratio1[CLDFB_NO_CHANNELS_MAX], + float spreadCoherence[CLDFB_NO_CHANNELS_MAX], + float surroundingCoherence[CLDFB_NO_CHANNELS_MAX], +#else int16_t azimuth[][CLDFB_NO_CHANNELS_MAX], int16_t elevation[][CLDFB_NO_CHANNELS_MAX], float energy_ratio1[][CLDFB_NO_CHANNELS_MAX], float spreadCoherence[][CLDFB_NO_CHANNELS_MAX], float surroundingCoherence[][CLDFB_NO_CHANNELS_MAX], +#endif float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */ float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /* i : Input audio in CLDFB domain, imag */ ); diff --git a/lib_com/options.h b/lib_com/options.h index 8f4a40aab3..12048be943 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -179,7 +179,7 @@ #define VARIABLE_SPEED_DECODING /* FhG: variable speed decoding employing the JBM functioniality */ #define JBM_TSM_ON_TCS /* FhG: run the TSM part of JBM on the TCs instead of the final output pcm waveforms */ #ifdef JBM_TSM_ON_TCS -#define JBM_DIRAC_DEBUG_BE +#define MASA_PARAMBIN_SF_MAP #endif /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index a0b6126415..b4a8b44e79 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -173,7 +173,7 @@ ivas_error ivas_dirac_dec_config( num_outputs_diff_old = 0; num_protos_diff_old = 0; -#ifdef JBM_DIRAC_DEBUG_BE +#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) hDirAC->voip_active = st_ivas->hDecoderConfig->voip_active; #endif @@ -846,11 +846,18 @@ ivas_error ivas_dirac_dec_config( #ifdef JBM_TSM_ON_TCS { int16_t map_idx; - set_s( hDirAC->render_to_md_slot_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME ); + set_s( hDirAC->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME ); +#ifdef MASA_PARAMBIN_SF_MAP + for ( map_idx = 0; map_idx < DEFAULT_JBM_SUBFRAMES_5MS; map_idx++ ) + { + hDirAC->render_to_md_map[map_idx] = map_idx; + } +#else for ( map_idx = 0; map_idx < DEFAULT_JBM_CLDFB_TIMESLOTS; map_idx++ ) { - hDirAC->render_to_md_slot_map[map_idx] = map_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME; + hDirAC->render_to_md_map[map_idx] = map_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME; } +#endif } #endif } @@ -858,6 +865,23 @@ ivas_error ivas_dirac_dec_config( { hDirAC->dirac_md_buffer_length = MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR; hDirAC->dirac_bs_md_write_idx = DELAY_MASA_PARAM_DEC_SFR; +#ifdef JBM_TSM_ON_TCS + { + int16_t map_idx; + set_s( hDirAC->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME ); +#ifdef MASA_PARAMBIN_SF_MAP + for ( map_idx = 0; map_idx < DEFAULT_JBM_SUBFRAMES_5MS; map_idx++ ) + { + hDirAC->render_to_md_map[map_idx] = map_idx; + } +#else + for ( map_idx = 0; map_idx < DEFAULT_JBM_CLDFB_TIMESLOTS; map_idx++ ) + { + hDirAC->render_to_md_map[map_idx] = map_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME; + } +#endif + } +#endif } else { @@ -883,10 +907,10 @@ ivas_error ivas_dirac_dec_config( #ifdef JBM_TSM_ON_TCS { int16_t map_idx; - set_s( hDirAC->render_to_md_slot_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME ); + set_s( hDirAC->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME ); for ( map_idx = 0; map_idx < DEFAULT_JBM_CLDFB_TIMESLOTS; map_idx++ ) { - hDirAC->render_to_md_slot_map[map_idx] = hDirAC->dirac_read_idx + map_idx * num_slots_in_subfr / JBM_CLDFB_SLOTS_IN_SUBFRAME; + hDirAC->render_to_md_map[map_idx] = hDirAC->dirac_read_idx + map_idx * num_slots_in_subfr / JBM_CLDFB_SLOTS_IN_SUBFRAME; } } #endif @@ -2275,6 +2299,11 @@ void ivas_qmetadata_to_dirac( #ifdef JBM_TSM_ON_TCS +/*------------------------------------------------------------------------- + * ivas_dirac_dec_set_md_map() + * + * Set metadata index mapping for DirAC + *------------------------------------------------------------------------*/ void ivas_dirac_dec_set_md_map( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ int16_t nCldfbTs ) @@ -2304,13 +2333,43 @@ void ivas_dirac_dec_set_md_map( /* set mapping according to dirac_read_idx */ - set_s( hDirAC->render_to_md_slot_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME ); - - ivas_jbm_dec_get_md_map( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbTs, num_slots_in_subfr, hDirAC->dirac_read_idx, hDirAC->dirac_md_buffer_length, hDirAC->render_to_md_slot_map ); + set_s( hDirAC->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME ); +#ifdef MASA_PARAMBIN_SF_MAP + if ( hDirAC->hConfig == NULL || hDirAC->hConfig->dec_param_estim == 0 ) + { + ivas_jbm_dec_get_md_map( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbTs, num_slots_in_subfr, 0, hDirAC->dirac_md_buffer_length, hDirAC->render_to_md_map ); + } + else + { +#endif + ivas_jbm_dec_get_md_map( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbTs, num_slots_in_subfr, hDirAC->dirac_read_idx, hDirAC->dirac_md_buffer_length, hDirAC->render_to_md_map ); +#ifdef MASA_PARAMBIN_SF_MAP + } +#endif +#ifdef MASA_PARAMBIN_SF_MAP + if ( hDirAC->hConfig == NULL || hDirAC->hConfig->dec_param_estim == 0 ) + { + float tmp; + int16_t sf_idx, slot_idx, slot_idx_abs; + slot_idx_abs = 0; + for ( sf_idx = 0; sf_idx < hDirAC->nb_subframes; sf_idx++ ) + { + tmp = 0.0f; + for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[sf_idx]; slot_idx++ ) + { + tmp += (float) hDirAC->render_to_md_map[slot_idx_abs]; + slot_idx_abs++; + } + hDirAC->render_to_md_map[sf_idx] = ( (int16_t) roundf( tmp / (float) hDirAC->subframe_nbslots[sf_idx] ) + hDirAC->dirac_read_idx ) % hDirAC->dirac_md_buffer_length; + } + set_s( &hDirAC->render_to_md_map[hDirAC->nb_subframes], 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME - hDirAC->nb_subframes ); + } +#endif return; } + /*------------------------------------------------------------------------- * ivas_dirac_dec() * @@ -2463,11 +2522,9 @@ void ivas_dirac_dec_render_sf( { int16_t i, ch, idx_in, idx_lfe; DIRAC_DEC_HANDLE hDirAC; -#if defined( JBM_DIRAC_DEBUG_BE ) || !defined( JBM_TSM_ON_TCS ) float dirEne; float surCohEner; float surCohRatio[CLDFB_NO_CHANNELS_MAX]; -#endif int16_t subframe_idx; #ifndef JBM_TSM_ON_TCS int16_t sf1, sf2; @@ -2589,13 +2646,30 @@ void ivas_dirac_dec_render_sf( } /* copy parameters into local buffers*/ - for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) +#ifdef MASA_PARAMBIN_SF_MAP + if ( hDirAC->hConfig->dec_param_estim == TRUE ) { - mvs2s( hDirAC->azimuth[hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]], azimuth[slot_idx], hDirAC->num_freq_bands ); - mvs2s( hDirAC->elevation[hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]], elevation[slot_idx], hDirAC->num_freq_bands ); - mvr2r( hDirAC->diffuseness_vector[hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]], diffuseness_vector[slot_idx], hDirAC->num_freq_bands ); +#endif + for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) + { + mvs2s( hDirAC->azimuth[hDirAC->render_to_md_map[slot_idx + slot_idx_start]], azimuth[slot_idx], hDirAC->num_freq_bands ); + mvs2s( hDirAC->elevation[hDirAC->render_to_md_map[slot_idx + slot_idx_start]], elevation[slot_idx], hDirAC->num_freq_bands ); + mvr2r( hDirAC->diffuseness_vector[hDirAC->render_to_md_map[slot_idx + slot_idx_start]], diffuseness_vector[slot_idx], hDirAC->num_freq_bands ); + } +#ifdef MASA_PARAMBIN_SF_MAP + } + else + { + for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) + { + mvs2s( hDirAC->azimuth[hDirAC->render_to_md_map[subframe_idx]], azimuth[slot_idx], hDirAC->num_freq_bands ); + mvs2s( hDirAC->elevation[hDirAC->render_to_md_map[subframe_idx]], elevation[slot_idx], hDirAC->num_freq_bands ); + mvr2r( hDirAC->diffuseness_vector[hDirAC->render_to_md_map[subframe_idx]], diffuseness_vector[slot_idx], hDirAC->num_freq_bands ); + } } #endif +#endif + if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD ) { set_zero( reference_power_smooth, hDirAC->num_freq_bands ); @@ -2645,15 +2719,18 @@ void ivas_dirac_dec_render_sf( p_Rmat = 0; } -#if defined( JBM_DIRAC_DEBUG_BE ) || !defined( JBM_TSM_ON_TCS ) -#ifdef JBM_DIRAC_DEBUG_BE +#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) if ( st_ivas->hDecoderConfig->voip_active == 0 && hDirAC->hConfig->dec_param_estim == FALSE ) #else - if ( hDirAC->hConfig->dec_param_estim == FALSE ) + if ( hDirAC->hConfig->dec_param_estim == FALSE ) #endif { #ifdef JBM_TSM_ON_TCS - int16_t md_idx = hDirAC->render_to_md_slot_map[slot_idx_start]; +#ifdef MASA_PARAMBIN_SF_MAP + int16_t md_idx = hDirAC->render_to_md_map[subframe_idx]; +#else + int16_t md_idx = hDirAC->render_to_md_map[slot_idx_start]; +#endif #endif /* compute response */ if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD ) @@ -2662,7 +2739,7 @@ void ivas_dirac_dec_render_sf( #ifdef JBM_TSM_ON_TCS diffuseness_vector[0], #else - hDirAC->diffuseness_vector[hDirAC->dirac_read_idx], + hDirAC->diffuseness_vector[hDirAC->dirac_read_idx], #endif hDirAC->h_output_synthesis_psd_params.max_band_decorr, hDirAC->h_output_synthesis_psd_state.direct_power_factor, @@ -2676,7 +2753,7 @@ void ivas_dirac_dec_render_sf( #ifdef JBM_TSM_ON_TCS surCohEner = hDirAC->h_output_synthesis_psd_state.diffuse_power_factor[i] * hDirAC->surroundingCoherence[md_idx][i]; #else - surCohEner = hDirAC->h_output_synthesis_psd_state.diffuse_power_factor[i] * hDirAC->surroundingCoherence[hDirAC->dirac_read_idx][i]; + surCohEner = hDirAC->h_output_synthesis_psd_state.diffuse_power_factor[i] * hDirAC->surroundingCoherence[hDirAC->dirac_read_idx][i]; #endif hDirAC->h_output_synthesis_psd_state.diffuse_power_factor[i] -= surCohEner; hDirAC->h_output_synthesis_psd_state.direct_power_factor[i] += surCohEner; @@ -2693,9 +2770,13 @@ void ivas_dirac_dec_render_sf( { ivas_dirac_dec_compute_gain_factors( hDirAC->num_freq_bands, #ifdef JBM_TSM_ON_TCS +#ifdef MASA_PARAMBIN_SF_MAP + hDirAC->diffuseness_vector[md_idx], +#else diffuseness_vector[0], +#endif #else - hDirAC->diffuseness_vector[hDirAC->dirac_read_idx], + hDirAC->diffuseness_vector[hDirAC->dirac_read_idx], #endif hDirAC->h_output_synthesis_psd_params.max_band_decorr, hDirAC->h_output_synthesis_psd_state.direct_power_factor, @@ -2708,7 +2789,7 @@ void ivas_dirac_dec_render_sf( #ifdef JBM_TSM_ON_TCS surCohRatio[i] = hDirAC->surroundingCoherence[md_idx][i]; #else - surCohRatio[i] = hDirAC->surroundingCoherence[hDirAC->dirac_read_idx][i]; + surCohRatio[i] = hDirAC->surroundingCoherence[hDirAC->dirac_read_idx][i]; #endif } } @@ -2746,7 +2827,7 @@ void ivas_dirac_dec_render_sf( 0 ); } } -#endif + #ifdef JBM_TSM_ON_TCS for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) @@ -2816,7 +2897,11 @@ void ivas_dirac_dec_render_sf( Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS - 1], Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS - 1], slot_idx, #ifdef JBM_TSM_ON_TCS - hDirAC->render_to_md_slot_map[index_slot], +#ifdef MASA_PARAMBIN_SF_MAP + hDirAC->render_to_md_map[subframe_idx], +#else + hDirAC->render_to_md_map[index_slot], +#endif #else subframe_idx, #endif @@ -3076,8 +3161,7 @@ void ivas_dirac_dec_render_sf( p_Rmat, st_ivas->hVBAPdata, hDirAC->hOutSetup, - nchan_transport, - index_slot ); + nchan_transport ); } else { @@ -3087,8 +3171,7 @@ void ivas_dirac_dec_render_sf( 0, st_ivas->hVBAPdata, hDirAC->hOutSetup, - nchan_transport, - index_slot ); + nchan_transport ); } #else if ( st_ivas->hDecoderConfig->Opt_Headrotation && st_ivas->hHeadTrackData->shd_rot_max_order > 0 ) @@ -3098,15 +3181,19 @@ void ivas_dirac_dec_render_sf( azimuth[slot_idx], elevation[slot_idx], diffuseness_vector[slot_idx], +#ifndef MASA_PARAMBIN_SF_MAP coherence_flag, +#endif hDirAC, +#ifndef MASA_PARAMBIN_SF_MAP st_ivas->hMasa, +#endif st_ivas->hHeadTrackData->shd_rot_max_order, p_Rmat, st_ivas->hVBAPdata, hDirAC->hOutSetup, nchan_transport, - hDirAC->render_to_md_slot_map[index_slot] ); + hDirAC->render_to_md_map[index_slot] ); } else { @@ -3115,15 +3202,19 @@ void ivas_dirac_dec_render_sf( azimuth[slot_idx], elevation[slot_idx], diffuseness_vector[slot_idx], +#ifndef MASA_PARAMBIN_SF_MAP coherence_flag, +#endif hDirAC, +#ifndef MASA_PARAMBIN_SF_MAP st_ivas->hMasa, +#endif 0, 0, st_ivas->hVBAPdata, hDirAC->hOutSetup, nchan_transport, - hDirAC->render_to_md_slot_map[index_slot] ); + hDirAC->render_to_md_map[index_slot] ); } #endif @@ -3178,12 +3269,13 @@ void ivas_dirac_dec_render_sf( num_freq_bands = hDirAC->band_grouping[hDirAC->hConfig->enc_param_start_band]; for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) { - mvs2s( azimuth[slot_idx], hDirAC->azimuth[hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]], num_freq_bands ); - mvs2s( elevation[slot_idx], hDirAC->elevation[hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]], num_freq_bands ); - mvr2r( diffuseness_vector[slot_idx], hDirAC->diffuseness_vector[hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]], num_freq_bands ); + mvs2s( azimuth[slot_idx], hDirAC->azimuth[hDirAC->render_to_md_map[slot_idx + slot_idx_start]], num_freq_bands ); + mvs2s( elevation[slot_idx], hDirAC->elevation[hDirAC->render_to_md_map[slot_idx + slot_idx_start]], num_freq_bands ); + mvr2r( diffuseness_vector[slot_idx], hDirAC->diffuseness_vector[hDirAC->render_to_md_map[slot_idx + slot_idx_start]], num_freq_bands ); } } /* get the correct md index for the direction smoothing, it is always the first slot of the next subframe*/ +#ifdef MASA_PARAMBIN_SF_MAP if ( slot_idx_start + hDirAC->subframe_nbslots[subframe_idx] == hDirAC->num_slots ) { /* we are at the end, get the next one using the normal dirac read idx...*/ @@ -3198,8 +3290,33 @@ void ivas_dirac_dec_render_sf( } else { - diff_md_idx = hDirAC->render_to_md_slot_map[slot_idx_start + hDirAC->subframe_nbslots[subframe_idx]]; + if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) + { + diff_md_idx = hDirAC->render_to_md_map[slot_idx_start + hDirAC->subframe_nbslots[subframe_idx]]; + } + else + { + diff_md_idx = hDirAC->render_to_md_map[subframe_idx + 1]; + } + } +#else + if ( slot_idx_start + hDirAC->subframe_nbslots[subframe_idx] == hDirAC->num_slots ) + { + /* we are at the end, get the next one using the normal dirac read idx...*/ + if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) + { + diff_md_idx = ( hDirAC->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % hDirAC->dirac_md_buffer_length; + } + else + { + diff_md_idx = ( hDirAC->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % hDirAC->dirac_md_buffer_length; + } } + else + { + diff_md_idx = hDirAC->render_to_md_map[slot_idx_start + hDirAC->subframe_nbslots[subframe_idx]]; + } +#endif #endif ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( Cldfb_RealBuffer, diff --git a/lib_dec/ivas_dirac_output_synthesis_dec.c b/lib_dec/ivas_dirac_output_synthesis_dec.c index 8271749e21..dd1aef168f 100644 --- a/lib_dec/ivas_dirac_output_synthesis_dec.c +++ b/lib_dec/ivas_dirac_output_synthesis_dec.c @@ -529,11 +529,15 @@ void ivas_dirac_dec_output_synthesis_process_slot( const int16_t *azimuth, const int16_t *elevation, const float *diffuseness, +#ifndef MASA_PARAMBIN_SF_MAP const uint16_t coherence_flag, +#endif #endif DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */ #ifdef JBM_TSM_ON_TCS +#ifndef MASA_PARAMBIN_SF_MAP MASA_DECODER_HANDLE hMasa, +#endif const int16_t sh_rot_max_order, #endif const float *p_Rmat, /* i : rotation matrix */ @@ -554,7 +558,7 @@ void ivas_dirac_dec_output_synthesis_process_slot( #ifndef JBM_TSM_ON_TCS const float *diffuseness; #endif -#ifdef JBM_TSM_ON_TCS +#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) float dirEne; float surCohEner; float surCohRatio[CLDFB_NO_CHANNELS_MAX]; @@ -586,20 +590,17 @@ void ivas_dirac_dec_output_synthesis_process_slot( num_channels_dir = hOutSetup.nchan_out_woLFE; } -#if defined( JBM_DIRAC_DEBUG_BE ) || !defined( JBM_TSM_ON_TCS ) -#ifdef JBM_DIRAC_DEBUG_BE + +#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) if ( hDirAC->hConfig->dec_param_estim == TRUE || hDirAC->voip_active == 1 ) #else if ( hDirAC->hConfig->dec_param_estim == TRUE ) -#endif #endif { -#ifdef JBM_TSM_ON_TCS -#ifdef JBM_DIRAC_DEBUG_BE +#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) if ( hDirAC->voip_active == 1 ) { -#endif if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { ivas_dirac_dec_compute_gain_factors( num_freq_bands, @@ -657,19 +658,26 @@ void ivas_dirac_dec_output_synthesis_process_slot( set_zero( surCohRatio, hDirAC->num_freq_bands ); } } -#ifdef JBM_DIRAC_DEBUG_BE } #endif -#endif + /* compute direct responses */ #ifdef JBM_TSM_ON_TCS ivas_dirac_dec_compute_directional_responses( hDirAC, hVBAPdata, +#ifdef MASA_PARAMBIN_SF_MAP + NULL, +#else hMasa, +#endif azimuth, elevation, index_slot, +#ifdef MASA_PARAMBIN_SF_MAP + NULL, +#else coherence_flag ? surCohRatio : NULL, +#endif sh_rot_max_order, p_Rmat ); #else @@ -683,11 +691,9 @@ void ivas_dirac_dec_output_synthesis_process_slot( if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { -#if !defined( JBM_TSM_ON_TCS ) || defined( JBM_DIRAC_DEBUG_BE ) -#ifdef JBM_DIRAC_DEBUG_BE +#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) if ( hDirAC->voip_active == 0 ) { - #endif ivas_dirac_dec_compute_gain_factors( num_freq_bands, diffuseness, @@ -704,13 +710,13 @@ void ivas_dirac_dec_output_synthesis_process_slot( 0.25f, h_dirac_output_synthesis_state->diffuse_power_factor, num_freq_bands ); -#ifdef JBM_DIRAC_DEBUG_BE +#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) } -#endif #endif + /*Direct gain*/ -#ifdef JBM_TSM_ON_TCS +#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) if ( hDirAC->hConfig->dec_param_estim == TRUE ) { #endif @@ -750,7 +756,7 @@ void ivas_dirac_dec_output_synthesis_process_slot( } } } -#ifdef JBM_TSM_ON_TCS +#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) } else { @@ -808,25 +814,22 @@ void ivas_dirac_dec_output_synthesis_process_slot( return; } -#if !defined( JBM_TSM_ON_TCS ) || defined( JBM_DIRAC_DEBUG_BE ) else { /* compute reference and diffuse power factor for this frame */ -#ifdef JBM_DIRAC_DEBUG_BE +#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) if ( hDirAC->voip_active == 0 ) { - #endif ivas_dirac_dec_compute_power_factors( num_freq_bands, diffuseness, h_dirac_output_synthesis_params->max_band_decorr, h_dirac_output_synthesis_state->direct_power_factor, h_dirac_output_synthesis_state->diffuse_power_factor ); -#ifdef JBM_DIRAC_DEBUG_BE +#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) } #endif } -#endif } diff_start_band = 0; @@ -845,12 +848,10 @@ void ivas_dirac_dec_output_synthesis_process_slot( } /* process other PSDs only slot wise for 4 transport channels */ -#if !defined( JBM_TSM_ON_TCS ) || defined( JBM_DIRAC_DEBUG_BE ) -#if defined( JBM_DIRAC_DEBUG_BE ) +#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) if ( hDirAC->hConfig->dec_param_estim == TRUE || hDirAC->voip_active == 1 ) #else if ( hDirAC->hConfig->dec_param_estim == TRUE ) -#endif #endif { computeTargetPSDs_direct( num_channels_dir, num_freq_bands, h_dirac_output_synthesis_state->direct_power_factor, reference_power, h_dirac_output_synthesis_state->direct_responses, h_dirac_output_synthesis_state->direct_responses_square, h_dirac_output_synthesis_state->cy_auto_dir_smooth, h_dirac_output_synthesis_state->cy_cross_dir_smooth ); @@ -912,8 +913,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( * comput target Gains *-----------------------------------------------------------------*/ -#if !defined( JBM_TSM_ON_TCS ) || defined( JBM_DIRAC_DEBUG_BE ) -#ifdef JBM_DIRAC_DEBUG_BE +#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) if ( hDirAC->voip_active == 0 && hDirAC->hConfig->dec_param_estim == FALSE ) #else if ( hDirAC->hConfig->dec_param_estim == FALSE ) @@ -955,7 +955,6 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( v_multc( h_dirac_output_synthesis_state.diffuse_power_factor, hDirAC->diffuse_response_function[ch_idx], &h_dirac_output_synthesis_state.cy_auto_diff_smooth[ch_idx * num_freq_bands_diff], num_freq_bands_diff ); } } -#endif /*-----------------------------------------------------------------* * compute gains @@ -1169,9 +1168,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( float qualityBasedSmFactor ) { int16_t buf_idx, num_freq_bands; -#if !defined( JBM_TSM_ON_TCS ) || defined( JBM_DIRAC_DEBUG_BE ) int16_t diff_start_band; -#endif int16_t k, l; int16_t nchan_out_woLFE; float *p_power_smooth_prev, *p_power_diff_smooth_prev; @@ -1192,9 +1189,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( float subtract_target_ratio; float subtract_target_ratio_db; float a, b; -#if !defined( JBM_TSM_ON_TCS ) || defined( JBM_DIRAC_DEBUG_BE ) uint16_t nchan_target_psds; -#endif float alpha[CLDFB_NO_CHANNELS_MAX]; float *alpha_synthesis; float *alpha_synthesis_fast; @@ -1215,8 +1210,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( /*-----------------------------------------------------------------* * compute target PSDs *-----------------------------------------------------------------*/ -#if !defined( JBM_TSM_ON_TCS ) || defined( JBM_DIRAC_DEBUG_BE ) -#ifdef JBM_DIRAC_DEBUG_BE +#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) if ( hDirAC->hConfig->enc_param_start_band == 0 && hDirAC->voip_active == 0 ) #else if ( hDirAC->hConfig->enc_param_start_band == 0 ) @@ -1247,7 +1241,6 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( h_dirac_output_synthesis_state->diffuse_responses_square, h_dirac_output_synthesis_state->cy_auto_diff_smooth ); } -#endif /*-----------------------------------------------------------------* * compute variables for stereo transport signal type detection *-----------------------------------------------------------------*/ @@ -1503,7 +1496,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( *-----------------------------------------------------------------*/ /* store estimates for next synthesis block */ -#ifdef JBM_TSM_ON_TCS +#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) if ( hDirAC->voip_active == 1 ) { mvr2r( gains_dir, h_dirac_output_synthesis_state->gains_dir_prev, num_freq_bands * hDirAC->num_outputs_dir ); @@ -1538,7 +1531,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( set_zero( h_dirac_output_synthesis_state->cy_auto_dir_smooth, num_freq_bands * nchan_out_woLFE ); set_zero( h_dirac_output_synthesis_state->cy_cross_dir_smooth, num_freq_bands * nchan_out_woLFE ); set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth, num_freq_bands * nchan_out_woLFE ); -#ifdef JBM_TSM_ON_TCS +#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) } #endif pop_wmops(); @@ -1843,9 +1836,9 @@ void ivas_dirac_dec_compute_directional_responses( directRatio[0] = hDirAC->energy_ratio1[md_idx][k] / totalDirect; directRatio[1] = hDirAC->energy_ratio2[md_idx][k] / totalDirect; #else - totalDirect = hDirAC->energy_ratio1[hDirAC->dirac_read_idx]][k] + hDirAC->energy_ratio2[hDirAC->dirac_read_idx]][k] + EPSILON; - directRatio[0] = hDirAC->energy_ratio1[hDirAC->dirac_read_idx]][k] / totalDirect; - directRatio[1] = hDirAC->energy_ratio2[hDirAC->dirac_read_idx]][k] / totalDirect; + totalDirect = hDirAC->energy_ratio1[hDirAC->dirac_read_idx][k] + hDirAC->energy_ratio2[hDirAC->dirac_read_idx][k] + EPSILON; + directRatio[0] = hDirAC->energy_ratio1[hDirAC->dirac_read_idx][k] / totalDirect; + directRatio[1] = hDirAC->energy_ratio2[hDirAC->dirac_read_idx][k] / totalDirect; #endif for ( l = 0; l < num_channels_dir; l++ ) { @@ -1897,7 +1890,7 @@ void ivas_dirac_dec_compute_directional_responses( #ifdef JBM_TSM_ON_TCS spreadCoherencePanningVbap( azimuth[k], elevation[k], hDirAC->spreadCoherence[md_idx][k], direct_response_ls, num_channels_dir, hVBAPdata ); #else - spreadCoherencePanningVbap( azimuth[k], elevation[k], hDirAC->spreadCoherence[hDirAC->dirac_read_idx]][k], direct_response_ls, num_channels_dir, hVBAPdata ); + spreadCoherencePanningVbap( azimuth[k], elevation[k], hDirAC->spreadCoherence[hDirAC->dirac_read_idx][k], direct_response_ls, num_channels_dir, hVBAPdata ); #endif normalizePanningGains( direct_response_ls, num_channels_dir ); @@ -1907,7 +1900,7 @@ void ivas_dirac_dec_compute_directional_responses( #ifdef JBM_TSM_ON_TCS spreadCoherencePanningVbap( azimuth2[k], elevation2[k], hDirAC->spreadCoherence2[md_idx][k], direct_response_dir2, num_channels_dir, hVBAPdata ); #else - spreadCoherencePanningVbap( azimuth2[k], elevation2[k], hDirAC->spreadCoherence2[hDirAC->dirac_read_idx]][k], direct_response_dir2, num_channels_dir, hVBAPdata ); + spreadCoherencePanningVbap( azimuth2[k], elevation2[k], hDirAC->spreadCoherence2[hDirAC->dirac_read_idx][k], direct_response_dir2, num_channels_dir, hVBAPdata ); #endif normalizePanningGains( direct_response_dir2, num_channels_dir ); @@ -1917,9 +1910,9 @@ void ivas_dirac_dec_compute_directional_responses( directRatio[0] = hDirAC->energy_ratio1[md_idx][k] / totalDirect; directRatio[1] = hDirAC->energy_ratio2[md_idx][k] / totalDirect; #else - totalDirect = hDirAC->energy_ratio1[hDirAC->dirac_read_idx]][k] + hDirAC->energy_ratio2[hDirAC->dirac_read_idx]][k] + EPSILON; - directRatio[0] = hDirAC->energy_ratio1[hDirAC->dirac_read_idx]][k] / totalDirect; - directRatio[1] = hDirAC->energy_ratio2[hDirAC->dirac_read_idx]][k] / totalDirect; + totalDirect = hDirAC->energy_ratio1[hDirAC->dirac_read_idx][k] + hDirAC->energy_ratio2[hDirAC->dirac_read_idx][k] + EPSILON; + directRatio[0] = hDirAC->energy_ratio1[hDirAC->dirac_read_idx][k] / totalDirect; + directRatio[1] = hDirAC->energy_ratio2[hDirAC->dirac_read_idx][k] / totalDirect; #endif for ( l = 0; l < num_channels_dir; l++ ) { diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index a3b7ddd6e9..a65369e2c4 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -1253,6 +1253,7 @@ ivas_error ivas_masa_dec_reconfigure( ivas_masa_set_elements( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &tmp, &tmp, &tmp ); +#ifdef JBM_TSM_ON_TCS if ( st_ivas->hDecoderConfig->voip_active == 1 && st_ivas->renderer_type != RENDERER_DISABLE ) { int16_t tc_nchan_to_allocate; @@ -1272,7 +1273,7 @@ ivas_error ivas_masa_dec_reconfigure( } } } - +#endif return error; } @@ -1285,11 +1286,19 @@ ivas_error ivas_masa_dec_reconfigure( #ifdef JBM_TSM_ON_TCS void ivas_spar_param_to_masa_param_mapping_sf( Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ +#ifdef MASA_PARAMBIN_SF_MAP + int16_t azimuth[CLDFB_NO_CHANNELS_MAX], + int16_t elevation[CLDFB_NO_CHANNELS_MAX], + float energy_ratio1[CLDFB_NO_CHANNELS_MAX], + float spreadCoherence[CLDFB_NO_CHANNELS_MAX], + float surroundingCoherence[CLDFB_NO_CHANNELS_MAX], +#else int16_t azimuth[][CLDFB_NO_CHANNELS_MAX], int16_t elevation[][CLDFB_NO_CHANNELS_MAX], float energy_ratio1[][CLDFB_NO_CHANNELS_MAX], float spreadCoherence[][CLDFB_NO_CHANNELS_MAX], float surroundingCoherence[][CLDFB_NO_CHANNELS_MAX], +#endif float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */ float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /* i : Input audio in CLDFB domain, imag */ ) @@ -1342,12 +1351,13 @@ void ivas_spar_param_to_masa_param_mapping_sf( } } + slot_fac = 1.0f / (float) hSpar->subframe_nbslots[subframe_idx]; /* Delay the SPAR mixing matrices to have them synced with the audio */ for ( slot_idx = 0; slot_idx < hSpar->subframe_nbslots[subframe_idx]; slot_idx++ ) { - sf = hSpar->render_to_md_slot_map[slot_idx + slot_idx_start] / JBM_CLDFB_SLOTS_IN_SUBFRAME; + sf = hSpar->render_to_md_map[slot_idx + slot_idx_start] / JBM_CLDFB_SLOTS_IN_SUBFRAME; if ( sf < SPAR_META_DELAY_SUBFRAMES ) { mixer_mat_index = sf + MAX_PARAM_SPATIAL_SUBFRAMES - SPAR_META_DELAY_SUBFRAMES + 1; @@ -1469,13 +1479,21 @@ void ivas_spar_param_to_masa_param_mapping_sf( ratio = I / fmaxf( 1e-12f, E ); /* Energy ratio */ ratio = fmaxf( 0.0f, fminf( 1.0f, ratio ) ); +#ifdef MASA_PARAMBIN_SF_MAP + azimuth[bin] = (int16_t) roundf( azi / PI_OVER_180 ); + elevation[bin] = (int16_t) roundf( ele / PI_OVER_180 ); + energy_ratio1[bin] = ratio; + + spreadCoherence[bin] = 0.0f; + surroundingCoherence[bin] = 0.0f; +#else azimuth[0][bin] = (int16_t) roundf( azi / PI_OVER_180 ); elevation[0][bin] = (int16_t) roundf( ele / PI_OVER_180 ); energy_ratio1[0][bin] = ratio; spreadCoherence[0][bin] = 0.0f; surroundingCoherence[0][bin] = 0.0f; - +#endif /* Determine directional distribution of the indirect audio based on the SPAR mixing matrices (and the transport audio signals when 2 TC) */ if ( hDiffuseDist != NULL ) { @@ -1515,6 +1533,7 @@ void ivas_spar_param_to_masa_param_mapping_sf( } } +#ifndef MASA_PARAMBIN_SF_MAP for ( slot_idx = 1; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) { mvs2s( azimuth[0], azimuth[slot_idx], nBins ); @@ -1523,7 +1542,7 @@ void ivas_spar_param_to_masa_param_mapping_sf( mvr2r( surroundingCoherence[0], surroundingCoherence[slot_idx], nBins ); mvr2r( energy_ratio1[0], energy_ratio1[slot_idx], nBins ); } - +#endif return; } diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 37c8f181aa..e4e6480254 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -1398,7 +1398,7 @@ void ivas_param_mc_dec_read_BS( hMetadataPMC->attackIndex = 0; #ifndef JBM_TSM_ON_TCS #ifdef FIX_431_PARAMMC_PLC_INTERPOLATOR - param_mc_compute_interpolator( hMetadataPMC->bAttackPresent, hMetadataPMC->attackIndex, PARAM_MC_MAX_NSLOTS, hParamMC->h_output_synthesis_params.interpolator ); + ivas_param_mc_dec_compute_interpolator( hMetadataPMC->bAttackPresent, hMetadataPMC->attackIndex, PARAM_MC_MAX_NSLOTS, hParamMC->h_output_synthesis_params.interpolator ); #endif #endif } @@ -1477,7 +1477,7 @@ void ivas_param_mc_dec_digest_tc( ivas_jbm_dec_get_adapted_subframes( nCldfbSlots, hParamMC->subframe_nbslots, &hParamMC->nb_subframes ); ivas_param_mc_dec_compute_interpolator( hParamMC->hMetadataPMC->bAttackPresent, hParamMC->hMetadataPMC->attackIndex, nCldfbSlots, hParamMC->h_output_synthesis_params.interpolator ); - + for ( param_band_idx = 0; param_band_idx < PARAM_MC_MAX_PARAMETER_BANDS; param_band_idx++ ) { set_zero( cx[param_band_idx], PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index c221769b36..701ff8892d 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -184,10 +184,10 @@ ivas_error ivas_spar_dec_open( /* init render timeslot mapping */ { int16_t map_idx; - set_s( hSpar->render_to_md_slot_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME ); + set_s( hSpar->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME ); for ( map_idx = 0; map_idx < DEFAULT_JBM_CLDFB_TIMESLOTS; map_idx++ ) { - hSpar->render_to_md_slot_map[map_idx] = map_idx; + hSpar->render_to_md_map[map_idx] = map_idx; } } /* allocate transport channels*/ @@ -1091,9 +1091,9 @@ void ivas_spar_dec_set_render_map( hSpar->num_slots = nCldfbTs; hSpar->slots_rendered = 0; hSpar->subframes_rendered = 0; - set_s( hSpar->render_to_md_slot_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME ); + set_s( hSpar->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME ); ivas_jbm_dec_get_adapted_subframes( nCldfbTs, hSpar->subframe_nbslots, &hSpar->nb_subframes ); - ivas_jbm_dec_get_md_map( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbTs, 1, 0, DEFAULT_JBM_CLDFB_TIMESLOTS, hSpar->render_to_md_slot_map ); + ivas_jbm_dec_get_md_map( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbTs, 1, 0, DEFAULT_JBM_CLDFB_TIMESLOTS, hSpar->render_to_md_map ); return; } @@ -1527,7 +1527,7 @@ void ivas_spar_dec_upmixer( #endif { #ifdef JBM_TSM_ON_TCS - md_idx = hSpar->render_to_md_slot_map[ts + slot_idx_start]; + md_idx = hSpar->render_to_md_map[ts + slot_idx_start]; ivas_spar_get_parameters( hSpar, hDecoderConfig, md_idx, numch_out, numch_in, num_spar_bands, mixer_mat ); #else /* determine SPAR parameters for this time slots */ @@ -1594,7 +1594,7 @@ void ivas_spar_dec_upmixer( } } #ifdef JBM_TSM_ON_TCS - if ( ( ( slot_idx_start + ts + 1 ) == hSpar->num_slots ) || ( ( md_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME ) != ( hSpar->render_to_md_slot_map[ts + slot_idx_start + 1] / JBM_CLDFB_SLOTS_IN_SUBFRAME ) ) ) + if ( ( ( slot_idx_start + ts + 1 ) == hSpar->num_slots ) || ( ( md_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME ) != ( hSpar->render_to_md_map[ts + slot_idx_start + 1] / JBM_CLDFB_SLOTS_IN_SUBFRAME ) ) ) { /* we have crossed an unadapted parameter sf border, update previous mixing matrices */ int16_t md_sf = md_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME; diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 4fa4f9ad43..af2edd614d 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -638,8 +638,8 @@ typedef struct ivas_dirac_dec_data_structure int16_t subframes_rendered; int16_t slots_rendered; int16_t num_slots; - int16_t render_to_md_slot_map[MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME]; -#ifdef JBM_DIRAC_DEBUG_BE + int16_t render_to_md_map[MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME]; +#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) int16_t voip_active; #endif #else @@ -891,7 +891,7 @@ typedef struct ivas_spar_dec_lib_t #endif #ifdef JBM_TSM_ON_TCS int16_t subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; - int16_t render_to_md_slot_map[MAX_JBM_CLDFB_TIMESLOTS]; + int16_t render_to_md_map[MAX_JBM_CLDFB_TIMESLOTS]; int16_t nb_subframes; int16_t subframes_rendered; int16_t slots_rendered; diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 9429c1bd89..da8b5049e5 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -653,6 +653,8 @@ ivas_error IVAS_DEC_EnableVoIP( { return IVAS_ERR_INIT_ERROR; } + /* we instantly need a new frame */ + hIvasDec->hVoIP->needNewFrame = true; } #else if ( apa_init( &hIvasDec->hVoIP->hTimeScaler, @@ -2041,6 +2043,16 @@ ivas_error IVAS_DEC_VoIP_GetSamples( { return IVAS_ERR_UNKNOWN; } +#ifdef VARIABLE_SPEED_DECODING + if ( hVoIP->mode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED ) + { + int16_t nSamplesAvailable = pcmdsp_fifo_nReadableSamplesPerChannel( hVoIP->hFifoAfterTimeScaler ); + if ( nSamplesAvailable < nSamplesPerChannel ) + { + hVoIP->needNewFrame = true; + } + } +#endif #endif #ifdef JBM_TSM_ON_TCS @@ -2065,7 +2077,7 @@ ivas_error IVAS_DEC_VoIP_GetSamples( st_ivas->noClipping += #endif syn_output( hVoIP->apaExecBuffer, nTimeScalerOutSamples, (int16_t *) hVoIP->apaExecBuffer ); -#endif + if ( pcmdsp_fifo_write( hVoIP->hFifoOut, (uint8_t *) hVoIP->apaExecBuffer, nSamplesTcsScaled ) != 0 ) { return IVAS_ERR_UNKNOWN; @@ -2073,6 +2085,7 @@ ivas_error IVAS_DEC_VoIP_GetSamples( nSamplesRendered = nSamplesTcsScaled; } } +#endif #ifdef SUPPORT_JBM_TRACEFILE /* jbmWriterFn and jbmWriter may be NULL if tracefile writing was not requested on CLI */ if ( jbmWriterFn != NULL && jbmWriter != NULL ) @@ -2147,7 +2160,7 @@ ivas_error IVAS_DEC_VoIP_GetSamples( { if ( pcmdsp_fifo_read( hVoIP->hFifoOut, nSamplesPerChannel, (uint8_t *) pcmBuf ) != 0 ) #else -if ( pcmdsp_fifo_read( hVoIP->hFifoAfterTimeScaler, nSamplesPerChannel, (uint8_t *) pcmBuf ) != 0 ) + if ( pcmdsp_fifo_read( hVoIP->hFifoAfterTimeScaler, nSamplesPerChannel, (uint8_t *) pcmBuf ) != 0 ) #endif { return IVAS_ERR_UNKNOWN; @@ -2161,6 +2174,15 @@ if ( pcmdsp_fifo_read( hVoIP->hFifoAfterTimeScaler, nSamplesPerChannel, (uint8_t *sampleAvailableNext = hVoIP->nSamplesAvailableNext; #else *sampleAvailableNext = max( 0, pcmdsp_fifo_nReadableSamplesPerChannel( hVoIP->hFifoAfterTimeScaler ) ); +#ifdef VARIABLE_SPEED_DECODING + if ( hVoIP->mode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED ) + { + if ( *sampleAvailableNext < nSamplesPerChannel ) + { + hVoIP->needNewFrame = true; + } + } +#endif #endif #endif @@ -2184,9 +2206,11 @@ ivas_error IVAS_DEC_VoIP_Flush( { ivas_error error; IVAS_DEC_VOIP *hVoIP; +#ifdef JBM_TSM_ON_TCS int16_t rendererPcmBuf[( MAX_OUTPUT_CHANNELS * L_FRAME_MAX * APA_MAX_SCALE ) / 100]; uint16_t nSamplesToRender; uint16_t nSamplesFlushedLocal; +#endif error = IVAS_ERR_OK; hVoIP = hIvasDec->hVoIP; diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index f8945d50d3..583aba3427 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -103,7 +103,11 @@ static void ivas_dirac_dec_binaural_process_output_sf( Decoder_Struct *st_ivas, static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked_sf( HEAD_TRACK_DATA_HANDLE hHeadTrackData, float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const uint8_t slotEnd, const uint8_t nBins, float Rmat[3][3] ); +#ifdef MASA_PARAMBIN_SF_MAP +static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_sf( Decoder_Struct *st_ivas, float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], int16_t azimuth[CLDFB_NO_CHANNELS_MAX], int16_t elevation[CLDFB_NO_CHANNELS_MAX], float energy_ratio1[CLDFB_NO_CHANNELS_MAX], float spreadCoherence[CLDFB_NO_CHANNELS_MAX], float surroundingCoherence[CLDFB_NO_CHANNELS_MAX], float Rmat[3][3] ); +#else static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_sf( Decoder_Struct *st_ivas, float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], int16_t azimuth[][CLDFB_NO_CHANNELS_MAX], int16_t elevation[][CLDFB_NO_CHANNELS_MAX], float energy_ratio1[][CLDFB_NO_CHANNELS_MAX], float spreadCoherence[][CLDFB_NO_CHANNELS_MAX], float surroundingCoherence[][CLDFB_NO_CHANNELS_MAX], float Rmat[3][3] ); +#endif static void ivas_dirac_dec_binaural_internal_sf( Decoder_Struct *st_ivas, float *output_f[], const int16_t nchan_transport ); @@ -590,13 +594,24 @@ static void ivas_dirac_dec_binaural_internal_sf( float Cldfb_RealBuffer_in[2 * BINAURAL_CHANNELS][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_in[2 * BINAURAL_CHANNELS][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; /* local copies of azi, ele, diffuseness */ +#ifdef MASA_PARAMBIN_SF_MAP + int16_t azimuth[CLDFB_NO_CHANNELS_MAX]; + int16_t elevation[CLDFB_NO_CHANNELS_MAX]; + float spreadCoherence[CLDFB_NO_CHANNELS_MAX]; + float surroundingCoherence[CLDFB_NO_CHANNELS_MAX]; + float energy_ratio1[CLDFB_NO_CHANNELS_MAX]; +#else int16_t azimuth[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; int16_t elevation[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; float spreadCoherence[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; float surroundingCoherence[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; float energy_ratio1[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; +#endif float Rmat[3][3]; - uint16_t slot_idx, slot_idx_start, subframe_idx; +#ifndef MASA_PARAMBIN_SF_MAP + uint16_t slot_idx; +#endif + uint16_t subframe_idx, slot_idx_start; int16_t max_band_decorr; DIFFUSE_DISTRIBUTION_DATA diffuseDistData; @@ -627,15 +642,22 @@ static void ivas_dirac_dec_binaural_internal_sf( subframe_idx = hDirAC->subframes_rendered; /* copy parameters into local buffers*/ +#ifdef MASA_PARAMBIN_SF_MAP + mvs2s( hDirAC->azimuth[hDirAC->render_to_md_map[subframe_idx]], azimuth, hDirAC->num_freq_bands ); + mvs2s( hDirAC->elevation[hDirAC->render_to_md_map[subframe_idx]], elevation, hDirAC->num_freq_bands ); + mvr2r( hDirAC->spreadCoherence[hDirAC->render_to_md_map[subframe_idx]], spreadCoherence, hDirAC->num_freq_bands ); + mvr2r( hDirAC->surroundingCoherence[hDirAC->render_to_md_map[subframe_idx]], surroundingCoherence, hDirAC->num_freq_bands ); + mvr2r( hDirAC->energy_ratio1[hDirAC->render_to_md_map[subframe_idx]], energy_ratio1, hDirAC->num_freq_bands ); +#else for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) { - mvs2s( hDirAC->azimuth[hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]], azimuth[slot_idx], hDirAC->num_freq_bands ); - mvs2s( hDirAC->elevation[hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]], elevation[slot_idx], hDirAC->num_freq_bands ); - mvr2r( hDirAC->spreadCoherence[hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]], spreadCoherence[slot_idx], hDirAC->num_freq_bands ); - mvr2r( hDirAC->surroundingCoherence[hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]], surroundingCoherence[slot_idx], hDirAC->num_freq_bands ); - mvr2r( hDirAC->energy_ratio1[hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]], energy_ratio1[slot_idx], hDirAC->num_freq_bands ); + mvs2s( hDirAC->azimuth[hDirAC->render_to_md_map[slot_idx + slot_idx_start]], azimuth[slot_idx], hDirAC->num_freq_bands ); + mvs2s( hDirAC->elevation[hDirAC->render_to_md_map[slot_idx + slot_idx_start]], elevation[slot_idx], hDirAC->num_freq_bands ); + mvr2r( hDirAC->spreadCoherence[hDirAC->render_to_md_map[slot_idx + slot_idx_start]], spreadCoherence[slot_idx], hDirAC->num_freq_bands ); + mvr2r( hDirAC->surroundingCoherence[hDirAC->render_to_md_map[slot_idx + slot_idx_start]], surroundingCoherence[slot_idx], hDirAC->num_freq_bands ); + mvr2r( hDirAC->energy_ratio1[hDirAC->render_to_md_map[slot_idx + slot_idx_start]], energy_ratio1[slot_idx], hDirAC->num_freq_bands ); } - +#endif /* CLDFB Analysis of input */ for ( slot = 0; slot < hDirAC->subframe_nbslots[hDirAC->subframes_rendered]; slot++ ) { @@ -1082,7 +1104,411 @@ static void ivas_dirac_dec_decorrelate_slot_sf( return; } +#ifdef MASA_PARAMBIN_SF_MAP +static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_sf( + Decoder_Struct *st_ivas, + float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + int16_t azimuth[CLDFB_NO_CHANNELS_MAX], + int16_t elevation[CLDFB_NO_CHANNELS_MAX], + float energy_ratio1[CLDFB_NO_CHANNELS_MAX], + float spreadCoherence[CLDFB_NO_CHANNELS_MAX], + float surroundingCoherence[CLDFB_NO_CHANNELS_MAX], + float Rmat[3][3] ) +{ + uint8_t ch, slot, bin; + uint8_t separateCenterChannelRendering; + int16_t nBins, idx, subframe; + float frameMeanDiffusenessEneWeight[CLDFB_NO_CHANNELS_MAX]; + DIRAC_DEC_HANDLE hDirAC; + DIRAC_DEC_BIN_HANDLE h; + float IIReneLimiterFactor; + float qualityBasedSmFactor; + float lowBitRateEQ[CLDFB_NO_CHANNELS_MAX]; + uint8_t applyLowBitRateEQ; + float subFrameTotalEne[CLDFB_NO_CHANNELS_MAX]; + int16_t md_idx; + + hDirAC = st_ivas->hDirAC; + h = st_ivas->hDiracDecBin; + separateCenterChannelRendering = st_ivas->hOutSetup.separateChannelEnabled; + nBins = hDirAC->num_freq_bands; /* Actually bins */ + subframe = hDirAC->subframes_rendered; + md_idx = hDirAC->render_to_md_map[hDirAC->subframes_rendered]; + + set_zero( h->ChCrossRe, nBins ); + set_zero( h->ChCrossIm, nBins ); + set_zero( h->ChCrossReOut, nBins ); + set_zero( h->ChCrossImOut, nBins ); + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + set_zero( h->ChEne[ch], nBins ); + set_zero( h->ChEneOut[ch], nBins ); + } + set_zero( h->frameMeanDiffuseness, nBins ); + + set_zero( frameMeanDiffusenessEneWeight, CLDFB_NO_CHANNELS_MAX ); + + /* Determine EQ for low bit rates (13.2 and 16.4 kbps) */ + applyLowBitRateEQ = 0; + if ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MC_FORMAT ) && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE ) + { + applyLowBitRateEQ = 1; + if ( st_ivas->hDecoderConfig->ivas_total_brate == IVAS_16k4 ) + { + for ( bin = 0; bin < LOW_BIT_RATE_BINAURAL_EQ_BINS; bin++ ) + { + lowBitRateEQ[bin + LOW_BIT_RATE_BINAURAL_EQ_OFFSET] = lowBitRateBinauralEQ[bin] * 0.5f + 0.5f; + } + } + else + { + for ( bin = 0; bin < LOW_BIT_RATE_BINAURAL_EQ_BINS; bin++ ) + { + lowBitRateEQ[bin + LOW_BIT_RATE_BINAURAL_EQ_OFFSET] = lowBitRateBinauralEQ[bin]; + } + } + } + /* Formulate input and target covariance matrices combining all subframes */ + set_zero( subFrameTotalEne, CLDFB_NO_CHANNELS_MAX ); + + /* Calculate input covariance matrix */ + for ( slot = 0; slot < (uint8_t) hDirAC->subframe_nbslots[subframe]; slot++ ) + { + for ( bin = 0; bin < nBins; bin++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + float instEne; + + instEne = ( inRe[ch][slot][bin] * inRe[ch][slot][bin] ); + instEne += ( inIm[ch][slot][bin] * inIm[ch][slot][bin] ); + h->ChEne[ch][bin] += instEne; + subFrameTotalEne[bin] += instEne; + } + h->ChCrossRe[bin] += inRe[0][slot][bin] * inRe[1][slot][bin]; + h->ChCrossRe[bin] += inIm[0][slot][bin] * inIm[1][slot][bin]; + h->ChCrossIm[bin] += inRe[0][slot][bin] * inIm[1][slot][bin]; + h->ChCrossIm[bin] -= inIm[0][slot][bin] * inRe[1][slot][bin]; + } + } + + /* Apply EQ at low bit rates */ + if ( applyLowBitRateEQ ) + { + int16_t lastEqBin = LOW_BIT_RATE_BINAURAL_EQ_OFFSET + LOW_BIT_RATE_BINAURAL_EQ_BINS - 1; + + for ( bin = LOW_BIT_RATE_BINAURAL_EQ_OFFSET; bin < lastEqBin; bin++ ) + { + subFrameTotalEne[bin] *= lowBitRateEQ[bin]; + } + for ( ; bin < nBins; bin++ ) + { + subFrameTotalEne[bin] *= lowBitRateEQ[lastEqBin]; + } + } + + if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->nchan_transport == 2 ) + { + float tempRe, tempIm; + + set_zero( subFrameTotalEne, CLDFB_NO_CHANNELS_MAX ); + + for ( slot = 0; slot < (uint8_t) hDirAC->subframe_nbslots[subframe]; slot++ ) + { + for ( bin = 0; bin < nBins; bin++ ) + { + tempRe = inRe[0][slot][bin] + inRe[1][slot][bin]; + tempIm = inIm[0][slot][bin] + inIm[1][slot][bin]; + subFrameTotalEne[bin] += tempRe * tempRe + tempIm * tempIm; + } + } + } + + /* Determine target covariance matrix containing target binaural properties */ + for ( bin = 0; bin < nBins; bin++ ) + { + float diffuseness = 1.0f; /* ratio1 and ratio2 are subtracted from diffuseness further below */ + float surCoh = 0.0f, spreadCoh = 0.0f; /* Default values if spreadSurroundCoherenceApplied == false */ + float diffEne, dirEne, meanEnePerCh; + uint16_t dirIndex; + + /* When BINAURAL_ROOM is not indicated, hBinaural->earlyPartEneCorrection[bin] values are all 1.0f. + * When BINAURAL_ROOM is indicated, the binaural audio output is based on combined use of the + * HRTF data set and a BRIR-based data set. The HRTF data set is spectrally corrected to match + * the early spectrum of the BRIR data, using the spectral correction data in + * hBinaural->earlyPartEneCorrection[bin], based on the BRIR set. */ + meanEnePerCh = h->earlyPartEneCorrection[bin] * subFrameTotalEne[bin] / 2.0f; + + /* Determine direct part target covariance matrix (for 1 or 2 directions) */ + for ( dirIndex = 0; dirIndex < hDirAC->numSimultaneousDirections; dirIndex++ ) + { + int16_t aziDeg, eleDeg; + float lRealp, lImagp, rRealp, rImagp; + float lRealpTmp, lImagpTmp, rRealpTmp, rImagpTmp; + float hrtfEne[BINAURAL_CHANNELS], hrtfCrossRe, hrtfCrossIm, ratio; + + if ( dirIndex == 0 ) /* For first of the two simultaneous directions */ + { + aziDeg = azimuth[bin]; + eleDeg = elevation[bin]; + ratio = energy_ratio1[bin]; + spreadCoh = spreadCoherence[bin]; + } + else /* For second of the two simultaneous directions */ + { + aziDeg = hDirAC->azimuth2[md_idx][bin]; + eleDeg = hDirAC->elevation2[md_idx][bin]; + ratio = hDirAC->energy_ratio2[md_idx][bin]; + spreadCoh = hDirAC->spreadCoherence2[md_idx][bin]; + } + diffuseness -= ratio; /* diffuseness = 1 - ratio1 - ratio2 */ + + if ( separateCenterChannelRendering ) + { + /* In masa + mono rendering mode, the center directions originate from phantom sources, so the + * spread coherence is increased */ + float aziRad, eleRad, doaVectorX, spatialAngleDeg, altSpreadCoh; + + aziRad = (float) aziDeg * PI_OVER_180; + eleRad = (float) eleDeg * PI_OVER_180; + doaVectorX = cosf( aziRad ) * cosf( eleRad ); + spatialAngleDeg = acosf( doaVectorX ) * _180_OVER_PI; + altSpreadCoh = 1.0f - ( spatialAngleDeg / 30.0f ); + spreadCoh = max( spreadCoh, altSpreadCoh ); + } + + getDirectPartGains( bin, aziDeg, eleDeg, &lRealp, &lImagp, &rRealp, &rImagp, h->renderStereoOutputInsteadOfBinaural, Rmat ); + + if ( h->renderStereoOutputInsteadOfBinaural ) + { + /* Synthesizing spread coherence is not needed for stereo loudspeaker output, + * as directional sound is reproduced with two loudspeakers in any case */ + spreadCoh = 0.0f; + } + + if ( spreadCoh > 0.0f ) + { + float centerMul, sidesMul; + float hrtfEneCenter, hrtfEneSides, hrtfEneRealized, eneCorrectionFactor; + float w1, w2, w3, eq; + + hrtfEneCenter = ( lRealp * lRealp ) + ( lImagp * lImagp ) + ( rRealp * rRealp ) + ( rImagp * rImagp ); + + /* Spread coherence is synthesized as coherent sources at 30 degree horizontal spacing. + * The following formulas determine the gains for these sources. + * spreadCoh = 0: Only panning + * spreadCoh = 0.5: Three sources coherent panning (e.g. 30 0 -30 deg azi) + * spreadCoh = 1.0: Two sources coherent panning with gap (as above, but center is silent) */ + if ( spreadCoh < 0.5f ) + { + /* 0.0f < spreadCoh < 0.5f */ + sidesMul = 0.5774f * spreadCoh * 2.0f; /* sqrt(1/3) = 0.5774f */ + centerMul = 1.0f - ( spreadCoh * 2.0f ) + sidesMul; + } + else + { + /* 0.5f <= spreadCoh < 1.0f */ + centerMul = 2.0f - ( 2.0f * spreadCoh ); + sidesMul = inv_sqrt( centerMul + 2.0f ); + centerMul *= sidesMul; + } + + /* Apply the gain for the center source of the three coherent sources */ + lRealp *= centerMul; + lImagp *= centerMul; + rRealp *= centerMul; + rImagp *= centerMul; + + /* Apply the gain for the left source of the three coherent sources */ + getDirectPartGains( bin, aziDeg + 30, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, h->renderStereoOutputInsteadOfBinaural, Rmat ); + + hrtfEneSides = ( lRealpTmp * lRealpTmp ) + ( lImagpTmp * lImagpTmp ) + ( rRealpTmp * rRealpTmp ) + ( rImagpTmp * rImagpTmp ); + lRealp += sidesMul * lRealpTmp; + lImagp += sidesMul * lImagpTmp; + rRealp += sidesMul * rRealpTmp; + rImagp += sidesMul * rImagpTmp; + + /* Apply the gain for the right source of the three coherent sources. + * -30 degrees to 330 wrapping due to internal functions. */ + getDirectPartGains( bin, aziDeg + 330, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, h->renderStereoOutputInsteadOfBinaural, Rmat ); + + hrtfEneSides += ( lRealpTmp * lRealpTmp ) + ( lImagpTmp * lImagpTmp ) + ( rRealpTmp * rRealpTmp ) + ( rImagpTmp * rImagpTmp ); + lRealp += sidesMul * lRealpTmp; + lImagp += sidesMul * lImagpTmp; + rRealp += sidesMul * rRealpTmp; + rImagp += sidesMul * rImagpTmp; + + /* Formulate an eneCorrectionFactor that compensates for the coherent summation of the HRTFs */ + hrtfEneRealized = ( lRealp * lRealp ) + ( lImagp * lImagp ) + ( rRealp * rRealp ) + ( rImagp * rImagp ); + eneCorrectionFactor = ( ( hrtfEneSides * sidesMul * sidesMul ) + + ( hrtfEneCenter * centerMul * centerMul ) ) / + max( 1e-12f, hrtfEneRealized ); + + /* Weighting factors to determine appropriate target spectrum for spread coherent sound */ + if ( spreadCoh < 0.5 ) + { + w1 = 1.0f - 2.0f * spreadCoh; + w2 = 2.0f * spreadCoh; + w3 = 0.0f; + } + else + { + w1 = 0.0f; + w2 = 2.0f - 2.0f * spreadCoh; + w3 = 2.0f * spreadCoh - 1.0f; + } + + if ( ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) ) + { + idx = min( bin, MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS - 1 ); + + /* Apply the target spectrum to the eneCorrectionFactor */ + if ( separateCenterChannelRendering ) /* spreadCoh mostly originates from phantom sources in separate channel rendering mode */ + { + eneCorrectionFactor *= w1 * 1.0f + ( w2 + w3 ) * spreadCohEne1[idx]; + } + else + { + eneCorrectionFactor *= w1 * 1.0f + w2 * spreadCohEne05[idx] + w3 * spreadCohEne1[idx]; + } + } + + /* Equalize the spread coherent combined HRTFs */ + eq = min( 4.0f, sqrtf( eneCorrectionFactor ) ); + lRealp *= eq; + lImagp *= eq; + rRealp *= eq; + rImagp *= eq; + } + + hrtfEne[0] = ( lRealp * lRealp ) + ( lImagp * lImagp ); + hrtfEne[1] = ( rRealp * rRealp ) + ( rImagp * rImagp ); + hrtfCrossRe = ( lRealp * rRealp ) + ( lImagp * rImagp ); + hrtfCrossIm = ( -lImagp * rRealp ) + ( lRealp * rImagp ); + + /* Add direct part (1 or 2) covariance matrix */ + dirEne = ratio * meanEnePerCh; + h->ChEneOut[0][bin] += dirEne * hrtfEne[0]; /* Dir ene part*/ + h->ChEneOut[1][bin] += dirEne * hrtfEne[1]; + h->ChCrossReOut[bin] += dirEne * hrtfCrossRe; /* Dir cross re */ + h->ChCrossImOut[bin] += dirEne * hrtfCrossIm; /* Dir cross im */ + } + + /* Add diffuse / ambient part covariance matrix */ + diffuseness = max( 0.0f, diffuseness ); + diffEne = diffuseness * meanEnePerCh; + surCoh = surroundingCoherence[bin]; + if ( ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) ) + { + if ( !h->renderStereoOutputInsteadOfBinaural ) + { + idx = min( bin, MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS - 1 ); + /* Apply target spectrum that emphasizes low frequencies when the sound is surround coherent */ + diffEne *= ( 1.0f - surCoh ) + surCoh * surCohEne[idx]; + } + } + h->ChEneOut[0][bin] += diffEne; /* Diff ene part*/ + h->ChEneOut[1][bin] += diffEne; + + if ( h->renderStereoOutputInsteadOfBinaural ) + { + /* When rendering stereo, ambience (except for surround coherent sound) has zero ICC. */ + h->ChCrossReOut[bin] += surCoh * diffEne; + } + else /* When rendering binaural, ambience has frequency dependent ICC. */ + { + if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR && bin < BINAURAL_COHERENCE_DIFFERENCE_BINS ) + { + float diffuseFieldCoherence; + diffuseFieldCoherence = hDirAC->hDiffuseDist->diffuseRatioX[0][bin] * h->diffuseFieldCoherenceX[bin] + hDirAC->hDiffuseDist->diffuseRatioY[0][bin] * h->diffuseFieldCoherenceY[bin] + hDirAC->hDiffuseDist->diffuseRatioZ[0][bin] * h->diffuseFieldCoherenceZ[bin]; + h->ChCrossReOut[bin] += ( ( 1.0f - surCoh ) * diffuseFieldCoherence + surCoh ) * diffEne; + } + else + { + h->ChCrossReOut[bin] += ( ( 1.0f - surCoh ) * h->diffuseFieldCoherence[bin] + surCoh ) * diffEne; + } + } + + /* Store parameters for formulating average diffuseness over frame */ + h->frameMeanDiffuseness[bin] += diffEne; + frameMeanDiffusenessEneWeight[bin] += meanEnePerCh; + } + + + /* Formulate average diffuseness over frame */ + for ( bin = 0; bin < nBins; bin++ ) + { + h->frameMeanDiffuseness[bin] /= fmaxf( 1e-12f, frameMeanDiffusenessEneWeight[bin] ); + } + + /* Determine encoding quality based additional smoothing factor */ + qualityBasedSmFactor = 1.0f; + if ( st_ivas->hMasa != NULL ) + { + qualityBasedSmFactor = st_ivas->hMasa->data.dir_decode_quality; + qualityBasedSmFactor *= qualityBasedSmFactor; + } + + /* Temporal IIR-type smoothing of covariance matrices */ + if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE ) + { + IIReneLimiterFactor = 16.0f + ( 1.0f - qualityBasedSmFactor ); + } + else + { + IIReneLimiterFactor = 8.0f + ( 1.0f - qualityBasedSmFactor ); + } + for ( bin = 0; bin < nBins; bin++ ) + { + float eneRatio, IIReneLimiter; + + /* Temporally smooth cov mtx estimates for resulting mixing matrix stability. The design principle is that + * the energy history (IIR) must not be more than double of the current frame energy. This provides more + * robust performance at energy offsets when compared to typical IIR averaging. */ + eneRatio = ( h->ChEne[0][bin] + h->ChEne[1][bin] ) / fmaxf( 1e-12f, ( h->ChEnePrev[0][bin] + h->ChEnePrev[1][bin] ) ); + IIReneLimiter = fminf( 1.0f, eneRatio * IIReneLimiterFactor ); + + h->ChCrossRe[bin] *= qualityBasedSmFactor; + h->ChCrossIm[bin] *= qualityBasedSmFactor; + h->ChCrossReOut[bin] *= qualityBasedSmFactor; + h->ChCrossImOut[bin] *= qualityBasedSmFactor; + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + h->ChEne[ch][bin] *= qualityBasedSmFactor; + h->ChEneOut[ch][bin] *= qualityBasedSmFactor; + } + + h->ChCrossRe[bin] += IIReneLimiter * h->ChCrossRePrev[bin]; + h->ChCrossIm[bin] += IIReneLimiter * h->ChCrossImPrev[bin]; + h->ChCrossReOut[bin] += IIReneLimiter * h->ChCrossReOutPrev[bin]; + h->ChCrossImOut[bin] += IIReneLimiter * h->ChCrossImOutPrev[bin]; + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + h->ChEne[ch][bin] += IIReneLimiter * h->ChEnePrev[ch][bin]; + h->ChEneOut[ch][bin] += IIReneLimiter * h->ChEneOutPrev[ch][bin]; + } + + /* Store energy values and coefficients for next round */ + h->ChCrossRePrev[bin] = h->ChCrossRe[bin]; + h->ChCrossImPrev[bin] = h->ChCrossIm[bin]; + h->ChCrossReOutPrev[bin] = h->ChCrossReOut[bin]; + h->ChCrossImOutPrev[bin] = h->ChCrossImOut[bin]; + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + h->ChEnePrev[ch][bin] = h->ChEne[ch][bin]; + h->ChEneOutPrev[ch][bin] = h->ChEneOut[ch][bin]; + } + } + + return; +} + +#else static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_sf( Decoder_Struct *st_ivas, float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], @@ -1215,7 +1641,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) { - md_idx = hDirAC->render_to_md_slot_map[slot_idx + slot_idx_start]; + md_idx = hDirAC->render_to_md_map[slot_idx + slot_idx_start]; /* Determine target covariance matrix containing target binaural properties */ for ( bin = 0; bin < nBins; bin++ ) { @@ -1498,6 +1924,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric return; } #endif +#endif static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( diff --git a/lib_rend/ivas_sba_rendering.c b/lib_rend/ivas_sba_rendering.c index f316f2885f..26d9cbdf17 100644 --- a/lib_rend/ivas_sba_rendering.c +++ b/lib_rend/ivas_sba_rendering.c @@ -96,7 +96,7 @@ void ivas_sba_prototype_renderer_sf( /* Apply mixing matrix */ for ( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) { - int16_t md_idx = hSpar->render_to_md_slot_map[ts + slot_idx_start]; + int16_t md_idx = hSpar->render_to_md_map[ts + slot_idx_start]; /* determine SPAR parameters for this time slot */ ivas_spar_get_parameters( hSpar, hDecoderConfig, md_idx, numch_out, numch_in, num_spar_bands, mixer_mat ); @@ -143,7 +143,7 @@ void ivas_sba_prototype_renderer_sf( } /* Update mixing matrices */ - if ( ( ( slot_idx_start + ts + 1 ) == hSpar->num_slots ) || ( ( md_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME ) != ( hSpar->render_to_md_slot_map[ts + slot_idx_start + 1] / JBM_CLDFB_SLOTS_IN_SUBFRAME ) ) ) + if ( ( ( slot_idx_start + ts + 1 ) == hSpar->num_slots ) || ( ( md_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME ) != ( hSpar->render_to_md_map[ts + slot_idx_start + 1] / JBM_CLDFB_SLOTS_IN_SUBFRAME ) ) ) { /* we have crossed an unadapted parameter sf border, update previous mixing matrices */ int16_t md_sf = md_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME; -- GitLab From ce82acf67f80cff9347deaa9c891f70bd39603bc Mon Sep 17 00:00:00 2001 From: knj Date: Tue, 9 May 2023 10:30:48 +0200 Subject: [PATCH 17/39] increase smoketest timeout and add printouts for easier log reading --- .gitlab-ci.yml | 2 +- ci/smoke_test.sh | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7ce29dfd65..377cbc8b24 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -314,7 +314,7 @@ codec-smoke-test: extends: - .test-job-linux-needs-testv-dir - .rules-merge-request - timeout: "5 minutes" + timeout: "10 minutes" stage: test needs: ["build-codec-linux-cmake"] script: diff --git a/ci/smoke_test.sh b/ci/smoke_test.sh index 852b74fe47..a301a48e54 100755 --- a/ci/smoke_test.sh +++ b/ci/smoke_test.sh @@ -78,28 +78,37 @@ fi # treat ISM modes separately because passing the metadata files to MASA modes causes crashes ism_modes=$(./scripts/runIvasCodec.py -l | grep ISM) non_ism_modes=$(./scripts/runIvasCodec.py -l | grep -v ISM) +echo "\n======================= 1. non-ism modes no FEC =======================\n\n" ./scripts/runIvasCodec.py -m $non_ism_modes -p $cfg -U 1 $WORKERS | tee smoke_test_output.txt +echo "\n======================= 2. ism modes no FEC =======================\n\n" ./scripts/runIvasCodec.py -m $ism_modes -p $cfg -U 1 $WORKERS $ism_md_cmd | tee smoke_test_output.txt # run the decoding again, but with 15% frame loss +echo "\n======================= 3. all modes with FEC =======================\n\n" ./scripts/runIvasCodec.py -p $cfg -U 1 $WORKERS -D="-fec 15" --decoder_only | tee smoke_test_output_plc.txt # run JBM modes - EXT is excluded as not supported yet modes_with_no_ext_out=$(./scripts/runIvasCodec.py -l | grep -v MASA | grep -v ISM) +modes_with_ext_out=$(./scripts/runIvasCodec.py -l | grep 'MASA\|ISM') +echo "\n======================= 4. JBM, modes with no EXT =======================\n\n" ./scripts/runIvasCodec.py -m $modes_with_no_ext_out -p $cfg -U 1 $WORKERS --decoder_only --jbm_file $dly_profile | tee smoke_test_output_jbm_noEXT.txt -./scripts/runIvasCodec.py -C MASA ISM1 ISM2 ISM3 ISM4 -p $cfg -U 1 $WORKERS --decoder_only --jbm_file $dly_profile --oc BINAURAL BINAURAL_ROOM mono stereo FOA HOA3 5_1 7_1_4 | tee -a smoke_test_output_jbm_noEXT.txt +echo "\n======================= 5. JBM, modes with EXT =======================\n\n" +./scripts/runIvasCodec.py -C $modes_with_ext_out -p $cfg -U 1 $WORKERS --decoder_only --jbm_file $dly_profile --oc BINAURAL BINAURAL_ROOM mono stereo FOA HOA3 5_1 7_1_4 | tee -a smoke_test_output_jbm_noEXT.txt # run all modes with binaural output using external files modes_with_bin_out="SBA PlanarSBA MASA MC ISM1 ISM2 ISM3 ISM4" bin_out_modes="BINAURAL BINAURAL_ROOM" +echo "\n======================= 6. binaural out with HRTF files - WB =======================\n\n" wb_modes=$(./scripts/runIvasCodec.py -l -C $modes_with_bin_out | grep _wb_) hrtf_wb="../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_16kHz.bin" ./scripts/runIvasCodec.py -p $cfg -m $wb_modes -U 1 $WORKERS -D="-hrtf ${hrtf_wb}" --decoder_only --oc $bin_out_modes | tee -a smoke_test_output_hrtf.txt +echo "\n======================= 7. binaural out with HRTF files - SWB =======================\n\n" swb_modes=$(./scripts/runIvasCodec.py -l -C $modes_with_bin_out | grep _swb_) hrtf_swb="../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_32kHz.bin" ./scripts/runIvasCodec.py -p $cfg -m $swb_modes -U 1 $WORKERS -D="-hrtf ${hrtf_swb}" --decoder_only --oc $bin_out_modes | tee -a smoke_test_output_hrtf.txt +echo "\n======================= 8. binaural out with HRTF files - FB =======================\n\n" fb_modes=$(./scripts/runIvasCodec.py -l -C $modes_with_bin_out | grep _fb_) hrtf_fb="../scripts/binauralRenderer_interface/binaural_renderers_hrtf_data/ivas_binaural_48kHz.bin" ./scripts/runIvasCodec.py -p $cfg -m $fb_modes -U 1 $WORKERS -D="-hrtf ${hrtf_fb}" --decoder_only --oc $bin_out_modes | tee -a smoke_test_output_hrtf.txt -- GitLab From 0830d2084f2ffad9c18958e42bc22991a6788668 Mon Sep 17 00:00:00 2001 From: knj Date: Tue, 9 May 2023 10:36:23 +0200 Subject: [PATCH 18/39] fix typo in command --- ci/smoke_test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/smoke_test.sh b/ci/smoke_test.sh index a301a48e54..85f695da22 100755 --- a/ci/smoke_test.sh +++ b/ci/smoke_test.sh @@ -92,7 +92,7 @@ modes_with_ext_out=$(./scripts/runIvasCodec.py -l | grep 'MASA\|ISM') echo "\n======================= 4. JBM, modes with no EXT =======================\n\n" ./scripts/runIvasCodec.py -m $modes_with_no_ext_out -p $cfg -U 1 $WORKERS --decoder_only --jbm_file $dly_profile | tee smoke_test_output_jbm_noEXT.txt echo "\n======================= 5. JBM, modes with EXT =======================\n\n" -./scripts/runIvasCodec.py -C $modes_with_ext_out -p $cfg -U 1 $WORKERS --decoder_only --jbm_file $dly_profile --oc BINAURAL BINAURAL_ROOM mono stereo FOA HOA3 5_1 7_1_4 | tee -a smoke_test_output_jbm_noEXT.txt +./scripts/runIvasCodec.py -m $modes_with_ext_out -p $cfg -U 1 $WORKERS --decoder_only --jbm_file $dly_profile --oc BINAURAL BINAURAL_ROOM mono stereo FOA HOA3 5_1 7_1_4 | tee -a smoke_test_output_jbm_noEXT.txt # run all modes with binaural output using external files modes_with_bin_out="SBA PlanarSBA MASA MC ISM1 ISM2 ISM3 ISM4" -- GitLab From e8c8d6c0b893db626a721bab2d74536092dbd9bf Mon Sep 17 00:00:00 2001 From: knj Date: Tue, 9 May 2023 10:50:23 +0200 Subject: [PATCH 19/39] exclude ISM+ modes again --- ci/smoke_test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/smoke_test.sh b/ci/smoke_test.sh index 85f695da22..8735584721 100755 --- a/ci/smoke_test.sh +++ b/ci/smoke_test.sh @@ -88,7 +88,7 @@ echo "\n======================= 3. all modes with FEC =======================\n\ # run JBM modes - EXT is excluded as not supported yet modes_with_no_ext_out=$(./scripts/runIvasCodec.py -l | grep -v MASA | grep -v ISM) -modes_with_ext_out=$(./scripts/runIvasCodec.py -l | grep 'MASA\|ISM') +modes_with_ext_out=$(./scripts/runIvasCodec.py -l | grep 'MASA\|ISM' | grep -v ISM+) echo "\n======================= 4. JBM, modes with no EXT =======================\n\n" ./scripts/runIvasCodec.py -m $modes_with_no_ext_out -p $cfg -U 1 $WORKERS --decoder_only --jbm_file $dly_profile | tee smoke_test_output_jbm_noEXT.txt echo "\n======================= 5. JBM, modes with EXT =======================\n\n" -- GitLab From f0ee4c37fc10fd5b7db1af218c84884d02573422 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Wed, 10 May 2023 11:19:25 +0200 Subject: [PATCH 20/39] adapt binaural reverb to variable subframe sizes, completely reintegrate JBM path into the parametric binaural rendering and remove duplicated functionality, fix typoes in ivas_mode.json, activate EXT interfache for JBM (not tested yet, but runs) --- apps/decoder.c | 49 ++++++ lib_com/ivas_prot.h | 2 + lib_dec/ivas_binRenderer_internal.c | 4 + lib_dec/ivas_masa_dec.c | 129 ++++++++++---- lib_dec/ivas_mc_param_dec.c | 2 +- lib_dec/ivas_stat_dec.h | 6 + lib_dec/lib_dec.c | 22 ++- lib_rend/ivas_dirac_dec_binaural_functions.c | 172 +++++++++++++++++-- lib_rend/ivas_prot_rend.h | 5 + lib_rend/ivas_reverb.c | 73 +++++++- lib_rend/ivas_sba_rendering.c | 42 +++++ scripts/config/ivas_modes.json | 4 +- 12 files changed, 450 insertions(+), 60 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 31f38ec1f3..16376844c6 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -2294,6 +2294,55 @@ static ivas_error decodeVoIP( { delayNumSamples -= nOutSamples; } + +#ifdef JBM_TSM_ON_TCS + /* Write ISM metadata to external file(s) */ + if ( decodedGoodFrame && arg.outputFormat == IVAS_DEC_OUTPUT_EXT ) + { + int16_t i; + + if ( bsFormat == IVAS_DEC_BS_OBJ ) + { + if ( ( error = IVAS_DEC_GetNumObjects( hIvasDec, &numObj ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetNumObjects: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + for ( i = 0; i < numObj; ++i ) + { + IVAS_ISM_METADATA IsmMetadata; + + if ( ( error = IVAS_DEC_GetObjectMetadata( hIvasDec, &IsmMetadata, 0, i ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetObjectMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + if ( ( IsmFileWriter_writeFrame( IsmMetadata, ismWriters[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError writing ISM metadata to file %s\n", IsmFileWriter_getFilePath( ismWriters[i] ) ); + goto cleanup; + } + } + } + else if ( bsFormat == IVAS_DEC_BS_MASA ) + { + MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta; + if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + if ( ( error = MasaFileWriter_writeFrame( masaWriter, hMasaExtOutMeta ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError writing MASA metadata to file: %s\n", MasaFileWriter_getFilePath( masaWriter ) ); + goto cleanup; + } + } + } +#endif } if ( !arg.quietModeEnabled ) diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 3362a69036..764e6e6940 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -5030,6 +5030,7 @@ void ivas_masa_prerender( ); #ifdef JBM_TSM_ON_TCS +#ifndef FIX_355_REFACTOR_PARAMBIN_TO_5MS void ivas_spar_param_to_masa_param_mapping_sf( Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ #ifdef MASA_PARAMBIN_SF_MAP @@ -5049,6 +5050,7 @@ void ivas_spar_param_to_masa_param_mapping_sf( float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /* i : Input audio in CLDFB domain, imag */ ); #endif +#endif #ifdef FIX_355_REFACTOR_PARAMBIN_TO_5MS void ivas_spar_param_to_masa_param_mapping( diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index 1144356094..bfe0a4bb53 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -1206,7 +1206,11 @@ void ivas_binRenderer( } #ifdef FIX_355_REFACTOR_PARAMBIN_TO_5MS +#ifdef JBM_TSM_ON_TCS + ivas_binaural_reverb_processSubframe( hBinRenderer->hReverb, BINAURAL_CHANNELS, numTimeSlots, inRe, inIm, reverbRe, reverbIm ); +#else ivas_binaural_reverb_processSubframe( hBinRenderer->hReverb, BINAURAL_CHANNELS, inRe, inIm, reverbRe, reverbIm ); +#endif #else ivas_binaural_reverb_processFrame( hBinRenderer->hReverb, BINAURAL_CHANNELS, inRe, inIm, reverbRe, reverbIm, 0u ); #endif diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index 8404e41863..e4fafa2d25 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -1278,12 +1278,13 @@ ivas_error ivas_masa_dec_reconfigure( } +#ifdef JBM_TSM_ON_TCS +#ifndef FIX_355_REFACTOR_PARAMBIN_TO_5MS /*-------------------------------------------------------------------* * ivas_spar_param_to_masa_param_mapping() * * Determine MASA metadata from the SPAR metadata *-------------------------------------------------------------------*/ -#ifdef JBM_TSM_ON_TCS void ivas_spar_param_to_masa_param_mapping_sf( Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ #ifdef MASA_PARAMBIN_SF_MAP @@ -1437,9 +1438,9 @@ void ivas_spar_param_to_masa_param_mapping_sf( if ( hDiffuseDist != NULL ) { - set_zero( hDiffuseDist->diffuseRatioX[0], CLDFB_NO_CHANNELS_MAX ); - set_zero( hDiffuseDist->diffuseRatioY[0], CLDFB_NO_CHANNELS_MAX ); - set_zero( hDiffuseDist->diffuseRatioZ[0], CLDFB_NO_CHANNELS_MAX ); + set_zero( hDiffuseDist->diffuseRatioX, CLDFB_NO_CHANNELS_MAX ); + set_zero( hDiffuseDist->diffuseRatioY, CLDFB_NO_CHANNELS_MAX ); + set_zero( hDiffuseDist->diffuseRatioZ, CLDFB_NO_CHANNELS_MAX ); } for ( bin = 0; bin < nBins; bin++ ) @@ -1520,15 +1521,15 @@ void ivas_spar_param_to_masa_param_mapping_sf( if ( diffuseGainSum == 0.0f ) { - hDiffuseDist->diffuseRatioX[0][bin] = 1.0f / 3.0f; - hDiffuseDist->diffuseRatioY[0][bin] = 1.0f / 3.0f; - hDiffuseDist->diffuseRatioZ[0][bin] = 1.0f / 3.0f; + hDiffuseDist->diffuseRatioX[bin] = 1.0f / 3.0f; + hDiffuseDist->diffuseRatioY[bin] = 1.0f / 3.0f; + hDiffuseDist->diffuseRatioZ[bin] = 1.0f / 3.0f; } else { - hDiffuseDist->diffuseRatioX[0][bin] = diffuseGainX / ( diffuseGainSum + EPSILON ); - hDiffuseDist->diffuseRatioY[0][bin] = diffuseGainY / ( diffuseGainSum + EPSILON ); - hDiffuseDist->diffuseRatioZ[0][bin] = diffuseGainZ / ( diffuseGainSum + EPSILON ); + hDiffuseDist->diffuseRatioX[bin] = diffuseGainX / ( diffuseGainSum + EPSILON ); + hDiffuseDist->diffuseRatioY[bin] = diffuseGainY / ( diffuseGainSum + EPSILON ); + hDiffuseDist->diffuseRatioZ[bin] = diffuseGainZ / ( diffuseGainSum + EPSILON ); } } } @@ -1547,6 +1548,7 @@ void ivas_spar_param_to_masa_param_mapping_sf( return; } #endif +#endif #ifdef FIX_355_REFACTOR_PARAMBIN_TO_5MS void ivas_spar_param_to_masa_param_mapping( @@ -1561,8 +1563,8 @@ void ivas_spar_param_to_masa_param_mapping( int16_t dirac_write_idx; DIRAC_DEC_HANDLE hDirAC; DIFFUSE_DISTRIBUTION_HANDLE hDiffuseDist; - float mixer_mat_sf_bands_real[MAX_PARAM_SPATIAL_SUBFRAMES][SPAR_DIRAC_SPLIT_START_BAND][FOA_CHANNELS][FOA_CHANNELS]; - float mixer_mat_sf_bins_real[MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX][FOA_CHANNELS][FOA_CHANNELS]; + float mixer_mat_sf_bands_real[SPAR_DIRAC_SPLIT_START_BAND][FOA_CHANNELS][FOA_CHANNELS]; + float mixer_mat_sf_bins_real[CLDFB_NO_CHANNELS_MAX][FOA_CHANNELS][FOA_CHANNELS]; int16_t *band_grouping; int16_t band_start, band_end; float transportSignalEnergies[2][CLDFB_NO_CHANNELS_MAX]; @@ -1572,6 +1574,12 @@ void ivas_spar_param_to_masa_param_mapping( float foaCovarianceMtx[FOA_CHANNELS][FOA_CHANNELS]; float Iy, Iz, Ix, E, azi, ele, I, ratio; float diffuseGainX, diffuseGainY, diffuseGainZ, diffuseGainSum; +#ifdef JBM_TSM_ON_TCS + int16_t slot_idx, slot_idx_start, sf; + SPAR_DEC_HANDLE hSpar; + float slot_fac; +#endif + /* Set values */ hDirAC = st_ivas->hDirAC; @@ -1579,7 +1587,12 @@ void ivas_spar_param_to_masa_param_mapping( hDiffuseDist = st_ivas->hDirAC->hDiffuseDist; nchan_transport = st_ivas->nchan_transport; band_grouping = hDirAC->band_grouping; +#ifdef JBM_TSM_ON_TCS + hSpar = st_ivas->hSpar; + dirac_write_idx = hDirAC->render_to_md_map[subframe]; +#else dirac_write_idx = hDirAC->dirac_read_idx; /* Mixing matrices, from which MASA meta is determined, already have the delay compensation */ +#endif /* Init arrays */ for ( i = 0; i < FOA_CHANNELS; i++ ) @@ -1588,34 +1601,61 @@ void ivas_spar_param_to_masa_param_mapping( } /* Delay the SPAR mixing matrices to have them synced with the audio */ - if ( subframe < SPAR_META_DELAY_SUBFRAMES ) +#ifdef JBM_TSM_ON_TCS + slot_idx_start = hSpar->slots_rendered; + slot_fac = 1.0f / (float) hSpar->subframe_nbslots[subframe]; + + for ( slot_idx = 0; slot_idx < hSpar->subframe_nbslots[subframe]; slot_idx++ ) { - mixer_mat_index = subframe + MAX_PARAM_SPATIAL_SUBFRAMES - SPAR_META_DELAY_SUBFRAMES + 1; - for ( band = 0; band < SPAR_DIRAC_SPLIT_START_BAND; band++ ) + sf = hSpar->render_to_md_map[slot_idx + slot_idx_start] / JBM_CLDFB_SLOTS_IN_SUBFRAME; +#endif + if ( subframe < SPAR_META_DELAY_SUBFRAMES ) { - for ( i = 0; i < FOA_CHANNELS; i++ ) +#ifdef JBM_TSM_ON_TCS + mixer_mat_index = sf + MAX_PARAM_SPATIAL_SUBFRAMES - SPAR_META_DELAY_SUBFRAMES + 1; +#else + mixer_mat_index = subframe + MAX_PARAM_SPATIAL_SUBFRAMES - SPAR_META_DELAY_SUBFRAMES + 1; +#endif + for ( band = 0; band < SPAR_DIRAC_SPLIT_START_BAND; band++ ) { - for ( j = 0; j < FOA_CHANNELS; j++ ) + for ( i = 0; i < FOA_CHANNELS; i++ ) { - mixer_mat_sf_bands_real[subframe][band][i][j] = st_ivas->hSpar->hMdDec->mixer_mat_prev[mixer_mat_index][i][j][band]; + for ( j = 0; j < FOA_CHANNELS; j++ ) + { +#ifdef JBM_TSM_ON_TCS + mixer_mat_sf_bands_real[band][i][j] = slot_fac * st_ivas->hSpar->hMdDec->mixer_mat_prev[mixer_mat_index][i][j][band]; +#else + mixer_mat_sf_bands_real[band][i][j] = st_ivas->hSpar->hMdDec->mixer_mat_prev[mixer_mat_index][i][j][band]; +#endif + } } } } - } - else - { - mixer_mat_index = subframe - SPAR_META_DELAY_SUBFRAMES; - for ( band = 0; band < SPAR_DIRAC_SPLIT_START_BAND; band++ ) + else { - for ( i = 0; i < FOA_CHANNELS; i++ ) +#ifdef JBM_TSM_ON_TCS + mixer_mat_index = sf - SPAR_META_DELAY_SUBFRAMES; +#else + mixer_mat_index = subframe - SPAR_META_DELAY_SUBFRAMES; +#endif + for ( band = 0; band < SPAR_DIRAC_SPLIT_START_BAND; band++ ) { - for ( j = 0; j < FOA_CHANNELS; j++ ) + for ( i = 0; i < FOA_CHANNELS; i++ ) { - mixer_mat_sf_bands_real[subframe][band][i][j] = st_ivas->hSpar->hMdDec->mixer_mat[i][j][band + mixer_mat_index * IVAS_MAX_NUM_BANDS]; + for ( j = 0; j < FOA_CHANNELS; j++ ) + { +#ifdef JBM_TSM_ON_TCS + mixer_mat_sf_bands_real[band][i][j] = slot_fac * st_ivas->hSpar->hMdDec->mixer_mat[i][j][band + mixer_mat_index * IVAS_MAX_NUM_BANDS]; +#else + mixer_mat_sf_bands_real[band][i][j] = st_ivas->hSpar->hMdDec->mixer_mat[i][j][band + mixer_mat_index * IVAS_MAX_NUM_BANDS]; +#endif + } } } } +#ifdef JBM_TSM_ON_TCS } +#endif /* Map the mixing matrices from the frequency bands to frequency bins */ bin = 0; @@ -1629,7 +1669,7 @@ void ivas_spar_param_to_masa_param_mapping( { for ( j = 0; j < FOA_CHANNELS; j++ ) { - mixer_mat_sf_bins_real[subframe][bin][i][j] = mixer_mat_sf_bands_real[subframe][band][i][j]; + mixer_mat_sf_bins_real[bin][i][j] = mixer_mat_sf_bands_real[band][i][j]; } } } @@ -1666,9 +1706,15 @@ void ivas_spar_param_to_masa_param_mapping( if ( hDiffuseDist != NULL ) { +#ifdef JBM_TSM_ON_TCS + set_zero( hDiffuseDist->diffuseRatioX, CLDFB_NO_CHANNELS_MAX ); + set_zero( hDiffuseDist->diffuseRatioY, CLDFB_NO_CHANNELS_MAX ); + set_zero( hDiffuseDist->diffuseRatioZ, CLDFB_NO_CHANNELS_MAX ); +#else set_zero( hDiffuseDist->diffuseRatioX[subframe], CLDFB_NO_CHANNELS_MAX ); set_zero( hDiffuseDist->diffuseRatioY[subframe], CLDFB_NO_CHANNELS_MAX ); set_zero( hDiffuseDist->diffuseRatioZ[subframe], CLDFB_NO_CHANNELS_MAX ); +#endif } for ( bin = 0; bin < nBins; bin++ ) @@ -1695,7 +1741,7 @@ void ivas_spar_param_to_masa_param_mapping( inCovarianceMtx[1][0] = inCovarianceMtx[0][1]; } - compute_foa_cov_matrix( foaCovarianceMtx, inCovarianceMtx, mixer_mat_sf_bins_real[subframe][bin] ); + compute_foa_cov_matrix( foaCovarianceMtx, inCovarianceMtx, mixer_mat_sf_bins_real[bin] ); /* Estimate MASA metadata */ Iy = foaCovarianceMtx[0][1]; /* Intensity in Y direction */ @@ -1721,15 +1767,15 @@ void ivas_spar_param_to_masa_param_mapping( { if ( nchan_transport == 1 ) { - diffuseGainY = fabsf( mixer_mat_sf_bins_real[subframe][bin][1][1] ); - diffuseGainX = fabsf( mixer_mat_sf_bins_real[subframe][bin][3][2] ); - diffuseGainZ = fabsf( mixer_mat_sf_bins_real[subframe][bin][2][3] ); + diffuseGainY = fabsf( mixer_mat_sf_bins_real[bin][1][1] ); + diffuseGainX = fabsf( mixer_mat_sf_bins_real[bin][3][2] ); + diffuseGainZ = fabsf( mixer_mat_sf_bins_real[bin][2][3] ); } else if ( nchan_transport == 2 ) { - diffuseGainY = fabsf( mixer_mat_sf_bins_real[subframe][bin][1][1] * transportSignalEnergies[1][bin] ); - diffuseGainX = fabsf( mixer_mat_sf_bins_real[subframe][bin][3][2] * transportSignalEnergies[0][bin] ) + fabsf( mixer_mat_sf_bins_real[subframe][bin][3][1] * transportSignalEnergies[1][bin] ); - diffuseGainZ = fabsf( mixer_mat_sf_bins_real[subframe][bin][2][3] * transportSignalEnergies[0][bin] ) + fabsf( mixer_mat_sf_bins_real[subframe][bin][2][1] * transportSignalEnergies[1][bin] ); + diffuseGainY = fabsf( mixer_mat_sf_bins_real[bin][1][1] * transportSignalEnergies[1][bin] ); + diffuseGainX = fabsf( mixer_mat_sf_bins_real[bin][3][2] * transportSignalEnergies[0][bin] ) + fabsf( mixer_mat_sf_bins_real[bin][3][1] * transportSignalEnergies[1][bin] ); + diffuseGainZ = fabsf( mixer_mat_sf_bins_real[bin][2][3] * transportSignalEnergies[0][bin] ) + fabsf( mixer_mat_sf_bins_real[bin][2][1] * transportSignalEnergies[1][bin] ); } else { @@ -1740,6 +1786,20 @@ void ivas_spar_param_to_masa_param_mapping( diffuseGainSum = diffuseGainY + diffuseGainX + diffuseGainZ; +#ifdef JBM_TSM_ON_TCS + if ( diffuseGainSum == 0.0f ) + { + hDiffuseDist->diffuseRatioX[bin] = 1.0f / 3.0f; + hDiffuseDist->diffuseRatioY[bin] = 1.0f / 3.0f; + hDiffuseDist->diffuseRatioZ[bin] = 1.0f / 3.0f; + } + else + { + hDiffuseDist->diffuseRatioX[bin] = diffuseGainX / ( diffuseGainSum + EPSILON ); + hDiffuseDist->diffuseRatioY[bin] = diffuseGainY / ( diffuseGainSum + EPSILON ); + hDiffuseDist->diffuseRatioZ[bin] = diffuseGainZ / ( diffuseGainSum + EPSILON ); + } +#else if ( diffuseGainSum == 0.0f ) { hDiffuseDist->diffuseRatioX[subframe][bin] = 1.0f / 3.0f; @@ -1752,6 +1812,7 @@ void ivas_spar_param_to_masa_param_mapping( hDiffuseDist->diffuseRatioY[subframe][bin] = diffuseGainY / ( diffuseGainSum + EPSILON ); hDiffuseDist->diffuseRatioZ[subframe][bin] = diffuseGainZ / ( diffuseGainSum + EPSILON ); } +#endif } } diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index e4e6480254..d19e2d33cc 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -1477,7 +1477,7 @@ void ivas_param_mc_dec_digest_tc( ivas_jbm_dec_get_adapted_subframes( nCldfbSlots, hParamMC->subframe_nbslots, &hParamMC->nb_subframes ); ivas_param_mc_dec_compute_interpolator( hParamMC->hMetadataPMC->bAttackPresent, hParamMC->hMetadataPMC->attackIndex, nCldfbSlots, hParamMC->h_output_synthesis_params.interpolator ); - + for ( param_band_idx = 0; param_band_idx < PARAM_MC_MAX_PARAMETER_BANDS; param_band_idx++ ) { set_zero( cx[param_band_idx], PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index af2edd614d..913799b0a6 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -619,9 +619,15 @@ typedef struct /* Diffuse sound directional distribution data structure */ typedef struct ivas_diffuse_distribution_data_structure { +#ifdef JBM_TSM_ON_TCS + float diffuseRatioX[CLDFB_NO_CHANNELS_MAX]; + float diffuseRatioY[CLDFB_NO_CHANNELS_MAX]; + float diffuseRatioZ[CLDFB_NO_CHANNELS_MAX]; +#else float diffuseRatioX[MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float diffuseRatioY[MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float diffuseRatioZ[MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#endif } DIFFUSE_DISTRIBUTION_DATA, *DIFFUSE_DISTRIBUTION_HANDLE; diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index da8b5049e5..f99209a1c5 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -526,9 +526,26 @@ ivas_error IVAS_DEC_EnableVoIP( hDecoderConfig->voip_active = 1; #endif - hDecoderConfig->nchan_out = audioCfg2channels( hDecoderConfig->output_config ); +#ifdef JBM_TSM_ON_TCS + if ( hDecoderConfig->output_config != AUDIO_CONFIG_EXTERNAL ) + { +#endif + hDecoderConfig->nchan_out = audioCfg2channels( hDecoderConfig->output_config ); + +#ifdef JBM_TSM_ON_TCS + } +#ifdef VARIABLE_SPEED_DECODING + else + { + hDecoderConfig->nchan_out = 1; + } +#endif +#endif + +#ifndef JBM_TSM_ON_TCS assert( hDecoderConfig->nchan_out > 0 && "EXT output not yet supported in VoIP mode" ); +#endif if ( ( error = input_format_API_to_internal( inputFormat, &hIvasDec->bitstreamformat, &hIvasDec->sdp_hf_only, true ) ) != IVAS_ERR_OK ) { @@ -628,6 +645,7 @@ ivas_error IVAS_DEC_EnableVoIP( hIvasDec->hVoIP->hTimeScaler = NULL; /* create output pcm fifo*/ /* :TODO: also provide CLDFB output FIFO if things work out */ +#ifdef VARIABLE_SPEED_DECODING if ( hIvasDec->hVoIP->mode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED ) { if ( pcmdsp_fifo_create( &hIvasDec->hVoIP->hFifoOut ) != 0 || @@ -638,7 +656,7 @@ ivas_error IVAS_DEC_EnableVoIP( /* we instantly need a new frame */ hIvasDec->hVoIP->needNewFrame = true; } - +#endif #else #ifdef VARIABLE_SPEED_DECODING { diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 94ef6086d1..aa3ad7f85b 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -71,8 +71,11 @@ *------------------------------------------------------------------------*/ #ifdef FIX_355_REFACTOR_PARAMBIN_TO_5MS +#ifdef JBM_TSM_ON_TCS +static void ivas_dirac_dec_binaural_internal( Decoder_Struct *st_ivas, float *output_f[], const int16_t nchan_transport, const int16_t subframe ); +#else static void ivas_dirac_dec_binaural_internal( Decoder_Struct *st_ivas, float output_f[][L_FRAME48k], const int16_t nchan_transport, const int16_t subframe ); - +#endif static void ivas_dirac_dec_decorrelate_slot( DIRAC_DEC_HANDLE hDirAC, const int16_t slot, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float decRe[][CLDFB_NO_CHANNELS_MAX], float decIm[][CLDFB_NO_CHANNELS_MAX] ); static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( Decoder_Struct *st_ivas, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float Rmat[3][3], const int16_t subframe ); @@ -87,11 +90,20 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric static void ivas_dirac_dec_binaural_determine_processing_matrices( Decoder_Struct *st_ivas, const int16_t max_band_decorr, float Rmat[3][3] ); #ifdef FIX_355_REFACTOR_PARAMBIN_TO_5MS +#ifdef JBM_TSM_ON_TCS +static void ivas_dirac_dec_binaural_process_output( Decoder_Struct *st_ivas, float *output_f[], float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t max_band_decorr, const int16_t numInChannels, const int16_t subframe ); + +static void adaptTransportSignalsHeadtracked( HEAD_TRACK_DATA_HANDLE hHeadTrackData, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t nBins, const int16_t nSlots, float Rmat[3][3] ); + +static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked( HEAD_TRACK_DATA_HANDLE hHeadTrackData, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t nBins, const int16_t nSlots, float Rmat[3][3] ); +#else static void ivas_dirac_dec_binaural_process_output( Decoder_Struct *st_ivas, float output_f[][L_FRAME48k], float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t max_band_decorr, const int16_t numInChannels, const int16_t subframe ); static void adaptTransportSignalsHeadtracked( HEAD_TRACK_DATA_HANDLE hHeadTrackData, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t nBins, float Rmat[3][3] ); static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked( HEAD_TRACK_DATA_HANDLE hHeadTrackData, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t nBins, float Rmat[3][3] ); +#endif + #else static void ivas_dirac_dec_binaural_process_output( Decoder_Struct *st_ivas, float output_f[][L_FRAME48k], float inRe[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const int16_t max_band_decorr, const uint8_t numInputChannels, const uint8_t firstSlot, const uint8_t slotEnd ); @@ -116,6 +128,7 @@ static float configure_reqularization_factor( const IVAS_FORMAT ivas_format, con #endif #ifdef JBM_TSM_ON_TCS +#ifndef FIX_355_REFACTOR_PARAMBIN_TO_5MS static void ivas_dirac_dec_binaural_process_output_sf( Decoder_Struct *st_ivas, float *output_f[], float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t max_band_decorr, const uint8_t numInChannels ); static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked_sf( HEAD_TRACK_DATA_HANDLE hHeadTrackData, float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const uint8_t slotEnd, const uint8_t nBins, float Rmat[3][3] ); @@ -128,8 +141,10 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric static void ivas_dirac_dec_binaural_internal_sf( Decoder_Struct *st_ivas, float *output_f[], const int16_t nchan_transport ); + static void ivas_dirac_dec_decorrelate_slot_sf( DIRAC_DEC_HANDLE hDirAC, const int8_t slot, float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float decRe[][CLDFB_NO_CHANNELS_MAX], float decIm[][CLDFB_NO_CHANNELS_MAX] ); #endif +#endif /*------------------------------------------------------------------------- * ivas_dirac_dec_init_binaural_data() * @@ -251,6 +266,18 @@ ivas_error ivas_dirac_dec_init_binaural_data( if ( hBinaural->hReverb == NULL ) { +#if defined( JBM_TSM_ON_TCS ) && !defined( FIX_355_REFACTOR_PARAMBIN_TO_5MS ) + int16_t reverbBlockSize = st_ivas->hDecoderConfig->voip_active ? 1 : CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; + if ( ( error = ivas_binaural_reverb_open( &hBinaural->hReverb, + nBins, + reverbBlockSize, NULL, + st_ivas->hIntSetup.output_config, + output_Fs, + RENDERER_BINAURAL_PARAMETRIC_ROOM, + st_ivas->hHrtfFastConv, + st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK ) + +#else if ( ( error = ivas_binaural_reverb_open( &hBinaural->hReverb, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, NULL, @@ -259,6 +286,7 @@ ivas_error ivas_dirac_dec_init_binaural_data( RENDERER_BINAURAL_PARAMETRIC_ROOM, st_ivas->hHrtfFastConv, st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -508,7 +536,11 @@ void ivas_dirac_dec_binaural_render( for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) { int16_t n_samples_sf = slot_size * hDirAC->subframe_nbslots[subframe_idx]; +#ifdef FIX_355_REFACTOR_PARAMBIN_TO_5MS + ivas_dirac_dec_binaural_internal( st_ivas, output_f_local, nchan_transport, subframe_idx ); +#else ivas_dirac_dec_binaural_internal_sf( st_ivas, output_f_local, nchan_transport ); +#endif for ( ch = 0; ch < nchan_out; ch++ ) { output_f_local[ch] += n_samples_sf; @@ -516,14 +548,7 @@ void ivas_dirac_dec_binaural_render( } if ( hDirAC->slots_rendered == hDirAC->num_slots ) { - if ( st_ivas->hDirAC->hConfig != NULL && st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) - { - st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % st_ivas->hDirAC->dirac_md_buffer_length; - } - else - { - st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % st_ivas->hDirAC->dirac_md_buffer_length; - } + st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % st_ivas->hDirAC->dirac_md_buffer_length; } *nSamplesAvailable = ( hDirAC->num_slots - hDirAC->slots_rendered ) * slot_size; @@ -545,13 +570,14 @@ void ivas_dirac_dec_binaural( { #ifdef FIX_355_REFACTOR_PARAMBIN_TO_5MS int16_t subframe; - #endif #ifdef JBM_TSM_ON_TCS float cng_td_buffer[L_FRAME16k]; float *p_output[MAX_OUTPUT_CHANNELS]; int16_t ch; + int16_t slot_size; + slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); for ( ch = 0; ch < 2 * BINAURAL_CHANNELS; ch++ ) { p_output[ch] = &output_f[ch][0]; @@ -604,7 +630,17 @@ void ivas_dirac_dec_binaural( #ifdef FIX_355_REFACTOR_PARAMBIN_TO_5MS for ( subframe = 0; subframe < MAX_PARAM_SPATIAL_SUBFRAMES; subframe++ ) { +#ifdef JBM_TSM_ON_TCS + int16_t n_samples_sf = slot_size * st_ivas->hDirAC->subframe_nbslots[subframe]; + ivas_dirac_dec_binaural_internal( st_ivas, p_output, nchan_transport, subframe ); + for ( ch = 0; ch < 2 * BINAURAL_CHANNELS; ch++ ) + { + p_output[ch] += n_samples_sf; + } + st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + 1 ) % st_ivas->hDirAC->dirac_md_buffer_length; +#else ivas_dirac_dec_binaural_internal( st_ivas, output_f, nchan_transport, subframe ); +#endif } #else if ( st_ivas->hDiracDecBin->useSubframeMode ) @@ -634,6 +670,7 @@ void ivas_dirac_dec_binaural( * Local functions *------------------------------------------------------------------------*/ #ifdef JBM_TSM_ON_TCS +#ifndef FIX_355_REFACTOR_PARAMBIN_TO_5MS static void ivas_dirac_dec_binaural_internal_sf( Decoder_Struct *st_ivas, float *output_f[], @@ -854,11 +891,16 @@ static void ivas_dirac_dec_binaural_internal_sf( return; } #endif +#endif #ifdef FIX_355_REFACTOR_PARAMBIN_TO_5MS static void ivas_dirac_dec_binaural_internal( Decoder_Struct *st_ivas, +#ifdef JBM_TSM_ON_TCS + float *output_f[], +#else float output_f[][L_FRAME48k], +#endif const int16_t nchan_transport, const int16_t subframe ) { @@ -873,7 +915,11 @@ static void ivas_dirac_dec_binaural_internal( hDirAC = st_ivas->hDirAC; nBins = hDirAC->num_freq_bands; +#ifdef JBM_TSM_ON_TCS + offsetSamples = hDirAC->slots_rendered * nBins; +#else offsetSamples = subframe * CLDFB_SLOTS_PER_SUBFRAME * nBins; +#endif /* The input channel number at this processing function (not nchan_transport) */ numInChannels = BINAURAL_CHANNELS; @@ -895,16 +941,25 @@ static void ivas_dirac_dec_binaural_internal( Rmat[2][2] = 1.0f; /* CLDFB Analysis of input */ +#ifdef JBM_TSM_ON_TCS + for ( slot = 0; slot < hDirAC->subframe_nbslots[subframe]; slot++ ) +#else for ( slot = 0; slot < CLDFB_SLOTS_PER_SUBFRAME; slot++ ) +#endif { for ( ch = 0; ch < numInChannels; ch++ ) { if ( ch == 0 || nchan_transport == 2 ) { - cldfbAnalysis_ts( &( output_f[ch][nBins * slot + offsetSamples] ), - Cldfb_RealBuffer_in[ch][slot], - Cldfb_ImagBuffer_in[ch][slot], - nBins, st_ivas->cldfbAnaDec[ch] ); + cldfbAnalysis_ts( +#ifdef JBM_TSM_ON_TCS + &( st_ivas->hTcBuffer->tc[ch][nBins * slot + offsetSamples] ), +#else + &( output_f[ch][nBins * slot + offsetSamples] ), +#endif + Cldfb_RealBuffer_in[ch][slot], + Cldfb_ImagBuffer_in[ch][slot], + nBins, st_ivas->cldfbAnaDec[ch] ); } else if ( st_ivas->nchan_transport == 2 ) /* Stereo signal transmitted as mono with DFT stereo */ { @@ -921,12 +976,16 @@ static void ivas_dirac_dec_binaural_internal( int16_t slotInFrame; numCoreBands = st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->numCoreBands; +#ifdef JBM_TSM_ON_TCS + slotInFrame = hDirAC->slots_rendered + slot; +#else slotInFrame = subframe * CLDFB_SLOTS_PER_SUBFRAME + slot; +#endif generate_masking_noise_dirac( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom, st_ivas->cldfbAnaDec[1], #ifdef JBM_TSM_ON_TCS - st_ivas->hTcBuffer->tc[1], + st_ivas->hTcBuffer->tc[nchan_transport], #else &( output_f[1][L_FRAME48k - L_FRAME16k] ), /*used as temporary static buffer for the whole frame*/ #endif @@ -1015,9 +1074,15 @@ static void ivas_dirac_dec_binaural_internal( if ( nchan_transport == 2 ) { +#ifdef JBM_TSM_ON_TCS + adaptTransportSignalsHeadtracked( st_ivas->hHeadTrackData, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, hDirAC->subframe_nbslots[subframe], Rmat ); + + ivas_dirac_dec_binaural_check_and_switch_transports_headtracked( st_ivas->hHeadTrackData, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, hDirAC->subframe_nbslots[subframe], Rmat ); +#else adaptTransportSignalsHeadtracked( st_ivas->hHeadTrackData, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, Rmat ); ivas_dirac_dec_binaural_check_and_switch_transports_headtracked( st_ivas->hHeadTrackData, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, Rmat ); +#endif } } @@ -1043,11 +1108,11 @@ static void ivas_dirac_dec_binaural_internal( st_ivas->hDirAC->hDiffuseDist = NULL; - hDirAC->dirac_read_idx = ( hDirAC->dirac_read_idx + 1 ) % hDirAC->dirac_md_buffer_length; - #ifdef JBM_TSM_ON_TCS hDirAC->slots_rendered += hDirAC->subframe_nbslots[subframe]; hDirAC->subframes_rendered++; +#else + hDirAC->dirac_read_idx = ( hDirAC->dirac_read_idx + 1 ) % hDirAC->dirac_md_buffer_length; #endif return; @@ -1312,6 +1377,7 @@ static void ivas_dirac_dec_decorrelate_slot( } #ifdef JBM_TSM_ON_TCS +#ifndef FIX_355_REFACTOR_PARAMBIN_TO_5MS static void ivas_dirac_dec_decorrelate_slot_sf( DIRAC_DEC_HANDLE hDirAC, const int8_t slot, @@ -1362,7 +1428,9 @@ static void ivas_dirac_dec_decorrelate_slot_sf( return; } +#endif +#ifndef FIX_355_REFACTOR_PARAMBIN_TO_5MS #ifdef MASA_PARAMBIN_SF_MAP static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_sf( Decoder_Struct *st_ivas, @@ -1681,7 +1749,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR && bin < BINAURAL_COHERENCE_DIFFERENCE_BINS ) { float diffuseFieldCoherence; - diffuseFieldCoherence = hDirAC->hDiffuseDist->diffuseRatioX[0][bin] * h->diffuseFieldCoherenceX[bin] + hDirAC->hDiffuseDist->diffuseRatioY[0][bin] * h->diffuseFieldCoherenceY[bin] + hDirAC->hDiffuseDist->diffuseRatioZ[0][bin] * h->diffuseFieldCoherenceZ[bin]; + diffuseFieldCoherence = hDirAC->hDiffuseDist->diffuseRatioX[bin] * h->diffuseFieldCoherenceX[bin] + hDirAC->hDiffuseDist->diffuseRatioY[bin] * h->diffuseFieldCoherenceY[bin] + hDirAC->hDiffuseDist->diffuseRatioZ[bin] * h->diffuseFieldCoherenceZ[bin]; h->ChCrossReOut[bin] += ( ( 1.0f - surCoh ) * diffuseFieldCoherence + surCoh ) * diffEne; } else @@ -2184,6 +2252,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric } #endif #endif +#endif #ifdef FIX_355_REFACTOR_PARAMBIN_TO_5MS @@ -2248,7 +2317,11 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric /* Formulate input and target covariance matrices for this subframe */ set_zero( subFrameTotalEne, CLDFB_NO_CHANNELS_MAX ); +#ifdef JBM_TSM_ON_TCS + dirac_read_idx = hDirAC->render_to_md_map[subframe]; +#else dirac_read_idx = hDirAC->dirac_read_idx; +#endif /* Calculate input covariance matrix */ #ifdef JBM_TSM_ON_TCS @@ -2507,7 +2580,11 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR && bin < BINAURAL_COHERENCE_DIFFERENCE_BINS ) { float diffuseFieldCoherence; +#ifdef JBM_TSM_ON_TCS + diffuseFieldCoherence = hDirAC->hDiffuseDist->diffuseRatioX[bin] * h->diffuseFieldCoherenceX[bin] + hDirAC->hDiffuseDist->diffuseRatioY[bin] * h->diffuseFieldCoherenceY[bin] + hDirAC->hDiffuseDist->diffuseRatioZ[bin] * h->diffuseFieldCoherenceZ[bin]; +#else diffuseFieldCoherence = hDirAC->hDiffuseDist->diffuseRatioX[subframe][bin] * h->diffuseFieldCoherenceX[bin] + hDirAC->hDiffuseDist->diffuseRatioY[subframe][bin] * h->diffuseFieldCoherenceY[bin] + hDirAC->hDiffuseDist->diffuseRatioZ[subframe][bin] * h->diffuseFieldCoherenceZ[bin]; +#endif h->ChCrossReOut[bin] += ( ( 1.0f - surCoh ) * diffuseFieldCoherence + surCoh ) * diffEne; } else @@ -3201,6 +3278,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices( } #ifdef JBM_TSM_ON_TCS +#ifndef FIX_355_REFACTOR_PARAMBIN_TO_5MS static void ivas_dirac_dec_binaural_process_output_sf( Decoder_Struct *st_ivas, float *output_f[], @@ -3238,7 +3316,11 @@ static void ivas_dirac_dec_binaural_process_output_sf( } if ( !st_ivas->hDiracDecBin->useTdDecorr && max_band_decorr > 0 ) { +#ifdef FIX_355_REFACTOR_PARAMBIN_TO_5MS + ivas_dirac_dec_decorrelate_slot( st_ivas->hDirAC, slot, inRe, inIm, decSlotRe, decSlotIm ); +#else ivas_dirac_dec_decorrelate_slot_sf( st_ivas->hDirAC, slot, inRe, inIm, decSlotRe, decSlotIm ); +#endif } for ( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) @@ -3311,11 +3393,16 @@ static void ivas_dirac_dec_binaural_process_output_sf( return; } #endif +#endif #ifdef FIX_355_REFACTOR_PARAMBIN_TO_5MS static void ivas_dirac_dec_binaural_process_output( Decoder_Struct *st_ivas, +#ifdef JBM_TSM_ON_TCS + float *output_f[], +#else float output_f[][L_FRAME48k], +#endif float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t max_band_decorr, @@ -3333,21 +3420,41 @@ static void ivas_dirac_dec_binaural_process_output( float *decSlotRePointer; float *decSlotImPointer; int16_t offsetSamples; +#ifdef JBM_TSM_ON_TCS + int16_t nSlots; +#endif h = st_ivas->hDiracDecBin; nBins = st_ivas->hDirAC->num_freq_bands; +#ifdef JBM_TSM_ON_TCS + offsetSamples = 0; + nSlots = st_ivas->hDirAC->subframe_nbslots[subframe]; +#else offsetSamples = subframe * CLDFB_SLOTS_PER_SUBFRAME * nBins; +#endif if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) { /* Process second / room effect part of binaural output when needed */ +#ifdef JBM_TSM_ON_TCS + ivas_binaural_reverb_processSubframe( st_ivas->hDiracDecBin->hReverb, numInChannels, nSlots, inRe, inIm, reverbRe, reverbIm ); +#else ivas_binaural_reverb_processSubframe( st_ivas->hDiracDecBin->hReverb, numInChannels, inRe, inIm, reverbRe, reverbIm ); +#endif } interpVal = 0.0f; +#ifdef JBM_TSM_ON_TCS + for ( slot = 0; slot < nSlots; slot++ ) +#else for ( slot = 0; slot < CLDFB_SLOTS_PER_SUBFRAME; slot++ ) +#endif { +#ifdef JBM_TSM_ON_TCS + interpVal += 1.0f / (float) nSlots; +#else interpVal += 1.0f / ( (float) CLDFB_SLOTS_PER_SUBFRAME ); +#endif if ( !st_ivas->hDiracDecBin->useTdDecorr && max_band_decorr > 0 ) { ivas_dirac_dec_decorrelate_slot( st_ivas->hDirAC, slot, inRe, inIm, decSlotRe, decSlotIm ); @@ -3536,6 +3643,7 @@ static void ivas_dirac_dec_binaural_process_output( #endif #ifdef JBM_TSM_ON_TCS +#ifndef FIX_355_REFACTOR_PARAMBIN_TO_5MS static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked_sf( HEAD_TRACK_DATA_HANDLE hHeadTrackData, float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], @@ -3638,12 +3746,17 @@ static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked_sf( return; } #endif +#endif + #ifdef FIX_355_REFACTOR_PARAMBIN_TO_5MS static void adaptTransportSignalsHeadtracked( HEAD_TRACK_DATA_HANDLE hHeadTrackData, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t nBins, +#ifdef JBM_TSM_ON_TCS + const int16_t nSlots, +#endif float Rmat[3][3] ) { int16_t slot, ch, bin, louderCh; @@ -3675,7 +3788,11 @@ static void adaptTransportSignalsHeadtracked( for ( ch = 0; ch < 2; ch++ ) { ch_nrg[ch] = 0.0f; +#ifdef JBM_TSM_ON_TCS + for ( slot = 0; slot < nSlots; slot++ ) +#else for ( slot = 0; slot < CLDFB_SLOTS_PER_SUBFRAME; slot++ ) +#endif { for ( bin = bin_lo; bin < bin_hi; bin++ ) { @@ -3711,7 +3828,11 @@ static void adaptTransportSignalsHeadtracked( { float band_nrg = 0.0f; +#ifdef JBM_TSM_ON_TCS + for ( slot = 0; slot < nSlots; slot++ ) +#else for ( slot = 0; slot < CLDFB_SLOTS_PER_SUBFRAME; slot++ ) +#endif { for ( bin = bin_lo; bin < bin_hi; bin++ ) { @@ -3737,7 +3858,11 @@ static void adaptTransportSignalsHeadtracked( ene_proc = hHeadTrackData->procChEneIIR[0][band_idx] + hHeadTrackData->procChEneIIR[1][band_idx]; eqVal = fminf( 4.0f, sqrtf( ene_target / fmaxf( 1e-12f, ene_proc ) ) ); +#ifdef JBM_TSM_ON_TCS + for ( slot = 0; slot < nSlots; slot++ ) +#else for ( slot = 0; slot < CLDFB_SLOTS_PER_SUBFRAME; slot++ ) +#endif { for ( ch = 0; ch < 2; ch++ ) { @@ -3887,6 +4012,9 @@ static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked( float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t nBins, +#ifdef JBM_TSM_ON_TCS + const int16_t nSlots, +#endif float Rmat[3][3] ) { int16_t slot, bin, ch; @@ -3922,7 +4050,11 @@ static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked( if ( hHeadTrackData->lrSwitchedNext != hHeadTrackData->lrSwitchedCurrent ) { #ifdef FIX_355_REFACTOR_PARAMBIN_TO_5MS +#ifdef JBM_TSM_ON_TCS + for ( slot = 0; slot < nSlots; slot++ ) +#else for ( slot = 0; slot < CLDFB_SLOTS_PER_SUBFRAME; slot++ ) +#endif #else for ( slot = firstSlot; slot < slotEnd; slot++ ) #endif @@ -3982,7 +4114,11 @@ static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked( if ( hHeadTrackData->lrSwitchedCurrent == 1 ) { #ifdef FIX_355_REFACTOR_PARAMBIN_TO_5MS +#ifdef JBM_TSM_ON_TCS + for ( slot = 0; slot < nSlots; slot++ ) +#else for ( slot = 0; slot < CLDFB_SLOTS_PER_SUBFRAME; slot++ ) +#endif #else for ( slot = firstSlot; slot < slotEnd; slot++ ) #endif diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 89bc8abf4c..b43a048f38 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -600,6 +600,9 @@ void ivas_binaural_reverb_close( void ivas_binaural_reverb_processSubframe( REVERB_STRUCT_HANDLE hReverb, /* i/o: binaural reverb handle */ const int16_t numInChannels, /* i : num input channels to be processed */ +#ifdef JBM_TSM_ON_TCS + const int16_t numSlots, /* i : number of slots to be processed */ +#endif float inReal[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : input CLDFB data real */ float inImag[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : input CLDFB data imag */ float outReal[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* o : output CLDFB data real */ @@ -618,6 +621,7 @@ void ivas_binaural_reverb_processFrame( #endif #ifdef JBM_TSM_ON_TCS +#ifndef FIX_355_REFACTOR_PARAMBIN_TO_5MS void ivas_binaural_reverb_processSlot( REVERB_STRUCT_HANDLE hReverb, /* i/o: binaural reverb handle */ const int16_t numInChannels, /* i : num inputs to be processed */ @@ -628,6 +632,7 @@ void ivas_binaural_reverb_processSlot( const uint8_t offsetSamplesIO /* i : number of offset samples */ ); #endif +#endif ivas_error ivas_reverb_open( REVERB_HANDLE *hReverb, /* i/o: Reverberator handle */ diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb.c index bf0c946d8c..12a8b55ddb 100644 --- a/lib_rend/ivas_reverb.c +++ b/lib_rend/ivas_reverb.c @@ -1627,8 +1627,11 @@ ivas_error ivas_reverb_process( #ifdef FIX_355_REFACTOR_PARAMBIN_TO_5MS void ivas_binaural_reverb_processSubframe( - REVERB_STRUCT_HANDLE hReverb, /* i/o: binaural reverb handle */ - const int16_t numInChannels, /* i : num inputs to be processed */ + REVERB_STRUCT_HANDLE hReverb, /* i/o: binaural reverb handle */ + const int16_t numInChannels, /* i : num inputs to be processed */ +#ifdef JBM_TSM_ON_TCS + const int16_t numSlots, /* i : number of slots to be processed */ +#endif float inReal[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : input CLDFB data real, Comment: This change swaps two first dimensions as first dimension is not constant. */ float inImag[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : input CLDFB data imag */ float outReal[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* o : output CLDFB data real */ @@ -1649,12 +1652,24 @@ void ivas_binaural_reverb_processFrame( /* Declare the required variables */ int16_t idx, bin, ch, sample, invertSampleIndex, tapIdx, *phaseShiftTypePr; float **tapRealPr, **tapImagPr; + push_wmops( "binaural_reverb" ); /* 1) Rotate the data in the loop buffer of the reverberator. * Notice that the audio at the loop buffers is at time-inverted order * for convolution purposes later on. */ for ( bin = 0; bin < hReverb->numBins; bin++ ) { +#ifdef JBM_TSM_ON_TCS + /* Move the data forwards by blockSize (i.e. by the frame size of 16 CLDFB slots) */ + mvr2r( hReverb->loopBufReal[bin], hReverb->loopBufReal[bin] + numSlots, hReverb->loopBufLength[bin] ); + mvr2r( hReverb->loopBufImag[bin], hReverb->loopBufImag[bin] + numSlots, hReverb->loopBufLength[bin] ); + + /* Add the data from the end of the loop to the beginning, with an attenuation factor + * according to RT60. This procedure generates an IIR decaying response. The response + * is decorrelated later on. */ + v_multc( hReverb->loopBufReal[bin] + hReverb->loopBufLength[bin], hReverb->loopAttenuationFactor[bin], hReverb->loopBufReal[bin], numSlots ); + v_multc( hReverb->loopBufImag[bin] + hReverb->loopBufLength[bin], hReverb->loopAttenuationFactor[bin], hReverb->loopBufImag[bin], numSlots ); +#else /* Move the data forwards by blockSize (i.e. by the frame size of 16 CLDFB slots) */ mvr2r( hReverb->loopBufReal[bin], hReverb->loopBufReal[bin] + hReverb->blockSize, hReverb->loopBufLength[bin] ); mvr2r( hReverb->loopBufImag[bin], hReverb->loopBufImag[bin] + hReverb->blockSize, hReverb->loopBufLength[bin] ); @@ -1664,17 +1679,27 @@ void ivas_binaural_reverb_processFrame( * is decorrelated later on. */ v_multc( hReverb->loopBufReal[bin] + hReverb->loopBufLength[bin], hReverb->loopAttenuationFactor[bin], hReverb->loopBufReal[bin], hReverb->blockSize ); v_multc( hReverb->loopBufImag[bin] + hReverb->loopBufLength[bin], hReverb->loopAttenuationFactor[bin], hReverb->loopBufImag[bin], hReverb->blockSize ); +#endif } /* 2) Apply the determined pre-delay to the input audio, and add the delayed audio to the loop. */ idx = hReverb->preDelayBufferIndex; +#ifdef JBM_TSM_ON_TCS + for ( sample = 0; sample < numSlots; sample++ ) +#else for ( sample = 0; sample < hReverb->blockSize; sample++ ) +#endif { #ifndef FIX_355_REFACTOR_PARAMBIN_TO_5MS uint16_t sampleWithOffset; sampleWithOffset = sample + offsetSamplesIO; #endif +#ifdef JBM_TSM_ON_TCS + invertSampleIndex = numSlots - sample - 1; +#else invertSampleIndex = hReverb->blockSize - sample - 1; +#endif + for ( bin = 0; bin < hReverb->numBins; bin++ ) { /* Add from pre-delay buffer a sample to the loop buffer, in a time-inverted order. @@ -1730,17 +1755,41 @@ void ivas_binaural_reverb_processFrame( /* These tap pointers have been determined to point to the loop buffer at sparse locations */ tapRealPr = hReverb->tapPointersReal[bin][ch]; tapImagPr = hReverb->tapPointersImag[bin][ch]; + phaseShiftTypePr = hReverb->tapPhaseShiftType[bin][ch]; /* Flush output */ +#ifdef JBM_TSM_ON_TCS + set_f( hReverb->outputBufferReal[bin][ch], 0.0f, numSlots ); + set_f( hReverb->outputBufferImag[bin][ch], 0.0f, numSlots ); +#else set_f( hReverb->outputBufferReal[bin][ch], 0.0f, hReverb->blockSize ); set_f( hReverb->outputBufferImag[bin][ch], 0.0f, hReverb->blockSize ); +#endif /* Add from temporally decaying sparse tap locations the audio to the output. */ for ( tapIdx = 0; tapIdx < hReverb->taps[bin][ch]; tapIdx++ ) { switch ( phaseShiftTypePr[tapIdx] ) { +#ifdef JBM_TSM_ON_TCS + case 0: /* 0 degrees phase */ + v_add( hReverb->outputBufferReal[bin][ch], tapRealPr[tapIdx], hReverb->outputBufferReal[bin][ch], numSlots ); + v_add( hReverb->outputBufferImag[bin][ch], tapImagPr[tapIdx], hReverb->outputBufferImag[bin][ch], numSlots ); + break; + case 1: /* 90 degrees phase */ + v_sub( hReverb->outputBufferReal[bin][ch], tapImagPr[tapIdx], hReverb->outputBufferReal[bin][ch], numSlots ); + v_add( hReverb->outputBufferImag[bin][ch], tapRealPr[tapIdx], hReverb->outputBufferImag[bin][ch], numSlots ); + break; + case 2: /* 180 degrees phase */ + v_sub( hReverb->outputBufferReal[bin][ch], tapRealPr[tapIdx], hReverb->outputBufferReal[bin][ch], numSlots ); + v_sub( hReverb->outputBufferImag[bin][ch], tapImagPr[tapIdx], hReverb->outputBufferImag[bin][ch], numSlots ); + break; + default: /* 270 degrees phase */ + v_add( hReverb->outputBufferReal[bin][ch], tapImagPr[tapIdx], hReverb->outputBufferReal[bin][ch], numSlots ); + v_sub( hReverb->outputBufferImag[bin][ch], tapRealPr[tapIdx], hReverb->outputBufferImag[bin][ch], numSlots ); + break; +#else case 0: /* 0 degrees phase */ v_add( hReverb->outputBufferReal[bin][ch], tapRealPr[tapIdx], hReverb->outputBufferReal[bin][ch], hReverb->blockSize ); v_add( hReverb->outputBufferImag[bin][ch], tapImagPr[tapIdx], hReverb->outputBufferImag[bin][ch], hReverb->blockSize ); @@ -1757,6 +1806,7 @@ void ivas_binaural_reverb_processFrame( v_add( hReverb->outputBufferReal[bin][ch], tapImagPr[tapIdx], hReverb->outputBufferReal[bin][ch], hReverb->blockSize ); v_sub( hReverb->outputBufferImag[bin][ch], tapRealPr[tapIdx], hReverb->outputBufferImag[bin][ch], hReverb->blockSize ); break; +#endif } } } @@ -1766,7 +1816,11 @@ void ivas_binaural_reverb_processFrame( { if ( hReverb->useBinauralCoherence ) { +#ifdef JBM_TSM_ON_TCS + for ( sample = 0; sample < numSlots; sample++ ) +#else for ( sample = 0; sample < hReverb->blockSize; sample++ ) +#endif { float leftRe, rightRe, leftIm, rightIm; @@ -1787,15 +1841,23 @@ void ivas_binaural_reverb_processFrame( /* 4) Write data to output */ for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { +#ifdef JBM_TSM_ON_TCS + for ( sample = 0; sample < numSlots; sample++ ) +#else for ( sample = 0; sample < hReverb->blockSize; sample++ ) +#endif { #ifndef FIX_355_REFACTOR_PARAMBIN_TO_5MS uint16_t sampleWithOffset; sampleWithOffset = sample + offsetSamplesIO; #endif - /* Audio was in the temporally inverted order for convolution, re-invert audio to output */ +/* Audio was in the temporally inverted order for convolution, re-invert audio to output */ +#ifdef JBM_TSM_ON_TCS + invertSampleIndex = numSlots - sample - 1; +#else invertSampleIndex = hReverb->blockSize - sample - 1; +#endif #ifdef FIX_355_REFACTOR_PARAMBIN_TO_5MS for ( bin = 0; bin < hReverb->numBins; bin++ ) @@ -1823,10 +1885,12 @@ void ivas_binaural_reverb_processFrame( } } + pop_wmops(); return; } #ifdef JBM_TSM_ON_TCS +#ifndef FIX_355_REFACTOR_PARAMBIN_TO_5MS /*------------------------------------------------------------------------- * ivas_binaural_reverb_processSlot() * @@ -1851,6 +1915,7 @@ void ivas_binaural_reverb_processSlot( assert( hReverb->blockSize == 1 ); #endif + push_wmops( "binaural_reverb" ); /* 1) Rotate the data in the loop buffer of the reverberator. * Notice that the audio at the loop buffers is at time-inverted order * for convolution purposes later on. */ @@ -1989,9 +2054,11 @@ void ivas_binaural_reverb_processSlot( } } + pop_wmops(); return; } #endif +#endif /*------------------------------------------------------------------------- * ivas_binaural_reverb_open() diff --git a/lib_rend/ivas_sba_rendering.c b/lib_rend/ivas_sba_rendering.c index e8c6162142..c549461c37 100644 --- a/lib_rend/ivas_sba_rendering.c +++ b/lib_rend/ivas_sba_rendering.c @@ -233,6 +233,9 @@ void ivas_sba_prototype_renderer( int16_t firstSlot, slotEnd, firstInCh, inChEnd, firstOutCh, outChEnd; int16_t sf_idx; #endif +#ifdef JBM_TSM_ON_TCS + int16_t slot_idx_start, md_idx; +#endif push_wmops( "ivas_sba_prototype_renderer" ); @@ -247,6 +250,9 @@ void ivas_sba_prototype_renderer( num_cldfb_bands = hSpar->hFbMixer->pFb->fb_bin_to_band.num_cldfb_bands; numch_in = hSpar->hFbMixer->fb_cfg->num_in_chans; numch_out = hSpar->hFbMixer->fb_cfg->num_out_chans; +#ifdef JBM_TSM_ON_TCS + slot_idx_start = hSpar->slots_rendered; +#endif if ( st_ivas->nchan_transport == 1 ) { @@ -265,10 +271,19 @@ void ivas_sba_prototype_renderer( /* Apply mixing matrix */ #ifdef FIX_355_REFACTOR_PARAMBIN_TO_5MS +#ifdef JBM_TSM_ON_TCS + for ( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) +#else for ( ts = 0; ts < CLDFB_SLOTS_PER_SUBFRAME; ts++ ) +#endif { /* determine SPAR parameters for this time slot */ +#ifdef JBM_TSM_ON_TCS + md_idx = hSpar->render_to_md_map[ts + slot_idx_start]; + ivas_spar_get_parameters( hSpar, hDecoderConfig, md_idx, numch_out, numch_in, num_spar_bands, mixer_mat ); +#else ivas_spar_get_parameters( hSpar, hDecoderConfig, ts + subframe * CLDFB_SLOTS_PER_SUBFRAME, numch_out, numch_in, num_spar_bands, mixer_mat ); +#endif for ( cldfb_band = 0; cldfb_band < num_cldfb_bands; cldfb_band++ ) { @@ -311,8 +326,34 @@ void ivas_sba_prototype_renderer( inIm[out_ch][ts][cldfb_band] = out_im[out_ch]; } } +#ifdef JBM_TSM_ON_TCS + /* Update mixing matrices */ + if ( ( ( slot_idx_start + ts + 1 ) == hSpar->num_slots ) || ( ( md_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME ) != ( hSpar->render_to_md_map[ts + slot_idx_start + 1] / JBM_CLDFB_SLOTS_IN_SUBFRAME ) ) ) + { + /* we have crossed an unadapted parameter sf border, update previous mixing matrices */ + int16_t md_sf = md_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME; + hSpar->i_subframe++; + hSpar->i_subframe = min( hSpar->i_subframe, MAX_PARAM_SPATIAL_SUBFRAMES ); + mvr2r( hSpar->hMdDec->mixer_mat_prev[1][0][0], hSpar->hMdDec->mixer_mat_prev[0][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); + mvr2r( hSpar->hMdDec->mixer_mat_prev[2][0][0], hSpar->hMdDec->mixer_mat_prev[1][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); + mvr2r( hSpar->hMdDec->mixer_mat_prev[3][0][0], hSpar->hMdDec->mixer_mat_prev[2][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); + mvr2r( hSpar->hMdDec->mixer_mat_prev[4][0][0], hSpar->hMdDec->mixer_mat_prev[3][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); + + for ( out_ch = 0; out_ch < numch_out; out_ch++ ) + { + for ( in_ch = 0; in_ch < numch_in; in_ch++ ) + { + for ( b = 0; b < num_spar_bands; b++ ) + { + hSpar->hMdDec->mixer_mat_prev[4][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat[out_ch][in_ch][b + md_sf * IVAS_MAX_NUM_BANDS]; + } + } + } + } +#endif } +#ifndef JBM_TSM_ON_TCS /* Update mixing matrices */ hSpar->i_subframe++; hSpar->i_subframe = min( hSpar->i_subframe, MAX_PARAM_SPATIAL_SUBFRAMES ); @@ -331,6 +372,7 @@ void ivas_sba_prototype_renderer( } } } +#endif #else for ( ts = firstSlot; ts < slotEnd; ts++ ) { diff --git a/scripts/config/ivas_modes.json b/scripts/config/ivas_modes.json index d6bce79929..d4f1e107cc 100644 --- a/scripts/config/ivas_modes.json +++ b/scripts/config/ivas_modes.json @@ -2158,7 +2158,7 @@ "table_name": "ISM2@{table_bitrate} kbps RS {bandwidth}", "nummetadata": 2, "metadatafilenames": [ - "stvISM{mdi}.csv.csv" + "stvISM{mdi}.csv" ], "rs": true, "amr": false, @@ -2318,7 +2318,7 @@ "table_name": "ISM3@{table_bitrate} kbps {bandwidth}", "nummetadata": 3, "metadatafilenames": [ - "stvISM{mdi}.csv.csv" + "stvISM{mdi}.csv" ], "rs": true, "amr": false, -- GitLab From 5fb1890dbddaf9f565a74ed6b599af9c21d4bedb Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Wed, 10 May 2023 12:34:21 +0200 Subject: [PATCH 21/39] fix JBM MASA BR switching --- lib_dec/ivas_masa_dec.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index e4fafa2d25..094085d354 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -1254,20 +1254,22 @@ ivas_error ivas_masa_dec_reconfigure( ivas_masa_set_elements( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &tmp, &tmp, &tmp ); #ifdef JBM_TSM_ON_TCS - if ( st_ivas->hDecoderConfig->voip_active == 1 && st_ivas->renderer_type != RENDERER_DISABLE ) + if ( st_ivas->hDecoderConfig->voip_active == 1 ) { int16_t tc_nchan_to_allocate; int16_t tc_nchan_transport; + TC_BUFFER_MODE buffer_mode_new; + buffer_mode_new = ivas_jbm_dec_get_tc_buffer_mode( st_ivas ); tc_nchan_transport = ivas_jbm_dec_get_num_tc_channels( st_ivas ); tc_nchan_to_allocate = tc_nchan_transport; if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) { tc_nchan_to_allocate = 2 * BINAURAL_CHANNELS; } - if ( tc_nchan_transport != st_ivas->hTcBuffer->nchan_transport_jbm || tc_nchan_to_allocate != st_ivas->hTcBuffer->nchan_transport_internal ) + 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, TC_BUFFER_MODE_RENDERER, tc_nchan_transport, tc_nchan_to_allocate, tc_nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_jbm_dec_tc_buffer_reconfigure( st_ivas, buffer_mode_new, tc_nchan_transport, tc_nchan_to_allocate, tc_nchan_to_allocate, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) { return error; } -- GitLab From 1d5c76a4d571e5da45a66e54d3641e2b9cfcb6a7 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Wed, 10 May 2023 12:52:28 +0200 Subject: [PATCH 22/39] fix McMASA 3TC binaural rendering --- lib_rend/ivas_dirac_dec_binaural_functions.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index aa3ad7f85b..4b0279fb2d 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -576,16 +576,23 @@ void ivas_dirac_dec_binaural( float *p_output[MAX_OUTPUT_CHANNELS]; int16_t ch; int16_t slot_size; + int16_t numInChannels; slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); for ( ch = 0; ch < 2 * BINAURAL_CHANNELS; ch++ ) { p_output[ch] = &output_f[ch][0]; } - for ( ch = 0; ch < nchan_transport; ch++ ) + numInChannels = nchan_transport; + if ( st_ivas->hOutSetup.separateChannelEnabled ) + { + numInChannels++; + } + 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->sba_mode == SBA_MODE_SPAR ) { -- GitLab From 9857f232a04f73cb165c04cb5d0cf462c727b7bc Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Thu, 11 May 2023 10:52:28 +0200 Subject: [PATCH 23/39] revert last commits accidental deletion of ivas_dirac_dec.c --- lib_dec/ivas_ism_param_dec.c | 17 +++++++++++++---- lib_dec/ivas_spar_md_dec.c | 2 +- lib_dec/lib_dec.c | 3 +-- lib_rend/ivas_dirac_dec_binaural_functions.c | 1 - 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 1d80767e77..0ce3ad7bef 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -1190,7 +1190,6 @@ void ivas_param_ism_dec( for ( subframe_idx = 0; subframe_idx < hDirAC->nb_subframes; subframe_idx++ ) { #ifdef JBM_TSM_ON_TCS - /* TODO: JBM just a quick fix to gewt SBA running, change to the right thing later...*/ uint16_t slot_idx_start = subframe_idx * hDirAC->subframe_nbslots[subframe_idx]; #else uint16_t slot_idx_start = subframe_idx * hDirAC->subframe_nbslots; @@ -1317,9 +1316,20 @@ void ivas_ism_dec_digest_tc( if ( ( st_ivas->hDecoderConfig->output_Fs / (int32_t) FRAMES_PER_SECOND ) == st_ivas->hTcBuffer->n_samples_available ) { int16_t interpolator_length = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / (int32_t) FRAMES_PER_SECOND ); - for ( i = 0; i < interpolator_length; i++ ) + if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) { - st_ivas->hIsmRendererData->interpolator[i] = (float) i / ( (float) interpolator_length - 1 ); + st_ivas->hIsmRendererData->interpolator[0] = 0.0f; + for ( i = 1; i < interpolator_length; i++ ) + { + st_ivas->hIsmRendererData->interpolator[i] = st_ivas->hIsmRendererData->interpolator[i - 1] + 1.f / ( interpolator_length - 1 ); + } + } + else + { + for ( i = 0; i < interpolator_length; i++ ) + { + st_ivas->hIsmRendererData->interpolator[i] = (float) i / ( (float) interpolator_length - 1 ); + } } } else @@ -1525,7 +1535,6 @@ static void ivas_ism_param_dec_render_sf( Decoder_Struct *st_ivas, float *Cldfb_ImagBuffer_in[PARAM_ISM_MAX_DMX]; DIRAC_DEC_HANDLE hDirAC; - /* TODO: JBM just a quick fix to gewt SBA running, change to the right thing later...*/ int16_t slot_idx_start; int16_t idx_in; int16_t idx_lfe; diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec.c index ca3f926e96..71ac89a08d 100644 --- a/lib_dec/ivas_spar_md_dec.c +++ b/lib_dec/ivas_spar_md_dec.c @@ -2957,7 +2957,7 @@ void ivas_spar_to_dirac( hDirAC->energy_ratio1[block][b] = en_ratio; tmp_write_idx_band = tmp_write_idx_param_band; - /* TODO: JBM */ + if ( hDirAC->hConfig->dec_param_estim == FALSE ) { hDirAC->elevation[tmp_write_idx_band][b] = ele_dith; diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index f99209a1c5..03de9374dc 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -890,8 +890,7 @@ static ivas_error IVAS_DEC_Setup( return error; } } - /* TODO: JBM replace with a function that gets the real number of TCs generated, - depending of remapping, td rendering already done in the TC decoding part, ....*/ + *nTransportChannels = (uint8_t) st_ivas->hTcBuffer->nchan_transport_jbm; *nTcBufferGranularity = (uint16_t) st_ivas->hTcBuffer->n_samples_granularity; *nOutChannels = (uint8_t) st_ivas->hDecoderConfig->nchan_out; diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 4b0279fb2d..33287b4207 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -2759,7 +2759,6 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric #endif { #ifdef JBM_TSM_ON_TCS - /* TODO: JBM this needs to be adapted to the variable size subframes */ int16_t slotThis = slot + slot_idx_start; #else int16_t slotThis = slot + ( hDirAC->subframe_nbslots * subframe ); -- GitLab From 480a38cf6b7ffd462fe8e1c5f2c73994aeb07e8d Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Thu, 11 May 2023 14:13:08 +0200 Subject: [PATCH 24/39] fix EXT out for variable speed mode --- lib_dec/lib_dec.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 03de9374dc..64a27298fa 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -648,12 +648,6 @@ ivas_error IVAS_DEC_EnableVoIP( #ifdef VARIABLE_SPEED_DECODING if ( hIvasDec->hVoIP->mode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED ) { - if ( pcmdsp_fifo_create( &hIvasDec->hVoIP->hFifoOut ) != 0 || - pcmdsp_fifo_init( hIvasDec->hVoIP->hFifoOut, (uint16_t) ( hDecoderConfig->output_Fs * 4 / FRAMES_PER_SEC ) /* 4 frames */, hDecoderConfig->nchan_out, sizeof( int16_t ) ) != 0 ) - { - return IVAS_ERR_INIT_ERROR; - } - /* we instantly need a new frame */ hIvasDec->hVoIP->needNewFrame = true; } #endif @@ -3172,6 +3166,16 @@ ivas_error IVAS_DEC_VoIP_reconfigure( IVAS_DEC_HANDLE hIvasDec, const uint16_t n return IVAS_ERR_INIT_ERROR; } } +#ifdef VARIABLE_SPEED_DECODING + else if ( hIvasDec->hVoIP->mode == IVAS_DEC_VOIP_MODE_VARIABLE_SPEED ) + { + if ( pcmdsp_fifo_create( &hIvasDec->hVoIP->hFifoOut ) != 0 || + pcmdsp_fifo_init( hIvasDec->hVoIP->hFifoOut, (uint16_t) ( hDecoderConfig->output_Fs * 4 / FRAMES_PER_SEC ) /* 4 frames */, hDecoderConfig->nchan_out, sizeof( int16_t ) ) != 0 ) + { + return IVAS_ERR_INIT_ERROR; + } + } +#endif if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) { if ( apa_set_evs_compat_mode( hIvasDec->hVoIP->hTimeScaler, true ) != 0 ) -- GitLab From 4a48efe98bcada01508d4e0164752398971039dc Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Thu, 11 May 2023 16:30:21 +0200 Subject: [PATCH 25/39] small fixes for HO-DirAC, still not BE --- lib_com/ivas_prot.h | 3 ++ lib_dec/ivas_dirac_dec.c | 3 ++ lib_dec/ivas_dirac_output_synthesis_dec.c | 49 +++++++++++++++++++---- lib_dec/ivas_spar_decoder.c | 23 ++++++++++- 4 files changed, 70 insertions(+), 8 deletions(-) diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index c4b297c054..5a3947ec19 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -3850,6 +3850,9 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( const float *onset_filter #ifdef HODIRAC , +#ifdef JBM_TSM_ON_TCS + const int16_t md_idx, +#endif const int16_t hodirac /* i: flag for sector-based processing */ #endif ); diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 0317eaa4de..3186b1ebf3 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -3626,6 +3626,9 @@ void ivas_dirac_dec_render_sf( p_onset_filter #ifdef HODIRAC , +#ifdef JBM_TSM_ON_TCS + md_idx, +#endif st_ivas->sba_analysis_order > 1 && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_256k #endif ); diff --git a/lib_dec/ivas_dirac_output_synthesis_dec.c b/lib_dec/ivas_dirac_output_synthesis_dec.c index a3f5ef1201..e7ccaeaba7 100644 --- a/lib_dec/ivas_dirac_output_synthesis_dec.c +++ b/lib_dec/ivas_dirac_output_synthesis_dec.c @@ -598,7 +598,7 @@ void ivas_dirac_dec_output_synthesis_process_slot( const int16_t nchan_transport /* i : number of transport channels*/ #if !defined( HODIRAC ) || defined( JBM_TSM_ON_TCS ) , - const int16_t index_slot + const int16_t md_idx #endif #ifdef HODIRAC , @@ -655,7 +655,7 @@ void ivas_dirac_dec_output_synthesis_process_slot( #ifdef JBM_TSM_ON_TCS azimuth, elevation, - index_slot, + md_idx, #endif NULL, 2, @@ -666,6 +666,25 @@ void ivas_dirac_dec_output_synthesis_process_slot( { if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { +#ifdef JBM_TSM_ON_TCS + v_multc( hDirAC->energy_ratio1[md_idx], -1.f, aux_buf, num_freq_bands ); + v_addc( aux_buf, 1.f, aux_buf, num_freq_bands ); + mvr2r( hDirAC->energy_ratio1[md_idx], + h_dirac_output_synthesis_state->direct_power_factor, + num_freq_bands ); + mvr2r( aux_buf, + h_dirac_output_synthesis_state->diffuse_power_factor, + num_freq_bands ); + + v_multc( hDirAC->energy_ratio2[md_idx], -1.f, aux_buf, num_freq_bands ); + v_addc( aux_buf, 1.f, aux_buf, num_freq_bands ); + mvr2r( hDirAC->energy_ratio2[md_idx], + &h_dirac_output_synthesis_state->direct_power_factor[hDirAC->num_freq_bands], + num_freq_bands ); + mvr2r( aux_buf, + &h_dirac_output_synthesis_state->diffuse_power_factor[hDirAC->num_freq_bands], + num_freq_bands ); +#else v_multc( hDirAC->energy_ratio1[hDirAC->dirac_read_idx], -1.f, aux_buf, num_freq_bands ); v_addc( aux_buf, 1.f, aux_buf, num_freq_bands ); mvr2r( hDirAC->energy_ratio1[hDirAC->dirac_read_idx], @@ -683,14 +702,23 @@ void ivas_dirac_dec_output_synthesis_process_slot( mvr2r( aux_buf, &h_dirac_output_synthesis_state->diffuse_power_factor[hDirAC->num_freq_bands], num_freq_bands ); +#endif } else { +#ifdef JBM_TSM_ON_TCS + ivas_dirac_dec_compute_gain_factors( num_freq_bands, + hDirAC->diffuseness_vector[md_idx], + h_dirac_output_synthesis_params->max_band_decorr, + h_dirac_output_synthesis_state->direct_power_factor, + h_dirac_output_synthesis_state->diffuse_power_factor ); +#else ivas_dirac_dec_compute_gain_factors( num_freq_bands, hDirAC->diffuseness_vector[hDirAC->dirac_read_idx], h_dirac_output_synthesis_params->max_band_decorr, h_dirac_output_synthesis_state->direct_power_factor, h_dirac_output_synthesis_state->diffuse_power_factor ); +#endif } } else // ( hDirAC->hConfig->dec_param_estim == TRUE ) @@ -724,7 +752,7 @@ void ivas_dirac_dec_output_synthesis_process_slot( { for ( i = 0; i < hDirAC->num_freq_bands; i++ ) { - surCohRatio[i] = hDirAC->surroundingCoherence[index_slot][i]; + surCohRatio[i] = hDirAC->surroundingCoherence[md_idx][i]; } } else @@ -749,7 +777,7 @@ void ivas_dirac_dec_output_synthesis_process_slot( for ( i = 0; i < hDirAC->num_freq_bands; i++ ) { dirEne = hDirAC->h_output_synthesis_psd_state.direct_power_factor[i]; - surCohEner = hDirAC->h_output_synthesis_psd_state.diffuse_power_factor[i] * hDirAC->surroundingCoherence[index_slot][i]; + surCohEner = hDirAC->h_output_synthesis_psd_state.diffuse_power_factor[i] * hDirAC->surroundingCoherence[md_idx][i]; hDirAC->h_output_synthesis_psd_state.diffuse_power_factor[i] -= surCohEner; hDirAC->h_output_synthesis_psd_state.direct_power_factor[i] += surCohEner; @@ -773,7 +801,7 @@ void ivas_dirac_dec_output_synthesis_process_slot( #endif azimuth, elevation, - index_slot, + md_idx, #ifdef MASA_PARAMBIN_SF_MAP NULL, #else @@ -987,10 +1015,13 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( const int16_t nchan_transport, /* i : number of transport channels */ #ifdef JBM_TSM_ON_TCS const int16_t nbslots, /* i : number of slots to process */ -#endif +#endif const float *onset_filter #ifdef HODIRAC , +#ifdef JBM_TSM_ON_TCS + const int16_t md_idx, +#endif const int16_t hodirac /* i: flag for sector-based processing */ #endif ) @@ -1032,7 +1063,11 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( nchan_transport_foa = min( 4, nchan_transport ); #ifdef HODIRAC +#ifdef JBM_TSM_ON_TCS + diffuseness = hDirAC->diffuseness_vector[md_idx]; +#else diffuseness = hDirAC->diffuseness_vector[hDirAC->dirac_read_idx]; +#endif #endif /*-----------------------------------------------------------------* @@ -1098,7 +1133,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( #if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) if ( hDirAC->voip_active == 0 && hDirAC->hConfig->dec_param_estim == FALSE ) #else - if ( hDirAC->hConfig->dec_param_estim == FALSE ) + if ( hDirAC->hConfig->dec_param_estim == FALSE ) #endif { /*Direct gain*/ diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index ffe8240750..7f0b29a2f1 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -1227,7 +1227,7 @@ void ivas_spar_dec_set_render_params( ivas_spar_dec_gen_umx_mat( hSpar->hMdDec, nchan_transport, num_bands_out, st_ivas->bfi #ifdef SPAR_TUNING , - MAX_PARAM_SPATIAL_SUBFRAMES + ivas_get_spar_dec_md_num_subframes( st_ivas->sba_order, st_ivas->hDecoderConfig->ivas_total_brate ) #endif ); @@ -1350,10 +1350,31 @@ void ivas_spar_dec_upmixer( if ( hSpar->hMdDec->td_decorr_flag ) { ivas_td_decorr_process( hSpar->hTdDecorr, st_ivas->hTcBuffer->tc, pPcm_tmp, output_frame ); +#ifdef SPAR_TUNING + if ( hSpar->hTdDecorr->num_apd_outputs >= ( nchan_internal - nchan_transport ) ) + { + for ( i = 0; i < nchan_internal - nchan_transport; i++ ) + { + mvr2r( pPcm_tmp[hSpar->hTdDecorr->num_apd_outputs - 1 - i], st_ivas->hTcBuffer->tc[nchan_internal - 1 - i], output_frame ); + } + } + else + { + for ( i = 0; i < nchan_internal - nchan_transport; i++ ) + { + set_zero( st_ivas->hTcBuffer->tc[nchan_internal - 1 - i], output_frame ); + } + for ( i = 0; i < hSpar->hTdDecorr->num_apd_outputs; i++ ) + { + mvr2r( pPcm_tmp[hSpar->hTdDecorr->num_apd_outputs - 1 - i], st_ivas->hTcBuffer->tc[nchan_internal - 1 - i], output_frame ); + } + } +#else for ( i = 0; i < nchan_internal - nchan_transport; i++ ) { mvr2r( pPcm_tmp[hSpar->hTdDecorr->num_apd_outputs - 1 - i], st_ivas->hTcBuffer->tc[nchan_internal - 1 - i], output_frame ); } +#endif } -- GitLab From 5c4e3a519ee8d8c56715dcf42d78dcea78847669 Mon Sep 17 00:00:00 2001 From: Dominik Weckbecker Date: Thu, 11 May 2023 17:38:53 +0200 Subject: [PATCH 26/39] preliminarily fix sanitizer errors --- lib_dec/ivas_dirac_dec.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 3186b1ebf3..274254df61 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2935,6 +2935,14 @@ void ivas_dirac_dec_render_sf( #endif #ifdef JBM_TSM_ON_TCS +#ifdef JBM_TSM_ON_TCS +#ifdef MASA_PARAMBIN_SF_MAP + md_idx = hDirAC->render_to_md_map[subframe_idx]; +#else + md_idx = hDirAC->render_to_md_map[slot_idx_start]; +#endif +#endif + /* Another workaround for self test BE */ if ( st_ivas->hHeadTrackData && st_ivas->hDecoderConfig->voip_active == 0 ) { @@ -3037,13 +3045,7 @@ void ivas_dirac_dec_render_sf( if ( hDirAC->hConfig->dec_param_estim == FALSE ) #endif { -#ifdef JBM_TSM_ON_TCS -#ifdef MASA_PARAMBIN_SF_MAP - md_idx = hDirAC->render_to_md_map[subframe_idx]; -#else - md_idx = hDirAC->render_to_md_map[slot_idx_start]; -#endif -#endif + /* compute response */ if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD ) { -- GitLab From 22591097624219f6c2772f2785bd5a6329c69b9e Mon Sep 17 00:00:00 2001 From: Dominik Weckbecker Date: Thu, 11 May 2023 18:18:47 +0200 Subject: [PATCH 27/39] fix noumber of SPAR channels --- lib_com/ivas_cnst.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 5640ded12b..f2673408c9 100755 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -209,7 +209,7 @@ typedef enum #define DEFAULT_JBM_CLDFB_TIMESLOTS 16 #define MAX_JBM_L_FRAME48k 1920 #define MAX_JBM_L_FRAME_NS 40000000L -#define MAX_SPAR_INTERNAL_CHANNELS FOA_CHANNELS + 2* ( IVAS_MAX_SBA_ORDER -1 ) +#define MAX_SPAR_INTERNAL_CHANNELS IVAS_SPAR_MAX_CH #define MAX_CLDFB_DIGEST_CHANNELS 4 typedef enum { -- GitLab From ab6eba33f55ef22e3b17bf2a3f33ef9e59d88f72 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Fri, 12 May 2023 09:25:48 +0200 Subject: [PATCH 28/39] Fix HO-DirAC CBR, SBA BR switching still no BE --- lib_dec/ivas_dirac_dec.c | 147 ++++++++++++++++++++++++--------------- 1 file changed, 90 insertions(+), 57 deletions(-) diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 274254df61..a19acac344 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2933,15 +2933,22 @@ void ivas_dirac_dec_render_sf( for ( subframe_idx = sf1; subframe_idx < sf2; subframe_idx++ ) { #endif -#ifdef JBM_TSM_ON_TCS - #ifdef JBM_TSM_ON_TCS #ifdef MASA_PARAMBIN_SF_MAP - md_idx = hDirAC->render_to_md_map[subframe_idx]; + if ( hDirAC->hConfig->dec_param_estim == FALSE ) + { + md_idx = hDirAC->render_to_md_map[subframe_idx]; + } + else + { + md_idx = hDirAC->render_to_md_map[slot_idx_start]; + } #else md_idx = hDirAC->render_to_md_map[slot_idx_start]; #endif #endif +#ifdef JBM_TSM_ON_TCS + /* Another workaround for self test BE */ if ( st_ivas->hHeadTrackData && st_ivas->hDecoderConfig->voip_active == 0 ) @@ -3163,6 +3170,14 @@ void ivas_dirac_dec_render_sf( { #ifdef JBM_TSM_ON_TCS index_slot = slot_idx_start + slot_idx; + if ( hDirAC->hConfig->dec_param_estim == TRUE ) + { + md_idx = hDirAC->render_to_md_map[index_slot]; + } + else + { + md_idx = hDirAC->render_to_md_map[subframe_idx]; + } #else index_slot = subframe_idx * hDirAC->subframe_nbslots + slot_idx; #endif @@ -3181,11 +3196,19 @@ void ivas_dirac_dec_render_sf( for ( ch = 0; ch < nchan_transport; ch++ ) { #ifdef JBM_TSM_ON_TCS +#ifdef SPAR_TUNING + cldfbAnalysis_ts( &( st_ivas->hTcBuffer->tc[hDirAC->sba_map_tc[ch]][hDirAC->num_freq_bands * index_slot] ), + Cldfb_RealBuffer[ch][0], + Cldfb_ImagBuffer[ch][0], + hDirAC->num_freq_bands, + st_ivas->cldfbAnaDec[ch] ); +#else cldfbAnalysis_ts( &( st_ivas->hTcBuffer->tc[sba_map_tc[ch]][hDirAC->num_freq_bands * index_slot] ), Cldfb_RealBuffer[ch][0], Cldfb_ImagBuffer[ch][0], hDirAC->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); +#endif #else #ifdef SPAR_TUNING cldfbAnalysis_ts( &( output_f[hDirAC->sba_map_tc[ch]][hDirAC->num_freq_bands * index_slot] ), @@ -3233,11 +3256,7 @@ void ivas_dirac_dec_render_sf( Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS - 1], Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS - 1], slot_idx, #ifdef JBM_TSM_ON_TCS -#ifdef MASA_PARAMBIN_SF_MAP - hDirAC->render_to_md_map[subframe_idx], -#else - hDirAC->render_to_md_map[index_slot], -#endif + md_idx, #else subframe_idx, #endif @@ -3559,7 +3578,7 @@ void ivas_dirac_dec_render_sf( st_ivas->hVBAPdata, hDirAC->hOutSetup, nchan_transport, - hDirAC->render_to_md_map[index_slot], + md_idx, #ifdef HODIRAC st_ivas->sba_analysis_order > 1 && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_256k @@ -3586,7 +3605,7 @@ void ivas_dirac_dec_render_sf( st_ivas->hVBAPdata, hDirAC->hOutSetup, nchan_transport, - hDirAC->render_to_md_map[index_slot], + md_idx, #ifdef HODIRAC st_ivas->sba_analysis_order > 1 && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_256k @@ -3615,6 +3634,64 @@ void ivas_dirac_dec_render_sf( #endif #ifdef JBM_TSM_ON_TCS ivas_dirac_dec_output_synthesis_get_interpolator( &hDirAC->h_output_synthesis_psd_params, hDirAC->subframe_nbslots[subframe_idx] ); +#ifdef MASA_PARAMBIN_SF_MAP + if ( hDirAC->hConfig->dec_param_estim == FALSE ) + { + md_idx = hDirAC->render_to_md_map[subframe_idx]; + } + else + { + md_idx = hDirAC->render_to_md_map[slot_idx_start]; + } +#else + md_idx = hDirAC->render_to_md_map[slot_idx_start]; +#endif + +#ifdef MASA_PARAMBIN_SF_MAP + /* Workaround for BE (should be gone when #393 is adressed and diffuseness index in the gain SHD renderer with HO-DirAC is fixed) */ + /* :TODO: remove */ + /* get the correct md index for the diffuseness in direction smoothing and HO-DirAC, it is always the first slot of the next subframe*/ + if ( slot_idx_start + hDirAC->subframe_nbslots[subframe_idx] == hDirAC->num_slots ) + { + /* we are at the end, get the next one using the normal dirac read idx...*/ + if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) + { + md_idx = ( hDirAC->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % hDirAC->dirac_md_buffer_length; + } + else + { + md_idx = ( hDirAC->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % hDirAC->dirac_md_buffer_length; + } + } + else + { + if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) + { + md_idx = hDirAC->render_to_md_map[slot_idx_start + hDirAC->subframe_nbslots[subframe_idx]]; + } + else + { + md_idx = hDirAC->render_to_md_map[subframe_idx + 1]; + } + } +#else + if ( slot_idx_start + hDirAC->subframe_nbslots[subframe_idx] == hDirAC->num_slots ) + { + /* we are at the end, get the next one using the normal dirac read idx...*/ + if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) + { + md_idx = ( hDirAC->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % hDirAC->dirac_md_buffer_length; + } + else + { + md_idx = ( hDirAC->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % hDirAC->dirac_md_buffer_length; + } + } + else + { + md_idx = hDirAC->render_to_md_map[slot_idx_start + hDirAC->subframe_nbslots[subframe_idx]]; + } +#endif #endif if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { @@ -3639,9 +3716,7 @@ void ivas_dirac_dec_render_sf( { /* Determine encoding quality based additional smoothing factor */ float qualityBasedSmFactor = 1.0f; -#ifdef JBM_TSM_ON_TCS - int16_t diff_md_idx; -#endif + if ( st_ivas->hMasa != NULL ) { qualityBasedSmFactor = st_ivas->hMasa->data.dir_decode_quality; @@ -3659,49 +3734,7 @@ void ivas_dirac_dec_render_sf( mvr2r( diffuseness_vector[slot_idx], hDirAC->diffuseness_vector[hDirAC->render_to_md_map[slot_idx + slot_idx_start]], num_freq_bands ); } } - /* get the correct md index for the direction smoothing, it is always the first slot of the next subframe*/ -#ifdef MASA_PARAMBIN_SF_MAP - if ( slot_idx_start + hDirAC->subframe_nbslots[subframe_idx] == hDirAC->num_slots ) - { - /* we are at the end, get the next one using the normal dirac read idx...*/ - if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) - { - diff_md_idx = ( hDirAC->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % hDirAC->dirac_md_buffer_length; - } - else - { - diff_md_idx = ( hDirAC->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % hDirAC->dirac_md_buffer_length; - } - } - else - { - if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) - { - diff_md_idx = hDirAC->render_to_md_map[slot_idx_start + hDirAC->subframe_nbslots[subframe_idx]]; - } - else - { - diff_md_idx = hDirAC->render_to_md_map[subframe_idx + 1]; - } - } -#else - if ( slot_idx_start + hDirAC->subframe_nbslots[subframe_idx] == hDirAC->num_slots ) - { - /* we are at the end, get the next one using the normal dirac read idx...*/ - if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) - { - diff_md_idx = ( hDirAC->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % hDirAC->dirac_md_buffer_length; - } - else - { - diff_md_idx = ( hDirAC->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % hDirAC->dirac_md_buffer_length; - } - } - else - { - diff_md_idx = hDirAC->render_to_md_map[slot_idx_start + hDirAC->subframe_nbslots[subframe_idx]]; - } -#endif + #endif ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( Cldfb_RealBuffer, @@ -3709,7 +3742,7 @@ void ivas_dirac_dec_render_sf( hDirAC, #ifdef JBM_TSM_ON_TCS hDirAC->subframe_nbslots[subframe_idx], - diff_md_idx, + md_idx, #endif reference_power_smooth, qualityBasedSmFactor ); -- GitLab From d2ee4f8e682f8d28ed02e57f4d34a86e947ad5af Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Fri, 12 May 2023 10:53:23 +0200 Subject: [PATCH 29/39] fix SBA JBM BR switching --- lib_dec/ivas_sba_dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index a1c03ab008..28920ccf53 100755 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -398,7 +398,7 @@ ivas_error ivas_sba_dec_reconfigure( } else if ( st_ivas->sba_mode == SBA_MODE_SPAR ) { - st_ivas->nchan_transport = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order + tc_nchan_to_allocate = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order #ifdef SPAR_TUNING , st_ivas->hDecoderConfig->ivas_total_brate -- GitLab From 8a41c3f5d184f8c66fb0243da7720801fc73b2b2 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Fri, 12 May 2023 11:30:58 +0200 Subject: [PATCH 30/39] fix compile errors in the JBM path --- lib_dec/ivas_jbm_dec.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 361754f2e3..13a062fd93 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -131,7 +131,11 @@ ivas_error ivas_jbm_dec_tc( } if ( st_ivas->renderer_type == RENDERER_MC && st_ivas->hDecoderConfig->nchan_out == 1 ) { +#ifdef MC_PARAMUPMIX_MODE + ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, output_frame, p_output, p_output ); +#else ivas_ls_setup_conversion( st_ivas, output_frame, p_output, p_output ); +#endif } } else if ( st_ivas->ivas_format == ISM_FORMAT ) @@ -363,7 +367,11 @@ ivas_error ivas_jbm_dec_tc( { if ( st_ivas->renderer_type == RENDERER_MC ) { +#ifdef MC_PARAMUPMIX_MODE + ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, output_frame, p_output, p_output ); +#else ivas_ls_setup_conversion( st_ivas, output_frame, p_output, p_output ); +#endif } else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) { @@ -400,7 +408,11 @@ ivas_error ivas_jbm_dec_tc( /* Rendering */ if ( output_config == AUDIO_CONFIG_MONO || output_config == AUDIO_CONFIG_STEREO ) { +#ifdef MC_PARAMUPMIX_MODE + ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, output_frame, p_output, p_output ); +#else ivas_ls_setup_conversion( st_ivas, output_frame, p_output, p_output ); +#endif } } else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) @@ -674,7 +686,11 @@ ivas_error ivas_jbm_dec_render( if ( st_ivas->renderer_type == RENDERER_MC ) { *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); - ivas_ls_setup_conversion( st_ivas, *nSamplesRendered, p_tc, p_output ); +#ifdef MC_PARAMUPMIX_MODE + ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, *nSamplesRendered, p_tc, p_output ); +#else + ivas_ls_setup_conversion( st_ivas, output_frame, p_output, p_output ); +#endif } } else if ( st_ivas->ivas_format == ISM_FORMAT ) @@ -806,7 +822,11 @@ ivas_error ivas_jbm_dec_render( else if ( st_ivas->renderer_type == RENDERER_MC ) { *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); +#ifdef MC_PARAMUPMIX_MODE + ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, *nSamplesRendered, p_tc, p_output ); +#else ivas_ls_setup_conversion( st_ivas, *nSamplesRendered, p_tc, p_output ); +#endif } else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) { -- GitLab From 64964adfbb394b66b57db3b24939955b1ccdbe7a Mon Sep 17 00:00:00 2001 From: knj Date: Fri, 12 May 2023 11:59:40 +0200 Subject: [PATCH 31/39] only run EVS conformance test on main --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 96ea0708d6..5d4cdd72f2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -657,7 +657,7 @@ clang-format-check: # check bitexactness to EVS windows binaries be-2-evs-windows: extends: - - .rules-basis + - .rules-main-push tags: - ivas-windows stage: test -- GitLab From b592f56516a6039e71e8c0643c1aa407806c4e71 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Fri, 12 May 2023 13:04:31 +0200 Subject: [PATCH 32/39] fix compiler warnings, clang-format --- lib_dec/ivas_sba_dec.c | 11 +++++------ lib_dec/ivas_spar_decoder.c | 17 ++++++++--------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 28920ccf53..471916d12c 100755 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -400,8 +400,8 @@ ivas_error ivas_sba_dec_reconfigure( { tc_nchan_to_allocate = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order #ifdef SPAR_TUNING - , - st_ivas->hDecoderConfig->ivas_total_brate + , + st_ivas->hDecoderConfig->ivas_total_brate #endif ); } @@ -490,16 +490,15 @@ void ivas_sba_dec_render( { int16_t slots_to_render, first_sf, last_sf, subframe_idx; uint16_t slot_size, ch; - uint16_t nchan_internal, sba_order_internal, nchan_out; + uint16_t nchan_internal, nchan_out; SPAR_DEC_HANDLE hSpar; float *output_f_local[MAX_OUTPUT_CHANNELS]; hSpar = st_ivas->hSpar; - sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order #ifdef SPAR_TUNING - , - st_ivas->hDecoderConfig->ivas_total_brate + , + st_ivas->hDecoderConfig->ivas_total_brate #endif ); nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index e346ffda61..33611932f0 100755 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -1151,8 +1151,8 @@ void ivas_spar_dec_agc_pca( { num_in_ingest = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order #ifdef SPAR_TUNING - , - st_ivas->hDecoderConfig->ivas_total_brate + , + st_ivas->hDecoderConfig->ivas_total_brate #endif ); } @@ -1251,12 +1251,11 @@ void ivas_spar_dec_digest_tc( float Pcm_tmp[MAX_SPAR_INTERNAL_CHANNELS][L_FRAME48k]; float *pPcm_tmp[MAX_SPAR_INTERNAL_CHANNELS]; float *p_tc[MAX_SPAR_INTERNAL_CHANNELS]; - int16_t nchan_internal, ch, sba_order_internal; + int16_t nchan_internal, ch; int16_t nSamplesLeftForTD, default_frame; /* TD decorrelator */ default_frame = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); nSamplesLeftForTD = nSamplesForRendering; - sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order #ifdef SPAR_TUNING , @@ -1717,10 +1716,10 @@ void ivas_spar_dec_upmixer( #ifdef LBR_ADAP_SMOOTHING_OPT 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 ); #else - for ( in_ch = 0; in_ch < numch_in; in_ch++ ) - { - ivas_spar_calc_smooth_facs( cldfb_in_ts_re[in_ch], cldfb_in_ts_im[in_ch], num_spar_bands, &hSpar->hFbMixer->pFb->fb_bin_to_band, hSpar->hMdDec->smooth_fac[in_ch], hSpar->hMdDec->smooth_buf[in_ch] ); - } + for ( in_ch = 0; in_ch < numch_in; in_ch++ ) + { + ivas_spar_calc_smooth_facs( cldfb_in_ts_re[in_ch], cldfb_in_ts_im[in_ch], num_spar_bands, &hSpar->hFbMixer->pFb->fb_bin_to_band, hSpar->hMdDec->smooth_fac[in_ch], hSpar->hMdDec->smooth_buf[in_ch] ); + } #endif } @@ -1748,7 +1747,7 @@ void ivas_spar_dec_upmixer( #ifdef LBR_ADAP_SMOOTHING_OPT mixer_mat[out_ch][in_ch][spar_band] = ( 1 - hSpar->hMdDec->smooth_fac[spar_band] ) * mixer_mat[out_ch][in_ch][spar_band] + hSpar->hMdDec->smooth_fac[spar_band] * hSpar->hMdDec->mixer_mat_prev2[out_ch][in_ch][spar_band]; #else - mixer_mat[out_ch][in_ch][spar_band] = ( 1 - hSpar->hMdDec->smooth_fac[in_ch][spar_band] ) * mixer_mat[out_ch][in_ch][spar_band] + hSpar->hMdDec->smooth_fac[in_ch][spar_band] * hSpar->hMdDec->mixer_mat_prev2[out_ch][in_ch][spar_band]; + mixer_mat[out_ch][in_ch][spar_band] = ( 1 - hSpar->hMdDec->smooth_fac[in_ch][spar_band] ) * mixer_mat[out_ch][in_ch][spar_band] + hSpar->hMdDec->smooth_fac[in_ch][spar_band] * hSpar->hMdDec->mixer_mat_prev2[out_ch][in_ch][spar_band]; #endif hSpar->hMdDec->mixer_mat_prev2[out_ch][in_ch][spar_band] = mixer_mat[out_ch][in_ch][spar_band]; } -- GitLab From be4217e1ebfa6d36d6bcce336051abd9d38d90be Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Fri, 12 May 2023 13:48:09 +0200 Subject: [PATCH 33/39] fix voip BE test --- apps/decoder.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 16376844c6..f4a2129cff 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -2123,7 +2123,7 @@ static ivas_error decodeVoIP( #ifdef JBM_TSM_ON_TCS #ifdef DEBUG_JBM_CMD_OPTION - nFrontendFramesPerIvasFrame = FRAME_SIZE_NS / ( 1000L * arg.frontendFetchSizeMs ); + nFrontendFramesPerIvasFrame = FRAME_SIZE_NS / ( 1000000L * arg.frontendFetchSizeMs ); systemTimeInc_ms = arg.frontendFetchSizeMs; #else nFrontendFramesPerIvasFrame = FRAME_SIZE_NS / ( 1000L * JBM_FRONTEND_FETCH_FRAMESIZE_MS ); @@ -2190,7 +2190,7 @@ static ivas_error decodeVoIP( /* also stop when the input file contains less than two frames, because JBM cannot calculate a delay value and won't start decoding */ #ifdef JBM_TSM_ON_TCS /* last clause should make sure that for BE tests we end up with the same number of samples...*/ - if ( nextPacketRcvTime_ms == (uint32_t) ( -1 ) && ( IVAS_DEC_VoIP_IsEmpty( hIvasDec, nOutSamples ) || nFramesFed < 2 || ( nFramesWritten % nFrontendFramesPerIvasFrame == 0 ) ) ) + if ( nextPacketRcvTime_ms == (uint32_t) ( -1 ) && ( IVAS_DEC_VoIP_IsEmpty( hIvasDec, nOutSamples ) || nFramesFed < 2 ) ) #else if ( nextPacketRcvTime_ms == (uint32_t) ( -1 ) && ( IVAS_DEC_VoIP_IsEmpty( hIvasDec ) || nFramesFed < 2 ) ) #endif -- GitLab From 90c7b25691cf41c4ca1538def63e7060e1a7df4b Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Fri, 12 May 2023 13:56:31 +0200 Subject: [PATCH 34/39] fix compiler warnings --- apps/decoder.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index f4a2129cff..df31d4c176 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -1984,7 +1984,6 @@ static ivas_error decodeVoIP( #ifdef JBM_TSM_ON_TCS uint32_t systemTimeInc_ms = (uint32_t) JBM_FRONTEND_FETCH_FRAMESIZE_MS; int32_t nFramesWritten = 0; - int32_t nFrontendFramesPerIvasFrame = 0; #endif int32_t nFramesFed = 0; @@ -2123,7 +2122,6 @@ static ivas_error decodeVoIP( #ifdef JBM_TSM_ON_TCS #ifdef DEBUG_JBM_CMD_OPTION - nFrontendFramesPerIvasFrame = FRAME_SIZE_NS / ( 1000000L * arg.frontendFetchSizeMs ); systemTimeInc_ms = arg.frontendFetchSizeMs; #else nFrontendFramesPerIvasFrame = FRAME_SIZE_NS / ( 1000L * JBM_FRONTEND_FETCH_FRAMESIZE_MS ); -- GitLab From 72fff2075d2e93a0403105edf69aa3b86ddb7cd6 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Fri, 12 May 2023 14:05:05 +0200 Subject: [PATCH 35/39] fix compiler error --- apps/decoder.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index df31d4c176..55d99d3e53 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -2123,8 +2123,6 @@ static ivas_error decodeVoIP( #ifdef JBM_TSM_ON_TCS #ifdef DEBUG_JBM_CMD_OPTION systemTimeInc_ms = arg.frontendFetchSizeMs; -#else - nFrontendFramesPerIvasFrame = FRAME_SIZE_NS / ( 1000L * JBM_FRONTEND_FETCH_FRAMESIZE_MS ); #endif #endif -- GitLab From 3f78adfcaaa58a26caaa7e6b6fef58a08749ef6c Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Fri, 12 May 2023 15:24:36 +0200 Subject: [PATCH 36/39] fix asan/msan errors for ParamISM and binaural output --- lib_dec/ivas_ism_dec.c | 2 +- lib_dec/ivas_ism_param_dec.c | 20 +++++++++++++++----- lib_dec/ivas_spar_decoder.c | 2 +- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index 0b305cacf6..19a8a40e5b 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -327,7 +327,7 @@ static ivas_error ivas_ism_bitrate_switching( tc_nchan_allocate_new = 2 * BINAURAL_CHANNELS; tc_nchan_full_new = tc_nchan_allocate_new; } - if ( st_ivas->ism_mode == ISM_MODE_PARAM && ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE ) ) + if ( st_ivas->ism_mode == ISM_MODE_PARAM && ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) { tc_nchan_full_new = 0; } diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 0ce3ad7bef..d58887f2da 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -801,13 +801,23 @@ ivas_error ivas_param_ism_dec_open( if ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE ) { int16_t nchan_transport = st_ivas->nchan_transport; - hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands * sizeof( float ) ); - set_zero( hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc, MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands ); - hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands * sizeof( float ) ); - set_zero( hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc, MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands ); + 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; + hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = NULL; + hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc = NULL; + } + else + { + hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands * sizeof( float ) ); + set_zero( hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc, MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands ); + hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands * sizeof( float ) ); + set_zero( hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc, MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands ); + } if ( st_ivas->hTcBuffer == NULL ) { - if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_transport, nchan_transport, 0, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_transport, nchan_transport, nchan_full, NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index 33611932f0..22d38997dd 100755 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -1457,7 +1457,7 @@ void ivas_spar_dec_upmixer( #ifdef SPAR_TUNING int16_t num_md_sub_frames; #ifndef JBM_TSM_ON_TCS - md_sf_idx; + int16_t md_sf_idx; #endif #endif -- GitLab From b69164d21c2b51b0a27b8b4bc3e7f777a46b5698 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Mon, 15 May 2023 10:21:00 +0200 Subject: [PATCH 37/39] accept define MASA_PARAMBIN_SF_MAP, fix compile error when JBM_TSM_ON_TCS is deactivated --- lib_com/ivas_prot.h | 14 - lib_com/options.h | 3 - lib_dec/ivas_dirac_dec.c | 202 +++------ lib_dec/ivas_dirac_output_synthesis_dec.c | 187 +------- lib_dec/ivas_masa_dec.c | 27 -- lib_dec/ivas_stat_dec.h | 3 - lib_rend/ivas_dirac_dec_binaural_functions.c | 448 +------------------ 7 files changed, 76 insertions(+), 808 deletions(-) diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 6b550685e9..4e84d455ea 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -3814,15 +3814,9 @@ void ivas_dirac_dec_output_synthesis_process_slot( const int16_t *azimuth, const int16_t *elevation, const float *diffuseness, -#ifndef MASA_PARAMBIN_SF_MAP - const uint16_t coherence_flag, -#endif #endif DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */ #ifdef JBM_TSM_ON_TCS -#ifndef MASA_PARAMBIN_SF_MAP - MASA_DECODER_HANDLE hMasa, -#endif const int16_t sh_rot_max_order, #endif const float *p_Rmat, /* i : rotation matrix */ @@ -5198,19 +5192,11 @@ void ivas_masa_prerender( #ifndef FIX_355_REFACTOR_PARAMBIN_TO_5MS void ivas_spar_param_to_masa_param_mapping_sf( Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ -#ifdef MASA_PARAMBIN_SF_MAP int16_t azimuth[CLDFB_NO_CHANNELS_MAX], int16_t elevation[CLDFB_NO_CHANNELS_MAX], float energy_ratio1[CLDFB_NO_CHANNELS_MAX], float spreadCoherence[CLDFB_NO_CHANNELS_MAX], float surroundingCoherence[CLDFB_NO_CHANNELS_MAX], -#else - int16_t azimuth[][CLDFB_NO_CHANNELS_MAX], - int16_t elevation[][CLDFB_NO_CHANNELS_MAX], - float energy_ratio1[][CLDFB_NO_CHANNELS_MAX], - float spreadCoherence[][CLDFB_NO_CHANNELS_MAX], - float surroundingCoherence[][CLDFB_NO_CHANNELS_MAX], -#endif float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */ float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /* i : Input audio in CLDFB domain, imag */ ); diff --git a/lib_com/options.h b/lib_com/options.h index fc468a6f25..3ea4170c7b 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -218,9 +218,6 @@ #define VARIABLE_SPEED_DECODING /* FhG: variable speed decoding employing the JBM functioniality */ #define JBM_TSM_ON_TCS /* FhG: run the TSM part of JBM on the TCs instead of the final output pcm waveforms */ -#ifdef JBM_TSM_ON_TCS -#define MASA_PARAMBIN_SF_MAP -#endif /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index a19acac344..861b7da545 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -183,10 +183,6 @@ ivas_error ivas_dirac_dec_config( num_outputs_diff_old = 0; num_protos_diff_old = 0; -#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) - hDirAC->voip_active = st_ivas->hDecoderConfig->voip_active; -#endif - nchan_transport_orig = st_ivas->nchan_transport; if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR && !( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) { @@ -950,17 +946,10 @@ ivas_error ivas_dirac_dec_config( { int16_t map_idx; set_s( hDirAC->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME ); -#ifdef MASA_PARAMBIN_SF_MAP for ( map_idx = 0; map_idx < DEFAULT_JBM_SUBFRAMES_5MS; map_idx++ ) { hDirAC->render_to_md_map[map_idx] = map_idx; } -#else - for ( map_idx = 0; map_idx < DEFAULT_JBM_CLDFB_TIMESLOTS; map_idx++ ) - { - hDirAC->render_to_md_map[map_idx] = map_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME; - } -#endif } #endif } @@ -972,17 +961,10 @@ ivas_error ivas_dirac_dec_config( { int16_t map_idx; set_s( hDirAC->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME ); -#ifdef MASA_PARAMBIN_SF_MAP for ( map_idx = 0; map_idx < DEFAULT_JBM_SUBFRAMES_5MS; map_idx++ ) { hDirAC->render_to_md_map[map_idx] = map_idx; } -#else - for ( map_idx = 0; map_idx < DEFAULT_JBM_CLDFB_TIMESLOTS; map_idx++ ) - { - hDirAC->render_to_md_map[map_idx] = map_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME; - } -#endif } #endif } @@ -2646,20 +2628,16 @@ void ivas_dirac_dec_set_md_map( /* set mapping according to dirac_read_idx */ set_s( hDirAC->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME ); -#ifdef MASA_PARAMBIN_SF_MAP + if ( hDirAC->hConfig == NULL || hDirAC->hConfig->dec_param_estim == 0 ) { ivas_jbm_dec_get_md_map( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbTs, num_slots_in_subfr, 0, hDirAC->dirac_md_buffer_length, hDirAC->render_to_md_map ); } else { -#endif ivas_jbm_dec_get_md_map( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbTs, num_slots_in_subfr, hDirAC->dirac_read_idx, hDirAC->dirac_md_buffer_length, hDirAC->render_to_md_map ); -#ifdef MASA_PARAMBIN_SF_MAP } -#endif -#ifdef MASA_PARAMBIN_SF_MAP if ( hDirAC->hConfig == NULL || hDirAC->hConfig->dec_param_estim == 0 ) { float tmp; @@ -2677,7 +2655,6 @@ void ivas_dirac_dec_set_md_map( } set_s( &hDirAC->render_to_md_map[hDirAC->nb_subframes], 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME - hDirAC->nb_subframes ); } -#endif return; } @@ -2934,7 +2911,6 @@ void ivas_dirac_dec_render_sf( { #endif #ifdef JBM_TSM_ON_TCS -#ifdef MASA_PARAMBIN_SF_MAP if ( hDirAC->hConfig->dec_param_estim == FALSE ) { md_idx = hDirAC->render_to_md_map[subframe_idx]; @@ -2943,13 +2919,8 @@ void ivas_dirac_dec_render_sf( { md_idx = hDirAC->render_to_md_map[slot_idx_start]; } -#else - md_idx = hDirAC->render_to_md_map[slot_idx_start]; -#endif #endif #ifdef JBM_TSM_ON_TCS - - /* Another workaround for self test BE */ if ( st_ivas->hHeadTrackData && st_ivas->hDecoderConfig->voip_active == 0 ) { @@ -2973,17 +2944,15 @@ void ivas_dirac_dec_render_sf( } /* copy parameters into local buffers*/ -#ifdef MASA_PARAMBIN_SF_MAP + if ( hDirAC->hConfig->dec_param_estim == TRUE ) { -#endif for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) { mvs2s( hDirAC->azimuth[hDirAC->render_to_md_map[slot_idx + slot_idx_start]], azimuth[slot_idx], hDirAC->num_freq_bands ); mvs2s( hDirAC->elevation[hDirAC->render_to_md_map[slot_idx + slot_idx_start]], elevation[slot_idx], hDirAC->num_freq_bands ); mvr2r( hDirAC->diffuseness_vector[hDirAC->render_to_md_map[slot_idx + slot_idx_start]], diffuseness_vector[slot_idx], hDirAC->num_freq_bands ); } -#ifdef MASA_PARAMBIN_SF_MAP } else { @@ -2994,7 +2963,7 @@ void ivas_dirac_dec_render_sf( mvr2r( hDirAC->diffuseness_vector[hDirAC->render_to_md_map[subframe_idx]], diffuseness_vector[slot_idx], hDirAC->num_freq_bands ); } } -#endif + #endif if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD ) @@ -3046,11 +3015,7 @@ void ivas_dirac_dec_render_sf( p_Rmat = 0; } -#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) - if ( st_ivas->hDecoderConfig->voip_active == 0 && hDirAC->hConfig->dec_param_estim == FALSE ) -#else - if ( hDirAC->hConfig->dec_param_estim == FALSE ) -#endif + if ( hDirAC->hConfig->dec_param_estim == FALSE ) { /* compute response */ @@ -3091,11 +3056,7 @@ void ivas_dirac_dec_render_sf( { ivas_dirac_dec_compute_gain_factors( hDirAC->num_freq_bands, #ifdef JBM_TSM_ON_TCS -#ifdef MASA_PARAMBIN_SF_MAP hDirAC->diffuseness_vector[md_idx], -#else - diffuseness_vector[0], -#endif #else hDirAC->diffuseness_vector[hDirAC->dirac_read_idx], #endif @@ -3224,7 +3185,6 @@ void ivas_dirac_dec_render_sf( st_ivas->cldfbAnaDec[ch] ); #endif - } #endif } } @@ -3239,7 +3199,7 @@ void ivas_dirac_dec_render_sf( #ifdef JBM_TSM_ON_TCS st_ivas->hTcBuffer->tc[1], #else - &( output_f[1][L_FRAME48k - L_FRAME16k] ), + &( output_f[1][L_FRAME48k - L_FRAME16k] ), #endif Cldfb_RealBuffer[1][0], Cldfb_ImagBuffer[1][0], @@ -3258,7 +3218,7 @@ void ivas_dirac_dec_render_sf( #ifdef JBM_TSM_ON_TCS md_idx, #else - subframe_idx, + subframe_idx, #endif nchan_transport ); } @@ -3375,8 +3335,8 @@ void ivas_dirac_dec_render_sf( azimuth[slot_idx], elevation[slot_idx] #else - hDirAC->azimuth[hDirAC->dirac_estimator_idx], - hDirAC->elevation[hDirAC->dirac_estimator_idx] + hDirAC->azimuth[hDirAC->dirac_estimator_idx], + hDirAC->elevation[hDirAC->dirac_estimator_idx] #endif ); @@ -3388,7 +3348,7 @@ void ivas_dirac_dec_render_sf( #ifdef JBM_TSM_ON_TCS diffuseness_vector[slot_idx] #else - hDirAC->diffuseness_vector[hDirAC->dirac_estimator_idx] + hDirAC->diffuseness_vector[hDirAC->dirac_estimator_idx] #endif ); @@ -3559,59 +3519,47 @@ void ivas_dirac_dec_render_sf( ); } #else - if ( st_ivas->hDecoderConfig->Opt_Headrotation && st_ivas->hHeadTrackData->shd_rot_max_order > 0 ) - { - ivas_dirac_dec_output_synthesis_process_slot( reference_power, - p_onset_filter, - azimuth[slot_idx], - elevation[slot_idx], - diffuseness_vector[slot_idx], -#ifndef MASA_PARAMBIN_SF_MAP - coherence_flag, -#endif - hDirAC, -#ifndef MASA_PARAMBIN_SF_MAP - st_ivas->hMasa, -#endif - st_ivas->hHeadTrackData->shd_rot_max_order, - p_Rmat, - st_ivas->hVBAPdata, - hDirAC->hOutSetup, - nchan_transport, - md_idx, + if ( st_ivas->hDecoderConfig->Opt_Headrotation && st_ivas->hHeadTrackData->shd_rot_max_order > 0 ) + { + ivas_dirac_dec_output_synthesis_process_slot( reference_power, + p_onset_filter, + azimuth[slot_idx], + elevation[slot_idx], + diffuseness_vector[slot_idx], + hDirAC, + st_ivas->hHeadTrackData->shd_rot_max_order, + p_Rmat, + st_ivas->hVBAPdata, + hDirAC->hOutSetup, + nchan_transport, + md_idx, #ifdef HODIRAC - st_ivas->sba_analysis_order > 1 && - st_ivas->hDecoderConfig->ivas_total_brate > IVAS_256k + st_ivas->sba_analysis_order > 1 && + st_ivas->hDecoderConfig->ivas_total_brate > IVAS_256k #endif - ); - } - else - { - ivas_dirac_dec_output_synthesis_process_slot( reference_power, - p_onset_filter, - azimuth[slot_idx], - elevation[slot_idx], - diffuseness_vector[slot_idx], -#ifndef MASA_PARAMBIN_SF_MAP - coherence_flag, -#endif - hDirAC, -#ifndef MASA_PARAMBIN_SF_MAP - st_ivas->hMasa, -#endif - 0, - 0, - st_ivas->hVBAPdata, - hDirAC->hOutSetup, - nchan_transport, - md_idx, + ); + } + else + { + ivas_dirac_dec_output_synthesis_process_slot( reference_power, + p_onset_filter, + azimuth[slot_idx], + elevation[slot_idx], + diffuseness_vector[slot_idx], + hDirAC, + 0, + 0, + st_ivas->hVBAPdata, + hDirAC->hOutSetup, + nchan_transport, + md_idx, #ifdef HODIRAC - st_ivas->sba_analysis_order > 1 && - st_ivas->hDecoderConfig->ivas_total_brate > IVAS_256k + st_ivas->sba_analysis_order > 1 && + st_ivas->hDecoderConfig->ivas_total_brate > IVAS_256k #endif - ); - } + ); + } #endif if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD ) @@ -3634,7 +3582,7 @@ void ivas_dirac_dec_render_sf( #endif #ifdef JBM_TSM_ON_TCS ivas_dirac_dec_output_synthesis_get_interpolator( &hDirAC->h_output_synthesis_psd_params, hDirAC->subframe_nbslots[subframe_idx] ); -#ifdef MASA_PARAMBIN_SF_MAP + if ( hDirAC->hConfig->dec_param_estim == FALSE ) { md_idx = hDirAC->render_to_md_map[subframe_idx]; @@ -3643,11 +3591,7 @@ void ivas_dirac_dec_render_sf( { md_idx = hDirAC->render_to_md_map[slot_idx_start]; } -#else - md_idx = hDirAC->render_to_md_map[slot_idx_start]; -#endif -#ifdef MASA_PARAMBIN_SF_MAP /* Workaround for BE (should be gone when #393 is adressed and diffuseness index in the gain SHD renderer with HO-DirAC is fixed) */ /* :TODO: remove */ /* get the correct md index for the diffuseness in direction smoothing and HO-DirAC, it is always the first slot of the next subframe*/ @@ -3674,24 +3618,7 @@ void ivas_dirac_dec_render_sf( md_idx = hDirAC->render_to_md_map[subframe_idx + 1]; } } -#else - if ( slot_idx_start + hDirAC->subframe_nbslots[subframe_idx] == hDirAC->num_slots ) - { - /* we are at the end, get the next one using the normal dirac read idx...*/ - if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) - { - md_idx = ( hDirAC->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % hDirAC->dirac_md_buffer_length; - } - else - { - md_idx = ( hDirAC->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % hDirAC->dirac_md_buffer_length; - } - } - else - { - md_idx = hDirAC->render_to_md_map[slot_idx_start + hDirAC->subframe_nbslots[subframe_idx]]; - } -#endif + #endif if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { @@ -3755,7 +3682,7 @@ void ivas_dirac_dec_render_sf( #ifdef JBM_TSM_ON_TCS index_slot = slot_idx_start_cldfb_synth; #else - index_slot = subframe_idx * hDirAC->subframe_nbslots; + index_slot = subframe_idx * hDirAC->subframe_nbslots; #endif if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) @@ -3781,7 +3708,7 @@ void ivas_dirac_dec_render_sf( #ifdef JBM_TSM_ON_TCS for ( i = 0; i < hDirAC->subframe_nbslots[subframe_idx]; i++ ) #else - for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) #endif { RealBuffer[i] = Cldfb_RealBuffer_Binaural[ch][i]; @@ -3795,11 +3722,11 @@ void ivas_dirac_dec_render_sf( hDirAC->num_freq_bands * hDirAC->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[ch] ); #else - cldfbSynthesis( RealBuffer, - ImagBuffer, - &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), - hDirAC->num_freq_bands * hDirAC->subframe_nbslots, - st_ivas->cldfbSynDec[ch] ); + cldfbSynthesis( RealBuffer, + ImagBuffer, + &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), + hDirAC->num_freq_bands * hDirAC->subframe_nbslots, + st_ivas->cldfbSynDec[ch] ); #endif } } @@ -3810,7 +3737,7 @@ void ivas_dirac_dec_render_sf( #ifdef JBM_TSM_ON_TCS for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) #else - for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots; slot_idx++ ) + for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots; slot_idx++ ) #endif { mvr2r( Cldfb_RealBuffer[ch][slot_idx], pppQMfFrame_ts_re[ch][slot_idx], hDirAC->num_freq_bands ); @@ -3846,7 +3773,7 @@ void ivas_dirac_dec_render_sf( #ifdef JBM_TSM_ON_TCS const int16_t num_samples_subframe = hDirAC->num_freq_bands * hDirAC->subframe_nbslots[subframe_idx]; #else - const int16_t num_samples_subframe = hDirAC->num_freq_bands * hDirAC->subframe_nbslots; + const int16_t num_samples_subframe = hDirAC->num_freq_bands * hDirAC->subframe_nbslots; #endif /* Move the separated and the LFE channels to temporary variables as spatial synthesis may overwrite current channels */ @@ -3877,7 +3804,7 @@ void ivas_dirac_dec_render_sf( #ifdef JBM_TSM_ON_TCS for ( i = 0; i < hDirAC->subframe_nbslots[subframe_idx]; i++ ) #else - for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) #endif { RealBuffer[i] = Cldfb_RealBuffer[idx_in][i]; @@ -3907,7 +3834,7 @@ void ivas_dirac_dec_render_sf( #ifdef JBM_TSM_ON_TCS for ( i = 0; i < hDirAC->subframe_nbslots[subframe_idx]; i++ ) #else - for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) #endif { RealBuffer[i] = Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS - 1][i]; @@ -3916,7 +3843,7 @@ void ivas_dirac_dec_render_sf( #ifdef JBM_TSM_ON_TCS cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), hDirAC->num_freq_bands * hDirAC->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[hDirAC->hOutSetup.nchan_out_woLFE + idx_lfe] ); #else - cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), hDirAC->num_freq_bands * hDirAC->subframe_nbslots, st_ivas->cldfbSynDec[hDirAC->hOutSetup.nchan_out_woLFE + idx_lfe] ); + cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), hDirAC->num_freq_bands * hDirAC->subframe_nbslots, st_ivas->cldfbSynDec[hDirAC->hOutSetup.nchan_out_woLFE + idx_lfe] ); #endif } else if ( st_ivas->mc_mode == MC_MODE_MCMASA && hDirAC->hOutSetup.separateChannelEnabled ) @@ -3928,7 +3855,7 @@ void ivas_dirac_dec_render_sf( #ifdef JBM_TSM_ON_TCS set_zero( &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), hDirAC->subframe_nbslots[subframe_idx] * hDirAC->num_freq_bands ); #else - set_zero( &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), hDirAC->subframe_nbslots * hDirAC->num_freq_bands ); + set_zero( &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), hDirAC->subframe_nbslots * hDirAC->num_freq_bands ); #endif } @@ -3948,7 +3875,7 @@ void ivas_dirac_dec_render_sf( #ifdef JBM_TSM_ON_TCS for ( i = 0; i < hDirAC->subframe_nbslots[subframe_idx]; i++ ) #else - for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) #endif { RealBuffer[i] = Cldfb_RealBuffer[idx_in][i]; @@ -3957,7 +3884,7 @@ void ivas_dirac_dec_render_sf( #ifdef JBM_TSM_ON_TCS cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), hDirAC->num_freq_bands * hDirAC->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[idx_in] ); #else - cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), hDirAC->num_freq_bands * hDirAC->subframe_nbslots, st_ivas->cldfbSynDec[idx_in] ); + cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), hDirAC->num_freq_bands * hDirAC->subframe_nbslots, st_ivas->cldfbSynDec[idx_in] ); #endif idx_in++; } @@ -3972,7 +3899,6 @@ void ivas_dirac_dec_render_sf( } #endif - pop_wmops(); return; @@ -4698,8 +4624,8 @@ static void protoSignalComputation4( proto_frame_f[2 * l * num_freq_bands + 2 * k] += RealBuffer[n][0][k] * mtx_hoa_decoder[l * 16 + sba_map_tc_ind[n]]; proto_frame_f[2 * l * num_freq_bands + 2 * k + 1] += ImagBuffer[n][0][k] * mtx_hoa_decoder[l * 16 + sba_map_tc_ind[n]]; #else - proto_frame_f[2 * l * num_freq_bands + 2 * k] += RealBuffer[n][0][k] * mtx_hoa_decoder[l * 16 + sba_map_tc[n]]; - proto_frame_f[2 * l * num_freq_bands + 2 * k + 1] += ImagBuffer[n][0][k] * mtx_hoa_decoder[l * 16 + sba_map_tc[n]]; + proto_frame_f[2 * l * num_freq_bands + 2 * k] += RealBuffer[n][0][k] * mtx_hoa_decoder[l * 16 + sba_map_tc[n]]; + proto_frame_f[2 * l * num_freq_bands + 2 * k + 1] += ImagBuffer[n][0][k] * mtx_hoa_decoder[l * 16 + sba_map_tc[n]]; #endif } } diff --git a/lib_dec/ivas_dirac_output_synthesis_dec.c b/lib_dec/ivas_dirac_output_synthesis_dec.c index e7ccaeaba7..275f56a40e 100644 --- a/lib_dec/ivas_dirac_output_synthesis_dec.c +++ b/lib_dec/ivas_dirac_output_synthesis_dec.c @@ -581,15 +581,9 @@ void ivas_dirac_dec_output_synthesis_process_slot( const int16_t *azimuth, const int16_t *elevation, const float *diffuseness, -#ifndef MASA_PARAMBIN_SF_MAP - const uint16_t coherence_flag, -#endif #endif DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */ #ifdef JBM_TSM_ON_TCS -#ifndef MASA_PARAMBIN_SF_MAP - MASA_DECODER_HANDLE hMasa, -#endif const int16_t sh_rot_max_order, #endif const float *p_Rmat, /* i : rotation matrix */ @@ -613,12 +607,6 @@ void ivas_dirac_dec_output_synthesis_process_slot( int16_t diff_start_band; #ifndef JBM_TSM_ON_TCS const float *diffuseness; -#endif -#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) - float dirEne; - float surCohEner; - float surCohRatio[CLDFB_NO_CHANNELS_MAX]; - int16_t i, l; #endif DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params; DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state; @@ -723,90 +711,18 @@ void ivas_dirac_dec_output_synthesis_process_slot( } else // ( hDirAC->hConfig->dec_param_estim == TRUE ) #endif -#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) - if ( hDirAC->hConfig->dec_param_estim == TRUE || hDirAC->voip_active == 1 ) -#else if ( hDirAC->hConfig->dec_param_estim == TRUE ) -#endif { -#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) - if ( hDirAC->voip_active == 1 ) - { - if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) - { - ivas_dirac_dec_compute_gain_factors( num_freq_bands, - diffuseness, - h_dirac_output_synthesis_params->max_band_decorr, - h_dirac_output_synthesis_state->direct_power_factor, - h_dirac_output_synthesis_state->diffuse_power_factor ); - v_multc( h_dirac_output_synthesis_state->direct_power_factor, - 0.25f, - h_dirac_output_synthesis_state->direct_power_factor, - num_freq_bands ); - v_multc( h_dirac_output_synthesis_state->diffuse_power_factor, - 0.25f, - h_dirac_output_synthesis_state->diffuse_power_factor, - num_freq_bands ); - if ( coherence_flag ) - { - for ( i = 0; i < hDirAC->num_freq_bands; i++ ) - { - surCohRatio[i] = hDirAC->surroundingCoherence[md_idx][i]; - } - } - else - { - set_zero( surCohRatio, hDirAC->num_freq_bands ); - } - } - else - { - - - /* compute reference and diffuse power factor for this frame */ - - ivas_dirac_dec_compute_power_factors( num_freq_bands, - diffuseness, - h_dirac_output_synthesis_params->max_band_decorr, - h_dirac_output_synthesis_state->direct_power_factor, - h_dirac_output_synthesis_state->diffuse_power_factor ); - - if ( coherence_flag ) - { - for ( i = 0; i < hDirAC->num_freq_bands; i++ ) - { - dirEne = hDirAC->h_output_synthesis_psd_state.direct_power_factor[i]; - surCohEner = hDirAC->h_output_synthesis_psd_state.diffuse_power_factor[i] * hDirAC->surroundingCoherence[md_idx][i]; - hDirAC->h_output_synthesis_psd_state.diffuse_power_factor[i] -= surCohEner; - hDirAC->h_output_synthesis_psd_state.direct_power_factor[i] += surCohEner; - - surCohRatio[i] = surCohEner / ( 1e-12f + dirEne + surCohEner ); - } - } - else - { - set_zero( surCohRatio, hDirAC->num_freq_bands ); - } - } - } -#endif /* compute direct responses */ + /* compute direct responses */ #ifdef JBM_TSM_ON_TCS ivas_dirac_dec_compute_directional_responses( hDirAC, hVBAPdata, -#ifdef MASA_PARAMBIN_SF_MAP NULL, -#else - hMasa, -#endif azimuth, elevation, md_idx, -#ifdef MASA_PARAMBIN_SF_MAP NULL, -#else - coherence_flag ? surCohRatio : NULL, -#endif sh_rot_max_order, p_Rmat #ifdef HODIRAC @@ -830,10 +746,6 @@ void ivas_dirac_dec_output_synthesis_process_slot( if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { -#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) - if ( hDirAC->voip_active == 0 ) - { -#endif ivas_dirac_dec_compute_gain_factors( num_freq_bands, diffuseness, h_dirac_output_synthesis_params->max_band_decorr, @@ -849,16 +761,8 @@ void ivas_dirac_dec_output_synthesis_process_slot( 0.25f, h_dirac_output_synthesis_state->diffuse_power_factor, num_freq_bands ); -#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) - } -#endif - /*Direct gain*/ -#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) - if ( hDirAC->hConfig->dec_param_estim == TRUE ) - { -#endif for ( ch_idx = 0; ch_idx < min( 4, nchan_transport ); ch_idx++ ) { int16_t k; @@ -895,34 +799,7 @@ void ivas_dirac_dec_output_synthesis_process_slot( } } } -#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) - } - else - { - for ( ch_idx = 0; ch_idx < min( 4, nchan_transport ); ch_idx++ ) - { - v_multc( h_dirac_output_synthesis_state->diffuse_power_factor, 4.0f, aux_buf, num_freq_bands ); - v_mult( aux_buf, - aux_buf, - aux_buf, - num_freq_bands ); - v_multc( aux_buf, - h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f, - aux_buf, - num_freq_bands_diff ); - v_multc( &aux_buf[num_freq_bands_diff], - h_dirac_output_synthesis_params->diffuse_compensation_factor - 1.f, - &aux_buf[num_freq_bands_diff], - num_freq_bands - num_freq_bands_diff ); - for ( l = 0; l < num_freq_bands; l++ ) - { - aux_buf[l] = 0.25f * sqrtf( 1.f + aux_buf[l] ); - } - v_add( aux_buf, &h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands], &h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands], num_freq_bands ); - } - } -#endif /*Directional gain (panning)*/ for ( ch_idx = min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ ) { @@ -956,18 +833,11 @@ void ivas_dirac_dec_output_synthesis_process_slot( else { /* compute reference and diffuse power factor for this frame */ -#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) - if ( hDirAC->voip_active == 0 ) - { -#endif ivas_dirac_dec_compute_power_factors( num_freq_bands, diffuseness, h_dirac_output_synthesis_params->max_band_decorr, h_dirac_output_synthesis_state->direct_power_factor, h_dirac_output_synthesis_state->diffuse_power_factor ); -#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) - } -#endif } } @@ -987,11 +857,7 @@ void ivas_dirac_dec_output_synthesis_process_slot( } /* process other PSDs only slot wise for 4 transport channels */ -#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) - if ( hDirAC->hConfig->dec_param_estim == TRUE || hDirAC->voip_active == 1 ) -#else if ( hDirAC->hConfig->dec_param_estim == TRUE ) -#endif { computeTargetPSDs_direct( num_channels_dir, num_freq_bands, h_dirac_output_synthesis_state->direct_power_factor, reference_power, h_dirac_output_synthesis_state->direct_responses, h_dirac_output_synthesis_state->direct_responses_square, h_dirac_output_synthesis_state->cy_auto_dir_smooth, h_dirac_output_synthesis_state->cy_cross_dir_smooth ); @@ -1130,11 +996,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( } else #endif -#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) - if ( hDirAC->voip_active == 0 && hDirAC->hConfig->dec_param_estim == FALSE ) -#else if ( hDirAC->hConfig->dec_param_estim == FALSE ) -#endif { /*Direct gain*/ for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ ) @@ -1556,11 +1418,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( /*-----------------------------------------------------------------* * compute target PSDs *-----------------------------------------------------------------*/ -#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) - if ( hDirAC->hConfig->enc_param_start_band == 0 && hDirAC->voip_active == 0 ) -#else if ( hDirAC->hConfig->enc_param_start_band == 0 ) -#endif { diff_start_band = h_dirac_output_synthesis_params->use_onset_filters == 1 ? h_dirac_output_synthesis_params->max_band_decorr : 0; @@ -1842,44 +1700,21 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( *-----------------------------------------------------------------*/ /* store estimates for next synthesis block */ -#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) - if ( hDirAC->voip_active == 1 ) - { - mvr2r( gains_dir, h_dirac_output_synthesis_state->gains_dir_prev, num_freq_bands * hDirAC->num_outputs_dir ); - mvr2r( gains_diff, h_dirac_output_synthesis_state->gains_diff_prev, num_freq_bands * hDirAC->num_outputs_dir ); + mvr2r( gains_dir, h_dirac_output_synthesis_state->gains_dir_prev, num_freq_bands * nchan_out_woLFE ); + mvr2r( gains_diff, h_dirac_output_synthesis_state->gains_diff_prev, num_freq_bands * nchan_out_woLFE ); - /* reset values */ - set_zero( h_dirac_output_synthesis_state->proto_power_smooth, num_freq_bands * hDirAC->num_outputs_dir ); + /* reset values */ + set_zero( h_dirac_output_synthesis_state->proto_power_smooth, num_freq_bands * num_protos_dir ); - if ( h_dirac_output_synthesis_state->proto_power_diff_smooth != NULL ) - { - set_zero( h_dirac_output_synthesis_state->proto_power_diff_smooth, h_dirac_output_synthesis_params->max_band_decorr * hDirAC->num_outputs_dir ); - } - - set_zero( h_dirac_output_synthesis_state->cy_auto_dir_smooth, num_freq_bands * hDirAC->num_outputs_dir ); - set_zero( h_dirac_output_synthesis_state->cy_cross_dir_smooth, num_freq_bands * hDirAC->num_outputs_dir ); - set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth, num_freq_bands * hDirAC->num_outputs_dir ); - } - else + if ( h_dirac_output_synthesis_state->proto_power_diff_smooth != NULL ) { -#endif - mvr2r( gains_dir, h_dirac_output_synthesis_state->gains_dir_prev, num_freq_bands * nchan_out_woLFE ); - mvr2r( gains_diff, h_dirac_output_synthesis_state->gains_diff_prev, num_freq_bands * nchan_out_woLFE ); - - /* reset values */ - set_zero( h_dirac_output_synthesis_state->proto_power_smooth, num_freq_bands * num_protos_dir ); + set_zero( h_dirac_output_synthesis_state->proto_power_diff_smooth, h_dirac_output_synthesis_params->max_band_decorr * nchan_out_woLFE ); + } - if ( h_dirac_output_synthesis_state->proto_power_diff_smooth != NULL ) - { - set_zero( h_dirac_output_synthesis_state->proto_power_diff_smooth, h_dirac_output_synthesis_params->max_band_decorr * nchan_out_woLFE ); - } + set_zero( h_dirac_output_synthesis_state->cy_auto_dir_smooth, num_freq_bands * nchan_out_woLFE ); + set_zero( h_dirac_output_synthesis_state->cy_cross_dir_smooth, num_freq_bands * nchan_out_woLFE ); + set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth, num_freq_bands * nchan_out_woLFE ); - set_zero( h_dirac_output_synthesis_state->cy_auto_dir_smooth, num_freq_bands * nchan_out_woLFE ); - set_zero( h_dirac_output_synthesis_state->cy_cross_dir_smooth, num_freq_bands * nchan_out_woLFE ); - set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth, num_freq_bands * nchan_out_woLFE ); -#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) - } -#endif pop_wmops(); return; diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index 7f79dae5fc..e69cedc6a2 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -1300,19 +1300,11 @@ ivas_error ivas_masa_dec_reconfigure( *-------------------------------------------------------------------*/ void ivas_spar_param_to_masa_param_mapping_sf( Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ -#ifdef MASA_PARAMBIN_SF_MAP int16_t azimuth[CLDFB_NO_CHANNELS_MAX], int16_t elevation[CLDFB_NO_CHANNELS_MAX], float energy_ratio1[CLDFB_NO_CHANNELS_MAX], float spreadCoherence[CLDFB_NO_CHANNELS_MAX], float surroundingCoherence[CLDFB_NO_CHANNELS_MAX], -#else - int16_t azimuth[][CLDFB_NO_CHANNELS_MAX], - int16_t elevation[][CLDFB_NO_CHANNELS_MAX], - float energy_ratio1[][CLDFB_NO_CHANNELS_MAX], - float spreadCoherence[][CLDFB_NO_CHANNELS_MAX], - float surroundingCoherence[][CLDFB_NO_CHANNELS_MAX], -#endif float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */ float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX] /* i : Input audio in CLDFB domain, imag */ ) @@ -1493,21 +1485,13 @@ void ivas_spar_param_to_masa_param_mapping_sf( ratio = I / fmaxf( 1e-12f, E ); /* Energy ratio */ ratio = fmaxf( 0.0f, fminf( 1.0f, ratio ) ); -#ifdef MASA_PARAMBIN_SF_MAP azimuth[bin] = (int16_t) roundf( azi / PI_OVER_180 ); elevation[bin] = (int16_t) roundf( ele / PI_OVER_180 ); energy_ratio1[bin] = ratio; spreadCoherence[bin] = 0.0f; surroundingCoherence[bin] = 0.0f; -#else - azimuth[0][bin] = (int16_t) roundf( azi / PI_OVER_180 ); - elevation[0][bin] = (int16_t) roundf( ele / PI_OVER_180 ); - energy_ratio1[0][bin] = ratio; - spreadCoherence[0][bin] = 0.0f; - surroundingCoherence[0][bin] = 0.0f; -#endif /* Determine directional distribution of the indirect audio based on the SPAR mixing matrices (and the transport audio signals when 2 TC) */ if ( hDiffuseDist != NULL ) { @@ -1547,17 +1531,6 @@ void ivas_spar_param_to_masa_param_mapping_sf( } } -#ifndef MASA_PARAMBIN_SF_MAP - for ( slot_idx = 1; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) - { - mvs2s( azimuth[0], azimuth[slot_idx], nBins ); - mvs2s( elevation[0], elevation[slot_idx], nBins ); - mvr2r( spreadCoherence[0], spreadCoherence[slot_idx], nBins ); - mvr2r( surroundingCoherence[0], surroundingCoherence[slot_idx], nBins ); - mvr2r( energy_ratio1[0], energy_ratio1[slot_idx], nBins ); - } -#endif - return; } #endif diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index d7200955ad..a928563240 100755 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -645,9 +645,6 @@ typedef struct ivas_dirac_dec_data_structure int16_t slots_rendered; int16_t num_slots; int16_t render_to_md_map[MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME]; -#if defined( JBM_TSM_ON_TCS ) && !defined( MASA_PARAMBIN_SF_MAP ) - int16_t voip_active; -#endif #else int16_t subframe_nbslots; #endif diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index a04a06d507..06fd160bb2 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -133,15 +133,10 @@ static void ivas_dirac_dec_binaural_process_output_sf( Decoder_Struct *st_ivas, static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked_sf( HEAD_TRACK_DATA_HANDLE hHeadTrackData, float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const uint8_t slotEnd, const uint8_t nBins, float Rmat[3][3] ); -#ifdef MASA_PARAMBIN_SF_MAP static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_sf( Decoder_Struct *st_ivas, float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], int16_t azimuth[CLDFB_NO_CHANNELS_MAX], int16_t elevation[CLDFB_NO_CHANNELS_MAX], float energy_ratio1[CLDFB_NO_CHANNELS_MAX], float spreadCoherence[CLDFB_NO_CHANNELS_MAX], float surroundingCoherence[CLDFB_NO_CHANNELS_MAX], float Rmat[3][3] ); -#else -static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_sf( Decoder_Struct *st_ivas, float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], int16_t azimuth[][CLDFB_NO_CHANNELS_MAX], int16_t elevation[][CLDFB_NO_CHANNELS_MAX], float energy_ratio1[][CLDFB_NO_CHANNELS_MAX], float spreadCoherence[][CLDFB_NO_CHANNELS_MAX], float surroundingCoherence[][CLDFB_NO_CHANNELS_MAX], float Rmat[3][3] ); -#endif static void ivas_dirac_dec_binaural_internal_sf( Decoder_Struct *st_ivas, float *output_f[], const int16_t nchan_transport ); - static void ivas_dirac_dec_decorrelate_slot_sf( DIRAC_DEC_HANDLE hDirAC, const int8_t slot, float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float decRe[][CLDFB_NO_CHANNELS_MAX], float decIm[][CLDFB_NO_CHANNELS_MAX] ); #endif #endif @@ -688,23 +683,12 @@ static void ivas_dirac_dec_binaural_internal_sf( float Cldfb_RealBuffer_in[2 * BINAURAL_CHANNELS][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_in[2 * BINAURAL_CHANNELS][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; /* local copies of azi, ele, diffuseness */ -#ifdef MASA_PARAMBIN_SF_MAP int16_t azimuth[CLDFB_NO_CHANNELS_MAX]; int16_t elevation[CLDFB_NO_CHANNELS_MAX]; float spreadCoherence[CLDFB_NO_CHANNELS_MAX]; float surroundingCoherence[CLDFB_NO_CHANNELS_MAX]; float energy_ratio1[CLDFB_NO_CHANNELS_MAX]; -#else - int16_t azimuth[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - int16_t elevation[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - float spreadCoherence[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - float surroundingCoherence[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - float energy_ratio1[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; -#endif float Rmat[3][3]; -#ifndef MASA_PARAMBIN_SF_MAP - uint16_t slot_idx; -#endif uint16_t subframe_idx, slot_idx_start; int16_t max_band_decorr; DIFFUSE_DISTRIBUTION_DATA diffuseDistData; @@ -736,22 +720,12 @@ static void ivas_dirac_dec_binaural_internal_sf( subframe_idx = hDirAC->subframes_rendered; /* copy parameters into local buffers*/ -#ifdef MASA_PARAMBIN_SF_MAP mvs2s( hDirAC->azimuth[hDirAC->render_to_md_map[subframe_idx]], azimuth, hDirAC->num_freq_bands ); mvs2s( hDirAC->elevation[hDirAC->render_to_md_map[subframe_idx]], elevation, hDirAC->num_freq_bands ); mvr2r( hDirAC->spreadCoherence[hDirAC->render_to_md_map[subframe_idx]], spreadCoherence, hDirAC->num_freq_bands ); mvr2r( hDirAC->surroundingCoherence[hDirAC->render_to_md_map[subframe_idx]], surroundingCoherence, hDirAC->num_freq_bands ); mvr2r( hDirAC->energy_ratio1[hDirAC->render_to_md_map[subframe_idx]], energy_ratio1, hDirAC->num_freq_bands ); -#else - for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) - { - mvs2s( hDirAC->azimuth[hDirAC->render_to_md_map[slot_idx + slot_idx_start]], azimuth[slot_idx], hDirAC->num_freq_bands ); - mvs2s( hDirAC->elevation[hDirAC->render_to_md_map[slot_idx + slot_idx_start]], elevation[slot_idx], hDirAC->num_freq_bands ); - mvr2r( hDirAC->spreadCoherence[hDirAC->render_to_md_map[slot_idx + slot_idx_start]], spreadCoherence[slot_idx], hDirAC->num_freq_bands ); - mvr2r( hDirAC->surroundingCoherence[hDirAC->render_to_md_map[slot_idx + slot_idx_start]], surroundingCoherence[slot_idx], hDirAC->num_freq_bands ); - mvr2r( hDirAC->energy_ratio1[hDirAC->render_to_md_map[slot_idx + slot_idx_start]], energy_ratio1[slot_idx], hDirAC->num_freq_bands ); - } -#endif + /* CLDFB Analysis of input */ for ( slot = 0; slot < hDirAC->subframe_nbslots[hDirAC->subframes_rendered]; slot++ ) { @@ -1435,10 +1409,7 @@ static void ivas_dirac_dec_decorrelate_slot_sf( return; } -#endif -#ifndef FIX_355_REFACTOR_PARAMBIN_TO_5MS -#ifdef MASA_PARAMBIN_SF_MAP static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_sf( Decoder_Struct *st_ivas, float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], @@ -1841,423 +1812,6 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric return; } - -#else -static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices_sf( - Decoder_Struct *st_ivas, - float inRe[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], - float inIm[][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], - int16_t azimuth[][CLDFB_NO_CHANNELS_MAX], - int16_t elevation[][CLDFB_NO_CHANNELS_MAX], - float energy_ratio1[][CLDFB_NO_CHANNELS_MAX], - float spreadCoherence[][CLDFB_NO_CHANNELS_MAX], - float surroundingCoherence[][CLDFB_NO_CHANNELS_MAX], - float Rmat[3][3] ) -{ - uint8_t ch, bin; - uint8_t separateCenterChannelRendering; - int16_t nBins, idx; - float frameMeanDiffusenessEneWeight[CLDFB_NO_CHANNELS_MAX]; - DIRAC_DEC_HANDLE hDirAC; - DIRAC_DEC_BIN_HANDLE h; - float IIReneLimiterFactor; - float qualityBasedSmFactor; - float lowBitRateEQ[CLDFB_NO_CHANNELS_MAX]; - uint8_t applyLowBitRateEQ; - int16_t slot_idx_start, slot_idx, subframe_idx; - float subFrameTotalEne[CLDFB_NO_CHANNELS_MAX]; - int16_t md_idx; - float slot_ratio; - - hDirAC = st_ivas->hDirAC; - h = st_ivas->hDiracDecBin; - separateCenterChannelRendering = st_ivas->hOutSetup.separateChannelEnabled; - nBins = hDirAC->num_freq_bands; /* Actually bins */ - slot_idx_start = hDirAC->slots_rendered; - subframe_idx = hDirAC->subframes_rendered; - slot_ratio = 1.0f / (float) hDirAC->subframe_nbslots[subframe_idx]; - - set_zero( h->ChCrossRe, nBins ); - set_zero( h->ChCrossIm, nBins ); - set_zero( h->ChCrossReOut, nBins ); - set_zero( h->ChCrossImOut, nBins ); - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - set_zero( h->ChEne[ch], nBins ); - set_zero( h->ChEneOut[ch], nBins ); - } - set_zero( h->frameMeanDiffuseness, nBins ); - - set_zero( frameMeanDiffusenessEneWeight, CLDFB_NO_CHANNELS_MAX ); - - /* Determine EQ for low bit rates (13.2 and 16.4 kbps) */ - applyLowBitRateEQ = 0; - if ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MC_FORMAT ) && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE ) - { - applyLowBitRateEQ = 1; - if ( st_ivas->hDecoderConfig->ivas_total_brate == IVAS_16k4 ) - { - for ( bin = 0; bin < LOW_BIT_RATE_BINAURAL_EQ_BINS; bin++ ) - { - lowBitRateEQ[bin + LOW_BIT_RATE_BINAURAL_EQ_OFFSET] = lowBitRateBinauralEQ[bin] * 0.5f + 0.5f; - } - } - else - { - for ( bin = 0; bin < LOW_BIT_RATE_BINAURAL_EQ_BINS; bin++ ) - { - lowBitRateEQ[bin + LOW_BIT_RATE_BINAURAL_EQ_OFFSET] = lowBitRateBinauralEQ[bin]; - } - } - } - - - set_zero( subFrameTotalEne, CLDFB_NO_CHANNELS_MAX ); - /* Formulate input and target covariance matrices combining all subframes */ - for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) - { - - - /* Calculate input covariance matrix */ - - - for ( bin = 0; bin < nBins; bin++ ) - { - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - float instEne; - - instEne = ( inRe[ch][slot_idx][bin] * inRe[ch][slot_idx][bin] ); - instEne += ( inIm[ch][slot_idx][bin] * inIm[ch][slot_idx][bin] ); - h->ChEne[ch][bin] += instEne; - subFrameTotalEne[bin] += instEne; - } - h->ChCrossRe[bin] += inRe[0][slot_idx][bin] * inRe[1][slot_idx][bin]; - h->ChCrossRe[bin] += inIm[0][slot_idx][bin] * inIm[1][slot_idx][bin]; - h->ChCrossIm[bin] += inRe[0][slot_idx][bin] * inIm[1][slot_idx][bin]; - h->ChCrossIm[bin] -= inIm[0][slot_idx][bin] * inRe[1][slot_idx][bin]; - } - } - - /* Apply EQ at low bit rates */ - if ( applyLowBitRateEQ ) - { - int16_t lastEqBin = LOW_BIT_RATE_BINAURAL_EQ_OFFSET + LOW_BIT_RATE_BINAURAL_EQ_BINS - 1; - - for ( bin = LOW_BIT_RATE_BINAURAL_EQ_OFFSET; bin < lastEqBin; bin++ ) - { - subFrameTotalEne[bin] *= lowBitRateEQ[bin]; - } - for ( ; bin < nBins; bin++ ) - { - subFrameTotalEne[bin] *= lowBitRateEQ[lastEqBin]; - } - } - - if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->nchan_transport == 2 ) - { - float tempRe, tempIm; - - set_zero( subFrameTotalEne, CLDFB_NO_CHANNELS_MAX ); - - for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) - { - - - for ( bin = 0; bin < nBins; bin++ ) - { - tempRe = inRe[0][slot_idx][bin] + inRe[1][slot_idx][bin]; - tempIm = inIm[0][slot_idx][bin] + inIm[1][slot_idx][bin]; - subFrameTotalEne[bin] += tempRe * tempRe + tempIm * tempIm; - } - } - } - - for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) - { - md_idx = hDirAC->render_to_md_map[slot_idx + slot_idx_start]; - /* Determine target covariance matrix containing target binaural properties */ - for ( bin = 0; bin < nBins; bin++ ) - { - float diffuseness = 1.0f; /* ratio1 and ratio2 are subtracted from diffuseness further below */ - float surCoh = 0.0f, spreadCoh = 0.0f; /* Default values if spreadSurroundCoherenceApplied == false */ - float diffEne, dirEne, meanEnePerCh; - uint16_t dirIndex; - - /* When BINAURAL_ROOM is not indicated, hBinaural->earlyPartEneCorrection[bin] values are all 1.0f. - * When BINAURAL_ROOM is indicated, the binaural audio output is based on combined use of the - * HRTF data set and a BRIR-based data set. The HRTF data set is spectrally corrected to match - * the early spectrum of the BRIR data, using the spectral correction data in - * hBinaural->earlyPartEneCorrection[bin], based on the BRIR set. */ - meanEnePerCh = h->earlyPartEneCorrection[bin] * subFrameTotalEne[bin] / 2.0f; - - /* Determine direct part target covariance matrix (for 1 or 2 directions) */ - for ( dirIndex = 0; dirIndex < hDirAC->numSimultaneousDirections; dirIndex++ ) - { - int16_t aziDeg, eleDeg; - float lRealp, lImagp, rRealp, rImagp; - float lRealpTmp, lImagpTmp, rRealpTmp, rImagpTmp; - float hrtfEne[BINAURAL_CHANNELS], hrtfCrossRe, hrtfCrossIm, ratio; - - if ( dirIndex == 0 ) /* For first of the two simultaneous directions */ - { - aziDeg = azimuth[slot_idx][bin]; - eleDeg = elevation[slot_idx][bin]; - ratio = energy_ratio1[slot_idx][bin]; - spreadCoh = spreadCoherence[slot_idx][bin]; - } - else /* For second of the two simultaneous directions */ - { - aziDeg = hDirAC->azimuth2[md_idx][bin]; - eleDeg = hDirAC->elevation2[md_idx][bin]; - ratio = hDirAC->energy_ratio2[md_idx][bin]; - spreadCoh = hDirAC->spreadCoherence2[md_idx][bin]; - } - diffuseness -= ratio; /* diffuseness = 1 - ratio1 - ratio2 */ - - if ( separateCenterChannelRendering ) - { - /* In masa + mono rendering mode, the center directions originate from phantom sources, so the - * spread coherence is increased */ - float aziRad, eleRad, doaVectorX, spatialAngleDeg, altSpreadCoh; - - aziRad = (float) aziDeg * PI_OVER_180; - eleRad = (float) eleDeg * PI_OVER_180; - doaVectorX = cosf( aziRad ) * cosf( eleRad ); - spatialAngleDeg = acosf( doaVectorX ) * _180_OVER_PI; - altSpreadCoh = 1.0f - ( spatialAngleDeg / 30.0f ); - spreadCoh = max( spreadCoh, altSpreadCoh ); - } - - getDirectPartGains( bin, aziDeg, eleDeg, &lRealp, &lImagp, &rRealp, &rImagp, h->renderStereoOutputInsteadOfBinaural, Rmat ); - - if ( h->renderStereoOutputInsteadOfBinaural ) - { - /* Synthesizing spread coherence is not needed for stereo loudspeaker output, - * as directional sound is reproduced with two loudspeakers in any case */ - spreadCoh = 0.0f; - } - - if ( spreadCoh > 0.0f ) - { - float centerMul, sidesMul; - float hrtfEneCenter, hrtfEneSides, hrtfEneRealized, eneCorrectionFactor; - float w1, w2, w3, eq; - - hrtfEneCenter = ( lRealp * lRealp ) + ( lImagp * lImagp ) + ( rRealp * rRealp ) + ( rImagp * rImagp ); - - /* Spread coherence is synthesized as coherent sources at 30 degree horizontal spacing. - * The following formulas determine the gains for these sources. - * spreadCoh = 0: Only panning - * spreadCoh = 0.5: Three sources coherent panning (e.g. 30 0 -30 deg azi) - * spreadCoh = 1.0: Two sources coherent panning with gap (as above, but center is silent) */ - if ( spreadCoh < 0.5f ) - { - /* 0.0f < spreadCoh < 0.5f */ - sidesMul = 0.5774f * spreadCoh * 2.0f; /* sqrt(1/3) = 0.5774f */ - centerMul = 1.0f - ( spreadCoh * 2.0f ) + sidesMul; - } - else - { - /* 0.5f <= spreadCoh < 1.0f */ - centerMul = 2.0f - ( 2.0f * spreadCoh ); - sidesMul = inv_sqrt( centerMul + 2.0f ); - centerMul *= sidesMul; - } - - /* Apply the gain for the center source of the three coherent sources */ - lRealp *= centerMul; - lImagp *= centerMul; - rRealp *= centerMul; - rImagp *= centerMul; - - /* Apply the gain for the left source of the three coherent sources */ - getDirectPartGains( bin, aziDeg + 30, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, h->renderStereoOutputInsteadOfBinaural, Rmat ); - - hrtfEneSides = ( lRealpTmp * lRealpTmp ) + ( lImagpTmp * lImagpTmp ) + ( rRealpTmp * rRealpTmp ) + ( rImagpTmp * rImagpTmp ); - lRealp += sidesMul * lRealpTmp; - lImagp += sidesMul * lImagpTmp; - rRealp += sidesMul * rRealpTmp; - rImagp += sidesMul * rImagpTmp; - - /* Apply the gain for the right source of the three coherent sources. - * -30 degrees to 330 wrapping due to internal functions. */ - getDirectPartGains( bin, aziDeg + 330, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, h->renderStereoOutputInsteadOfBinaural, Rmat ); - - hrtfEneSides += ( lRealpTmp * lRealpTmp ) + ( lImagpTmp * lImagpTmp ) + ( rRealpTmp * rRealpTmp ) + ( rImagpTmp * rImagpTmp ); - lRealp += sidesMul * lRealpTmp; - lImagp += sidesMul * lImagpTmp; - rRealp += sidesMul * rRealpTmp; - rImagp += sidesMul * rImagpTmp; - - /* Formulate an eneCorrectionFactor that compensates for the coherent summation of the HRTFs */ - hrtfEneRealized = ( lRealp * lRealp ) + ( lImagp * lImagp ) + ( rRealp * rRealp ) + ( rImagp * rImagp ); - eneCorrectionFactor = ( ( hrtfEneSides * sidesMul * sidesMul ) + - ( hrtfEneCenter * centerMul * centerMul ) ) / - max( 1e-12f, hrtfEneRealized ); - - /* Weighting factors to determine appropriate target spectrum for spread coherent sound */ - if ( spreadCoh < 0.5 ) - { - w1 = 1.0f - 2.0f * spreadCoh; - w2 = 2.0f * spreadCoh; - w3 = 0.0f; - } - else - { - w1 = 0.0f; - w2 = 2.0f - 2.0f * spreadCoh; - w3 = 2.0f * spreadCoh - 1.0f; - } - - if ( ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) ) - { - idx = min( bin, MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS - 1 ); - - /* Apply the target spectrum to the eneCorrectionFactor */ - if ( separateCenterChannelRendering ) /* spreadCoh mostly originates from phantom sources in separate channel rendering mode */ - { - eneCorrectionFactor *= w1 * 1.0f + ( w2 + w3 ) * spreadCohEne1[idx]; - } - else - { - eneCorrectionFactor *= w1 * 1.0f + w2 * spreadCohEne05[idx] + w3 * spreadCohEne1[idx]; - } - } - - /* Equalize the spread coherent combined HRTFs */ - eq = min( 4.0f, sqrtf( eneCorrectionFactor ) ); - lRealp *= eq; - lImagp *= eq; - rRealp *= eq; - rImagp *= eq; - } - - hrtfEne[0] = ( lRealp * lRealp ) + ( lImagp * lImagp ); - hrtfEne[1] = ( rRealp * rRealp ) + ( rImagp * rImagp ); - hrtfCrossRe = ( lRealp * rRealp ) + ( lImagp * rImagp ); - hrtfCrossIm = ( -lImagp * rRealp ) + ( lRealp * rImagp ); - - /* Add direct part (1 or 2) covariance matrix */ - dirEne = slot_ratio * ratio * meanEnePerCh; - h->ChEneOut[0][bin] += dirEne * hrtfEne[0]; /* Dir ene part*/ - h->ChEneOut[1][bin] += dirEne * hrtfEne[1]; - h->ChCrossReOut[bin] += dirEne * hrtfCrossRe; /* Dir cross re */ - h->ChCrossImOut[bin] += dirEne * hrtfCrossIm; /* Dir cross im */ - } - - /* Add diffuse / ambient part covariance matrix */ - diffuseness = max( 0.0f, diffuseness ); - diffEne = slot_ratio * diffuseness * meanEnePerCh; - surCoh = surroundingCoherence[slot_idx][bin]; - if ( ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) ) - { - if ( !h->renderStereoOutputInsteadOfBinaural ) - { - idx = min( bin, MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS - 1 ); - /* Apply target spectrum that emphasizes low frequencies when the sound is surround coherent */ - diffEne *= ( 1.0f - surCoh ) + surCoh * surCohEne[idx]; - } - } - h->ChEneOut[0][bin] += diffEne; /* Diff ene part*/ - h->ChEneOut[1][bin] += diffEne; - - if ( h->renderStereoOutputInsteadOfBinaural ) - { - /* When rendering stereo, ambience (except for surround coherent sound) has zero ICC. */ - h->ChCrossReOut[bin] += surCoh * diffEne; - } - else /* When rendering binaural, ambience has frequency dependent ICC. */ - { - if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR && bin < BINAURAL_COHERENCE_DIFFERENCE_BINS ) - { - float diffuseFieldCoherence; - diffuseFieldCoherence = hDirAC->hDiffuseDist->diffuseRatioX[0][bin] * h->diffuseFieldCoherenceX[bin] + hDirAC->hDiffuseDist->diffuseRatioY[0][bin] * h->diffuseFieldCoherenceY[bin] + hDirAC->hDiffuseDist->diffuseRatioZ[0][bin] * h->diffuseFieldCoherenceZ[bin]; - h->ChCrossReOut[bin] += ( ( 1.0f - surCoh ) * diffuseFieldCoherence + surCoh ) * diffEne; - } - else - { - h->ChCrossReOut[bin] += ( ( 1.0f - surCoh ) * h->diffuseFieldCoherence[bin] + surCoh ) * diffEne; - } - } - - /* Store parameters for formulating average diffuseness over frame */ - h->frameMeanDiffuseness[bin] += diffEne; - frameMeanDiffusenessEneWeight[bin] += slot_ratio * meanEnePerCh; - } - } - - /* Formulate average diffuseness over frame */ - for ( bin = 0; bin < nBins; bin++ ) - { - h->frameMeanDiffuseness[bin] /= fmaxf( 1e-12f, frameMeanDiffusenessEneWeight[bin] ); - } - - /* Determine encoding quality based additional smoothing factor */ - qualityBasedSmFactor = 1.0f; - if ( st_ivas->hMasa != NULL ) - { - qualityBasedSmFactor = st_ivas->hMasa->data.dir_decode_quality; - qualityBasedSmFactor *= qualityBasedSmFactor; - } - - /* Temporal IIR-type smoothing of covariance matrices */ - if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE ) - { - IIReneLimiterFactor = 16.0f + ( 1.0f - qualityBasedSmFactor ); - } - else - { - IIReneLimiterFactor = 8.0f + ( 1.0f - qualityBasedSmFactor ); - } - for ( bin = 0; bin < nBins; bin++ ) - { - float eneRatio, IIReneLimiter; - - /* Temporally smooth cov mtx estimates for resulting mixing matrix stability. The design principle is that - * the energy history (IIR) must not be more than double of the current frame energy. This provides more - * robust performance at energy offsets when compared to typical IIR averaging. */ - eneRatio = ( h->ChEne[0][bin] + h->ChEne[1][bin] ) / fmaxf( 1e-12f, ( h->ChEnePrev[0][bin] + h->ChEnePrev[1][bin] ) ); - IIReneLimiter = fminf( 1.0f, eneRatio * IIReneLimiterFactor ); - - h->ChCrossRe[bin] *= qualityBasedSmFactor; - h->ChCrossIm[bin] *= qualityBasedSmFactor; - h->ChCrossReOut[bin] *= qualityBasedSmFactor; - h->ChCrossImOut[bin] *= qualityBasedSmFactor; - - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - h->ChEne[ch][bin] *= qualityBasedSmFactor; - h->ChEneOut[ch][bin] *= qualityBasedSmFactor; - } - - h->ChCrossRe[bin] += IIReneLimiter * h->ChCrossRePrev[bin]; - h->ChCrossIm[bin] += IIReneLimiter * h->ChCrossImPrev[bin]; - h->ChCrossReOut[bin] += IIReneLimiter * h->ChCrossReOutPrev[bin]; - h->ChCrossImOut[bin] += IIReneLimiter * h->ChCrossImOutPrev[bin]; - - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - h->ChEne[ch][bin] += IIReneLimiter * h->ChEnePrev[ch][bin]; - h->ChEneOut[ch][bin] += IIReneLimiter * h->ChEneOutPrev[ch][bin]; - } - - /* Store energy values and coefficients for next round */ - h->ChCrossRePrev[bin] = h->ChCrossRe[bin]; - h->ChCrossImPrev[bin] = h->ChCrossIm[bin]; - h->ChCrossReOutPrev[bin] = h->ChCrossReOut[bin]; - h->ChCrossImOutPrev[bin] = h->ChCrossImOut[bin]; - - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - h->ChEnePrev[ch][bin] = h->ChEne[ch][bin]; - h->ChEneOutPrev[ch][bin] = h->ChEneOut[ch][bin]; - } - } - - return; -} -#endif #endif #endif -- GitLab From 5a0ea5bccfaa927fde58793a64287152e10d459d Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Mon, 15 May 2023 10:23:53 +0200 Subject: [PATCH 38/39] clang-format --- lib_dec/ivas_dirac_output_synthesis_dec.c | 100 +++++++++++----------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/lib_dec/ivas_dirac_output_synthesis_dec.c b/lib_dec/ivas_dirac_output_synthesis_dec.c index 275f56a40e..a7bb8e504d 100644 --- a/lib_dec/ivas_dirac_output_synthesis_dec.c +++ b/lib_dec/ivas_dirac_output_synthesis_dec.c @@ -711,7 +711,7 @@ void ivas_dirac_dec_output_synthesis_process_slot( } else // ( hDirAC->hConfig->dec_param_estim == TRUE ) #endif - if ( hDirAC->hConfig->dec_param_estim == TRUE ) + if ( hDirAC->hConfig->dec_param_estim == TRUE ) { /* compute direct responses */ @@ -746,59 +746,59 @@ void ivas_dirac_dec_output_synthesis_process_slot( if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { - ivas_dirac_dec_compute_gain_factors( num_freq_bands, - diffuseness, - h_dirac_output_synthesis_params->max_band_decorr, - h_dirac_output_synthesis_state->direct_power_factor, - h_dirac_output_synthesis_state->diffuse_power_factor ); + ivas_dirac_dec_compute_gain_factors( num_freq_bands, + diffuseness, + h_dirac_output_synthesis_params->max_band_decorr, + h_dirac_output_synthesis_state->direct_power_factor, + h_dirac_output_synthesis_state->diffuse_power_factor ); - v_multc( h_dirac_output_synthesis_state->direct_power_factor, - 0.25f, - h_dirac_output_synthesis_state->direct_power_factor, - num_freq_bands ); - v_multc( h_dirac_output_synthesis_state->diffuse_power_factor, - 0.25f, - h_dirac_output_synthesis_state->diffuse_power_factor, - num_freq_bands ); + v_multc( h_dirac_output_synthesis_state->direct_power_factor, + 0.25f, + h_dirac_output_synthesis_state->direct_power_factor, + num_freq_bands ); + v_multc( h_dirac_output_synthesis_state->diffuse_power_factor, + 0.25f, + h_dirac_output_synthesis_state->diffuse_power_factor, + num_freq_bands ); /*Direct gain*/ - for ( ch_idx = 0; ch_idx < min( 4, nchan_transport ); ch_idx++ ) + for ( ch_idx = 0; ch_idx < min( 4, nchan_transport ); ch_idx++ ) + { + int16_t k; + if ( ch_idx != 0 ) { - int16_t k; - if ( ch_idx != 0 ) - { - float a, b, c; + float a, b, c; - /*Directonal sound gain nrg compensation*/ - for ( k = 0; k < num_freq_bands_diff; k++ ) - { - a = h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands + k]; - b = reference_power[k + num_freq_bands] / ( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] + EPSILON ); - c = 1.f + ( 1.f / 6.f ) * ( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f ); /*Diffuseness modellling nrg compensation*/ - h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( diffuseness[k] * c + ( ( 1.f - diffuseness[k] ) * a * a * b ) ); - } - for ( ; k < num_freq_bands; k++ ) - { - a = h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands + k]; - b = reference_power[k + num_freq_bands] / ( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] + EPSILON ); - c = 1.f + ( 1.f / 6.f ) * ( h_dirac_output_synthesis_params->diffuse_compensation_factor - 1.f ); /*Diffuseness modellling nrg compensation*/ - h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( diffuseness[k] * c + ( ( 1.f - diffuseness[k] ) * a * a * b ) ); - } + /*Directonal sound gain nrg compensation*/ + for ( k = 0; k < num_freq_bands_diff; k++ ) + { + a = h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands + k]; + b = reference_power[k + num_freq_bands] / ( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] + EPSILON ); + c = 1.f + ( 1.f / 6.f ) * ( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f ); /*Diffuseness modellling nrg compensation*/ + h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( diffuseness[k] * c + ( ( 1.f - diffuseness[k] ) * a * a * b ) ); } - else + for ( ; k < num_freq_bands; k++ ) { - /*Diffuseness modellling nrg compensation*/ - for ( k = 0; k < num_freq_bands_diff; k++ ) - { - h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( 1.0f + diffuseness[k] * 0.5f * ( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f ) ); - } - for ( ; k < num_freq_bands; k++ ) - { - h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( 1.0f + diffuseness[k] * 0.5f * ( h_dirac_output_synthesis_params->diffuse_compensation_factor - 1.f ) ); - } + a = h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands + k]; + b = reference_power[k + num_freq_bands] / ( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] + EPSILON ); + c = 1.f + ( 1.f / 6.f ) * ( h_dirac_output_synthesis_params->diffuse_compensation_factor - 1.f ); /*Diffuseness modellling nrg compensation*/ + h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( diffuseness[k] * c + ( ( 1.f - diffuseness[k] ) * a * a * b ) ); } } + else + { + /*Diffuseness modellling nrg compensation*/ + for ( k = 0; k < num_freq_bands_diff; k++ ) + { + h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( 1.0f + diffuseness[k] * 0.5f * ( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f ) ); + } + for ( ; k < num_freq_bands; k++ ) + { + h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( 1.0f + diffuseness[k] * 0.5f * ( h_dirac_output_synthesis_params->diffuse_compensation_factor - 1.f ) ); + } + } + } /*Directional gain (panning)*/ for ( ch_idx = min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ ) @@ -833,11 +833,11 @@ void ivas_dirac_dec_output_synthesis_process_slot( else { /* compute reference and diffuse power factor for this frame */ - ivas_dirac_dec_compute_power_factors( num_freq_bands, - diffuseness, - h_dirac_output_synthesis_params->max_band_decorr, - h_dirac_output_synthesis_state->direct_power_factor, - h_dirac_output_synthesis_state->diffuse_power_factor ); + ivas_dirac_dec_compute_power_factors( num_freq_bands, + diffuseness, + h_dirac_output_synthesis_params->max_band_decorr, + h_dirac_output_synthesis_state->direct_power_factor, + h_dirac_output_synthesis_state->diffuse_power_factor ); } } @@ -996,7 +996,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( } else #endif - if ( hDirAC->hConfig->dec_param_estim == FALSE ) + if ( hDirAC->hConfig->dec_param_estim == FALSE ) { /*Direct gain*/ for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ ) -- GitLab From f88ec7013b795d9d72245697b410279ee834ff3a Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Mon, 15 May 2023 10:56:18 +0200 Subject: [PATCH 39/39] clang-format --- lib_rend/ivas_objectRenderer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 5d9689f4f7..83db832937 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -454,7 +454,7 @@ void TDREND_Update_object_positions( #ifdef JBM_TSM_ON_TCS float *output[] #else - float output[][L_FRAME48k] /* i/o: SCE/MC channels */ + float output[][L_FRAME48k] /* i/o: SCE/MC channels */ #endif ) { -- GitLab