diff --git a/apps/decoder.c b/apps/decoder.c index 871738ec0d762256e644bb655b611f6c944e0cf4..6f7b929cd2eccb2451bb5b6146cfcd531a8a14ba 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -38,15 +38,16 @@ #include "bitstream_reader.h" #include "evs_rtp_payload.h" #include "ism_file_writer.h" +#ifdef IVAS_RTPDUMP +#include "ivas_rtp_file.h" +#endif #include "jbm_file_writer.h" #include "hrtf_file_reader.h" #include "ls_custom_file_reader.h" #include "masa_file_writer.h" #include "render_config_reader.h" #include "rotation_file_reader.h" -#ifdef FIX_1053_REVERB_RECONFIGURATION #include "aeid_file_reader.h" -#endif #include "split_render_file_read_write.h" #include "obj_edit_file_reader.h" #ifdef VARIABLE_SPEED_DECODING @@ -58,7 +59,13 @@ #include "debug.h" #endif #include "wmc_auto.h" +#ifdef FLP_EXCEPTION_TRAP +#include "flp_debug.h" +#endif +#ifdef FIXED_RTP_SEQUENCE_NUM +#define RANDOM_INITSEED_DEC ( 0xFEEDFADE ) +#endif #define WMC_TOOL_SKIP @@ -81,7 +88,6 @@ static * Local structure for storing cmdln arguments *------------------------------------------------------------------------------------------*/ - typedef struct { uint16_t *pID; @@ -129,6 +135,11 @@ typedef struct IVAS_DEC_COMPLEXITY_LEVEL complexityLevel; bool tsmEnabled; IVAS_RENDER_FRAMESIZE renderFramesize; +#ifdef IVAS_RTPDUMP + bool applyPiData; + char *piOutputFilename; + bool rtpOutSR; +#endif #ifdef DEBUGGING #ifdef DEBUG_FOA_AGC FILE *agcBitstream; /* temporary */ @@ -152,7 +163,7 @@ typedef struct hrtfFileReader *hrtfReader; char *hrtfFileName; - IVAS_DEC_HRTF_HANDLE *hHrtfTD; + IVAS_DEC_HRTF_TD_HANDLE *hHrtfTD; IVAS_DEC_HRTF_STATISTICS_HANDLE *hHrtfStatistics; @@ -172,11 +183,11 @@ typedef struct static bool parseCmdlIVAS_dec( int16_t argc, char **argv, DecArguments *arg ); static void usage_dec( void ); -static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtfBinary, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); +static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtf, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); #ifdef FIX_1119_SPLIT_RENDERING_VOIP static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtf, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); #else -static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtfBinary, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); +static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtf, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ObjectEditFileReader *objectEditFileReader, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); #endif static ivas_error load_hrtf_from_file( IVAS_DEC_HRTF_BINARY_WRAPPER *hHrtfBinary, IVAS_DEC_HANDLE hIvasDec, const IVAS_AUDIO_CONFIG OutputConfig, const int32_t output_Fs ); #ifdef DEBUGGING @@ -185,7 +196,6 @@ static int16_t app_own_random( int16_t *seed ); #endif static void do_object_editing( IVAS_EDITABLE_PARAMETERS *editableParameters, ObjectEditFileReader *objectEditFileReader ); - /*------------------------------------------------------------------------------------------* * main() * @@ -231,6 +241,9 @@ int main( reset_wmops(); reset_mem( USE_BYTES ); #endif +#ifdef FLP_EXCEPTION_TRAP + enable_float_exception_trap( FLE_MASK_DENORM | FLE_MASK_UNDERFLOW ); +#endif hHrtfBinary.hHrtfTD = NULL; /* just to avoid compilation warning */ hHrtfBinary.hHrtfStatistics = NULL; /* just to avoid compilation warning */ @@ -437,15 +450,19 @@ int main( *------------------------------------------------------------------------------------------*/ asked_frame_size = arg.renderFramesize; - uint16_t aeID = arg.aeSequence.count > 0 ? arg.aeSequence.pID[0] : 65535; - if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputConfig, arg.renderFramesize, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.enableExternalOrientation, arg.orientation_tracking, arg.renderConfigEnabled, arg.non_diegetic_pan_enabled, arg.non_diegetic_pan_gain, - arg.dpidEnabled, aeID, arg.objEditEnabled, arg.delayCompensationEnabled ) ) != IVAS_ERR_OK ) +#ifdef IVAS_RTPDUMP + arg.enableHeadRotation = arg.enableHeadRotation || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM; +#endif + if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputConfig, arg.renderFramesize, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, + arg.enableHeadRotation, arg.enableExternalOrientation, arg.orientation_tracking, arg.renderConfigEnabled, arg.non_diegetic_pan_enabled, + arg.non_diegetic_pan_gain, arg.dpidEnabled, aeID, arg.objEditEnabled, arg.delayCompensationEnabled ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } + if ( ( error = IVAS_DEC_GetRenderFramesize( hIvasDec, &arg.renderFramesize ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); @@ -476,7 +493,9 @@ int main( goto cleanup; } +#ifndef IVAS_RTPDUMP arg.enableHeadRotation = true; +#endif } /*------------------------------------------------------------------------------------------* @@ -588,7 +607,8 @@ int main( IVAS_RENDER_CONFIG_DATA renderConfig; /* sanity check */ - if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM && arg.non_diegetic_pan_enabled == false ) + if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && + arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM && arg.non_diegetic_pan_enabled == false ) { fprintf( stderr, "\nExternal Renderer Config is supported only when binaural output configurations is used as output OR when Split rendering mode is enabled. Exiting. \n" ); goto cleanup; @@ -617,14 +637,12 @@ int main( fprintf( stderr, "Failed to get directivity patterns for one or more of IDs: %d %d %d %d\n\n", arg.directivityPatternId[0], arg.directivityPatternId[1], arg.directivityPatternId[2], arg.directivityPatternId[3] ); goto cleanup; } - if ( ( error = RenderConfigReader_getDistanceAttenuation( renderConfigReader, renderConfig.distAtt ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Failed to get Distance Attenuation \n\n" ); goto cleanup; } - - if ( ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { if ( asked_frame_size != IVAS_RENDER_FRAMESIZE_20MS && ( renderConfig.split_rend_config.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE || @@ -736,6 +754,7 @@ int main( if ( arg.voipMode ) { + #ifdef FIX_1119_SPLIT_RENDERING_VOIP error = decodeVoIP( arg, hBsReader, &hHrtfBinary, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, objectEditFileReader, &splitRendBits, hIvasDec, pcmBuf ); #else @@ -790,7 +809,6 @@ cleanup: free( arg.aeSequence.pID ); free( arg.aeSequence.pValidity ); } - #ifdef DEBUG_SBA_AUDIO_DUMP IVAS_DEC_GetSbaDebugParams( hIvasDec, &numOutChannels, &numTransportChannels, &pca_ingest_channels ); @@ -967,6 +985,11 @@ static bool parseCmdlIVAS_dec( arg->referenceVectorTrajFileName = NULL; arg->enableExternalOrientation = false; arg->externalOrientationTrajFileName = NULL; +#ifdef IVAS_RTPDUMP + arg->applyPiData = false; + arg->piOutputFilename = NULL; + arg->rtpOutSR = false; +#endif #ifdef SUPPORT_JBM_TRACEFILE arg->jbmTraceFilename = NULL; @@ -1053,6 +1076,30 @@ static bool parseCmdlIVAS_dec( arg->inputFormat = IVAS_DEC_INPUT_FORMAT_RTPDUMP_HF; i++; } +#ifdef IVAS_RTPDUMP + else if ( strcmp( argv_to_upper, "-PIDATAFILE" ) == 0 ) + { + i++; + if ( argc - i <= 3 || argv[i][0] == '-' ) + { + fprintf( stderr, "Error: PI Data Output file name not specified!\n\n" ); + usage_dec(); + return false; + } + + arg->piOutputFilename = argv[i++]; + } + else if ( strcmp( argv_to_upper, "-APPLYPIDATA" ) == 0 ) + { + arg->applyPiData = true; + i++; + } + else if ( strcmp( argv_to_upper, "-RTPOUTSR" ) == 0 ) + { + arg->rtpOutSR = true; + i++; + } +#endif #ifdef SUPPORT_JBM_TRACEFILE else if ( strcmp( argv_to_upper, "-TRACEFILE" ) == 0 ) { @@ -1151,7 +1198,7 @@ static bool parseCmdlIVAS_dec( if ( arg->tsmScale < IVAS_TIME_SCALE_MIN || arg->tsmScale > IVAS_TIME_SCALE_MAX ) { - fprintf( stderr, "Error: Scaling factor value must be IVAS_TIME_SCALE_MIN <= fac <= IVAS_TIME_SCALE_MAX !\n\n" ); + fprintf( stderr, "Error: Scaling factor value must be IVAS_TIME_SCALE_MIN <= fac <= IVAS_TIME_SCALE_MAX!\n\n" ); usage_dec(); return false; } @@ -1380,86 +1427,26 @@ static bool parseCmdlIVAS_dec( if ( !is_digits_only( argv[i] ) ) { -#ifdef FIX_1053_REVERB_RECONFIGURATION aeidFileReader *aeidReader = NULL; + if ( aeidFileReader_open( argv[i], &aeidReader ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError: Can't open aeid file %s \n", argv[i] ); usage_dec(); return false; } + if ( aeidFileReading( aeidReader, &arg->aeSequence.count, &arg->aeSequence.pID, &arg->aeSequence.pValidity ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError while reading aeid from %s\n", argv[i] ); usage_dec(); return false; } - aeidFileReader_close( &aeidReader ); - i++; - } -#else - uint16_t k; - char *s = argv[i]; - char *token = argv[i]; - - for ( k = 0; s[k]; ) - { - s[k] == ',' ? k++ : *s++; - } - k++; - - if ( k == 0 ) - { - fprintf( stdout, "Error: Invalid acoustic environment sequence specified: %s\n\n", argv[i] ); - usage_dec(); - return false; - } - - if ( NULL == ( arg->aeSequence.pID = malloc( sizeof( uint16_t ) * k ) ) || - NULL == ( arg->aeSequence.pValidity = malloc( sizeof( uint16_t ) * k ) ) ) - { - fprintf( stdout, "Error: Unable to allocate memory for acoustic environment sequence: %s\n\n", argv[i] ); - usage_dec(); - return false; - } - - arg->aeSequence.count = k; - - k = 0; - token = strtok( argv[i++], ":" ); - - while ( token != NULL ) - { - if ( !is_number( token ) ) - { - fprintf( stdout, "Error: Invalid token %s found in acoustic environment sequence: %s\n\n", token, argv[i] ); - usage_dec(); - return false; - } - arg->aeSequence.pID[k] = (uint16_t) atoi( token ); - token = strtok( NULL, "," ); - if ( !is_number( token ) ) - { - fprintf( stdout, "Error: Invalid token %s found in acoustic environment sequence: %s\n\n", token, argv[i] ); - usage_dec(); - return false; - } - arg->aeSequence.pValidity[k] = (uint16_t) atoi( token ); - - token = strtok( NULL, ":" ); - k++; - } + aeidFileReader_close( &aeidReader ); - if ( k != arg->aeSequence.count ) - { - fprintf( stdout, "Error while parsing acoustic environment sequence: %s\n\n", argv[i] ); - usage_dec(); - return false; - } + i++; } -#endif - else { /* A single acoustic environment */ @@ -1587,6 +1574,7 @@ static bool parseCmdlIVAS_dec( usage_dec(); return false; } + if ( arg->outputMdFilename != NULL && arg->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { fprintf( stderr, "Error: Output split rendering metadata file is supported for BINAURAL_SPLIT_PCM output config. only\n\n" ); @@ -1696,10 +1684,21 @@ static void usage_dec( void ) fprintf( stdout, "--------\n" ); 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" ); +#ifdef IVAS_RTPDUMP + fprintf( stdout, "-VOIP_hf_only=1 : VoIP mode: EVS or IVAS RTP Payload Format hf_only=1 in rtpdump\n" ); + fprintf( stdout, " The decoder may read rtpdump files containing TS26.445 Annex A.2.2\n" ); + fprintf( stdout, " EVS RTP Payload Format or rtpdump files containing TS26.253 Annex A\n" ); + fprintf( stdout, " IVAS 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" ); + fprintf( stdout, "-PiDataFile PF Log the timestampped PI data.\n" ); + fprintf( stdout, "-ApplyPiData Apply the PI data found in the rtp packet.\n" ); + fprintf( stdout, "-rtpOutSR : Split Rendering bitstream RTPDump output \n" ); +#else fprintf( stdout, "-VOIP_hf_only=1 : VoIP mode: EVS RTP Payload Format hf_only=1 in rtpdump\n" ); 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" ); +#endif #ifdef SUPPORT_JBM_TRACEFILE fprintf( stdout, "-Tracefile TF : VoIP mode: Generate trace file named TF. Requires -no_delay_cmp to\n" ); fprintf( stdout, " be enabled so that trace contents remain in sync with audio output.\n" ); @@ -1747,15 +1746,8 @@ static void usage_dec( void ) fprintf( stdout, " output configuration. ID1, ID2, ID3, ID4 specify the directivity pattern IDs used for\n" ); fprintf( stdout, " ISMs 1,2,3 and 4 respectively. This options needs to be accompanied by a render_config file,\n" ); fprintf( stdout, " otherwise a default directivity pattern is used.\n" ); -#ifdef FIX_1053_REVERB_RECONFIGURATION fprintf( stdout, "-aeid ID | File : Acoustic environment ID (number > 0)\n" ); fprintf( stdout, " alternatively, it can be a text file where each line contains \"ID duration\"\n" ); -#else - fprintf( stdout, "-aeid ID : Acoustic environment ID (number > 0) or\n" ); - fprintf( stdout, " a sequence thereof in the format [ID1:duration1,ID2:duration2...]\n" ); - fprintf( stdout, " without braces and spaces, with ':' character separating ID from duration and ',' separating\n" ); - fprintf( stdout, " ID and duration pairs, where duration is specified in frames\n" ); -#endif fprintf( stdout, " for BINAURAL_ROOM_REVERB output configuration.\n" ); fprintf( stdout, "-obj_edit File : Object editing instructions file or NULL for built-in example\n" ); fprintf( stdout, "-level level : Complexity level, level = (1, 2, 3), will be defined after characterisation. \n" ); @@ -1809,6 +1801,9 @@ static ivas_error initOnFirstGoodFrame( IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS], /* o : */ int16_t *pNumOutChannels, /* o : */ uint16_t *pNumObj, /* o : */ +#ifdef IVAS_RTPDUMP + IVAS_RTP *srRtp, /* o : */ +#endif SplitFileReadWrite **splitRendWriter ) { int16_t isSplitRend, isSplitCoded; @@ -1860,6 +1855,14 @@ static ivas_error initOnFirstGoodFrame( ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; int16_t splitRendIsarFrameSizeMs; int16_t lc3plusHighRes; +#ifdef FIXED_RTP_SEQUENCE_NUM + /* Ideally ssrc is negotiated via SDP and sequence number is radomized but we + use fixed seed for random num generator for regression based tests. Any realtime + application should implement this initialization seperately */ + srand( RANDOM_INITSEED_DEC ); + uint32_t ssrc = ( (uint32_t) rand() & 0x0000FFFF ) | ( (uint32_t) rand() << 16 ); + uint16_t seqNumInitVal = (uint16_t) ( rand() & 0xFFFF ); +#endif if ( ( error = IVAS_DEC_GetDelay( hIvasDec, delayNumSamples_temp, &delayTimeScale_temp ) ) != IVAS_ERR_OK ) { @@ -1873,7 +1876,45 @@ static ivas_error initOnFirstGoodFrame( return error; } +#ifdef IVAS_RTPDUMP + /* Split Rendering RTPDump Output file */ + if ( arg.rtpOutSR && srRtp != NULL ) + { + FILE *fParamsSR = NULL; + char srParamsFile[FILENAME_MAX], *ext = ".sr.txt"; + strncpy( srParamsFile, arg.outputWavFilename, FILENAME_MAX - sizeof( ext ) ); + strncat( srParamsFile, ext, sizeof( ext ) + 1 ); + + /* Write the Split Rendering Params passed from SDP to srParamsFile */ + fParamsSR = fopen( srParamsFile, "w" ); + if ( NULL != fParamsSR ) + { + fprintf( fParamsSR, "CODEC = %s;\nDOF = %d;\nFRAMESIZE = %d;\nRENDERSIZE = %d;\nLC3PLUS_HIGHRES = %d;\n", + splitRendCodec == ISAR_SPLIT_REND_CODEC_LC3PLUS ? "LC3PLUS" : "LCLD", + poseCorrection, + splitRendCodecFrameSizeMs, + splitRendIsarFrameSizeMs, + lc3plusHighRes ); + fclose( fParamsSR ); + fParamsSR = NULL; + } + + + /* Split Rendering RTPDump Output file */ +#ifdef FIXED_RTP_SEQUENCE_NUM + if ( ( error = IVAS_RTP_WRITER_Init( srRtp, arg.outputWavFilename, 1000 / ( IVAS_NUM_FRAMES_PER_SEC * splitRendCodecFrameSizeMs ), ssrc, seqNumInitVal ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_RTP_WRITER_Init( srRtp, arg.outputWavFilename, 1000 / ( IVAS_NUM_FRAMES_PER_SEC * splitRendCodecFrameSizeMs ) ) ) != IVAS_ERR_OK ) +#endif + { + fprintf( stderr, "\nError: Can't open SR output bitstream file for RTP output %s \n\n", arg.outputWavFilename ); + return error; + } + } + else if ( isSplitCoded ) +#else if ( isSplitCoded ) +#endif { if ( ( error = split_rend_writer_open( splitRendWriter, arg.outputWavFilename, delayNumSamples_temp[0], delayTimeScale_temp, splitRendCodec, poseCorrection, splitRendCodecFrameSizeMs, splitRendIsarFrameSizeMs, arg.output_Fs, lc3plusHighRes ) ) != IVAS_ERR_OK ) { @@ -1907,6 +1948,74 @@ static ivas_error initOnFirstGoodFrame( } } +#ifdef IVAS_RTPDUMP + if ( !arg.rtpOutSR ) + { + int16_t pcmFrameSize; + if ( ( error = IVAS_DEC_GetOutputBufferSize( hIvasDec, &pcmFrameSize ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetOutputBufferSize, error code: %d\n", error ); + return error; + } + + /* Write zeros to the output audio buffer */ + int16_t *zeroBuf = calloc( pcmFrameSize, sizeof( int16_t ) ); + if ( zeroBuf == NULL ) + { + fprintf( stdout, "Error: Unable to allocate memory for output buffer.\n" ); + return IVAS_ERR_FAILED_ALLOC; + } + + for ( int16_t i = 0; i < numInitialBadFrames; ++i ) + { +#ifdef FIX_1119_SPLIT_RENDERING_VOIP + if ( isSplitRend ) +#else + if ( *splitRendWriter != NULL ) +#endif + { + ISAR_SPLIT_REND_BITS_DATA splitRendBitsZero; + splitRendBitsZero.bits_buf = NULL; + splitRendBitsZero.bits_read = 0; + splitRendBitsZero.bits_written = 0; + splitRendBitsZero.buf_len = 0; + splitRendBitsZero.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + splitRendBitsZero.pose_correction = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + splitRendBitsZero.codec_frame_size_ms = 0; + splitRendBitsZero.isar_frame_size_ms = 20; + + if ( split_rend_write_bitstream_to_file( *splitRendWriter, splitRendBitsZero.bits_buf, &splitRendBitsZero.bits_read, &splitRendBitsZero.bits_written ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to write to bitstream file!\n" ); + return error; + } + } + +#ifdef FIX_1119_SPLIT_RENDERING_VOIP + if ( !isSplitCoded ) +#else + else +#endif + { + if ( *pRemainingDelayNumSamples < *numOutSamples ) + { + if ( ( error = AudioFileWriter_write( *ppAfWriter, zeroBuf, *numOutSamples * *pNumOutChannels - ( *pRemainingDelayNumSamples * *pNumOutChannels ) ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + return error; + } + *pRemainingDelayNumSamples = 0; + } + else + { + *pRemainingDelayNumSamples -= *numOutSamples; + } + } + } + + free( zeroBuf ); + } +#else int16_t pcmFrameSize; if ( ( error = IVAS_DEC_GetOutputBufferSize( hIvasDec, &pcmFrameSize ) ) != IVAS_ERR_OK ) { @@ -1971,6 +2080,8 @@ static ivas_error initOnFirstGoodFrame( free( zeroBuf ); +#endif + /* Open other output files if EXT output config - now details about ISM or MASA are known */ if ( arg.outputConfig == IVAS_AUDIO_CONFIG_EXTERNAL ) { @@ -2063,7 +2174,11 @@ static ivas_error initOnFirstGoodFrame( } } +#ifdef IVAS_RTPDUMP + if ( arg.rtpOutSR || *splitRendWriter != NULL ) +#else if ( *splitRendWriter != NULL ) +#endif { if ( numOutSamples == NULL || vec_pos_len == NULL ) { @@ -2140,8 +2255,6 @@ static ivas_error decodeG192( int16_t vec_pos_update, vec_pos_len; SplitFileReadWrite *splitRendWriter = NULL; int16_t isSplitRend, isSplitCoded; - IVAS_RENDER_CONFIG_DATA renderConfig; - RenderConfigReader *renderConfigReader = NULL; #ifdef VARIABLE_SPEED_DECODING if ( arg.tsmEnabled ) @@ -2174,6 +2287,9 @@ static ivas_error decodeG192( return error; } + IVAS_RENDER_CONFIG_DATA renderConfig; + RenderConfigReader *renderConfigReader = NULL; + if ( arg.renderConfigEnabled ) { if ( ( error = RenderConfigReader_open( arg.renderConfigFilename, &renderConfigReader ) ) != IVAS_ERR_OK ) @@ -2203,6 +2319,7 @@ static ivas_error decodeG192( /* we always start with needing a new frame */ needNewFrame = true; + if ( !arg.quietModeEnabled ) { fprintf( stdout, "\n------ Running the decoder ------\n\n" ); @@ -2470,7 +2587,7 @@ static ivas_error decodeG192( } } #endif - /* Feed into decoder */ + /* Feed into decoder and decode transport channels */ 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 ) ); @@ -2532,13 +2649,14 @@ static ivas_error decodeG192( /* Do object metadata editing here ... */ do_object_editing( &editableParameters, objectEditFileReader ); - /* set new object parameters*/ + /* set new object parameters */ if ( ( error = IVAS_DEC_SetEditableParameters( hIvasDec, editableParameters ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError: could not set the editable parameters: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); return error; } } + /* Do the final preparations needed for rendering */ if ( ( error = IVAS_DEC_PrepareRenderer( hIvasDec ) ) != IVAS_ERR_OK ) { @@ -2547,6 +2665,7 @@ static ivas_error decodeG192( } } + /* Render */ if ( isSplitRend ) { if ( ( error = IVAS_DEC_GetSplitBinauralBitstream( hIvasDec, (void *) ( pcmBuf + nOutChannels * nSamplesRendered ), splitRendBits, &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) @@ -2565,9 +2684,11 @@ static ivas_error decodeG192( fprintf( stderr, "\nError in IVAS_DEC_GetSamplesRenderer(): %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } + nSamplesRendered += nSamplesRendered_loop; nSamplesToRender -= nSamplesRendered_loop; } + if ( needNewFrame ) { frame++; @@ -2601,7 +2722,11 @@ static ivas_error decodeG192( /* Once good frame decoded, catch up */ if ( decodedGoodFrame ) { +#ifdef IVAS_RTPDUMP + if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, &nOutSamples, &vec_pos_len, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj, NULL, &splitRendWriter ) ) != IVAS_ERR_OK ) +#else if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, &nOutSamples, &vec_pos_len, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj, &splitRendWriter ) ) != IVAS_ERR_OK ) +#endif { goto cleanup; } @@ -2642,7 +2767,6 @@ static ivas_error decodeG192( } } - /* Write ISm metadata to external file(s) */ if ( decodedGoodFrame && arg.outputConfig == IVAS_AUDIO_CONFIG_EXTERNAL ) { @@ -2683,7 +2807,6 @@ static ivas_error decodeG192( { fprintf( stderr, "\nUnable to get delay of decoder: %s\n", ivas_error_to_string( error ) ); } - if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta, 0 ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); @@ -2704,9 +2827,6 @@ static ivas_error decodeG192( { update_wmops(); update_mem(); -#ifdef MEM_COUNT_DETAILS - export_mem( "mem_analysis.csv" ); -#endif } #endif } @@ -2830,6 +2950,7 @@ static ivas_error decodeG192( fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } + delayMs = (float) ( fullDelayNumSamples[0] ) / (float) ( delayTimeScale ); if ( ( error = MasaFileWriter_writeFrame( masaWriter, hMasaExtOutMeta, &delayMs ) ) != IVAS_ERR_OK ) { @@ -2890,6 +3011,7 @@ static ivas_error decodeG192( *------------------------------------------------------------------------------------------*/ memset( pcmBuf, 0, delayNumSamples_orig[0] * nOutChannels * sizeof( int16_t ) ); + if ( afWriter != NULL ) { if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK ) @@ -2943,24 +3065,44 @@ static ivas_error printBitstreamInfoVoip( { bool previewFailed = true; ivas_error error = IVAS_ERR_OK; +#ifdef IVAS_RTPDUMP + IVAS_RTP ivasRtp; + uint8_t au[( IVAS_MAX_BITS_PER_FRAME + 7 ) >> 3]; + int16_t auSizeBits; + uint8_t *auPtr = NULL; +#else FILE *f_rtpstream = NULL; EVS_RTPDUMP_DEPACKER rtpdumpDepacker; EVS_RTPDUMP_DEPACKER_ERROR rtpdumpDepackerError = EVS_RTPDUMP_DEPACKER_NO_ERROR; + bool isAMRWB_IOmode; + uint16_t frameTypeIndex; uint8_t au[( IVAS_MAX_BITS_PER_FRAME + 7 ) >> 3]; int16_t auSizeBits; uint8_t *auPtr = NULL; - bool isAMRWB_IOmode; - uint16_t frameTypeIndex; +#endif bool qBit; uint32_t nextPacketRcvTime_ms = 0; uint16_t rtpSequenceNumber; uint32_t rtpTimeStamp; +#ifndef IVAS_RTPDUMP rtpdumpDepacker.rtpdump = NULL; +#endif switch ( arg.inputFormat ) { case IVAS_DEC_INPUT_FORMAT_RTPDUMP: case IVAS_DEC_INPUT_FORMAT_RTPDUMP_HF: +#ifdef IVAS_RTPDUMP +#ifdef RTP_S4_251135_CR26253_0016_REV1 + if ( ( error = IVAS_RTP_READER_Init( &ivasRtp, 0, arg.inputBitstreamFilename, arg.piOutputFilename, arg.outputConfig == IVAS_AUDIO_CONFIG_EXTERNAL, arg.outputWavFilename ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_RTP_READER_Init( &ivasRtp, arg.inputBitstreamFilename, arg.piOutputFilename, arg.outputConfig == IVAS_AUDIO_CONFIG_EXTERNAL, arg.outputWavFilename ) ) != IVAS_ERR_OK ) +#endif + { + fprintf( stderr, "error in IVAS_RTP_READER_Init(): %d\n", error ); + goto cleanup; + } +#else f_rtpstream = fopen( arg.inputBitstreamFilename, "r" ); if ( f_rtpstream == NULL ) @@ -2975,6 +3117,7 @@ static ivas_error printBitstreamInfoVoip( fprintf( stderr, "error in EVS_RTPDUMP_DEPACKER_open(): %d\n", rtpdumpDepackerError ); goto cleanup; } +#endif break; case IVAS_DEC_INPUT_FORMAT_G192: auPtr = au; @@ -2995,12 +3138,24 @@ static ivas_error printBitstreamInfoVoip( else { auPtr = au; /* might have been set to RTP packet in prev call */ +#ifdef IVAS_RTPDUMP +#ifdef RTP_S4_251135_CR26253_0016_REV1 + error = IVAS_RTP_ReadNextFrame( &ivasRtp, auPtr, &auSizeBits, &rtpTimeStamp, &rtpSequenceNumber, &nextPacketRcvTime_ms, NULL, &qBit ); +#else + error = IVAS_RTP_ReadNextFrame( &ivasRtp, auPtr, &auSizeBits, &rtpTimeStamp, &rtpSequenceNumber, &nextPacketRcvTime_ms, &qBit ); +#endif +#else rtpdumpDepackerError = EVS_RTPDUMP_DEPACKER_readNextFrame( &rtpdumpDepacker, &rtpSequenceNumber, &rtpTimeStamp, &nextPacketRcvTime_ms, &isAMRWB_IOmode, &frameTypeIndex, &qBit, &auPtr, (uint16_t *) &auSizeBits ); +#endif /* EVS RTP payload format has timescale 16000, JBM uses 1000 internally */ rtpTimeStamp = rtpTimeStamp / 16; } +#ifdef IVAS_RTPDUMP + if ( error != IVAS_ERR_OK ) +#else if ( error != IVAS_ERR_OK || rtpdumpDepackerError != EVS_RTPDUMP_DEPACKER_NO_ERROR ) +#endif { fprintf( stderr, "failed to read first RTP packet\n" ); goto cleanup; @@ -3019,7 +3174,11 @@ static ivas_error printBitstreamInfoVoip( cleanup: +#ifdef IVAS_RTPDUMP + IVAS_RTP_Term( &ivasRtp ); +#else EVS_RTPDUMP_DEPACKER_close( &rtpdumpDepacker ); +#endif if ( previewFailed && error == IVAS_ERR_OK ) { @@ -3088,12 +3247,21 @@ static ivas_error decodeVoIP( int16_t delayNumSamples = -1; int32_t delayTimeScale = -1; int16_t i; +#ifdef IVAS_RTPDUMP + IVAS_RTP ivasRtp = { 0 }; + IVAS_RTP srRtp = { 0 }; + IVAS_RTP_SR_INFO srInfo = { true, false, 0, IVAS_SR_TRANSPORT_LCLD }; + int32_t initialTsOffsetSystemAndRTP = 0; +#else FILE *f_rtpstream = NULL; EVS_RTPDUMP_DEPACKER rtpdumpDepacker; EVS_RTPDUMP_DEPACKER_ERROR rtpdumpDepackerError = EVS_RTPDUMP_DEPACKER_NO_ERROR; +#endif uint8_t *auPtr = NULL; +#ifndef IVAS_RTPDUMP bool isAMRWB_IOmode; uint16_t frameTypeIndex; +#endif bool qBit; IVAS_DEC_BS_FORMAT bsFormat = IVAS_DEC_BS_UNKOWN; @@ -3101,9 +3269,11 @@ static ivas_error decodeVoIP( IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES] = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; int16_t vec_pos_update, vec_pos_len; int16_t nOutSamples = 0; + bool bitstreamReadDone = false; + bool parametersAvailableForEditing = false; - uint16_t nSamplesRendered; + uint16_t nSamplesRendered = 0; #ifdef FIX_1119_SPLIT_RENDERING_VOIP SplitFileReadWrite *splitRendWriter = NULL; @@ -3152,11 +3322,24 @@ static ivas_error decodeVoIP( delayNumSamples_orig[0] = -1; +#ifndef IVAS_RTPDUMP rtpdumpDepacker.rtpdump = NULL; +#endif switch ( arg.inputFormat ) { case IVAS_DEC_INPUT_FORMAT_RTPDUMP: case IVAS_DEC_INPUT_FORMAT_RTPDUMP_HF: +#ifdef IVAS_RTPDUMP +#ifdef RTP_S4_251135_CR26253_0016_REV1 + if ( ( error = IVAS_RTP_READER_Init( &ivasRtp, 0, arg.inputBitstreamFilename, arg.piOutputFilename, arg.outputConfig == IVAS_AUDIO_CONFIG_EXTERNAL, arg.outputWavFilename ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_RTP_READER_Init( &ivasRtp, arg.inputBitstreamFilename, arg.piOutputFilename, arg.outputConfig == IVAS_AUDIO_CONFIG_EXTERNAL, arg.outputWavFilename ) ) != IVAS_ERR_OK ) +#endif + { + fprintf( stderr, "error in IVAS_RTP_READER_Init(): %d\n", error ); + goto cleanup; + } +#else f_rtpstream = fopen( arg.inputBitstreamFilename, "r" ); if ( f_rtpstream == NULL ) @@ -3171,6 +3354,7 @@ static ivas_error decodeVoIP( fprintf( stderr, "error in EVS_RTPDUMP_DEPACKER_open(): %d\n", rtpdumpDepackerError ); goto cleanup; } +#endif break; case IVAS_DEC_INPUT_FORMAT_G192: auPtr = au; @@ -3212,12 +3396,25 @@ static ivas_error decodeVoIP( else { auPtr = au; /* might have been set to RTP packet in prev call */ +#ifdef IVAS_RTPDUMP +#ifdef RTP_S4_251135_CR26253_0016_REV1 + error = IVAS_RTP_ReadNextFrame( &ivasRtp, auPtr, &auSize, &rtpTimeStamp, &rtpSequenceNumber, &nextPacketRcvTime_ms, NULL, &qBit ); +#else + error = IVAS_RTP_ReadNextFrame( &ivasRtp, auPtr, &auSize, &rtpTimeStamp, &rtpSequenceNumber, &nextPacketRcvTime_ms, &qBit ); +#endif + initialTsOffsetSystemAndRTP = rtpTimeStamp - systemTime_ms * 16; /* For time mapping */ +#else rtpdumpDepackerError = EVS_RTPDUMP_DEPACKER_readNextFrame( &rtpdumpDepacker, &rtpSequenceNumber, &rtpTimeStamp, &nextPacketRcvTime_ms, &isAMRWB_IOmode, &frameTypeIndex, &qBit, &auPtr, (uint16_t *) &auSize ); +#endif /* EVS RTP payload format has timescale 16000, JBM uses 1000 internally */ rtpTimeStamp = rtpTimeStamp / 16; } +#ifdef IVAS_RTPDUMP + if ( error != IVAS_ERR_OK ) +#else if ( error != IVAS_ERR_OK || rtpdumpDepackerError != EVS_RTPDUMP_DEPACKER_NO_ERROR ) +#endif { fprintf( stderr, "failed to read first RTP packet\n" ); goto cleanup; @@ -3320,8 +3517,7 @@ static ivas_error decodeVoIP( for ( i = 0; i < num_subframes; i++ ) { - if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i, - DEFAULT_AXIS ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i, DEFAULT_AXIS ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -3388,19 +3584,38 @@ static ivas_error decodeVoIP( else { auPtr = au; /* might have been set to RTP packet in prev call */ +#ifdef IVAS_RTPDUMP +#ifdef RTP_S4_251135_CR26253_0016_REV1 + error = IVAS_RTP_ReadNextFrame( &ivasRtp, au, &auSize, &rtpTimeStamp, &rtpSequenceNumber, &nextPacketRcvTime_ms, NULL, &qBit ); +#else + error = IVAS_RTP_ReadNextFrame( &ivasRtp, au, &auSize, &rtpTimeStamp, &rtpSequenceNumber, &nextPacketRcvTime_ms, &qBit ); +#endif + + /* IVAS RTP payload format has timescale 16000, JBM uses 1000 internally */ + rtpTimeStamp = rtpTimeStamp / 16; +#else rtpdumpDepackerError = EVS_RTPDUMP_DEPACKER_readNextFrame( &rtpdumpDepacker, &rtpSequenceNumber, &rtpTimeStamp, &nextPacketRcvTime_ms, &isAMRWB_IOmode, &frameTypeIndex, &qBit, &auPtr, (uint16_t *) &auSize ); /* EVS RTP payload format has timescale 16000, JBM uses 1000 internally */ rtpTimeStamp = rtpTimeStamp / 16; +#endif } +#ifdef IVAS_RTPDUMP + if ( error == IVAS_ERR_END_OF_FILE ) +#else if ( error == IVAS_ERR_END_OF_FILE || rtpdumpDepackerError == EVS_RTPDUMP_DEPACKER_EOF ) +#endif { /* finished reading */ nextPacketRcvTime_ms = (uint32_t) -1; } +#ifdef IVAS_RTPDUMP + else if ( error != IVAS_ERR_OK ) +#else else if ( error != IVAS_ERR_OK || rtpdumpDepackerError != EVS_RTPDUMP_DEPACKER_NO_ERROR ) +#endif { fprintf( stderr, "\nError in BS_Reader_ReadVoipFrame_compact, error code: %d\n", error ); goto cleanup; @@ -3419,6 +3634,28 @@ static ivas_error decodeVoIP( /* decode and get samples */ while ( nSamplesRendered < nOutSamples ) { +#ifdef IVAS_RTPDUMP + if ( arg.applyPiData ) + { + /* Rudimentry Time Mapping to map system time to rtp timestamp */ + uint32_t piTs = systemTime_ms * 16 + initialTsOffsetSystemAndRTP; + uint32_t numPiData = 0; + + while ( ivasRtp.nProcPiData + numPiData < ivasRtp.nReadPiData && + ivasRtp.piData[ivasRtp.nProcPiData + numPiData].timestamp <= piTs ) + { + numPiData++; + } + + if ( ( error = IVAS_RTP_FeedPiDataToDecoder( hIvasDec, &ivasRtp.piData[ivasRtp.nProcPiData], numPiData ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_VoIP_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + ivasRtp.nProcPiData += numPiData; + } +#endif #ifdef FIX_1119_SPLIT_RENDERING_VOIP if ( isSplitRend ) { @@ -3438,7 +3675,7 @@ static ivas_error decodeVoIP( #ifdef SUPPORT_JBM_TRACEFILE if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, writeJbmTraceFileFrameWrapper, jbmTraceWriter, &bitstreamReadDone, &nSamplesRendered, ¶metersAvailableForEditing, systemTime_ms ) ) != IVAS_ERR_OK ) #else - if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, &bitstreamReadDone, ¶metersAvailableForEditing, systemTime_ms ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, &bitstreamReadDone, &nSamplesRendered, ¶meterAvailableForEditing, systemTime_ms ) ) != IVAS_ERR_OK ) #endif { fprintf( stderr, "\nError in IVAS_DEC_VoIP_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); @@ -3535,7 +3772,11 @@ static ivas_error decodeVoIP( #else if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, &nOutSamples, NULL, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, #endif +#ifdef IVAS_RTPDUMP + &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj, &srRtp, &splitRendWriter ) ) != IVAS_ERR_OK ) +#else &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj, &splitRendWriter ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "Error in initOnFirstGoodFrame(): %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -3548,7 +3789,11 @@ static ivas_error decodeVoIP( } /* Write current frame */ +#ifdef IVAS_RTPDUMP + if ( !srRtp.hPack && decodedGoodFrame ) +#else if ( decodedGoodFrame ) +#endif { #ifdef FIX_1119_SPLIT_RENDERING_VOIP if ( isSplitRend ) @@ -3625,6 +3870,7 @@ static ivas_error decodeVoIP( fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } + delayMs = (float) ( fullDelayNumSamples[0] ) / (float) ( delayTimeScale ); if ( ( error = MasaFileWriter_writeFrame( masaWriter, hMasaExtOutMeta, &delayMs ) ) != IVAS_ERR_OK ) { @@ -3632,8 +3878,25 @@ static ivas_error decodeVoIP( goto cleanup; } } + + IVAS_RTP_WriteExtPiData( ivasRtp.f_piExtOut, ivasRtp.piData, ivasRtp.nReadPiData, numObj ); + } + } +#ifdef IVAS_RTPDUMP + else if ( decodedGoodFrame ) + { + srInfo.bitrateKbps = splitRendBits->bits_written * 1000 / splitRendBits->codec_frame_size_ms; + srInfo.codec = ( splitRendBits->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) ? IVAS_SR_TRANSPORT_LC3PLUS : IVAS_SR_TRANSPORT_LCLD; + if ( ( error = IVAS_RTP_WriteNextFrame( &srRtp, splitRendBits->bits_buf, &srInfo, (int16_t) splitRendBits->bits_written, false, false ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while pushing SR audio bitstream to RTP pack\n", ivas_error_to_string( error ) ); + goto cleanup; } + splitRendBits->bits_written = 0; + splitRendBits->bits_read = 0; } +#endif + vec_pos_update = ( vec_pos_update + 1 ) % vec_pos_len; if ( vec_pos_update == 0 ) @@ -3732,10 +3995,11 @@ static ivas_error decodeVoIP( goto cleanup; } } + + IVAS_RTP_WriteExtPiData( ivasRtp.f_piExtOut, ivasRtp.piData, ivasRtp.nReadPiData, numObj ); } } - /*------------------------------------------------------------------------------------------* * Add zeros at the end to have equal length of synthesized signals *------------------------------------------------------------------------------------------*/ @@ -3786,6 +4050,8 @@ static ivas_error decodeVoIP( { fprintf( stdout, "\nOutput MASA metadata file: %s\n", MasaFileWriter_getFilePath( masaWriter ) ); } + + fprintf( stdout, "\nOutput PI data file: %s\n", IVAS_RTP_GetExtPiFilePath( &ivasRtp ) ); } /*------------------------------------------------------------------------------------------* @@ -3796,7 +4062,12 @@ static ivas_error decodeVoIP( cleanup: +#ifdef IVAS_RTPDUMP + IVAS_RTP_Term( &srRtp ); + IVAS_RTP_Term( &ivasRtp ); +#else EVS_RTPDUMP_DEPACKER_close( &rtpdumpDepacker ); +#endif AudioFileWriter_close( &afWriter ); #ifdef FIX_1119_SPLIT_RENDERING_VOIP split_rend_reader_writer_close( &splitRendWriter ); @@ -3927,7 +4198,6 @@ static void do_object_editing( editableParameters->gain_bed = 0.5f; } - return; } diff --git a/apps/encoder.c b/apps/encoder.c index 7e5154226196f061b43140f49c7e86cca921f58d..162ac9a19dfd4e83a2fbbd46d30e81ca78a7f45e 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -38,23 +38,20 @@ #include "ism_file_reader.h" #include "jbm_file_reader.h" #include "masa_file_reader.h" +#ifdef IVAS_RTPDUMP +#include "rotation_file_reader.h" +#include "ivas_rtp_file.h" +#endif #ifdef DEBUGGING #include "debug.h" #endif #include "wmc_auto.h" - -#ifdef DEBUG_FORCE_DIR -/* Windows does not define the S_ISREG and S_ISDIR macros in stat.h, so we do. - We have to define _CRT_INTERNAL_NONSTDC_NAMES 1 before #including sys/stat.h - in order for Microsoft's stat.h to define names like S_IFMT, S_IFREG, and S_IFDIR, - rather than just defining _S_IFMT, _S_IFREG, and _S_IFDIR as it normally does. */ -#include -#if !defined( S_ISREG ) && defined( S_IFMT ) && defined( S_IFREG ) -#define S_ISREG( m ) ( ( (m) &S_IFMT ) == S_IFREG ) -#endif -#if !defined( S_ISDIR ) && defined( S_IFMT ) && defined( S_IFDIR ) -#define S_ISDIR( m ) ( ( (m) &S_IFMT ) == S_IFDIR ) +#ifdef FLP_EXCEPTION_TRAP +#include "flp_debug.h" #endif + +#ifdef FIXED_RTP_SEQUENCE_NUM +#define RANDOM_INITSEED_ENC ( 0xFEEDDEAF ) #endif #define WMC_TOOL_SKIP @@ -147,9 +144,6 @@ typedef struct #ifdef DEBUGGING IVAS_ENC_FORCED_MODE forcedMode; const char *forcedModeFile; -#ifdef DEBUG_FORCE_DIR - const char *forcedModeDir; -#endif #ifdef DEBUG_AGC_ENCODER_CMD_OPTION IVAS_ENC_AGC agc; #endif @@ -162,6 +156,12 @@ typedef struct #endif bool pca; bool ism_extended_metadata; +#ifdef IVAS_RTPDUMP + bool rtpdumpOutput; + uint32_t numFramesPerPacket; + char *sceneOrientationTrajFileName; + char *deviceOrientationTrajFileName; +#endif } EncArguments; @@ -205,6 +205,10 @@ int main( MasaFileReader *masaReader = NULL; IsmFileReader *ismReaders[IVAS_MAX_NUM_OBJECTS] = { NULL, NULL, NULL, NULL }; int16_t *pcmBuf = NULL; +#ifdef IVAS_RTPDUMP + RotFileReader *sceneOrientationFileReader = NULL; + RotFileReader *deviceOrientationFileReader = NULL; +#endif #ifdef DEBUGGING FILE *f_forcedModeProfile = NULL; #ifdef DEBUG_SBA @@ -221,6 +225,23 @@ int main( reset_wmops(); reset_mem( USE_BYTES ); #endif +#ifdef FLP_EXCEPTION_TRAP + enable_float_exception_trap( FLE_MASK_DENORM | FLE_MASK_UNDERFLOW ); +#endif + +#ifdef IVAS_RTPDUMP + uint8_t au[IVAS_MAX_BITS_PER_FRAME / 8]; + IVAS_RTP ivasRtp = { 0 }; +#endif + +#ifdef FIXED_RTP_SEQUENCE_NUM + /* Ideally ssrc is negotiated via SDP and sequence number is radomized but we + use fixed seed for random num generator for regression based tests. Any realtime + application should implement this initialization seperately */ + srand( RANDOM_INITSEED_ENC ); + uint32_t ssrc = ( (uint32_t) rand() & 0x0000FFFF ) | ( (uint32_t) rand() << 16 ); + uint16_t seqNumInitVal = (uint16_t) ( rand() & 0xFFFF ); +#endif /*------------------------------------------------------------------------------------------* * Parse command-line arguments @@ -250,7 +271,11 @@ int main( const BS_WRITER_FORMAT bsWriterFormat = arg.mimeOutput ? BS_WRITER_FORMAT_MIME : BS_WRITER_FORMAT_G192; +#ifdef IVAS_RTPDUMP + if ( !arg.rtpdumpOutput && BS_Writer_Open_filename( &hBsWriter, arg.outputBitstreamFilename, bsWriterFormat ) != IVAS_ERR_OK ) +#else if ( BS_Writer_Open_filename( &hBsWriter, arg.outputBitstreamFilename, bsWriterFormat ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nCan't open %s\n\n", arg.outputBitstreamFilename ); goto cleanup; @@ -383,13 +408,6 @@ int main( goto cleanup; } -#ifdef DEBUGGING - if ( arg.forcedMode == IVAS_ENC_FORCE_TCX10 && totalBitrate < 48000 ) - { - fprintf( stderr, "Warning: Enforcing the TCX10 mode is only supported for bitrates higher or equal than 48 kbps!\n\n" ); - } -#endif - /*------------------------------------------------------------------------------------------* * Configure and initialize (allocate memory for static variables) the encoder *------------------------------------------------------------------------------------------*/ @@ -615,6 +633,51 @@ int main( } } +#ifdef IVAS_RTPDUMP + /*------------------------------------------------------------------------------------------* + * RTPDump + *------------------------------------------------------------------------------------------*/ + + if ( arg.rtpdumpOutput ) + { +#ifdef FIXED_RTP_SEQUENCE_NUM + if ( ( error = IVAS_RTP_WRITER_Init( &ivasRtp, arg.outputBitstreamFilename, arg.numFramesPerPacket, ssrc, seqNumInitVal ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_RTP_WRITER_Init( &ivasRtp, arg.outputBitstreamFilename, arg.numFramesPerPacket ) ) != IVAS_ERR_OK ) +#endif + { + fprintf( stderr, "\nError: Can't open output bitstream file for RTP output %s \n\n", arg.outputBitstreamFilename ); + goto cleanup; + } + } + + /*------------------------------------------------------------------------------------------* + * Open scene orientation file + *------------------------------------------------------------------------------------------*/ + + if ( arg.sceneOrientationTrajFileName != NULL ) + { + if ( ( error = RotationFileReader_open( arg.sceneOrientationTrajFileName, &sceneOrientationFileReader ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: Can't open scene orientation file %s \n\n", arg.sceneOrientationTrajFileName ); + goto cleanup; + } + } + + /*------------------------------------------------------------------------------------------* + * Open device orientation file + *------------------------------------------------------------------------------------------*/ + + if ( arg.deviceOrientationTrajFileName != NULL ) + { + if ( ( error = RotationFileReader_open( arg.deviceOrientationTrajFileName, &deviceOrientationFileReader ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: Can't open device orientation file %s \n\n", arg.deviceOrientationTrajFileName ); + goto cleanup; + } + } +#endif + int16_t numSamplesRead = 0; uint16_t bitStream[IVAS_MAX_BITS_PER_FRAME]; uint16_t numBits = 0; @@ -732,12 +795,7 @@ int main( /* Force mode not set when configuring, set in first frame even if not reading from file */ if ( f_forcedModeProfile || frame == 0 ) { - if ( ( error = IVAS_ENC_SetForcedMode( hIvasEnc, forcedMode -#ifdef DEBUG_FORCE_DIR - , - arg.forcedModeDir -#endif - ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_ENC_SetForcedMode( hIvasEnc, forcedMode ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_ENC_SetForcedMode failed: %s\n\n", IVAS_ENC_GetErrorMessage( error ) ); goto cleanup; @@ -784,18 +842,82 @@ int main( } /* *** Encode one frame *** */ - if ( ( error = IVAS_ENC_EncodeFrameToSerial( hIvasEnc, pcmBuf, pcmBufSize, bitStream, &numBits ) ) != IVAS_ERR_OK ) +#ifdef IVAS_RTPDUMP + if ( ivasRtp.hPack ) { - fprintf( stderr, "\nencodeFrame failed: %s\n\n", IVAS_ENC_GetErrorMessage( error ) ); - goto cleanup; - } + bool isMono = ( arg.inputFormat == IVAS_ENC_INPUT_MONO ); + bool forcePacket = ( numSamplesRead < pcmBufSize ); /* If EoF force Packet generation */ + + ivasRtp.nWrittenPiData = 0; + + /* scene orientation */ + if ( sceneOrientationFileReader ) + { + PIDATA_TS *piDataTs = &ivasRtp.piData[ivasRtp.nWrittenPiData++]; + IVAS_PIDATA_ORIENTATION *scene = &piDataTs->data.scene; - /* write bitstream */ - if ( ( error = BS_Writer_WriteFrame_short( hBsWriter, bitStream, numBits, totalBitrate ) ) != IVAS_ERR_OK ) + memset( piDataTs, 0, sizeof( PIDATA_TS ) ); + scene->size = sizeof( IVAS_PIDATA_ORIENTATION ); + scene->piDataType = IVAS_PI_SCENE_ORIENTATION; + + if ( ( error = HeadRotationFileReading( sceneOrientationFileReader, &scene->orientation, NULL ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while reading scene orientation from %s\n", IVAS_ENC_GetErrorMessage( error ), RotationFileReader_getFilePath( sceneOrientationFileReader ) ); + goto cleanup; + } + } + + /* device orientation */ + if ( deviceOrientationFileReader ) + { + PIDATA_TS *piDataTs = &ivasRtp.piData[ivasRtp.nWrittenPiData++]; + IVAS_PIDATA_ORIENTATION *device = &piDataTs->data.deviceUnCompensated; + + memset( piDataTs, 0, sizeof( PIDATA_TS ) ); + device->size = sizeof( IVAS_PIDATA_ORIENTATION ); + device->piDataType = IVAS_PI_DEVICE_ORIENTATION_COMPENSATED; + + if ( ( error = HeadRotationFileReading( deviceOrientationFileReader, &device->orientation, NULL ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while reading device orientation from %s\n", IVAS_ENC_GetErrorMessage( error ), RotationFileReader_getFilePath( deviceOrientationFileReader ) ); + goto cleanup; + } + } + + if ( ( error = IVAS_ENC_EncodeFrameToCompact( hIvasEnc, pcmBuf, pcmBufSize, au, &numBits ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nencodeFrame failed: %s\n\n", IVAS_ENC_GetErrorMessage( error ) ); + goto cleanup; + } + +#ifdef RTP_S4_251135_CR26253_0016_REV1 + if ( ( error = IVAS_RTP_WriteNextFrame( &ivasRtp, au, NULL, numBits, isMono, forcePacket ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_RTP_WriteNextFrame( &ivasRtp, au, numBits, isMono, forcePacket ) ) != IVAS_ERR_OK ) +#endif + { + fprintf( stderr, "\nError %s while pushing audio frame to RTP pack\n", IVAS_ENC_GetErrorMessage( error ) ); + goto cleanup; + } + } + else { - fprintf( stderr, "\nBS_Writer_WriteFrame_short failed, error code %d\n\n", error ); - goto cleanup; +#endif + if ( ( error = IVAS_ENC_EncodeFrameToSerial( hIvasEnc, pcmBuf, pcmBufSize, bitStream, &numBits ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nencodeFrame failed: %s\n\n", IVAS_ENC_GetErrorMessage( error ) ); + goto cleanup; + } + + /* write bitstream */ + if ( ( error = BS_Writer_WriteFrame_short( hBsWriter, bitStream, numBits, totalBitrate ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nBS_Writer_WriteFrame_short failed, error code %d\n\n", error ); + goto cleanup; + } +#ifdef IVAS_RTPDUMP } +#endif frame++; if ( !arg.quietModeEnabled ) @@ -873,6 +995,20 @@ cleanup: fclose( f_bitrateProfile ); } +#ifdef IVAS_RTPDUMP + if ( sceneOrientationFileReader ) + { + RotationFileReader_close( &sceneOrientationFileReader ); + } + + if ( deviceOrientationFileReader ) + { + RotationFileReader_close( &deviceOrientationFileReader ); + } + + IVAS_RTP_Term( &ivasRtp ); +#endif + IVAS_ENC_Close( &hIvasEnc ); #ifdef WMOPS @@ -943,6 +1079,11 @@ static bool parseCmdlIVAS_enc( arg->mimeOutput = false; arg->ism_extended_metadata = false; arg->complexityLevel = IVAS_ENC_COMPLEXITY_LEVEL_THREE; +#ifdef IVAS_RTPDUMP + arg->rtpdumpOutput = false; + arg->sceneOrientationTrajFileName = NULL; + arg->deviceOrientationTrajFileName = NULL; +#endif #ifdef DEBUGGING arg->forcedMode = IVAS_ENC_FORCE_UNFORCED; @@ -1081,28 +1222,6 @@ static bool parseCmdlIVAS_enc( arg->forcedMode = parseForcedMode( stmp ); -#ifdef DEBUG_FORCE_DIR - if ( arg->forcedMode < IVAS_ENC_FORCE_FILE ) - { - fprintf( stdout, "Forcing codec to: %s\n", argv[i + 1] ); - } - else if ( arg->forcedMode == IVAS_ENC_FORCE_FILE ) - { - arg->forcedModeFile = argv[i + 1]; - fprintf( stdout, "Force switching file: %s\n", argv[i + 1] ); - } - else if ( arg->forcedMode == IVAS_ENC_FORCE_DIR ) - { - arg->forcedModeDir = argv[i + 1]; - fprintf( stdout, "Forcing switching directory: %s\n", argv[i + 1] ); - } - else - { - fprintf( stderr, "\nError: The force switching profile file/dir %s does not exist or could not be opened!\n\n", argv[i + 1] ); - usage_enc(); - return false; - } -#else if ( arg->forcedMode == IVAS_ENC_FORCE_UNDEFINED ) { arg->forcedModeFile = argv[i + 1]; @@ -1110,22 +1229,8 @@ static bool parseCmdlIVAS_enc( } else { - if ( arg->forcedMode == IVAS_ENC_FORCE_TCX10 ) - { - strcpy( stmp, "TCX10" ); - } - else if ( arg->forcedMode == IVAS_ENC_FORCE_TCX20 ) - { - strcpy( stmp, "TCX20" ); - } - else - { - strncpy( stmp, argv[i + 1], sizeof( stmp ) ); - } - - fprintf( stdout, "Forcing codec to: %s\n", stmp ); + fprintf( stdout, "Forcing codec to: %s\n", argv[i + 1] ); } -#endif i += 2; } @@ -1773,6 +1878,71 @@ static bool parseCmdlIVAS_enc( i++; } +#ifdef IVAS_RTPDUMP + /*-----------------------------------------------------------------* + * RTPDump output + *-----------------------------------------------------------------*/ + + else if ( strcmp( argv_to_upper, "-RTPDUMP" ) == 0 ) + { + i++; + arg->rtpdumpOutput = true; + if ( i < argc - 4 ) + { + if ( !is_digits_only( argv[i] ) ) + { + arg->numFramesPerPacket = 1; /* Default to 1 frame per packet */ + } + else + { + arg->numFramesPerPacket = atoi( argv[i++] ); + if ( arg->numFramesPerPacket > IVAS_MAX_FRAMES_PER_RTP_PACKET ) + { + fprintf( stderr, "numFramesPerPacket(%d) exceeds max frames per packet (%d) \n", arg->numFramesPerPacket, IVAS_MAX_FRAMES_PER_RTP_PACKET ); + arg->numFramesPerPacket = 1; + } + } + } + fprintf( stdout, "Output format: RTPDump using %d frames/packet \n", arg->numFramesPerPacket ); + } + + /*-----------------------------------------------------------------* + * Scene orientation + *-----------------------------------------------------------------*/ + + else if ( strcmp( argv_to_upper, "-SCENE_ORIENTATION" ) == 0 ) + { + i++; + if ( argc - i <= 4 || argv[i][0] == '-' ) + { + fprintf( stderr, "Error: Scene orientation file name not specified!\n\n" ); + usage_enc(); + return false; + } + + arg->sceneOrientationTrajFileName = argv[i]; + i++; + } + + /*-----------------------------------------------------------------* + * Device orientation + *-----------------------------------------------------------------*/ + + else if ( strcmp( argv_to_upper, "-DEVICE_ORIENTATION" ) == 0 ) + { + i++; + if ( argc - i <= 4 || argv[i][0] == '-' ) + { + fprintf( stderr, "Error: Device orientation file name not specified!\n\n" ); + usage_enc(); + return false; + } + + arg->deviceOrientationTrajFileName = argv[i]; + i++; + } + +#endif /*-----------------------------------------------------------------* * Option not recognized *-----------------------------------------------------------------*/ @@ -1784,6 +1954,21 @@ static bool parseCmdlIVAS_enc( } } /* end of while */ +#ifdef IVAS_RTPDUMP + if ( arg->sceneOrientationTrajFileName != NULL && arg->rtpdumpOutput == false ) + { + fprintf( stderr, "Error: Scene orientations are only enabled with rtpdump output!\n\n" ); + usage_enc(); + return false; + } + if ( arg->deviceOrientationTrajFileName != NULL && arg->rtpdumpOutput == false ) + { + fprintf( stderr, "Error: Device orientations are only enabled with rtpdump output!\n\n" ); + usage_enc(); + return false; + } + +#endif /*-----------------------------------------------------------------* * Mandatory input arguments *-----------------------------------------------------------------*/ @@ -1974,9 +2159,6 @@ static void usage_enc( void ) #ifdef DEBUGGING fprintf( stdout, "-force T : Force specific mode, T = (speech, music, ACELP, GSC, TCX, HQ),\n" ); fprintf( stdout, " alternatively, T can be a text file where each line contains \"nb_frames T\"\n" ); -#ifdef DEBUG_FORCE_DIR - fprintf( stdout, " or T can be a directory containing external binary files for modes/parameters enforcement\n" ); -#endif #ifdef DEBUG_SBA fprintf( stdout, "-tag : Tag name for intermediate debug files\n" ); #endif @@ -1993,6 +2175,14 @@ static void usage_enc( void ) #endif fprintf( stdout, "-q : Quiet mode, no frame counters\n" ); fprintf( stdout, " default is deactivated\n" ); +#ifdef IVAS_RTPDUMP + fprintf( stdout, "-rtpdump : RTPDump output, hf_only=1 by default. The encoder will packetize the \n" ); + fprintf( stdout, " bitstream frames into TS26.253 Annex A IVAS RTP Payload Format packets and \n" ); + fprintf( stdout, " writes those to the output file. In EVS mono operating mode, TS26.445 Annex A.2.2 \n" ); + fprintf( stdout, " EVS RTP Payload Format is used. Optional N represents number of frames per RTP packet\n" ); + fprintf( stdout, "-scene_orientation : Scene orientation trajectory file. Only used with rtpdump output.\n" ); + fprintf( stdout, "-device_orientation : Device orientation trajectory file. Only used with rtpdump output.\n" ); +#endif fprintf( stdout, "\n" ); return; @@ -2094,63 +2284,8 @@ static bool readBitrate( static IVAS_ENC_FORCED_MODE parseForcedMode( char *forcedModeChar ) { -#ifdef DEBUG_FORCE_DIR - struct stat path_stat; -#endif - to_upper( forcedModeChar ); -#ifdef DEBUG_FORCE_DIR - if ( ( strcmp( forcedModeChar, "SPEECH" ) == 0 ) || ( strcmp( forcedModeChar, "'SPEECH'" ) == 0 ) || - ( strcmp( forcedModeChar, "0" ) == 0 ) ) - { - return IVAS_ENC_FORCE_SPEECH; - } - else if ( ( strcmp( forcedModeChar, "MUSIC" ) == 0 ) || ( strcmp( forcedModeChar, "'MUSIC'" ) == 0 ) || ( strcmp( forcedModeChar, "AUDIO" ) == 0 ) || ( strcmp( forcedModeChar, "'AUDIO'" ) == 0 ) || ( strcmp( forcedModeChar, "1" ) == 0 ) ) - { - return IVAS_ENC_FORCE_MUSIC; - } - else if ( ( strcmp( forcedModeChar, "ACELP" ) == 0 ) || ( strcmp( forcedModeChar, "'ACELP'" ) == 0 ) ) - { - return IVAS_ENC_FORCE_ACELP; - } - else if ( ( strcmp( forcedModeChar, "GSC" ) == 0 ) || ( strcmp( forcedModeChar, "'GSC'" ) == 0 ) ) - { - return IVAS_ENC_FORCE_GSC; - } - if ( ( strcmp( forcedModeChar, "TCX" ) == 0 ) || ( strcmp( forcedModeChar, "'TCX'" ) == 0 ) || ( strcmp( forcedModeChar, "TCX20" ) == 0 ) || ( strcmp( forcedModeChar, "'TCX20'" ) == 0 ) ) - { - return IVAS_ENC_FORCE_TCX20; - } - if ( ( strcmp( forcedModeChar, "TCX10" ) == 0 ) || ( strcmp( forcedModeChar, "'TCX10'" ) == 0 ) ) - { - return IVAS_ENC_FORCE_TCX10; - } - else if ( ( strcmp( forcedModeChar, "HQ" ) == 0 ) || ( strcmp( forcedModeChar, "'HQ'" ) == 0 ) ) - { - return IVAS_ENC_FORCE_HQ; - } - else - { - if ( stat( forcedModeChar, &path_stat ) != 0 ) - { - return IVAS_ENC_FORCE_UNDEFINED; - } - - /* check if the argument represents an existing file or directory */ - if ( S_ISDIR( path_stat.st_mode ) ) - { - /* it's a directory */ - return IVAS_ENC_FORCE_DIR; - } - else - { - /* it's a file */ - return IVAS_ENC_FORCE_FILE; - } - } - -#else if ( ( strcmp( forcedModeChar, "SPEECH" ) == 0 ) || ( strcmp( forcedModeChar, "'SPEECH'" ) == 0 ) || ( strcmp( forcedModeChar, "0" ) == 0 ) ) { @@ -2168,13 +2303,9 @@ static IVAS_ENC_FORCED_MODE parseForcedMode( { return IVAS_ENC_FORCE_GSC; } - if ( ( strcmp( forcedModeChar, "TCX" ) == 0 ) || ( strcmp( forcedModeChar, "'TCX'" ) == 0 ) || ( strcmp( forcedModeChar, "TCX20" ) == 0 ) || ( strcmp( forcedModeChar, "'TCX20'" ) == 0 ) ) + if ( ( strcmp( forcedModeChar, "TCX" ) == 0 ) || ( strcmp( forcedModeChar, "'TCX'" ) == 0 ) ) { - return IVAS_ENC_FORCE_TCX20; - } - if ( ( strcmp( forcedModeChar, "TCX10" ) == 0 ) || ( strcmp( forcedModeChar, "'TCX10'" ) == 0 ) ) - { - return IVAS_ENC_FORCE_TCX10; + return IVAS_ENC_FORCE_TCX; } if ( ( strcmp( forcedModeChar, "HQ" ) == 0 ) || ( strcmp( forcedModeChar, "'HQ'" ) == 0 ) ) { @@ -2182,7 +2313,6 @@ static IVAS_ENC_FORCED_MODE parseForcedMode( } return IVAS_ENC_FORCE_UNDEFINED; -#endif } diff --git a/apps/isar_post_rend.c b/apps/isar_post_rend.c index 3159548da417798d404345cf218d866fab139fa0..7d8fd0939fe88432bceb8c600130ad9ba0794c52 100644 --- a/apps/isar_post_rend.c +++ b/apps/isar_post_rend.c @@ -48,6 +48,9 @@ #include "debug.h" #endif #include "wmc_auto.h" +#ifdef RTP_S4_251135_CR26253_0016_REV1 +#include "ivas_rtp_file.h" +#endif #define WMC_TOOL_SKIP @@ -78,6 +81,9 @@ static typedef struct { +#ifdef RTP_S4_251135_CR26253_0016_REV1 + bool srRtp; +#endif IVAS_AUDIO_CONFIG audioConfig; int32_t inputChannelIndex; float gain_dB; @@ -99,6 +105,9 @@ typedef struct char executableName[POST_REND_MAX_CLI_ARG_LENGTH]; char inputFilePath[POST_REND_MAX_CLI_ARG_LENGTH]; char outputFilePath[POST_REND_MAX_CLI_ARG_LENGTH]; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + char srParamsFilePath[POST_REND_MAX_CLI_ARG_LENGTH]; +#endif int32_t sampleRate; InputConfig inConfig; OutputConfig outConfig; @@ -128,6 +137,9 @@ typedef enum CmdLnOptionId_listFormats, CmdLnOptionId_SplitRendBFIFile, CmdLnOptionId_framing, +#ifdef RTP_S4_251135_CR26253_0016_REV1 + CmdLnOptionId_srParamsFile, +#endif } CmdLnOptionId; static const CmdLnParser_Option cliOptions[] = { @@ -203,6 +215,14 @@ static const CmdLnParser_Option cliOptions[] = { .matchShort = "fr", .description = "Set Render audio framing.", }, +#ifdef RTP_S4_251135_CR26253_0016_REV1 + { + .id = CmdLnOptionId_srParamsFile, + .match = "sr_params", + .matchShort = "s", + .description = "Path to the split rendering init params file", + }, +#endif }; @@ -214,10 +234,15 @@ static const int32_t numCliOptions = sizeof( cliOptions ) / sizeof( CmdLnParser_ static void printSupportedAudioConfigs( void ); +#ifdef RTP_S4_251135_CR26253_0016_REV1 +static IVAS_AUDIO_CONFIG parseAudioConfig( const char *configString, bool *srRtp ); +#else static IVAS_AUDIO_CONFIG parseAudioConfig( const char *configString ); +#endif static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer ); + /*------------------------------------------------------------------------------------------* * Local functions *------------------------------------------------------------------------------------------*/ @@ -264,10 +289,6 @@ static int16_t getTotalNumInChannels( return totalNumInChannels; } -/*------------------------------------------------------------------------------------------* - * Local functions - *------------------------------------------------------------------------------------------*/ - static const CmdLnParser_Option *findOptionById( const int32_t id ) { @@ -305,12 +326,20 @@ static bool parseInConfig( } /* Check for single-format inputs. The given string should map to a member of AUDIO_CONFIG enum. */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + bool srRtp = false; + IVAS_AUDIO_CONFIG audioConfig = parseAudioConfig( inFormatStr, &srRtp ); +#else IVAS_AUDIO_CONFIG audioConfig = parseAudioConfig( inFormatStr ); +#endif switch ( audioConfig ) { case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: inConfig->numBinBuses = 1; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + inConfig->binBuses[0].srRtp = srRtp; +#endif inConfig->binBuses[0].audioConfig = audioConfig; inConfig->binBuses[0].inputChannelIndex = 0; inConfig->binBuses[0].gain_dB = 0.0f; @@ -361,11 +390,19 @@ static bool parseRenderFramesize( static IVAS_AUDIO_CONFIG parseAudioConfig( +#ifdef RTP_S4_251135_CR26253_0016_REV1 + const char *configString, + bool *srRtp ) +#else const char *configString ) +#endif { char charBuf[25]; charBuf[24] = '\0'; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + *srRtp = false; +#endif strncpy( charBuf, configString, sizeof( charBuf ) - 1 ); charBuf[sizeof( charBuf ) - 1] = '\0'; to_upper( charBuf ); @@ -382,6 +419,13 @@ static IVAS_AUDIO_CONFIG parseAudioConfig( { return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED; } +#ifdef RTP_S4_251135_CR26253_0016_REV1 + if ( strcmp( charBuf, "RTPDUMP" ) == 0 ) + { + *srRtp = true; + return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED; + } +#endif return IVAS_AUDIO_CONFIG_INVALID; } @@ -429,6 +473,7 @@ static bool checkRequiredArgs( return !missingRequiredArg; } + static CmdlnArgs defaultArgs( const char *executableName ) { @@ -437,6 +482,9 @@ static CmdlnArgs defaultArgs( strncpy( args.executableName, executableName, POST_REND_MAX_CLI_ARG_LENGTH ); clearString( args.inputFilePath ); clearString( args.outputFilePath ); +#ifdef RTP_S4_251135_CR26253_0016_REV1 + clearString( args.srParamsFilePath ); +#endif args.sampleRate = 0; args.outConfig.audioConfig = IVAS_AUDIO_CONFIG_INVALID; @@ -459,6 +507,7 @@ static CmdlnArgs defaultArgs( return args; } + static void parseOption( const int32_t optionId, char **optionValues, @@ -543,6 +592,12 @@ static void parseOption( } break; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + case CmdLnOptionId_srParamsFile: + assert( numOptionValues == 1 ); + strncpy( args->srParamsFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 ); + break; +#endif default: assert( 0 && "This should be unreachable - all command line options should be explicitly handled." ); break; @@ -551,6 +606,7 @@ static void parseOption( return; } + static CmdlnArgs parseCmdlnArgs( const int argc, char **argv ) @@ -578,6 +634,9 @@ static void printSupportedAudioConfigs( void ) "BINAURAL (output only)", "BINAURAL_SPLIT_PCM", "BINAURAL_SPLIT_CODED", +#ifdef RTP_S4_251135_CR26253_0016_REV1 + "RTPDUMP", +#endif }; fprintf( stdout, "Supported audio formats:\n" ); @@ -589,6 +648,7 @@ static void printSupportedAudioConfigs( void ) return; } + /*--------------------------------------------------------------------------* * convertInputBuffer() * @@ -627,6 +687,7 @@ static void convertInputBuffer( return; } + /*--------------------------------------------------------------------------* * convertOutputBuffer() * @@ -668,6 +729,97 @@ static void convertOutputBuffer( return; } +#ifdef RTP_S4_251135_CR26253_0016_REV1 +static void trim( char *str ) +{ + char c; + int r = 0, w = 0; + while ( ( c = str[r] ) != 0 && ( c == ' ' || c == '\t' || c == ';' ) ) + { + r++; + } + + while ( ( c = str[r] ) != 0 && ( c != ' ' && c != '\t' && c != ';' ) ) + { + str[w++] = c; + r++; + } + str[w] = 0; +} + +static ivas_error parseSRParamsFile( + const char *srParamsFilePath, + ISAR_SPLIT_REND_CODEC *codec, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, + int16_t *codec_frame_size_ms, + int16_t *isar_frame_size_ms, + int16_t *lc3plusHighRes ) +{ + FILE *fParamSR = fopen( srParamsFilePath, "r" ); + if ( NULL == fParamSR ) + { + fprintf( stderr, "error in opening srParams File %s)\n", srParamsFilePath ); + return IVAS_ERR_FAILED_FILE_OPEN; + } + + *codec = ISAR_SPLIT_REND_CODEC_NONE; + *poseCorrection = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + *codec_frame_size_ms = 5; + *lc3plusHighRes = 0; + + while ( !feof( fParamSR ) ) + { + char key[16], value[16]; + if ( 2 == fscanf( fParamSR, "%15s = %15s", key, value ) ) + { + trim( key ); + trim( value ); + + if ( 0 == strncmp( key, "CODEC", 5 ) ) + { + *codec = ( 0 == strncmp( value, "LCLD", 4 ) ) ? ISAR_SPLIT_REND_CODEC_LCLD : *codec; + *codec = ( 0 == strncmp( value, "LC3PLUS", 7 ) ) ? ISAR_SPLIT_REND_CODEC_LC3PLUS : *codec; + } + else if ( 0 == strncmp( key, "DOF", 3 ) ) + { + int val = atoi( value ); + if ( val == 0 || val == 1 ) + { + *poseCorrection = ( val == 0 ) ? ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE : ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + } + } + else if ( 0 == strncmp( key, "FRAMESIZE", 9 ) ) + { + int val = atoi( value ); + if ( val == 5 || val == 10 || val == 20 ) + { + *codec_frame_size_ms = (int16_t) val; + } + } + else if ( 0 == strncmp( key, "RENDERSIZE", 9 ) ) + { + int val = atoi( value ); + if ( val == 5 || val == 10 || val == 20 ) + { + *isar_frame_size_ms = (int16_t) val; + } + } + else if ( 0 == strncmp( key, "LC3PLUS_HIGHRES", 15 ) ) + { + int val = atoi( value ); + if ( val == 0 || val == 1 ) + { + *lc3plusHighRes = (int16_t) val; + } + } + } + } + + fclose( fParamSR ); + return IVAS_ERR_OK; +} +#endif + /*------------------------------------------------------------------------------------------* * main() * @@ -707,6 +859,9 @@ int main( int16_t i, numChannels; ivas_error error = IVAS_ERR_OK; bool splitBinNeedsNewFrame = true; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + IVAS_RTP srRTP = { 0 }; +#endif #ifdef WMOPS reset_wmops(); @@ -724,12 +879,22 @@ int main( bitsBuffer.config.isar_frame_size_ms = 20; bitsBuffer.config.lc3plusHighRes = 0; + /*------------------------------------------------------------------------------------------* + * Parse command-line arguments + *------------------------------------------------------------------------------------------*/ CmdlnArgs args = parseCmdlnArgs( argc, argv ); convert_backslash( args.inputFilePath ); convert_backslash( args.outputFilePath ); convert_backslash( args.headRotationFilePath ); +#ifdef RTP_S4_251135_CR26253_0016_REV1 + convert_backslash( args.srParamsFilePath ); +#endif + + /*------------------------------------------------------------------------------------------* + * Open head-rotation file + *------------------------------------------------------------------------------------------*/ if ( !isEmptyString( args.headRotationFilePath ) ) { @@ -740,12 +905,20 @@ int main( } } + /*------------------------------------------------------------------------------------------* + * Open BFI file + *------------------------------------------------------------------------------------------*/ + if ( !isEmptyString( args.splitRendBFIFilePath ) ) { convert_backslash( args.splitRendBFIFilePath ); SplitRendBFIFileReader_open( args.splitRendBFIFilePath, &splitRendBFIReader ); } + /*------------------------------------------------------------------------------------------* + * Open input files + *------------------------------------------------------------------------------------------*/ + int32_t inFileSampleRate = 0; strncpy( audioFilePath, args.inputFilePath, FILENAME_MAX - 1 ); hSplitRendFileReadWrite = NULL; @@ -772,8 +945,34 @@ int main( } } +#ifdef RTP_S4_251135_CR26253_0016_REV1 + if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].srRtp ) ) + { + error = parseSRParamsFile( args.srParamsFilePath, + &bitsBuffer.config.codec, + &bitsBuffer.config.poseCorrection, + &bitsBuffer.config.codec_frame_size_ms, + &bitsBuffer.config.isar_frame_size_ms, + &bitsBuffer.config.lc3plusHighRes ); + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "\nCould not open split rend params file %s\n", args.srParamsFilePath ); + goto cleanup; + } + + if ( ( error = IVAS_RTP_READER_Init( &srRTP, (uint32_t) bitsBuffer.config.codec_frame_size_ms, args.inputFilePath, NULL, false, NULL ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "error in IVAS_RTP_READER_Init(): %d\n", error ); + goto cleanup; + } + audioReader = NULL; + } + /*if split renderer is running in post renderer mode*/ + else if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ) +#else /*if split renderer is running in post renderer mode*/ if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ) +#endif { error = split_rend_reader_open( &hSplitRendFileReadWrite, args.inputFilePath, @@ -838,6 +1037,10 @@ int main( } } + /*------------------------------------------------------------------------------------------* + * Open ISAR handle + *------------------------------------------------------------------------------------------*/ + const int16_t frameSize_smpls = (int16_t) ( ( args.render_framesize ) * args.sampleRate * 5 / ( 1000 ) ); args.outConfig.audioConfig = IVAS_AUDIO_CONFIG_BINAURAL; if ( ( error = ISAR_POST_REND_open( &hIsarPostRend, args.sampleRate, args.outConfig.audioConfig, true, 0, 0.0, (int16_t) args.render_framesize ) ) != IVAS_ERR_OK ) @@ -846,7 +1049,10 @@ int main( goto cleanup; } - /* === Configure === */ + /*------------------------------------------------------------------------------------------* + * Configuration + *------------------------------------------------------------------------------------------*/ + if ( ( error = ISAR_POST_REND_InitConfig( hIsarPostRend, args.outConfig.audioConfig ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError in Renderer Config Init: %s\n", ivas_error_to_string( error ) ); @@ -868,7 +1074,6 @@ int main( } ISAR_POST_REND_InputId splitBinIds[RENDERER_MAX_BIN_INPUTS]; - for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; i++ ) { splitBinIds[i] = 0u; @@ -884,7 +1089,6 @@ int main( } const int16_t totalNumInChannels = getTotalNumInChannels( hIsarPostRend, splitBinIds ); - if ( inFileNumChannels != 0 /* inFileNumChannels is 0 with raw PCM input */ && totalNumInChannels != inFileNumChannels ) { fprintf( stderr, "\nNumber of channels in input file does not match selected configuration\n" ); @@ -892,13 +1096,16 @@ int main( } int16_t numOutChannels = 2; - if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, numOutChannels ) != IVAS_ERR_OK ) { fprintf( stderr, "\nFailed to open file: %s\n", args.outputFilePath ); goto cleanup; } + /*------------------------------------------------------------------------------------------* + * Allocate processing buffers + *------------------------------------------------------------------------------------------*/ + inBufferSize = frameSize_smpls * totalNumInChannels; outBufferSize = frameSize_smpls * numOutChannels; inpInt16Buffer = malloc( inBufferSize * sizeof( int16_t ) ); @@ -951,6 +1158,13 @@ int main( fprintf( stdout, "\n\n-- Start the ISAR post renderer (quiet mode) --\n\n" ); } + /*------------------------------------------------------------------------------------------* + * Loop for every frame of data + * - Read the input data + * - Run the post-rendering + * - Write the data into output file + *------------------------------------------------------------------------------------------*/ + while ( 1 ) { int16_t bfi = 0; @@ -958,10 +1172,58 @@ int main( num_in_channels = inBuffer.config.numChannels; numSamplesRead = 0; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + if ( srRTP.hRtpFile && splitBinNeedsNewFrame ) + { + IVAS_RTP_SR_INFO srInfo = { 0 }; + uint32_t rtpTimeStamp = 0, nextPacketRcvTime_ms = 0; + uint16_t rtpSequenceNumber = 0; + int16_t auSizeBits = 0; + bool qBit = false; + uint8_t *bitBuffer = bitsBuffer.bits; + int16_t frameMS = 0; + + numSamplesRead = (int16_t) inBufferSize; + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; + + while ( frameMS < bitsBuffer.config.isar_frame_size_ms ) + { + error = IVAS_RTP_ReadNextFrame( &srRTP, bitBuffer, &auSizeBits, &rtpTimeStamp, &rtpSequenceNumber, &nextPacketRcvTime_ms, &srInfo, &qBit ); + if ( error != IVAS_ERR_OK ) + { + if ( error == IVAS_ERR_END_OF_FILE ) + { + numSamplesRead = 0; + } + else + { + fprintf( stderr, "\nUnable to read from bitstream file!\n" ); + goto cleanup; + } + } + /* Ensure a SR RTP stream was received */ + if ( !srInfo.valid ) + { + fprintf( stderr, "\nNon-SR RTP stream detected !\n" ); + goto cleanup; + } + + bitBuffer += ( auSizeBits + 7 ) / 8; + bitsBuffer.config.bitsWritten += auSizeBits; + bitsBuffer.config.codec = srInfo.codec == IVAS_SR_TRANSPORT_LC3PLUS ? ISAR_SPLIT_REND_CODEC_LC3PLUS : ISAR_SPLIT_REND_CODEC_LCLD; + frameMS += bitsBuffer.config.codec_frame_size_ms; + } + } + else if ( ( hSplitRendFileReadWrite != NULL ) && splitBinNeedsNewFrame ) +#else if ( ( hSplitRendFileReadWrite != NULL ) && splitBinNeedsNewFrame ) +#endif { ivas_error error_tmp; + numSamplesRead = (int16_t) inBufferSize; + error_tmp = split_rend_read_bits_from_file( hSplitRendFileReadWrite, bitsBuffer.bits, &bitsBuffer.config.bitsRead, &bitsBuffer.config.bitsWritten, &bfi ); if ( error_tmp != IVAS_ERR_OK ) { @@ -1035,6 +1297,7 @@ int main( goto cleanup; } } + if ( splitBinNeedsNewFrame ) { if ( ( error = ISAR_POST_REND_SetSplitRendBFI( hIsarPostRend, bfi ) ) != IVAS_ERR_OK ) diff --git a/apps/renderer.c b/apps/renderer.c index c49b793058814141cf9fd107ab831b55d433c30c..e434c0ca2a2193c674c2919cf2737efab37db3ed 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -33,7 +33,9 @@ #include "lib_rend.h" #include #include +#ifdef RENDERER_MD_SYNC_DELAY_TO_INTEGER #include +#endif #include #include "audio_file_reader.h" #include "audio_file_writer.h" @@ -46,9 +48,7 @@ #include "masa_file_writer.h" #include "render_config_reader.h" #include "rotation_file_reader.h" -#ifdef FIX_1053_REVERB_RECONFIGURATION #include "aeid_file_reader.h" -#endif #include "split_render_file_read_write.h" #include "split_rend_bfi_file_reader.h" #include "vector3_pair_file_reader.h" @@ -56,6 +56,9 @@ #include "debug.h" #endif #include "wmc_auto.h" +#ifdef FLP_EXCEPTION_TRAP +#include "flp_debug.h" +#endif #define WMC_TOOL_SKIP @@ -71,9 +74,7 @@ #define IVAS_MAX16B_FLT 32767.0f #define IVAS_MIN16B_FLT ( -32768.0f ) -#ifdef NONBE_1359_FIX_IVASREND_OMASA_BINAURAL_LOUDNESS #define OMASA_TDREND_MATCHING_GAIN_DB ( -2.0f ) -#endif #if !defined( DEBUGGING ) && !defined( WMOPS ) static @@ -191,7 +192,11 @@ typedef struct float lfeConfigElevation; bool lfeCustomRoutingEnabled; char inLfePanningMatrixFile[RENDERER_MAX_CLI_ARG_LENGTH]; +#ifdef RENDERER_MD_SYNC_DELAY_TO_INTEGER int16_t syncMdDelay; +#else + float syncMdDelay; +#endif IVAS_RENDER_FRAMESIZE render_framesize; uint16_t directivityPatternId[RENDERER_MAX_ISM_INPUTS]; AcousticEnvironmentSequence aeSequence; @@ -389,11 +394,7 @@ static const CmdLnParser_Option cliOptions[] = { .id = CmdLnOptionId_acousticEnvironmentId, .match = "acoustic_environment_id", .matchShort = "aeid", -#ifdef FIX_1053_REVERB_RECONFIGURATION - .description = "Acoustic environment ID (number > 0) alternatively, it can be a text file where each line contains \"ID duration\" for BINAURAL_ROOM_REVERB output configuration.", -#else - .description = "Acoustic environment ID( number > 0 ) or a sequence thereof in the format [ID1:duration1,ID2:duration2...] without braces and spaces, with ':' character separating ID from duration and ',' separating ID and duration pairs, where duration is specified in frames for BINAURAL_ROOM_REVERB output configuration.", -#endif + .description = "Acoustic environment ID (number > 0) alternatively, it can be\na text file where each line contains \"ID duration\" for\nBINAURAL_ROOM_REVERB output.", }, }; @@ -573,7 +574,6 @@ static void setupWithSingleFormatInput( positionProvider->numObjects = args.inConfig.numAudioObjects; for ( int16_t i = 0; i < positionProvider->numObjects; ++i ) { -#ifdef FIX_1376_MISSING_ISM_METADATA /* Check if path to metadata file was given */ if ( isEmptyString( args.inMetadataFilePaths[i] ) ) { @@ -582,18 +582,11 @@ static void setupWithSingleFormatInput( } /* It is allowed on CLI to have no metadata for an ISM input - skip opening if string contains "NULL" */ -#else - /* It is allowed on CLI to have no metadata for an ISM input - skip opening if string is empty or contains "NULL" */ -#endif char charBuf[FILENAME_MAX]; strncpy( charBuf, args.inMetadataFilePaths[i], min( FILENAME_MAX, RENDERER_MAX_CLI_ARG_LENGTH ) - 1 ); charBuf[min( FILENAME_MAX, RENDERER_MAX_CLI_ARG_LENGTH ) - 1] = '\0'; to_upper( charBuf ); -#ifdef FIX_1376_MISSING_ISM_METADATA if ( strncmp( charBuf, "NULL", 4 ) == 0 ) -#else - if ( isEmptyString( args.inMetadataFilePaths[i] ) || strncmp( charBuf, "NULL", 4 ) == 0 ) -#endif { continue; } @@ -637,6 +630,7 @@ static float dBToLin( return powf( 10.0f, gain_dB / 20.0f ); } + static int16_t get_cldfb_in_flag( const IVAS_AUDIO_CONFIG audioConfig, const IVAS_RENDER_CONFIG_DATA *renderConfig ) @@ -658,6 +652,7 @@ static int16_t get_cldfb_in_flag( return cldfb_in_flag; } + static int16_t is_split_pre_rend_mode( CmdlnArgs *args ) { @@ -672,6 +667,7 @@ static int16_t is_split_pre_rend_mode( return flag; } + /*------------------------------------------------------------------------------------------* * main() * @@ -696,7 +692,7 @@ int main( IVAS_DEC_HRTF_CREND_HANDLE *hHrtfCrend = NULL; IVAS_DEC_HRTF_FASTCONV_HANDLE *hHrtfFastConv = NULL; IVAS_DEC_HRTF_PARAMBIN_HANDLE *hHrtfParambin = NULL; - IVAS_DEC_HRTF_HANDLE *hHrtfTD = NULL; + IVAS_DEC_HRTF_TD_HANDLE *hHrtfTD = NULL; IVAS_DEC_HRTF_STATISTICS_HANDLE *hHrtfStatistics = NULL; IsmPositionProvider *positionProvider = NULL; LfeRoutingConfig *lfeRoutingConfigs[RENDERER_MAX_MC_INPUTS]; @@ -729,16 +725,17 @@ int main( int16_t zeroPadToWrite = 0; int32_t delayTimeScale = 0; int16_t i, numChannels; - uint16_t aeID; -#ifdef FIX_1053_REVERB_RECONFIGURATION IVAS_RENDER_CONFIG_DATA renderConfig; -#endif + uint16_t aeID; ivas_error error = IVAS_ERR_OK; #ifdef WMOPS reset_wmops(); reset_mem( USE_BYTES ); #endif +#ifdef FLP_EXCEPTION_TRAP + enable_float_exception_trap( FLE_MASK_DENORM | FLE_MASK_UNDERFLOW ); +#endif for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) { @@ -977,9 +974,9 @@ int main( if ( hrtfFileReader != NULL ) { - if ( ( error = IVAS_REND_GetHrtfHandle( hIvasRend, &hHrtfTD ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_REND_GetHrtfTdHandle( hIvasRend, &hHrtfTD ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nIVAS_REND_GetHrtfHandle failed: %s\n\n", ivas_error_to_string( error ) ); + fprintf( stderr, "\nIVAS_REND_GetHrtfTdHandle failed: %s\n\n", ivas_error_to_string( error ) ); goto cleanup; } @@ -996,11 +993,13 @@ int main( } } + if ( ( error = IVAS_REND_GetHrtfCRendHandle( hIvasRend, &hHrtfCrend ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_Rend_GetHrtfCRendHandle failed: %s\n\n", ivas_error_to_string( error ) ); goto cleanup; } + IVAS_AUDIO_CONFIG hrtf_set_audio_cfg = IVAS_AUDIO_CONFIG_7_1_4; if ( args.inConfig.ambisonicsBuses->audioConfig != IVAS_AUDIO_CONFIG_INVALID && args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) { @@ -1089,9 +1088,7 @@ int main( if ( args.renderConfigFilePath[0] != '\0' ) { -#ifndef FIX_1053_REVERB_RECONFIGURATION - IVAS_RENDER_CONFIG_DATA renderConfig; -#endif + /* sanity check */ if ( ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL ) && ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) && @@ -1113,16 +1110,19 @@ int main( fprintf( stderr, "\nFailed to read renderer configuration from file %s\n", args.renderConfigFilePath ); goto cleanup; } + if ( ( error = RenderConfigReader_getDirectivity( renderConfigReader, args.directivityPatternId, renderConfig.directivity ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Failed to get directivity patterns for one or more of IDs: %d %d %d %d\n\n", args.directivityPatternId[0], args.directivityPatternId[1], args.directivityPatternId[2], args.directivityPatternId[3] ); goto cleanup; } + if ( ( error = RenderConfigReader_getDistanceAttenuation( renderConfigReader, renderConfig.distAtt ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Failed to get Distance Attenuation \n\n" ); goto cleanup; } + if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { aeID = args.aeSequence.count > 0 ? args.aeSequence.pID[0] : 65535; @@ -1182,29 +1182,21 @@ int main( } } -#ifndef NONBE_1359_FIX_IVASREND_OMASA_BINAURAL_LOUDNESS - /* Set the total number of objects */ -#endif if ( args.inConfig.numAudioObjects > 0 ) { -#ifdef NONBE_1359_FIX_IVASREND_OMASA_BINAURAL_LOUDNESS /* Set the total number of objects */ -#endif if ( ( error = IVAS_REND_SetTotalNumberOfObjects( hIvasRend, args.inConfig.numAudioObjects ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError in IVAS_REND_SetTotalNumberOfObjects(): %s\n", ivas_error_to_string( error ) ); goto cleanup; } -#ifdef NONBE_1359_FIX_IVASREND_OMASA_BINAURAL_LOUDNESS /* Set the metadata delay for objects */ -#endif if ( ( error = IVAS_REND_SetIsmMetadataDelay( hIvasRend, args.syncMdDelay ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError in IVAS_REND_SetIsmMetadataDelay(): %s\n", ivas_error_to_string( error ) ); goto cleanup; } -#ifdef NONBE_1359_FIX_IVASREND_OMASA_BINAURAL_LOUDNESS /* For OMASA input and BINAURAL output, apply a gain to objects to match the loudness with MASA part */ if ( args.inConfig.numMasaBuses > 0 && args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL ) @@ -1214,7 +1206,6 @@ int main( args.inConfig.audioObjects[i].gain_dB += OMASA_TDREND_MATCHING_GAIN_DB; } } -#endif } IVAS_REND_LfePanMtx lfePanMatrix; @@ -1250,17 +1241,12 @@ int main( { masaIds[i] = 0u; } -#ifdef NONBE_1377_REND_DIRATT_CONF -#ifdef FIX_1377_HANDLE_ERROR_CODE + if ( ( error = IVAS_REND_SetObjectIDs( hIvasRend ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_REND_SetObjectIDs: %s\n", ivas_error_to_string( error ) ); goto cleanup; } -#else - IVAS_REND_SetObjectIDs( hIvasRend ); -#endif -#endif for ( i = 0; i < args.inConfig.numMultiChannelBuses; ++i ) { @@ -1544,11 +1530,6 @@ int main( { if ( ++args.aeSequence.frameCounter >= args.aeSequence.pValidity[args.aeSequence.selected] ) { - -#ifndef FIX_1053_REVERB_RECONFIGURATION - IVAS_RENDER_CONFIG_DATA renderConfig; - -#endif if ( ++args.aeSequence.selected >= args.aeSequence.count ) { args.aeSequence.selected = 0; @@ -1558,13 +1539,13 @@ int main( { if ( RenderConfigReader_checkValues( &renderConfig ) != IVAS_ERR_OK ) { - fprintf( stderr, "Invalid acoustic environment configuration parameters\n\n" ); + fprintf( stderr, "\nInvalid acoustic environment configuration parameters\n\n" ); goto cleanup; } } else { - fprintf( stderr, "Failed to get acoustic environment with ID %d\n\n", args.aeSequence.pID[args.aeSequence.selected] ); + fprintf( stderr, "\nFailed to get acoustic environment with ID %d\n\n", args.aeSequence.pID[args.aeSequence.selected] ); goto cleanup; } if ( ( error = IVAS_REND_FeedRenderConfig( hIvasRend, renderConfig ) ) != IVAS_ERR_OK ) @@ -1574,6 +1555,7 @@ int main( } } } + numSamplesRead = 0; /* Read the input data */ if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) @@ -1967,6 +1949,7 @@ int main( } } } + if ( ( error = MasaFileWriter_writeFrame( masaWriter, hMetaOutput, NULL ) ) != IVAS_ERR_OK ) /* NULL -> use default metadata delay settings */ { fprintf( stderr, "\nError writing MASA metadata to file: %s\n", MasaFileWriter_getFilePath( masaWriter ) ); @@ -2017,7 +2000,7 @@ int main( if ( args.inConfig.numAudioObjects != 0 && ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL || args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) { - fprintf( stdout, "\n\nMetadata delayed %d subframes\n\n", (int16_t) round( args.syncMdDelay / ( (float) BINAURAL_RENDERING_FRAME_SIZE_MS ) ) ); + fprintf( stdout, "\n\nMetadata delayed %d subframes\n\n", (int16_t) round( args.syncMdDelay / ( 1000.f / IVAS_NUM_FRAMES_PER_SEC / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ) ) ); } if ( !args.quietModeEnabled && args.delayCompensationEnabled ) @@ -2056,6 +2039,7 @@ cleanup: { free( bitsBufferData ); } + if ( args.aeSequence.count > 0 ) { free( args.aeSequence.pID ); @@ -2084,6 +2068,7 @@ cleanup: RotationFileReader_close( &headRotReader ); RotationFileReader_close( &externalOrientationFileReader ); RotationFileReader_close( &referenceRotReader ); + Vector3PairFileReader_close( &referenceVectorReader ); destroy_td_hrtf( hHrtfTD ); destroy_hrtf_statistics( hHrtfStatistics ); @@ -2528,90 +2513,28 @@ static bool parseAcousticEnvironmentIds( const char *value, AcousticEnvironmentSequence *aeSequence ) { -#ifdef FIX_1053_REVERB_RECONFIGURATION char config_string[RENDERER_MAX_METADATA_LINE_LENGTH]; + strncpy( config_string, value, RENDERER_MAX_METADATA_LINE_LENGTH ); + if ( !is_digits_only( config_string ) ) { aeidFileReader *aeidReader = NULL; + if ( aeidFileReader_open( config_string, &aeidReader ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError: Can't open aeid file %s \n", config_string ); return false; } + if ( aeidFileReading( aeidReader, &aeSequence->count, &aeSequence->pID, &aeSequence->pValidity ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError while reading aeid from %s\n", config_string ); return false; } - aeidFileReader_close( &aeidReader ); - } -#else - uint16_t k; - char config_string[RENDERER_MAX_METADATA_LINE_LENGTH]; - char *s; - char *token; - - strncpy( config_string, value, RENDERER_MAX_METADATA_LINE_LENGTH ); - s = config_string; - token = config_string; - - if ( !is_digits_only( config_string ) ) - { - - for ( k = 0; s[k]; ) - { - s[k] == ',' ? k++ : *s++; - } - k++; - - if ( k == 0 ) - { - fprintf( stdout, "Error: Invalid acoustic environment sequence specified: %s\n\n", config_string ); - return false; - } - - if ( NULL == ( aeSequence->pID = malloc( sizeof( uint16_t ) * k ) ) || - NULL == ( aeSequence->pValidity = malloc( sizeof( uint16_t ) * k ) ) ) - { - fprintf( stdout, "Error: Unable to allocate memory for acoustic environment sequence: %s\n\n", config_string ); - return false; - } - - aeSequence->count = k; - k = 0; - - token = strtok( config_string, ":" ); - - while ( token != NULL ) - { - if ( !is_number( token ) ) - { - fprintf( stdout, "Error: Invalid token %s found in acoustic environment sequence: %s\n\n", token, config_string ); - return false; - } - aeSequence->pID[k] = (uint16_t) atoi( token ); - - token = strtok( NULL, "," ); - if ( !is_number( token ) ) - { - fprintf( stdout, "Error: Invalid token %s found in acoustic environment sequence: %s\n\n", token, config_string ); - return false; - } - aeSequence->pValidity[k] = (uint16_t) atoi( token ); - - token = strtok( NULL, ":" ); - k++; - } - - if ( k != aeSequence->count ) - { - fprintf( stdout, "Error while parsing acoustic environment sequence: %s\n\n", config_string ); - return false; - } + aeidFileReader_close( &aeidReader ); } -#endif else { /* A single acoustic environment */ @@ -2629,6 +2552,7 @@ static bool parseAcousticEnvironmentIds( return true; } + static bool checkRequiredArgs( CmdlnArgs args ) { @@ -2718,7 +2642,6 @@ static CmdlnArgs defaultArgs( args.Opt_Headrotation = 0; args.Opt_ExternalOrientation = 0; - args.orientation_tracking = IVAS_HEAD_ORIENT_TRK_NONE; args.nonDiegeticPan = 0; @@ -2928,7 +2851,11 @@ static void parseOption( case CmdLnOptionId_syncMdDelay: assert( numOptionValues == 1 ); /* Metadata Delay to sync with audio delay in ms */ +#ifdef RENDERER_MD_SYNC_DELAY_TO_INTEGER args->syncMdDelay = (int16_t) strtol( optionValues[0], NULL, 10 ); +#else + args->syncMdDelay = strtof( optionValues[0], NULL ); +#endif break; default: assert( 0 && "This should be unreachable - all command line options should be explicitly handled." ); @@ -3621,20 +3548,8 @@ static void parseCombinedFormatInput( inConfig->numAmbisonicsBuses = 1; inConfig->ambisonicsBuses[0].audioConfig = audioConfig; inConfig->ambisonicsBuses[0].inputChannelIndex = inConfig->numAudioObjects; -#ifdef NONBE_1352_HARMONIZE_OSBA_LOUDNESS inConfig->ambisonicsBuses[0].gain_dB = 0.f; -#else - inConfig->ambisonicsBuses[0].gain_dB = -6.f; -#endif *configString += 4; - - /* Modify input gain for objects too */ -#ifndef NONBE_1352_HARMONIZE_OSBA_LOUDNESS - for ( int16_t i = 0; i < inConfig->numAudioObjects; ++i ) - { - inConfig->audioObjects[i].gain_dB = -6.f; - } -#endif } else if ( audioConfig == IVAS_AUDIO_CONFIG_MASA1 || audioConfig == IVAS_AUDIO_CONFIG_MASA2 ) { @@ -3892,7 +3807,7 @@ static ivas_error parseLfePanMtxFile( { int16_t i, lfe_in, ch_out; const char *tok; - char line[200]; /* > (10 chars * IVAS_MAX_OUTPUT_CHANNELS) i.e. "-999, " */ + char line[200]; /* > (10 chars * RENDERER_MAX_OUTPUT_CHANNELS) i.e. "-999, " */ FILE *mtxFile; if ( strlen( lfeRoutingMatrixFilePath ) < 1 ) @@ -3908,7 +3823,7 @@ static ivas_error parseLfePanMtxFile( } /* set default panning matrix to all zeros - any subsequent issue in file reading will gracefully exit the function */ + any subsequent issue in file reading will gracefully exit the function */ for ( lfe_in = 0; lfe_in < RENDERER_MAX_INPUT_LFE_CHANNELS; lfe_in++ ) { for ( i = 0; i < RENDERER_MAX_OUTPUT_CHANNELS; i++ ) diff --git a/lib_com/ari_hm.c b/lib_com/ari_hm.c index 71ed483c671e70a71e8b1783e2df8d60f50ef916..a21e955590c7cc3a5b5455c15b69c03c80da1c87 100644 --- a/lib_com/ari_hm.c +++ b/lib_com/ari_hm.c @@ -272,7 +272,7 @@ void tcx_hm_modify_envelope( const int16_t L_frame /* i : number of spectral lines */ ) { - int32_t k, h, x; + int32_t h, x, k; Word16 inv_shape[2 * kTcxHmParabolaHalfWidth + 1]; /* Q15 */ if ( gain == 0 ) @@ -290,7 +290,6 @@ void tcx_hm_modify_envelope( while ( k <= L_frame + kTcxHmParabolaHalfWidth - 1 ) { - for ( x = max( 0, k - kTcxHmParabolaHalfWidth ); x <= min( k + kTcxHmParabolaHalfWidth, L_frame - 1 ); ++x ) { env[x] = Mpy_32_16( env[x], inv_shape[x - k + kTcxHmParabolaHalfWidth] ); diff --git a/lib_com/arith_coder.c b/lib_com/arith_coder.c index c0db15127ac8dccad79f13d7120b2ab3dfec8a8c..e71a40749e81ffff546e77fe4159e8e0969a3401 100644 --- a/lib_com/arith_coder.c +++ b/lib_com/arith_coder.c @@ -243,7 +243,10 @@ void tcx_arith_scale_envelope( Word16 statesi, bits; Word32 mean, a, s, L_tmp; Word16 mean_e, tmp, tmp2; +#ifdef BASOP_NOGLOB Flag Overflow; +#endif /* BASOP_NOGLOB */ + lob_bits = 0; move16(); @@ -268,7 +271,11 @@ void tcx_arith_scale_envelope( tmp = norm_l( env[k] ); tmp2 = sub( 15, tmp ); +#ifndef BASOP_NOGLOB + tmp = Inv16( round_fx( L_shl( env[k], tmp ) ), &tmp2 ); +#else /* BASOP_NOGLOB */ tmp = Inv16( round_fx_o( L_shl( env[k], tmp ), &Overflow ), &tmp2 ); +#endif /* BASOP_NOGLOB */ ienv[k] = L_shl( L_deposit_h( tmp ), sub( tmp2, 15 ) ); /* Q16 */ move32(); mean = L_add( mean, ienv[k] ); @@ -302,7 +309,11 @@ void tcx_arith_scale_envelope( b_e = add( b_e, mean_e ); /* scale = (-b + sqrtf(b*b - 4.0f*a*0.035f)) / (2.0f * a); */ +#ifndef BASOP_NOGLOB + tmp = round_fx( BASOP_Util_Add_Mant32Exp( L_mult( b, b ), shl( b_e, 1 ), Mpy_32_16( a, FL2WORD16( -4.0f * 0.035f ) ), a_e, &tmp2 ) ); +#else tmp = round_fx_o( BASOP_Util_Add_Mant32Exp( L_mult( b, b ), shl( b_e, 1 ), Mpy_32_16( a, FL2WORD16( -4.0f * 0.035f ) ), a_e, &tmp2 ), &Overflow ); +#endif IF( tmp <= 0 ) { @@ -321,7 +332,11 @@ void tcx_arith_scale_envelope( tmp2 = BASOP_Util_Add_MantExp( negate( b ), b_e, tmp, tmp2, &scale ); scale = BASOP_Util_Divide1616_Scale( scale, round_fx( a ), &tmp ); +#ifndef BASOP_NOGLOB + scale = shl( scale, sub( sub( add( tmp, tmp2 ), a_e ), 1 ) ); /* Q15 */ +#else scale = shl_o( scale, sub( sub( add( tmp, tmp2 ), a_e ), 1 ), &Overflow ); /* Q15 */ +#endif /* iscale = 1.0f / scale; */ iscale_e = 0; @@ -370,7 +385,11 @@ void tcx_arith_scale_envelope( L_tmp = L_add( L_tmp, L_shl( Mpy_32_16( env[k], mult_r( FL2WORD16( 0.035f ), iscale ) ), iscale_e ) ); tmp = norm_l( L_tmp ); +#ifndef BASOP_NOGLOB + statesi = mult_r( statesi, round_fx( L_shl( L_tmp, tmp ) ) ); +#else /* BASOP_NOGLOB */ statesi = mult_r( statesi, round_fx_o( L_shl( L_tmp, tmp ), &Overflow ) ); +#endif /* BASOP_NOGLOB */ bits = add( bits, sub( 15, tmp ) ); tmp = norm_s( statesi ); @@ -470,7 +489,11 @@ void tcx_arith_scale_envelope( *s_env_e = sub( add( 15, iscale_e ), tmp ); move16(); BASOP_SATURATE_WARNING_OFF; +#ifndef BASOP_NOGLOB + a = L_shl( 1265000, sub( 15, *s_env_e ) ); +#else /* BASOP_NOGLOB */ a = L_shl_o( 1265000, sub( 15, *s_env_e ), &Overflow ); +#endif /* BASOP_NOGLOB */ BASOP_SATURATE_WARNING_ON; FOR( k = 0; k < L_frame; k++ ) diff --git a/lib_com/basop32.c b/lib_com/basop32.c index 0a3bbb3a8ad8436d8454ab14bcfe9ee8b984573b..5a5a434846333bbcc752cf8e1e0dbcfa5ab08241 100644 --- a/lib_com/basop32.c +++ b/lib_com/basop32.c @@ -160,7 +160,9 @@ HISTORY: #include #include #include "stl.h" +#ifdef BASOP_NOGLOB #include +#endif /* BASOP_NOGLOB */ #define WMC_TOOL_SKIP @@ -173,7 +175,9 @@ HISTORY: | Local Functions | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB static Word16 saturate_o( Word32 L_var1, Flag *Overflow ); +#endif /* BASOP_NOGLOB */ static Word16 saturate( Word32 L_var1 ); @@ -182,10 +186,16 @@ static Word16 saturate( Word32 L_var1 ); | Constants and Globals | |___________________________________________________________________________| */ +#ifndef BASOP_NOGLOB +Flag Overflow = 0; +Flag Carry = 0; + +#else /* BASOP_NOGLOB */ /* Flag BASOP_Overflow = 0; Flag BASOP_Carry = 0; */ +#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ | | @@ -222,18 +232,30 @@ Flag BASOP_Carry = 0; | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ +#ifndef BASOP_NOGLOB +static Word16 saturate( Word32 L_var1 ) +#else /* BASOP_NOGLOB */ static Word16 saturate_o( Word32 L_var1, Flag *Overflow ) +#endif /* BASOP_NOGLOB */ { Word16 var_out; if ( L_var1 > 0X00007fffL ) { +#ifndef BASOP_NOGLOB + Overflow = 1; +#else /* BASOP_NOGLOB */ *Overflow = 1; +#endif /* BASOP_NOGLOB */ var_out = MAX_16; } else if ( L_var1 < (Word32) 0xffff8000L ) { +#ifndef BASOP_NOGLOB + Overflow = 1; +#else /* BASOP_NOGLOB */ *Overflow = 1; +#endif /* BASOP_NOGLOB */ var_out = MIN_16; } else @@ -249,6 +271,7 @@ static Word16 saturate_o( Word32 L_var1, Flag *Overflow ) return ( var_out ); } +#ifdef BASOP_NOGLOB static Word16 saturate( Word32 L_var1 ) { Word16 var_out; @@ -275,6 +298,7 @@ static Word16 saturate( Word32 L_var1 ) return ( var_out ); } +#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ | | @@ -309,6 +333,7 @@ static Word16 saturate( Word32 L_var1 ) | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB Word16 add_o( Word16 var1, Word16 var2, Flag *Overflow ) { Word16 var_out; @@ -323,6 +348,7 @@ Word16 add_o( Word16 var1, Word16 var2, Flag *Overflow ) return ( var_out ); } +#endif /* BASOP_NOGLOB */ Word16 add( Word16 var1, Word16 var2 ) { Word16 var_out; @@ -371,6 +397,7 @@ Word16 add( Word16 var1, Word16 var2 ) | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB Word16 sub_o( Word16 var1, Word16 var2, Flag *Overflow ) { Word16 var_out; @@ -385,6 +412,7 @@ Word16 sub_o( Word16 var1, Word16 var2, Flag *Overflow ) return ( var_out ); } +#endif /* BASOP_NOGLOB */ Word16 sub( Word16 var1, Word16 var2 ) { Word16 var_out; @@ -491,7 +519,11 @@ Word16 abs_s( Word16 var1 ) | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ +#ifndef BASOP_NOGLOB +Word16 shl( Word16 var1, Word16 var2 ) +#else /* BASOP_NOGLOB */ Word16 shl_o( Word16 var1, Word16 var2, Flag *Overflow ) +#endif /* BASOP_NOGLOB */ { Word16 var_out; Word32 result; @@ -513,7 +545,11 @@ Word16 shl_o( Word16 var1, Word16 var2, Flag *Overflow ) if ( ( var2 > 15 && var1 != 0 ) || ( result != (Word32) ( (Word16) result ) ) ) { +#ifndef BASOP_NOGLOB + Overflow = 1; +#else /* BASOP_NOGLOB */ *Overflow = 1; +#endif /* BASOP_NOGLOB */ var_out = ( var1 > 0 ) ? MAX_16 : MIN_16; } else @@ -536,6 +572,7 @@ Word16 shl_o( Word16 var1, Word16 var2, Flag *Overflow ) return ( var_out ); } +#ifdef BASOP_NOGLOB Word16 shl( Word16 var1, Word16 var2 ) { Word16 var_out; @@ -579,6 +616,7 @@ Word16 shl( Word16 var1, Word16 var2 ) return ( var_out ); } +#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ | | @@ -620,7 +658,9 @@ Word16 shr( Word16 var1, Word16 var2 ) if ( var2 < 0 ) { +#ifdef BASOP_NOGLOB assert( 0 ); +#endif /* BASOP_NOGLOB */ if ( var2 < -16 ) var2 = -16; var2 = -var2; @@ -694,6 +734,7 @@ Word16 shr( Word16 var1, Word16 var2 ) | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB Word16 mult_o( Word16 var1, Word16 var2, Flag *Overflow ) { Word16 var_out; @@ -715,6 +756,7 @@ Word16 mult_o( Word16 var1, Word16 var2, Flag *Overflow ) return ( var_out ); } +#endif /* BASOP_NOGLOB */ Word16 mult( Word16 var1, Word16 var2 ) { Word16 var_out; @@ -770,7 +812,11 @@ Word16 mult( Word16 var1, Word16 var2 ) | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ +#ifndef BASOP_NOGLOB +Word32 L_mult( Word16 var1, Word16 var2 ) +#else /* BASOP_NOGLOB */ Word32 L_mult_o( Word16 var1, Word16 var2, Flag *Overflow ) +#endif /* BASOP_NOGLOB */ { Word32 L_var_out; @@ -782,7 +828,11 @@ Word32 L_mult_o( Word16 var1, Word16 var2, Flag *Overflow ) } else { +#ifndef BASOP_NOGLOB + Overflow = 1; +#else /* BASOP_NOGLOB */ *Overflow = 1; +#endif /* BASOP_NOGLOB */ L_var_out = MAX_32; } @@ -795,6 +845,7 @@ Word32 L_mult_o( Word16 var1, Word16 var2, Flag *Overflow ) return ( L_var_out ); } +#ifdef BASOP_NOGLOB Word32 L_mult( Word16 var1, Word16 var2 ) { Word32 L_var_out; @@ -819,6 +870,7 @@ Word32 L_mult( Word16 var1, Word16 var2 ) return ( L_var_out ); } +#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ | | @@ -984,6 +1036,7 @@ Word16 extract_l( Word32 L_var1 ) | range : 0xffff 8000 <= var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB Word16 round_fx_o( Word32 L_var1, Flag *Overflow ) { Word16 var_out; @@ -1005,6 +1058,7 @@ Word16 round_fx_o( Word32 L_var1, Flag *Overflow ) return ( var_out ); } +#endif /* BASOP_NOGLOB */ Word16 round_fx( Word32 L_var1 ) { Word16 var_out; @@ -1062,6 +1116,7 @@ Word16 round_fx( Word32 L_var1 ) | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB Word32 L_mac_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) { Word32 L_var_out; @@ -1079,6 +1134,7 @@ Word32 L_mac_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) return ( L_var_out ); } +#endif /* BASOP_NOGLOB */ Word32 L_mac( Word32 L_var3, Word16 var1, Word16 var2 ) { Word32 L_var_out; @@ -1134,6 +1190,7 @@ Word32 L_mac( Word32 L_var3, Word16 var1, Word16 var2 ) | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB Word32 L_msu_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) { Word32 L_var_out; @@ -1151,6 +1208,7 @@ Word32 L_msu_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) return ( L_var_out ); } +#endif /* BASOP_NOGLOB */ Word32 L_msu( Word32 L_var3, Word16 var1, Word16 var2 ) { Word32 L_var_out; @@ -1208,16 +1266,28 @@ Word32 L_msu( Word32 L_var3, Word16 var1, Word16 var2 ) | | | Caution : | | | +#ifndef BASOP_NOGLOB + | In some cases the Carry flag has to be cleared or set before using | +#else | In some cases the BASOP_Carry flag has to be cleared or set before using | +#endif | operators which take into account its value. | |___________________________________________________________________________| */ +#ifndef BASOP_NOGLOB +Word32 L_macNs( Word32 L_var3, Word16 var1, Word16 var2 ) +#else /* BASOP_NOGLOB */ Word32 DEPR_L_macNs( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry ) +#endif /* BASOP_NOGLOB */ { Word32 L_var_out; L_var_out = L_mult( var1, var2 ); +#ifndef BASOP_NOGLOB + L_var_out = L_add_c( L_var3, L_var_out ); +#else /* BASOP_NOGLOB */ L_var_out = DEPR_L_add_c( L_var3, L_var_out, Carry ); +#endif /* BASOP_NOGLOB */ #ifdef WMOPS multiCounter[currCounter].L_mult--; @@ -1270,16 +1340,28 @@ Word32 DEPR_L_macNs( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry ) | | | Caution : | | | +#ifndef BASOP_NOGLOB + | In some cases the Carry flag has to be cleared or set before using | +#else | In some cases the BASOP_Carry flag has to be cleared or set before using | +#endif | operators which take into account its value. | |___________________________________________________________________________| */ +#ifndef BASOP_NOGLOB +Word32 L_msuNs( Word32 L_var3, Word16 var1, Word16 var2 ) +#else /* BASOP_NOGLOB */ Word32 DEPR_L_msuNs( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry ) +#endif /* BASOP_NOGLOB */ { Word32 L_var_out; L_var_out = L_mult( var1, var2 ); +#ifndef BASOP_NOGLOB + L_var_out = L_sub_c( L_var3, L_var_out ); +#else /* BASOP_NOGLOB */ L_var_out = DEPR_L_sub_c( L_var3, L_var_out, Carry ); +#endif /* BASOP_NOGLOB */ #ifdef WMOPS multiCounter[currCounter].L_mult--; @@ -1324,7 +1406,11 @@ Word32 DEPR_L_msuNs( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry ) | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ +#ifndef BASOP_NOGLOB +Word32 L_add( Word32 L_var1, Word32 L_var2 ) +#else /* BASOP_NOGLOB */ Word32 L_add_o( Word32 L_var1, Word32 L_var2, Flag *Overflow ) +#endif /* BASOP_NOGLOB */ { Word32 L_var_out; @@ -1335,7 +1421,11 @@ Word32 L_add_o( Word32 L_var1, Word32 L_var2, Flag *Overflow ) if ( ( L_var_out ^ L_var1 ) & MIN_32 ) { L_var_out = ( L_var1 < 0 ) ? MIN_32 : MAX_32; +#ifndef BASOP_NOGLOB + Overflow = 1; +#else /* BASOP_NOGLOB */ *Overflow = 1; +#endif /* BASOP_NOGLOB */ } } @@ -1349,6 +1439,7 @@ Word32 L_add_o( Word32 L_var1, Word32 L_var2, Flag *Overflow ) return ( L_var_out ); } +#ifdef BASOP_NOGLOB Word32 L_add( Word32 L_var1, Word32 L_var2 ) { Word32 L_var_out; @@ -1369,6 +1460,7 @@ Word32 L_add( Word32 L_var1, Word32 L_var2 ) #endif return ( L_var_out ); } +#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ | | @@ -1401,7 +1493,11 @@ Word32 L_add( Word32 L_var1, Word32 L_var2 ) | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ +#ifndef BASOP_NOGLOB +Word32 L_sub( Word32 L_var1, Word32 L_var2 ) +#else /* BASOP_NOGLOB */ Word32 L_sub_o( Word32 L_var1, Word32 L_var2, Flag *Overflow ) +#endif /* BASOP_NOGLOB */ { Word32 L_var_out; @@ -1412,7 +1508,11 @@ Word32 L_sub_o( Word32 L_var1, Word32 L_var2, Flag *Overflow ) if ( ( L_var_out ^ L_var1 ) & MIN_32 ) { L_var_out = ( L_var1 < 0L ) ? MIN_32 : MAX_32; +#ifndef BASOP_NOGLOB + Overflow = 1; +#else /* BASOP_NOGLOB */ *Overflow = 1; +#endif /* BASOP_NOGLOB */ } } @@ -1425,6 +1525,7 @@ Word32 L_sub_o( Word32 L_var1, Word32 L_var2, Flag *Overflow ) return ( L_var_out ); } +#ifdef BASOP_NOGLOB Word32 L_sub( Word32 L_var1, Word32 L_var2 ) { Word32 L_var_out; @@ -1447,6 +1548,7 @@ Word32 L_sub( Word32 L_var1, Word32 L_var2 ) return ( L_var_out ); } +#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ | | @@ -1455,7 +1557,11 @@ Word32 L_sub( Word32 L_var1, Word32 L_var2 ) | Purpose : | | | | Performs 32 bits addition of the two 32 bits variables (L_var1+L_var2+C)| +#ifndef BASOP_NOGLOB + | with carry. No saturation. Generate carry and Overflow values. The car- | +#else | with carry. No saturation. Generate carry and BASOP_Overflow values. The car- | +#endif | ry and overflow values are binary variables which can be tested and as- | | signed values. | | | @@ -1481,22 +1587,37 @@ Word32 L_sub( Word32 L_var1, Word32 L_var2 ) | | | Caution : | | | +#ifndef BASOP_NOGLOB + | In some cases the Carry flag has to be cleared or set before using | +#else | In some cases the BASOP_Carry flag has to be cleared or set before using | +#endif | operators which take into account its value. | |___________________________________________________________________________| */ +#ifndef BASOP_NOGLOB +Word32 L_add_c( Word32 L_var1, Word32 L_var2 ) +#else /* BASOP_NOGLOB */ Word32 DEPR_L_add_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) +#endif /* BASOP_NOGLOB */ { Word32 L_var_out; Word32 L_test; Flag carry_int = 0; +#ifndef BASOP_NOGLOB + L_var_out = L_var1 + L_var2 + Carry; +#else /* BASOP_NOGLOB */ L_var_out = L_var1 + L_var2 + *Carry; +#endif /* BASOP_NOGLOB */ L_test = L_var1 + L_var2; if ( ( L_var1 > 0 ) && ( L_var2 > 0 ) && ( L_test < 0 ) ) { +#ifndef BASOP_NOGLOB + Overflow = 1; +#endif /* ! BASOP_NOGLOB */ carry_int = 0; } else @@ -1505,10 +1626,16 @@ Word32 DEPR_L_add_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) { if ( L_test >= 0 ) { +#ifndef BASOP_NOGLOB + Overflow = 1; +#endif /* ! BASOP_NOGLOB */ carry_int = 1; } else { +#ifndef BASOP_NOGLOB + Overflow = 0; +#endif /* ! BASOP_NOGLOB */ carry_int = 1; } } @@ -1516,36 +1643,63 @@ Word32 DEPR_L_add_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) { if ( ( ( L_var1 ^ L_var2 ) < 0 ) && ( L_test >= 0 ) ) { +#ifndef BASOP_NOGLOB + Overflow = 0; +#endif /* ! BASOP_NOGLOB */ carry_int = 1; } else { +#ifndef BASOP_NOGLOB + Overflow = 0; +#endif /* ! BASOP_NOGLOB */ carry_int = 0; } } } +#ifndef BASOP_NOGLOB + if ( Carry ) +#else /* BASOP_NOGLOB */ if ( *Carry ) +#endif /* BASOP_NOGLOB */ { if ( L_test == MAX_32 ) { +#ifndef BASOP_NOGLOB + Overflow = 1; + Carry = carry_int; +#else /* BASOP_NOGLOB */ *Carry = carry_int; +#endif /* BASOP_NOGLOB */ } else { if ( L_test == (Word32) 0xFFFFFFFFL ) { +#ifndef BASOP_NOGLOB + Carry = 1; +#else /* BASOP_NOGLOB */ *Carry = 1; +#endif /* BASOP_NOGLOB */ } else { +#ifndef BASOP_NOGLOB + Carry = carry_int; +#else /* BASOP_NOGLOB */ *Carry = carry_int; +#endif /* BASOP_NOGLOB */ } } } else { +#ifndef BASOP_NOGLOB + Carry = carry_int; +#else /* BASOP_NOGLOB */ *Carry = carry_int; +#endif /* BASOP_NOGLOB */ } #ifdef WMOPS @@ -1566,7 +1720,11 @@ Word32 DEPR_L_add_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) | Purpose : | | | | Performs 32 bits subtraction of the two 32 bits variables with carry | +#ifndef BASOP_NOGLOB + | (borrow) : L_var1-L_var2-C. No saturation. Generate carry and Overflow | +#else | (borrow) : L_var1-L_var2-C. No saturation. Generate carry and BASOP_Overflow | +#endif | values. The carry and overflow values are binary variables which can | | be tested and assigned values. | | | @@ -1592,22 +1750,42 @@ Word32 DEPR_L_add_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) | | | Caution : | | | +#ifndef BASOP_NOGLOB + | In some cases the Carry flag has to be cleared or set before using | +#else | In some cases the BASOP_Carry flag has to be cleared or set before using | +#endif | operators which take into account its value. | |___________________________________________________________________________| */ +#ifndef BASOP_NOGLOB +Word32 L_sub_c( Word32 L_var1, Word32 L_var2 ) +#else /* BASOP_NOGLOB */ Word32 DEPR_L_sub_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) +#endif /* BASOP_NOGLOB */ { Word32 L_var_out; Word32 L_test; Flag carry_int = 0; +#ifndef BASOP_NOGLOB + if ( Carry ) +#else /* BASOP_NOGLOB */ if ( *Carry ) +#endif /* BASOP_NOGLOB */ { +#ifndef BASOP_NOGLOB + Carry = 0; +#else /* BASOP_NOGLOB */ *Carry = 0; +#endif /* BASOP_NOGLOB */ if ( L_var2 != MIN_32 ) { +#ifndef BASOP_NOGLOB + L_var_out = L_add_c( L_var1, -L_var2 ); +#else /* BASOP_NOGLOB */ L_var_out = DEPR_L_add_c( L_var1, -L_var2, Carry ); +#endif /* BASOP_NOGLOB */ #ifdef WMOPS multiCounter[currCounter].L_add_c--; #endif @@ -1617,7 +1795,12 @@ Word32 DEPR_L_sub_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) L_var_out = L_var1 - L_var2; if ( L_var1 > 0L ) { +#ifndef BASOP_NOGLOB + Overflow = 1; + Carry = 0; +#else /* BASOP_NOGLOB */ *Carry = 0; +#endif /* BASOP_NOGLOB */ } } } @@ -1628,23 +1811,41 @@ Word32 DEPR_L_sub_c( Word32 L_var1, Word32 L_var2, Flag *Carry ) if ( ( L_test < 0 ) && ( L_var1 > 0 ) && ( L_var2 < 0 ) ) { +#ifndef BASOP_NOGLOB + Overflow = 1; +#endif /* ! BASOP_NOGLOB */ carry_int = 0; } else if ( ( L_test > 0 ) && ( L_var1 < 0 ) && ( L_var2 > 0 ) ) { +#ifndef BASOP_NOGLOB + Overflow = 1; +#endif /* ! BASOP_NOGLOB */ carry_int = 1; } else if ( ( L_test > 0 ) && ( ( L_var1 ^ L_var2 ) > 0 ) ) { +#ifndef BASOP_NOGLOB + Overflow = 0; +#endif /* ! BASOP_NOGLOB */ carry_int = 1; } if ( L_test == MIN_32 ) { +#ifndef BASOP_NOGLOB + Overflow = 1; + Carry = carry_int; +#else /* BASOP_NOGLOB */ *Carry = carry_int; +#endif /* BASOP_NOGLOB */ } else { +#ifndef BASOP_NOGLOB + Carry = carry_int; +#else /* BASOP_NOGLOB */ *Carry = carry_int; +#endif /* BASOP_NOGLOB */ } } @@ -1736,6 +1937,7 @@ Word32 L_negate( Word32 L_var1 ) | range : 0x8000 <= var_out <= 0x7fff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB Word16 mult_ro( Word16 var1, Word16 var2, Flag *Overflow ) { Word16 var_out; @@ -1759,6 +1961,7 @@ Word16 mult_ro( Word16 var1, Word16 var2, Flag *Overflow ) return ( var_out ); } +#endif /* BASOP_NOGLOB */ Word16 mult_r( Word16 var1, Word16 var2 ) { Word16 var_out; @@ -1815,7 +2018,11 @@ Word16 mult_r( Word16 var1, Word16 var2 ) | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ +#ifndef BASOP_NOGLOB +Word32 L_shl( Word32 L_var1, Word16 var2 ) +#else /* BASOP_NOGLOB */ Word32 L_shl_o( Word32 L_var1, Word16 var2, Flag *Overflow ) +#endif /* BASOP_NOGLOB */ { Word32 L_var_out = 0L; @@ -1836,7 +2043,11 @@ Word32 L_shl_o( Word32 L_var1, Word16 var2, Flag *Overflow ) { if ( L_var1 > (Word32) 0X3fffffffL ) { +#ifndef BASOP_NOGLOB + Overflow = 1; +#else /* BASOP_NOGLOB */ *Overflow = 1; +#endif /* BASOP_NOGLOB */ L_var_out = MAX_32; break; } @@ -1844,7 +2055,11 @@ Word32 L_shl_o( Word32 L_var1, Word16 var2, Flag *Overflow ) { if ( L_var1 < (Word32) 0xc0000000L ) { +#ifndef BASOP_NOGLOB + Overflow = 1; +#else /* BASOP_NOGLOB */ *Overflow = 1; +#endif /* BASOP_NOGLOB */ L_var_out = MIN_32; break; } @@ -1864,6 +2079,7 @@ Word32 L_shl_o( Word32 L_var1, Word16 var2, Flag *Overflow ) return ( L_var_out ); } +#ifdef BASOP_NOGLOB Word32 L_shl( Word32 L_var1, Word16 var2 ) { @@ -1911,6 +2127,7 @@ Word32 L_shl( Word32 L_var1, Word16 var2 ) return ( L_var_out ); } +#endif /* BASOP_NOGLOB */ /*___________________________________________________________________________ | | @@ -1945,6 +2162,7 @@ Word32 L_shl( Word32 L_var1, Word16 var2 ) | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB Word32 L_shr_o( Word32 L_var1, Word16 var2, Flag *Overflow ) { Word32 L_var_out; @@ -1988,6 +2206,7 @@ Word32 L_shr_o( Word32 L_var1, Word16 var2, Flag *Overflow ) return ( L_var_out ); } +#endif /* BASOP_NOGLOB */ Word32 L_shr( Word32 L_var1, Word16 var2 ) { Word32 L_var_out; @@ -2144,6 +2363,7 @@ Word16 shr_r( Word16 var1, Word16 var2 ) | range : 0x0000 8000 <= L_var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB Word16 mac_ro( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) { Word16 var_out; @@ -2165,6 +2385,7 @@ Word16 mac_ro( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) return ( var_out ); } +#endif /* BASOP_NOGLOB */ Word16 mac_r( Word32 L_var3, Word16 var1, Word16 var2 ) { Word16 var_out; @@ -2225,6 +2446,7 @@ Word16 mac_r( Word32 L_var3, Word16 var1, Word16 var2 ) | range : 0x0000 8000 <= L_var_out <= 0x0000 7fff. | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB Word16 msu_ro( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) { Word16 var_out; @@ -2244,6 +2466,7 @@ Word16 msu_ro( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) return ( var_out ); } +#endif /* BASOP_NOGLOB */ Word16 msu_r( Word32 L_var3, Word16 var1, Word16 var2 ) { Word16 var_out; @@ -2519,7 +2742,11 @@ Word32 L_abs( Word32 L_var1 ) | range : 0x8000 0000 <= var_out <= 0x7fff ffff. | |___________________________________________________________________________| */ +#ifndef BASOP_NOGLOB +Word32 L_sat( Word32 L_var1 ) +#else /* BASOP_NOGLOB */ Word32 DEPR_L_sat_co( Word32 L_var1, Flag Overflow, Flag Carry ) +#endif /* BASOP_NOGLOB */ { Word32 L_var_out; @@ -2536,9 +2763,11 @@ Word32 DEPR_L_sat_co( Word32 L_var1, Flag Overflow, Flag Carry ) { L_var_out = MAX_32; } +#ifndef BASOP_NOGLOB Carry = 0; Overflow = 0; +#endif /* ! BASOP_NOGLOB */ } #ifdef WMOPS @@ -2841,6 +3070,7 @@ Word16 norm_l( Word32 L_var1 ) | | |___________________________________________________________________________| */ +#ifdef BASOP_NOGLOB Word32 L_mls_o( Word32 Lv, Word16 v, Flag *Overflow ) { Word32 Temp; @@ -2862,6 +3092,7 @@ Word32 L_mls_o( Word32 Lv, Word16 v, Flag *Overflow ) return Temp; } +#endif /* BASOP_NOGLOB */ Word32 L_mls( Word32 Lv, Word16 v ) { Word32 Temp; @@ -3020,7 +3251,11 @@ Word16 div_l( Word32 L_num, Word16 den ) | are performed if ORIGINAL_G7231 is defined. | |___________________________________________________________________________| */ +#ifndef BASOP_NOGLOB +Word16 i_mult( Word16 a, Word16 b ) +#else /* BASOP_NOGLOB */ Word16 DEPR_i_mult( Word16 a, Word16 b ) +#endif /* BASOP_NOGLOB */ { #ifdef ORIGINAL_G7231 return a * b; @@ -3113,6 +3348,7 @@ Word32 L_mult0( Word16 var1, Word16 var2 ) | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |___________________________________________________________________________ */ +#ifdef BASOP_NOGLOB Word32 L_mac0_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) { Word32 L_var_out; @@ -3132,6 +3368,7 @@ Word32 L_mac0_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) return ( L_var_out ); } +#endif /* BASOP_NOGLOB */ Word32 L_mac0( Word32 L_var3, Word16 var1, Word16 var2 ) { Word32 L_var_out; @@ -3183,6 +3420,7 @@ Word32 L_mac0( Word32 L_var3, Word16 var1, Word16 var2 ) | range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. |___________________________________________________________________________ */ +#ifdef BASOP_NOGLOB Word32 L_msu0_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) { Word32 L_var_out; @@ -3202,6 +3440,7 @@ Word32 L_msu0_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ) return ( L_var_out ); } +#endif /* BASOP_NOGLOB */ Word32 L_msu0( Word32 L_var3, Word16 var1, Word16 var2 ) { Word32 L_var_out; diff --git a/lib_com/basop32.h b/lib_com/basop32.h index 422bc7229505c661acb5f93751caa91280405451..a8a72aed04825925a8ce418730d929c571b70203 100644 --- a/lib_com/basop32.h +++ b/lib_com/basop32.h @@ -86,12 +86,17 @@ | Constants and Globals | |___________________________________________________________________________| */ +#ifndef BASOP_NOGLOB +extern Flag Overflow, Overflow2; +extern Flag Carry; +#else /* BASOP_NOGLOB */ /* DISABLED TO AVOID GLOBAL VARIABLES */ /* extern Flag BASOP_Overflow, BASOP_Overflow2; extern Flag BASOP_Carry; */ +#endif /* BASOP_NOGLOB */ #define BASOP_SATURATE_WARNING_ON #define BASOP_SATURATE_WARNING_OFF #define BASOP_SATURATE_ERROR_ON @@ -111,7 +116,23 @@ extern Flag BASOP_Carry; |___________________________________________________________________________| */ - +#ifndef BASOP_NOGLOB +Word16 add( Word16 var1, Word16 var2 ); /* Short add, 1 */ +Word16 sub( Word16 var1, Word16 var2 ); /* Short sub, 1 */ +Word16 abs_s( Word16 var1 ); /* Short abs, 1 */ +Word16 shl( Word16 var1, Word16 var2 ); /* Short shift left, 1 */ +Word16 shr( Word16 var1, Word16 var2 ); /* Short shift right, 1 */ +Word16 mult( Word16 var1, Word16 var2 ); /* Short mult, 1 */ +Word32 L_mult( Word16 var1, Word16 var2 ); /* Long mult, 1 */ +Word16 negate( Word16 var1 ); /* Short negate, 1 */ +Word16 extract_h( Word32 L_var1 ); /* Extract high, 1 */ +Word16 extract_l( Word32 L_var1 ); /* Extract low, 1 */ +Word16 round_fx( Word32 L_var1 ); /* Round, 1 */ +Word32 L_mac( Word32 L_var3, Word16 var1, Word16 var2 ); /* Mac, 1 */ +Word32 L_msu( Word32 L_var3, Word16 var1, Word16 var2 ); /* Msu, 1 */ +Word32 L_macNs( Word32 L_var3, Word16 var1, Word16 var2 ); /* Mac without + sat, 1 */ +#else /* BASOP_NOGLOB */ Word16 add( Word16 var1, Word16 var2 ); /* Short add, 1 */ Word16 sub( Word16 var1, Word16 var2 ); /* Short sub, 1 */ Word16 abs_s( Word16 var1 ); /* Short abs, 1 */ @@ -125,44 +146,97 @@ Word16 extract_l( Word32 L_var1 ); /* Word16 round_fx( Word32 L_var1 ); /* Round, 1 */ Word32 L_mac( Word32 L_var3, Word16 var1, Word16 var2 ); /* Mac, 1 */ Word32 L_msu( Word32 L_var3, Word16 var1, Word16 var2 ); /* Msu, 1 */ -Word32 DEPR_L_macNs( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry ); /* Mac without sat, 1 */ - -Word32 DEPR_L_msuNs( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry ); /* Msu without sat, 1 */ - -Word32 L_add( Word32 L_var1, Word32 L_var2 ); /* Long add, 1 */ -Word32 L_sub( Word32 L_var1, Word32 L_var2 ); /* Long sub, 1 */ -Word32 DEPR_L_add_c( Word32 L_var1, Word32 L_var2, Flag *Carry ); /* Long add with c, 2 */ -Word32 DEPR_L_sub_c( Word32 L_var1, Word32 L_var2, Flag *Carry ); /* Long sub with c, 2 */ -Word32 L_negate( Word32 L_var1 ); /* Long negate, 1 */ -Word16 mult_r( Word16 var1, Word16 var2 ); /* Mult with round, 1 */ -Word32 L_shl( Word32 L_var1, Word16 var2 ); /* Long shift left, 1 */ -Word32 L_shr( Word32 L_var1, Word16 var2 ); /* Long shift right, 1 */ -Word16 shr_r( Word16 var1, Word16 var2 ); /* Shift right with - round, 2 */ - +Word32 DEPR_L_macNs( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry ); /* Mac without + sat, 1 */ +#endif /* BASOP_NOGLOB */ + +#ifndef BASOP_NOGLOB +Word32 L_msuNs( Word32 L_var3, Word16 var1, Word16 var2 ); /* Msu without + sat, 1 */ +#else /* BASOP_NOGLOB */ +Word32 DEPR_L_msuNs( Word32 L_var3, Word16 var1, Word16 var2, Flag *Carry ); /* Msu without + sat, 1 */ +#endif /* BASOP_NOGLOB */ +#ifndef BASOP_NOGLOB +Word32 L_add( Word32 L_var1, Word32 L_var2 ); /* Long add, 1 */ +Word32 L_sub( Word32 L_var1, Word32 L_var2 ); /* Long sub, 1 */ +Word32 L_add_c( Word32 L_var1, Word32 L_var2 ); /* Long add with c, 2 */ +Word32 L_sub_c( Word32 L_var1, Word32 L_var2 ); /* Long sub with c, 2 */ +Word32 L_negate( Word32 L_var1 ); /* Long negate, 1 */ +Word16 mult_r( Word16 var1, Word16 var2 ); /* Mult with round, 1 */ +Word32 L_shl( Word32 L_var1, Word16 var2 ); /* Long shift left, 1 */ +Word32 L_shr( Word32 L_var1, Word16 var2 ); /* Long shift right, 1 */ +Word16 shr_r( Word16 var1, Word16 var2 ); /* Shift right with + round, 2 */ +#else /* BASOP_NOGLOB */ +Word32 L_add( Word32 L_var1, Word32 L_var2 ); /* Long add, 1 */ +Word32 L_sub( Word32 L_var1, Word32 L_var2 ); /* Long sub, 1 */ +Word32 DEPR_L_add_c( Word32 L_var1, Word32 L_var2, Flag *Carry ); /* Long add with c, 2 */ +Word32 DEPR_L_sub_c( Word32 L_var1, Word32 L_var2, Flag *Carry ); /* Long sub with c, 2 */ +Word32 L_negate( Word32 L_var1 ); /* Long negate, 1 */ +Word16 mult_r( Word16 var1, Word16 var2 ); /* Mult with round, 1 */ +Word32 L_shl( Word32 L_var1, Word16 var2 ); /* Long shift left, 1 */ +Word32 L_shr( Word32 L_var1, Word16 var2 ); /* Long shift right, 1 */ +Word16 shr_r( Word16 var1, Word16 var2 ); /* Shift right with + round, 2 */ +#endif /* BASOP_NOGLOB */ + +#ifndef BASOP_NOGLOB Word16 mac_r( Word32 L_var3, Word16 var1, Word16 var2 ); /* Mac with - rounding, 1 */ + rounding, 1 */ +#else /* BASOP_NOGLOB */ +Word16 mac_r( Word32 L_var3, Word16 var1, Word16 var2 ); /* Mac with + rounding, 1 */ +#endif /* BASOP_NOGLOB */ +#ifndef BASOP_NOGLOB Word16 msu_r( Word32 L_var3, Word16 var1, Word16 var2 ); /* Msu with - rounding, 1 */ -Word32 L_deposit_h( Word16 var1 ); /* 16 bit var1 -> MSB, 1 */ -Word32 L_deposit_l( Word16 var1 ); /* 16 bit var1 -> LSB, 1 */ - + rounding, 1 */ +#else /* BASOP_NOGLOB */ +Word16 msu_r( Word32 L_var3, Word16 var1, Word16 var2 ); /* Msu with + rounding, 1 */ +#endif /* BASOP_NOGLOB */ +#ifndef BASOP_NOGLOB +Word32 L_deposit_h( Word16 var1 ); /* 16 bit var1 -> MSB, 1 */ +Word32 L_deposit_l( Word16 var1 ); /* 16 bit var1 -> LSB, 1 */ +#else /* BASOP_NOGLOB */ +Word32 L_deposit_h( Word16 var1 ); /* 16 bit var1 -> MSB, 1 */ +Word32 L_deposit_l( Word16 var1 ); /* 16 bit var1 -> LSB, 1 */ +#endif /* BASOP_NOGLOB */ + +#ifndef BASOP_NOGLOB Word32 L_shr_r( Word32 L_var1, Word16 var2 ); /* Long shift right with - round, 3 */ - -Word32 L_abs( Word32 L_var1 ); /* Long abs, 1 */ -Word32 DEPR_L_sat_co( Word32 L_var1, Flag Overflow, Flag Carry ); /* Long saturation, 4 */ -Word16 norm_s( Word16 var1 ); /* Short norm, 1 */ -Word16 div_s( Word16 var1, Word16 var2 ); /* Short division, 18 */ -Word16 norm_l( Word32 L_var1 ); /* Long norm, 1 */ + round, 3 */ +#else /* BASOP_NOGLOB */ +Word32 L_shr_r( Word32 L_var1, Word16 var2 ); /* Long shift right with + round, 3 */ +#endif /* BASOP_NOGLOB */ +#ifndef BASOP_NOGLOB +Word32 L_abs( Word32 L_var1 ); /* Long abs, 1 */ +Word32 L_sat( Word32 L_var1 ); /* Long saturation, 4 */ +Word16 norm_s( Word16 var1 ); /* Short norm, 1 */ +Word16 div_s( Word16 var1, Word16 var2 ); /* Short division, 18 */ +Word16 norm_l( Word32 L_var1 ); /* Long norm, 1 */ +#else /* BASOP_NOGLOB */ +Word32 L_abs( Word32 L_var1 ); /* Long abs, 1 */ +Word32 DEPR_L_sat_co( Word32 L_var1, Flag Overflow, Flag Carry ); /* Long saturation, 4 */ +Word16 norm_s( Word16 var1 ); /* Short norm, 1 */ +Word16 div_s( Word16 var1, Word16 var2 ); /* Short division, 18 */ +Word16 norm_l( Word32 L_var1 ); /* Long norm, 1 */ +#endif /* BASOP_NOGLOB */ /* * Additional G.723.1 operators */ -Word32 L_mls( Word32, Word16 ); /* Weight FFS; currently assigned 5 */ -Word16 div_l( Word32, Word16 ); /* Weight FFS; currently assigned 32 */ -Word16 DEPR_i_mult( Word16 a, Word16 b ); /* Weight FFS; currently assigned 3 */ +#ifndef BASOP_NOGLOB +Word32 L_mls( Word32, Word16 ); /* Weight FFS; currently assigned 5 */ +Word16 div_l( Word32, Word16 ); /* Weight FFS; currently assigned 32 */ +Word16 i_mult( Word16 a, Word16 b ); /* Weight FFS; currently assigned 3 */ +#else /* BASOP_NOGLOB */ +Word32 L_mls( Word32, Word16 ); /* Weight FFS; currently assigned 5 */ +Word16 div_l( Word32, Word16 ); /* Weight FFS; currently assigned 32 */ +Word16 DEPR_i_mult( Word16 a, Word16 b ); /* Weight FFS; currently assigned 3 */ +#endif /* BASOP_NOGLOB */ /* * New shiftless operators, not used in G.729/G.723.1 @@ -170,6 +244,7 @@ Word16 DEPR_i_mult( Word16 a, Word16 b ); /* Weight FFS; currently assigned 3 */ Word32 L_mult0( Word16 v1, Word16 v2 ); /* 32-bit Multiply w/o shift 1 */ Word32 L_mac0( Word32 L_v3, Word16 v1, Word16 v2 ); /* 32-bit Mac w/o shift 1 */ Word32 L_msu0( Word32 L_v3, Word16 v1, Word16 v2 ); /* 32-bit Msu w/o shift 1 */ +#ifdef BASOP_NOGLOB /* * Overflowing operators @@ -192,6 +267,7 @@ Word32 L_msu0_o( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ); Word16 mult_ro( Word16 var1, Word16 var2, Flag *Overflow ); Word16 mac_ro( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ); Word16 msu_ro( Word32 L_var3, Word16 var1, Word16 var2, Flag *Overflow ); +#endif /* BASOP_NOGLOB */ #endif /* ifndef _BASIC_OP_H */ diff --git a/lib_com/basop_lsf_tools.c b/lib_com/basop_lsf_tools.c index b3319d95dc78e7c49911fbec1e1294587168afc4..498018c1eea64571bcf8eecbcf8c694a197b55ab 100644 --- a/lib_com/basop_lsf_tools.c +++ b/lib_com/basop_lsf_tools.c @@ -243,7 +243,10 @@ static Word16 E_LPC_f_lsp_pol_get( Word16 Ovf = 0; Word16 Q_out; Word16 m2; +#ifdef BASOP_NOGLOB Flag Overflow; +#endif /* BASOP_NOGLOB */ + Q_out = 31 - 23; move16(); @@ -297,8 +300,9 @@ static Word16 E_LPC_f_lsp_pol_get( test(); IF( Overflow > 0 && isMODE1 ) { +#ifdef BASOP_NOGLOB assert( 0 ); - +#endif /* BASOP_NOGLOB */ /* If an overflow is detected, redo the computation with 1 bit less */ Ovf = add( Ovf, 1 ); Ovf = E_LPC_f_lsp_pol_get( lsp, f, n, Ovf, isMODE1 ); diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index 5d9b6bc03f0020fd748d500e5f192651da6ba902..197fe884082c1c57d3a8b56b9da51875bc1002a9 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -240,7 +240,9 @@ static Word16 Sqrt16_common( Word16 e ) { Word16 index, frac; +#ifdef BASOP_NOGLOB Flag Overflow; +#endif /* BASOP_NOGLOB */ assert( ( m >= 0x4000 ) || ( m == 0 ) ); @@ -255,7 +257,11 @@ static Word16 Sqrt16_common( if ( m != 0 ) { BASOP_SATURATE_WARNING_OFF; +#ifndef BASOP_NOGLOB + m = mac_r( SqrtTable[index], SqrtDiffTable[index], frac ); +#else /* BASOP_NOGLOB */ m = mac_ro( SqrtTable[index], SqrtDiffTable[index], frac, &Overflow ); +#endif /* BASOP_NOGLOB */ BASOP_SATURATE_WARNING_ON; } diff --git a/lib_com/bitalloc.c b/lib_com/bitalloc.c index 951f75eacd6a85a3688b4662d156f601c01ff089..28715d184c0e24c403a492f31424a18160df7fd2 100644 --- a/lib_com/bitalloc.c +++ b/lib_com/bitalloc.c @@ -250,7 +250,9 @@ int16_t BitAllocF( Word16 tmp, exp1, exp2; Word32 Rsubband_w32_fx[NB_SFM]; /* Q15 */ Word16 B_w16_fx; +#ifdef BASOP_NOGLOB Flag Overflow; +#endif /* BASOP_NOGLOB */ set_l( Rsubband_w32_fx, 0, NB_SFM ); @@ -363,7 +365,11 @@ int16_t BitAllocF( exp1 = sub( norm_l( L_tmp1 ), 1 ); exp2 = norm_s( n ); tmp = div_s( extract_h( L_shl( L_tmp1, exp1 ) ), shl( n, exp2 ) ); /*15 + 15 + exp1 - 16 - exp2*/ - m_fx = shl_o( tmp, sub( exp2, exp1 ), &Overflow ); /*Q14*/ +#ifndef BASOP_NOGLOB + m_fx = shl( tmp, sub( exp2, exp1 ) ); /*Q14*/ +#else + m_fx = shl_o( tmp, sub( exp2, exp1 ), &Overflow ); /*Q14*/ +#endif t_fx = 0; n = 0; @@ -429,7 +435,11 @@ int16_t BitAllocF( exp1 = sub( norm_l( L_tmp2 ), 1 ); exp2 = norm_s( n ); tmp = div_s( extract_h( L_shl( L_tmp2, exp1 ) ), shl( n, exp2 ) ); /*15 + 15 + exp1 - 16 - exp2*/ - m_fx = shl_o( tmp, sub( exp2, exp1 ), &Overflow ); /*Q14*/ +#ifndef BASOP_NOGLOB + m_fx = shl( tmp, sub( exp2, exp1 ) ); /*Q14*/ +#else /* BASOP_NOGLOB */ + m_fx = shl_o( tmp, sub( exp2, exp1 ), &Overflow ); /*Q14*/ +#endif /* BASOP_NOGLOB */ if ( L_tmp1 < 0 ) { m_fx = negate( m_fx ); diff --git a/lib_com/bits_alloc.c b/lib_com/bits_alloc.c index 4b12661876343b9bc5b61c17503c01a8181055a1..58a5c8296a0993e0beedc4f20c7e094e844b1fec 100644 --- a/lib_com/bits_alloc.c +++ b/lib_com/bits_alloc.c @@ -774,9 +774,10 @@ ivas_error config_acelp1( bits -= TDM_IC_LSF_PRED_BITS; } - /* gain Q bit-budget - part 1 */ + /* gain Q bit-budget - part 1: 'Es_pred' of memory-less gain Q */ if ( ( coder_type != UNVOICED && coder_type != AUDIO && coder_type != INACTIVE && !( core_brate <= ACELP_8k00 && coder_type != TRANSITION ) ) /* mid bitrates in GC and VC, low+mid bitrates in TC */ || - ( coder_type == INACTIVE && !inactive_coder_type_flag ) /* AVQ inactive */ ) + ( coder_type == INACTIVE && !inactive_coder_type_flag ) /* AVQ inactive */ + ) { *nBits_es_Pred = Es_pred_bits_tbl[BIT_ALLOC_IDX( core_brate, coder_type, -1, -1 )]; bits -= *nBits_es_Pred; diff --git a/lib_com/bitstream.c b/lib_com/bitstream.c index 8b8790b808fd64427ff5d0b45380803ad9d67698..bd8bf608de9651819136470a456120d076bf3298 100644 --- a/lib_com/bitstream.c +++ b/lib_com/bitstream.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "stat_enc.h" @@ -47,12 +50,9 @@ #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#ifdef DEBUGGING -#include "debug.h" -#ifdef DBG_BITSTREAM_ANALYSIS +#if defined( DEBUGGING ) && defined( DBG_BITSTREAM_ANALYSIS ) #include #endif -#endif #ifdef DEBUGGING @@ -811,10 +811,10 @@ void move_indices( new_ind_list[i].id = old_ind_list[i].id; new_ind_list[i].value = old_ind_list[i].value; new_ind_list[i].nb_bits = old_ind_list[i].nb_bits; - #if defined( DEBUGGING ) && defined( DBG_BITSTREAM_ANALYSIS ) strncpy( new_ind_list[i].function_name, old_ind_list[i].function_name, 100 ); #endif + old_ind_list[i].nb_bits = -1; } } @@ -2794,11 +2794,20 @@ const char *named_indices_table[] = { * Push a new indice into the buffer *-------------------------------------------------------------------*/ +#ifdef DEBUG_BS_READ_WRITE +ivas_error push_indice_( +#else ivas_error push_indice( +#endif BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ int16_t id, /* i : ID of the indice */ uint16_t value, /* i : value of the quantized indice */ int16_t nb_bits /* i : number of bits used to quantize the indice */ +#ifdef DEBUG_BS_READ_WRITE + , + int16_t line, + const char *func +#endif ) { int16_t i; @@ -2807,6 +2816,9 @@ ivas_error push_indice( error = IVAS_ERR_OK; +#ifdef DEBUG_BS_READ_WRITE + printf( "%s: %d: %d: %d\n", func, line, nb_bits, value ); +#endif #ifdef DEBUGGING if ( nb_bits < ( 32 - 1 ) && ( value >> nb_bits ) > 0 ) { @@ -2922,7 +2934,6 @@ ivas_error push_next_indice( hBstr->ind_list[hBstr->nb_ind_tot].id = prev_id; hBstr->ind_list[hBstr->nb_ind_tot].value = value; hBstr->ind_list[hBstr->nb_ind_tot].nb_bits = nb_bits; - #if defined( DEBUGGING ) && defined( DBG_BITSTREAM_ANALYSIS ) strncpy( hBstr->ind_list[hBstr->nb_ind_tot].function_name, caller, 100 ); #endif @@ -3115,9 +3126,18 @@ uint16_t delete_indice( *-------------------------------------------------------------------*/ /*! r: value of the indice */ +#ifdef DEBUG_BS_READ_WRITE +uint16_t get_next_indice_( +#else uint16_t get_next_indice( +#endif Decoder_State *st, /* i/o: decoder state structure */ int16_t nb_bits /* i : number of bits that were used to quantize the indice */ +#ifdef DEBUG_BS_READ_WRITE + , + int16_t line, + const char *func +#endif ) { uint16_t value; @@ -3140,6 +3160,9 @@ uint16_t get_next_indice( value <<= 1; value += st->bit_stream[st->next_bit_pos + i]; } +#ifdef DEBUG_BS_READ_WRITE + printf( "%s: %d: %d: %d\n", func, line, nb_bits, value ); +#endif /* update the position in the bitstream */ st->next_bit_pos += nb_bits; @@ -3196,10 +3219,19 @@ void get_next_indice_tmp( *-------------------------------------------------------------------*/ /*! r: value of the indice */ +#ifdef DEBUG_BS_READ_WRITE +uint16_t get_indice_( +#else uint16_t get_indice( +#endif Decoder_State *st, /* i/o: decoder state structure */ int16_t pos, /* i : absolute position in the bitstream (update after the read) */ int16_t nb_bits /* i : number of bits that were used to quantize the indice */ +#ifdef DEBUG_BS_READ_WRITE + , + int16_t line, + const char *func +#endif ) { uint16_t value; @@ -3223,6 +3255,9 @@ uint16_t get_indice( value <<= 1; value += st->bit_stream[pos + i]; } +#ifdef DEBUG_BS_READ_WRITE + printf( "%s: %d: %d: %d\n", func, line, nb_bits, value ); +#endif return value; } @@ -3325,6 +3360,7 @@ void reset_indices_dec( return; } + /*-------------------------------------------------------------------* * write_indices_to_stream() * @@ -3523,7 +3559,6 @@ static ivas_error write_indices_element( } } - #if defined( DEBUGGING ) && defined( DBG_BITSTREAM_ANALYSIS ) if ( is_SCE ) /* EVS and SCE */ { @@ -3591,7 +3626,6 @@ static ivas_error write_indices_element( } #endif - /*----------------------------------------------------------------* * Clearing of indices * Reset index pointers @@ -3764,6 +3798,7 @@ void convertBytestreamToSerial( } } + /*-------------------------------------------------------------------* * decoder_selectCodec() * @@ -4441,8 +4476,8 @@ void ivas_set_bitstream_pointers( return; } - #ifdef DEBUGGING + /*-------------------------------------------------------------------* * preview_indices() * @@ -4708,8 +4743,8 @@ ivas_error preview_indices( return error; } -#endif +#endif /*-------------------------------------------------------------------* * read_indices() @@ -4762,7 +4797,7 @@ ivas_error read_indices( total_brate = (int32_t) ( num_bits * FRAMES_PER_SEC ); /* verify that a valid num bits value is present */ - /* only AMRWB, EVS or IVAS bitrates or 0 (NO DATA) are allowed */ + /* only AMRWB, EVS or IVAS bitrates or 0(NO DATA) are allowed */ if ( st_ivas->ivas_format != MONO_FORMAT ) { k = 0; @@ -4959,7 +4994,6 @@ ivas_error read_indices( /* GOOD frame */ if ( st_ivas->bfi == 0 || st_ivas->bfi == FRAMEMODE_FUTURE ) { - /* GOOD frame - convert ITU-T G.192 words to short values */ st_ivas->hDecoderConfig->ivas_total_brate = total_brate; } @@ -5000,7 +5034,6 @@ static void get_rfFrameType( return; } - /*-------------------------------------------------------------------* * get_rfFlag() * @@ -5056,7 +5089,6 @@ static void get_rfFlag( return; } - /*-------------------------------------------------------------------* * get_rf_fec_offset() * @@ -5092,7 +5124,6 @@ static void get_rf_fec_offset( return; } - /*-------------------------------------------------------------------* * get_rfTargetBits() * @@ -5141,7 +5172,6 @@ static void get_rfTargetBits( return; } - /*-------------------------------------------------------------------* * berCheck() * @@ -5169,7 +5199,6 @@ static void berCheck( return; } - /*-------------------------------------------------------------------* * getPartialCopyInfo() * diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 585bb4340682cb5aa83b443b93799d2b1302aa22..f06e880297861d3d2aeebba9850708130def7ee0 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -81,9 +81,8 @@ #define FORCE_MUSIC 101 /* debugging - force music on the command line */ #define FORCE_ACELP 102 /* debugging - force ACELP core on the command line */ #define FORCE_GSC 103 /* debugging - force GSC core on the command line */ -#define FORCE_TCX10 104 /* debugging - force TCX10 core on the command line */ -#define FORCE_TCX20 105 /* debugging - force TCX20 core on the command line */ -#define FORCE_HQ 106 /* debugging - force HQ core on the command line */ +#define FORCE_TCX 104 /* debugging - force TCX core on the command line */ +#define FORCE_HQ 105 /* debugging - force HQ core on the command line */ #define FORCE_TD_RENDERER 201 #define FORCE_CLDFB_RENDERER 202 #endif @@ -525,10 +524,8 @@ enum #define ACELP_TCX_TRANS_NS 1250000 /* Duration of the ACELP->TCX overlap - 1.25 ms */ #define L_FRAME_MAX L_FRAME48k /* Max 20ms frame size @48kHz */ #define L_FRAME_PLUS 1200 /* Max frame size (long TCX frame) */ -#define L_MDCT_OVLP_MAX NS2SA( 48000, ACELP_LOOK_NS ) /* = Max mdct overlap */ -#ifdef FIX_1320_STACK_CPE_DECODER #define L_FRAME_PLUS_INTERNAL 800 /* Max frame size (long TCX frame) at maximum internal sampling rate */ -#endif +#define L_MDCT_OVLP_MAX NS2SA( 48000, ACELP_LOOK_NS ) /* = Max mdct overlap */ #define N_TCX10_MAX 480 /* Max size of TCX10 MDCT spectrum */ #define BITS_TEC 1 /* number of bits for TEC */ #define BITS_TFA 1 /* number of bits for TTF */ @@ -746,7 +743,7 @@ typedef enum #define GAIN_PRED_ORDER 4 /* Gain quantization - prediction order for gain quantizer (only for AMR-WB IO mode) */ #define MEAN_ENER 30 /* Gain quantization - average innovation energy */ -#define DTX_THR 5 /* DTX - lp_noise threshold for DTX at higher bitrates */ +#define DTX_THR 5 /* DTX - lp_noise threshold for DTX at higher bitrates */ #define DTX_HIST_SIZE 8 /* CNG & DTX - number of last signal frames used for CNG averaging */ #define CNG_ISF_FACT 0.9f /* CNG & DTX - CNG spectral envelope smoothing factor */ diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 0a4c9e780da54124479fae0d766ae3c7430a9227..80c90d6b3152a5ace3ef0f0f205ac0c61784a356 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -176,7 +176,7 @@ typedef enum typedef struct ivas_masa_metadata_frame_struct *IVAS_MASA_METADATA_HANDLE; typedef struct ivas_masa_decoder_ext_out_meta_struct *IVAS_MASA_DECODER_EXT_OUT_META_HANDLE; -typedef struct ivas_hrtf_TDREND_HRFILT_FiltSet_struct *IVAS_DEC_HRTF_HANDLE; +typedef struct ivas_hrtf_TDREND_HRFILT_FiltSet_struct *IVAS_DEC_HRTF_TD_HANDLE; typedef struct ivas_hrtf_crend_structure *IVAS_DEC_HRTF_CREND_HANDLE; typedef struct ivas_hrtf_fastconv_struct *IVAS_DEC_HRTF_FASTCONV_HANDLE; typedef struct ivas_hrtf_parambin_struct *IVAS_DEC_HRTF_PARAMBIN_HANDLE; @@ -260,6 +260,7 @@ typedef enum } ISAR_SPLIT_REND_CODEC; + typedef struct _ISAR_SPLIT_REND_BITS_DATA { uint8_t *bits_buf; @@ -307,6 +308,7 @@ typedef enum IVAS_RENDER_TYPE_OVERRIDE_FASTCONV } IVAS_RENDER_TYPE_OVERRIDE; + #endif typedef struct _IVAS_ROOM_ACOUSTICS_CONFIG { diff --git a/lib_com/disclaimer.c b/lib_com/disclaimer.c index 451dd43e898dbe6d364ad47e2853ba2daebf0d77..170d58a3fab8bafb115909bda3390722696b10fd 100644 --- a/lib_com/disclaimer.c +++ b/lib_com/disclaimer.c @@ -47,7 +47,7 @@ int16_t print_disclaimer( FILE *fPtr ) { fprintf( fPtr, "\n==================================================================================================\n" ); - fprintf( fPtr, " \n IVAS Codec Version IVAS-FL-1.0\n" ); + fprintf( fPtr, " \n IVAS Codec Version IVAS-FL-2.0\n" ); fprintf( fPtr, " \n" ); fprintf( fPtr, " Based on EVS Codec (Floating Point) 3GPP TS26.443 Nov 04, 2021,\n" ); fprintf( fPtr, " Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0\n" ); diff --git a/lib_com/enh40.c b/lib_com/enh40.c index 570f4b211ab675c8fd924a2b0d4786ddec25c679..80ff285cece358464a7b4da491ced951553340b3 100644 --- a/lib_com/enh40.c +++ b/lib_com/enh40.c @@ -96,7 +96,9 @@ #include #include #include "stl.h" +#ifdef BASOP_NOGLOB #include +#endif /* BASOP_NOGLOB */ #define WMC_TOOL_SKIP @@ -158,7 +160,11 @@ * the range : MIN_40 <= L40_var_out <= MAX_40. * *****************************************************************************/ +#ifndef BASOP_NOGLOB +Word40 L40_shl( Word40 L40_var1, Word16 var2 ) +#else /* BASOP_NOGLOB */ Word40 L40_shl_o( Word40 L40_var1, Word16 var2, Flag *Overflow ) +#endif /* BASOP_NOGLOB */ { Word40 L40_var_out; @@ -188,15 +194,27 @@ Word40 L40_shl_o( Word40 L40_var1, Word16 var2, Flag *Overflow ) if ( L40_var_out > 0x003fffffffffLL ) #endif { +#ifndef BASOP_NOGLOB + Overflow = 1; + exit( 1 ); + /* L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out); */ +#else /* BASOP_NOGLOB */ *Overflow = 1; L40_var_out = MAX_40; +#endif /* BASOP_NOGLOB */ break; } else if ( L40_var_out < L40_constant ) { +#ifndef BASOP_NOGLOB + Overflow = 1; + exit( 2 ); + /* L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out); */ +#else /* BASOP_NOGLOB */ *Overflow = 1; L40_var_out = MIN_40; +#endif /* BASOP_NOGLOB */ break; } @@ -216,6 +234,7 @@ Word40 L40_shl_o( Word40 L40_var1, Word16 var2, Flag *Overflow ) return ( L40_var_out ); } +#ifdef BASOP_NOGLOB Word40 L40_shl( Word40 L40_var1, Word16 var2 ) { @@ -274,6 +293,7 @@ Word40 L40_shl( Word40 L40_var1, Word16 var2 ) return ( L40_var_out ); } +#endif /* BASOP_NOGLOB */ /***************************************************************************** * @@ -402,6 +422,7 @@ Word40 L40_negate( Word40 L40_var1 ) * the range : MIN_40 <= L40_var_out <= MAX_40. * *****************************************************************************/ +#ifdef BASOP_NOGLOB Word40 L40_add_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow ) { @@ -444,6 +465,7 @@ Word40 L40_add_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow ) return ( L40_var_out ); } +#endif /* BASOP_NOGLOB */ Word40 L40_add( Word40 L40_var1, Word40 L40_var2 ) { Word40 L40_var_out; @@ -453,24 +475,48 @@ Word40 L40_add( Word40 L40_var1, Word40 L40_var2 ) #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 ) if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) == 0 ) ) { +#ifndef BASOP_NOGLOB + Overflow = 1; + exit( 2 ); + /* L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out); */ +#else /* BASOP_NOGLOB */ assert( 0 ); L40_var_out = MIN_40; +#endif /* BASOP_NOGLOB */ } else if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) != 0 ) ) { +#ifndef BASOP_NOGLOB + Overflow = 1; + exit( 1 ); + /* L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out); */ +#else /* BASOP_NOGLOB */ assert( 0 ); L40_var_out = MAX_40; +#endif /* BASOP_NOGLOB */ } #else if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) == 0 ) ) { +#ifndef BASOP_NOGLOB + Overflow = 1; + exit( 2 ); + /* L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out); */ +#else /* BASOP_NOGLOB */ assert( 0 ); L40_var_out = MIN_40; +#endif /* BASOP_NOGLOB */ } else if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) != 0 ) ) { +#ifndef BASOP_NOGLOB + Overflow = 1; + exit( 1 ); + /* L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out); */ +#else /* BASOP_NOGLOB */ assert( 0 ); L40_var_out = MAX_40; +#endif /* BASOP_NOGLOB */ } #endif @@ -515,7 +561,11 @@ Word40 L40_add( Word40 L40_var1, Word40 L40_var2 ) * the range : MIN_40 <= L40_var_out <= MAX_40. * *****************************************************************************/ +#ifndef BASOP_NOGLOB +Word40 L40_sub( Word40 L40_var1, Word40 L40_var2 ) +#else /* BASOP_NOGLOB */ Word40 L40_sub_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow ) +#endif /* BASOP_NOGLOB */ { Word40 L40_var_out; @@ -524,24 +574,48 @@ Word40 L40_sub_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow ) #if defined( _MSC_VER ) && ( _MSC_VER <= 1200 ) if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) == 0 ) ) { +#ifndef BASOP_NOGLOB + Overflow = 1; + exit( 2 ); + /* L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out); */ +#else /* BASOP_NOGLOB */ *Overflow = 1; L40_var_out = MIN_40; +#endif /* BASOP_NOGLOB */ } else if ( ( ( ( L40_var1 & 0x8000000000 ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000 ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000 ) >> 39 ) != 0 ) ) { +#ifndef BASOP_NOGLOB + Overflow = 1; + exit( 1 ); + /* L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out); */ +#else /* BASOP_NOGLOB */ *Overflow = 1; L40_var_out = MAX_40; +#endif /* BASOP_NOGLOB */ } #else if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) == 0 ) ) { +#ifndef BASOP_NOGLOB + Overflow = 1; + exit( 2 ); + /* L40_var_out = L40_UNDERFLOW_OCCURED( L40_var_out); */ +#else /* BASOP_NOGLOB */ *Overflow = 1; L40_var_out = MIN_40; +#endif /* BASOP_NOGLOB */ } else if ( ( ( ( L40_var1 & 0x8000000000LL ) >> 39 ) == 0 ) && ( ( ( L40_var2 & 0x8000000000LL ) >> 39 ) != 0 ) && ( ( ( L40_var_out & 0x8000000000LL ) >> 39 ) != 0 ) ) { +#ifndef BASOP_NOGLOB + Overflow = 1; + exit( 1 ); + /* L40_var_out = L40_OVERFLOW_OCCURED( L40_var_out); */ +#else /* BASOP_NOGLOB */ *Overflow = 1; L40_var_out = MAX_40; +#endif /* BASOP_NOGLOB */ } #endif @@ -555,6 +629,7 @@ Word40 L40_sub_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow ) return ( L40_var_out ); } +#ifdef BASOP_NOGLOB Word40 L40_sub( Word40 L40_var1, Word40 L40_var2 ) { Word40 L40_var_out; @@ -594,6 +669,7 @@ Word40 L40_sub( Word40 L40_var1, Word40 L40_var2 ) return ( L40_var_out ); } +#endif /* BASOP_NOGLOB */ /***************************************************************************** * @@ -762,8 +838,12 @@ Word40 L40_min( Word40 L40_var1, Word40 L40_var2 ) * the range : 0x8000 0000 <= L_var_out <= 0x7fff ffff. * *****************************************************************************/ +#ifndef BASOP_NOGLOB +Word32 L_saturate40( Word40 L40_var1 ) +#else /* BASOP_NOGLOB */ Word32 L_saturate40_o( Word40 L40_var1, Flag *Overflow ) +#endif /* BASOP_NOGLOB */ { Word32 L_var_out; @@ -773,13 +853,21 @@ Word32 L_saturate40_o( Word40 L40_var1, Flag *Overflow ) if ( L40_var1 < UNDER_L40_var2 ) { L40_var1 = UNDER_L40_var2; +#ifndef BASOP_NOGLOB + Overflow = 1; +#else /* BASOP_NOGLOB */ *Overflow = 1; +#endif /* BASOP_NOGLOB */ } if ( L40_var1 > OVER_L40_var2 ) { L40_var1 = OVER_L40_var2; +#ifndef BASOP_NOGLOB + Overflow = 1; +#else /* BASOP_NOGLOB */ *Overflow = 1; +#endif /* BASOP_NOGLOB */ } L_var_out = L_Extract40( L40_var1 ); @@ -794,6 +882,7 @@ Word32 L_saturate40_o( Word40 L40_var1, Flag *Overflow ) return ( L_var_out ); } +#ifdef BASOP_NOGLOB Word32 L_saturate40( Word40 L40_var1 ) { Word32 L_var_out; @@ -824,6 +913,7 @@ Word32 L_saturate40( Word40 L40_var1 ) return ( L_var_out ); } +#endif /* BASOP_NOGLOB */ /***************************************************************************** * diff --git a/lib_com/enh40.h b/lib_com/enh40.h index 9c3742f3ef23b24bced88e87e71b85a8ac83baca..a258a4869353f5bfcf078e38cf47959b7f5f26f2 100644 --- a/lib_com/enh40.h +++ b/lib_com/enh40.h @@ -56,8 +56,10 @@ #include "stl.h" +#if defined( BASOP_NOGLOB ) || defined( _MSC_VER ) #define MAX_40 ( 0x0000007fffffffff ) #define MIN_40 ( 0xffffff8000000000 ) +#endif #define L40_OVERFLOW_OCCURED( L40_var1 ) ( Overflow = 1, exit( 1 ), L40_var1 ) #define L40_UNDERFLOW_OCCURED( L40_var1 ) ( Overflow = 1, exit( 2 ), L40_var1 ) @@ -109,6 +111,7 @@ Word40 L40_max( Word40 L40_var1, Word40 L40_var2 ); Word40 L40_min( Word40 L40_var1, Word40 L40_var2 ); Word32 L_saturate40( Word40 L40_var1 ); Word16 norm_L40( Word40 L40_var1 ); +#ifdef BASOP_NOGLOB /* * Overflowing operators */ @@ -116,6 +119,7 @@ Word40 L40_shl_o( Word40 L40_var1, Word16 var2, Flag *Overflow ); Word40 L40_add_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow ); Word40 L40_sub_o( Word40 L40_var1, Word40 L40_var2, Flag *Overflow ); Word32 L_saturate40_o( Word40 L40_var1, Flag *Overflow ); +#endif /* BASOP_NOGLOB */ /*#ifdef _MSC_VER*/ static __inline Word40 L40_set( Word40 L40_var1 ) { diff --git a/lib_com/env_stab.c b/lib_com/env_stab.c index 8821899402c67a4367f4e1393d18a19047ff51bd..0908ce3377dea71fe7fb952c4cbaf3f242bbc6d7 100644 --- a/lib_com/env_stab.c +++ b/lib_com/env_stab.c @@ -80,7 +80,9 @@ float env_stability( Word32 L_tmp, L_env_delta; Word16 inv_nb_sfm; float env_stab_f; +#ifdef BASOP_NOGLOB Flag Overflow; +#endif /* BASOP_NOGLOB */ if ( core_switching_flag ) { @@ -88,8 +90,12 @@ float env_stability( { mem_norm[i] = ynrm[i]; } +#ifdef BASOP_NOGLOB Overflow = 0; env_delta = shl_o( *mem_env_delta, 1, &Overflow ); +#else + env_delta = shl( *mem_env_delta, 1 ); +#endif } else { @@ -122,12 +128,23 @@ float env_stability( } exp = shr( exp, 1 ); +#ifndef BASOP_NOGLOB + env_delta = round_fx( L_shl( L_tmp, sub( 26, exp ) ) ); /* Q10 */ + L_tmp = L_mult0( 26214, env_delta ); /* 26214 is 0.1 in Q18. Q28 */ + L_tmp = L_mac( L_tmp, 29491, *mem_env_delta ); /* 29491 is 0.9 in Q15. Q28 */ + *mem_env_delta = round_fx( L_tmp ); /* Q12 */ +#else /* BASOP_NOGLOB */ env_delta = round_fx_o( L_shl_o( L_tmp, sub( 26, exp ), &Overflow ), &Overflow ); /* Q10 */ L_tmp = L_mult0( 26214, env_delta ); /* 26214 is 0.1 in Q18. Q28 */ L_tmp = L_mac_o( L_tmp, 29491, *mem_env_delta, &Overflow ); /* 29491 is 0.9 in Q15. Q28 */ *mem_env_delta = round_fx_o( L_tmp, &Overflow ); /* Q12 */ +#endif /* BASOP_NOGLOB */ Overflow = 0; - env_delta = round_fx_o( L_shl_o( L_tmp, 1, &Overflow ), &Overflow ); /* Q13 */ +#ifndef BASOP_NOGLOB + env_delta = round_fx( L_shl( L_tmp, 1 ) ); /* Q13 */ +#else /* BASOP_NOGLOB */ + env_delta = round_fx_o( L_shl_o( L_tmp, 1, &Overflow ), &Overflow ); /* Q13 */ +#endif /* BASOP_NOGLOB */ } if ( Overflow != 0 ) /* Saturated due to the above up-shifting operation. */ { diff --git a/lib_com/gs_bitallocation.c b/lib_com/gs_bitallocation.c index eddda88c32cf908b5e8a1ce166320e4dedc3a955..481458f22a02d7b9ad6e8f6869cd9a8d408372fb 100644 --- a/lib_com/gs_bitallocation.c +++ b/lib_com/gs_bitallocation.c @@ -46,14 +46,11 @@ #include "ivas_prot.h" #include "wmc_auto.h" + /*-------------------------------------------------------------------* - * Local function prototypes + * Local constants *-------------------------------------------------------------------*/ -static float Find_bit_frac( const int16_t nb_band, const int16_t remaining_bits ); - -static void reajust_bits( float *bits_per_bands, const int16_t st_band, const int16_t end_band, const int16_t sum_bit_in, const int16_t bit_bdgt_in ); - #define Q15_0_33 10922 /* 0.33 */ #define Q18_0_1 26214 /* 0.1 */ #define Q18_0_50 131072 /* 0.50 */ @@ -72,10 +69,23 @@ static void reajust_bits( float *bits_per_bands, const int16_t st_band, const in #define Q31_0_02 42949673 /* 0.02 */ #define Q31_0_17 365072220 /* 0.17 */ #define Q31_0_23 493921239 /* 0.23 */ + + +/*-------------------------------------------------------------------* + * Local function prototypes + *-------------------------------------------------------------------*/ + +static float Find_bit_frac( const int16_t nb_band, const int16_t remaining_bits ); + +static void reajust_bits( float *bits_per_bands, const int16_t st_band, const int16_t end_band, const int16_t sum_bit_in, const int16_t bit_bdgt_in ); + static Word16 Find_norm_inv( const Word32 ToDivide, Word16 *e_div ); + static Word16 Find_bit_alloc_IVAS_int( const Word32 core_brate, const Word16 GSC_IVAS_mode, const Word16 Diff_len, const Word16 nb_tot_bands, const Word16 L_frame, Word16 *bit, Word16 *max_ener_band, float *ener_vec, float *bits_per_bands ); + static Word16 maximum_fx( const Word16 *vec_fx, const Word16 lvec_fx, Word16 *max_fx ); + /*-------------------------------------------------------------------* * bands_and_bit_alloc() * @@ -213,7 +223,7 @@ void bands_and_bit_alloc( { if ( GSC_IVAS_mode > 0 ) { - nb_tot_bands = Find_bit_alloc_IVAS_int( core_brate, GSC_IVAS_mode, Diff_len, nb_tot_bands, L_frame, bit, max_ener_band, ener_vec, bits_per_bands ); + nb_tot_bands = (int16_t) Find_bit_alloc_IVAS_int( (Word32) core_brate, (Word16) GSC_IVAS_mode, (Word16) Diff_len, (Word16) nb_tot_bands, (Word16) L_frame, (Word16 *) bit, (Word16 *) max_ener_band, ener_vec, bits_per_bands ); nb_bands = nb_tot_bands; } else if ( GSC_noisy_speech ) @@ -668,7 +678,6 @@ void bands_and_bit_alloc( *nb_subbands = 0; *pvq_len = 0; } - return; } @@ -778,40 +787,48 @@ static float Find_bit_frac( return ( var_out ); } -static Word16 Find_bit_alloc_IVAS_int( /* o : Number of band to encode */ - const Word32 core_brate, /* i : core bit rate */ - const Word16 GSC_IVAS_mode, /* i : GSC IVAS mode */ - const Word16 Diff_len, /* i : Length of the difference signal (before pure spectral)*/ - const Word16 nb_tot_bands_in, /* i : total number of band */ - const Word16 L_frame, /* i : frame length */ - Word16 *bit, /* i/o: Number of bit allowed for frequency quantization */ - Word16 *max_ener_band, /* i/o: Energy based sorted order */ - float *ener_vec_io, /* i/o: Energy per band order */ - float *bits_per_bands_o /* o : Number of bit allowed per allowed sub-band Q3 */ + +/*-------------------------------------------------------------------* + * Find_bit_alloc_IVAS_int() + * + * + *-------------------------------------------------------------------*/ + +/*! r: Number of bands to encode */ +static Word16 Find_bit_alloc_IVAS_int( + const Word32 core_brate, /* i : core bit rate */ + const Word16 GSC_IVAS_mode, /* i : GSC IVAS mode */ + const Word16 Diff_len, /* i : Length of the difference signal (before pure spectral)*/ + const Word16 nb_tot_bands_in, /* i : total number of band */ + const Word16 L_frame, /* i : frame length */ + Word16 *bit, /* i/o: Number of bit allowed for frequency quantization */ + Word16 *max_ener_band, /* i/o: Energy based sorted order */ + float *ener_vec_io, /* i/o: Energy per band order */ + float *bits_per_bands_o /* o : Number of bit allowed per allowed sub-band Q3 */ ) { Word32 mp, mb, nb_bands_adj, bit_adj; Word16 nb_pulse_per_band[MBANDS_GN_BITALLOC16k]; - Word32 SWB_bit_budget; // Q0 -> Q18 + Word32 SWB_bit_budget; /* Q0 -> Q18 */ Word16 i, j, nb_bands_max, st_band, nb_tot_bands_loc, etmp; Word32 sum_bit /*Q18*/, bit_fracf /*Q18*/; Word16 d_tmp, e_div, tmp16, ener_vec[MBANDS_GN_BITALLOC16k]; Word32 Ltmp, etmp_32fx, bits_per_bands[MBANDS_GN_BITALLOC16k]; - SWB_bit_budget = *bit; // Q0 + SWB_bit_budget = *bit; /* Q0 */ st_band = 5; nb_bands_max = nb_tot_bands_in; for ( i = 0; i < MBANDS_GN; i++ ) { - ener_vec[i] = (short) ( ener_vec_io[i] ); /* Q12 -> Q12 */ + ener_vec[i] = (Word16) ( ener_vec_io[i] ); /* Q12 -> Q12 */ } if ( L_frame == L_FRAME16k ) { for ( i = MBANDS_GN; i < MBANDS_GN_BITALLOC16k; i++ ) { - ener_vec[i] = (short) ( ener_vec_io[i] * 4096.0 + 0.5f ); /* Q0 -> Q12 */ + ener_vec[i] = (Word16) ( ener_vec_io[i] * 4096.0 + 0.5f ); /* Q0 -> Q12 */ } } @@ -856,12 +873,12 @@ static Word16 Find_bit_alloc_IVAS_int( /* o : Num if ( GSC_IVAS_mode == 1 && core_brate < GSC_L_RATE_STG ) { /* nb_bands_adj = 0.0125f * SWB_bit_budget - 0.75f;*/ - nb_bands_adj = L_sub( Mpy_32_32( Q31_0_0125, L_shl( SWB_bit_budget, 18 ) ), Q18_0_75 ); // Q18 + nb_bands_adj = L_sub( Mpy_32_32( Q31_0_0125, L_shl( SWB_bit_budget, 18 ) ), Q18_0_75 ); /* Q18 */ } else if ( GSC_IVAS_mode != 2 && core_brate > GSC_H_RATE_STG ) { /*nb_bands_adj = 0.02f * SWB_bit_budget - 1.2f;*/ - nb_bands_adj = L_sub( Mpy_32_32( Q31_0_02, L_shl( SWB_bit_budget, 18 ) ), Q18_1_2 ); // Q18 + nb_bands_adj = L_sub( Mpy_32_32( Q31_0_02, L_shl( SWB_bit_budget, 18 ) ), Q18_1_2 ); /* Q18 */ } /*nb_bands_max = (int16_t)(nb_bands_max * nb_bands_adj + 0.5f);*/ @@ -937,7 +954,6 @@ static Word16 Find_bit_alloc_IVAS_int( /* o : Num nb_pulse_per_band[i] = 1; } } - for ( j = st_band; j < nb_tot_bands_loc; j++ ) { if ( j > 6 ) @@ -955,7 +971,6 @@ static Word16 Find_bit_alloc_IVAS_int( /* o : Num /* Recompute the final bit distribution for HF */ if ( nb_tot_bands_loc > st_band ) { - /* This is not bit exact because of the precision lost */ /* mb = ( SWB_bit_budget * 2 / ( nb_tot_bands_loc - st_band ) ) - mp; */ d_tmp = Find_norm_inv( L_deposit_h( sub( nb_tot_bands_loc, st_band ) ), &e_div ); mb = L_sub( L_shr( Mpy_32_16_1( L_shl( SWB_bit_budget, 1 ), d_tmp ), e_div ), mp ); /* Q18 */ @@ -972,7 +987,7 @@ static Word16 Find_bit_alloc_IVAS_int( /* o : Num bits_per_bands[max_ener_band[j]] = mb; } mb -= bit_fracf; - SWB_bit_budget -= bits_per_bands[max_ener_band[j]]; // Q18 + SWB_bit_budget -= bits_per_bands[max_ener_band[j]]; /* Q18 */ } } @@ -1009,7 +1024,6 @@ static Word16 Find_bit_alloc_IVAS_int( /* o : Num bits_per_bands[i] = Q18_112; j = add( j, add( i, 1 ) ); } - /* safety check for overage bit reallocation */ /* else if (bits_per_bands[i] + sum_bit / 3 > 112) */ else if ( L_add( bits_per_bands[i], Mpy_32_16_1( sum_bit, Q15_0_33 ) ) > Q18_112 ) @@ -1037,7 +1051,13 @@ static Word16 Find_bit_alloc_IVAS_int( /* o : Num return nb_tot_bands_loc; } -/* Find normalized 1 / ToDivide */ + +/*-------------------------------------------------------------------* + * Find_norm_inv() + * + * Find normalized 1 / ToDivide + *-------------------------------------------------------------------*/ + static Word16 Find_norm_inv( const Word32 ToDivide, Word16 *e_div ) @@ -1048,14 +1068,23 @@ static Word16 Find_norm_inv( d_tmp = round_fx( L_shl( ToDivide, e_tmp ) ); d_tmp = div_s( 16384, d_tmp ); /* 1.0 in Q14, dividend is normalize so >= 16384 as required for the division */ *e_div = sub( 14, e_tmp ); + move16(); return d_tmp; } -static Word16 maximum_fx( /* o : index of the maximum value in the input vector */ - const Word16 *vec_fx, /* i : input vector */ - const Word16 lvec_fx, /* i : length of input vector */ - Word16 *max_fx /* o : maximum value in the input vector */ + +/*-------------------------------------------------------------------* + * maximum_fx() + * + * + *-------------------------------------------------------------------*/ + +/*! r: index of the maximum value in the input vector */ +static Word16 maximum_fx( + const Word16 *vec_fx, /* i : input vector */ + const Word16 lvec_fx, /* i : length of input vector */ + Word16 *max_fx /* o : maximum value in the input vector */ ) { Word16 j, ind; diff --git a/lib_com/hq2_bit_alloc.c b/lib_com/hq2_bit_alloc.c index e74c1d880ba0aa139433d88ed1d4b8cb62dd872b..b2a65ba469aa185f2d67b5da5f99ff3b5116e99f 100644 --- a/lib_com/hq2_bit_alloc.c +++ b/lib_com/hq2_bit_alloc.c @@ -375,8 +375,10 @@ void hq2_bit_alloc_har( Word32 L_y[BANDS_MAX]; +#ifdef BASOP_NOGLOB Flag Overflow; Overflow = 0; +#endif grp_rngmax_fx[0] = 0; grp_rngmax_fx[1] = 0; @@ -642,8 +644,12 @@ void hq2_bit_alloc_har( L_temp = Mpy_32_16( L_Ravg_sub[GRP_SB - 1], sub( GRP_SB, 1 ) ); /* Qbe+0+1 */ L_temp = Mpy_32_16( L_temp, Inv_norm_sum_fx ); /* Qbe+1+QIpb+1 */ +#ifdef BASOP_NOGLOB lf_hf_ge_r_fx = round_fx_o( L_shl_o( L_temp, sub( 15 + 16, sub( add( SWB_BWE_LR_Qbe, QIns ), 30 ) ), &Overflow ), &Overflow ); Overflow = 0; /* reset BASOP Overflow */ +#else + lf_hf_ge_r_fx = round_fx( L_shl( L_temp, sub( 15 + 16, sub( add( SWB_BWE_LR_Qbe, QIns ), 30 ) ) ) ); +#endif exp_normn = norm_s( norm_sum_fx ); exp_normn = sub( exp_normn, 1 ); diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h old mode 100644 new mode 100755 index 23802a3b1ec2c91bebc0ec6a842dfb7ecdda481e..3e8521f47d8f5fc485771b6c1ce76bfaffcf783d --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -172,13 +172,8 @@ typedef enum #define JBM_CLDFB_SLOTS_IN_SUBFRAME 4 #define MAX_JBM_CLDFB_TIMESLOTS 32 #define DEFAULT_JBM_CLDFB_TIMESLOTS 16 -#ifdef JBM_MEMORY_OPT #define MAX_JBM_L_FRAME48k ( IVAS_MAX_FRAME_SIZE * 2 ) /* 1920: max. time-scaled frame buffer length (per channel) in samples */ #define MAX_JBM_L_FRAME_NS 40000000L /* 40 ms: time-scaled frame size in ns, proportional to MAX_JBM_L_FRAME48k */ -#else -#define MAX_JBM_L_FRAME48k 1920 -#define MAX_JBM_L_FRAME_NS 40000000L -#endif #define MAX_SPAR_INTERNAL_CHANNELS IVAS_SPAR_MAX_CH #define MAX_CLDFB_DIGEST_CHANNELS 3 /* == maximum of ParamISM TCs and ParamMC TCs */ @@ -234,9 +229,7 @@ typedef enum /* format signaling in SID frames */ #define SID_FORMAT_NBITS 3 /* Bit 0 | Bit 1 | Bit 2 */ /*-------|-------|------ */ -#ifdef FIX_1384_MSAN_ivas_spar_dec_open #define SID_FORMAT_NONE (-0x1) /* n/a| n/a| n/a*/ -#endif #define SID_DFT_STEREO 0x0 /* 0| 0| 0 */ #define SID_MDCT_STEREO 0x1 /* 1| 0| 0 */ #define SID_ISM 0x2 /* 0| 1| 0 */ @@ -1154,9 +1147,8 @@ enum #define MASA_TRANSP_BITS 1 #define NO_BITS_MASA_ISM_NO_OBJ 2 -#define MASA2TOTAL_THR 0.9799999f -#define MASA2TOTAL_PREC_THRESHOLD 1e-7 -#define MASA2TOTAL_PREC_INV_THRESHOLD 1e7 +#define MASA2TOTAL_THR 0.98f + #define BITS_MASA2TOTTAL_DCT0 6 #define STEP_M2T 0.1f #define STEP_M2T_FX 214748365 // Q31 @@ -1234,6 +1226,9 @@ enum #define OMASA_GAIN_EDIT_THR 0.06f /* OMASA gain change threshold */ #define OMASA_AZI_EDIT_THR 1.0f /* OMASA-DISC azimuth change threshold */ #define OMASA_ELE_EDIT_THR 2.0f /* OMASA-DISC elevation change threshold */ +#ifdef NONBE_1380_OMASA_BUILD_DIFF +#define OMASA_PAN_TBL_LEN 601 +#endif #define MASA_JBM_RINGBUFFER_FRAMES 3 @@ -1310,6 +1305,7 @@ typedef enum #define MIN_LFE_NRG 0.5f #define MCT_MAX_CHANNELS 11 /* == 7.1.4 LS channels without the LFE channel */ #define MCT_MAX_BLOCKS ( ( MCT_MAX_CHANNELS + 1 ) / CPE_CHANNELS ) /* max. number of channel pairs (MCT_MAX_CHANNELS/2) within MCT*/ + #define NBBITS_MCT_RATIO 4 #define BITRATE_MCT_RATIO_RANGE ( 1 << NBBITS_MCT_RATIO ) /* Range of the coded bitrate distribution ratio */ @@ -1364,6 +1360,7 @@ typedef struct { int16_t offset; float data[35]; } ACPL_QUANT_TABLE; + typedef struct { const int16_t (*alpha)[2]; @@ -1508,17 +1505,6 @@ typedef enum #define BINAURAL_COHERENCE_DIFFERENCE_BINS 9 /* Number of bins for direction-dependent diffuse-field binaural coherence */ -typedef enum -{ - BINAURAL_INPUT_AUDIO_CONFIG_INVALID, - BINAURAL_INPUT_AUDIO_CONFIG_COMBINED, /* 5_1, 5_1_2, 5_1_4, 7_1, 7_1_4 */ - BINAURAL_INPUT_AUDIO_CONFIG_HOA3, /* HOA3 */ - BINAURAL_INPUT_AUDIO_CONFIG_HOA2, /* HOA2 */ - BINAURAL_INPUT_AUDIO_CONFIG_FOA, /* FOA */ - BINAURAL_INPUT_AUDIO_CONFIG_UNDEFINED /* Not used */ - -} BINAURAL_INPUT_AUDIO_CONFIG; - #define HEADROT_ORDER 3 #define HEADROT_SHMAT_DIM ( ( HEADROT_ORDER + 1 ) * ( HEADROT_ORDER + 1 ) ) #define HEADROT_SHMAT_DIM2 ( HEADROT_SHMAT_DIM * HEADROT_SHMAT_DIM ) @@ -1600,13 +1586,13 @@ typedef enum #define RV_FILTER_MAX_FFT_SIZE ( 512 ) #define RV_FILTER_MAX_HISTORY ( 512 - 160 ) /* for longest history */ #define RV_LENGTH_NR_FC ( RV_FILTER_MAX_FFT_SIZE / 2 ) + 1 - #define RV_LENGTH_NR_FC_16KHZ ( RV_FILTER_MAX_FFT_SIZE / 4 ) + 1 #define IVAS_REVERB_DEFAULT_N_BANDS 31 #define LR_IAC_LENGTH_NR_FC ( RV_LENGTH_NR_FC ) #define LR_IAC_LENGTH_NR_FC_16KHZ ( RV_LENGTH_NR_FC_16KHZ ) + /*----------------------------------------------------------------------------------* * FB mixer constants *----------------------------------------------------------------------------------*/ diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index 092e8494007a73810920bdf89cea7fa6b91b34a8..c48931391c5a29360c9f598e323bd8651a1fd9d4 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -162,8 +162,7 @@ ivas_error ivas_dirac_config( hConfig->dec_param_estim = FALSE; if ( ivas_format == SBA_FORMAT || ivas_format == SBA_ISM_FORMAT ) /* skip for MASA decoder */ { - if ( ( error = ivas_dirac_sba_config( hQMetaData, element_mode, ivas_total_brate, sba_order, hConfig->nbands - spar_dirac_split_band, - ivas_format ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_dirac_sba_config( hQMetaData, element_mode, ivas_total_brate, sba_order, hConfig->nbands - spar_dirac_split_band, ivas_format ) ) != IVAS_ERR_OK ) { return error; } @@ -343,7 +342,7 @@ void ivas_get_dirac_sba_max_md_bits( { *bits_frame_nominal = ACELP_16k40 / FRAMES_PER_SEC; *metadata_max_bits = 103; - /* OSBA needs an additional 2-bits safety margin to avoid acelp crashes */ + /* OSBA needs an additional 5-bits safety margin to avoid acelp crashes */ if ( ivas_format == SBA_ISM_FORMAT ) { ( *metadata_max_bits ) -= 7; @@ -402,8 +401,7 @@ ivas_error ivas_dirac_sba_config( int16_t *element_mode, /* i/o: element mode of the core coder */ int32_t sba_total_brate, /* i : SBA total bitrate */ const int16_t sba_order, /* i : Ambisonic (SBA) order */ - const int16_t nbands /* i : number of frequency bands */ - , + const int16_t nbands, /* i : number of frequency bands */ IVAS_FORMAT ivas_format ) { int16_t nbands_coded; @@ -463,8 +461,7 @@ ivas_error ivas_dirac_sba_config( } } - ivas_get_dirac_sba_max_md_bits( sba_total_brate, &hQMetaData->bits_frame_nominal, &hQMetaData->metadata_max_bits, &hQMetaData->qmetadata_max_bit_req, hQMetaData->q_direction[0].cfg.nbands, - ivas_format ); + ivas_get_dirac_sba_max_md_bits( sba_total_brate, &hQMetaData->bits_frame_nominal, &hQMetaData->metadata_max_bits, &hQMetaData->qmetadata_max_bit_req, hQMetaData->q_direction[0].cfg.nbands, ivas_format ); return error; } diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h index c6d18125e296bfbb0310733888cb81a336bc98d5..4a5249934ce8cd4167a9d3a39b410dc9c9bee7b2 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -134,9 +134,7 @@ typedef enum IVAS_ERR_BITSTREAM_READER_INVALID_FORMAT, IVAS_ERR_NO_FILE_OPEN, IVAS_ERR_SAMPLING_RATE_UNKNOWN, -#ifdef FIX_1370_EXTERNAL_ORIENTATION_CHECK IVAS_ERR_EXTERNAL_ORIENTATION_INVALID_FORMAT, -#endif /*----------------------------------------* * renderer (lib_rend only) * @@ -153,6 +151,14 @@ typedef enum IVAS_ERR_LC3PLUS_INVALID_BITRATE, IVAS_ERR_INVALID_SPLIT_REND_CONFIG, + /*----------------------------------------* + * rtp errors * + *----------------------------------------*/ + IVAS_ERR_RTP_UNDERFLOW = 0x7000, + IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, + IVAS_ERR_RTP_UNPACK_PI_DATA, + IVAS_ERR_RTP_UNSUPPORTED_FRAME, + /*----------------------------------------* * unknown error * *----------------------------------------*/ @@ -274,10 +280,8 @@ static inline const char *ivas_error_to_string( ivas_error error_code ) return "Invalid input format"; case IVAS_ERR_INVALID_INDEX: return "Invalid index"; -#ifdef FIX_1370_EXTERNAL_ORIENTATION_CHECK case IVAS_ERR_EXTERNAL_ORIENTATION_INVALID_FORMAT: return "Euler angles were detected in the input but only Quaternions are supported"; -#endif default: break; } @@ -292,6 +296,22 @@ static inline const char *ivas_error_to_string( ivas_error error_code ) { return "data error"; } + if ( ( error_code & 0x7000 ) == 0x7000 ) + { + switch ( error_code ) + { + case IVAS_ERR_RTP_UNDERFLOW: + return "RTP Undeflow in reading frame/packet"; + case IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE: + return "Output buffer size is insufficient"; + case IVAS_ERR_RTP_UNPACK_PI_DATA: + return "Unpacking PI data failure"; + case IVAS_ERR_RTP_UNSUPPORTED_FRAME: + return "Unsupported RTP frame"; + default: + return "rtp error"; + } + } return "Unknown error"; } diff --git a/lib_com/ivas_error_utils.h b/lib_com/ivas_error_utils.h index 27bb18990b3dc4c07916da83c16911f4721fc5ac..a5a8ac51e36c9d53c37fa6a3cd7d21e92d1aee24 100644 --- a/lib_com/ivas_error_utils.h +++ b/lib_com/ivas_error_utils.h @@ -30,6 +30,9 @@ *******************************************************************************************************/ +#ifndef IVAS_ERROR_UTILS_H +#define IVAS_ERROR_UTILS_H + #include "options.h" #include @@ -42,9 +45,6 @@ #include #endif -#ifndef IVAS_ERROR_UTILS_H -#define IVAS_ERROR_UTILS_H - /* * Usage: * @@ -83,7 +83,6 @@ static inline ivas_error ivas_error_wrapper( const ivas_error error_code, const va_end( args ); fprintf( stderr, "\n\nIn function: %s(), %s:%d\n\n", function, file, line ); - // assert( 0 ); return error_code; } diff --git a/lib_com/ivas_mc_param_com.c b/lib_com/ivas_mc_param_com.c index 7029851d88d059fc1a088b03296f01a1e0f28b2c..cc2ee73c96743bc042e728ec6a3cce21a9dae620 100644 --- a/lib_com/ivas_mc_param_com.c +++ b/lib_com/ivas_mc_param_com.c @@ -128,7 +128,6 @@ void ivas_param_mc_metadata_open( hMetadataPMC->ild_mapping_conf = ivas_param_mc_conf[config_index].ild_mapping_conf; hMetadataPMC->ild_factors = ivas_param_mc_conf[config_index].ild_factors; - /* init remaining flags and indices */ hMetadataPMC->param_frame_idx = 0; hMetadataPMC->bAttackPresent = 0; diff --git a/lib_com/ivas_omasa_com.c b/lib_com/ivas_omasa_com.c index 4042dd959b6e5a5e0ce4c18ca96f9685c118933e..a66e0e5c6b90130930482c74ef2b0d8da3359b88 100644 --- a/lib_com/ivas_omasa_com.c +++ b/lib_com/ivas_omasa_com.c @@ -61,7 +61,11 @@ #define GAMMA_ISM_MEDIUM_IMP4 1.0f #define GAMMA_ISM_HIGH_IMP4 1.2f - +#ifdef NONBE_1380_OMASA_BUILD_DIFF +#define PAN_MAX_DEG 30.0f +#define ONE_OVER_PAN_STEP_DEG 10.0f +#define SIN_LS_ANGLE 0.5f /* sinf( 30.0f * PI_OVER_180 ) */ +#endif /*--------------------------------------------------------------- * ivas_omasa_ism_mode_select() * @@ -496,6 +500,64 @@ void ivas_get_stereo_panning_gains( const float eleDeg, float panningGains[2] ) { +#ifdef NONBE_1380_OMASA_BUILD_DIFF + float aziPlusEle, aziMinusEle, y; + + /* use identity sin(A+B) + sin(A−B) = 2 sinA cosB */ + aziPlusEle = aziDeg + eleDeg; + aziMinusEle = aziDeg - eleDeg; + + /* wrap into -180..+180 */ + while ( aziPlusEle > 180.0f ) + { + aziPlusEle -= 360.0f; + } + while ( aziPlusEle < -180.0f ) + { + aziPlusEle += 360.0f; + } + while ( aziMinusEle > 180.0f ) + { + aziMinusEle -= 360.0f; + } + while ( aziMinusEle < -180.0f ) + { + aziMinusEle += 360.0f; + } + + /* compute Y-coordinate corresponding to the azimuth and elevation: y = sin(azi) * cos(ele) = (sin(azi+ele) + sin(azi-ele)) / 2 */ + y = ( sinf( aziPlusEle * PI_OVER_180 ) + sinf( aziMinusEle * PI_OVER_180 ) ) * 0.5f; + + if ( y >= SIN_LS_ANGLE ) + { /* Left side */ + panningGains[0] = 1.0f; + panningGains[1] = 0.0f; + } + else if ( y <= -SIN_LS_ANGLE ) + { /* Right side */ + panningGains[0] = 0.0f; + panningGains[1] = 1.0f; + } + else /* Tangent panning law */ + { + /* from sin(angle) to index assuming range -30..+30 degrees with 0.1-degree spacing */ + float angleDeg, pos; + int16_t idx; + + /* Convert azi and ele to an azi value of the cone of confusion */ + angleDeg = asinf( y ) * _180_OVER_PI; + angleDeg = fmaxf( fminf( angleDeg, PAN_MAX_DEG ), -PAN_MAX_DEG ); + + /* compute the panning gains from the mapped azimuth using a look-up table */ + pos = ( angleDeg + PAN_MAX_DEG ) * ONE_OVER_PAN_STEP_DEG; /* ideal floating index */ + idx = (int16_t) roundf( pos ); + + idx = max( 0, min( idx, OMASA_PAN_TBL_LEN - 1 ) ); + + panningGains[0] = ivas_tan_panning_gain_tbl[idx]; + panningGains[1] = ivas_tan_panning_gain_tbl[OMASA_PAN_TBL_LEN - 1 - idx]; + } +#else float aziRad, eleRad; float y, mappedX, aziRadMapped, A, A2, A3; const float LsAngleRad = 30.0f * PI_OVER_180; @@ -524,6 +586,7 @@ void ivas_get_stereo_panning_gains( panningGains[0] = sqrtf( A3 ); panningGains[1] = sqrtf( 1.0f - A3 ); } +#endif return; } diff --git a/lib_com/ivas_osba_com.c b/lib_com/ivas_osba_com.c index ae89edcfc58213869f6b6dd8aaab0a684748a942..70065e87774324e34f757d300a1fce054d13c5da 100644 --- a/lib_com/ivas_osba_com.c +++ b/lib_com/ivas_osba_com.c @@ -55,8 +55,6 @@ ISM_MODE ivas_osba_ism_mode_select( ism_mode = ISM_SBA_MODE_DISC; } break; - - case 2: case 3: case 4: diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h old mode 100644 new mode 100755 index 9e3858351046f4875ccb606273e477788de15c7d..d05817443d721c58f7474044e547beb201260aaf --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -205,9 +205,6 @@ ivas_error pre_proc_front_ivas( const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ const int32_t last_ivas_total_brate, /* i : last IVAS total bitrate */ const int32_t ivas_total_brate /* i : IVAS total bitrate */ -#ifdef DEBUG_MODE_INFO - , const int16_t ch_idx -#endif ); ivas_error pre_proc_ivas( @@ -262,7 +259,6 @@ uint32_t ivas_syn_output( int16_t *synth_out /* o : integer 16 bits synthesis signal */ ); -#ifdef JBM_MEMORY_OPT void ivas_buffer_interleaved_to_deinterleaved( float *audio, /* i/o: audio buffer */ const int16_t n_channels, /* i : number of channels */ @@ -276,14 +272,7 @@ void ivas_buffer_deinterleaved_to_interleaved( const int16_t frame_length, /* i : frame length (one channel) */ float *audio_out /* o : interleaved audio buffer */ ); -#else -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 */ ); @@ -319,26 +308,11 @@ ivas_error ivas_init_decoder( ivas_error ivas_output_buff_dec( float *p_output_f[], /* i/o: output audio buffers */ -#ifdef FIX_1330_JBM_MEMORY const int16_t nchan_out_buff, /* i : number of output channels */ const int16_t Opt_tsm, /* i : TSM option flag */ DECODER_TC_BUFFER_HANDLE hTcBuffer /* i : TSM buffer handle */ -#else - const int16_t nchan_out_buff_old, /* i : previous frame number of output channels*/ - const int16_t nchan_out_buff /* i : number of output channels */ -#endif ); -/*! r: flag to indicate if split rendering is enabled */ -int16_t is_split_rendering_enabled( - const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ - const IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* i : Render config data structure */ -); - -ivas_error get_channel_config( - const AUDIO_CONFIG config, - char *str ); - ivas_error stereo_dmx_evs_init_encoder( STEREO_DMX_EVS_ENC_HANDLE *hStereoDmxEVS, /* o : Stereo downmix for EVS encoder handle */ const int32_t input_Fs /* i : input sampling rate */ @@ -358,7 +332,7 @@ ivas_error ivas_dec_get_format( ); ivas_error ivas_dec_setup( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); ivas_error create_sce_dec( @@ -795,7 +769,6 @@ int16_t get_igf_startline( float rand_triangular_signed( int16_t *seed ); - Word16 matrix_product_fx( const Word32 *X_fx, /* i : left hand matrix Qx*/ const Word16 rowsX, /* i : number of rows of the left hand matrix Q0*/ @@ -821,10 +794,12 @@ Word16 matrix_product_q30_fx( ); #ifndef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG + void dtx_read_padding_bits( DEC_CORE_HANDLE st, const int16_t num_bits ); + #endif void ivas_apply_non_diegetic_panning( float *input_f, /* i : non-diegetic object */ @@ -833,7 +808,19 @@ void ivas_apply_non_diegetic_panning( const int16_t output_frame /* i : output frame length per channel */ ); +#ifdef IVAS_RTPDUMP +void QuaternionProduct( + const IVAS_QUATERNION q1, + const IVAS_QUATERNION q2, + IVAS_QUATERNION *const r +); + +void QuaternionInverse( + const IVAS_QUATERNION q, + IVAS_QUATERNION *const r +); +#endif /*----------------------------------------------------------------------------------* * JBM prototypes *----------------------------------------------------------------------------------*/ @@ -868,10 +855,6 @@ void 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*/ -#ifndef JBM_MEMORY_OPT - , - float *data /* i/o: time-scaled transport channels */ -#endif ); void ivas_dec_prepare_renderer( @@ -1148,7 +1131,7 @@ void ivas_ism_dec_digest_tc( void ivas_param_ism_dec_digest_tc( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const uint16_t nCldfbSlots, /* i : number of CLDFB slots in transport channels */ - float *p_data_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ + float *p_data_f[] /* i : synthesized core-coder transport channels/DirAC output */ ); void ivas_param_ism_dec_dequant_md( @@ -2964,8 +2947,8 @@ int16_t check_bounds_s( ); void set_zero_l( - float *vec, /* o : input vector */ - const uint32_t lvec /* i : length of the vector */ + float *vec, /* o : input vector */ + const uint32_t lvec /* i : length of the vector */ ); ivas_error stereo_memory_enc( @@ -3248,9 +3231,9 @@ void reset_metadata_spatial( void ivas_qmetadata_enc_sid_encode( BSTR_ENC_HANDLE hMetaData, /* i/o: metadata bitstream handle */ IVAS_QMETADATA *q_metadata, /* i/o: metadata handle */ - const int16_t masa_sid_descriptor, /* i : description of MASA SID coding structure*/ - const int16_t nchan_transport, /* i : number of transport channels */ - const int16_t ivas_format /* i : ivas format */ + const int16_t masa_sid_descriptor, /* i : description of MASA SID coding structure*/ + const int16_t nchan_transport, /* i : number of transport channels */ + const int16_t ivas_format /* i : ivas format */ ); /*! r: number of bits read */ @@ -3532,6 +3515,7 @@ ivas_error ivas_cldfb_dec_reconfig( int16_t numCldfbAnalyses_old, /* i : number of CLDFB analysis instances in previous frame */ const int16_t numCldfbSyntheses_old /* i : number of CLDFB synthesis instances in previous frame */ ); + /*! r: Ambisonic (SBA) order used for analysis and coding */ int16_t ivas_sba_get_analysis_order( const int32_t ivas_total_brate, /* i : IVAS total bitrate */ @@ -3550,7 +3534,7 @@ int16_t ivas_sba_get_nchan_metadata( const int32_t ivas_total_brate /* i : IVAS total bitrate */ ); -/*! r: number of bits in SBA SID frame */ +/*! r: number of bits in SBA SPAR SID frame */ int16_t ivas_sba_spar_sid_bitlen( const int16_t nchan_transport /* i : number of transport channels */ ); @@ -3656,8 +3640,8 @@ ivas_error ivas_dirac_enc( const int16_t input_frame, /* i : input frame length */ const int16_t dtx_vad, /* i : DTX vad flag */ const IVAS_FORMAT ivas_format, /* i : ivas format */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int16_t hodirac_flag /* i : hodirac flag */ + const int16_t nchan_transport, /* i : number of transport channels */ + const int16_t hodirac_flag /* i : hodirac flag */ ); ivas_error ivas_dirac_config( @@ -3681,9 +3665,8 @@ void ivas_get_dirac_sba_max_md_bits( int16_t *bits_frame_nominal, int16_t *metadata_max_bits, int16_t *qmetadata_max_bit_req, - const int16_t nbands - , - IVAS_FORMAT ivas_format + const int16_t nbands, + IVAS_FORMAT ivas_format ); ivas_error ivas_dirac_sba_config( @@ -3691,9 +3674,8 @@ ivas_error ivas_dirac_sba_config( int16_t *element_mode, /* o : element mode of the core coder */ int32_t sba_total_brate, /* i : SBA total bitrate */ const int16_t sba_order, /* i : Ambisonic (SBA) order */ - const int16_t nbands /* i : number of frequency bands */ - , - IVAS_FORMAT ivas_format + const int16_t nbands, /* i : number of frequency bands */ + IVAS_FORMAT ivas_format ); ivas_error ivas_dirac_dec_config( @@ -3714,7 +3696,7 @@ void ivas_dirac_dec_read_BS( int16_t *nb_bits, /* o : number of bits read */ const int16_t last_bit_pos, /* i : last read bitstream position */ const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */ - const int16_t nchan_transport, /* i : number of transport channels */ + const int16_t nchan_transport, /* i : number of transport channels */ int16_t *dirac_to_spar_md_bands /* o : DirAC->SPAR MD bands */ ); @@ -3744,13 +3726,8 @@ void ivas_dirac_dec_render_sf( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ const int16_t nchan_transport, /* i : number of transport channels */ -#ifdef FIX_1319_STACK_SBA_DECODER float *pppQMfFrame_ts_re[HOA3_CHANNELS][CLDFB_NO_COL_MAX], float *pppQMfFrame_ts_im[HOA3_CHANNELS][CLDFB_NO_COL_MAX] -#else - 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] -#endif ); void computeDiffuseness_mdft( @@ -3910,7 +3887,7 @@ void ivas_param_mc_dec_digest_tc( void ivas_param_mc_dec_prepare_renderer( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint8_t nCldfbSlots /* i : number of CLDFB slots in transport channels */ + const uint8_t nCldfbSlots /* i : number of CLDFB slots in the transport channels */ ); void ivas_param_mc_dec_render( @@ -4387,6 +4364,7 @@ void ivas_spar_dec_upmixer_sf( float *output[], /* o : output audio channels */ const int16_t nchan_internal /* i : number of internal channels */ ); + /* MD module */ ivas_error ivas_spar_md_enc_open( ivas_spar_md_enc_state_t **hMdEnc, /* i/o: SPAR MD encoder handle */ @@ -5199,7 +5177,7 @@ ivas_error ivas_allocate_binaural_hrtf( void ivas_binRenderer( BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ - const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle */ const int16_t numTimeSlots, /* i : number of time slots to process */ #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG @@ -5671,7 +5649,6 @@ void ivas_osba_stereo_add_channels( const float gain, /* i : gain bed value */ const int16_t nchan_out, /* i : number of output channels */ const int16_t nchan_ism, /* i : number of ISM channels */ - const int16_t ism_mode, /* i : ISM mode */ const int16_t n_samples_to_render /* i : output frame length per channel */ ); @@ -5680,8 +5657,8 @@ void ivas_osba_data_close( ); ISM_MODE ivas_osba_ism_mode_select( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t nchan_ism /* i : number of input ISM's */ + const int32_t ivas_total_brate, /* i : IVAS total bitrate */ + const int16_t nchan_ism /* i : number of input ISM's */ ); @@ -5848,7 +5825,7 @@ void ivas_omasa_render_objects_from_mix( ); void ivas_omasa_gain_masa_tc( - float *output[], /* i/o : output synthesis signal */ + float *output[], /* i/o: output synthesis signal */ const float gainMasa, /* i : gain for MASA transport channels */ const int16_t nchan_transport_ism, /* i : number of ISM TCs */ const int16_t output_frame /* i : output frame length per channel */ @@ -5884,12 +5861,7 @@ void ivas_omasa_separate_object_render_jbm( const uint16_t nSamplesRendered, /* i : number of samples rendered */ float input_f[][L_FRAME48k], /* i : separated object signal */ float *output_f[], /* o : rendered time signal */ -#ifdef FIX_1330_JBM_MEMORY const int16_t subframes_rendered /* i : number of subframes rendered */ -#else - const int16_t subframes_rendered, /* i : number of subframes rendered */ - const int16_t slots_rendered /* i : number of CLDFB slots rendered */ -#endif ); void ivas_omasa_encode_masa_to_total( diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c index 3ef13d15057217f389e1124b04e7df43ffa6ee46..039dee13c5bb829a839ba2e29eef384e4a318204 100644 --- a/lib_com/ivas_rom_com.c +++ b/lib_com/ivas_rom_com.c @@ -1882,7 +1882,6 @@ const float ivas_param_mc_dmx_fac_CICP19_3tc[36] = 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f /*Ct*/ }; - /* Coefficient for Parametric MC ILD factorization */ const float ivas_param_mc_ild_fac_CICP6_2tc[6] = { @@ -2825,7 +2824,6 @@ const Word32 dct12_fx[12 * 12] = { // Q31 619978560, -335436960, 0, 335436960, -619978560, 810030848, -876602816, 810030848, -619978560, 335436960, 619978560, -869301376, 846752832, -810030848, 759350208, -695569984, 619978560, -533649696, 438301408, -335436960, 226989024, -114460880 }; - const float dct4[4*4] = { 0.5000f, 0.6533f, 0.5000f, 0.2706f, @@ -2871,6 +2869,133 @@ const float dct12[12*12]= 0.2887f, -0.4048f, 0.3943f, -0.3772f, 0.3536f, -0.3239f, 0.2887f, -0.2485f, 0.2041f, -0.1562f, 0.1057f, -0.0533f }; +#ifdef NONBE_1380_OMASA_BUILD_DIFF +const float ivas_tan_panning_gain_tbl[OMASA_PAN_TBL_LEN] = +{ + 0.0000000f, 0.0020142f, 0.0040283f, 0.0060425f, 0.0080872f, + 0.0101013f, 0.0121460f, 0.0141907f, 0.0162354f, 0.0182800f, + 0.0203552f, 0.0223999f, 0.0244751f, 0.0265198f, 0.0285950f, + 0.0306702f, 0.0327454f, 0.0348206f, 0.0369263f, 0.0390015f, + 0.0411072f, 0.0432129f, 0.0453186f, 0.0474243f, 0.0495300f, + 0.0516357f, 0.0537415f, 0.0558777f, 0.0580139f, 0.0601196f, + 0.0622559f, 0.0643921f, 0.0665588f, 0.0686951f, 0.0708313f, + 0.0729980f, 0.0751648f, 0.0773315f, 0.0794983f, 0.0816650f, + 0.0838318f, 0.0859985f, 0.0881958f, 0.0903625f, 0.0925598f, + 0.0947571f, 0.0969543f, 0.0991516f, 0.1013489f, 0.1035767f, + 0.1057739f, 0.1080017f, 0.1102295f, 0.1124573f, 0.1146851f, + 0.1169128f, 0.1191406f, 0.1213684f, 0.1236267f, 0.1258850f, + 0.1281128f, 0.1303711f, 0.1326294f, 0.1348877f, 0.1371765f, + 0.1394348f, 0.1416931f, 0.1439819f, 0.1462708f, 0.1485596f, + 0.1508484f, 0.1531372f, 0.1554260f, 0.1577148f, 0.1600342f, + 0.1623230f, 0.1646423f, 0.1669617f, 0.1692505f, 0.1715698f, + 0.1739197f, 0.1762390f, 0.1785583f, 0.1809082f, 0.1832275f, + 0.1855774f, 0.1879272f, 0.1902466f, 0.1925964f, 0.1949768f, + 0.1973267f, 0.1996765f, 0.2020569f, 0.2044067f, 0.2067871f, + 0.2091370f, 0.2115173f, 0.2138977f, 0.2162781f, 0.2186584f, + 0.2210693f, 0.2234497f, 0.2258301f, 0.2282410f, 0.2306519f, + 0.2330322f, 0.2354431f, 0.2378540f, 0.2402649f, 0.2426758f, + 0.2450867f, 0.2475281f, 0.2499390f, 0.2523499f, 0.2547913f, + 0.2572327f, 0.2596436f, 0.2620850f, 0.2645264f, 0.2669678f, + 0.2694092f, 0.2718506f, 0.2742920f, 0.2767639f, 0.2792053f, + 0.2816772f, 0.2841187f, 0.2865906f, 0.2890320f, 0.2915039f, + 0.2939758f, 0.2964478f, 0.2989197f, 0.3013916f, 0.3038635f, + 0.3063354f, 0.3088074f, 0.3113098f, 0.3137817f, 0.3162537f, + 0.3187561f, 0.3212280f, 0.3237305f, 0.3262329f, 0.3287048f, + 0.3312073f, 0.3337097f, 0.3362122f, 0.3387146f, 0.3412170f, + 0.3437195f, 0.3462219f, 0.3487244f, 0.3512268f, 0.3537292f, + 0.3562317f, 0.3587646f, 0.3612671f, 0.3637695f, 0.3663025f, + 0.3688049f, 0.3713074f, 0.3738403f, 0.3763428f, 0.3788757f, + 0.3814087f, 0.3839111f, 0.3864441f, 0.3889465f, 0.3914795f, + 0.3940125f, 0.3965149f, 0.3990479f, 0.4015808f, 0.4041138f, + 0.4066162f, 0.4091492f, 0.4116821f, 0.4142151f, 0.4167175f, + 0.4192505f, 0.4217834f, 0.4243164f, 0.4268188f, 0.4293518f, + 0.4318848f, 0.4344177f, 0.4369202f, 0.4394531f, 0.4419861f, + 0.4445190f, 0.4470215f, 0.4495544f, 0.4520874f, 0.4545898f, + 0.4571228f, 0.4596558f, 0.4621582f, 0.4646912f, 0.4671936f, + 0.4697266f, 0.4722290f, 0.4747620f, 0.4772644f, 0.4797668f, + 0.4822998f, 0.4848022f, 0.4873047f, 0.4898071f, 0.4923096f, + 0.4948425f, 0.4973450f, 0.4998474f, 0.5023193f, 0.5048218f, + 0.5073242f, 0.5098267f, 0.5123291f, 0.5148010f, 0.5173035f, + 0.5197754f, 0.5222778f, 0.5247498f, 0.5272217f, 0.5297241f, + 0.5321960f, 0.5346680f, 0.5371399f, 0.5396118f, 0.5420837f, + 0.5445251f, 0.5469971f, 0.5494385f, 0.5519104f, 0.5543518f, + 0.5568237f, 0.5592651f, 0.5617065f, 0.5641479f, 0.5665894f, + 0.5690002f, 0.5714417f, 0.5738831f, 0.5762939f, 0.5787048f, + 0.5811462f, 0.5835571f, 0.5859680f, 0.5883789f, 0.5907593f, + 0.5931702f, 0.5955505f, 0.5979614f, 0.6003418f, 0.6027222f, + 0.6051025f, 0.6074829f, 0.6098633f, 0.6122131f, 0.6145935f, + 0.6169434f, 0.6192932f, 0.6216431f, 0.6239929f, 0.6263428f, + 0.6286621f, 0.6309814f, 0.6333313f, 0.6356506f, 0.6379700f, + 0.6402588f, 0.6425781f, 0.6448669f, 0.6471863f, 0.6494751f, + 0.6517639f, 0.6540527f, 0.6563110f, 0.6585999f, 0.6608582f, + 0.6631165f, 0.6653748f, 0.6676025f, 0.6698608f, 0.6720886f, + 0.6743164f, 0.6765442f, 0.6787720f, 0.6809998f, 0.6831970f, + 0.6853943f, 0.6875916f, 0.6897888f, 0.6919861f, 0.6941528f, + 0.6963196f, 0.6984863f, 0.7006531f, 0.7027893f, 0.7049561f, + 0.7070923f, 0.7092285f, 0.7113647f, 0.7134705f, 0.7155762f, + 0.7177124f, 0.7197876f, 0.7218933f, 0.7239685f, 0.7260742f, + 0.7281494f, 0.7301941f, 0.7322693f, 0.7343140f, 0.7363586f, + 0.7384033f, 0.7404480f, 0.7424622f, 0.7444763f, 0.7464905f, + 0.7485046f, 0.7504883f, 0.7524719f, 0.7544556f, 0.7564392f, + 0.7583923f, 0.7603455f, 0.7622986f, 0.7642517f, 0.7662048f, + 0.7681274f, 0.7700500f, 0.7719421f, 0.7738647f, 0.7757568f, + 0.7776489f, 0.7795410f, 0.7814026f, 0.7832642f, 0.7851257f, + 0.7869873f, 0.7888184f, 0.7906494f, 0.7924805f, 0.7943115f, + 0.7961121f, 0.7979126f, 0.7997131f, 0.8015137f, 0.8032837f, + 0.8050537f, 0.8068237f, 0.8085632f, 0.8103027f, 0.8120422f, + 0.8137817f, 0.8154907f, 0.8171997f, 0.8189087f, 0.8206177f, + 0.8222961f, 0.8239746f, 0.8256531f, 0.8273010f, 0.8289795f, + 0.8306274f, 0.8322449f, 0.8338928f, 0.8355103f, 0.8370972f, + 0.8387146f, 0.8403015f, 0.8418884f, 0.8434753f, 0.8450317f, + 0.8465881f, 0.8481445f, 0.8497009f, 0.8512268f, 0.8527527f, + 0.8542786f, 0.8557739f, 0.8572693f, 0.8587646f, 0.8602600f, + 0.8617249f, 0.8631897f, 0.8646545f, 0.8660889f, 0.8675232f, + 0.8689575f, 0.8703918f, 0.8717957f, 0.8731995f, 0.8746033f, + 0.8759766f, 0.8773804f, 0.8787231f, 0.8800964f, 0.8814392f, + 0.8827820f, 0.8841248f, 0.8854675f, 0.8867798f, 0.8880920f, + 0.8893738f, 0.8906860f, 0.8919678f, 0.8932190f, 0.8945007f, + 0.8957520f, 0.8970032f, 0.8982544f, 0.8994751f, 0.9006958f, + 0.9019165f, 0.9031067f, 0.9042969f, 0.9054871f, 0.9066772f, + 0.9078369f, 0.9089966f, 0.9101562f, 0.9113159f, 0.9124451f, + 0.9135742f, 0.9147034f, 0.9158020f, 0.9169006f, 0.9179993f, + 0.9190979f, 0.9201660f, 0.9212341f, 0.9223022f, 0.9233398f, + 0.9243774f, 0.9254150f, 0.9264526f, 0.9274597f, 0.9284973f, + 0.9294739f, 0.9304810f, 0.9314575f, 0.9324341f, 0.9334106f, + 0.9343872f, 0.9353333f, 0.9362793f, 0.9371948f, 0.9381409f, + 0.9390564f, 0.9399719f, 0.9408569f, 0.9417725f, 0.9426575f, + 0.9435425f, 0.9443970f, 0.9452820f, 0.9461365f, 0.9469910f, + 0.9478149f, 0.9486389f, 0.9494629f, 0.9502869f, 0.9511108f, + 0.9519043f, 0.9526978f, 0.9534912f, 0.9542542f, 0.9550171f, + 0.9557800f, 0.9565430f, 0.9573059f, 0.9580383f, 0.9587708f, + 0.9595032f, 0.9602051f, 0.9609070f, 0.9616089f, 0.9623108f, + 0.9630127f, 0.9636841f, 0.9643555f, 0.9650269f, 0.9656677f, + 0.9663391f, 0.9669800f, 0.9676208f, 0.9682312f, 0.9688721f, + 0.9694824f, 0.9700928f, 0.9707031f, 0.9712830f, 0.9718628f, + 0.9724426f, 0.9730225f, 0.9735718f, 0.9741516f, 0.9747009f, + 0.9752502f, 0.9757690f, 0.9763184f, 0.9768372f, 0.9773560f, + 0.9778748f, 0.9783630f, 0.9788818f, 0.9793701f, 0.9798279f, + 0.9803162f, 0.9808044f, 0.9812622f, 0.9817200f, 0.9821777f, + 0.9826050f, 0.9830627f, 0.9834900f, 0.9839172f, 0.9843445f, + 0.9847412f, 0.9851379f, 0.9855652f, 0.9859619f, 0.9863281f, + 0.9867249f, 0.9870911f, 0.9874573f, 0.9878235f, 0.9881897f, + 0.9885559f, 0.9888916f, 0.9892273f, 0.9895630f, 0.9898987f, + 0.9902039f, 0.9905396f, 0.9908447f, 0.9911499f, 0.9914551f, + 0.9917297f, 0.9920349f, 0.9923096f, 0.9925842f, 0.9928589f, + 0.9931335f, 0.9933777f, 0.9936523f, 0.9938965f, 0.9941406f, + 0.9943848f, 0.9945984f, 0.9948425f, 0.9950562f, 0.9952698f, + 0.9954834f, 0.9956970f, 0.9958801f, 0.9960938f, 0.9962769f, + 0.9964600f, 0.9966431f, 0.9968262f, 0.9969788f, 0.9971619f, + 0.9973145f, 0.9974670f, 0.9976196f, 0.9977722f, 0.9978943f, + 0.9980469f, 0.9981689f, 0.9982910f, 0.9984131f, 0.9985352f, + 0.9986572f, 0.9987488f, 0.9988708f, 0.9989624f, 0.9990540f, + 0.9991455f, 0.9992371f, 0.9992981f, 0.9993896f, 0.9994507f, + 0.9995117f, 0.9995728f, 0.9996338f, 0.9996948f, 0.9997253f, + 0.9997864f, 0.9998169f, 0.9998474f, 0.9998779f, 0.9999084f, + 0.9999390f, 0.9999390f, 0.9999695f, 0.9999695f, 0.9999695f, + 0.9999695f +}; +#endif + /*----------------------------------------------------------------------------------* * ISM ROM tables *----------------------------------------------------------------------------------*/ @@ -3124,7 +3249,6 @@ const float ivas_lpf_4_butter_48k_sos[IVAS_BIQUAD_FILT_LEN << 2] = 1.00000000471366f, 1.f , -1.98677297369091f, 0.987060670205863f }; - const ivas_lfe_freq_models ivas_str_lfe_freq_models = { { 16384, 14924, 13463, 12003, 10542, 9082, 7622, 6161, diff --git a/lib_com/ivas_rom_com.h b/lib_com/ivas_rom_com.h index 28fe9511feb62b2722d59bd19e54e387e4765e56..9ef4737c59c6cdfeaf73782c43095ac7fecfb317 100644 --- a/lib_com/ivas_rom_com.h +++ b/lib_com/ivas_rom_com.h @@ -328,14 +328,17 @@ extern const float McMASA_LFEGain_vectors[64]; *----------------------------------------------------------------------------------*/ extern const int32_t sep_object_brate[][MAX_NUM_OBJECTS]; -extern const float dct4[]; -extern const float dct5[]; -extern const float dct8[]; -extern const float dct12[]; extern const Word32 dct4_fx[]; extern const Word32 dct5_fx[]; extern const Word32 dct8_fx[]; extern const Word32 dct12_fx[]; +extern const float dct4[]; +extern const float dct5[]; +extern const float dct8[]; +extern const float dct12[]; +#ifdef NONBE_1380_OMASA_BUILD_DIFF +extern const float ivas_tan_panning_gain_tbl[]; +#endif /*----------------------------------------------------------------------------------* * ISM ROM tables diff --git a/lib_com/ivas_sba_config.c b/lib_com/ivas_sba_config.c index ae040fd3d9c4900c422037d1942b57c0bb4ec0f7..ea284a6abf6104de3a530239caaa2e1ab7a56b2f 100644 --- a/lib_com/ivas_sba_config.c +++ b/lib_com/ivas_sba_config.c @@ -162,10 +162,10 @@ int16_t ivas_sba_get_nchan( /*-------------------------------------------------------------------* * ivas_sba_spar_sid_bitlen() * - * Get number of bits in SBA SID frame + * Get number of bits in SBA SPAR SID frame *-------------------------------------------------------------------*/ -/*! r: number of bits in SBA SID frame */ +/*! r: number of bits in SBA SPAR SID frame */ int16_t ivas_sba_spar_sid_bitlen( const int16_t nchan_transport /* i : number of transport channels */ ) diff --git a/lib_com/ivas_spar_com.c b/lib_com/ivas_spar_com.c index ac21ec3e7aeca641c05894dd0296a76db6426086..9b2f3c3ce446dff53bdd5c4d316ccb54737e9337 100644 --- a/lib_com/ivas_spar_com.c +++ b/lib_com/ivas_spar_com.c @@ -1257,7 +1257,6 @@ static void ivas_calc_mat_inv( int16_t sign = 1; ivas_calc_mat_det( dbl_in_re, dim, &det_re ); - det = det_re > 0 ? 1 / max( IVAS_DBL_EPS, det_re ) : 1 / min( det_re, -IVAS_DBL_EPS ); for ( i = 0; i < dim; i++ ) diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index de00e54b923e26457410a99b69cc51c3374dc077..18697006c2b827a7c6c45c87f306a9a6f0b9de13 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -792,6 +792,4 @@ typedef struct ivas_param_ism_data_structure float last_cardioid_left[MAX_NUM_OBJECTS]; } PARAM_ISM_CONFIG_DATA, *PARAM_ISM_CONFIG_HANDLE; - - #endif /* IVAS_STAT_COM */ diff --git a/lib_com/ivas_stereo_mdct_bands_com.c b/lib_com/ivas_stereo_mdct_bands_com.c index 3e414582afa6658fed2378f0ccc89ab073d08bd0..51b541ab2cf0ce201daf0b0ab85a05a009d045db 100644 --- a/lib_com/ivas_stereo_mdct_bands_com.c +++ b/lib_com/ivas_stereo_mdct_bands_com.c @@ -44,7 +44,11 @@ * Local union *-------------------------------------------------------------------*/ +#ifndef BASOP_NOGLOB typedef union +#else /* BASOP_NOGLOB */ +typedef union +#endif /* BASOP_NOGLOB */ { MDCTStereoBands_config const *steBands; SpectrumWarping const *lpcBndsParam; diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index 6e66502dd239e7773e5d785a765460a40ecc7d2d..e7ada0a3432364b499f974d3625af3546d294af6 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -148,7 +148,6 @@ uint32_t ivas_syn_output( return noClipping; } -#ifdef JBM_MEMORY_OPT /*-------------------------------------------------------------------* * ivas_buffer_interleaved_to_deinterleaved() @@ -199,64 +198,24 @@ void ivas_buffer_deinterleaved_to_interleaved( ) { int16_t ch, m; -#ifdef FIX_1330_JBM_MEMORY float buffer[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS][L_FRAME48k]; /* temp buffer needed when "*audio[]" and "*audio_out[]" are the same */ for ( ch = 0; ch < n_channels; ch++ ) { mvr2r( audio[ch], buffer[ch], frame_length ); } -#endif for ( ch = 0; ch < n_channels; ch++ ) { for ( m = 0; m < frame_length; m++ ) { -#ifdef FIX_1330_JBM_MEMORY audio_out[m * n_channels + ch] = buffer[ch][m]; -#else - audio_out[m * n_channels + ch] = audio[ch][m]; -#endif } } return; } -#else - -/*-------------------------------------------------------------------* - * 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() @@ -678,6 +637,7 @@ void set_zero_l( return; } + /****************************************************************************/ /* matrix functions */ /* matrices are ordered column-wise in memory */ @@ -1350,7 +1310,6 @@ float rand_triangular_signed( return 0.5f - 0.5f * sqrtf( 1.0f - rand_val ); } } - Word16 matrix_product_fx( const Word32 *X_fx, /* i : left hand matrix Qx*/ const Word16 rowsX, /* i : number of rows of the left hand matrix Q0*/ diff --git a/lib_com/options.h b/lib_com/options.h old mode 100644 new mode 100755 index af4dc101490465ab7f84d6d075c1953057bb3f02..a98f995caace1d62781b56c3f8ece92d70c7bb24 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -55,13 +55,11 @@ /*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ /*#define WMOPS_WC_FRAME_ANALYSIS*/ /* Output detailed complexity analysis for the worst-case frame */ /*#define MEM_COUNT_DETAILS*/ /* Output detailed memory analysis for the worst-case frame (writes to the file "mem_analysis.csv") */ +/*#define FLP_EXCEPTION_TRAP*/ /* Enable trap for floating-point exceptions (e.g., denormals, underflow, overflow, ...) */ #ifdef DEBUGGING -/*#define DBG_BITSTREAM_ANALYSIS*/ /* Write bitstream with annotations to a text file */ - -#define DISABLE_DFT_STEREO_ASSERT /* This assert is hit for -10 dB tests/codec_be_on_mr_nonselection/test_param_file.py::test_param_file_tests[stv-stereo at 32 kbps, 48kHz in, 48kHz out, DTX on, random FER at 5%, bandwidth switching] */ - -/*#define DEBUG_MODE_INFO*/ /* output most important parameters to the subdirectory "res/" */ +/*#define DBG_BITSTREAM_ANALYSIS*/ /* Write bitstream with annotations to a text file */ +/*#define DEBUG_MODE_INFO*/ /* output most important parameters to the subdirectory "res/" */ #ifdef DEBUG_MODE_INFO /*#define DEBUG_MODE_ACELP*/ /* output most important ACELP core parameters to the subdirectory "res/" */ /*#define DEBUG_MODE_TCX*/ /* output most important TCX core parameters to the subdirectory "res/" */ @@ -71,15 +69,16 @@ /*#define DEBUG_MODE_MDCT*/ /* output most important MDCT parameters to the subdirectory "res/" */ /*#define DEBUG_MODE_PARAM_MC*/ /* output Parametric MC paramters to the subdirectory "res/" */ /*#define DEBUG_MODE_PARAM_ISM*/ /* output Parametric ISM paramters to the subdirectory "res/" */ -/*#define DEBUG_MODE_INFO_TWEAK*/ /* enable command line switch to specify subdirectory for debug info output inside "./res/" */ +/*#define DEBUG_MODE_INFO_TWEAK*/ /* enable command line switch to specify subdirectory for debug info output inside "./res/" */ /*#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_FORCE_DIR*/ /* Force modes/parameters by reading from external binary files */ +/*#define DEBUG_MODE_ORIENTATION */ /* define to output combined orientation relevant parameters */ +/*#define DEBUG_MODE_JBM */ /* define to output JBM relevant parameters */ #endif #ifdef DEBUG_MODE_MDCT -/*#define DEBUG_PLOT_BITS*/ +#define DEBUG_PLOT_BITS #define DEBUG_OSBA_MD_BITS #endif @@ -100,6 +99,7 @@ /*DirAC Debug switches*/ /*#define DEBUG_DISABLE_DIRAC_DELAY_COMP */ /* temporarily disable delay compensation on DirAC encoder */ +/*#define DEBUG_BS_READ_WRITE*/ /*#define DEBUG_MODE_DIRAC_NOCORE*/ /*#define DEBUG_MODE_QMETADATA*/ /* output q_metadata parameters */ @@ -136,80 +136,67 @@ /*#define DEBUG_AGC_ENCODER_CMD_OPTION*/ /* Ability to force enable or disable AGC behaviour in DIRAC/SPAR via command line option */ /*#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 */ /*#define VARIABLE_SPEED_DECODING*/ /* variable speed decoding employing the JBM functioniality; move to DEBUGGING after build for disabled is fixed */ +/*#define DISABLE_LIMITER*/ /* disable the limiter */ +/*#define DEBUG_APA_SILENCE_NON_SCALED*/ /* Switch APA into mode that replaces contents of non-scaled frames with silence. Useful for identifying scaled regions in the audio output of the decoder */ /*Split Rendering Debug switches*/ /*#define DBG_WAV_WRITER*/ /* add debugging function dbgwrite_wav() */ /*#define SPLIT_REND_WITH_HEAD_ROT_DEBUG*/ /* debugging switch for split rendering */ /*#define SPLIT_POSE_CORRECTION_DEBUG*/ /* debugging switch for split rendering pose correction */ /*#define SPLIT_MD_CODING_DEBUG*/ /* debugging switch for split rendering metadata coding */ +/*#define DEBUG_WRITE_PREDICTORS*/ /* debugging switch for LCDL predictors*/ +/*#define DEBUG_WRITE_MS_PRED*/ /* debugging switch for LCLD mid-side prediction*/ #endif /* DEBUGGING */ -/*#define DISABLE_LIMITER*/ /* disable the limiter - needed for testing Bitexactness between different renderer framings */ -/*#define DEBUG_APA_SILENCE_NON_SCALED*/ /* Switch APA into mode that replaces contents of non-scaled frames with silence. Useful for identifying scaled regions in the audio output of the decoder */ - /* #################### End DEBUGGING switches ############################ */ -#define BASOP_NOGLOB /* Disable global symbols in BASOPs, Overflow/Carry in BASOPs disabled, additional BASOPs in case of Overflow */ +/* keep as part of options.h */ +#define BASOP_NOGLOB /* Disable global symbols in BASOPs, Overflow/Carry in BASOPs disabled, additional BASOPs in case of Overflow */ +/*#define DISABLE_LIMITER */ /* test switch for testing BE between 5ms and 20ms rendering */ -/* ################### Start FIXES switches ########################### */ +/* ################## Start DEVELOPMENT switches ######################### */ -#define TEMP_FIX_2088_MSAN_INIT_ERROR /* Eri: Temporary fix for Issue 2088 - MSAN error. Will come with later port of JBM+Split rendering update */ -/* #################### End FIXES switches ############################ */ +#define RTP_S4_251135_CR26253_0016_REV1 /* RTP Pack/Unpack API corresponding to CR 26253 */ +#define IVAS_RTPDUMP /* RTPDUMP writing and reading for IVAS payloads */ +#define FIXED_RTP_SEQUENCE_NUM /* Remove random sequence number initialization */ -/* #################### Start BASOP porting switches ############################ */ +/* ################### Start BE switches ################################# */ +/* only BE switches wrt selection floating point code */ -#define NONBE_1244_FIX_SWB_BWE_MEMORY /* VA: issue 1244: fix to SWB BWE memory in case of switching from FB coding - pending a review by Huawei */ -#define FIX_1320_STACK_CPE_DECODER /* VA: issue 1320: Optimize the stack memory consumption in the CPE decoder */ -#define NONBE_1328_FIX_NON_LINEARITY /* VA: Fix possible issue when computing bwe_exc_extended and previous frame were almost 0 */ -#define FIX_1320_STACK_CPE_DECODER /* VA: issue 1320: Optimize the stack memory consumption in the CPE decoder */ -#define NONBE_1302_FIX_OMASA_JBM_FLUSH /* VA: issue 1302: fix OMASA JBM bitrate switching flush in binaural output */ -#define FIX_1319_STACK_SBA_DECODER /* VA: issue 1319: Optimize the definition of buffer lengths in the SBA decoder */ -#define NONBE_FIX_1376_MDCT_CONCEALMENT /* FhG: fix concealment artifact in MDCT Stereo with DTX, in case transition frame gets lost */ -#define NONBE_1377_REND_DIRATT_CONF /* Eri: Issue 1377: Error in directivity attenuation configuration for both IVAS_dec and IVAS_rend */ -#define FIX_1377_HANDLE_ERROR_CODE /* Eri: Add missing error code handling from IVAS_REND_SetObjectIDs */ -#define FIX_1053_REVERB_RECONFIGURATION +/*#define FIX_I4_OL_PITCH*/ /* fix open-loop pitch used for EVS core switching */ #define FIX_1119_SPLIT_RENDERING_VOIP /* FhG: Add split rendering support to decoder in VoIP mode */ #define TMP_1342_WORKAROUND_DEC_FLUSH_BROKEN_IN_SR /* FhG: Temporary workaround for incorrect implementation of decoder flush with split rendering */ -#define NONBE_1122_KEEP_EVS_MODE_UNCHANGED /* FhG: Disables fix for issue 1122 in EVS mode to keep BE tests green. This switch should be removed once the 1122 fix is added to EVS via a CR. */ -#define FIX_938_COMPILER_WARNING /* FhG: Fix compiler warning in ivas_mdct_core_reconstruct() */ -#define FIX_1376_MISSING_ISM_METADATA /* FhG: IVAS_rend: throw error if there exists an ISM input without a corresponding metadata file path */ -#define FIX_1385_INIT_IGF_STOP_FREQ /* FhG: Initialize infoIGFStopFreq in init_igf_dec() */ -#define FIX_1387_INIT_PRM_SQQ /* FhG: initialize pointer prm_sqQ, which might be uninitialized in case of bfi == 1 */ -#define FIX_1349_TNS_CRASH /* FhG: Fix crash in TNS entropy coding, in case order of joint TNS coding is reduced to 0 */ -#define FIX_1384_MSAN_stereo_tcx_core_enc /* VA: issue 1384: fix use-of-uninitialized value in stereo_tcx_core_enc() */ -#define FIX_1384_MSAN_ivas_spar_dec_open /* VA: issue 1386: fix use-of-uninitialized value in ivas_spar_dec_open() */ -#define FIX_1388_MSAN_ivas_init_decoder /* VA: issue 1388: fix use-of-uninitialized value in ivas_init_decoder() */ -#define FIX_1288_SPLIT_REND_XSAN /* Dlb: Fix asan, msan and usan issues in split rendering mode*/ -#define FIX_NCHAN_BUFFERS /* VA: issue 1322: Correct the number of float buffers (channels) at the decoder */ -#define FIX_RENDERER_STACK /* VA: issue 1322: reduction of renderers' buffers size */ -#define JBM_MEMORY_OPT /* VA: issue 916: optimization of RAM in the JBM decoder */ -#define NONBE_1324_TC_BUFFER_MEMOERY_KEEP /* VA: issue 1324: do not reset TSM memory in JBM bitrate switching */ -#define FIX_1370_EXTERNAL_ORIENTATION_CHECK /* Nokia: add sanity check for Euler angles for external orientations */ #define FIX_1413_IGF_INIT_PRINTOUT /* FhG: use correct variable for IGF initiliazation */ -#define FIX_1330_JBM_MEMORY /* VA: issue 1330: memory savings in the JBM decoder */ -#define CODE_IMPROVEMENTS -#define NONBE_1359_FIX_IVASREND_OMASA_BINAURAL_LOUDNESS /* Nokia: issue 1339: Apply scaling to the object-part of OMASA for binaural rendering in IVAS_rend. */ -#define NONBE_1362_FIX_OMASA_TO_MASA1_RENDERING /* Nokia: Fix OMASA to MASA1 rendering in IVAS_rend */ -#define FIX_1383_HEAD_TRACK_SANITIZER /* Nok: issue 1383: Fix head tracking struc values reading in renderer */ +#define RENDERER_MD_SYNC_DELAY_TO_INTEGER /* FhG: change data type of metadata sync delay in ext renderer to int16_t for better BASOP portability (and nicer code) */ + + +/* #################### End BE switches ################################## */ + +/* #################### Start NON-BE switches ############################ */ + +/* any switch which is non-be wrt selection floating point code */ +/* all switches in this category should start with "NONBE_" */ + +#define NONBE_1244_FIX_SWB_BWE_MEMORY /* VA: issue 1244: fix to SWB BWE memory in case of switching from FB coding - pending a review by Huawei */ +#define NONBE_1122_KEEP_EVS_MODE_UNCHANGED /* FhG: Disables fix for issue 1122 in EVS mode to keep BE tests green. This switch should be removed once the 1122 fix is added to EVS via a CR. */ +#define NONBE_1399_1400_FIX_OBJ_EDIT_ISSUES /* Nokia: Fix for issues 1399: obj edit broken with MC/SBA output in VOIP, and 1400: negative energy estimate used for gaining. */ #define FIX_1411_IGF_CRASH_BW_SWITCHING /* FhG: Fix for issue 1411: fixes crash that can happen for IGF with BW switching and DTX*/ -#define NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG /* FhG: Fix MDCT-Stereo comfort noise for certain noise types */ -#define NONBE_1344_REND_MASA_LOW_FS /* Nokia: Issue 1344: Fix sanitizer errors when using IVAS_rend to render MASA with lower sampling rates */ + #define NONBE_1412_AVOID_ROUNDING_AZ_ELEV /* FhG: Avoid rounding when passing azimuth and elevation to efap_determine_gains() */ +#define NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG /* FhG: Fix MDCT-Stereo comfort noise for certain noise types */ #define NONBE_FIX_NONBE_BETWEEN_OPTIMIZATION_LEVELS /* FhG: fix non-BE in DFT stereo encoder between optimization levels */ #define NONBE_FIX_NONBE_BETWEEN_OPTIMIZATION_LEVELS_2 /* FhG: fix even more non-BEnesses */ -// object-editing feature porting -#define FIX_HRTF_LOAD_API // solves API conflicts between HRTF and object-editing features -#define TMP_FIX_SPLIT_REND // temporary fix to split-rendering (it follows the later state of the framework but it is needed now because of current test-conditions) -#define TMP_FIX_OMASA_SR_BE // temporary fix to keep OMASA split-rendering BE -#define FIX_1372_OSBA_OBJECT_EDITING /* VA: issue 1372: Fix OSBA object-editing in BINAURAL_ROOM_IR */ -#define NONBE_FIX_1172_OBJ_EDIT_JBM /* VA: issue 1172: fix OMASA object editing in JBM */ -#define NONBE_1399_1400_FIX_OBJ_EDIT_ISSUES /* Nokia: Fix for issues 1399: obj edit broken with MC/SBA output in VOIP, and 1400: negative energy estimate used for gaining. */ +/*#define NONBE_1324_TC_BUFFER_MEMOERY_KEEP*/ /* VA: issue 1324: do not reset TSM memory in JBM bitrate switching */ + +#define NONBE_1380_OMASA_BUILD_DIFF /* Nokia: Fix for issue #1380: Large differences in OMASA output between Debug and Release builds */ + +/* ##################### End NON-BE switches ########################### */ -/* #################### End BASOP porting switches ############################ */ +/* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_com/prot.h b/lib_com/prot.h index 1a6b62e1c6005a5b0de1137f864a83e0b55e6998..c624212fc3060e0b874a32170932fbf5c9183f11 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -160,6 +160,7 @@ int16_t sum_s( const int16_t *vec, /* i : input vector */ const int16_t lvec /* i : length of input vector */ ); + #ifdef DEBUGGING /*! r: sum of all vector elements */ int32_t sum_l( @@ -215,6 +216,12 @@ void mvr2r( const int16_t n /* i : vector size */ ); +void mvs2s( + const int16_t x[], /* i : input vector */ + int16_t y[], /* o : output vector */ + const int16_t n /* i : vector size */ +); + #ifdef DEBUGGING /*! r: number of overload samples */ uint32_t check_clipping( @@ -226,12 +233,6 @@ uint32_t check_clipping( #endif /*! r: number of clipped samples */ -void mvs2s( - const int16_t x[], /* i : input vector */ - int16_t y[], /* o : output vector */ - const int16_t n /* i : vector size */ -); - uint32_t mvr2s( const float x[], /* i : input vector */ int16_t y[], /* o : output vector */ @@ -483,6 +484,7 @@ void delay_signal( const int16_t delay /* i : delay in samples */ ); + ivas_error push_indice( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ int16_t id, /* i : ID of the indice */ @@ -495,6 +497,7 @@ ivas_error push_indice( #define push_next_bits( ... ) push_next_bits_( __func__, __VA_ARGS__ ); #endif + #if defined( DEBUGGING ) && defined( DBG_BITSTREAM_ANALYSIS ) ivas_error push_next_indice_( const char *caller, @@ -703,7 +706,7 @@ int32_t get_delay( const int32_t io_fs, /* i : input/output sampling frequency */ const IVAS_FORMAT ivas_format, /* i : IVAS format */ HANDLE_CLDFB_FILTER_BANK hCldfb, /* i : Handle of Cldfb analysis */ - const int16_t flag_binaural_split_coded /* i : split rendering on/off flag */ + const int16_t flag_binaural_split_coded /* i : split rendering on/off flag */ ); void decision_matrix_enc( @@ -2249,7 +2252,7 @@ ivas_error init_encoder( const int16_t idchan, /* i : channel ID */ const int16_t vad_only_flag, /* i : flag to indicate front-VAD structure */ const ISM_MODE ism_mode, /* i : ISM mode */ - const int32_t element_brate /* i : element bitrate */ + const int32_t element_brate /* element bitrate */ ); void LPDmem_enc_init( @@ -2281,14 +2284,16 @@ void amr_wb_enc_init( ); void pre_proc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t input_frame, /* i : frame length */ - float old_inp_12k8[], /* i/o: buffer of old input signal */ - float old_inp_16k[], /* i/o: buffer of old input signal @ 16kHz */ - float **inp, /* o : ptr. to inp. signal in the current frame*/ - float fr_bands[2 * NB_BANDS], /* i : energy in frequency bands */ - float *ener, /* o : residual energy from Levinson-Durbin */ - int16_t pitch_orig[3], /* o : open-loop pitch values for quantization */ + Encoder_State *st, /* i/o: encoder state structure */ + const int16_t input_frame, /* i : frame length */ + float old_inp_12k8[], /* i/o: buffer of old input signal */ + float old_inp_16k[], /* i/o: buffer of old input signal @ 16kHz */ + float **inp, /* o : ptr. to inp. signal in the current frame*/ + float fr_bands[2 * NB_BANDS], /* i : energy in frequency bands */ + float *ener, /* o : residual energy from Levinson-Durbin */ +#ifndef FIX_I4_OL_PITCH + int16_t pitch_orig[3], /* o : open-loop pitch values for quantization */ +#endif float A[NB_SUBFR16k * ( M + 1 )], /* i/o: A(z) unquantized for the 4 subframes */ float Aw[NB_SUBFR16k * ( M + 1 )], /* i/o: weighted A(z) unquantized for subframes */ float epsP[M + 1], /* i/o: LP prediction errors */ @@ -2638,18 +2643,15 @@ void flip_and_downmix_generic( ); void non_linearity( - const float input[], /* i : input signal */ - float output[], /* i : output signal */ - float old_bwe_exc_extended[], /* i/o: memory bugffer */ - const int16_t length, /* i : input length */ - float *prev_scale, /* i/o: memory */ - const int16_t coder_type, /* i : Coder Type */ - const float *voice_factors, /* i : Voice Factors */ - const int16_t L_frame /* i : ACELP frame length */ -#ifdef NONBE_1328_FIX_NON_LINEARITY - , - const int16_t element_mode /* i : element_mode to differentiate EVS and IVAS */ -#endif + const float input[], /* i : input signal */ + float output[], /* i : output signal */ + float old_bwe_exc_extended[], /* i/o: memory bugffer */ + const int16_t length, /* i : input length */ + float *prev_scale, /* i/o: memory */ + const int16_t coder_type, /* i : Coder Type */ + const float *voice_factors, /* i : Voice Factors */ + const int16_t L_frame, /* i : ACELP frame length */ + const int16_t element_mode /* i : element_mode to differentiate EVS and IVAS*/ ); void interp_code_5over2( @@ -3883,7 +3885,7 @@ void td_cng_enc_init( void dtx( Encoder_State *st, /* i/o: encoder state structure */ - const int32_t last_ivas_total_brate, /* i : last IVAS total bitrate */ + const int32_t last_ivas_total_brate, /* i : last IVAS total bitrate */ const int32_t ivas_total_brate, /* i : IVAS total bitrate */ const int16_t vad, /* i : VAD flag for DTX */ const float speech[] /* i : Pointer to the speech frame */ @@ -4796,6 +4798,7 @@ void dec_acelp_4t64( float code[], /* o : algebraic (fixed) codebook excitation */ const int16_t Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ ); + void FEC_exc_estim( Decoder_State *st, /* i/o: Decoder static memory */ const int16_t L_frame, /* i : length of the frame */ diff --git a/lib_com/rom_com.c b/lib_com/rom_com.c old mode 100644 new mode 100755 diff --git a/lib_com/stl.h b/lib_com/stl.h index 06e7df889787ca4a196bc185a5b56388d7a9e799..5389c3c3a27da2664f2c0b94297376002025733e 100644 --- a/lib_com/stl.h +++ b/lib_com/stl.h @@ -57,6 +57,7 @@ #ifndef _STL_H #define _STL_H +#include "options.h" /* note: needed until BASOP_NOGLOB is accepted */ #include "typedef.h" #include "basop32.h" #include "wmc_auto.h" diff --git a/lib_com/swb_tbe_com.c b/lib_com/swb_tbe_com.c index ed06e57636c1bb4fa0f19df5422c1125585b5edb..2104e5cdee89af298c6c2a8d9df5c9fd39feda0e 100644 --- a/lib_com/swb_tbe_com.c +++ b/lib_com/swb_tbe_com.c @@ -1345,18 +1345,15 @@ void ScaleShapedSHB( * -------------------------------------------------------------------*/ void non_linearity( - const float input[], /* i : input signal */ - float output[], /* o : output signal */ - float old_bwe_exc_extended[], /* i/o: memory bugffer */ - const int16_t length, /* i : input length */ - float *prev_scale, /* i/o: memory */ - const int16_t coder_type, /* i : Coder Type */ - const float *voice_factors, /* i : Voice Factors */ - const int16_t L_frame /* i : ACELP frame length */ -#ifdef NONBE_1328_FIX_NON_LINEARITY - , - const int16_t element_mode /* i : element_mode to differentiate EVS and IVAS */ -#endif + const float input[], /* i : input signal */ + float output[], /* o : output signal */ + float old_bwe_exc_extended[], /* i/o: memory bugffer */ + const int16_t length, /* i : input length */ + float *prev_scale, /* i/o: memory */ + const int16_t coder_type, /* i : Coder Type */ + const float *voice_factors, /* i : Voice Factors */ + const int16_t L_frame, /* i : ACELP frame length */ + const int16_t element_mode /* i : element_mode to differentiate EVS and IVAS*/ ) { int16_t i, j; @@ -1369,17 +1366,16 @@ void non_linearity( int16_t en_abs = 0; float v_fac = 0, ths; int16_t nframes; -#ifdef NONBE_1328_FIX_NON_LINEARITY float sc_factor; -#endif + if ( L_frame == L_FRAME16k ) { - nframes = 5; + nframes = NB_SUBFR16k; ths = 0.87f; } else { - nframes = 4; + nframes = NB_SUBFR; ths = 0.94f; } @@ -1416,17 +1412,14 @@ void non_linearity( scale = 0.67f; } -#ifdef NONBE_1328_FIX_NON_LINEARITY sc_factor = 1024.0f; if ( element_mode > EVS_MONO ) { sc_factor = (float) ( 1 << max( 13 - norm_s( j + 1 ), 0 ) ); /* Adapt the scaling factor allowed depending of max position */ sc_factor = max( sc_factor, 2.0f ); } + if ( *prev_scale <= 0.0 || *prev_scale > sc_factor * scale ) -#else - if ( *prev_scale <= 0.0 || *prev_scale > 1024.0f * scale ) -#endif { scale_step = 1.0; *prev_scale = scale; @@ -1483,17 +1476,14 @@ void non_linearity( scale = 0.67f; } -#ifdef NONBE_1328_FIX_NON_LINEARITY sc_factor = 1024.0f; if ( element_mode > EVS_MONO ) { sc_factor = (float) ( 1 << max( 12 - norm_s( j - length / 2 + 1 ), 0 ) ); /* allowed intra frame jump is smaller */ sc_factor = max( sc_factor, 2.0f ); } + if ( *prev_scale <= 0.0 || *prev_scale > sc_factor * scale ) -#else - if ( *prev_scale <= 0.0 || *prev_scale > 1024.0f * scale ) -#endif { scale_step = 1.0; *prev_scale = scale; diff --git a/lib_com/tcx_ltp.c b/lib_com/tcx_ltp.c old mode 100644 new mode 100755 diff --git a/lib_com/tools.c b/lib_com/tools.c index 45e7941487b34ffc82a62135d49dc4b5952e9258..6dca2331ff73320a615f120e5a1cea687704ab9f 100644 --- a/lib_com/tools.c +++ b/lib_com/tools.c @@ -1742,23 +1742,11 @@ double anint( int16_t is_numeric_float( float x ) { -#ifdef CODE_IMPROVEMENTS int16_t retval; #define WMC_TOOL_SKIP retval = (int16_t) ( !isnan( x ) && !isinf( x ) ); #undef WMC_TOOL_SKIP return retval; -#else - union float_int - { - float float_val; - int32_t int_val; - } float_int; - - float_int.float_val = x; - - return ( ( float_int.int_val & 0x7f800000 ) != 0x7f800000 ); -#endif } /*-------------------------------------------------------------------* diff --git a/lib_debug/debug.c b/lib_debug/debug.c index 77823632b8d70ce66c003c3b442b816b0d835bb4..012183c5ac9e392b1114723e5a698c8df7a87118 100644 --- a/lib_debug/debug.c +++ b/lib_debug/debug.c @@ -364,13 +364,6 @@ int16_t dbgread( { index = in_count; in_fileptr[index] = fopen( filename, "rb" ); -#ifdef DEBUG_FORCE_DIR - if ( in_fileptr[index] == NULL ) - { - /* file does not exist or could not be opened -> just return */ - return -1; - } -#endif in_filename[index] = malloc( sizeof( char ) * ( strlen( filename ) + 1 ) ); strcpy( in_filename[index], filename ); in_count++; @@ -759,7 +752,7 @@ int16_t tweakdbgfolder( const char *filename, char *filename_mod, int16_t *textm #endif -#ifdef DEBUGGING +#ifdef DEBUG_MODE_INFO /*-------------------------------------------------------------------* * fname() * @@ -779,23 +772,12 @@ char *fname( const int16_t id, const int16_t enc_dec ) { -#ifdef DEBUG_FORCE_DIR - size_t len; -#endif char idd[6]; assert( id < 100 ); sprintf( idd, ".id%d", id ); strcpy( tmp_fname, dir ); -#ifdef DEBUG_FORCE_DIR - len = strlen( tmp_fname ); - if ( tmp_fname[len - 1] != '/' && tmp_fname[len - 1] != '\\' ) - { - /* add trailing '/' slash */ - strcat( tmp_fname, "/" ); - } -#endif strcat( tmp_fname, file ); if ( enc_dec == DEC ) diff --git a/lib_debug/debug.h b/lib_debug/debug.h index 62102e95ec107efeca8065afb72bb72c2ab20489..b96a6ca42394b548b2695ddc9ed53cb7a6e0290f 100644 --- a/lib_debug/debug.h +++ b/lib_debug/debug.h @@ -60,16 +60,12 @@ extern int16_t debug_level; #define DEBUG_LINE( level ) if ( 0 ) #endif -#ifdef DEBUGGING +#ifdef DEBUG_MODE_INFO extern char tmp_fname[]; extern char debug_dir[6]; char *fname( char *dir, char *file, const int16_t n, const int16_t id, const int16_t enc_dec ); #endif -#ifdef DEBUG_FORCE_DIR -#define FORCE_DIR_MAX_LENGTH 255 /* maximum length of the directory for modes/parameters enforcement */ -#endif - /*------------------------------------------------------------------------------------------* * Read/write I/O tool *------------------------------------------------------------------------------------------*/ diff --git a/lib_debug/flp_debug.h b/lib_debug/flp_debug.h new file mode 100644 index 0000000000000000000000000000000000000000..d0fd894a2ef0a824eb2da87a77c2bb63e1e8163f --- /dev/null +++ b/lib_debug/flp_debug.h @@ -0,0 +1,263 @@ +/****************************************************************************************************** + + (C) 2022-2025 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 + +#if defined( _MSC_VER ) +// MSVC, x87 +#include +#elif defined( __GNUC__ ) && ( defined( __SSE__ ) || defined( __SSE2__ ) || defined( __AVX__ ) ) +// GCC/Clang, x86 SSE/AVX +#include +#endif + +#define FLE_MASK_INVALID 0x080 +#define FLE_MASK_DENORM 0x100 +#define FLE_MASK_DIV_ZERO 0x200 +#define FLE_MASK_OVERFLOW 0x400 +#define FLE_MASK_UNDERFLOW 0x800 + +/* + detect underflow execption, which results in a denormal; + this will not detect each and every denormal - otherwise, + all FLP values would have to be tested for denormals using + e.g. fpclassify()/fpstatus or bitmasks +*/ + + +static inline void enable_float_exception_trap( uint32_t fle_mask ) +{ + +#if defined( _MSC_VER ) + + // MSVC, x87 + unsigned int cw = _controlfp( 0, 0 ); + + if ( fle_mask & FLE_MASK_INVALID ) + { + cw &= ~_EM_INVALID; + } + if ( fle_mask & FLE_MASK_DENORM ) + { + cw &= ~_EM_DENORMAL; + } + if ( fle_mask & FLE_MASK_DIV_ZERO ) + { + cw &= ~_EM_ZERODIVIDE; + } + if ( fle_mask & FLE_MASK_OVERFLOW ) + { + cw &= ~_EM_OVERFLOW; + } + if ( fle_mask & FLE_MASK_UNDERFLOW ) + { + cw &= ~_EM_UNDERFLOW; + } + + _controlfp( cw, _MCW_EM ); + +#elif defined( __GNUC__ ) && ( defined( __SSE__ ) || defined( __SSE2__ ) || defined( __AVX__ ) ) + + // GCC/Clang, x86 SSE/AVX + unsigned int mx = _mm_getcsr(); + + if ( fle_mask & FLE_MASK_INVALID ) + { + mx &= ~_MM_MASK_INVALID; + } + if ( fle_mask & FLE_MASK_DENORM ) + { + mx &= ~_MM_MASK_DENORM; + } + if ( fle_mask & FLE_MASK_DIV_ZERO ) + { + mx &= ~_MM_MASK_DIV_ZERO; + } + if ( fle_mask & FLE_MASK_OVERFLOW ) + { + mx &= ~_MM_MASK_OVERFLOW; + } + if ( fle_mask & FLE_MASK_UNDERFLOW ) + { + mx &= ~_MM_MASK_UNDERFLOW; + } + + _mm_setcsr( mx ); + +#elif defined( __aarch64__ ) + + // AArch64 (e.g., Apple Silicon) + uint64_t fpcr; + __asm__ volatile( "mrs %0, fpcr" + : "=r"( fpcr ) ); + + // disable sits 24(FZ) & 25(DN) --> allow denormals to happen + fpcr &= ~( ( 1ull << 24 ) | ( 1ull << 25 ) ); + + if ( fle_mask & FLE_MASK_INVALID ) + { + // set bit 8 (IOE) to unmask invalid operations exceptions + fpcr |= ( 1ull << 8 ); + } + if ( fle_mask & FLE_MASK_DENORM ) + { + // set bit 15 (IDE) to unmask input denormal exceptions + fpcr |= ( 1ull << 15 ); + } + if ( fle_mask & FLE_MASK_DIV_ZERO ) + { + // set bit 9 (DZE) to unmask div_zero exceptions + fpcr |= ( 1ull << 9 ); + } + if ( fle_mask & FLE_MASK_OVERFLOW ) + { + // set bit 10 (OFE) to unmask overflow exceptions + fpcr |= ( 1ull << 10 ); + } + if ( fle_mask & FLE_MASK_UNDERFLOW ) + { + // set bit 11 (UFE) to unmask underflow exceptions + fpcr |= ( 1ull << 11 ); + } + + __asm__ volatile( "msr fpcr, %0" ::"r"( fpcr ) ); + +#else + fprintf( stderr, "enable_float_exception_trap() not supported on platform!\n" ); +#endif +} + +static inline void disable_float_exception_trap( uint32_t fle_mask ) +{ + +#if defined( _MSC_VER ) + + // MSVC, x87 + unsigned int cw = _controlfp( 0, 0 ); + + if ( fle_mask & FLE_MASK_INVALID ) + { + cw |= _EM_INVALID; + } + if ( fle_mask & FLE_MASK_DENORM ) + { + cw |= _EM_DENORMAL; + } + if ( fle_mask & FLE_MASK_DIV_ZERO ) + { + cw |= _EM_ZERODIVIDE; + } + if ( fle_mask & FLE_MASK_OVERFLOW ) + { + cw |= _EM_OVERFLOW; + } + if ( fle_mask & FLE_MASK_UNDERFLOW ) + { + cw |= _EM_UNDERFLOW; + } + + _controlfp( cw, _MCW_EM ); + +#elif defined( __GNUC__ ) && ( defined( __SSE__ ) || defined( __SSE2__ ) || defined( __AVX__ ) ) + + // GCC/Clang, x86 SSE/AVX + unsigned int mx = _mm_getcsr(); + + if ( fle_mask & FLE_MASK_INVALID ) + { + mx |= _MM_MASK_INVALID; + } + if ( fle_mask & FLE_MASK_DENORM ) + { + mx |= _MM_MASK_DENORM; + } + if ( fle_mask & FLE_MASK_DIV_ZERO ) + { + mx |= _MM_MASK_DIV_ZERO; + } + if ( fle_mask & FLE_MASK_OVERFLOW ) + { + mx |= _MM_MASK_OVERFLOW; + } + if ( fle_mask & FLE_MASK_UNDERFLOW ) + { + mx |= _MM_MASK_UNDERFLOW; + } + + _mm_setcsr( mx ); + +#elif defined( __aarch64__ ) + + // AArch64 (Apple Silicon) + uint64_t fpcr; + __asm__ volatile( "mrs %0, fpcr" + : "=r"( fpcr ) ); + + if ( fle_mask & FLE_MASK_INVALID ) + { + // unset bit 8 (IOE) to mask invalid operations exceptions + fpcr &= ~( 1ull << 8 ); + } + if ( fle_mask & FLE_MASK_DENORM ) + { + // unset bit 15 (IDE) to mask input denormal exceptions + fpcr &= ~( 1ull << 15 ); + } + if ( fle_mask & FLE_MASK_DIV_ZERO ) + { + // unset bit 9 (DZE) to mask div_zero exceptions + fpcr &= ~( 1ull << 9 ); + } + if ( fle_mask & FLE_MASK_OVERFLOW ) + { + // unset bit 10 (OFE) to mask overflow exceptions + fpcr &= ~( 1ull << 10 ); + } + if ( fle_mask & FLE_MASK_UNDERFLOW ) + { + // unset bit 11 (UFE) to mask underflow exceptions + fpcr &= ~( 1ull << 11 ); + } + + + // set bits 24/25 (FZ/DN) again + fpcr |= ( 1ull << 24 ) | ( 1ull << 25 ); + fprintf( stderr, "float_exception_trap(): Setting bits 24/25 (FZ/DN) again\n" ); + + __asm__ volatile( "msr fpcr, %0" ::"r"( fpcr ) ); + +#else + + fprintf( stderr, "float_exception_trap() not supported on platform!\n" ); + +#endif +} diff --git a/lib_debug/wmc_auto.c b/lib_debug/wmc_auto.c index 3cb7c753614a5fc9197bc1bf339b002c89bc2657..30e7733f93523460838058541cadea64972e87c5 100644 --- a/lib_debug/wmc_auto.c +++ b/lib_debug/wmc_auto.c @@ -1,5 +1,5 @@ /* - * (C) 2022 copyright VoiceAge Corporation. All Rights Reserved. + * (C) 2024 copyright VoiceAge Corporation. All Rights Reserved. * * This software is protected by copyright law and by international treaties. The source code, and all of its derivations, * is provided by VoiceAge Corporation under the "ITU-T Software Tools' General Public License". Please, read the license file @@ -18,6 +18,7 @@ #include #include #include +#include #ifndef _MSC_VER #include @@ -31,8 +32,11 @@ #define WMC_TOOL_SKIP /* Skip the instrumentation of this file, if invoked by accident */ -#ifdef WMOPS +#ifndef WMOPS +int cntr_push_pop = 0; /* global counter for checking balanced push_wmops()/pop_wmops() pairs when WMOPS is not activated */ +#endif +#ifdef WMOPS /*-------------------------------------------------------------------* * Complexity counting tool *--------------------------------------------------------------------*/ @@ -43,8 +47,9 @@ #define MAX_NUM_RECORDS_REALLOC_STEP 50 /* When re-allocating the list of records, increase the number of records by this number */ #define MAX_CALL_TREE_DEPTH 100 /* maximum depth of the function call tree */ #define DOUBLE_MAX 0x80000000 +#define FRAMES_PER_SECOND 50.0 #define FAC ( FRAMES_PER_SECOND / 1e6 ) - +#define PROM_INST_SIZE 32 /* number of bits of each program instruction when stored in the PROM memory (applied only when the user selects reporting in bytes) */ typedef struct { @@ -58,7 +63,7 @@ typedef struct double max_selfcnt; double min_selfcnt; double tot_selfcnt; - double start_cnt; + double start_cnt; /* The following take into account the decendants */ double current_cnt; double max_cnt; double min_cnt; @@ -72,7 +77,6 @@ typedef struct } wmops_record; double ops_cnt; -double prom_cnt; double inst_cnt[NUM_INST]; static wmops_record *wmops = NULL; @@ -87,10 +91,73 @@ static long fnum_cnt_wc; static int *wmops_caller_stack = NULL, wmops_caller_stack_index, max_wmops_caller_stack_index = 0; static int *heap_allocation_call_tree = NULL, heap_allocation_call_tree_size = 0, heap_allocation_call_tree_max_size = 0; +static BASIC_OP op_weight = { + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 2, 2, 1, + 1, 1, 1, 2, 1, + + 1, 1, 1, 2, 1, + 1, 1, 18, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 2, 2, 2, 2, 1, + + 1, 1, 1, 1, 1, + 1, 1, 1, 2, + 1, 2, 2, 2, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 3, + 3, 3, 3, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 3, 2, + 2, 6, 3, 3, 2, + + 1, 32, 1 + +/* New complex basops */ +#ifdef COMPLEX_OPERATOR + , + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1 + + , + 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1 + +#endif /* #ifdef COMPLEX_OPERATOR */ + +#ifdef ENH_64_BIT_OPERATOR + /* Weights of new 64 bit basops */ + , + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +#endif /* #ifdef ENH_64_BIT_OPERATOR */ + +#ifdef ENH_32_BIT_OPERATOR + , + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +#endif /* #ifdef ENH_32_BIT_OPERATOR */ + +#ifdef ENH_U_32_BIT_OPERATOR + , + 1, 1, 1, 2, 2, 1, 1 +#endif /* #ifdef ENH_U_32_BIT_OPERATOR */ + +#ifdef CONTROL_CODE_OPS + , + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +#endif /* #ifdef CONTROL_CODE_OPS */ +}; + +BASIC_OP *multiCounter = NULL; +unsigned int currCounter = 0; +long funcid_total_wmops_at_last_call_to_else; +char func_name_where_last_call_to_else_occurred[MAX_FUNCTION_NAME_LENGTH + 1]; + void reset_wmops( void ) { int i, j; - unsigned int *ptr; num_wmops_records = 0; max_num_wmops_records = MAX_NUM_RECORDS; @@ -102,7 +169,7 @@ void reset_wmops( void ) start_cnt = 0.0; ops_cnt = 0.0; - /* allocate the list of wmops records */ + /* allocate the list of WMOPS records */ if ( wmops == NULL ) { wmops = (wmops_record *) malloc( max_num_wmops_records * sizeof( wmops_record ) ); @@ -114,7 +181,7 @@ void reset_wmops( void ) exit( -1 ); } - /* allocate the BASOP WMOPS counter */ + /* allocate the list of BASOP WMOPS records */ if ( multiCounter == NULL ) { multiCounter = (BASIC_OP *) malloc( max_num_wmops_records * sizeof( BASIC_OP ) ); @@ -127,7 +194,7 @@ void reset_wmops( void ) } /* initilize the list of WMOPS records */ - /* initilize the BASOP WMOPS counters */ + /* initilize BASOP operation counters */ for ( i = 0; i < max_num_wmops_records; i++ ) { strcpy( &wmops[i].label[0], "\0" ); @@ -154,13 +221,8 @@ void reset_wmops( void ) wmops[i].wc_call_number = -1; #endif - /* clear all BASOP operation counters */ - ptr = (unsigned int *) &multiCounter[i]; - for ( j = 0; j < (int) ( sizeof( BASIC_OP ) / sizeof( unsigned int ) ); j++ ) - { - *ptr++ = 0; - } - wmops[i].LastWOper = 0; + /* Reset BASOP operation counter */ + Reset_BASOP_WMOPS_counter( i ); } /* allocate the list of wmops callers to track the sequence of function calls */ @@ -182,10 +244,6 @@ void reset_wmops( void ) wmops_caller_stack[i] = -1; } - /* initialize auxiliary BASOP WMOPS variables */ - call_occurred = 1; - funcId_where_last_call_to_else_occurred = INT_MAX; - return; } @@ -193,7 +251,7 @@ void push_wmops_fct( const char *label, ... ) { int new_flag; int i, j, index_record; - unsigned int *ptr; + long tot; va_list arg; char func_name[MAX_FUNCTION_NAME_LENGTH] = ""; @@ -218,7 +276,7 @@ void push_wmops_fct( const char *label, ... ) } index_record = i; - /* Create a new record in the list */ + /* Create a new WMOPS record in the list */ if ( new_flag ) { if ( num_wmops_records >= max_num_wmops_records ) @@ -227,50 +285,42 @@ void push_wmops_fct( const char *label, ... ) max_num_wmops_records += MAX_NUM_RECORDS_REALLOC_STEP; wmops = realloc( wmops, max_num_wmops_records * sizeof( wmops_record ) ); multiCounter = realloc( multiCounter, max_num_wmops_records * sizeof( BASIC_OP ) ); + } - /* initilize newly created WMOPS records */ - for ( i = num_wmops_records; i < max_num_wmops_records; i++ ) - { - strcpy( &wmops[i].label[0], "\0" ); - wmops[i].call_number = 0; - wmops[i].update_cnt = 0; - for ( j = 0; j < MAX_CALL_TREE_DEPTH; j++ ) - { - wmops[i].call_tree[j] = -1; - } - wmops[i].start_selfcnt = 0.0; - wmops[i].current_selfcnt = 0.0; - wmops[i].max_selfcnt = 0.0; - wmops[i].min_selfcnt = DOUBLE_MAX; - wmops[i].tot_selfcnt = 0.0; - wmops[i].start_cnt = 0.0; - wmops[i].current_cnt = 0.0; - wmops[i].max_cnt = 0.0; - wmops[i].min_cnt = DOUBLE_MAX; - wmops[i].tot_cnt = 0.0; + /* initilize the new WMOPS record */ + strcpy( &wmops[index_record].label[0], "\0" ); + wmops[index_record].call_number = 0; + wmops[index_record].update_cnt = 0; + for ( j = 0; j < MAX_CALL_TREE_DEPTH; j++ ) + { + wmops[index_record].call_tree[j] = -1; + } + wmops[index_record].start_selfcnt = 0.0; + wmops[index_record].current_selfcnt = 0.0; + wmops[index_record].max_selfcnt = 0.0; + wmops[index_record].min_selfcnt = DOUBLE_MAX; + wmops[index_record].tot_selfcnt = 0.0; + wmops[index_record].start_cnt = 0.0; + wmops[index_record].current_cnt = 0.0; + wmops[index_record].max_cnt = 0.0; + wmops[index_record].min_cnt = DOUBLE_MAX; + wmops[index_record].tot_cnt = 0.0; #ifdef WMOPS_WC_FRAME_ANALYSIS - wmops[i].wc_cnt = 0.0; - wmops[i].wc_selfcnt = 0.0; - wmops[i].current_call_number = 0; - wmops[i].wc_call_number = -1; + wmops[index_record].wc_cnt = 0.0; + wmops[index_record].wc_selfcnt = 0.0; + wmops[index_record].current_call_number = 0; + wmops[index_record].wc_call_number = -1; #endif - /* initialize BASOP WMOPS counters */ - ptr = (unsigned int *) &multiCounter[i]; - for ( j = 0; j < (int) ( sizeof( BASIC_OP ) / sizeof( unsigned int ) ); j++ ) - { - *ptr++ = 0; - } - wmops[i].LastWOper = 0; - } - } + /* Reset BASOP operation counter */ + Reset_BASOP_WMOPS_counter( index_record ); strcpy( wmops[index_record].label, func_name ); num_wmops_records++; } - /* Push the current context info to the new record */ + /* Update the WMOPS context info of the old record before switching to the new one */ if ( current_record >= 0 ) { if ( wmops_caller_stack_index >= max_wmops_caller_stack_index ) @@ -281,7 +331,9 @@ void push_wmops_fct( const char *label, ... ) } wmops_caller_stack[wmops_caller_stack_index++] = current_record; - /* accumulate op counts */ + /* add the BASOP complexity to the counter and update the old WMOPS counter */ + tot = DeltaWeightedOperation( current_record ); + ops_cnt += tot; wmops[current_record].current_selfcnt += ops_cnt - wmops[current_record].start_selfcnt; /* update call tree */ @@ -299,7 +351,14 @@ void push_wmops_fct( const char *label, ... ) } } - /* update the current context info */ + /* Need to reset the BASOP operation counter of the 0th record in every push_wmops() */ + /* because currCounter can never be -1 */ + if ( current_record == -1 && index_record == 0 ) + { + wmops[index_record].LastWOper = TotalWeightedOperation( index_record ); + } + + /* switch to the new record */ current_record = index_record; wmops[index_record].start_selfcnt = ops_cnt; wmops[index_record].start_cnt = ops_cnt; @@ -308,13 +367,12 @@ void push_wmops_fct( const char *label, ... ) wmops[index_record].current_call_number++; #endif - /* set the ID of BASOP functions counters */ - Set_BASOP_WMOPS_counter( index_record ); + /* set the ID of the current BASOP operations counter */ + currCounter = index_record; return; } - void pop_wmops( void ) { long tot; @@ -327,7 +385,7 @@ void pop_wmops( void ) } /* add the BASOP complexity to the counter */ - tot = DeltaWeightedOperation(); + tot = DeltaWeightedOperation( currCounter ); ops_cnt += tot; /* update count of current record */ @@ -339,15 +397,21 @@ void pop_wmops( void ) { current_record = wmops_caller_stack[--wmops_caller_stack_index]; wmops[current_record].start_selfcnt = ops_cnt; - - /* set the ID of the previous BASOP counter */ - Set_BASOP_WMOPS_counter( current_record ); } else { current_record = -1; } + /* set the ID of the previous BASOP operations counter */ + if ( current_record == -1 ) + { + currCounter = 0; /* Note: currCounter cannot be set to -1 because it's defined as unsigned int ! */ + } + else + { + currCounter = current_record; + } return; } @@ -440,9 +504,8 @@ void update_wmops( void ) wmops[i].current_call_number = 0; #endif - /* update the WC of all BASOP counters */ - Set_BASOP_WMOPS_counter( i ); - Reset_BASOP_WMOPS_counter(); + /* reset the BASOP operations counter */ + Reset_BASOP_WMOPS_counter( i ); } current_cnt = ops_cnt - start_cnt; @@ -476,7 +539,6 @@ void update_wmops( void ) return; } - void print_wmops( void ) { int i, label_len, max_label_len; @@ -653,7 +715,6 @@ void print_wmops( void ) return; } - /*-------------------------------------------------------------------* * Memory counting tool measuring RAM usage (stack and heap) * @@ -676,6 +737,7 @@ void print_wmops( void ) * #define WMC_TOOL_SKIP ... #undef WMC_TOOL_SKIP macro pair around the malloc(), calloc() and free(). *--------------------------------------------------------------------*/ + /* This is the value (in bytes) towards which the block size is rounded. For example, a block of 123 bytes, when using a 32 bits system, will end up taking 124 bytes since the last unused byte cannot be used for another block. */ #ifdef MEM_ALIGN_64BITS @@ -684,13 +746,15 @@ void print_wmops( void ) #define BLOCK_ROUNDING 4 /* Align on 32 Bits */ #endif -#define N_32BITS_BLOCKS ( BLOCK_ROUNDING / sizeof( int32_t ) ) -#define ROUND_BLOCK_SIZE( n ) ( ( ( n ) + BLOCK_ROUNDING - 1 ) & ~( BLOCK_ROUNDING - 1 ) ) +#define N_32BITS_BLOCKS ( BLOCK_ROUNDING / sizeof( int32_t ) ) #define MAGIC_VALUE_OOB 0x12A534F0 /* Signature value which is inserted before and after each allocated memory block, used to detect out-of-bound access */ #define MAGIC_VALUE_USED ( ~MAGIC_VALUE_OOB ) /* Value used to pre-fill allocated memory blocks, used to calculate actual memory usage */ -#define OOB_START 0x1 /* Flag indicating out-of-bounds access before memory block */ -#define OOB_END 0x2 /* Flag indicating out-of-bounds access after memory block */ +#define OOB_START 0x1 /* int indicating out-of-bounds access before memory block */ +#define OOB_END 0x2 /* int indicating out-of-bounds access after memory block */ + +#define ROUND_BLOCK_SIZE( n ) ( ( ( n ) + BLOCK_ROUNDING - 1 ) & ~( BLOCK_ROUNDING - 1 ) ) +#define IS_CALLOC( str ) ( str[0] == 'c' ) #ifdef MEM_COUNT_DETAILS const char *csv_filename = "mem_analysis.csv"; @@ -712,7 +776,6 @@ static int32_t wc_stack_frame = 0; /* Frame corresponding to the worst-case static int current_calls = 0, max_num_calls = MAX_NUM_RECORDS; static char location_max_stack[256] = "undefined"; -/* Heap-related variables */ typedef struct { char name[MAX_FUNCTION_NAME_LENGTH + 1]; /* +1 for NUL */ @@ -953,7 +1016,7 @@ int push_stack( const char *filename, const char *fctname ) } /* Check, if This is the New Worst-Case RAM (stack + heap) */ - current_stack_size = (int32_t) ( ( ( ptr_base_stack - ptr_current_stack ) * sizeof( int16_t ) ) ); + current_stack_size = ( int32_t )( ( ( ptr_base_stack - ptr_current_stack ) * sizeof( int16_t ) ) ); if ( current_stack_size < 0 ) { @@ -1161,7 +1224,7 @@ void *mem_alloc( current_heap_size += ptr_record->block_size; /* Check, if this is the new Worst-Case RAM (stack + heap) */ - current_stack_size = (int32_t) ( ( ( ptr_base_stack - ptr_current_stack ) * sizeof( int16_t ) ) ); + current_stack_size = ( int32_t )( ( ( ptr_base_stack - ptr_current_stack ) * sizeof( int16_t ) ) ); if ( current_stack_size + current_heap_size > wc_ram_size ) { wc_ram_size = current_stack_size + current_heap_size; @@ -1965,10 +2028,8 @@ void print_mem( ROM_Size_Lookup_Table Const_Data_PROM_Table[] ) { fprintf( stdout, "Error: Cannot retrieve or calculate Table ROM size of (%s)!\n", Const_Data_PROM_Table[i].file_spec ); } - else - { - fprintf( stdout, "Table ROM (const data) size (%s): %d %s\n", Const_Data_PROM_Table[i].file_spec, Const_Data_PROM_Table[i].Get_Const_Data_Size_Func() >> Stat_Cnt_Size, Count_Unit[Stat_Cnt_Size] ); - } + + fprintf( stdout, "Table ROM (const data) size (%s): %d %s\n", Const_Data_PROM_Table[i].file_spec, Const_Data_PROM_Table[i].Get_Const_Data_Size_Func() >> Stat_Cnt_Size, Count_Unit[Stat_Cnt_Size] ); } } else @@ -2115,104 +2176,337 @@ void print_mem( ROM_Size_Lookup_Table Const_Data_PROM_Table[] ) #endif /* WMOPS */ -#ifndef WMOPS -int cntr_push_pop = 0; /* global counter for checking balanced push_wmops()/pop_wmops() pairs when WMOPS is not activated */ +#ifdef CONTROL_CODE_OPS + +int LT_16( short var1, short var2 ) +{ + int F_ret = 0; + + if ( var1 < var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].LT_16++; #endif + return F_ret; +} + +int GT_16( short var1, short var2 ) +{ + int F_ret = 0; + if ( var1 > var2 ) + { + F_ret = 1; + } #ifdef WMOPS -/* Global counter for the calculation of BASOP complexity */ -BASIC_OP *multiCounter = NULL; -int currCounter = 0; -int funcId_where_last_call_to_else_occurred; -long funcid_total_wmops_at_last_call_to_else; -int call_occurred = 1; + multiCounter[currCounter].GT_16++; +#endif + return F_ret; +} -BASIC_OP op_weight = { - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 2, 2, 1, - 1, 1, 1, 3, 1, +int LE_16( short var1, short var2 ) +{ + int F_ret = 0; - 1, 1, 1, 3, 1, - 4, 1, 18, 1, 1, - 2, 1, 2, 2, 1, - 1, 1, 1, 1, 1, - 3, 3, 3, 3, 1, + if ( var1 <= var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].LE_16++; +#endif + return F_ret; +} - 1, 1, 1, 1, 1, - 1, 1, 1, 2, - 1, 2, 2, 4, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, +int GE_16( short var1, short var2 ) +{ + int F_ret = 0; - 1, 1, 1, 1, 3, - 3, 3, 3, 3, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 4, 4, - 4, 8, 3, 4, 4, + if ( var1 >= var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].GE_16++; +#endif + return F_ret; +} - 5, 32, 3 -}; +int EQ_16( short var1, short var2 ) +{ + int F_ret = 0; -/* Set the counter group to use, default is zero */ -void Set_BASOP_WMOPS_counter( int counterId ) + if ( var1 == var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].EQ_16++; +#endif + return F_ret; +} + +int NE_16( short var1, short var2 ) +{ + int F_ret = 0; + + if ( var1 != var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].NE_16++; +#endif + return F_ret; +} + +int LT_32( int L_var1, int L_var2 ) +{ + int F_ret = 0; + + if ( L_var1 < L_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].LT_32++; +#endif + return F_ret; +} + +int GT_32( int L_var1, int L_var2 ) { - if ( ( counterId > num_wmops_records ) || ( counterId < 0 ) ) + int F_ret = 0; + + if ( L_var1 > L_var2 ) { - currCounter = 0; - return; + F_ret = 1; } - currCounter = counterId; - call_occurred = 1; +#ifdef WMOPS + multiCounter[currCounter].GT_32++; +#endif + return F_ret; } -extern int32_t frame; +int LE_32( int L_var1, int L_var2 ) +{ + int F_ret = 0; + + if ( L_var1 <= L_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].LE_32++; +#endif + return F_ret; +} + +int GE_32( int L_var1, int L_var2 ) +{ + int F_ret = 0; + + if ( L_var1 >= L_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].GE_32++; +#endif + return F_ret; +} + +int EQ_32( int L_var1, int L_var2 ) +{ + int F_ret = 0; + + if ( L_var1 == L_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].EQ_32++; +#endif + return F_ret; +} + +int NE_32( int L_var1, int L_var2 ) +{ + int F_ret = 0; + + if ( L_var1 != L_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].NE_32++; +#endif + return F_ret; +} + +int LT_64( long long int L64_var1, long long int L64_var2 ) +{ + int F_ret = 0; + + if ( L64_var1 < L64_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].LT_64++; +#endif + return F_ret; +} -long TotalWeightedOperation() +int GT_64( long long int L64_var1, long long int L64_var2 ) +{ + int F_ret = 0; + + if ( L64_var1 > L64_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].GT_64++; +#endif + return F_ret; +} + +int LE_64( long long int L64_var1, long long int L64_var2 ) +{ + int F_ret = 0; + + if ( L64_var1 <= L64_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].LE_64++; +#endif + return F_ret; +} +int GE_64( long long int L64_var1, long long int L64_var2 ) +{ + int F_ret = 0; + + if ( L64_var1 >= L64_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].GE_64++; +#endif + return F_ret; +} + +int EQ_64( long long int L64_var1, long long int L64_var2 ) +{ + int F_ret = 0; + + if ( L64_var1 == L64_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].EQ_64++; +#endif + return F_ret; +} +int NE_64( long long int L64_var1, long long int L64_var2 ) +{ + int F_ret = 0; + + if ( L64_var1 != L64_var2 ) + { + F_ret = 1; + } +#ifdef WMOPS + multiCounter[currCounter].NE_64++; +#endif + return F_ret; +} + +#endif /* #ifdef CONTROL_CODE_OPS */ + +#ifdef WMOPS + +void incrIf( const char *func_name ) +{ + /* Technical note: If the "IF" operator comes just after an "ELSE", its counter must not be incremented */ + /* The following auxiliary variables are used to check if the "IF" operator doesn't immediately follow an "ELSE" operator */ + if ( ( strncmp( func_name, func_name_where_last_call_to_else_occurred, MAX_FUNCTION_NAME_LENGTH ) != 0 ) || ( TotalWeightedOperation( currCounter ) != funcid_total_wmops_at_last_call_to_else ) ) + { + + multiCounter[currCounter].If++; + } + + func_name_where_last_call_to_else_occurred[0] = '\0'; +} + +void incrElse( const char *func_name ) +{ + multiCounter[currCounter].If++; + + /* Save the BASOP comeplxity in the last call of the ELSE() statement */ + funcid_total_wmops_at_last_call_to_else = TotalWeightedOperation( currCounter ); + + /* We keep track of the name of the last calling function when the ELSE macro was called */ + strncpy( func_name_where_last_call_to_else_occurred, func_name, MAX_FUNCTION_NAME_LENGTH ); + func_name_where_last_call_to_else_occurred[MAX_FUNCTION_NAME_LENGTH] = '\0'; +} + +long TotalWeightedOperation( unsigned int CounterId ) { int i; unsigned int *ptr, *ptr2; long tot; tot = 0; - ptr = (unsigned int *) &multiCounter[currCounter]; + ptr = (unsigned int *) &multiCounter[CounterId]; ptr2 = (unsigned int *) &op_weight; - for ( i = 0; i < (int) ( sizeof( multiCounter[currCounter] ) / sizeof( unsigned int ) ); i++ ) + for ( i = 0; i < (int) ( sizeof( multiCounter[CounterId] ) / sizeof( unsigned int ) ); i++ ) { + if ( *ptr == UINT_MAX ) + { + printf( "\nError in BASOP complexity counters: multiCounter[%d][%d] = %d !!!\n", CounterId, i, *ptr ); + exit( -1 ); + } + tot += ( ( *ptr++ ) * ( *ptr2++ ) ); } return ( tot ); } -long DeltaWeightedOperation( void ) +long DeltaWeightedOperation( unsigned int CounterId ) { long NewWOper, delta; - NewWOper = TotalWeightedOperation(); + NewWOper = TotalWeightedOperation( CounterId ); - delta = NewWOper - wmops[currCounter].LastWOper; - wmops[currCounter].LastWOper = NewWOper; + delta = NewWOper - wmops[CounterId].LastWOper; + wmops[CounterId].LastWOper = NewWOper; return ( delta ); } -/* Resets the current BASOP WMOPS counter */ -void Reset_BASOP_WMOPS_counter( void ) +/* Resets BASOP operation counter */ +void Reset_BASOP_WMOPS_counter( unsigned int counterId ) { int i; - long *ptr; + unsigned int *ptr; - /* clear the current BASOP operation counter before new frame begins */ - ptr = (long *) &multiCounter[currCounter]; - for ( i = 0; i < (int) ( sizeof( multiCounter[currCounter] ) / sizeof( long ) ); i++ ) + /* reset the current BASOP operation counter */ + ptr = (unsigned int *) &multiCounter[counterId]; + for ( i = 0; i < (int) (sizeof(BASIC_OP) / sizeof(unsigned int)); i++ ) { *ptr++ = 0; } - wmops[currCounter].LastWOper = 0; + wmops[counterId].LastWOper = 0; return; } diff --git a/lib_debug/wmc_auto.h b/lib_debug/wmc_auto.h index 64eec1c15e74017e06507fc254c1e6422747f713..2ca5f6f9a99bf66d5f09512b23249b66a7d5adbd 100644 --- a/lib_debug/wmc_auto.h +++ b/lib_debug/wmc_auto.h @@ -1,5 +1,5 @@ /* - * (C) 2023 copyright VoiceAge Corporation. All Rights Reserved. + * (C) 2024 copyright VoiceAge Corporation. All Rights Reserved. * * This software is protected by copyright law and by international treaties. The source code, and all of its derivations, * is provided by VoiceAge Corporation under the "ITU-T Software Tools' General Public License". Please, read the license file @@ -23,18 +23,19 @@ #include /* stdio is needed for fprintf() */ #endif +#include "options.h" /* To Prevent "warning: '$' in identifier or number" message under GCC */ #ifdef __GNUC__ #pragma GCC system_header #endif -#ifndef INT_MAX -#define INT_MAX 32767 -#endif - -#define FRAMES_PER_SECOND 50.0 -#define PROM_INST_SIZE 32 /* number of bits of each program instruction when stored in the PROM memory (applied only when the user selects reporting in bytes) */ +#define ENH_32_BIT_OPERATOR +#define ENH_64_BIT_OPERATOR +#define ENH_U_32_BIT_OPERATOR +#define COMPLEX_OPERATOR +#define CONTROL_CODE_OPS /* enable control code operators such as LT_16, GT_16, ... */ +/* #define WMOPS_DISABLE_FCN_CALL_PENALIZATION*/ /* do not count the complexity of function calls */ #ifdef WMOPS enum instructions @@ -62,6 +63,30 @@ enum instructions NUM_INST }; +extern double ops_cnt; +extern double inst_cnt[NUM_INST]; + +/******************************************************************/ +/* NOTES: */ +/* The 'wmc_flag_' flag is global to avoid declaration in every */ +/* function and 'static' to avoid clashing with other modules */ +/* that include this header file. */ +/* */ +/* The declarations of 'wmc_flag_' and 'wops_' in this header */ +/* file prevent the addition of a 'C' file to the Project. */ +/******************************************************************/ + +/* General Purpose Global int */ +static int wmc_flag_ = 0; + +#define push_wmops( ... ) push_wmops_fct( __VA_ARGS__, NULL ) +void push_wmops_fct( const char *label, ... ); +void pop_wmops( void ); +void reset_wmops( void ); +void print_wmops( void ); +void update_wmops( void ); +void update_mem( void ); + #define _ADD_C 1 #define _ABS_C 1 #define _MULT_C 1 @@ -83,502 +108,167 @@ enum instructions #define _LOG_C 25 #define _MISC_C 1 -#define _ADD_P 1 -#define _ABS_P 1 -#define _MULT_P 1 -#define _MAC_P 1 -#define _MOVE_P 1 -#define _STORE_P 0 -#define _LOGIC_P 1 -#define _SHIFT_P 1 -#define _BRANCH_P 2 -#define _DIV_P 2 -#define _SQRT_P 2 -#define _TRANS_P 2 -#define _FUNC_P 2 /* need to add number of arguments */ -#define _LOOP_P 1 -#define _INDIRECT_P 2 -#define _PTR_INIT_P 1 -#define _TEST_P 1 -#define _POWER_P 2 -#define _LOG_P 2 -#define _MISC_P 1 - -#define ADD( x ) \ - { \ - { \ - ops_cnt += ( _ADD_C * ( x ) ); \ - inst_cnt[_ADD] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _ADD_P * ( x ) ); \ - } \ - } \ - } \ +#define ADD( x ) \ + { \ + ops_cnt += ( _ADD_C * ( x ) ); \ + inst_cnt[_ADD] += ( x ); \ } -#define ABS( x ) \ - { \ - { \ - ops_cnt += ( _ABS_C * ( x ) ); \ - inst_cnt[_ABS] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _ABS_P * ( x ) ); \ - } \ - } \ - } \ +#define ABS( x ) \ + { \ + ops_cnt += ( _ABS_C * ( x ) ); \ + inst_cnt[_ABS] += ( x ); \ } -#define MULT( x ) \ - { \ - { \ - ops_cnt += ( _MULT_C * ( x ) ); \ - inst_cnt[_MULT] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _MULT_P * ( x ) ); \ - } \ - } \ - } \ +#define MULT( x ) \ + { \ + ops_cnt += ( _MULT_C * ( x ) ); \ + inst_cnt[_MULT] += ( x ); \ } -#define MAC( x ) \ - { \ - { \ - ops_cnt += ( _MAC_C * ( x ) ); \ - inst_cnt[_MAC] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _MAC_P * ( x ) ); \ - } \ - } \ - } \ +#define MAC( x ) \ + { \ + ops_cnt += ( _MAC_C * ( x ) ); \ + inst_cnt[_MAC] += ( x ); \ } -#define MOVE( x ) \ - { \ - { \ - ops_cnt += ( _MOVE_C * ( x ) ); \ - inst_cnt[_MOVE] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _MOVE_P * ( x ) ); \ - } \ - } \ - } \ +#define MOVE( x ) \ + { \ + ops_cnt += ( _MOVE_C * ( x ) ); \ + inst_cnt[_MOVE] += ( x ); \ } -#define STORE( x ) \ - { \ - { \ - ops_cnt += ( _STORE_C * ( x ) ); \ - inst_cnt[_STORE] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _STORE_P * ( x ) ); \ - } \ - } \ - } \ +#define STORE( x ) \ + { \ + ops_cnt += ( _STORE_C * ( x ) ); \ + inst_cnt[_STORE] += ( x ); \ } -#define LOGIC( x ) \ - { \ - { \ - ops_cnt += ( _LOGIC_C * ( x ) ); \ - inst_cnt[_LOGIC] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _LOGIC_P * ( x ) ); \ - } \ - } \ - } \ +#define LOGIC( x ) \ + { \ + ops_cnt += ( _LOGIC_C * ( x ) ); \ + inst_cnt[_LOGIC] += ( x ); \ } -#define SHIFT( x ) \ - { \ - { \ - ops_cnt += ( _SHIFT_C * ( x ) ); \ - inst_cnt[_SHIFT] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _SHIFT_P * ( x ) ); \ - } \ - } \ - } \ +#define SHIFT( x ) \ + { \ + ops_cnt += ( _SHIFT_C * ( x ) ); \ + inst_cnt[_SHIFT] += ( x ); \ } -#define BRANCH( x ) \ - { \ - { \ - ops_cnt += ( _BRANCH_C * ( x ) ); \ - inst_cnt[_BRANCH] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _BRANCH_P * ( x ) ); \ - } \ - } \ - } \ +#define BRANCH( x ) \ + { \ + ops_cnt += ( _BRANCH_C * ( x ) ); \ + inst_cnt[_BRANCH] += ( x ); \ } -#define DIV( x ) \ - { \ - { \ - ops_cnt += ( _DIV_C * ( x ) ); \ - inst_cnt[_DIV] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _DIV_P * ( x ) ); \ - } \ - } \ - } \ +#define DIV( x ) \ + { \ + ops_cnt += ( _DIV_C * ( x ) ); \ + inst_cnt[_DIV] += ( x ); \ } -#define SQRT( x ) \ - { \ - { \ - ops_cnt += ( _SQRT_C * ( x ) ); \ - inst_cnt[_SQRT] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _SQRT_P * ( x ) ); \ - } \ - } \ - } \ +#define SQRT( x ) \ + { \ + ops_cnt += ( _SQRT_C * ( x ) ); \ + inst_cnt[_SQRT] += ( x ); \ } -#define TRANS( x ) \ - { \ - { \ - ops_cnt += ( _TRANS_C * ( x ) ); \ - inst_cnt[_TRANS] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _TRANS_P * ( x ) ); \ - } \ - } \ - } \ +#define TRANS( x ) \ + { \ + ops_cnt += ( _TRANS_C * ( x ) ); \ + inst_cnt[_TRANS] += ( x ); \ } -#define LOOP( x ) \ - { \ - { \ - ops_cnt += ( _LOOP_C * ( x ) ); \ - inst_cnt[_LOOP] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _LOOP_P * ( x ) ); \ - } \ - } \ - } \ +#define LOOP( x ) \ + { \ + ops_cnt += ( _LOOP_C * ( x ) ); \ + inst_cnt[_LOOP] += ( x ); \ } -#define INDIRECT( x ) \ - { \ - { \ - ops_cnt += ( _INDIRECT_C * ( x ) ); \ - inst_cnt[_INDIRECT] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _INDIRECT_P * ( x ) ); \ - } \ - } \ - } \ +#define INDIRECT( x ) \ + { \ + ops_cnt += ( _INDIRECT_C * ( x ) ); \ + inst_cnt[_INDIRECT] += ( x ); \ } -#define PTR_INIT( x ) \ - { \ - { \ - ops_cnt += ( _PTR_INIT_C * ( x ) ); \ - inst_cnt[_PTR_INIT] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _PTR_INIT_P * ( x ) ); \ - } \ - } \ - } \ +#define PTR_INIT( x ) \ + { \ + ops_cnt += ( _PTR_INIT_C * ( x ) ); \ + inst_cnt[_PTR_INIT] += ( x ); \ } -#define TEST( x ) \ - { \ - { \ - ops_cnt += ( _TEST_C * ( x ) ); \ - inst_cnt[_TEST] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _TEST_P * ( x ) ); \ - } \ - } \ - } \ +#define TEST( x ) \ + { \ + ops_cnt += ( _TEST_C * ( x ) ); \ + inst_cnt[_TEST] += ( x ); \ } -#define POWER( x ) \ - { \ - { \ - ops_cnt += ( _POWER_C * ( x ) ); \ - inst_cnt[_POWER] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _POWER_P * ( x ) ); \ - } \ - } \ - } \ +#define POWER( x ) \ + { \ + ops_cnt += ( _POWER_C * ( x ) ); \ + inst_cnt[_POWER] += ( x ); \ } -#define LOG( x ) \ - { \ - { \ - ops_cnt += ( _LOG_C * ( x ) ); \ - inst_cnt[_LOG] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _LOG_P * ( x ) ); \ - } \ - } \ - } \ +#define LOG( x ) \ + { \ + ops_cnt += ( _LOG_C * ( x ) ); \ + inst_cnt[_LOG] += ( x ); \ } -#define MISC( x ) \ - { \ - { \ - ops_cnt += ( _MISC_C * ( x ) ); \ - inst_cnt[_MISC] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _MISC_P * ( x ) ); \ - } \ - } \ - } \ +#define MISC( x ) \ + { \ + ops_cnt += ( _MISC_C * ( x ) ); \ + inst_cnt[_MISC] += ( x ); \ } - -#define FUNC( x ) \ - { \ - { \ - ops_cnt += ( _FUNC_C + _MOVE_C * ( x ) ); \ - inst_cnt[_FUNC]++; \ - inst_cnt[_MOVE] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _FUNC_P + _MOVE_P * ( x ) ); \ - } \ - } \ - } \ +#define FUNC( x ) \ + { \ + ops_cnt += ( _FUNC_C + _MOVE_C * ( x ) ); \ + inst_cnt[_FUNC]++; \ + inst_cnt[_MOVE] += ( x ); \ } - -#define DADD( x ) \ - { \ - { \ - ops_cnt += ( 2 * _ADD_C * ( x ) ); \ - inst_cnt[_ADD] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _ADD_P * ( x ) ); \ - } \ - } \ - } \ +#define DADD( x ) \ + { \ + ops_cnt += ( 2 * _ADD_C * ( x ) ); \ + inst_cnt[_ADD] += ( x ); \ } -#define DMULT( x ) \ - { \ - { \ - ops_cnt += ( 2 * _MULT_C * ( x ) ); \ - inst_cnt[_MULT] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _MULT_P * ( x ) ); \ - } \ - } \ - } \ +#define DMULT( x ) \ + { \ + ops_cnt += ( 2 * _MULT_C * ( x ) ); \ + inst_cnt[_MULT] += ( x ); \ } -#define DMAC( x ) \ - { \ - { \ - ops_cnt += ( 2 * _MAC_C * ( x ) ); \ - inst_cnt[_MAC] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _MAC_P * ( x ) ); \ - } \ - } \ - } \ +#define DMAC( x ) \ + { \ + ops_cnt += ( 2 * _MAC_C * ( x ) ); \ + inst_cnt[_MAC] += ( x ); \ } -#define DMOVE( x ) \ - { \ - { \ - ops_cnt += ( 2 * _MOVE_C * ( x ) ); \ - inst_cnt[_MOVE] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _MOVE_P * ( x ) ); \ - } \ - } \ - } \ +#define DMOVE( x ) \ + { \ + ops_cnt += ( 2 * _MOVE_C * ( x ) ); \ + inst_cnt[_MOVE] += ( x ); \ } -#define DSTORE( x ) \ - { \ - { \ - ops_cnt += ( 2 * _STORE_C * ( x ) ); \ - inst_cnt[_STORE] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _STORE_P * ( x ) ); \ - } \ - } \ - } \ +#define DSTORE( x ) \ + { \ + ops_cnt += ( 2 * _STORE_C * ( x ) ); \ + inst_cnt[_STORE] += ( x ); \ } -#define DLOGIC( x ) \ - { \ - { \ - ops_cnt += ( 2 * _LOGIC_C * ( x ) ); \ - inst_cnt[_LOGIC] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _LOGIC_P * ( x ) ); \ - } \ - } \ - } \ +#define DLOGIC( x ) \ + { \ + ops_cnt += ( 2 * _LOGIC_C * ( x ) ); \ + inst_cnt[_LOGIC] += ( x ); \ } -#define DSHIFT( x ) \ - { \ - { \ - ops_cnt += ( 2 * _SHIFT_C * ( x ) ); \ - inst_cnt[_SHIFT] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _SHIFT_P * ( x ) ); \ - } \ - } \ - } \ +#define DSHIFT( x ) \ + { \ + ops_cnt += ( 2 * _SHIFT_C * ( x ) ); \ + inst_cnt[_SHIFT] += ( x ); \ } -#define DDIV( x ) \ - { \ - { \ - ops_cnt += ( 2 * _DIV_C * ( x ) ); \ - inst_cnt[_DIV] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _DIV_P * ( x ) ); \ - } \ - } \ - } \ +#define DDIV( x ) \ + { \ + ops_cnt += ( 2 * _DIV_C * ( x ) ); \ + inst_cnt[_DIV] += ( x ); \ } -#define DSQRT( x ) \ - { \ - { \ - ops_cnt += ( 2 * _SQRT_C * ( x ) ); \ - inst_cnt[_SQRT] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _SQRT_P * ( x ) ); \ - } \ - } \ - } \ +#define DSQRT( x ) \ + { \ + ops_cnt += ( 2 * _SQRT_C * ( x ) ); \ + inst_cnt[_SQRT] += ( x ); \ } -#define DTRANS( x ) \ - { \ - { \ - ops_cnt += ( 2 * _TRANS_C * ( x ) ); \ - inst_cnt[_TRANS] += ( x ); \ - { \ - static int pcnt; \ - if ( !pcnt ) \ - { \ - pcnt = 1; \ - prom_cnt += ( _TRANS_P * ( x ) ); \ - } \ - } \ - } \ +#define DTRANS( x ) \ + { \ + ops_cnt += ( 2 * _TRANS_C * ( x ) ); \ + inst_cnt[_TRANS] += ( x ); \ } -extern double ops_cnt; -extern double prom_cnt; -extern double inst_cnt[NUM_INST]; - -void reset_wmops( void ); -#define push_wmops( ... ) push_wmops_fct( __VA_ARGS__, NULL ) -void push_wmops_fct( const char *label, ... ); -void pop_wmops( void ); -void update_wmops( void ); -void update_mem( void ); -void print_wmops( void ); - -#else /* WMOPS counting disabled */ +#else -#define reset_wmops() extern int cntr_push_pop; #define push_wmops( x ) ( cntr_push_pop++ ) #define pop_wmops() ( cntr_push_pop-- ) -#define update_wmops() ( assert( cntr_push_pop == 0 ) ) -#define update_mem() +#define reset_wmops() #define print_wmops() +#define update_wmops() ( assert( cntr_push_pop == 0 ) ) +#define update_mem() #define ADD( x ) #define ABS( x ) @@ -629,24 +319,8 @@ extern int cntr_push_pop; #else -/* '*ops_cnt_ptr' is Used to Avoid: "warning: operation on 'ops_cnt' may be undefined" with Cygwin gcc Compiler */ -static double *ops_cnt_ptr = &ops_cnt; -#define OP_COUNT_( op, x ) ( *ops_cnt_ptr += ( op##_C * ( x ) ), inst_cnt[op] += ( x ) ) - -/******************************************************************/ -/* NOTES: */ -/* The 'wmc_flag_' flag is global to avoid declaration in every */ -/* function and 'static' to avoid clashing with other modules */ -/* that include this header file. */ -/* */ -/* The declarations of 'wmc_flag_' and 'wops_' in this header */ -/* file prevent the addition of a 'C' file to the Project. */ -/******************************************************************/ - -/* General Purpose Global Flag */ -static int wmc_flag_ = 0; - /* Operation Counter Wrappers */ +#define OP_COUNT_( op, x ) ( ops_cnt += ( op##_C * ( x ) ), inst_cnt[op] += ( x ) ) #define OP_COUNT_WRAPPER1_( op, val ) ( op, val ) #define OP_COUNT_WRAPPER2_( expr ) \ if ( expr, 0 ) \ @@ -678,8 +352,12 @@ static int wmc_flag_ = 0; #define LOOP_( x ) OP_COUNT_( _LOOP, ( x ) ) #define INDIRECT_( x ) OP_COUNT_( _INDIRECT, ( x ) ) #define PTR_INIT_( x ) OP_COUNT_( _PTR_INIT, ( x ) ) -#define FUNC_( x ) ( OP_COUNT_( _MOVE, ( x ) ), OP_COUNT_( _FUNC, 1 ) ) -#define MISC_( x ) ABS_( x ) +#ifdef WMOPS_DISABLE_FCN_CALL_PENALIZATION +#define FUNC_( x ) ( x ) +#else +#define FUNC_( x ) ( OP_COUNT_( _MOVE, ( x ) ), OP_COUNT_( _FUNC, 1 ) ) +#endif +#define MISC_( x ) ABS_( x ) /* Math Operations */ #define abs_ OP_COUNT_WRAPPER1_( ABS_( 1 ), abs ) @@ -723,9 +401,9 @@ static int wmc_flag_ = 0; #define frexp_ OP_COUNT_WRAPPER1_( MISC_( 2 ), frexp ) #define frexpf_ OP_COUNT_WRAPPER1_( MISC_( 2 ), frexpf ) -/* the macros below are instrumented versions of user-defined macros that might be used in the source code -/* representing some well-known and recognized mathematical operations (that are not defined in math.h) */ -/* Note: the 'wmc_flag_=wmc_flag_' is used to avoid warning: left-hand operand of comma expression has no effect with gcc */ +/* the macros below are instrumented versions of user-defined macros that might be used in the source code + representing some well-known and recognized mathematical operations (that are not defined in math.h) + Note: the 'wmc_flag_=wmc_flag_' is used to avoid warning: left-hand operand of comma expression has no effect with gcc */ #define min_( a, b ) OP_COUNT_WRAPPER1_( MISC_( 1 ), min( ( a ), ( b ) ) ) #define max_( a, b ) OP_COUNT_WRAPPER1_( MISC_( 1 ), max( ( a ), ( b ) ) ) @@ -796,7 +474,6 @@ static int wmc_flag_ = 0; #define return_ \ OP_COUNT_WRAPPER2_( ( wmc_flag_ = stack_tree_level_, STACK_DEPTH_FCT_RETURN ) ) \ return - #define switch_ \ OP_COUNT_WRAPPER2_( ( BRANCH_( 1 ), wmc_flag_ = 1 ) ) \ switch @@ -912,7 +589,6 @@ st: /* This Shouldn't Happen */ /* These are Used to Avoid: "warning: 'name' defined but not used" with Cygwin gcc Compiler */ wmc_flag_ = wmc_flag_; - ops_cnt_ptr = ops_cnt_ptr; fct( "" ); error: default: @@ -974,7 +650,7 @@ typedef struct ROM_Size_Lookup_Table * ROM_Size_Lookup_Table Const_Data_PROM_Table[] = * { * {"../lib_enc/rom_enc.c", 0, NULL}, - * {"../lib_com/*.c", 0, NULL}, + * {"../lib_com/[star].c", 0, NULL}, * {"", -1, NULL} * }; * #endif @@ -987,22 +663,9 @@ typedef enum { USE_BYTES = 0, USE_16BITS = 1, - USE_32BITS = 2, - USE_64BITS = 3 + USE_32BITS = 2 } Counting_Size; -#if ( defined( _WIN32 ) && ( _MSC_VER <= 1800 ) && ( _MSC_VER >= 1300 ) ) -#define __func__ __FUNCTION__ -#elif defined( __STDC_VERSION__ ) && __STDC_VERSION__ < 199901L -#if ( __GNUC__ >= 2 ) -#define __func__ __FUNCTION__ -#else -#define __func__ "" -#endif -#elif defined( __GNUC__ ) -#define __func__ __extension__ __FUNCTION__ -#endif - #ifdef WMOPS @@ -1023,7 +686,7 @@ int pop_stack( const char *filename, const char *fctname ); #define STACK_DEPTH_FCT_CALL ( push_wmops( __func__, "[WMC_AUTO]" ), push_stack( __FILE__, __func__ ) ) /* add push_wmops() in all function calls */ #define STACK_DEPTH_FCT_RETURN ( pop_wmops(), pop_stack( __FILE__, __func__ ) ) /* add pop_wmops() in all function returns */ #else -#define STACK_DEPTH_FCT_CALL push_stack( __FILE__, __FUNCTION__ ) +#define STACK_DEPTH_FCT_CALL push_stack( __FILE__, __func__ ) #define STACK_DEPTH_FCT_RETURN pop_stack( __FILE__, __func__ ) #endif @@ -1044,7 +707,6 @@ void reset_stack( void ); #endif - /* Global counter variable for calculation of complexity weight */ typedef struct { @@ -1102,10 +764,10 @@ typedef struct unsigned int L40_max; /* Complexity Weight of 1 */ unsigned int L40_min; /* Complexity Weight of 1 */ - unsigned int shl_r; /* Complexity Weight of 3 */ - unsigned int L_shl_r; /* Complexity Weight of 3 */ - unsigned int L40_shr_r; /* Complexity Weight of 3 */ - unsigned int L40_shl_r; /* Complexity Weight of 3 */ + unsigned int shl_r; /* Complexity Weight of 2 */ + unsigned int L_shl_r; /* Complexity Weight of 2 */ + unsigned int L40_shr_r; /* Complexity Weight of 2 */ + unsigned int L40_shl_r; /* Complexity Weight of 2 */ unsigned int norm_L40; /* Complexity Weight of 1 */ unsigned int L40_shl; /* Complexity Weight of 1 */ @@ -1122,7 +784,7 @@ typedef struct unsigned int L40_msu; /* Complexity Weight of 1 */ unsigned int msu_r40; /* Complexity Weight of 2 */ unsigned int Mpy_32_16_ss; /* Complexity Weight of 2 */ - unsigned int Mpy_32_32_ss; /* Complexity Weight of 4 */ + unsigned int Mpy_32_32_ss; /* Complexity Weight of 2 */ unsigned int L_mult0; /* Complexity Weight of 1 */ unsigned int L_mac0; /* Complexity Weight of 1 */ @@ -1146,7 +808,7 @@ typedef struct unsigned int rotr; /* Complexity Weight of 3 */ unsigned int L_rotl; /* Complexity Weight of 3 */ unsigned int L_rotr; /* Complexity Weight of 3 */ - unsigned int L40_set; /* Complexity Weight of 3 */ + unsigned int L40_set; /* Complexity Weight of 1 */ unsigned int L40_deposit_h; /* Complexity Weight of 1 */ unsigned int L40_deposit_l; /* Complexity Weight of 1 */ @@ -1158,48 +820,158 @@ typedef struct unsigned int L40_round; /* Complexity Weight of 1 */ unsigned int L_saturate40; /* Complexity Weight of 1 */ unsigned int round40; /* Complexity Weight of 1 */ - unsigned int If; /* Complexity Weight of 4 */ - unsigned int Goto; /* Complexity Weight of 4 */ + unsigned int If; /* Complexity Weight of 3 */ + unsigned int Goto; /* Complexity Weight of 2 */ - unsigned int Break; /* Complexity Weight of 4 */ - unsigned int Switch; /* Complexity Weight of 8 */ + unsigned int Break; /* Complexity Weight of 2 */ + unsigned int Switch; /* Complexity Weight of 6 */ unsigned int For; /* Complexity Weight of 3 */ - unsigned int While; /* Complexity Weight of 4 */ - unsigned int Continue; /* Complexity Weight of 4 */ + unsigned int While; /* Complexity Weight of 3 */ + unsigned int Continue; /* Complexity Weight of 2 */ - unsigned int L_mls; /* Complexity Weight of 6 */ + unsigned int L_mls; /* Complexity Weight of 1 */ unsigned int div_l; /* Complexity Weight of 32 */ - unsigned int i_mult; /* Complexity Weight of 3 */ + unsigned int i_mult; /* Complexity Weight of 1 */ + +/* New complex basic operators */ +#ifdef COMPLEX_OPERATOR + unsigned int CL_shr; /* Complexity Weight of 1 */ + unsigned int CL_shl; /* Complexity Weight of 1 */ + unsigned int CL_add; /* Complexity Weight of 1 */ + unsigned int CL_sub; /* Complexity Weight of 1 */ + unsigned int CL_scale; /* Complexity Weight of 1 */ + unsigned int CL_dscale; /* Complexity Weight of 1 */ + unsigned int CL_msu_j; /* Complexity Weight of 1 */ + unsigned int CL_mac_j; /* Complexity Weight of 1 */ + unsigned int CL_move; /* Complexity Weight of 1 */ + unsigned int CL_Extract_real; /* Complexity Weight of 1 */ + unsigned int CL_Extract_imag; /* Complexity Weight of 1 */ + unsigned int CL_form; /* Complexity Weight of 1 */ + unsigned int CL_multr_32x16; /* Complexity Weight of 2 */ + unsigned int CL_negate; /* Complexity Weight of 1 */ + unsigned int CL_conjugate; /* Complexity Weight of 1 */ + unsigned int CL_mul_j; /* Complexity Weight of 1 */ + unsigned int CL_swap_real_imag; /* Complexity Weight of 1 */ + unsigned int C_add; /* Complexity Weight of 1 */ + unsigned int C_sub; /* Complexity Weight of 1 */ + unsigned int C_mul_j; /* Complexity Weight of 1 */ + unsigned int C_multr; /* Complexity Weight of 2 */ + unsigned int C_form; /* Complexity Weight of 1 */ + + unsigned int C_scale; /* Complexity Weight of 1 */ + unsigned int CL_round32_16; /* Complexity Weight of 1 */ + unsigned int CL_scale_32; /* Complexity Weight of 1 */ + unsigned int CL_dscale_32; /* Complexity Weight of 1 */ + unsigned int CL_multr_32x32; /* Complexity Weight of 2 */ + unsigned int C_mac_r; /* Complexity Weight of 2 */ + unsigned int C_msu_r; /* Complexity Weight of 2 */ + unsigned int C_Extract_real; /* Complexity Weight of 1 */ + unsigned int C_Extract_imag; /* Complexity Weight of 1 */ + unsigned int C_negate; /* Complexity Weight of 1 */ + unsigned int C_conjugate; /* Complexity Weight of 1 */ + unsigned int C_shr; /* Complexity Weight of 1 */ + unsigned int C_shl; /* Complexity Weight of 1 */ + +#endif /* #ifdef COMPLEX_OPERATOR */ + +/* New 64 bit basops */ +#ifdef ENH_64_BIT_OPERATOR + unsigned int move64; /* Complexity Weight of 1 */ + unsigned int W_add_nosat; /* Complexity Weight of 1 */ + unsigned int W_sub_nosat; /* Complexity Weight of 1 */ + unsigned int W_shl; /* Complexity Weight of 1 */ + unsigned int W_shr; /* Complexity Weight of 1 */ + unsigned int W_shl_nosat; /* Complexity Weight of 1 */ + unsigned int W_shr_nosat; /* Complexity Weight of 1 */ + unsigned int W_mac_32_16; /* Complexity Weight of 1 */ + unsigned int W_msu_32_16; /* Complexity Weight of 1 */ + unsigned int W_mult_32_16; /* Complexity Weight of 1 */ + unsigned int W_mult0_16_16; /* Complexity Weight of 1 */ + unsigned int W_mac0_16_16; /* Complexity Weight of 1 */ + unsigned int W_msu0_16_16; /* Complexity Weight of 1 */ + unsigned int W_mult_16_16; /* Complexity Weight of 1 */ + unsigned int W_mac_16_16; /* Complexity Weight of 1 */ + unsigned int W_msu_16_16; /* Complexity Weight of 1 */ + unsigned int W_shl_sat_l; /* Complexity Weight of 1 */ + unsigned int W_sat_l; /* Complexity Weight of 1 */ + unsigned int W_sat_m; /* Complexity Weight of 1 */ + unsigned int W_deposit32_l; /* Complexity Weight of 1 */ + unsigned int W_deposit32_h; /* Complexity Weight of 1 */ + unsigned int W_extract_l; /* Complexity Weight of 1 */ + unsigned int W_extract_h; /* Complexity Weight of 1 */ + unsigned int W_round48_L; /* Complexity Weight of 1 */ + unsigned int W_round32_s; /* Complexity Weight of 1 */ + unsigned int W_norm; /* Complexity Weight of 1 */ + + unsigned int W_add; /* Complexity Weight of 1 */ + unsigned int W_sub; /* Complexity Weight of 1 */ + unsigned int W_neg; /* Complexity Weight of 1 */ + unsigned int W_abs; /* Complexity Weight of 1 */ + unsigned int W_mult_32_32; /* Complexity Weight of 1 */ + unsigned int W_mult0_32_32; /* Complexity Weight of 1 */ + unsigned int W_lshl; /* Complexity Weight of 1 */ + unsigned int W_lshr; /* Complexity Weight of 1 */ + unsigned int W_round64_L; /* Complexity Weight of 1 */ + +#endif /* #ifdef ENH_64_BIT_OPERATOR */ + +#ifdef ENH_32_BIT_OPERATOR + unsigned int Mpy_32_16_1; /* Complexity Weight of 1 */ + unsigned int Mpy_32_16_r; /* Complexity Weight of 1 */ + unsigned int Mpy_32_32; /* Complexity Weight of 1 */ + unsigned int Mpy_32_32_r; /* Complexity Weight of 1 */ + unsigned int Madd_32_16; /* Complexity Weight of 1 */ + unsigned int Madd_32_16_r; /* Complexity Weight of 1 */ + unsigned int Msub_32_16; /* Complexity Weight of 1 */ + unsigned int Msub_32_16_r; /* Complexity Weight of 1 */ + unsigned int Madd_32_32; /* Complexity Weight of 1 */ + unsigned int Madd_32_32_r; /* Complexity Weight of 1 */ + unsigned int Msub_32_32; /* Complexity Weight of 1 */ + unsigned int Msub_32_32_r; /* Complexity Weight of 1 */ +#endif /* #ifdef ENH_32_BIT_OPERATOR */ + +#ifdef ENH_U_32_BIT_OPERATOR + unsigned int UL_addNs; /* Complexity Weight of 1 */ + unsigned int UL_subNs; /* Complexity Weight of 1 */ + unsigned int UL_Mpy_32_32; /* Complexity Weight of 1 */ + unsigned int Mpy_32_32_uu; /* Complexity Weight of 2 */ + unsigned int Mpy_32_16_uu; /* Complexity Weight of 2 */ + unsigned int norm_ul_float; /* Complexity Weight of 1 */ + unsigned int UL_deposit_l; /* Complexity Weight of 1 */ +#endif /* #ifdef ENH_U_32_BIT_OPERATOR */ + +#ifdef CONTROL_CODE_OPS + unsigned int LT_16; /* Complexity Weight of 1 */ + unsigned int GT_16; /* Complexity Weight of 1 */ + unsigned int LE_16; /* Complexity Weight of 1 */ + unsigned int GE_16; /* Complexity Weight of 1 */ + unsigned int EQ_16; /* Complexity Weight of 1 */ + unsigned int NE_16; /* Complexity Weight of 1 */ + unsigned int LT_32; /* Complexity Weight of 1 */ + unsigned int GT_32; /* Complexity Weight of 1 */ + unsigned int LE_32; /* Complexity Weight of 1 */ + unsigned int GE_32; /* Complexity Weight of 1 */ + unsigned int EQ_32; /* Complexity Weight of 1 */ + unsigned int NE_32; /* Complexity Weight of 1 */ + unsigned int LT_64; /* Complexity Weight of 1 */ + unsigned int GT_64; /* Complexity Weight of 1 */ + unsigned int LE_64; /* Complexity Weight of 1 */ + unsigned int GE_64; /* Complexity Weight of 1 */ + unsigned int EQ_64; /* Complexity Weight of 1 */ + unsigned int NE_64; /* Complexity Weight of 1 */ + +#endif /* #ifdef CONTROL_CODE_OPS */ } BASIC_OP; #ifdef WMOPS extern BASIC_OP *multiCounter; -extern int currCounter; - -/* Technical note : - * The following 3 variables are only used for correct complexity - * evaluation of the following structure : - * IF{ - * ... - * } ELSE IF { - * ... - * } ELSE IF { - * ... - * } - * ... - * } ELSE { - * ... - * } - */ -extern int funcId_where_last_call_to_else_occurred; +extern unsigned int currCounter; extern long funcid_total_wmops_at_last_call_to_else; -extern int call_occurred; - -extern long TotalWeightedOperation( void ); -long DeltaWeightedOperation( void ); +extern char func_name_where_last_call_to_else_occurred[]; -void Set_BASOP_WMOPS_counter( int counterId ); -void Reset_BASOP_WMOPS_counter( void ); +long TotalWeightedOperation( unsigned int counterId ); +long DeltaWeightedOperation( unsigned int counterId ); +void Reset_BASOP_WMOPS_counter( unsigned int counterId ); #endif @@ -1219,7 +991,7 @@ void Reset_BASOP_WMOPS_counter( void ); #ifndef WMOPS #define FOR( a ) for ( a ) -#else +#else /* ifndef WMOPS */ #define FOR( a ) \ if ( incrFor(), 0 ) \ ; \ @@ -1230,7 +1002,7 @@ static __inline void incrFor( void ) { multiCounter[currCounter].For++; } -#endif +#endif /* ifndef WMOPS */ /***************************************************************************** @@ -1249,14 +1021,14 @@ static __inline void incrFor( void ) #ifndef WMOPS #define WHILE( a ) while ( a ) -#else +#else /* ifndef WMOPS */ #define WHILE( a ) while ( incrWhile(), a ) static __inline void incrWhile( void ) { multiCounter[currCounter].While++; } -#endif +#endif /* ifndef WMOPS */ /***************************************************************************** @@ -1273,10 +1045,10 @@ static __inline void incrWhile( void ) #ifndef WMOPS #define DO do -#else +#else /* ifndef WMOPS */ #define DO do -#endif +#endif /* ifndef WMOPS */ /***************************************************************************** @@ -1296,30 +1068,16 @@ static __inline void incrWhile( void ) * - or when the 'if' conditions several DSP basic operations, * - or when the 'if' conditions a function call. * - * Complexity weight : 4 + * Complexity weight : 3 * *****************************************************************************/ + #ifndef WMOPS #define IF( a ) if ( a ) - -#else -#define IF( a ) if ( incrIf(), a ) - -static __inline void incrIf( void ) -{ - /* Technical note : - * If the "IF" operator comes just after an "ELSE", its counter - * must not be incremented. - */ - if ( ( currCounter != funcId_where_last_call_to_else_occurred ) || ( TotalWeightedOperation() != funcid_total_wmops_at_last_call_to_else ) || ( call_occurred == 1 ) ) - { - multiCounter[currCounter].If++; - } - - call_occurred = 0; - funcId_where_last_call_to_else_occurred = INT_MAX; -} -#endif +#else /* ifndef WMOPS */ +#define IF( a ) if ( incrIf( __func__ ), a ) +void incrIf( const char *func_name ); +#endif /* ifndef WMOPS */ /***************************************************************************** @@ -1330,36 +1088,18 @@ static __inline void incrIf( void ) * * The macro ELSE should be used instead of the 'else' C statement. * - * Complexity weight : 4 + * Complexity weight : 3 * *****************************************************************************/ + #ifndef WMOPS #define ELSE else - -#else -#define ELSE \ - else if ( incrElse(), 0 ); \ +#else /* ifndef WMOPS */ +#define ELSE \ + else if ( incrElse( __func__ ), 0 ); \ else - -static __inline void incrElse( void ) -{ - multiCounter[currCounter].If++; - - /* We keep track of the funcId of the last function - * which used ELSE {...} structure. - */ - funcId_where_last_call_to_else_occurred = currCounter; - - /* We keep track of the number of WMOPS of this funcId - * when the ELSE macro was called. - */ - funcid_total_wmops_at_last_call_to_else = TotalWeightedOperation(); - - /* call_occurred is set to 0, in order to count the next IF (if necessary) - */ - call_occurred = 0; -} -#endif +void incrElse( const char *func_name ); +#endif /* ifndef WMOPS */ /***************************************************************************** @@ -1370,20 +1110,20 @@ static __inline void incrElse( void ) * * The macro SWITCH should be used instead of the 'switch' C statement. * - * Complexity weight : 8 + * Complexity weight : 6 * *****************************************************************************/ #ifndef WMOPS #define SWITCH( a ) switch ( a ) -#else +#else /* ifndef WMOPS */ #define SWITCH( a ) switch ( incrSwitch(), a ) static __inline void incrSwitch( void ) { multiCounter[currCounter].Switch++; } -#endif +#endif /* ifndef WMOPS */ /***************************************************************************** @@ -1394,13 +1134,13 @@ static __inline void incrSwitch( void ) * * The macro CONTINUE should be used instead of the 'continue' C statement. * - * Complexity weight : 4 + * Complexity weight : 2 * *****************************************************************************/ #ifndef WMOPS #define CONTINUE continue -#else +#else /* ifndef WMOPS */ #define CONTINUE \ if ( incrContinue(), 0 ) \ ; \ @@ -1411,7 +1151,7 @@ static __inline void incrContinue( void ) { multiCounter[currCounter].Continue++; } -#endif +#endif /* ifndef WMOPS */ /***************************************************************************** @@ -1422,16 +1162,16 @@ static __inline void incrContinue( void ) * * The macro BREAK should be used instead of the 'break' C statement. * - * Complexity weight : 4 + * Complexity weight : 2 * *****************************************************************************/ #ifndef WMOPS #define BREAK break -#else +#else /* ifndef WMOPS */ #define BREAK \ if ( incrBreak(), 0 ) \ - break; \ + ; \ else \ break @@ -1439,7 +1179,7 @@ static __inline void incrBreak( void ) { multiCounter[currCounter].Break++; } -#endif +#endif /* ifndef WMOPS */ /***************************************************************************** @@ -1450,13 +1190,13 @@ static __inline void incrBreak( void ) * * The macro GOTO should be used instead of the 'goto' C statement. * - * Complexity weight : 4 + * Complexity weight : 2 * *****************************************************************************/ #ifndef WMOPS #define GOTO goto -#else +#else /* ifndef WMOPS */ #define GOTO \ if ( incrGoto(), 0 ) \ ; \ @@ -1467,6 +1207,33 @@ static __inline void incrGoto( void ) { multiCounter[currCounter].Goto++; } -#endif +#endif /* ifndef WMOPS */ + + +#ifdef CONTROL_CODE_OPS + +extern int LT_16( short var1, short var2 ); +extern int GT_16( short var1, short var2 ); +extern int LE_16( short var1, short var2 ); +extern int GE_16( short var1, short var2 ); +extern int EQ_16( short var1, short var2 ); +extern int NE_16( short var1, short var2 ); + +extern int LT_32( int L_var1, int L_var2 ); +extern int GT_32( int L_var1, int L_var2 ); +extern int LE_32( int L_var1, int L_var2 ); +extern int GE_32( int L_var1, int L_var2 ); +extern int EQ_32( int L_var1, int L_var2 ); +extern int NE_32( int L_var1, int L_var2 ); + +extern int LT_64( long long int L64_var1, long long int L64_var2 ); +extern int GT_64( long long int L64_var1, long long int L64_var2 ); +extern int LE_64( long long int L64_var1, long long int L64_var2 ); +extern int GE_64( long long int L64_var1, long long int L64_var2 ); +extern int EQ_64( long long int L64_var1, long long int L64_var2 ); +extern int NE_64( long long int L64_var1, long long int L64_var2 ); + +#endif /* #ifdef CONTROL_CODE_OPS */ + #endif /* WMOPS_H */ diff --git a/lib_dec/FEC.c b/lib_dec/FEC.c index deb80c697eb1cf6f2f4087b3f79069cee642dce5..7c81376368be694f50b01dca2f3faebe96f3b5c1 100644 --- a/lib_dec/FEC.c +++ b/lib_dec/FEC.c @@ -539,7 +539,9 @@ static void pulseRes_preCalc( { Word16 tmp_pit, tmp_pit_e, tmp_frame, tmp_frame_e; Word32 tmp_pit2; +#ifdef BASOP_NOGLOB Flag Overflow; +#endif /* BASOP_NOGLOB */ tmp_pit = BASOP_Util_Divide1616_Scale( new_pit /*Q0*/, Tc /*Q0*/, &tmp_pit_e ) /*Q15*/; tmp_frame = add( extract_l( L_mult0( L_frame, 64 /*1.f/L_SUBFR Q12*/ ) /*Q12*/ ), 4096 /*1.f Q12*/ ); /*Q12*/ @@ -547,8 +549,16 @@ static void pulseRes_preCalc( tmp_frame = shl( tmp_frame, add( tmp_frame_e, 1 ) ); tmp_frame = sub( 32767 /*1.f Q15*/, tmp_frame ); /*Q15*/ +#ifndef BASOP_NOGLOB + BASOP_SATURATE_WARNING_OFF +#endif /* ! BASOP_NOGLOB */ /*To calc Q15 threshold, overflow may happen - do negation and compare with negated value to check also highest possible value*/ +#ifndef BASOP_NOGLOB + tmp_pit = shl( negate( tmp_pit ), tmp_pit_e ); + BASOP_SATURATE_WARNING_ON +#else /* BASOP_NOGLOB */ tmp_pit = shl_o( negate( tmp_pit ), tmp_pit_e, &Overflow ); +#endif /* BASOP_NOGLOB */ *cond1 = sub( tmp_pit, negate( tmp_frame ) ); diff --git a/lib_dec/FEC_HQ_phase_ecu.c b/lib_dec/FEC_HQ_phase_ecu.c index b8630de3d4ab3f33f0ed3bcda748eb0ce824085d..9055f2b547f7c91c97241cfad16db483a40c8a96 100644 --- a/lib_dec/FEC_HQ_phase_ecu.c +++ b/lib_dec/FEC_HQ_phase_ecu.c @@ -263,7 +263,7 @@ static void trans_ana( const int16_t time_offs, /* i : Time offset */ const float est_mus_content, /* i : 0.0=speech_like ... 1.0=Music (==st->env_stab ) */ const int16_t last_fec, /* i : signal that previous frame was concealed with fec_alg*/ - const int16_t element_mode, /* i : element_mode req to handle EVS_MONO specific BE path */ + const int16_t element_mode, /* i : element_mode req to handle EVS_MONO specific BE path*/ float *alpha, /* o : Magnitude modification factors for fade to average */ float *beta, /* o : Magnitude modification factors for fade to average */ float *beta_mute, /* o : Factor for long-term mute */ @@ -986,7 +986,6 @@ static void subst_spec( float alpha_local; float beta_local; - sincos = sincos_t_ext + 128; Lprot = (int16_t) ( L_PROT32k * output_frame / 640 ); Lprot_1 = 1.0f / Lprot; @@ -1105,9 +1104,10 @@ static void subst_spec( } Xph = corr_phase[m]; - /* extract fractional phase integer index in the range [0...1023] */ Xph_short = (int16_t) ( 0x000003ff & (int32_t) ( ( Xph * 512 ) / EVS_PI ) ); + + if ( Xph_short >= 512 ) { sin_F = -sincos_t_ext[Xph_short - 512]; @@ -2108,12 +2108,10 @@ static void hq_phase_ecu( } trans_ana( prevsynth + 2 * output_frame - Lprot - *time_offs + ph_ecu_lookahead, mag_chg, &ph_dith, mag_chg_1st, output_frame, *time_offs, env_stab, *last_fec, element_mode, alpha, beta, beta_mute, Xavg ); - spec_ana( prevsynth + 2 * output_frame - Lprot - *time_offs + ph_ecu_lookahead, plocs, plocsi, num_p, X_sav, output_frame, bwidth, element_mode, &noise_fac, pcorr ); if ( prev_bfi && *last_fec ) { - if ( element_mode != EVS_MONO ) { *time_offs = (int16_t) ( *time_offs + output_frame ); /* USAN avoid risk of internal int32_t in "+=" */ @@ -2134,7 +2132,7 @@ static void hq_phase_ecu( if ( *time_offs <= 0 ) { /* detect wrap around of st->time_offs */ - *time_offs = (int16_t) INT16_MAX; /* high value --> continued muting will ensure that the now saturated seed is not creating tones */ + *time_offs = (int16_t) INT16_MAX; /* high value --> continued muting will ensure that the now saturated seed is not creating tones */ } trans_ana( prevsynth + 2 * output_frame - Lprot, mag_chg, &ph_dith, mag_chg_1st, output_frame, *time_offs, env_stab, 0, element_mode, alpha, beta, beta_mute, Xavg ); /* 1.0 stable-music, 0.0 speech-like */ diff --git a/lib_dec/acelp_core_dec.c b/lib_dec/acelp_core_dec.c index c5ae6c1ae9c641b92c2666b3e9deda0631af9909..8824a6f840dacbcf36a95e2a5cb73d668bfa7c14 100644 --- a/lib_dec/acelp_core_dec.c +++ b/lib_dec/acelp_core_dec.c @@ -966,7 +966,6 @@ ivas_error acelp_core_dec( /* Apply energy matching when switching to inactive frames */ inact_switch_ematch( exc2, dct_exc_tmp, st->hGSCDec->lt_ener_per_band, st->coder_type, st->inactive_coder_type_flag, st->L_frame, st->bfi, st->last_core, st->last_codec_mode, tdm_low_rate_mode, st->element_mode ); - /* update past excitation signals for LD music post-filter */ if ( st->hMusicPF != NULL ) { @@ -1415,12 +1414,7 @@ ivas_error acelp_core_dec( if ( !st->ppp_mode_dec && ( st->idchan == 0 || st->element_mode != IVAS_CPE_TD || ( st->idchan == 1 && st->element_mode == IVAS_CPE_TD && st->tdm_LRTD_flag ) ) ) { - non_linearity( bwe_exc, bwe_exc_extended, st->hBWE_TD->old_bwe_exc_extended, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale, st->coder_type, voice_factors, st->L_frame -#ifdef NONBE_1328_FIX_NON_LINEARITY - , - st->element_mode -#endif - ); + non_linearity( bwe_exc, bwe_exc_extended, st->hBWE_TD->old_bwe_exc_extended, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale, st->coder_type, voice_factors, st->L_frame, st->element_mode ); } if ( st->core_brate == FRAME_NO_DATA || st->core_brate == SID_2k40 ) diff --git a/lib_dec/amr_wb_dec.c b/lib_dec/amr_wb_dec.c index f36d7751e1ead558be3120d5ee5f19f179184b22..1b4712da1100fe3c9bc9de5538c19e16dde1ffc1 100644 --- a/lib_dec/amr_wb_dec.c +++ b/lib_dec/amr_wb_dec.c @@ -104,8 +104,6 @@ ivas_error amr_wb_dec( error = IVAS_ERR_OK; - push_wmops( "amr_wb_dec" ); - /*------------------------------------------------------------------* * Initialization *------------------------------------------------------------------*/ @@ -826,8 +824,6 @@ ivas_error amr_wb_dec( dbgwrite( &st->bfi, sizeof( int16_t ), 1, output_frame, "res/bfi" ); #endif - pop_wmops(); - return error; } diff --git a/lib_dec/dec_LPD.c b/lib_dec/dec_LPD.c index bf4aab5e3192c5b94d34f598591f7af78ed758a5..3eb6e2ea33865a6745bd068753591e2cb45e63e4 100644 --- a/lib_dec/dec_LPD.c +++ b/lib_dec/dec_LPD.c @@ -71,11 +71,7 @@ void decoder_LPD( { int16_t *prm; int16_t param_lpc[NPRM_LPC_NEW]; -#ifdef FIX_1320_STACK_CPE_DECODER float synth_buf[OLD_SYNTH_INTERNAL_DEC + L_FRAME_PLUS_INTERNAL + M]; -#else - float synth_buf[OLD_SYNTH_SIZE_DEC + L_FRAME_PLUS + M]; -#endif float *synth; float synth_bufFB[OLD_SYNTH_SIZE_DEC + L_FRAME_PLUS + M]; float *synthFB; @@ -128,14 +124,9 @@ void decoder_LPD( synthFB = synth_bufFB + st->hTcxDec->old_synth_lenFB; mvr2r( st->hTcxDec->old_synth, synth_buf, st->hTcxDec->old_synth_len ); mvr2r( st->hTcxDec->old_synthFB, synth_bufFB, st->hTcxDec->old_synth_lenFB ); -#ifdef FIX_1320_STACK_CPE_DECODER set_zero( synth, L_FRAME_PLUS_INTERNAL + M ); -#else - set_zero( synth, L_FRAME_PLUS + M ); -#endif set_zero( synthFB, L_FRAME_PLUS + M ); - /*For post-processing (post-filtering+blind BWE)*/ if ( st->tcxonly == 0 ) { diff --git a/lib_dec/dec_acelp_tcx_main.c b/lib_dec/dec_acelp_tcx_main.c index a591157e44e72a87adab547256f7e80b5326acca..95a3f3275b0e403918159b7d4e6a8a33f3f1214b 100644 --- a/lib_dec/dec_acelp_tcx_main.c +++ b/lib_dec/dec_acelp_tcx_main.c @@ -425,12 +425,7 @@ void dec_acelp_tcx_frame( if ( st->core == ACELP_CORE && st->igf && st->con_tcx == 0 ) { - non_linearity( ptr_bwe_exc, bwe_exc_extended, st->hBWE_TD->old_bwe_exc_extended, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale, st->coder_type, voice_factors, st->L_frame -#ifdef NONBE_1328_FIX_NON_LINEARITY - , - st->element_mode -#endif - ); + non_linearity( ptr_bwe_exc, bwe_exc_extended, st->hBWE_TD->old_bwe_exc_extended, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale, st->coder_type, voice_factors, st->L_frame, st->element_mode ); /* update the old BWE exe memory */ mvr2r( &old_bwe_exc[L_FRAME32k], st->hBWE_TD->old_bwe_exc, PIT16k_MAX * 2 ); diff --git a/lib_dec/dec_tcx.c b/lib_dec/dec_tcx.c index 34dd5770f3e7504a1d3191ac5ea13abfc657a973..23dd28556d66ffad608b8405ffabbd27ca3d4bb3 100644 --- a/lib_dec/dec_tcx.c +++ b/lib_dec/dec_tcx.c @@ -731,6 +731,7 @@ void decoder_tcx_invQ( TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg; tnsSize = 0; + /* just to suppress MSVC warnigs */ prm_target = NULL; prm_ltp = NULL; @@ -755,7 +756,6 @@ void decoder_tcx_invQ( noiseFillingSize = st->hIGFDec->infoIGFStartLine; } - /*-----------------------------------------------------------* * Read TCX parameters * *-----------------------------------------------------------*/ @@ -767,6 +767,7 @@ void decoder_tcx_invQ( index = prm[0]; prm_ltp = &prm[1 + NOISE_FILL_RANGES]; prm_tns = prm_ltp + LTPSIZE; + /* read noise level (fac_ns) */ st->hTcxDec->noise_filling_index[frame_cnt] = prm[1]; } @@ -781,7 +782,6 @@ void decoder_tcx_invQ( *fUseTns = 0; } - /*-----------------------------------------------------------* * Spectrum data * *-----------------------------------------------------------*/ @@ -791,6 +791,7 @@ void decoder_tcx_invQ( prm_hm = prm_tns + tnsSize; prm_sqQ = prm_hm + NPRM_CTX_HM; *prm_sqQ1 = prm_sqQ; + /*-----------------------------------------------------------* * Context HM * *-----------------------------------------------------------*/ @@ -1547,7 +1548,6 @@ void decoder_tcx_tns( if ( ( L_frame == st->L_frame >> 1 ) && st->tcxonly && isTCX5 ) { - if ( st->element_mode == EVS_MONO || ( L_spec < L_frameTCX && !whitenedDomain ) ) /* todo: this is temporary to maintain EVS BE, this is a bug and should be fixed also for EVS (see issue 13) */ { tcx5TnsUngrouping( L_frameTCX >> 1, hTcxCfg->tnsConfig[0][0].iFilterBorders[0] >> 1, x, DEC ); diff --git a/lib_dec/evs_dec.c b/lib_dec/evs_dec.c index 14df97361e34d3d14bfc1a8660a033b0f8a9ee6b..c02263482535ac3318bf34dcf189db8e328bf558 100644 --- a/lib_dec/evs_dec.c +++ b/lib_dec/evs_dec.c @@ -279,7 +279,6 @@ ivas_error evs_dec( return error; } - /*---------------------------------------------------------------------* * Pre-processing for bandwidth switching *---------------------------------------------------------------------*/ diff --git a/lib_dec/fd_cng_dec.c b/lib_dec/fd_cng_dec.c index 983863c852f460454a463aaccdff8cf54c8731c7..adca10685d6e1e3bb9e214522e92c5bc7bab6655 100644 --- a/lib_dec/fd_cng_dec.c +++ b/lib_dec/fd_cng_dec.c @@ -2075,6 +2075,7 @@ void generate_masking_noise_lb_dirac( n_samples_out -= hFdCngCom->frameSize; n_samples_start += hFdCngCom->frameSize; } + /* move generated noise to the 5ms subframe starts in the tc buffer according to the output sampling frequency to avoid overwriting it with the synthesis in case of shared tc and synth channel memory, i.e. non-TSM mode */ slot_size_cng = hFdCngCom->frameSize / DEFAULT_JBM_CLDFB_TIMESLOTS; @@ -2097,6 +2098,7 @@ void generate_masking_noise_lb_dirac( } } + pop_wmops(); return; diff --git a/lib_dec/hq_lr_dec.c b/lib_dec/hq_lr_dec.c index 730955e9a19e0bc6c8139d2b15ac16de43318cec..e50bd127d78b5e29f92f8cf55952344fd5a3f3a1 100644 --- a/lib_dec/hq_lr_dec.c +++ b/lib_dec/hq_lr_dec.c @@ -120,7 +120,9 @@ void hq_lr_dec( Word32 L_band_energy[BANDS_MAX], L_band_energy_tmp[BANDS_MAX]; UWord16 lo; Word16 Q_band_energy; +#ifdef BASOP_NOGLOB Flag Overflow; +#endif /* BASOP_NOGLOB */ HQ_DEC_HANDLE hHQ_core = st->hHQ_core; @@ -263,7 +265,7 @@ void hq_lr_dec( #ifdef BASOP_NOGLOB Ep_fx[i] = L_shl_o( L_tmp, s_max( sub( exp, 6 ), -31 ), &Overflow ); /* Q -6 */ #else - Ep_fx[i] = L_shl( L_tmp, s_max( sub( exp, 6 ), -31 ) ); /* Q -6 */ + Ep_fx[i] = L_shl( L_tmp, s_max( sub( exp, 6 ), -31 ) ); /* Q -6 */ #endif Ep[i] = (float) ( Ep_fx[i] / pow( 2.0, -6 ) ); } @@ -463,10 +465,17 @@ void hq_lr_dec( move16(); } Mpy_32_16_ss( Ep_avrg_fx, tmp, &L_tmp, &lo ); +#ifndef BASOP_NOGLOB + L_tmp = L_shl( L_tmp, sub( 14, exp ) ); /*Q(13+exp-15 +14-exp+2 = 14) */ + L_tmp = L_max( L_tmp, 16384 ); /*14 */ + tmp = extract_l( L_min( L_tmp, beta_fx ) ); /*14 */ + alpha_fx = shl( mult( alpha_fx, tmp ), 1 ); /*14+14-15 +1=14 */ +#else /* BASOP_NOGLOB */ L_tmp = L_shl_o( L_tmp, sub( 14, exp ), &Overflow ); /*Q(13+exp-15 +14-exp+2 = 14) */ L_tmp = L_max( L_tmp, 16384 ); /*14 */ tmp = extract_l( L_min( L_tmp, beta_fx ) ); /*14 */ alpha_fx = shl( mult( alpha_fx, tmp ), 1 ); /*14+14-15 +1=14 */ +#endif /* BASOP_NOGLOB */ } ELSE { @@ -547,10 +556,19 @@ void hq_lr_dec( Mpy_32_16_ss( Ep_peak_fx, tmp, &L_tmp, &lo ); Mpy_32_16_ss( L_tmp, lowband, &L_tmp, &lo ); Mpy_32_16_ss( L_tmp, 18842, &L_tmp, &lo ); - L_tmp = L_shl_o( L_tmp, sub( 27, exp ), &Overflow ); /*Q14 0.5 */ - tmp2 = extract_l( L_min( L_tmp, 19661 ) ); /*14 */ +#ifndef BASOP_NOGLOB + L_tmp = L_shl( L_tmp, sub( 27, exp ) ); /*Q14 0.5 */ + tmp2 = extract_l( L_min( L_tmp, 19661 ) ); /*14 */ +#else /* BASOP_NOGLOB */ + L_tmp = L_shl_o( L_tmp, sub( 27, exp ), &Overflow ); /*Q14 0.5 */ + tmp2 = extract_l( L_min( L_tmp, 19661 ) ); /*14 */ +#endif /* BASOP_NOGLOB */ Mpy_32_16_ss( L_band_energy_tmp[i], tmp2, &L_tmp, &lo ); - L_band_energy_tmp[i] = L_shl_o( L_tmp, 1, &Overflow ); /*Q_band_energy */ +#ifndef BASOP_NOGLOB + L_band_energy_tmp[i] = L_shl( L_tmp, 1 ); /*Q_band_energy */ +#else /* BASOP_NOGLOB */ + L_band_energy_tmp[i] = L_shl_o( L_tmp, 1, &Overflow ); /*Q_band_energy */ +#endif /* BASOP_NOGLOB */ } } #undef WMC_TOOL_SKIP @@ -573,7 +591,11 @@ void hq_lr_dec( } FOR( i = 0; i < bands; i++ ) { +#ifndef BASOP_NOGLOB + Ep_tmp_fx[i] = L_shl( Ep_tmp_fx[i], 2 ); +#else /* BASOP_NOGLOB */ Ep_tmp_fx[i] = L_shl_o( Ep_tmp_fx[i], 2, &Overflow ); +#endif /* BASOP_NOGLOB */ } IF( st->core_brate == ACELP_13k20 ) { @@ -606,8 +628,13 @@ void hq_lr_dec( { IF( sub( i, lowband ) >= 0 && add( sub( i, bands ), p2a_bands ) < 0 ) { +#ifndef BASOP_NOGLOB + Ep_vari_fx = L_add( Ep_vari_fx, L_abs( L_sub( Ep_tmp_fx[i], Ep_tmp_fx[sub( i, 1 )] ) ) ); /*Q15 */ + Ep_avrg_fx = L_add( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ +#else /* BASOP_NOGLOB */ Ep_vari_fx = L_add_o( Ep_vari_fx, L_abs( L_sub( Ep_tmp_fx[i], Ep_tmp_fx[sub( i, 1 )] ) ), &Overflow ); /*Q15 */ Ep_avrg_fx = L_add_o( Ep_avrg_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ +#endif /* BASOP_NOGLOB */ } IF( sub( i, highband ) >= 0 ) @@ -657,7 +684,11 @@ void hq_lr_dec( tmp = sub( bands, p2a_bands ); tmp = sub( tmp, lowband ); /*Q0 */ - tmp1 = extract_h( L_shl_o( Ep_avrg_fx, 1, &Overflow ) ); /*Q0 */ +#ifndef BASOP_NOGLOB + tmp1 = extract_h( L_shl( Ep_avrg_fx, 1 ) ); /*Q0 */ +#else + tmp1 = extract_h( L_shl_o( Ep_avrg_fx, 1, &Overflow ) ); /*Q0 */ +#endif IF( tmp1 != 0 ) { exp = norm_s( tmp1 ); @@ -697,7 +728,11 @@ void hq_lr_dec( { tmp = sub( tmp, lowband ); Mpy_32_16_ss( Ep_tmp_fx[i], tmp, &L_tmp, &lo ); - tmp = extract_h( L_shl_o( L_tmp, 16, &Overflow ) ); /*Q0 */ +#ifndef BASOP_NOGLOB + tmp = extract_h( L_shl( L_tmp, 16 ) ); /*Q0 */ +#else + tmp = extract_h( L_shl_o( L_tmp, 16, &Overflow ) ); /*Q0 */ +#endif IF( tmp != 0 ) { exp = norm_s( tmp ); @@ -722,7 +757,11 @@ void hq_lr_dec( { tmp = sub( tmp, lowband ); - tmp1 = extract_h( L_shl_o( Ep_avrg_fx, 1, &Overflow ) ); /*Q0 */ +#ifndef BASOP_NOGLOB + tmp1 = extract_h( L_shl( Ep_avrg_fx, 1 ) ); /*Q0 */ +#else + tmp1 = extract_h( L_shl_o( Ep_avrg_fx, 1, &Overflow ) ); /*Q0 */ +#endif IF( tmp1 != 0 ) { exp = norm_s( tmp1 ); @@ -761,11 +800,19 @@ void hq_lr_dec( { IF( sub( i, lowband ) >= 0 ) { - Ep_avrg_fx = L_add_o( Ep_avrg_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ +#ifndef BASOP_NOGLOB + Ep_avrg_fx = L_add( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ +#else /* BASOP_NOGLOB */ + Ep_avrg_fx = L_add_o( Ep_avrg_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ +#endif /* BASOP_NOGLOB */ } ELSE { - Ep_avrgL_fx = L_add_o( Ep_avrgL_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ +#ifndef BASOP_NOGLOB + Ep_avrgL_fx = L_add( Ep_avrgL_fx, Ep_tmp_fx[i] ); /*Q15 */ +#else /* BASOP_NOGLOB */ + Ep_avrgL_fx = L_add_o( Ep_avrgL_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ +#endif /* BASOP_NOGLOB */ IF( L_sub( Ep_tmp_fx[i], Ep_peak_fx ) > 0 ) { Ep_peak_fx = Ep_tmp_fx[i]; @@ -785,7 +832,11 @@ void hq_lr_dec( move16(); FOR( i = 0; i < lowband; i++ ) { - tmp = extract_h( L_shl_o( Ep_avrgL_fx, 1, &Overflow ) ); /*Q0 */ +#ifndef BASOP_NOGLOB + tmp = extract_h( L_shl( Ep_avrgL_fx, 1 ) ); /*Q0 */ +#else + tmp = extract_h( L_shl_o( Ep_avrgL_fx, 1, &Overflow ) ); /*Q0 */ +#endif IF( tmp != 0 ) { exp = norm_s( tmp ); diff --git a/lib_dec/igf_dec.c b/lib_dec/igf_dec.c old mode 100644 new mode 100755 index ba7c4993fd1f8722f8a81aa6ca62afbc61958b53..8f91c43fb2282956044fa51d42850d9407e7a44f --- a/lib_dec/igf_dec.c +++ b/lib_dec/igf_dec.c @@ -1573,6 +1573,7 @@ void IGFDecRestoreTCX10SubFrameData( return; } + /*-----------------------------------------------------------------------* * init_igf_dec() * @@ -1592,9 +1593,7 @@ void init_igf_dec( hIGFDec->flag_sparse = &hIGFDec->flag_sparseBuf[0]; hIGFDec->infoTCXNoise = &hIGFDec->infoTCXNoiseBuf[0]; hIGFDec->virtualSpec = &hIGFDec->virtualSpecBuf[0]; -#ifdef FIX_1385_INIT_IGF_STOP_FREQ hIGFDec->infoIGFStopFreq = 0; -#endif return; } diff --git a/lib_dec/igf_scf_dec.c b/lib_dec/igf_scf_dec.c old mode 100644 new mode 100755 diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index d1dad30234f00a6bbe1c922e8b84aa9ca30cd753..60808714ca483d496c57d63a40762cf7a116930a 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -301,8 +301,8 @@ static ivas_error ivas_binRenderer_convModuleOpen( for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) { int16_t tmp = 0; - tmp = chIdx; + tmp = chIdx; if ( isLoudspeaker ) { if ( input_config == IVAS_AUDIO_CONFIG_5_1 ) @@ -560,10 +560,12 @@ static ivas_error ivas_binaural_hrtf_open( n_channels = FOA_CHANNELS; } } + if ( ( error = ivas_allocate_binaural_hrtf( HrtfFastConv, n_channels, HrtfFastConv->allocate_init_flag ) ) != IVAS_ERR_OK ) { return error; } + for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) { if ( renderer_type == RENDERER_BINAURAL_FASTCONV && HrtfFastConv->n_channels == HRTF_LS_CHANNELS ) @@ -586,6 +588,7 @@ static ivas_error ivas_binaural_hrtf_open( HrtfFastConv->rightImag[i][j] = rightBRIRImag[i][j]; } } + if ( input_config == IVAS_AUDIO_CONFIG_HOA3 && HrtfFastConv->n_channels == HOA3_CHANNELS ) { for ( j = 0; j < HOA3_CHANNELS; j++ ) @@ -621,13 +624,14 @@ static ivas_error ivas_binaural_hrtf_open( } } } + mvr2r( fastconvReverberationTimes, HrtfFastConv->fastconvReverberationTimes, CLDFB_NO_CHANNELS_MAX ); mvr2r( fastconvReverberationEneCorrections, HrtfFastConv->fastconvReverberationEneCorrections, CLDFB_NO_CHANNELS_MAX ); *hHrtfFastConv = HrtfFastConv; - } - return IVAS_ERR_OK; + return IVAS_ERR_OK; + } } @@ -671,6 +675,7 @@ static void ivas_binaural_obtain_DMX( for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) { float dmxConst = dmxmtx_table[chOutIdx][chIdx]; + for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) { for ( k = 0; k < numTimeSlots; k++ ) @@ -790,8 +795,6 @@ ivas_error ivas_rend_openCldfbRend( int16_t convBand; ivas_error error; - error = IVAS_ERR_OK; - /*-----------------------------------------------------------------* * prepare library opening *-----------------------------------------------------------------*/ @@ -824,7 +827,6 @@ ivas_error ivas_rend_openCldfbRend( } ivas_output_init( hBinRenderer->hInputSetup, inConfig ); - if ( ( error = getAudioConfigNumChannels( inConfig, &hBinRenderer->hInputSetup->nchan_out_woLFE ) ) != IVAS_ERR_OK ) { return error; @@ -856,14 +858,16 @@ ivas_error ivas_rend_openCldfbRend( } pCldfbRend->binaural_latency_ns = (int32_t) ( pCldfbRend->hHrtfFastConv->FASTCONV_latency_s * 1000000000.f ); + hBinRenderer->hReverb = NULL; hBinRenderer->hEFAPdata = NULL; pCldfbRend->hCldfbRend = hBinRenderer; - return error; + return IVAS_ERR_OK; } + /*------------------------------------------------------------------------- * ivas_binRenderer_open() * @@ -879,8 +883,6 @@ ivas_error ivas_binRenderer_open( ivas_error error; const IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pRoomAcoustics; - error = IVAS_ERR_OK; - /*-----------------------------------------------------------------* * prepare library opening *-----------------------------------------------------------------*/ @@ -993,6 +995,7 @@ ivas_error ivas_binRenderer_open( if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) { pRoomAcoustics = ( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ? &( st_ivas->hRenderConfig->roomAcoustics ) : NULL; + if ( ( error = ivas_binaural_reverb_init( &( hBinRenderer->hReverb ), st_ivas->hHrtfStatistics, hBinRenderer->conv_band, @@ -1002,6 +1005,7 @@ ivas_error ivas_binRenderer_open( st_ivas->hHrtfFastConv->fastconvReverberationTimes, st_ivas->hHrtfFastConv->fastconvReverberationEneCorrections, NULL ) ) != IVAS_ERR_OK ) + { return error; } @@ -1022,7 +1026,11 @@ ivas_error ivas_binRenderer_open( ivas_dirac_dec_get_response( (int16_t) ls_azimuth_CICP19[k], (int16_t) ls_elevation_CICP19[k], hBinRenderer->hReverb->foa_enc[k], 1 ); } } +#ifdef IVAS_RTPDUMP + else if ( st_ivas->ivas_format == MC_FORMAT && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation || st_ivas->hCombinedOrientationData ) ) +#else else if ( st_ivas->ivas_format == MC_FORMAT && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) ) +#endif { if ( ( error = efap_init_data( &( st_ivas->hEFAPdata ), st_ivas->hIntSetup.ls_azimuth, st_ivas->hIntSetup.ls_elevation, st_ivas->hIntSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) { @@ -1037,7 +1045,7 @@ ivas_error ivas_binRenderer_open( /* Copy the handles to main handle */ st_ivas->hBinRenderer = hBinRenderer; - return error; + return IVAS_ERR_OK; } @@ -1522,13 +1530,14 @@ void ivas_rend_CldfbMultiBinRendProcess( head_track_post.num_quaternions = 0; head_track_post.shd_rot_max_order = -1; head_track_post.Quaternions[0] = ivas_split_rend_get_sf_rot_data( pHeadRotData->headPositionsPostRend, sf_idx ); -#endif +#endif #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG ivas_binRenderer( hCldfbRend, pMultiBinPoseData, *pCombinedOrientationData, MAX_PARAM_SPATIAL_SUBFRAMES, &head_track_post, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer_sfIn, Cldfb_ImagBuffer_sfIn ); #else ivas_binRenderer( hCldfbRend, pMultiBinPoseData, *pCombinedOrientationData, MAX_PARAM_SPATIAL_SUBFRAMES, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer_sfIn, Cldfb_ImagBuffer_sfIn ); #endif + for ( pose_idx = 0; pose_idx < hCldfbRend->numPoses; pose_idx++ ) { for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index 0feea67e6ec84d6754b92e1e0fa9e7ee89f6197d..a82b81243fd6894584ca6681f4d2fc2c69951f7f 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -75,12 +75,8 @@ ivas_error ivas_core_dec( float synth[CPE_CHANNELS][L_FRAME48k]; float tmp_buffer[L_FRAME48k]; int16_t tmps, incr; -#ifdef FIX_1320_STACK_CPE_DECODER float *bwe_exc_extended[CPE_CHANNELS] = { NULL, NULL }; int16_t flag_bwe_bws; -#else - float bwe_exc_extended[CPE_CHANNELS][L_FRAME32k + NL_BUFF_OFFSET]; -#endif float voice_factors[CPE_CHANNELS][NB_SUBFR16k]; int16_t core_switching_flag[CPE_CHANNELS]; float old_syn_12k8_16k[CPE_CHANNELS][L_FRAME16k]; @@ -121,8 +117,8 @@ ivas_error ivas_core_dec( last_element_brate = hSCE->last_element_brate; /* note: this parameter is unused */ last_element_mode = IVAS_SCE; hStereoTD = NULL; - p_output_mem = NULL; hStereoCng = NULL; + p_output_mem = NULL; nchan_out = 1; if ( st_ivas != NULL && st_ivas->ivas_format == ISM_FORMAT ) { @@ -205,9 +201,7 @@ ivas_error ivas_core_dec( set_f( voice_factors[n], 0.f, NB_SUBFR16k ); set_f( hb_synth[n], 0.0f, L_FRAME48k ); -#ifdef FIX_1320_STACK_CPE_DECODER bwe_exc_extended[n] = hb_synth[n]; /* note: reuse the buffer */ -#endif /*------------------------------------------------------------------* * Decision matrix (selection of technologies) @@ -237,7 +231,7 @@ ivas_error ivas_core_dec( } /* n_channels loop */ /* MDCT stereo -> DFT stereo switching */ - if ( hCPE != NULL && hCPE->last_element_mode == IVAS_CPE_MDCT && hCPE->element_mode == IVAS_CPE_DFT ) + if ( last_element_mode == IVAS_CPE_MDCT && sts[0]->element_mode == IVAS_CPE_DFT ) { int16_t ovl, fade_len; if ( sts[0]->L_frame != sts[0]->last_L_frame ) @@ -356,7 +350,8 @@ ivas_error ivas_core_dec( if ( st->core == ACELP_CORE ) { /* ACELP core decoder */ - if ( ( error = acelp_core_dec( st, output[n], synth[n], save_hb_synth, bwe_exc_extended[n], voice_factors[n], old_syn_12k8_16k[n], sharpFlag[n], pitch_buf[n], &unbits[n], &sid_bw[n], hStereoTD, tdm_lsfQ_PCh, use_cldfb_for_dft, last_element_mode, last_element_brate, flag_sec_CNA, nchan_out, hStereoCng, read_sid_info ) ) != IVAS_ERR_OK ) + if ( ( error = acelp_core_dec( st, output[n], synth[n], save_hb_synth, bwe_exc_extended[n], voice_factors[n], old_syn_12k8_16k[n], sharpFlag[n], pitch_buf[n], &unbits[n], &sid_bw[n], hStereoTD, + tdm_lsfQ_PCh, use_cldfb_for_dft, last_element_mode, last_element_brate, flag_sec_CNA, nchan_out, hStereoCng, read_sid_info ) ) != IVAS_ERR_OK ) { return error; } @@ -364,8 +359,8 @@ ivas_error ivas_core_dec( if ( ( st->core == TCX_20_CORE || st->core == TCX_10_CORE ) && st->element_mode != IVAS_CPE_MDCT ) { - /* TCX decoder */ - stereo_tcx_core_dec( st, frameMode[n], output[n], synth[n], pitch_buf[n], sba_dirac_stereo_flag, hStereoTD, last_element_mode, flag_sec_CNA, hStereoCng, nchan_out, st_ivas == NULL ? 0 : st_ivas->ivas_format ); + /* TCX core decoder */ + stereo_tcx_core_dec( st, frameMode[n], output[n], synth[n], pitch_buf[n], sba_dirac_stereo_flag, hStereoTD, last_element_mode, flag_sec_CNA, hCPE == NULL ? NULL : hCPE->hStereoCng, nchan_out, st_ivas == NULL ? 0 : st_ivas->ivas_format ); } if ( st->core == HQ_CORE ) @@ -470,7 +465,7 @@ ivas_error ivas_core_dec( mvr2r( synth[n], hSCE->save_synth, output_frame ); } - if ( ( error = core_switching_post_dec( st, synth[n], output[n], p_output_mem, use_cldfb_for_dft, output_frame, 0 /*core_switching_flag*/, sba_dirac_stereo_flag, nchan_out, ( hCPE != NULL ) ? hCPE->last_element_mode : IVAS_SCE ) ) != IVAS_ERR_OK ) + if ( ( error = core_switching_post_dec( st, synth[n], output[n], p_output_mem, use_cldfb_for_dft, output_frame, 0 /*core_switching_flag*/, sba_dirac_stereo_flag, nchan_out, last_element_mode ) ) != IVAS_ERR_OK ) { return error; } @@ -518,10 +513,8 @@ ivas_error ivas_core_dec( * SWB(FB) BWE decoding *---------------------------------------------------------------------*/ -#ifdef FIX_1320_STACK_CPE_DECODER flag_bwe_bws = ( output_Fs >= 32000 && st->core == ACELP_CORE && st->bwidth > NB && st->bws_cnt > 0 && st->bfi == 0 ); -#endif if ( st->extl == SWB_TBE || st->extl == FB_TBE || ( st->coder_type != AUDIO && st->coder_type != INACTIVE && st->core_brate >= SID_2k40 && st->core == ACELP_CORE && !st->con_tcx && output_Fs >= 32000 && st->bwidth > NB && st->bws_cnt > 0 ) ) { /* SWB TBE decoder */ @@ -533,24 +526,17 @@ ivas_error ivas_core_dec( fb_tbe_dec( st, tmp_buffer /*fb_exc*/, hb_synth[n], tmp_buffer /*fb_synth_ref*/, output_frame ); } } -#ifdef FIX_1320_STACK_CPE_DECODER else if ( st->extl == SWB_BWE || st->extl == FB_BWE || flag_bwe_bws ) -#else - else if ( st->extl == SWB_BWE || st->extl == FB_BWE || ( output_Fs >= 32000 && st->core == ACELP_CORE && st->bwidth > NB && st->bws_cnt > 0 && !st->ppp_mode_dec && !( st->nelp_mode_dec == 1 && st->bfi == 1 ) ) ) -#endif { /* SWB BWE decoder */ swb_bwe_dec( st, output[n], synth[n], hb_synth[n], use_cldfb_for_dft, output_frame ); } -#ifdef FIX_1320_STACK_CPE_DECODER if ( ( st->core == ACELP_CORE && ( st->extl == -1 || st->extl == SWB_CNG ) ) && flag_bwe_bws == 0 ) { set_f( hb_synth[n], 0.0f, L_FRAME48k ); } -#endif - /*---------------------------------------------------------------------* * FEC - recovery after lost HQ core (smoothing of the BWE component) *---------------------------------------------------------------------*/ @@ -584,23 +570,6 @@ ivas_error ivas_core_dec( stereo_icBWE_dec( hCPE, hb_synth[0], hb_synth[1], tmp_buffer /*fb_synth_ref*/, voice_factors[0], output_frame ); } -#ifndef FIX_1320_STACK_CPE_DECODER - if ( st->element_mode == EVS_MONO ) - { - /*----------------------------------------------------------------* - * BFI waveform adjustment - *----------------------------------------------------------------*/ - - if ( st->core == ACELP_CORE && !st->bfi && st->prev_bfi && st->last_total_brate >= HQ_48k && st->last_codec_mode == MODE2 && ( st->last_core_bfi == TCX_20_CORE || st->last_core_bfi == TCX_10_CORE ) && st->hPlcInfo->concealment_method == TCX_NONTONAL && st->hPlcInfo->nbLostCmpt < 4 ) - { - tmps = NS2SA( output_Fs, DELAY_CLDFB_NS ); - - waveform_adj2( st->hPlcInfo, st->hTonalMDCTConc->secondLastPcmOut, synth[n] + tmps, tmps, st->hPlcInfo->nbLostCmpt + 1, st->bfi ); - - st->hPlcInfo->Pitch = 0; - } - } -#endif /*----------------------------------------------------------------* * Transition and synchronization of BWE components *----------------------------------------------------------------*/ @@ -615,20 +584,8 @@ ivas_error ivas_core_dec( } else { -#ifndef FIX_1320_STACK_CPE_DECODER - if ( st->extl == SWB_BWE_HIGHRATE || st->extl == FB_BWE_HIGHRATE ) - { - /* HR SWB BWE on top of ACELP@16kHz */ - tmps = NS2SA( output_Fs, DELAY_BWE_TOTAL_NS ); - } - else - { -#endif - /* TBE on top of ACELP@16kHz */ - tmps = NS2SA( output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_16k_NS ); -#ifndef FIX_1320_STACK_CPE_DECODER - } -#endif + /* TBE on top of ACELP@16kHz */ + tmps = NS2SA( output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_16k_NS ); } /* Smooth transitions when switching between different technologies */ diff --git a/lib_dec/ivas_cpe_dec.c b/lib_dec/ivas_cpe_dec.c index 5de10f5e7b439a45a5dcd9a237cac7b98ac733f9..8094a09052575ccb1f213b90f9d09bc78d9fd63a 100644 --- a/lib_dec/ivas_cpe_dec.c +++ b/lib_dec/ivas_cpe_dec.c @@ -54,9 +54,7 @@ static void read_stereo_mode_and_bwidth( CPE_DEC_HANDLE hCPE, const Decoder_Stru static void stereo_mode_combined_format_dec( const Decoder_Struct *st_ivas, CPE_DEC_HANDLE hCPE ); -#ifdef FIX_1320_STACK_CPE_DECODER static ivas_error stereo_dft_dec_main( CPE_DEC_HANDLE hCPE, const int32_t ivas_total_brate, const int16_t n_channels, float *p_res_buf, float *output[], float outputHB[][L_FRAME48k], const int16_t output_frame ); -#endif /*--------------------------------------------------------------------------* @@ -78,14 +76,10 @@ ivas_error ivas_cpe_dec( int16_t last_bwidth; int16_t tdm_ratio_idx; float outputHB[CPE_CHANNELS][L_FRAME48k]; /* 'float' buffer for output HB synthesis, both channels */ -#ifdef FIX_1320_STACK_CPE_DECODER float *res_buf = NULL; -#else - float res_buf[STEREO_DFT_N_8k]; -#endif CPE_DEC_HANDLE hCPE; - STEREO_DFT_CONFIG_DATA_HANDLE hConfigDft; Decoder_State **sts; + STEREO_DFT_CONFIG_DATA_HANDLE hConfigDft; int32_t ivas_total_brate; ivas_error error; int32_t cpe_brate; @@ -273,11 +267,8 @@ ivas_error ivas_cpe_dec( } else { - -#ifdef FIX_1320_STACK_CPE_DECODER res_buf = outputHB[0]; /* note: temporarily reused buffer */ -#endif if ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) { nb_bits -= nb_bits_metadata; @@ -460,47 +451,10 @@ ivas_error ivas_cpe_dec( if ( hCPE->element_mode == IVAS_CPE_DFT && !( hCPE->nchan_out == 1 && hConfigDft->res_cod_mode == STEREO_DFT_RES_COD_OFF ) ) { -#ifdef FIX_1320_STACK_CPE_DECODER if ( ( error = stereo_dft_dec_main( hCPE, ivas_total_brate, n_channels, res_buf, output, outputHB, output_frame ) ) != IVAS_ERR_OK ) { return error; } -#else - float DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX]; - - /* core decoder */ - if ( ( error = ivas_core_dec( NULL, NULL, hCPE, st_ivas->hMCT, n_channels, output, outputHB, DFT, 0 ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* DFT Stereo residual decoding */ - if ( hCPE->hStereoDft->res_cod_band_max > 0 && !st_ivas->bfi ) - { - stereo_dft_dec_res( hCPE, res_buf, output[1] ); - - stereo_dft_dec_analyze( hCPE, output[1], DFT, 1, L_FRAME8k, output_frame, DFT_STEREO_DEC_ANA_LB, 0, 0 ); - } - - /* DFT stereo CNG */ - stereo_dtf_cng( hCPE, ivas_total_brate, DFT, output_frame ); - - /* decoding */ - if ( hCPE->nchan_out == 1 ) - { - stereo_dft_unify_dmx( hCPE->hStereoDft, sts[0], DFT, hCPE->input_mem[1], hCPE->hStereoCng->prev_sid_nodata ); - } - else - { - stereo_dft_dec( hCPE->hStereoDft, sts[0], DFT, hCPE->input_mem[1], hCPE->hStereoCng, 0, 0, 0, 0, 0, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); - } - - /* synthesis iFFT */ - for ( n = 0; n < hCPE->nchan_out; n++ ) - { - stereo_dft_dec_synthesize( hCPE, DFT, n, output[n], output_frame ); - } -#endif } else if ( hCPE->element_mode == IVAS_CPE_TD ) { @@ -625,7 +579,6 @@ ivas_error ivas_cpe_dec( return error; } -#ifdef FIX_1320_STACK_CPE_DECODER /*------------------------------------------------------------------------- * stereo_dft_dec_main() @@ -692,7 +645,6 @@ static ivas_error stereo_dft_dec_main( return IVAS_ERR_OK; } -#endif /*------------------------------------------------------------------------- * create_cpe_dec() diff --git a/lib_dec/ivas_decision_matrix_dec.c b/lib_dec/ivas_decision_matrix_dec.c index c78ad3802f56b454cf4aadd4780e731f37d59337..da624d5a66125d9c37d193e8f65c276e6d6556dd 100644 --- a/lib_dec/ivas_decision_matrix_dec.c +++ b/lib_dec/ivas_decision_matrix_dec.c @@ -442,6 +442,7 @@ void ivas_decision_matrix_dec( *-----------------------------------------------------------------*/ st->inactive_coder_type_flag = 0; /* AVQ by default */ + if ( st->total_brate <= MAX_GSC_INACTIVE_BRATE ) { st->inactive_coder_type_flag = 1; /* GSC */ diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 142cac7e50c4a9bcd7045e83230561ddfcd2331f..31f47c4dfdf03f541bbe35d64895bd4d04b4babd 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -896,7 +896,6 @@ ivas_error ivas_dirac_dec_config( } if ( !st_ivas->hDiracDecBin[0]->useTdDecorr ) - { if ( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_params == NULL ) { @@ -1008,6 +1007,7 @@ void ivas_dirac_dec_read_BS( } *nb_bits += ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), nchan_transport, NULL, SBA_FORMAT ); + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].azimuth[i] = hQMetaData->q_direction[0].band_data[1].azimuth[0]; @@ -1076,7 +1076,6 @@ void ivas_dirac_dec_read_BS( } } - *nb_bits += ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), nchan_transport, NULL, SBA_FORMAT ); for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) @@ -1251,7 +1250,9 @@ void ivas_qmetadata_to_dirac( /* SID/zero-frame: 1 direction, 5 bands, nblocks re-generated out of SID decoder*/ start_band = 0; hDirAC->hConfig->nbands = 5; + ivas_dirac_config_bands( hDirAC->band_grouping, hDirAC->hConfig->nbands, nbands, NULL, 0, 0, NULL, 1 ); + nbands = 5; } else @@ -1325,6 +1326,7 @@ void ivas_qmetadata_to_dirac( { qBand_idx = band; } + diffuseness = 1.0f - q_direction->band_data[qBand_idx].energy_ratio[0]; #ifdef DEBUG_MODE_DIRAC dbgwrite( &diffuseness, sizeof( float ), 1, 1, "./res/dirac_dec_diffuseness.dat" ); @@ -1552,12 +1554,8 @@ void ivas_dirac_dec_render( uint16_t slot_size, n_samples_sf, ch, nchan_intern; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; float *output_f_local[MAX_OUTPUT_CHANNELS]; -#ifdef FIX_RENDERER_STACK float *p_output_f[MAX_OUTPUT_CHANNELS]; float output_f_local_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; -#else - float output_f_local_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k]; -#endif hSpatParamRendCom = st_ivas->hSpatParamRendCom; @@ -1568,11 +1566,7 @@ void ivas_dirac_dec_render( for ( ch = 0; ch < nchan_intern; ch++ ) { output_f_local[ch] = output_f_local_buff[ch]; -#ifdef FIX_RENDERER_STACK p_output_f[ch] = output_f[ch]; -#else - set_zero( output_f_local_buff[ch], nSamplesAsked ); -#endif } slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); @@ -1599,7 +1593,6 @@ void ivas_dirac_dec_render( for ( ch = 0; ch < nchan_intern; ch++ ) { -#ifdef FIX_RENDERER_STACK /* move to output */ if ( !( ( st_ivas->hDirACRend->hOutSetup.separateChannelEnabled ) && ( st_ivas->hDirACRend->hOutSetup.separateChannelIndex == ch || st_ivas->hDirACRend->hOutSetup.separateChannelIndex + 1 == ch ) ) ) { @@ -1607,24 +1600,12 @@ void ivas_dirac_dec_render( } p_output_f[ch] += n_samples_sf; -#else - output_f_local[ch] += n_samples_sf; -#endif } /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); } -#ifndef FIX_RENDERER_STACK - for ( ch = 0; ch < nchan_intern; ch++ ) - { - if ( !( ( st_ivas->hDirACRend->hOutSetup.separateChannelEnabled ) && ( st_ivas->hDirACRend->hOutSetup.separateChannelIndex == ch || st_ivas->hDirACRend->hOutSetup.separateChannelIndex + 1 == ch ) ) ) - { - mvr2r( output_f_local_buff[ch], output_f[ch], *nSamplesRendered ); - } - } -#endif if ( hSpatParamRendCom->slots_rendered == hSpatParamRendCom->num_slots ) { if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) @@ -1643,7 +1624,6 @@ void ivas_dirac_dec_render( } -#ifdef FIX_1319_STACK_SBA_DECODER /*------------------------------------------------------------------------- * Local functions to perform binaural rendering with optimized stack *------------------------------------------------------------------------*/ @@ -1726,7 +1706,6 @@ static void binRenderer( return; } -#endif /*------------------------------------------------------------------------- @@ -1739,14 +1718,8 @@ void ivas_dirac_dec_render_sf( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ const int16_t nchan_transport, /* i : number of transport channels */ -#ifdef FIX_1319_STACK_SBA_DECODER float *pppQMfFrame_ts_re[HOA3_CHANNELS][CLDFB_NO_COL_MAX], - float *pppQMfFrame_ts_im[HOA3_CHANNELS][CLDFB_NO_COL_MAX] -#else - 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] -#endif -) + float *pppQMfFrame_ts_im[HOA3_CHANNELS][CLDFB_NO_COL_MAX] ) { int16_t i, ch, idx_in, idx_lfe; DIRAC_DEC_HANDLE hDirAC; @@ -1760,20 +1733,11 @@ void ivas_dirac_dec_render_sf( float *p_Rmat; int16_t slot_idx_start, slot_idx_start_cldfb_synth, md_idx; - /*CLDFB: last output channels reserved to LFT for CICPx*/ -#ifdef FIX_1319_STACK_SBA_DECODER + /*CLDFB: last output channels reserved to LFE for CICPx*/ float Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; float Cldfb_RealBuffer_Binaural[1][BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[1][BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; -#else - float Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_RealBuffer_Temp[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer_Temp[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; -#endif int16_t index, num_freq_bands; /* local copies of azi, ele, diffuseness */ @@ -1950,29 +1914,17 @@ void ivas_dirac_dec_render_sf( /* CLDFB Analysis*/ for ( ch = 0; ch < nchan_transport; ch++ ) { -#ifdef FIX_1319_STACK_SBA_DECODER cldfbAnalysis_ts( &( st_ivas->hTcBuffer->tc[hDirACRend->sba_map_tc[ch]][hSpatParamRendCom->num_freq_bands * index_slot] ), Cldfb_RealBuffer_Binaural[0][ch][slot_idx], /* note: it is a tmp. buffer at this point */ Cldfb_ImagBuffer_Binaural[0][ch][slot_idx], /* note: it is a tmp. buffer at this point */ hSpatParamRendCom->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); -#else - cldfbAnalysis_ts( &( st_ivas->hTcBuffer->tc[hDirACRend->sba_map_tc[ch]][hSpatParamRendCom->num_freq_bands * index_slot] ), - Cldfb_RealBuffer_Temp[ch][slot_idx], - Cldfb_ImagBuffer_Temp[ch][slot_idx], - hSpatParamRendCom->num_freq_bands, - st_ivas->cldfbAnaDec[ch] ); -#endif } } if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) { -#ifdef FIX_1319_STACK_SBA_DECODER ivas_omasa_preProcessStereoTransportsForEditedObjects( st_ivas, Cldfb_RealBuffer_Binaural[0], Cldfb_ImagBuffer_Binaural[0], hSpatParamRendCom->num_freq_bands, subframe_idx ); -#else - ivas_omasa_preProcessStereoTransportsForEditedObjects( st_ivas, Cldfb_RealBuffer_Temp, Cldfb_ImagBuffer_Temp, hSpatParamRendCom->num_freq_bands, subframe_idx ); -#endif } } @@ -1999,13 +1951,8 @@ void ivas_dirac_dec_render_sf( { for ( ch = 0; ch < nchan_transport; ch++ ) { -#ifdef FIX_1319_STACK_SBA_DECODER mvr2r( Cldfb_RealBuffer_Binaural[0][ch][slot_idx], Cldfb_RealBuffer[ch][0], hSpatParamRendCom->num_freq_bands ); mvr2r( Cldfb_ImagBuffer_Binaural[0][ch][slot_idx], Cldfb_ImagBuffer[ch][0], hSpatParamRendCom->num_freq_bands ); -#else - mvr2r( Cldfb_RealBuffer_Temp[ch][slot_idx], Cldfb_RealBuffer[ch][0], hSpatParamRendCom->num_freq_bands ); - mvr2r( Cldfb_ImagBuffer_Temp[ch][slot_idx], Cldfb_ImagBuffer[ch][0], hSpatParamRendCom->num_freq_bands ); -#endif } } else @@ -2135,7 +2082,11 @@ void ivas_dirac_dec_render_sf( { mvs2s( &hSpatParamRendCom->azimuth[md_idx][hDirAC->hConfig->enc_param_start_band], &azimuth[hDirAC->hConfig->enc_param_start_band], hSpatParamRendCom->num_freq_bands - hDirAC->hConfig->enc_param_start_band ); mvs2s( &hSpatParamRendCom->elevation[md_idx][hDirAC->hConfig->enc_param_start_band], &elevation[hDirAC->hConfig->enc_param_start_band], hSpatParamRendCom->num_freq_bands - hDirAC->hConfig->enc_param_start_band ); +#ifdef IVAS_RTPDUMP + if ( ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation || st_ivas->hCombinedOrientationData ) && st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 ) +#else if ( ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) && st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 ) +#endif { num_freq_bands = hDirAC->band_grouping[hDirAC->hConfig->enc_param_start_band]; rotateAziEle_DirAC( azimuth, elevation, num_freq_bands, hSpatParamRendCom->num_freq_bands, p_Rmat ); @@ -2299,7 +2250,6 @@ void ivas_dirac_dec_render_sf( hodirac_flag, hDirAC->hConfig->dec_param_estim ); - if ( hDirAC->hConfig->dec_param_estim ) { float fac = 1.0f / (float) hSpatParamRendCom->subframe_nbslots[subframe_idx]; @@ -2394,6 +2344,7 @@ void ivas_dirac_dec_render_sf( for ( j = 0; j < nchan_out_woLFE; j++ ) { + 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 ) @@ -2448,7 +2399,6 @@ void ivas_dirac_dec_render_sf( } } -#ifdef FIX_1319_STACK_SBA_DECODER /* Perform binaural rendering */ if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { @@ -2465,42 +2415,12 @@ void ivas_dirac_dec_render_sf( Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); } -#else - /* Perform binaural rendering */ - ivas_binRenderer( st_ivas->hBinRenderer, ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, - st_ivas->hCombinedOrientationData, hSpatParamRendCom->subframe_nbslots[subframe_idx], -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - NULL, -#endif - Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - int16_t pos_idx; - for ( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ ) - { - for ( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) - { - for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) - { - mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); - mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); - } - } - } - } -#endif - /* Inverse CLDFB*/ for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) { /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */ -#ifdef FIX_1319_STACK_SBA_DECODER float *RealBuffer[CLDFB_SLOTS_PER_SUBFRAME]; float *ImagBuffer[CLDFB_SLOTS_PER_SUBFRAME]; -#else - float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; - float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; -#endif for ( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++ ) { @@ -2524,13 +2444,8 @@ void ivas_dirac_dec_render_sf( } else { -#ifdef FIX_1319_STACK_SBA_DECODER float *RealBuffer[CLDFB_SLOTS_PER_SUBFRAME]; float *ImagBuffer[CLDFB_SLOTS_PER_SUBFRAME]; -#else - float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; - float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; -#endif int16_t outchannels; idx_in = 0; diff --git a/lib_dec/ivas_dirac_output_synthesis_cov.c b/lib_dec/ivas_dirac_output_synthesis_cov.c index f7606e71448d26ae9931970d13c0b916191902a3..bfad98855652ac814e84714f048e3b1b64261784 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov.c @@ -350,8 +350,10 @@ void ivas_dirac_dec_output_synthesis_cov_param_mc_collect_slot( cmplx_matrix_square( real_in_buffer, imag_in_buffer, num_bands, nchan_in, real_buffer, imag_buffer ); v_add( cx, real_buffer, cx, nchan_in * nchan_in ); + v_add( cx_imag, imag_buffer, cx_imag, nchan_in * nchan_in ); + return; } @@ -580,7 +582,6 @@ int16_t computeMixingMatrices( maximum( svd_s_buffer, lengthCx, &limit ); limit = (float) max( limit * reg_Sx, SQRT_EPSILON ); - for ( i = 0; i < lengthCx; ++i ) { svd_s_buffer[i] = ( ( svd_s_buffer[i] > limit ) ? svd_s_buffer[i] : limit ); diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index c8b4260434279290b14d30e1a8e5377445c09408..7e09074af0431592f1b423e7985adcbda5c6ee82 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -54,8 +54,6 @@ static ivas_error ivas_read_format( Decoder_Struct *st_ivas, int16_t *num_bits_r static ivas_error doSanityChecks_IVAS( Decoder_Struct *st_ivas ); -static AUDIO_CONFIG ivas_set_audio_config_from_sba_order( const int16_t sba_order ); - /*-------------------------------------------------------------------* * ivas_set_audio_config_from_sba_order() @@ -463,7 +461,7 @@ ivas_error ivas_dec_get_format( *-------------------------------------------------------------------*/ ivas_error ivas_dec_setup( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ) { int16_t k, idx, num_bits_read; @@ -646,12 +644,12 @@ ivas_error ivas_dec_setup( /* read Ambisonic (SBA) planar flag */ st_ivas->sba_planar = st_ivas->bit_stream[num_bits_read]; num_bits_read += SBA_PLANAR_BITS; + /* read Ambisonic (SBA) order (0 for signaling OSBA format at low bitrates)*/ st_ivas->sba_order = st_ivas->bit_stream[num_bits_read + 1]; st_ivas->sba_order += 2 * st_ivas->bit_stream[num_bits_read]; num_bits_read += SBA_ORDER_BITS; - /* read Ambisonic (SBA) order */ /* read the real Ambisonic order when the above bits are used to signal OSBA format */ if ( ivas_total_brate < IVAS_24k4 ) { @@ -677,13 +675,14 @@ ivas_error ivas_dec_setup( /*correct number of CPEs for discrete ISM coding*/ if ( st_ivas->ini_frame > 0 && st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { - int16_t n; + { + int16_t n; - n = st_ivas->nchan_transport + st_ivas->nchan_ism; - st_ivas->nCPE = ( n + 1 ) >> 1; + n = st_ivas->nchan_transport + st_ivas->nchan_ism; + st_ivas->nCPE = ( n + 1 ) >> 1; + } } } - if ( ivas_osba_ism_mode_select( ivas_total_brate, st_ivas->nchan_ism ) == ISM_SBA_MODE_DISC ) { st_ivas->ism_mode = ISM_SBA_MODE_DISC; @@ -952,7 +951,6 @@ static ivas_error ivas_read_format( st_ivas->ivas_format = MASA_ISM_FORMAT; } } - ( *num_bits_read )++; } break; @@ -1037,7 +1035,6 @@ static ivas_error ivas_read_format( if ( st_ivas->ivas_format == SBA_FORMAT ) { - /* read Ambisonic (SBA) planar flag */ st_ivas->sba_planar = st_ivas->bit_stream[*num_bits_read]; *num_bits_read += SBA_PLANAR_BITS; @@ -1157,9 +1154,7 @@ ivas_error ivas_init_decoder_front( st_ivas->ism_mode = ISM_MODE_NONE; st_ivas->mc_mode = MC_MODE_NONE; -#ifdef FIX_1384_MSAN_ivas_spar_dec_open st_ivas->sid_format = SID_FORMAT_NONE; -#endif st_ivas->sba_dirac_stereo_flag = 0; /* HRTF binauralization latency in ns */ @@ -1260,9 +1255,7 @@ ivas_error ivas_init_decoder( int16_t sce_id, cpe_id; int16_t numCldfbAnalyses, numCldfbSyntheses; int16_t granularity, n_channels_transport_jbm; -#ifdef FIX_1330_JBM_MEMORY int16_t nchan_out_buff; -#endif int32_t output_Fs, ivas_total_brate; int32_t delay_ns; AUDIO_CONFIG output_config; @@ -1520,7 +1513,8 @@ ivas_error ivas_init_decoder( return error; } - if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ), + if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, + ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ), st_ivas->ivas_format ) ) != IVAS_ERR_OK ) { return error; @@ -1666,7 +1660,8 @@ ivas_error ivas_init_decoder( return error; } - if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ), + if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, + ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ), st_ivas->ivas_format ) ) != IVAS_ERR_OK ) { return error; @@ -2131,7 +2126,6 @@ ivas_error ivas_init_decoder( if ( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { - if ( ( error = ivas_reverb_open( &st_ivas->hReverb, st_ivas->hHrtfStatistics, st_ivas->hRenderConfig, output_Fs ) ) != IVAS_ERR_OK ) { return error; @@ -2154,7 +2148,11 @@ ivas_error ivas_init_decoder( } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { +#ifdef IVAS_RTPDUMP + if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM && st_ivas->ivas_format == MC_FORMAT && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation || st_ivas->hCombinedOrientationData ) ) +#else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM && st_ivas->ivas_format == MC_FORMAT && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) ) +#endif { if ( ( error = efap_init_data( &( st_ivas->hEFAPdata ), st_ivas->hIntSetup.ls_azimuth, st_ivas->hIntSetup.ls_elevation, st_ivas->hIntSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) { @@ -2162,8 +2160,8 @@ ivas_error ivas_init_decoder( } } - if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, - st_ivas->hRenderConfig, st_ivas->hHrtfCrend, st_ivas->hHrtfStatistics, st_ivas->hDecoderConfig->output_Fs, 0, ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, output_config, + st_ivas->hRenderConfig, st_ivas->hHrtfCrend, st_ivas->hHrtfStatistics, output_Fs, 0, ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) { return error; } @@ -2180,6 +2178,7 @@ ivas_error ivas_init_decoder( { return error; } + if ( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { if ( ( error = ivas_reverb_open( &st_ivas->hReverb, st_ivas->hHrtfStatistics, st_ivas->hRenderConfig, output_Fs ) ) != IVAS_ERR_OK ) @@ -2195,23 +2194,23 @@ ivas_error ivas_init_decoder( } } - if ( st_ivas->renderer_type == RENDERER_DIRAC && ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) + if ( ( st_ivas->renderer_type == RENDERER_DIRAC ) && + ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) { /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */ if ( ( error = ivas_omasa_objects_delay_open( st_ivas ) ) != IVAS_ERR_OK ) { return error; } - if ( ( error = ivas_omasa_separate_object_renderer_open( st_ivas ) ) != IVAS_ERR_OK ) { return error; } } + if ( st_ivas->renderer_type == RENDERER_OMASA_OBJECT_EXT ) { /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */ - if ( ( error = ivas_omasa_objects_delay_open( st_ivas ) ) != IVAS_ERR_OK ) { return error; @@ -2261,6 +2260,7 @@ ivas_error ivas_init_decoder( { return error; } + if ( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { if ( ( error = ivas_reverb_open( &st_ivas->hReverb, st_ivas->hHrtfStatistics, st_ivas->hRenderConfig, output_Fs ) ) != IVAS_ERR_OK ) @@ -2271,7 +2271,6 @@ ivas_error ivas_init_decoder( } } - /*-----------------------------------------------------------------* * CLDFB handles for rendering *-----------------------------------------------------------------*/ @@ -2322,6 +2321,7 @@ ivas_error ivas_init_decoder( { delay_ns = 0; } + if ( st_ivas->hBinRenderer != NULL ) { if ( st_ivas->hBinRenderer->render_lfe ) @@ -2394,34 +2394,13 @@ ivas_error ivas_init_decoder( * Allocate floating-point output audio buffers *-----------------------------------------------------------------*/ -#ifdef FIX_1330_JBM_MEMORY nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, ivas_total_brate ); if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff, hDecoderConfig->Opt_tsm, st_ivas->hTcBuffer ) ) != IVAS_ERR_OK ) { return error; } -#else -#ifdef FIX_NCHAN_BUFFERS - k = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); - for ( n = 0; n < k; n++ ) -#else - for ( n = 0; n < ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); n++ ) -#endif - { - /* note: these are intra-frame heap memories */ - if ( ( st_ivas->p_output_f[n] = (float *) malloc( ( 48000 / FRAMES_PER_SEC ) * sizeof( float ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for floating-point output audio buffer!\n" ) ); - } - } - - for ( ; n < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; n++ ) - { - st_ivas->p_output_f[n] = NULL; - } -#endif - return error; + return IVAS_ERR_OK; } @@ -2847,6 +2826,7 @@ void ivas_destroy_dec( { ivas_td_binaural_close( &st_ivas->hBinRendererTd ); } + if ( st_ivas->hHrtfTD != NULL ) { BSplineModelEvalDealloc( &st_ivas->hHrtfTD->ModelParams, &st_ivas->hHrtfTD->ModelEval ); @@ -2875,12 +2855,14 @@ void ivas_destroy_dec( /* Limiter struct */ ivas_limiter_close( &( st_ivas->hLimiter ) ); + /* Decoder configuration structure */ if ( st_ivas->hDecoderConfig != NULL ) { free( st_ivas->hDecoderConfig ); st_ivas->hDecoderConfig = NULL; } + /* JBM TC buffer structure */ ivas_jbm_dec_tc_buffer_close( &st_ivas->hTcBuffer ); if ( st_ivas->hJbmMetadata != NULL ) @@ -2892,15 +2874,7 @@ void ivas_destroy_dec( /* floating-point output audio buffers */ for ( i = 0; i < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; i++ ) { -#ifdef FIX_1330_JBM_MEMORY st_ivas->p_output_f[i] = NULL; -#else - if ( st_ivas->p_output_f[i] != NULL ) - { - free( st_ivas->p_output_f[i] ); - st_ivas->p_output_f[i] = NULL; - } -#endif } /* main IVAS handle */ @@ -2963,6 +2937,7 @@ void ivas_init_dec_get_num_cldfb_instances( *numCldfbAnalyses = st_ivas->nchan_transport + 1; } } + if ( st_ivas->hDiracDecBin[0]->useTdDecorr ) { *numCldfbAnalyses += 2; @@ -3173,12 +3148,19 @@ static ivas_error doSanityChecks_IVAS( return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Wrong output configuration specified for Stereo!" ); } } - if ( output_config != IVAS_AUDIO_CONFIG_MONO && output_config != IVAS_AUDIO_CONFIG_STEREO && output_config != IVAS_AUDIO_CONFIG_5_1 && output_config != IVAS_AUDIO_CONFIG_7_1 && output_config != IVAS_AUDIO_CONFIG_5_1_2 && output_config != IVAS_AUDIO_CONFIG_5_1_4 && output_config != IVAS_AUDIO_CONFIG_7_1_4 && output_config != IVAS_AUDIO_CONFIG_LS_CUSTOM && output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) - - if ( ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) && output_Fs != 48000 ) + /* Verify output configuration for other formats */ + else + { + if ( output_config == IVAS_AUDIO_CONFIG_INVALID ) { - return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Error: Only 48kHz output sampling rate is supported for split rendering." ); + return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified!" ); } + } + + if ( ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) && output_Fs != 48000 ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Error: Only 48kHz output sampling rate is supported for split rendering." ); + } if ( st_ivas->hDecoderConfig->Opt_Headrotation ) { diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index d0498839580b85d95d55e1fbc5ec3b2af77e66a0..c29dd20a674bccbd8d9c1c19fcf62b6335d5bef1 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -60,11 +60,7 @@ static ivas_error ivas_ism_bitrate_switching_dec( int16_t tc_nchan_tc_new; int16_t tc_nchan_allocate_new; int16_t tc_granularity_new; -#ifdef FIX_1330_JBM_MEMORY int16_t nchan_out_buff; -#else - int16_t nchan_out_buff, nchan_out_buff_old; -#endif nCPE_old = st_ivas->nCPE; nSCE_old = st_ivas->nSCE; @@ -74,9 +70,6 @@ static ivas_error ivas_ism_bitrate_switching_dec( st_ivas->ism_mode = last_ism_mode; ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old ); st_ivas->ism_mode = ism_mode; -#ifndef FIX_1330_JBM_MEMORY - nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); -#endif if ( ( error = ivas_ism_config( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->nchan_ism, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 0 ) ) != IVAS_ERR_OK ) { @@ -129,7 +122,7 @@ static ivas_error ivas_ism_bitrate_switching_dec( } /* 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 */ + render what still fits in the new granularity */ tc_granularity_new = ivas_jbm_dec_get_render_granularity( st_ivas->renderer_type, RENDERER_DISABLE, st_ivas->hDecoderConfig->output_Fs ); if ( tc_granularity_new < st_ivas->hTcBuffer->n_samples_granularity ) @@ -179,7 +172,6 @@ static ivas_error ivas_ism_bitrate_switching_dec( if ( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { if ( ( error = ivas_reverb_open( &st_ivas->hReverb, st_ivas->hHrtfStatistics, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) - { return error; } @@ -290,18 +282,6 @@ static ivas_error ivas_ism_bitrate_switching_dec( return error; } -#ifndef FIX_1330_JBM_MEMORY - /*-----------------------------------------------------------------* - * floating-point output audio buffers - *-----------------------------------------------------------------*/ - - nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); - - if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) - { - return error; - } -#endif /*-----------------------------------------------------------------* * JBM TC buffers *-----------------------------------------------------------------*/ @@ -315,7 +295,6 @@ static ivas_error ivas_ism_bitrate_switching_dec( tc_nchan_allocate_new = tc_nchan_tc_new; tc_nchan_full_new = tc_nchan_tc_new; - 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; @@ -341,7 +320,6 @@ static ivas_error ivas_ism_bitrate_switching_dec( mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hSpatParamRendCom->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); } -#ifdef FIX_1330_JBM_MEMORY /*-----------------------------------------------------------------* * floating-point output audio buffers @@ -352,7 +330,6 @@ static ivas_error ivas_ism_bitrate_switching_dec( { return error; } -#endif return IVAS_ERR_OK; } @@ -402,7 +379,7 @@ ivas_error ivas_ism_dec_config( if ( st_ivas->ini_active_frame != 0 ) { /* ISM bit-rate switching */ - if ( ( st_ivas->ism_mode != last_ism_mode ) || ( st_ivas->hDecoderConfig->ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate ) ) + if ( ( st_ivas->ism_mode != last_ism_mode ) || ( ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate ) ) { if ( ( error = ivas_ism_bitrate_switching_dec( st_ivas, nchan_transport_old, last_ism_mode ) ) != IVAS_ERR_OK ) { @@ -426,6 +403,7 @@ ivas_error ivas_ism_dec_config( /* ISM mode switching */ if ( st_ivas->ism_mode != last_ism_mode ) { + if ( ( error = ivas_ism_bitrate_switching_dec( st_ivas, nchan_transport_old, last_ism_mode ) ) != IVAS_ERR_OK ) { return error; diff --git a/lib_dec/ivas_ism_metadata_dec.c b/lib_dec/ivas_ism_metadata_dec.c index bf25409a8a3d9379c5fd99ac898c37e917c57b01..5f65826b5ba9f0b5e74ec39808f32279f563e647 100644 --- a/lib_dec/ivas_ism_metadata_dec.c +++ b/lib_dec/ivas_ism_metadata_dec.c @@ -682,9 +682,9 @@ void ivas_ism_reset_metadata_handle_dec( *-------------------------------------------------------------------------*/ ivas_error ivas_ism_metadata_dec_create( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const int16_t n_ISms, /* i : number of separately coded objects */ - int32_t element_brate_tmp[] /* o : element bitrate per object */ + int32_t element_brate_tmp[] /* o : element bitrate per object */ ) { int16_t ch; diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 785c5cfdd4a64c3f42f3da38eacfa72089757f24..0c51b5216bf6c8cfacb4e031ff114a5e675ae013 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -51,7 +51,6 @@ static void ivas_ism_param_dec_tc_gain_adjust( Decoder_Struct *st_ivas, const int16_t nSamples, const int16_t nFadeLength, float *p_data_f[] ); - /*-----------------------------------------------------------------------* * Local function definitions *-----------------------------------------------------------------------*/ @@ -599,6 +598,7 @@ ivas_error ivas_param_ism_dec_open( if ( st_ivas->hTcBuffer == NULL ) { 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, granularity ) ) != IVAS_ERR_OK ) { return error; @@ -712,7 +712,6 @@ void ivas_ism_dec_digest_tc( #ifndef NONBE_1412_AVOID_ROUNDING_AZ_ELEV int16_t azimuth, elevation; #endif - /* we have a full frame interpolator, adapt it */ /* for BE testing */ if ( ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ) == st_ivas->hTcBuffer->n_samples_available ) @@ -760,7 +759,6 @@ void ivas_ism_dec_digest_tc( azimuth = (int16_t) floorf( st_ivas->hIsmMetaData[i]->edited_azimuth + 0.5f ); elevation = (int16_t) floorf( st_ivas->hIsmMetaData[i]->edited_elevation + 0.5f ); #endif - if ( ( st_ivas->renderer_type == RENDERER_TD_PANNING || st_ivas->renderer_type == RENDERER_OSBA_LS || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM || ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM && st_ivas->ivas_format == SBA_ISM_FORMAT && st_ivas->ism_mode == ISM_SBA_MODE_DISC ) ) && @@ -781,14 +779,12 @@ void ivas_ism_dec_digest_tc( if ( st_ivas->hEFAPdata != NULL ) { - #ifdef NONBE_1412_AVOID_ROUNDING_AZ_ELEV efap_determine_gains( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains[i], st_ivas->hIsmMetaData[i]->edited_azimuth, elevation, EFAP_MODE_EFAP ); #else efap_determine_gains( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains[i], azimuth, elevation, EFAP_MODE_EFAP ); #endif - v_multc( st_ivas->hIsmRendererData->gains[i], - st_ivas->hIsmMetaData[i]->edited_gain, st_ivas->hIsmRendererData->gains[i], st_ivas->hEFAPdata->numSpk ); + v_multc( st_ivas->hIsmRendererData->gains[i], st_ivas->hIsmMetaData[i]->edited_gain, st_ivas->hIsmRendererData->gains[i], st_ivas->hEFAPdata->numSpk ); } } else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || @@ -1289,7 +1285,6 @@ void ivas_param_ism_params_to_masa_param_mapping( hMasaIsmData = st_ivas->hMasaIsmData; nBins = hSpatParamRendCom->num_freq_bands; - if ( st_ivas->hISMDTX.dtx_flag ) { float energy_ratio; @@ -1356,6 +1351,7 @@ void ivas_param_ism_params_to_masa_param_mapping( hSpatParamRendCom->surroundingCoherence[sf_idx][bin_idx] = 0.0; } } + for ( obj = 0; obj < st_ivas->nchan_ism; obj++ ) { for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c index 82fabafcfa92a63c11daf9ff369d8f075a8d5764..11d797253aa423b253950e3707bf6404e9e97e93 100644 --- a/lib_dec/ivas_ism_renderer.c +++ b/lib_dec/ivas_ism_renderer.c @@ -176,7 +176,6 @@ void ivas_ism_render_sf( assert( slots_to_render == 0 ); assert( last_sf <= st_ivas->hTcBuffer->nb_subframes ); #endif - num_objects = st_ivas->nchan_ism; nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; @@ -194,25 +193,11 @@ void ivas_ism_render_sf( ism_md_subframe_update_jbm = st_ivas->hTcBuffer->nb_subframes - 2; } -#ifndef FIX_1330_JBM_MEMORY - if ( st_ivas->hDecoderConfig->Opt_tsm ) - { - for ( i = 0; i < num_objects; i++ ) - { - p_tc[i] = &st_ivas->hTcBuffer->tc[i][tc_offset]; - } - } - else + for ( i = 0; i < num_objects; i++ ) { -#endif - for ( i = 0; i < num_objects; i++ ) - { - mvr2r( &output_f[i][tc_offset], tc_local[i], n_samples_to_render ); - p_tc[i] = tc_local[i]; - } -#ifndef FIX_1330_JBM_MEMORY + mvr2r( &output_f[i][tc_offset], tc_local[i], n_samples_to_render ); + p_tc[i] = tc_local[i]; } -#endif for ( i = 0; i < nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; i++ ) { @@ -244,6 +229,7 @@ void ivas_ism_render_sf( { rotateAziEle( st_ivas->hIsmMetaData[i]->edited_azimuth, st_ivas->hIsmMetaData[i]->edited_elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat[st_ivas->hCombinedOrientationData->subframe_idx], 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 ); @@ -374,7 +360,6 @@ ivas_error ivas_omasa_separate_object_renderer_open( init_interpolator_length = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ); interpolator_length = init_interpolator_length; - if ( ( st_ivas->hIsmRendererData->interpolator = (float *) malloc( sizeof( float ) * init_interpolator_length ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM renderer interpolator \n" ) ); @@ -437,12 +422,7 @@ void ivas_omasa_separate_object_render_jbm( const uint16_t nSamplesRendered, /* i : number of samples rendered */ float input_f_in[][L_FRAME48k], /* i : separated object signal */ float *output_f[], /* o : rendered time signal */ -#ifdef FIX_1330_JBM_MEMORY const int16_t subframes_rendered /* i : number of subframes rendered */ -#else - const int16_t subframes_rendered, /* i : number of subframes rendered */ - const int16_t slots_rendered /* i : number of CLDFB slots rendered */ -#endif ) { VBAP_HANDLE hVBAPdata; @@ -483,32 +463,15 @@ void ivas_omasa_separate_object_render_jbm( num_objects = st_ivas->nchan_ism; } -#ifndef FIX_1330_JBM_MEMORY - offsetSamples = slots_rendered * hSpatParamRendCom->slot_size; -#endif for ( j = 0; j < nchan_out_woLFE + num_lfe; j++ ) { output_f_local[j] = output_f[j]; } -#ifndef FIX_1330_JBM_MEMORY - if ( st_ivas->hDecoderConfig->Opt_tsm ) - { - for ( obj = 0; obj < num_objects; obj++ ) - { - input_f[obj] = &st_ivas->hTcBuffer->tc[obj + 2][offsetSamples]; - } - } - else + for ( obj = 0; obj < num_objects; obj++ ) { -#endif - for ( obj = 0; obj < num_objects; obj++ ) - { - input_f[obj] = input_f_in[obj]; - } -#ifndef FIX_1330_JBM_MEMORY + input_f[obj] = input_f_in[obj]; } -#endif slots_to_render = nSamplesRendered / hSpatParamRendCom->slot_size; first_sf = subframes_rendered; @@ -522,7 +485,6 @@ void ivas_omasa_separate_object_render_jbm( for ( obj = 0; obj < num_objects; obj++ ) { - /* Delay the signal to match CLDFB delay. Delay the whole buffer with the first rendering call of the stretched buffer. */ offsetSamples = 0; for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index ae595dd31507cbdc5cc1f49ad1230944cc7f7b9e..b19f0bdf7ecfc2b2729a803959e96120c27bc967 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -148,6 +148,7 @@ ivas_error ivas_jbm_dec_tc( } ivas_ism_dtx_limit_noise_energy_for_near_silence( st_ivas->hSCE, st_ivas->hISMDTX.sce_id_dtx, st_ivas->nchan_transport ); + ivas_param_ism_dec_dequant_md( st_ivas ); } else if ( st_ivas->ism_mode == ISM_MODE_PARAM ) @@ -156,6 +157,7 @@ ivas_error ivas_jbm_dec_tc( { return error; } + ivas_param_ism_dec_dequant_md( st_ivas ); } else /* ISM_MODE_DISC */ @@ -756,25 +758,12 @@ void 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*/ -#ifndef JBM_MEMORY_OPT - , - float *data /* i : transport channels */ -#endif ) { -#ifdef JBM_MEMORY_OPT float tmp_buf[MAX_JBM_L_FRAME48k]; float *p_data_f[FOA_CHANNELS + MAX_NUM_OBJECTS]; -#else - 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]; -#endif int16_t n, n_render_timeslots, n_ch_cldfb; -#ifdef FIX_1330_JBM_MEMORY int16_t ch, offset, len_offset; -#else - int16_t ch; -#endif DECODER_TC_BUFFER_HANDLE hTcBuffer; hTcBuffer = st_ivas->hTcBuffer; @@ -782,7 +771,6 @@ void ivas_jbm_dec_feed_tc_to_renderer( if ( st_ivas->hDecoderConfig->Opt_tsm ) { -#ifdef JBM_MEMORY_OPT int16_t n_samples_still_available; int16_t n_ch_full_copy, n_ch_res_copy; @@ -793,7 +781,6 @@ void ivas_jbm_dec_feed_tc_to_renderer( 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; -#ifdef FIX_1330_JBM_MEMORY /* buffers are shared between 'hTcBuffer->tc[]' and 'p_output_f[]': in case of 'length(hTcBuffer->tc[]) < length(p_output_f[])', reset of TC buffers pointers is needed after ivas_buffer_interleaved_to_deinterleaved() */ @@ -808,7 +795,6 @@ void ivas_jbm_dec_feed_tc_to_renderer( } } -#endif for ( ch = 0; ch < n_ch_full_copy; ch++ ) { mvr2r( hTcBuffer->tc[ch], tmp_buf, nSamplesForRendering ); @@ -829,47 +815,6 @@ void ivas_jbm_dec_feed_tc_to_renderer( mvr2r( tmp_buf + nSamplesForRendering - *nSamplesResidual, hTcBuffer->tc_buffer_old[ch], *nSamplesResidual ); } } -#else - int16_t n_samples_still_available, m; - int16_t n_ch_full_copy; - int16_t n_ch_res_copy; - - for ( n = 0; n < n_ch_cldfb; n++ ) - { - p_data_f[n] = &data_f[n][0]; - } - - 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 * hTcBuffer->nchan_transport_jbm + ch]; - } - } - - if ( n_ch_res_copy > 0 ) - { - for ( ; ch < hTcBuffer->nchan_transport_jbm; ch++ ) - { - mvr2r( hTcBuffer->tc[ch], p_data_f[ch], n_samples_still_available ); - - for ( m = 0; m < nSamplesForRendering; m++ ) - { - p_data_f[ch][n_samples_still_available + m] = data[m * hTcBuffer->nchan_transport_jbm + ch]; - } - mvr2r( p_data_f[ch] + hTcBuffer->n_samples_available, hTcBuffer->tc[ch], *nSamplesResidual ); - } - } -#endif n_render_timeslots = hTcBuffer->n_samples_available / hTcBuffer->n_samples_granularity; } @@ -880,16 +825,8 @@ void ivas_jbm_dec_feed_tc_to_renderer( p_data_f[n] = &st_ivas->p_output_f[n][0]; } -#ifdef FIX_NCHAN_BUFFERS -#ifdef JBM_MEMORY_OPT ch = max( hTcBuffer->nchan_transport_jbm, hTcBuffer->nchan_buffer_full ); -#else - ch = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); -#endif for ( n = 0; n < ch; n++ ) -#else - for ( n = 0; n < ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); n++ ) -#endif { hTcBuffer->tc[n] = st_ivas->p_output_f[n]; /* note: buffers needed in the TD decorellator */ } @@ -962,15 +899,12 @@ ivas_error ivas_jbm_dec_render( if ( !st_ivas->hDecoderConfig->Opt_tsm ) { -#ifdef JBM_MEMORY_OPT for ( n = 0; n < MAX_INTERN_CHANNELS; n++ ) -#else - for ( n = 0; n < MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS; n++ ) -#endif { st_ivas->hTcBuffer->tc[n] = p_output[n]; } } + for ( n = 0; n < st_ivas->hTcBuffer->nchan_buffer_full; n++ ) { p_tc[n] = &st_ivas->hTcBuffer->tc[n][st_ivas->hTcBuffer->n_samples_rendered]; @@ -1043,7 +977,6 @@ ivas_error ivas_jbm_dec_render( { ivas_apply_non_diegetic_panning( p_tc[0], p_output, st_ivas->hDecoderConfig->non_diegetic_pan_gain, *nSamplesRendered ); } - #ifdef DEBUGGING else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) #else @@ -1165,7 +1098,7 @@ ivas_error ivas_jbm_dec_render( ivas_ism_render_sf( st_ivas, st_ivas->renderer_type, p_output, *nSamplesRendered ); /* add already rendered SBA part */ - ivas_osba_stereo_add_channels( p_tc, p_output, st_ivas->hSbaIsmData->gain_bed, nchan_out, st_ivas->nchan_ism, st_ivas->ism_mode, *nSamplesRendered ); + ivas_osba_stereo_add_channels( p_tc, p_output, st_ivas->hSbaIsmData->gain_bed, nchan_out, st_ivas->nchan_ism, *nSamplesRendered ); } else if ( st_ivas->renderer_type == RENDERER_OSBA_AMBI || st_ivas->renderer_type == RENDERER_OSBA_LS || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { @@ -1223,7 +1156,6 @@ ivas_error ivas_jbm_dec_render( set_zero( p_output[n], *nSamplesRendered ); } } - for ( n = 0; n < st_ivas->hDecoderConfig->nchan_out; n++ ) { v_multc( p_output[n], 2.0f, p_output[n], *nSamplesRendered ); @@ -1278,7 +1210,6 @@ ivas_error ivas_jbm_dec_render( } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { if ( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) @@ -1366,8 +1297,6 @@ ivas_error ivas_jbm_dec_render( } else if ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe == 0 ) { - /* Delay the separated channel to sync with the DirAC rendering */ - mvr2r( p_tc[LFE_CHANNEL - 1], p_output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); } } @@ -1431,11 +1360,7 @@ ivas_error ivas_jbm_dec_render( break; case PCM_FLOAT32: -#ifdef JBM_MEMORY_OPT ivas_buffer_deinterleaved_to_interleaved( p_output, nchan_out_syn_output, *nSamplesRendered, (float *) data ); -#else - ivas_syn_output_f( p_output, *nSamplesRendered, nchan_out_syn_output, (float *) data ); -#endif break; default: error = IVAS_ERR_UNKNOWN; @@ -1498,7 +1423,6 @@ ivas_error ivas_jbm_dec_flush_renderer( { int16_t ch_idx; -#ifdef JBM_MEMORY_OPT /* render available full slots (with new lower granularity) */ for ( ch_idx = 0; ch_idx < max( hTcBuffer->nchan_transport_jbm, hTcBuffer->nchan_buffer_full ); ch_idx++ ) { @@ -1506,16 +1430,6 @@ ivas_error ivas_jbm_dec_flush_renderer( mvr2r( hTcBuffer->tc_buffer_old[ch_idx], hTcBuffer->tc[ch_idx], n_samples_to_render ); set_zero( hTcBuffer->tc[ch_idx] + n_samples_to_render, hTcBuffer->n_samples_granularity - n_samples_to_render ); } -#else - /* 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 ); - } -#endif /* simple change of the slot info */ hTcBuffer->num_slots = 1; @@ -1612,13 +1526,11 @@ ivas_error ivas_jbm_dec_flush_renderer( if ( ism_mode_old == ISM_MASA_MODE_DISC ) { float *tc_local[MAX_NUM_OBJECTS]; -#ifdef NONBE_1302_FIX_OMASA_JBM_FLUSH int16_t last_dirac_md_idx; uint16_t nSamplesAvailableNext; ISM_MODE ism_mode_orig; RENDERER_TYPE renderer_type_orig; int32_t ivas_total_brate; -#endif /* copy from ISM delay buffer to the correct place in TCs */ for ( ch_idx = 0; ch_idx < st_ivas->nchan_ism; ch_idx++ ) @@ -1627,7 +1539,6 @@ ivas_error ivas_jbm_dec_flush_renderer( mvr2r( st_ivas->hMasaIsmData->delayBuffer[ch_idx], tc_local[ch_idx], st_ivas->hMasaIsmData->delayBuffer_size ); } -#ifdef NONBE_1302_FIX_OMASA_JBM_FLUSH /* to render flushed samples, use configuration from the last received frame */ ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; renderer_type_orig = st_ivas->renderer_type; @@ -1654,12 +1565,6 @@ ivas_error ivas_jbm_dec_flush_renderer( st_ivas->ism_mode = ism_mode_orig; st_ivas->renderer_type = renderer_type_orig; st_ivas->hDecoderConfig->ivas_total_brate = ivas_total_brate; -#else - if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_output, hTcBuffer->n_samples_granularity ) ) != IVAS_ERR_OK ) - { - return error; - } -#endif } } else if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) @@ -1673,19 +1578,21 @@ ivas_error ivas_jbm_dec_flush_renderer( ISM_MODE ism_mode_orig; RENDERER_TYPE renderer_type_orig; int32_t ivas_total_brate; + + /* to render flushed samples, use configuration from the last received frame */ ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; renderer_type_orig = st_ivas->renderer_type; ism_mode_orig = st_ivas->ism_mode; st_ivas->ism_mode = ism_mode_old; st_ivas->renderer_type = renderer_type_old; st_ivas->hDecoderConfig->ivas_total_brate = st_ivas->hDecoderConfig->last_ivas_total_brate; - last_spar_md_idx = st_ivas->hSpar->render_to_md_map[st_ivas->hSpar->slots_rendered - 1]; last_dirac_md_idx = st_ivas->hSpatParamRendCom->render_to_md_map[st_ivas->hSpatParamRendCom->slots_rendered - 1]; #ifdef DEBUGGING assert( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ); #endif - /* copy from ISM delay buffer to the correct place in tcs */ + + /* copy from ISM delay buffer to the correct place in TCs */ for ( ch_idx = 0; ch_idx < st_ivas->nchan_ism; ch_idx++ ) { tc_local[ch_idx] = &st_ivas->hTcBuffer->tc[ch_idx][hTcBuffer->n_samples_rendered]; @@ -1714,6 +1621,7 @@ ivas_error ivas_jbm_dec_flush_renderer( return error; } + /* restore original configuration */ st_ivas->ism_mode = ism_mode_orig; st_ivas->renderer_type = renderer_type_orig; st_ivas->hDecoderConfig->ivas_total_brate = ivas_total_brate; @@ -1723,6 +1631,7 @@ ivas_error ivas_jbm_dec_flush_renderer( { return IVAS_ERROR( IVAS_ERR_WRONG_MODE, "Wrong IVAS format in VoIP renderer flushing!" ); } + hTcBuffer->n_samples_rendered = hTcBuffer->n_samples_granularity; } @@ -1749,14 +1658,9 @@ ivas_error ivas_jbm_dec_flush_renderer( st_ivas->noClipping += #endif ivas_syn_output( p_output, *nSamplesRendered, st_ivas->hDecoderConfig->nchan_out, (int16_t *) data ); - break; case PCM_FLOAT32: -#ifdef JBM_MEMORY_OPT ivas_buffer_deinterleaved_to_interleaved( p_output, st_ivas->hDecoderConfig->nchan_out, *nSamplesRendered, (float *) data ); -#else - ivas_syn_output_f( p_output, *nSamplesRendered, st_ivas->hDecoderConfig->nchan_out, (float *) data ); -#endif break; default: error = IVAS_ERR_UNKNOWN; @@ -2177,7 +2081,6 @@ int16_t ivas_jbm_dec_get_render_granularity( return render_granularity; } -#ifdef JBM_MEMORY_OPT /*--------------------------------------------------------------------------* * ivas_jbm_dec_tc_audio_allocate() @@ -2197,9 +2100,7 @@ static ivas_error ivas_jbm_dec_tc_audio_allocate( if ( Opt_tsm ) { n_samp_full = ( NS2SA( output_Fs, MAX_JBM_L_FRAME_NS ) ); -#ifdef FIX_1330_JBM_MEMORY n_samp_full = max( n_samp_full, L_FRAME48k ); /* buffers are shared between 'hTcBuffer->tc[]' and 'p_output_f[]': ensure minimal length */ -#endif n_samp_residual = hTcBuffer->n_samples_granularity - 1; } else @@ -2259,10 +2160,8 @@ static ivas_error ivas_jbm_dec_tc_audio_allocate( } } -#ifdef FIX_1330_JBM_MEMORY hTcBuffer->tc_buffer2 = NULL; -#endif return IVAS_ERR_OK; } @@ -2300,20 +2199,17 @@ static void ivas_jbm_dec_tc_audio_deallocate( hTcBuffer->tc_buffer_old[ch_idx] = NULL; } } -#ifdef FIX_1330_JBM_MEMORY if ( hTcBuffer->tc_buffer2 != NULL ) { free( hTcBuffer->tc_buffer2 ); hTcBuffer->tc_buffer2 = NULL; } -#endif } return; } -#endif /*--------------------------------------------------------------------------* * ivas_jbm_dec_tc_buffer_open() @@ -2330,17 +2226,9 @@ ivas_error ivas_jbm_dec_tc_buffer_open( const int16_t n_samples_granularity /* i : granularity of the renderer/buffer */ ) { -#ifndef JBM_MEMORY_OPT - int16_t nsamp_to_allocate; -#endif DECODER_TC_BUFFER_HANDLE hTcBuffer; int16_t nMaxSlotsPerSubframe; -#ifdef JBM_MEMORY_OPT ivas_error error; -#else - int16_t nchan_residual; - int16_t ch_idx; -#endif /*-----------------------------------------------------------------* * prepare library opening @@ -2355,9 +2243,6 @@ ivas_error ivas_jbm_dec_tc_buffer_open( hTcBuffer->nchan_transport_jbm = nchan_transport_jbm; hTcBuffer->nchan_transport_internal = nchan_transport_internal; hTcBuffer->nchan_buffer_full = nchan_full; -#ifndef JBM_MEMORY_OPT - nchan_residual = nchan_transport_internal - nchan_full; -#endif hTcBuffer->n_samples_granularity = n_samples_granularity; hTcBuffer->n_samples_available = 0; hTcBuffer->n_samples_buffered = 0; @@ -2367,80 +2252,16 @@ ivas_error ivas_jbm_dec_tc_buffer_open( hTcBuffer->n_samples_discard = 0; hTcBuffer->n_samples_flushed = 0; hTcBuffer->nb_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; -#ifndef JBM_MEMORY_OPT - nsamp_to_allocate = 0; -#endif + 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 ); -#ifdef JBM_MEMORY_OPT if ( ( error = ivas_jbm_dec_tc_audio_allocate( hTcBuffer, st_ivas->hDecoderConfig->output_Fs, st_ivas->hDecoderConfig->Opt_tsm ) ) != IVAS_ERR_OK ) { return error; } -#else - { - int16_t n_samp_full, n_samp_residual; - int32_t offset; - if ( st_ivas->hDecoderConfig->Opt_tsm ) - { - n_samp_full = ( NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) + hTcBuffer->n_samples_granularity - 1 ); - n_samp_residual = hTcBuffer->n_samples_granularity - 1; - } - else - { - n_samp_full = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); - n_samp_residual = 0; - } - - nsamp_to_allocate = hTcBuffer->nchan_buffer_full * n_samp_full; - nsamp_to_allocate += nchan_residual * n_samp_residual; - - if ( nsamp_to_allocate == 0 ) - { - hTcBuffer->tc_buffer = NULL; - - for ( ch_idx = 0; ch_idx < MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS; ch_idx++ ) - { - hTcBuffer->tc[ch_idx] = NULL; - } - } - else - { - if ( st_ivas->hDecoderConfig->Opt_tsm ) - { - /* note: the maximum buffer length is for OSBA DISC mode with ISMs -> 15*(1920+239)=32385 samples */ - if ( ( hTcBuffer->tc_buffer = (float *) malloc( nsamp_to_allocate * sizeof( float ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for JBM TC Buffer\n" ) ); - } - set_zero( hTcBuffer->tc_buffer, nsamp_to_allocate ); - - offset = 0; - for ( ch_idx = 0; ch_idx < hTcBuffer->nchan_buffer_full; ch_idx++ ) - { - hTcBuffer->tc[ch_idx] = &hTcBuffer->tc_buffer[offset]; - offset += n_samp_full; - } - for ( ; ch_idx < hTcBuffer->nchan_transport_internal; ch_idx++ ) - { - hTcBuffer->tc[ch_idx] = &hTcBuffer->tc_buffer[offset]; - offset += n_samp_residual; - } - for ( ; ch_idx < MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS; ch_idx++ ) - { - hTcBuffer->tc[ch_idx] = NULL; - } - } - else - { - hTcBuffer->tc_buffer = NULL; - } - } - } -#endif st_ivas->hTcBuffer = hTcBuffer; @@ -2467,12 +2288,7 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( int16_t ch_idx, num_tc_buffer_mem, n_samples_still_available; float tc_buffer_mem[MAX_INTERN_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES - 1]; #endif -#ifdef JBM_MEMORY_OPT ivas_error error; -#else - int16_t nsamp_to_allocate, n_samp_full, n_samp_residual, offset, nchan_residual; - int16_t ch_idx; -#endif DECODER_TC_BUFFER_HANDLE hTcBuffer; hTcBuffer = st_ivas->hTcBuffer; @@ -2534,85 +2350,22 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( hTcBuffer->nchan_transport_jbm = nchan_transport_jbm; hTcBuffer->nchan_transport_internal = nchan_transport_internal; hTcBuffer->nchan_buffer_full = nchan_full; -#ifndef JBM_MEMORY_OPT - nchan_residual = nchan_transport_internal - nchan_full; -#endif hTcBuffer->n_samples_granularity = n_samples_granularity; -#ifdef JBM_MEMORY_OPT - /* reallocate TC audio buffers */ - - ivas_jbm_dec_tc_audio_deallocate( hTcBuffer ); - - if ( ( error = ivas_jbm_dec_tc_audio_allocate( hTcBuffer, st_ivas->hDecoderConfig->output_Fs, st_ivas->hDecoderConfig->Opt_tsm ) ) != IVAS_ERR_OK ) - { - return error; - } -#else +#ifndef NONBE_1324_TC_BUFFER_MEMOERY_KEEP #ifdef DEBUGGING /* 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 ); #endif - /* realloc buffers */ - if ( hTcBuffer->tc_buffer != NULL ) - { - free( hTcBuffer->tc_buffer ); - hTcBuffer->tc_buffer = NULL; - } +#endif + /* reallocate TC audio buffers */ - if ( st_ivas->hDecoderConfig->Opt_tsm ) - { - n_samp_full = ( NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) + hTcBuffer->n_samples_granularity - 1 ); - n_samp_residual = hTcBuffer->n_samples_granularity - 1; - } - else - { - n_samp_full = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); - n_samp_residual = 0; - } - nsamp_to_allocate = hTcBuffer->nchan_buffer_full * n_samp_full; - nsamp_to_allocate += nchan_residual * n_samp_residual; + ivas_jbm_dec_tc_audio_deallocate( hTcBuffer ); - if ( nsamp_to_allocate == 0 ) - { - hTcBuffer->tc_buffer = NULL; - for ( ch_idx = 0; ch_idx < MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS; ch_idx++ ) - { - hTcBuffer->tc[ch_idx] = NULL; - } - } - else + if ( ( error = ivas_jbm_dec_tc_audio_allocate( hTcBuffer, st_ivas->hDecoderConfig->output_Fs, st_ivas->hDecoderConfig->Opt_tsm ) ) != IVAS_ERR_OK ) { - if ( st_ivas->hDecoderConfig->Opt_tsm ) - { - if ( ( hTcBuffer->tc_buffer = (float *) malloc( nsamp_to_allocate * sizeof( float ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for JBM TC Buffer\n" ) ); - } - set_zero( hTcBuffer->tc_buffer, nsamp_to_allocate ); - - offset = 0; - for ( ch_idx = 0; ch_idx < hTcBuffer->nchan_buffer_full; ch_idx++ ) - { - hTcBuffer->tc[ch_idx] = &hTcBuffer->tc_buffer[offset]; - offset += n_samp_full; - } - for ( ; ch_idx < hTcBuffer->nchan_transport_internal; ch_idx++ ) - { - hTcBuffer->tc[ch_idx] = &hTcBuffer->tc_buffer[offset]; - offset += n_samp_residual; - } - for ( ; ch_idx < MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS; ch_idx++ ) - { - hTcBuffer->tc[ch_idx] = NULL; - } - } - else - { - hTcBuffer->tc_buffer = NULL; - } + return error; } -#endif #ifdef NONBE_1324_TC_BUFFER_MEMOERY_KEEP /* propagate samples of the TC buffer from the previous frame */ @@ -2660,11 +2413,7 @@ static void ivas_jbm_dec_tc_buffer_playout( for ( ch_idx = 0; ch_idx < st_ivas->hTcBuffer->nchan_transport_jbm; ch_idx++ ) { -#ifdef FIX_1330_JBM_MEMORY output[ch_idx] = st_ivas->hTcBuffer->tc[ch_idx] + st_ivas->hTcBuffer->n_samples_rendered; -#else - mvr2r( st_ivas->hTcBuffer->tc[ch_idx] + st_ivas->hTcBuffer->n_samples_rendered, output[ch_idx], *nSamplesRendered ); -#endif } st_ivas->hTcBuffer->subframes_rendered = last_sf; @@ -2683,26 +2432,9 @@ void ivas_jbm_dec_tc_buffer_close( DECODER_TC_BUFFER_HANDLE *phTcBuffer /* i/o: TC buffer handle */ ) { -#ifndef JBM_MEMORY_OPT - int16_t i; - -#endif if ( *phTcBuffer != NULL ) { -#ifdef JBM_MEMORY_OPT ivas_jbm_dec_tc_audio_deallocate( *phTcBuffer ); -#else - for ( i = 0; i < MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS; i++ ) - { - ( *phTcBuffer )->tc[i] = NULL; - } - - if ( ( *phTcBuffer )->tc_buffer != NULL ) - { - free( ( *phTcBuffer )->tc_buffer ); - ( *phTcBuffer )->tc_buffer = NULL; - } -#endif free( *phTcBuffer ); *phTcBuffer = NULL; @@ -3061,6 +2793,7 @@ void ivas_dec_prepare_renderer( { ivas_jbm_masa_sf_to_slot_map( st_ivas, n_render_timeslots ); } + /* MASA transport gaining for edited disc OMASA EXT. For ISMs, only metadata is modified */ if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC && st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL && st_ivas->hMasaIsmData->masa_gain_is_edited == 1 ) { @@ -3141,6 +2874,7 @@ void ivas_dec_prepare_renderer( { ivas_jbm_masa_sf_to_slot_map( st_ivas, n_render_timeslots ); } + /* MASA transport gaining for edited param_one OMASA EXT. For ISMs, only metadata is modified. */ if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && st_ivas->hMasaIsmData->masa_gain_is_edited == 1 ) { @@ -3207,9 +2941,8 @@ void ivas_dec_prepare_renderer( v_multc( st_ivas->hTcBuffer->tc[CPE_CHANNELS + n], gainIsm, st_ivas->hTcBuffer->tc[CPE_CHANNELS + n], st_ivas->hTcBuffer->n_samples_available ); } -#ifndef TMP_FIX_OMASA_SR_BE + if ( st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) -#endif { delay_signal( st_ivas->hTcBuffer->tc[CPE_CHANNELS + n], st_ivas->hTcBuffer->n_samples_available, st_ivas->hMasaIsmData->delayBuffer[n], st_ivas->hMasaIsmData->delayBuffer_size ); } diff --git a/lib_dec/ivas_lfe_dec.c b/lib_dec/ivas_lfe_dec.c index d8cf359347373479a23405df30f5a2cc738f5a88..6dfe76f9652331c0354d052ebe052e20fe4b6b75 100644 --- a/lib_dec/ivas_lfe_dec.c +++ b/lib_dec/ivas_lfe_dec.c @@ -271,6 +271,7 @@ static void ivas_create_lfe_lpf_dec( return; } + /*-----------------------------------------------------------------------------------------* * Function ivas_lfe_dec() * @@ -428,18 +429,19 @@ ivas_error ivas_create_lfe_dec( low_pass_delay_dec_out = ivas_lfe_lpf_delay[IVAS_FILTER_ORDER_4 - 3]; ivas_create_lfe_lpf_dec( &( hLFE->filter_state ), output_Fs ); } + hLFE->filter_state.order = filt_order; lfe_block_delay_s = lfe_block_delay_s + low_pass_delay_dec_out; hLFE->lfe_prior_buf_len = NS2SA( output_Fs, IVAS_LFE_FADE_NS ); hLFE->bfi_count = 0; - block_offset_s += delay_ns / 1000000000.f; lfe_addl_delay_s = block_offset_s - lfe_block_delay_s; - lfe_addl_delay_s = max( 0.0f, lfe_addl_delay_s ); + lfe_addl_delay_s = max( 0.0f, lfe_addl_delay_s ); hLFE->lfe_addl_delay = (int16_t) ( lfe_addl_delay_s * output_Fs ); hLFE->delay_ns = delay_ns; + if ( hLFE->lfe_addl_delay > 0 ) { if ( ( hLFE->lfe_delay_buf = (float *) malloc( hLFE->lfe_addl_delay * sizeof( float ) ) ) == NULL ) diff --git a/lib_dec/ivas_lfe_plc.c b/lib_dec/ivas_lfe_plc.c index 9a35a85407f1f2831aff71db431dc9394afe147c..d4335fe300485b285fb396731eb4b55b725568f3 100644 --- a/lib_dec/ivas_lfe_plc.c +++ b/lib_dec/ivas_lfe_plc.c @@ -121,6 +121,7 @@ static int16_t lfeplc_lev_dur( return 0; } + /*-----------------------------------------------------------------------------------------* * Function check_stab() * diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index c1442f518a551a8d64dc88402132d0999194d9da..a3855196dd08660376353593a0d618ddef32c250 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -300,7 +300,6 @@ ivas_error ivas_masa_decode( } } - byteBuffer = st->bit_stream[( st->next_bit_pos )--]; byteBuffer = byteBuffer + 2 * st->bit_stream[( st->next_bit_pos )--]; @@ -522,6 +521,7 @@ ivas_error ivas_masa_decode( { st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx = ( st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx + MAX_PARAM_SPATIAL_SUBFRAMES ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length; } + if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) { if ( hQMetaData->q_direction == NULL ) @@ -1311,7 +1311,7 @@ static int16_t decode_lfe_to_total_energy_ratio( *-------------------------------------------------------------------*/ ivas_error ivas_masa_dec_reconfigure( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ) { int16_t n, tmp, num_bits; @@ -1320,25 +1320,14 @@ ivas_error ivas_masa_dec_reconfigure( Decoder_State **sts; int32_t ivas_total_brate, last_ivas_total_brate; int16_t numCldfbAnalyses_old, numCldfbSyntheses_old; -#ifdef FIX_NCHAN_BUFFERS -#ifdef FIX_1330_JBM_MEMORY int16_t nchan_out_buff; -#else - int16_t nchan_out_buff_old, nchan_out_buff; -#endif -#endif ivas_error error; int16_t pos_idx; int32_t ism_total_brate; ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; last_ivas_total_brate = st_ivas->hDecoderConfig->last_ivas_total_brate; -#ifdef FIX_NCHAN_BUFFERS -#ifndef FIX_1330_JBM_MEMORY - nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); -#endif -#endif /* Copy state to TC buffer if granularity matches and we are not in OMASA EXT rendering mode */ if ( st_ivas->hSpatParamRendCom != NULL && st_ivas->hSpatParamRendCom->slot_size == st_ivas->hTcBuffer->n_samples_granularity && st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) { @@ -1413,7 +1402,6 @@ ivas_error ivas_masa_dec_reconfigure( ( ivas_total_brate < MASA_STEREO_MIN_BITRATE && last_ivas_total_brate == IVAS_SID_5k2 ) ) { st_ivas->hCPE[cpe_id]->nchan_out = 1; - if ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend != NULL ) || ( ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) && st_ivas->hDiracDecBin[0] != NULL ) ) { if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK ) @@ -1450,6 +1438,7 @@ ivas_error ivas_masa_dec_reconfigure( /*-----------------------------------------------------------------* * TD Decorrelator *-----------------------------------------------------------------*/ + if ( st_ivas->hDiracDecBin[0] != NULL ) { if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin[0]->hTdDecorr ), &( st_ivas->hDiracDecBin[0]->useTdDecorr ) ) ) != IVAS_ERR_OK ) @@ -1486,6 +1475,7 @@ ivas_error ivas_masa_dec_reconfigure( /*-----------------------------------------------------------------* * JBM TC buffers *-----------------------------------------------------------------*/ + { int16_t tc_nchan_to_allocate; int16_t tc_nchan_transport; @@ -1505,15 +1495,11 @@ ivas_error ivas_masa_dec_reconfigure( } else { -#ifdef FIX_NCHAN_BUFFERS tc_nchan_to_allocate = BINAURAL_CHANNELS; if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->useTdDecorr ) { tc_nchan_to_allocate = 2 * BINAURAL_CHANNELS; } -#else - tc_nchan_to_allocate = 2 * BINAURAL_CHANNELS; -#endif } if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) @@ -1571,7 +1557,6 @@ ivas_error ivas_masa_dec_reconfigure( } } -#ifdef FIX_NCHAN_BUFFERS /*-----------------------------------------------------------------* * floating-point output audio buffers *-----------------------------------------------------------------*/ @@ -1579,18 +1564,12 @@ ivas_error ivas_masa_dec_reconfigure( if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->last_ivas_format == MASA_FORMAT ) /* note: switching with OMASA is addressed in ivas_omasa_dec_config() */ { nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); - -#ifdef FIX_1330_JBM_MEMORY if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff, st_ivas->hDecoderConfig->Opt_tsm, st_ivas->hTcBuffer ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) -#endif { return error; } } -#endif return IVAS_ERR_OK; } @@ -2464,12 +2443,14 @@ static int16_t ivas_decode_masaism_metadata( if ( azimuth * hMasaIsmData->q_azimuth_old[obj] > 0 ) { delta_phi = 180.0f / (float) ( no_phi_masa[bits_ism[obj] - 1][idx_el] ); /* 360/2*/ - if ( roundf( 100 * ( no_phi_masa[bits_ism[obj] - 1][idx_el] ) * ( azimuth - hMasaIsmData->q_azimuth_old[obj] ) ) / (float) 100.0f > 180.0f ) + /* this is equivalent to testing if 'azimuth - hMasaIsmData->q_azimuth_old[obj] > delta_phi' with limited precision */ + if ( roundf( 100 * ( no_phi_masa[bits_ism[obj] - 1][idx_el] ) * ( azimuth - hMasaIsmData->q_azimuth_old[obj] ) ) / 100.0f > 180.0f ) { azimuth -= delta_phi; } else { + /* this is equivalent to testing if 'hMasaIsmData->q_azimuth_old[obj] - azimuth > delta_phi' with limited precision */ if ( roundf( 100 * ( no_phi_masa[bits_ism[obj] - 1][idx_el] ) * ( hMasaIsmData->q_azimuth_old[obj] - azimuth ) ) / 100.0f > 180.0f ) { azimuth += delta_phi; diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index e912222b579eb78c267f389129837e3a28ea5bcd..fb1acc52aeffdee21169fa25a13a4fc00a5e0016 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -401,7 +401,11 @@ ivas_error ivas_param_mc_dec_open( ivas_param_mc_dec_compute_interpolator( 0, 0, DEFAULT_JBM_CLDFB_TIMESLOTS, hParamMC->h_output_synthesis_params.interpolator ); /* Head or external rotation */ +#ifdef IVAS_RTPDUMP + if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation || st_ivas->hCombinedOrientationData ) ) +#else if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) ) +#endif { if ( ( hParamMC->hoa_encoder = (float *) malloc( st_ivas->hTransSetup.nchan_out_woLFE * MAX_INTERN_CHANNELS * sizeof( float ) ) ) == NULL ) { @@ -444,6 +448,7 @@ ivas_error ivas_param_mc_dec_open( { n_cldfb_slots = MAX_JBM_CLDFB_TIMESLOTS; } + if ( ( hParamMC->Cldfb_RealBuffer_tc = (float *) malloc( n_cldfb_slots * nchan_transport * hParamMC->num_freq_bands * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC JBM\n" ) ); @@ -1324,9 +1329,9 @@ void ivas_param_mc_dec_read_BS( *------------------------------------------------------------------------*/ void ivas_param_mc_dec_digest_tc( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - const uint8_t nCldfbSlots, /* i : number of CLDFB slots in transport channels */ - float *p_data_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint8_t nCldfbSlots, /* i : number of CLDFB slots in transport channels */ + float *p_data_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ ) { int16_t ch, num_freq_bands, slot_idx, cldfb_ch, n_ch_cldfb; @@ -1425,7 +1430,6 @@ void ivas_param_mc_dec_prepare_renderer( { 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; @@ -1477,11 +1481,9 @@ void ivas_param_mc_dec_prepare_renderer( { continue; } - /* Cx for transport channels */ pCx = is_next_band ? &cx_next_band[0] : &cx[0]; pCx_imag = is_next_band ? &cx_imag_next_band[0] : &cx_imag[0]; - for ( i = 0; i < nchan_transport * nchan_transport; i++ ) { real_part = pCx[i]; @@ -1506,6 +1508,7 @@ void ivas_param_mc_dec_prepare_renderer( mvr2r( cx, cx_next_band, nchan_transport * nchan_transport ); } + for ( is_next_band = 0; is_next_band < 2; is_next_band++ ) { if ( is_next_band && skip_next_band ) @@ -2296,7 +2299,6 @@ static void ivas_param_mc_get_mixing_matrices( num_lfe_bands = PARAM_MC_MAX_BAND_LFE; } - if ( hSynthesisOutputSetup->num_lfe > 0 && param_band_idx >= num_lfe_bands ) { remove_lfe = 1; diff --git a/lib_dec/ivas_mc_paramupmix_dec.c b/lib_dec/ivas_mc_paramupmix_dec.c index a95490b5c47469f3d10a74f45b857dbaabc08cc7..3724372ab04b30da4f4c26d8de5feec2b93bf365 100644 --- a/lib_dec/ivas_mc_paramupmix_dec.c +++ b/lib_dec/ivas_mc_paramupmix_dec.c @@ -260,7 +260,6 @@ void ivas_mc_paramupmix_dec_render( assert( slots_to_render == 0 ); #endif { - for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) { int16_t n_samples_sf = slot_size * st_ivas->hTcBuffer->subframe_nbslots[subframe_idx]; @@ -350,7 +349,11 @@ ivas_error ivas_mc_paramupmix_dec_open( } /* Head or external rotation */ +#ifdef IVAS_RTPDUMP + if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation || st_ivas->hCombinedOrientationData ) ) +#else if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) ) +#endif { if ( ( hMCParamUpmix->hoa_encoder = (float *) malloc( st_ivas->hTransSetup.nchan_out_woLFE * MAX_INTERN_CHANNELS * sizeof( float ) ) ) == NULL ) { @@ -400,6 +403,7 @@ ivas_error ivas_mc_paramupmix_dec_open( return error; } } + st_ivas->hMCParamUpmix = hMCParamUpmix; return error; @@ -679,6 +683,7 @@ static void ivas_mc_paramupmix_dec_sf( cldfbAnalysis_ts( &( pPcm_temp[ch][hMCParamUpmix->num_freq_bands * slot_idx] ), Cldfb_RealBuffer[ch][slot_idx], Cldfb_ImagBuffer[ch][slot_idx], hMCParamUpmix->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); } } + for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS; ch++ ) { ps_pred_process_sf( hMCParamUpmix, @@ -845,6 +850,7 @@ static void ivas_mc_paramupmix_dec_sf( hMCParamUpmix->num_freq_bands, st_ivas->cldfbSynDec[ch] ); } } + /* adjust delay of other channels */ noparamupmix_delay = NS2SA( st_ivas->hDecoderConfig->output_Fs, IVAS_FB_DEC_DELAY_NS ); n_samples_rendered = st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->subframes_rendered] * hMCParamUpmix->num_freq_bands; @@ -867,7 +873,6 @@ static void ivas_mc_paramupmix_dec_sf( { for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS; ch++ ) { - /*delay is handled within LFE decoder*/ if ( st_ivas->hIntSetup.index_lfe[0] != ch ) { float tmp_buf[L_SUBFRAME5MS_48k]; diff --git a/lib_dec/ivas_mcmasa_dec.c b/lib_dec/ivas_mcmasa_dec.c old mode 100644 new mode 100755 diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 8bfe30b3671b7e9b5fd34db1f09ea564756434b6..6ffd1b4f7e6ae990259f4b05f66cd7a1f442d534 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -279,7 +279,6 @@ ivas_error ivas_mct_dec( #endif } /* n_channels loop */ - /* synthesis synchronization between stereo modes */ if ( !st_ivas->sba_dirac_stereo_flag || ( st_ivas->ivas_format == SBA_ISM_FORMAT && cpe_id < nCPE - 2 ) ) { @@ -733,17 +732,10 @@ static ivas_error ivas_mc_dec_reconfig( int16_t tc_nchan_tc_new; int16_t tc_nchan_allocate_new; int16_t tc_granularity_new; -#ifdef FIX_1330_JBM_MEMORY int16_t nchan_out_buff; -#else - int16_t nchan_out_buff_old, nchan_out_buff; -#endif ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; nchan_transport_old = st_ivas->nchan_transport; -#ifndef FIX_1330_JBM_MEMORY - nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); -#endif last_mc_mode = ivas_mc_mode_select( ivas_mc_map_output_config_to_mc_ls_setup( st_ivas->transport_config ), st_ivas->hDecoderConfig->last_ivas_total_brate ); /* NB: this assumes that LS config remains the same between frames */ /* temporally set the current mc_mode back to the previous one to make sure the following call to @@ -797,8 +789,9 @@ static ivas_error ivas_mc_dec_reconfig( } /* JBM: when granularity goes down (e.g. MCT with CREND -> ParamMC with binaural fastconv - render what still fits in the new granularity */ + render what still fits in the new granularity */ tc_granularity_new = ivas_jbm_dec_get_render_granularity( st_ivas->renderer_type, RENDERER_DISABLE, st_ivas->hDecoderConfig->output_Fs ); + if ( tc_granularity_new < st_ivas->hTcBuffer->n_samples_granularity ) { /* flush already done in IVAS_DEC_ReadFormat() */ @@ -1100,7 +1093,6 @@ static ivas_error ivas_mc_dec_reconfig( return error; } - /*-----------------------------------------------------------------* * Reconfigure renderers *-----------------------------------------------------------------*/ @@ -1149,7 +1141,12 @@ static ivas_error ivas_mc_dec_reconfig( if ( st_ivas->hBinRenderer != NULL && ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV && st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV_ROOM ) ) { ivas_binRenderer_close( &st_ivas->hBinRenderer ); + +#ifdef IVAS_RTPDUMP + if ( ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation || st_ivas->hCombinedOrientationData ) ) +#else if ( ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) ) +#endif { efap_free_data( &st_ivas->hEFAPdata ); } @@ -1187,6 +1184,7 @@ static ivas_error ivas_mc_dec_reconfig( { return error; } + if ( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { if ( ( error = ivas_reverb_open( &st_ivas->hReverb, st_ivas->hHrtfStatistics, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) @@ -1250,9 +1248,11 @@ static ivas_error ivas_mc_dec_reconfig( return error; } + /*-----------------------------------------------------------------* * Allocate the LFE handle that is coded separately after the allocation of the core coders *-----------------------------------------------------------------*/ + if ( ( st_ivas->mc_mode == MC_MODE_MCT || st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) ) { int32_t delay_ns; @@ -1264,6 +1264,7 @@ static ivas_error ivas_mc_dec_reconfig( { delay_ns = 0; } + if ( st_ivas->hBinRenderer != NULL ) { if ( st_ivas->hBinRenderer->render_lfe ) @@ -1307,7 +1308,6 @@ static ivas_error ivas_mc_dec_reconfig( /*-----------------------------------------------------------------* * JBM TC buffers *-----------------------------------------------------------------*/ - { int16_t tc_nchan_full_new; DECODER_TC_BUFFER_HANDLE hTcBuffer; @@ -1320,7 +1320,6 @@ static ivas_error ivas_mc_dec_reconfig( if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) { -#ifdef FIX_NCHAN_BUFFERS tc_nchan_allocate_new = BINAURAL_CHANNELS; if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->useTdDecorr ) { @@ -1330,9 +1329,7 @@ static ivas_error ivas_mc_dec_reconfig( { tc_nchan_allocate_new++; } -#else - tc_nchan_allocate_new = 2 * BINAURAL_CHANNELS; -#endif + tc_nchan_full_new = tc_nchan_allocate_new; } @@ -1383,17 +1380,12 @@ static ivas_error ivas_mc_dec_reconfig( } } - /*-----------------------------------------------------------------* * floating-point output audio buffers *-----------------------------------------------------------------*/ nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); -#ifdef FIX_1330_JBM_MEMORY if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff, st_ivas->hDecoderConfig->Opt_tsm, st_ivas->hTcBuffer ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) -#endif { return error; } diff --git a/lib_dec/ivas_mdct_core_dec.c b/lib_dec/ivas_mdct_core_dec.c index 273925bb4a2ecadb2a9c53ad8f460c4384cb2b9d..9cf401aba420831ffb4701c627136ca1345cb345 100644 --- a/lib_dec/ivas_mdct_core_dec.c +++ b/lib_dec/ivas_mdct_core_dec.c @@ -532,9 +532,7 @@ void ivas_mdct_core_invQ( set_s( total_nbbits, 0, CPE_CHANNELS ); set_s( bitsRead, 0, CPE_CHANNELS ); tmp_concealment_method = 0; -#ifdef FIX_1387_INIT_PRM_SQQ prm_sqQ = NULL; /* set prm_sqQ to NULL - in case of bfi == 1 it's not set or needed, but it triggers sanitizers */ -#endif for ( ch = 0; ch < CPE_CHANNELS; ch++ ) { @@ -807,11 +805,7 @@ void ivas_mdct_core_reconstruct( int16_t L_frame[CPE_CHANNELS], L_frameTCX[CPE_CHANNELS], nSubframes[CPE_CHANNELS]; int16_t L_frame_global[CPE_CHANNELS], L_frame_globalTCX[CPE_CHANNELS]; /* Synth */ -#ifdef FIX_1320_STACK_CPE_DECODER float synth_buf[OLD_SYNTH_INTERNAL_DEC + L_FRAME_PLUS_INTERNAL + M]; -#else - float synth_buf[OLD_SYNTH_SIZE_DEC + L_FRAME_PLUS + M]; -#endif float *synth; float synth_bufFB[OLD_SYNTH_SIZE_DEC + L_FRAME_PLUS + M]; float *synthFB; @@ -848,11 +842,7 @@ void ivas_mdct_core_reconstruct( synthFB = synth_bufFB + st->hTcxDec->old_synth_lenFB; mvr2r( st->hTcxDec->old_synth, synth_buf, st->hTcxDec->old_synth_len ); mvr2r( st->hTcxDec->old_synthFB, synth_bufFB, st->hTcxDec->old_synth_lenFB ); -#ifdef FIX_1320_STACK_CPE_DECODER set_zero( synth, L_FRAME_PLUS_INTERNAL + M ); -#else - set_zero( synth, L_FRAME_PLUS + M ); -#endif set_zero( synthFB, L_FRAME_PLUS + M ); if ( st->core != ACELP_CORE ) @@ -954,15 +944,7 @@ void ivas_mdct_core_reconstruct( /* Postfiltering */ post_decoder( st, synth_buf, pit_gain[ch], pitch[ch], x[ch][0], st->p_bpf_noise_buf ); -#ifndef FIX_938_COMPILER_WARNING - if ( signal_outFB[ch] ) - { -#endif - mvr2r( synthFB, signal_outFB[ch], st->hTcxDec->L_frameTCX ); -#ifndef FIX_938_COMPILER_WARNING - } -#endif - + mvr2r( synthFB, signal_outFB[ch], st->hTcxDec->L_frameTCX ); #ifdef DEBUG_PLC_INFO { int16_t i; @@ -1123,17 +1105,13 @@ void ivas_mdct_core_tns_ns( decoder_tcx_tns( st, L_frame_global[ch], L_spec[ch], L_frame[ch], L_frameTCX[ch], &x[ch][k][0], fUseTns[ch][k], &tnsData[ch][k], bfi, k, 1 ); sns_shape_spectrum( x[ch][k], st->hTcxCfg->psychParamsCurrent, &sns_int_scf[0], st->hTcxCfg->psychParamsCurrent->nBins ); -#ifdef NONBE_FIX_1376_MDCT_CONCEALMENT /* - 2025-09-07, mul: - in case of PLC, applying SNS up to L_spec might not be enough: In case the transition frame from DTX after an inactive period is lost, L_spec is assumed to represent a regular TCX frame, - however, this frame is nevertheless acting as an transition frame as also visible in L_frameTCX; thus, the safer approach to prevent high frequency artifacts is to apply the SNS up to L_frameTCX; - in case this is not necessary, x[] is filled with zeros, and the multiplication is not causing any additional harm + 2025-09-07, mul: + in case of PLC, applying SNS up to L_spec might not be enough : In case the transition frame from DTX after an inactive period is lost, L_spec is assumed to represent a regular TCX frame, however, this frame is nevertheless acting as an transition frame as also visible in L_frameTCX; + thus, the safer approach to prevent high frequency artifacts is to apply the SNS up to L_frameTCX; + in case this is not necessary, x[] is filled with zeros, and the multiplication is not causing any additional harm * / */ v_multc( x[ch][k] + st->hTcxCfg->psychParamsCurrent->nBins, sns_int_scf[FDNS_NPTS - 1], x[ch][k] + st->hTcxCfg->psychParamsCurrent->nBins, max( L_spec[ch], L_frameTCX[ch] ) - st->hTcxCfg->psychParamsCurrent->nBins ); -#else - v_multc( x[ch][k] + st->hTcxCfg->psychParamsCurrent->nBins, sns_int_scf[FDNS_NPTS - 1], x[ch][k] + st->hTcxCfg->psychParamsCurrent->nBins, L_spec[ch] - st->hTcxCfg->psychParamsCurrent->nBins ); -#endif decoder_tcx_tns( st, L_frame_global[ch], L_spec[ch], L_frame[ch], L_frameTCX[ch], &x[ch][k][0], fUseTns[ch][k], &tnsData[ch][k], bfi, k, 0 ); } diff --git a/lib_dec/ivas_mono_dmx_renderer.c b/lib_dec/ivas_mono_dmx_renderer.c index b3003bfc975c15f3292566b1bc4f1778db5a5cbd..40ae744154afeed3afacbeb54cc644809b73c3ce 100644 --- a/lib_dec/ivas_mono_dmx_renderer.c +++ b/lib_dec/ivas_mono_dmx_renderer.c @@ -102,6 +102,7 @@ void ivas_mono_dmx_renderer_close( * * Downmix process *------------------------------------------------------------------------*/ + void ivas_ism_mono_dmx( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ float *output_f[], /* i/o: synthesized core-coder transport channels/mono output */ @@ -220,8 +221,8 @@ void ivas_mono_stereo_downmix_mcmasa( *------------------------------------------------------------------------*/ void ivas_apply_non_diegetic_panning( - float *input_f, /* i : non-diegetic object */ - float *output_f[], /* o: core-coder transport mono channel/stereo output */ + float *input_f, /* i : non-diegetic object */ + float *output_f[], /* o : core-coder transport mono channel/stereo output */ const float non_diegetic_pan_gain, /* i : non-diegetic panning gain */ const int16_t output_frame /* i : output frame length per channel */ ) @@ -230,7 +231,6 @@ void ivas_apply_non_diegetic_panning( pan_left = ( non_diegetic_pan_gain + 1.f ) * 0.5f; pan_right = 1.f - pan_left; - v_multc( input_f, pan_right, output_f[1], output_frame ); v_multc( input_f, pan_left, output_f[0], output_frame ); diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index 530974416463050d469512f076216b6eee3e1da5..ff47b1b9a77fa56f539ca737a201d2fff16f22b5 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -176,12 +176,14 @@ ivas_error ivas_td_binaural_renderer_sf( c_indx++; } } + if ( subframe_idx == ism_md_subframe_update_jbm ) { if ( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) { ISM_METADATA_FRAME ismMetaData[MAX_NUM_OBJECTS]; ISM_METADATA_HANDLE hIsmMetaData[MAX_NUM_OBJECTS]; + for ( nS = 0; nS < nchan_ism; nS++ ) { ismMetaData[nS].azimuth = st_ivas->hIsmMetaData[nS]->edited_azimuth; @@ -190,6 +192,7 @@ ivas_error ivas_td_binaural_renderer_sf( ismMetaData[nS].yaw = st_ivas->hIsmMetaData[nS]->edited_yaw; ismMetaData[nS].pitch = st_ivas->hIsmMetaData[nS]->edited_pitch; ismMetaData[nS].non_diegetic_flag = st_ivas->hIsmMetaData[nS]->non_diegetic_flag; + if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) { /* DISC OMASA ISM gaining with TDREND is done in ivas_dec_prepare_renderer()*/ @@ -199,6 +202,7 @@ ivas_error ivas_td_binaural_renderer_sf( { ismMetaData[nS].gain = st_ivas->hIsmMetaData[nS]->edited_gain; } + hIsmMetaData[nS] = &ismMetaData[nS]; } @@ -207,9 +211,12 @@ ivas_error ivas_td_binaural_renderer_sf( return error; } } - else if ( ( error = TDREND_Update_object_positions( st_ivas->hBinRendererTd, nchan_ism, st_ivas->ivas_format, st_ivas->hIsmMetaData ) ) != IVAS_ERR_OK ) + else { - return error; + if ( ( error = TDREND_Update_object_positions( st_ivas->hBinRendererTd, nchan_ism, st_ivas->ivas_format, st_ivas->hIsmMetaData ) ) != IVAS_ERR_OK ) + { + return error; + } } } @@ -221,7 +228,6 @@ ivas_error ivas_td_binaural_renderer_sf( { return error; } - if ( st_ivas->hRenderConfig != NULL && st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { if ( ( error = ivas_reverb_process( st_ivas->hReverb, st_ivas->transport_config, 0, tc_local, p_reverb_signal, 0 ) ) != IVAS_ERR_OK ) @@ -233,12 +239,10 @@ ivas_error ivas_td_binaural_renderer_sf( /* Render subframe */ /* ism_md_subframe_update_jbm != subframe_idx: trigger update only for ism_md_subframe_update_jbm == subframe_idx, where then the two TDREND_GetMix()-arguments subframe_idx and ism_md_subframe_update are equal, and we want to enforce the update inside TDREND_GetMix to use subframe_idx == 0 */ - if ( ( error = TDREND_GetMix( st_ivas->hBinRendererTd, output_f_local, output_frame, 0 ) ) != IVAS_ERR_OK ) { return error; } - if ( st_ivas->hRenderConfig != NULL && st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { /* add reverb to rendered signals */ diff --git a/lib_dec/ivas_omasa_dec.c b/lib_dec/ivas_omasa_dec.c index e3b2716f2bb954949e36370951a8655e288640e9..f3e0b90aa96d9d1aa69066a099b8dde679dcc211 100644 --- a/lib_dec/ivas_omasa_dec.c +++ b/lib_dec/ivas_omasa_dec.c @@ -43,7 +43,6 @@ #endif #include "wmc_auto.h" - /*------------------------------------------------------------------------- * Local constants *------------------------------------------------------------------------*/ @@ -107,6 +106,7 @@ ivas_error ivas_omasa_data_open( } set_s( hMasaIsmData->azimuth_separated_ism, 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR ); set_s( hMasaIsmData->elevation_separated_ism, 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR ); + hMasaIsmData->hExtData = NULL; if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) { @@ -118,6 +118,7 @@ ivas_error ivas_omasa_data_open( } hExtData->prev_idx_separated_ism = 0; + for ( ch = 0; ch < MAX_NUM_OBJECTS; ch++ ) { set_zero( hExtData->prev_panning_gains[ch], 2 ); @@ -171,11 +172,13 @@ void ivas_omasa_data_close( free( ( *hMasaIsmData )->delayBuffer ); ( *hMasaIsmData )->delayBuffer = NULL; } + if ( ( *hMasaIsmData )->hExtData != NULL ) { free( ( *hMasaIsmData )->hExtData ); ( *hMasaIsmData )->hExtData = NULL; } + free( *hMasaIsmData ); *hMasaIsmData = NULL; @@ -190,18 +193,14 @@ void ivas_omasa_data_close( *--------------------------------------------------------------------------*/ ivas_error ivas_omasa_dec_config( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ) { int16_t k, sce_id, nSCE_old, nchan_hp20_old, numCldfbAnalyses_old, numCldfbSyntheses_old; int32_t ivas_total_brate, ism_total_brate, cpe_brate; ISM_MODE ism_mode_old; IVAS_FORMAT ivas_format_orig; -#ifdef FIX_1330_JBM_MEMORY int16_t nchan_out_buff; -#else - int16_t nchan_out_buff, nchan_out_buff_old; -#endif ivas_error error; RENDERER_TYPE old_renderer_type; @@ -216,10 +215,6 @@ ivas_error ivas_omasa_dec_config( ivas_format_orig = st_ivas->ivas_format; st_ivas->ivas_format = st_ivas->last_ivas_format; ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old ); -#ifndef FIX_1330_JBM_MEMORY - nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); -#endif - st_ivas->ivas_format = ivas_format_orig; nSCE_old = st_ivas->nSCE; @@ -367,6 +362,7 @@ ivas_error ivas_omasa_dec_config( { return error; } + if ( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { if ( ( error = ivas_reverb_open( &st_ivas->hReverb, st_ivas->hHrtfStatistics, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) @@ -408,7 +404,6 @@ ivas_error ivas_omasa_dec_config( { return error; } - if ( ( error = ivas_omasa_separate_object_renderer_open( st_ivas ) ) != IVAS_ERR_OK ) { return error; @@ -420,6 +415,7 @@ ivas_error ivas_omasa_dec_config( ivas_omasa_separate_object_renderer_close( st_ivas ); } } + if ( st_ivas->renderer_type == RENDERER_OMASA_MIX_EXT ) { /* Allocate 'hIsmRendererData' handle */ @@ -445,6 +441,7 @@ ivas_error ivas_omasa_dec_config( return error; } } + /*-----------------------------------------------------------------* * TD Decorrelator *-----------------------------------------------------------------*/ @@ -452,7 +449,6 @@ ivas_error ivas_omasa_dec_config( if ( st_ivas->hDiracDecBin[0] != NULL ) { if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin[0]->hTdDecorr ), &( st_ivas->hDiracDecBin[0]->useTdDecorr ) ) ) != IVAS_ERR_OK ) - { return error; } @@ -472,17 +468,12 @@ ivas_error ivas_omasa_dec_config( *-----------------------------------------------------------------*/ nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); -#ifdef FIX_1330_JBM_MEMORY if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff, st_ivas->hDecoderConfig->Opt_tsm, st_ivas->hTcBuffer ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) -#endif { return error; } } - return IVAS_ERR_OK; } @@ -680,99 +671,70 @@ void ivas_omasa_dirac_rend_jbm( ) { int16_t subframes_rendered; -#ifndef FIX_1330_JBM_MEMORY - int16_t slots_rendered; -#endif int16_t n; float data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k]; -#ifndef FIX_1330_JBM_MEMORY - if ( !st_ivas->hDecoderConfig->Opt_tsm ) - { -#endif - *nSamplesRendered = min( nSamplesAsked, st_ivas->hTcBuffer->n_samples_available ); + *nSamplesRendered = min( nSamplesAsked, st_ivas->hTcBuffer->n_samples_available ); - if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) - { - mvr2r( &output_f[CPE_CHANNELS][st_ivas->hTcBuffer->n_samples_rendered], data_separated_objects[0], *nSamplesRendered ); + if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + { + mvr2r( &output_f[CPE_CHANNELS][st_ivas->hTcBuffer->n_samples_rendered], data_separated_objects[0], *nSamplesRendered ); #ifdef NONBE_1399_1400_FIX_OBJ_EDIT_ISSUES - if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) #else -#ifdef FIX_1330_JBM_MEMORY if ( !st_ivas->hDecoderConfig->Opt_tsm && st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) -#else - if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) -#endif #endif + { + /* Gain separated object, if edited */ + for ( n = 0; n < st_ivas->nchan_ism; n++ ) { - /* Gain separated object, if edited */ - for ( n = 0; n < st_ivas->nchan_ism; n++ ) + if ( st_ivas->hMasaIsmData->ism_gain_is_edited[n] && st_ivas->hMasaIsmData->idx_separated_ism == n ) { - if ( st_ivas->hMasaIsmData->ism_gain_is_edited[n] && st_ivas->hMasaIsmData->idx_separated_ism == n ) - { - v_multc( data_separated_objects[0], st_ivas->hMasaIsmData->gain_ism_edited[n], data_separated_objects[0], *nSamplesRendered ); - } + v_multc( data_separated_objects[0], st_ivas->hMasaIsmData->gain_ism_edited[n], data_separated_objects[0], *nSamplesRendered ); } } } - else + } + else + { + for ( n = 0; n < st_ivas->nchan_ism; n++ ) { - for ( n = 0; n < st_ivas->nchan_ism; n++ ) - { - mvr2r( &output_f[n + CPE_CHANNELS][st_ivas->hTcBuffer->n_samples_rendered], data_separated_objects[n], *nSamplesRendered ); + mvr2r( &output_f[n + CPE_CHANNELS][st_ivas->hTcBuffer->n_samples_rendered], data_separated_objects[n], *nSamplesRendered ); - /* Gain discrete objects, if edited */ + /* Gain discrete objects, if edited */ #ifdef NONBE_1399_1400_FIX_OBJ_EDIT_ISSUES - if ( st_ivas->hMasaIsmData->ism_gain_is_edited[n] ) + if ( st_ivas->hMasaIsmData->ism_gain_is_edited[n] ) #else -#ifdef FIX_1330_JBM_MEMORY if ( !st_ivas->hDecoderConfig->Opt_tsm && st_ivas->hMasaIsmData->ism_gain_is_edited[n] ) -#else - if ( st_ivas->hMasaIsmData->ism_gain_is_edited[n] ) #endif -#endif - { - v_multc( data_separated_objects[n], st_ivas->hMasaIsmData->gain_ism_edited[n], data_separated_objects[n], *nSamplesRendered ); - } + { + v_multc( data_separated_objects[n], st_ivas->hMasaIsmData->gain_ism_edited[n], data_separated_objects[n], *nSamplesRendered ); } + } - /* Gain MASA part, if edited in G192. MASA gaining with VOIP is done in ivas_dec_prepare_renderer() */ -#ifdef FIX_1330_JBM_MEMORY - if ( !st_ivas->hDecoderConfig->Opt_tsm && st_ivas->hMasaIsmData->masa_gain_is_edited ) -#else - if ( st_ivas->hMasaIsmData->masa_gain_is_edited ) -#endif + /* Gain MASA part, if edited in G192. MASA gaining with VOIP is done in ivas_dec_prepare_renderer() */ + if ( !st_ivas->hDecoderConfig->Opt_tsm && st_ivas->hMasaIsmData->masa_gain_is_edited ) + { + for ( n = 0; n < CPE_CHANNELS; n++ ) { - for ( n = 0; n < CPE_CHANNELS; n++ ) - { - v_multc( output_f[n], st_ivas->hMasaIsmData->gain_masa_edited, output_f[n], *nSamplesRendered ); - } + v_multc( output_f[n], st_ivas->hMasaIsmData->gain_masa_edited, output_f[n], *nSamplesRendered ); } } -#ifndef FIX_1330_JBM_MEMORY } -#endif subframes_rendered = st_ivas->hSpatParamRendCom->subframes_rendered; -#ifndef FIX_1330_JBM_MEMORY - slots_rendered = st_ivas->hSpatParamRendCom->slots_rendered; -#endif ivas_dirac_dec_render( st_ivas, nchan_transport, nSamplesAsked, nSamplesRendered, nSamplesAvailable, output_f ); -#ifdef FIX_1330_JBM_MEMORY ivas_omasa_separate_object_render_jbm( st_ivas, *nSamplesRendered, data_separated_objects, output_f, subframes_rendered ); -#else - ivas_omasa_separate_object_render_jbm( st_ivas, *nSamplesRendered, data_separated_objects, output_f, subframes_rendered, slots_rendered ); -#endif return; } /*--------------------------------------------------------------------------* - * ivas_omasa_dirac_td_binaural_jbm() + * ivas_omasa_dirac_td_binaural_render() * * Binaural rendering in OMASA format for JBM *--------------------------------------------------------------------------*/ @@ -854,6 +816,7 @@ ivas_error ivas_omasa_dirac_td_binaural_jbm( { return error; } + for ( n = 0; n < BINAURAL_CHANNELS; n++ ) { v_add( output_f[n], p_sepobj[n], output_f[n], *nSamplesRendered ); @@ -1118,6 +1081,7 @@ ivas_error ivas_omasa_objects_delay_open( return IVAS_ERR_OK; } + /*--------------------------------------------------------------------------* * ivas_omasa_render_objects_from_mix() * @@ -1346,7 +1310,6 @@ void ivas_omasa_render_objects_from_mix( { outSlotRePr = &( inRe[n][slot][0] ); outSlotImPr = &( inIm[n][slot][0] ); - cldfbSynthesis( &outSlotRePr, &outSlotImPr, &( output[n][nBins * slot] ), nBins, st_ivas->cldfbSynDec[n] ); } @@ -1369,6 +1332,7 @@ void ivas_omasa_render_objects_from_mix( return; } + /*--------------------------------------------------------------------------* * ivas_omasa_gain_masa_tc() * @@ -1377,14 +1341,14 @@ void ivas_omasa_render_objects_from_mix( *--------------------------------------------------------------------------*/ void ivas_omasa_gain_masa_tc( - float *output[], /* i/o : output synthesis signal */ + float *output[], /* i/o: output synthesis signal */ const float gainMasa, /* i : gain */ const int16_t nchan_transport_ism, /* i : number of ISM TCs */ const int16_t output_frame /* i : output frame length per channel */ ) { /* Edited OMASA EXT MASA transport gaining */ - for ( int16_t ch = 0; ch < 2; ch++ ) + for ( int16_t ch = 0; ch < CPE_CHANNELS; ch++ ) { v_multc( output[nchan_transport_ism + ch], gainMasa, output[nchan_transport_ism + ch], output_frame ); } diff --git a/lib_dec/ivas_osba_dec.c b/lib_dec/ivas_osba_dec.c index 00025b6847b2d8f932d833ec503b42a2d417da61..185f90530689360c36a4a4330df0c920e0bb998a 100644 --- a/lib_dec/ivas_osba_dec.c +++ b/lib_dec/ivas_osba_dec.c @@ -159,7 +159,6 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData ); - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { int16_t slot_idx, num_cldfb_bands, nchan_transport_orig; @@ -173,10 +172,12 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( num_cldfb_bands = st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[0]->no_channels; nchan_transport_orig = st_ivas->nchan_transport; st_ivas->nchan_transport = st_ivas->nchan_ism; + if ( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, output_f, *nSamplesRendered ) ) != IVAS_ERR_OK ) { return error; } + st_ivas->nchan_transport = nchan_transport_orig; cldfb_slots = *nSamplesRendered / num_cldfb_bands; @@ -194,10 +195,11 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( for ( b = 0; b < num_cldfb_bands; b++ ) { st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx][b] = - st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx][b] + Cldfb_RealBuffer[b]; - + st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx][b] + + Cldfb_RealBuffer[b]; st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx][b] = - st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx][b] + Cldfb_ImagBuffer[b]; + st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx][b] + + Cldfb_ImagBuffer[b]; } #endif } @@ -219,6 +221,7 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( } } } + return IVAS_ERR_OK; } @@ -253,58 +256,6 @@ ivas_error ivas_osba_ism_metadata_dec( return IVAS_ERR_OK; } - -/*-------------------------------------------------------------------------* - * ivas_osba_stereo_add_channels() - * - * - *-------------------------------------------------------------------------*/ - -void ivas_osba_stereo_add_channels( - float *tc_f[], /* i : transport channels */ - float *output_f[], /* i/o: output channels */ - const float gain, /* i : gain bed value */ - const int16_t nchan_out, /* i : number of output channels */ - const int16_t nchan_ism, /* i : number of ISM channels */ - const int16_t ism_mode, /* i : ISM mode */ - const int16_t n_samples_to_render /* i : output frame length per channel */ -) -{ - int16_t n; - - if ( ism_mode == ISM_SBA_MODE_DISC ) - { - if ( gain != 1.0f && gain >= 0.0f ) - { - int16_t i; - for ( n = 0; n < nchan_out; n++ ) - { - for ( i = 0; i < n_samples_to_render; i++ ) - { - output_f[n][i] += tc_f[n + nchan_ism][i] * gain; - } - } - } - else - { - for ( n = 0; n < nchan_out; n++ ) - { - v_add( output_f[n], tc_f[n + nchan_ism], output_f[n], n_samples_to_render ); - } - } - } - else - { - for ( n = 0; n < nchan_out; n++ ) - { - v_add( output_f[n], tc_f[n + nchan_ism], output_f[n], n_samples_to_render ); - } - } - - return; -} - - /*-------------------------------------------------------------------------* * ivas_osba_render_sf() * @@ -320,71 +271,77 @@ ivas_error ivas_osba_render_sf( ) { int16_t n; -#ifdef FIX_1330_JBM_MEMORY float output_sba[MAX_OUTPUT_CHANNELS][L_FRAME48k]; float *p_output_sba[MAX_OUTPUT_CHANNELS]; -#else - float output_ism[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - float *p_output_ism[MAX_OUTPUT_CHANNELS]; -#endif ivas_error error; for ( n = 0; n < MAX_OUTPUT_CHANNELS; n++ ) { -#ifdef FIX_1330_JBM_MEMORY p_output_sba[n] = output_sba[n]; -#else - p_output_ism[n] = &output_ism[n][0]; -#endif } -#ifndef FIX_1330_JBM_MEMORY - if ( !st_ivas->hDecoderConfig->Opt_tsm ) - { - int16_t tc_offset; - tc_offset = st_ivas->hTcBuffer->n_samples_rendered; - for ( n = 0; n < st_ivas->nchan_ism; n++ ) - { - - mvr2r( &p_output[n][tc_offset], &output_ism[n][tc_offset], nSamplesAsked ); - } - } -#endif -#ifdef FIX_1330_JBM_MEMORY if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailableNext, p_output_sba ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailableNext, p_output ) ) != IVAS_ERR_OK ) -#endif { return error; } if ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV_ROOM ) { -#ifdef FIX_1330_JBM_MEMORY ivas_ism_render_sf( st_ivas, st_ivas->renderer_type, p_output, *nSamplesRendered ); -#else - ivas_ism_render_sf( st_ivas, st_ivas->renderer_type, p_output_ism, *nSamplesRendered ); -#endif } for ( n = 0; n < st_ivas->hDecoderConfig->nchan_out; n++ ) { if ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV_ROOM ) { -#ifdef FIX_1330_JBM_MEMORY v_add( p_output[n], p_output_sba[n], p_output[n], *nSamplesRendered ); -#else - v_add( p_output[n], p_output_ism[n], p_output[n], *nSamplesRendered ); -#endif } -#ifdef FIX_1330_JBM_MEMORY else { mvr2r( p_output_sba[n], p_output[n], *nSamplesRendered ); } -#endif } return IVAS_ERR_OK; } + + +/*-------------------------------------------------------------------------* + * ivas_osba_stereo_add_channels() + * + * + *-------------------------------------------------------------------------*/ + +void ivas_osba_stereo_add_channels( + float *tc_f[], /* i : transport channels */ + float *output_f[], /* i/o: output channels */ + const float gain, /* i : gain bed value */ + const int16_t nchan_out, /* i : number of output channels */ + const int16_t nchan_ism, /* i : number of ISM channels */ + const int16_t n_samples_to_render /* i : output frame length per channel */ +) +{ + int16_t n; + + if ( gain != 1.0f && gain >= 0.0f ) + { + int16_t i; + for ( n = 0; n < nchan_out; n++ ) + { + for ( i = 0; i < n_samples_to_render; i++ ) + { + output_f[n][i] += tc_f[n + nchan_ism][i] * gain; + } + } + } + else + { + for ( n = 0; n < nchan_out; n++ ) + { + v_add( output_f[n], tc_f[n + nchan_ism], output_f[n], n_samples_to_render ); + } + } + + + return; +} diff --git a/lib_dec/ivas_output_config.c b/lib_dec/ivas_output_config.c index 0c147185c9bf0588c17c3a54a1af29cebbb10024..b4b241815dd11075e142dd2a595cfa0935b692c3 100644 --- a/lib_dec/ivas_output_config.c +++ b/lib_dec/ivas_output_config.c @@ -71,7 +71,11 @@ void ivas_renderer_select( * Binaural rendering configurations *-----------------------------------------------------------------*/ +#ifdef IVAS_RTPDUMP + if ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation || st_ivas->hCombinedOrientationData ) +#else if ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) +#endif { st_ivas->hCombinedOrientationData->shd_rot_max_order = -1; } @@ -142,7 +146,11 @@ void ivas_renderer_select( *internal_config = IVAS_AUDIO_CONFIG_7_1_4; } +#ifdef IVAS_RTPDUMP + if ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation || st_ivas->hCombinedOrientationData ) +#else if ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) +#endif { nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); @@ -185,7 +193,11 @@ void ivas_renderer_select( if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) { +#ifdef IVAS_RTPDUMP + if ( ( st_ivas->transport_config == IVAS_AUDIO_CONFIG_5_1 || st_ivas->transport_config == IVAS_AUDIO_CONFIG_7_1 ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation || st_ivas->hCombinedOrientationData ) && st_ivas->mc_mode == MC_MODE_MCT ) +#else if ( ( st_ivas->transport_config == IVAS_AUDIO_CONFIG_5_1 || st_ivas->transport_config == IVAS_AUDIO_CONFIG_7_1 ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) && st_ivas->mc_mode == MC_MODE_MCT ) +#endif { *renderer_type = RENDERER_BINAURAL_OBJECTS_TD; } @@ -200,7 +212,11 @@ void ivas_renderer_select( *renderer_type = RENDERER_BINAURAL_FASTCONV; } +#ifdef IVAS_RTPDUMP + if ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation || st_ivas->hCombinedOrientationData ) +#else if ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) +#endif { /* force HOA3 domain for rotation*/ *internal_config = IVAS_AUDIO_CONFIG_HOA3; @@ -367,7 +383,6 @@ void ivas_renderer_select( } else if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) { - if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) { *renderer_type = RENDERER_OMASA_OBJECT_EXT; diff --git a/lib_dec/ivas_qmetadata_dec.c b/lib_dec/ivas_qmetadata_dec.c index 6b4dae19d940967c4d0c50aebd691aa66f7eccf0..acb094019f76d5bc8497d42d854c9f3a2831a88e 100644 --- a/lib_dec/ivas_qmetadata_dec.c +++ b/lib_dec/ivas_qmetadata_dec.c @@ -42,6 +42,7 @@ #include "prot.h" #include "basop_settings.h" + /*-----------------------------------------------------------------------* * Local function prototypes *-----------------------------------------------------------------------*/ @@ -98,7 +99,13 @@ static int16_t read_surround_coherence_hr( uint16_t *bitstream, int16_t *p_bit_p static int16_t read_coherence_data_hr_512( uint16_t *bitstream, int16_t *p_bit_pos, IVAS_QMETADATA *hQMetaData, const int16_t idx_dir, const int16_t nbits_coh ); -static void read_stream_dct_coeffs_omasa( int16_t *q_idx, Word32 *q_dct_data_fx, const int16_t len_stream, uint16_t *bit_stream, int16_t *index, const int16_t first_line ); +static void read_stream_dct_coeffs_omasa( int16_t *q_idx, + Word32 *q_dct_data_fx, + const int16_t len_stream, + uint16_t *bit_stream, + int16_t *index, + const int16_t first_line ); + /*-----------------------------------------------------------------------* * Global function definitions @@ -4073,6 +4080,7 @@ static int16_t read_surround_coherence_hr( int16_t min_index; int16_t d, idx; int32_t int_error_ratio_surr; + coding_subbands = hQMetaData->q_direction[0].cfg.nbands; q_direction = hQMetaData->q_direction; @@ -4107,7 +4115,7 @@ static int16_t read_surround_coherence_hr( } else { - idx_ER[j] = 7; // masa_sq( error_ratio_surr, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); + idx_ER[j] = 7; /* masa_sq( error_ratio_surr, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); */ no_cv_vec[j] = idx_cb_sur_coh_masa[idx_ER[j]] + 2; } } @@ -4288,6 +4296,7 @@ static void read_stream_dct_coeffs_omasa( { i_min = ( i_min << 1 ) + bit_stream[( *index )--]; } + /* read GR orders */ GR1 = bit_stream[( *index )--] + 1; if ( GR1 == 2 ) @@ -4333,7 +4342,6 @@ static void read_stream_dct_coeffs_omasa( q_dct_data_fx[i] = (Word32) ( ( step_fx * ( q_idx[i] + 1 ) ) >> 7 ); /* Q25 */ } } - return; } diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 96bcb8c39ccaabf4252a2466936f38a99e71b241..649cda2f12ec66d8ed21152910c30f21e116448d 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -111,12 +111,7 @@ ivas_error ivas_sba_dec_reconfigure( int32_t ivas_total_brate; int32_t last_ivas_total_brate; int16_t num_channels, num_md_sub_frames; -#ifdef FIX_1330_JBM_MEMORY int16_t nchan_out_buff; -#else - int16_t nchan_out_buff, nchan_out_buff_old; - int16_t sba_analysis_order_old_flush; -#endif DECODER_CONFIG_HANDLE hDecoderConfig; ivas_error error; ISM_MODE ism_mode_old; @@ -127,18 +122,12 @@ ivas_error ivas_sba_dec_reconfigure( hDecoderConfig = st_ivas->hDecoderConfig; ivas_total_brate = hDecoderConfig->ivas_total_brate; last_ivas_total_brate = st_ivas->last_active_ivas_total_brate; -#ifndef FIX_1330_JBM_MEMORY - sba_analysis_order_old_flush = st_ivas->sba_analysis_order; -#endif /*-----------------------------------------------------------------* * Set SBA high-level parameters * Save old SBA high-level parameters *-----------------------------------------------------------------*/ -#ifndef FIX_1330_JBM_MEMORY - nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, sba_analysis_order_old_flush, last_ivas_total_brate ); -#endif ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old ); nchan_hp20_old = getNumChanSynthesis( st_ivas ); @@ -173,7 +162,7 @@ ivas_error ivas_sba_dec_reconfigure( /* determine new granularity */ granularity_new = ivas_jbm_dec_get_render_granularity( st_ivas->renderer_type, ivas_renderer_secondary_select( st_ivas ), st_ivas->hDecoderConfig->output_Fs ); - /* flush renderer on granularity change form 5ms to 1.25ms, again only possible for binaural rendering */ + /* flush renderer on granularity change from 5ms to 1.25ms, again only possible for binaural rendering */ if ( granularity_new < st_ivas->hTcBuffer->n_samples_granularity ) { /* flush already done in IVAS_DEC_ReadFormat() */ @@ -330,7 +319,8 @@ ivas_error ivas_sba_dec_reconfigure( ivas_mono_dmx_renderer_close( &st_ivas->hMonoDmxRenderer ); } - if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ), + if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, + ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ), st_ivas->ivas_format ) ) != IVAS_ERR_OK ) { return error; @@ -444,6 +434,7 @@ ivas_error ivas_sba_dec_reconfigure( return error; } } + if ( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { if ( ( error = ivas_reverb_open( &st_ivas->hReverb, st_ivas->hHrtfStatistics, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) @@ -474,8 +465,10 @@ ivas_error ivas_sba_dec_reconfigure( { ivas_td_binaural_close( &st_ivas->hBinRendererTd ); } + nchan_transport = st_ivas->nchan_transport; nchan_transport_old += st_ivas->nchan_ism; + st_ivas->ism_mode = ISM_MODE_NONE; } else if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) @@ -604,11 +597,7 @@ ivas_error ivas_sba_dec_reconfigure( *-----------------------------------------------------------------*/ nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); -#ifdef FIX_1330_JBM_MEMORY if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff, hDecoderConfig->Opt_tsm, st_ivas->hTcBuffer ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -720,7 +709,6 @@ ivas_error ivas_sba_dec_render( nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; -#ifdef FIX_NCHAN_BUFFERS if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { nchan_out = max( nchan_internal, st_ivas->hDecoderConfig->nchan_out ); @@ -729,17 +717,14 @@ ivas_error ivas_sba_dec_render( { nchan_out = max( nchan_internal, st_ivas->hDecoderConfig->nchan_out - st_ivas->nchan_ism ); } -#ifdef FIX_1372_OSBA_OBJECT_EDITING else if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { nchan_out = BINAURAL_CHANNELS; } -#endif } nchan_out = min( nchan_out, ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ) ); -#endif #ifdef DEBUGGING assert( hSpar ); #endif diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index 260ea208d548f472cc78e722998427e2e07af8aa..dd8bf56d42f0eb8b633836b5250cdbb37bfb075e 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -247,14 +247,6 @@ ivas_error ivas_spar_dec_open( nchan_to_allocate = 2 * BINAURAL_CHANNELS; } - if ( st_ivas->ivas_format == SBA_ISM_FORMAT && - st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL && - st_ivas->ism_mode == ISM_SBA_MODE_DISC ) - { - /* get correct granularity in case of binaural rendering of the discrete objects with the td obj renderer */ - granularity = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ); - } - granularity = ivas_jbm_dec_get_render_granularity( st_ivas->renderer_type, ivas_renderer_secondary_select( st_ivas ), output_Fs ); if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, buffer_mode, nchan_tc, nchan_to_allocate, nchan_to_allocate, granularity ) ) != IVAS_ERR_OK ) @@ -1250,7 +1242,6 @@ void ivas_spar_dec_set_render_map( return; } - /*-------------------------------------------------------------------* * ivas_spar_dec_set_render_params() * @@ -1376,28 +1367,15 @@ void ivas_spar_dec_upmixer_sf( ) { int16_t cldfb_band, num_cldfb_bands, numch_in, numch_out; -#ifdef FIX_1319_STACK_SBA_DECODER float *cldfb_in_ts_re[HOA3_CHANNELS][CLDFB_NO_COL_MAX]; float *cldfb_in_ts_im[HOA3_CHANNELS][CLDFB_NO_COL_MAX]; -#else - float *cldfb_in_ts_re[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX]; - float *cldfb_in_ts_im[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX]; -#endif int16_t i, b, ts, out_ch, in_ch; int16_t num_spar_bands, spar_band, nchan_transport; int16_t num_in_ingest, split_band; int16_t slot_size, slot_idx_start; -#ifdef FIX_1319_STACK_SBA_DECODER float *p_tc[HOA3_CHANNELS]; -#else - float *p_tc[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; -#endif int16_t md_idx; -#ifdef FIX_1319_STACK_SBA_DECODER float Pcm_tmp[HOA3_CHANNELS][2 /* Re, Im*/ * L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; -#else - float Pcm_tmp[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS][L_FRAME48k]; -#endif int16_t numch_out_dirac; 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]; @@ -1428,11 +1406,7 @@ void ivas_spar_dec_upmixer_sf( p_tc[i] = st_ivas->hTcBuffer->tc[i + nchan_ism] + slot_idx_start * slot_size; } -#ifdef FIX_1372_OSBA_OBJECT_EDITING if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) -#else - if ( st_ivas->ivas_format == SBA_ISM_FORMAT && st_ivas->ism_mode == ISM_SBA_MODE_DISC && st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) -#endif { for ( i = 0; i < nchan_ism; i++ ) { @@ -1484,7 +1458,6 @@ void ivas_spar_dec_upmixer_sf( } } #endif - /*---------------------------------------------------------------------* * TD Decorr and pcm ingest *---------------------------------------------------------------------*/ @@ -1516,11 +1489,7 @@ void ivas_spar_dec_upmixer_sf( if ( hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_FOA ) { /* at this point, output channels are used as intermediate procesing buffers */ -#ifdef FIX_1319_STACK_SBA_DECODER for ( in_ch = 0; in_ch < HOA3_CHANNELS; in_ch++ ) -#else - for ( in_ch = 0; in_ch < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; in_ch++ ) -#endif { for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) { diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec.c index fea1fcf76b6eb3d8df4f0d41eb10d4993c264839..9c45dab2a314fbd0c71d1aab334b3fcb03d55afb 100644 --- a/lib_dec/ivas_spar_md_dec.c +++ b/lib_dec/ivas_spar_md_dec.c @@ -2446,6 +2446,7 @@ static void ivas_parse_parameter_bitstream_dtx( sid_bits_len = st0->next_bit_pos - sid_bits_len; sba_spar_bitlen = ivas_sba_spar_sid_bitlen( num_dmx_per_band[0] ); zero_pad_bits = sba_spar_bitlen - sid_bits_len; + assert( zero_pad_bits >= 0 ); if ( num_dmx_per_band[0] == 2 ) { diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index abdec141463edb24cad4f1dbc89a04d1bdc15d8d..f1efb32a1019670330be0bc7f647dbadc404a0d3 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -849,7 +849,7 @@ typedef struct TD_RINGBUF_HANDLE hMultiBinTdData; ISAR_CLDFB_RINGBUF_HANDLE hMultiBinCldfbData[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; #else - ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE hMultiBinCldfbData; /*scratch buffer for frame by frame processing*/ + ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE hMultiBinCldfbData; /*scratch buffer for frame by frame processing*/ #endif ISAR_SPLIT_REND_BITS_HANDLE hSplitRendBits; /*scratch buffer for frame by frame processing*/ SPLIT_REND_WRAPPER splitrend; @@ -858,6 +858,7 @@ typedef struct } ISAR_DEC_SPLIT_REND_WRAPPER, *ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE; + /*----------------------------------------------------------------------------------* * MASA decoder structures *----------------------------------------------------------------------------------*/ @@ -956,23 +957,17 @@ typedef struct ivas_masa_ism_data_structure typedef struct decoder_tc_buffer_structure { -#ifdef JBM_MEMORY_OPT float *tc_buffer_old[MAX_INTERN_CHANNELS]; /* TC audio samples not rendered in the previous frame */ -#endif - float *tc_buffer; /* the buffer itself */ -#ifdef JBM_MEMORY_OPT - float *tc[MAX_INTERN_CHANNELS]; /* pointers into the buffer to the beginning of each tc */ -#else - float *tc[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; /* pointers into the buffer to the beginning of each tc */ // VE2SB: TBV -#endif - TC_BUFFER_MODE tc_buffer_mode; /* mode of the buffer (no buffering, render buffering, out buffering) */ - int16_t nchan_transport_jbm; /* number of TCs after TC decoding */ - int16_t nchan_transport_internal; /* total number of TC buffer channels, can include e.g. TD decorr data */ - int16_t nchan_buffer_full; /* number of channels to be fully buffered */ - int16_t n_samples_available; /* samples still available for rendering in the current frame */ - int16_t n_samples_buffered; /* full number of samples in the buffer (including spill to next frame) */ - int16_t n_samples_rendered; /* samples already rendered in the current frame */ - int16_t n_samples_granularity; /* render granularity */ + float *tc_buffer; /* the buffer itself */ + float *tc[MAX_INTERN_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; @@ -981,10 +976,8 @@ typedef struct decoder_tc_buffer_structure int16_t num_slots; int16_t n_samples_discard; /* number of samples to discard from the beginning of the output */ -#ifdef FIX_1330_JBM_MEMORY float *tc_buffer2; /* non-scaled buffer of output audio - needed only when '*tc_buffer* is not long enough */ -#endif } DECODER_TC_BUFFER, *DECODER_TC_BUFFER_HANDLE; typedef struct jbm_metadata_structure @@ -1122,7 +1115,7 @@ typedef struct Decoder_Struct HRTFS_CREND_HANDLE hHrtfCrend; /* HRTF tables for CRend binaural renderer */ HRTFS_FASTCONV_HANDLE hHrtfFastConv; /* FASTCONV HRTF tables for binaural rendering */ HRTFS_PARAMBIN_HANDLE hHrtfParambin; /* HRTF tables for parametric binauralizer */ - HRTFS_STATISTICS_HANDLE hHrtfStatistics; /* HRTF statistics handle */ + HRTFS_STATISTICS_HANDLE hHrtfStatistics; /* HRTF statistics handle */ LSSETUP_CUSTOM_HANDLE hLsSetupCustom; /* Custom LS configuration handle */ float *hoa_dec_mtx; /* Pointer to decoder matrix for SBA */ HEAD_TRACK_DATA_HANDLE hHeadTrackData; /* Head tracking data structure */ diff --git a/lib_dec/ivas_stereo_mdct_core_dec.c b/lib_dec/ivas_stereo_mdct_core_dec.c index 5b3839aef3cfffb5719be0f071dbc39f79a43cdb..971163ae87f6f31ea18efcd151e0afec895b6a66 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec.c +++ b/lib_dec/ivas_stereo_mdct_core_dec.c @@ -155,10 +155,6 @@ void stereo_mdct_core_dec( float Aq[CPE_CHANNELS][( NB_SUBFR16k + 1 ) * ( M + 1 )]; float *x[CPE_CHANNELS][NB_DIV]; - /*needed to allocate N_MAX to prevent stereo switching crash */ -#ifndef FIX_1320_STACK_CPE_DECODER - float x_0_buf[CPE_CHANNELS][N_MAX]; -#endif float *x_0[CPE_CHANNELS][NB_DIV]; /* Concealment */ @@ -180,6 +176,7 @@ void stereo_mdct_core_dec( int16_t p_param[CPE_CHANNELS][NB_DIV]; int16_t nTnsBitsTCX10[CPE_CHANNELS][NB_DIV]; + float signal_outFB_tmp[CPE_CHANNELS][L_FRAME_PLUS]; float signal_out_tmp[CPE_CHANNELS][L_FRAME_PLUS]; push_wmops( "stereo_mdct_core_dec" ); @@ -204,15 +201,9 @@ void stereo_mdct_core_dec( x[ch][0] = &signal_out_tmp[ch][0]; x[ch][1] = &signal_out_tmp[ch][0] + L_FRAME_PLUS / 2; -#ifdef FIX_1320_STACK_CPE_DECODER set_zero( signal_outFB_tmp[ch], N_MAX ); /* length of N_MAX is needed to prevent stereo switching crash -> reuse buffer signal_outFB_tmp[][] */ x_0[ch][0] = &signal_outFB_tmp[ch][0]; x_0[ch][1] = &signal_outFB_tmp[ch][0] + L_FRAME48k / 2; -#else - set_zero( x_0_buf[ch], N_MAX ); - x_0[ch][0] = &x_0_buf[ch][0]; - x_0[ch][1] = &x_0_buf[ch][0] + L_FRAME48k / 2; -#endif nTnsBitsTCX10[ch][0] = 0; nTnsBitsTCX10[ch][1] = 0; @@ -634,7 +625,6 @@ static void run_min_stats( power_spec_scale_fac = 1.f / (float) ( L_FRAME16k * L_FRAME16k ); power_spec[0] = spec_in[0] * spec_in[0] * power_spec_scale_fac; power_spec[L_FRAME16k - 1] = spec_in[L_FRAME16k - 1] * spec_in[L_FRAME16k - 1] * power_spec_scale_fac; - for ( int16_t i = 1; i < L_FRAME16k - 1; i++ ) { float mdst; diff --git a/lib_dec/ivas_svd_dec.c b/lib_dec/ivas_svd_dec.c index 5d15910c1db2a0ae1f361d911e37d9a0d4496f82..12a98e87e954da5b1b676f6dab3a23541db55419 100644 --- a/lib_dec/ivas_svd_dec.c +++ b/lib_dec/ivas_svd_dec.c @@ -42,6 +42,7 @@ #endif #include "wmc_auto.h" + /*-----------------------------------------------------------------------* * Local constants *-----------------------------------------------------------------------*/ @@ -52,14 +53,16 @@ #define SVD_MAX_NUM_ITERATION 75 /* maximum number of interations before exiting the SVD */ #define SVD_ZERO_FLUSH_THRESHOLD 1.0e-20f + /*-----------------------------------------------------------------------* * Local function prototypes *-----------------------------------------------------------------------*/ static float GivensRotation( const float x, const float z ); + static void biDiagonalReductionLeft( float singularVectors[][MAX_OUTPUT_CHANNELS], const int16_t nChannelsL, const int16_t nChannelsC, const int16_t currChannel, float *g ); -static void biDiagonalReductionRight( float singularVectors[][MAX_OUTPUT_CHANNELS], const int16_t nChannelsL, const int16_t nChannelsC, const int16_t currChannel, float *g ); +static void biDiagonalReductionRight( float singularVectors[][MAX_OUTPUT_CHANNELS], const int16_t nChannelsL, const int16_t nChannelsC, const int16_t currChannel, float *g ); static void singularVectorsAccumulationLeft( float singularVectors_Left[][MAX_OUTPUT_CHANNELS], float singularValues[MAX_OUTPUT_CHANNELS], const int16_t nChannelsL, const int16_t nChannelsC ); @@ -496,10 +499,10 @@ static void HouseholderReduction( biDiagonalReductionLeft( singularVectors_Left, nChannelsL, nChannelsC, nCh, &g_left ); singularValues[nCh] = g_left; biDiagonalReductionRight( singularVectors_Left, nChannelsL, nChannelsC, nCh, &g_right ); + *eps_x = max( *eps_x, ( fabsf( singularValues[nCh] ) + fabsf( secDiag[nCh] ) ) ); } - /* SingularVecotr Accumulation */ singularVectorsAccumulationRight( singularVectors_Left, singularVectors_Right, secDiag, nChannelsC ); singularVectorsAccumulationLeft( singularVectors_Left, singularValues, nChannelsL, nChannelsC ); @@ -513,6 +516,7 @@ static void HouseholderReduction( * * *-------------------------------------------------------------------------*/ + static void biDiagonalReductionLeft( float singularVectors[][MAX_OUTPUT_CHANNELS], const int16_t nChannelsL, @@ -530,11 +534,11 @@ static void biDiagonalReductionLeft( { norm_x = 0.0f; - for ( jCh = currChannel; jCh < nChannelsL; jCh++ ) /* nChannelsL */ { norm_x += ( singularVectors[jCh][currChannel] * singularVectors[jCh][currChannel] ); } + if ( ( norm_x ) ) /*(fabsf(*sig_x) > EPSILON * fabsf(*sig_x)) { */ { ( *g ) = -( singularVectors[currChannel][currChannel] >= 0 ? 1 : ( -1 ) ) * sqrtf( norm_x ); @@ -563,11 +567,13 @@ static void biDiagonalReductionLeft( return; } + /*------------------------------------------------------------------------- * biDiagonalReductionRight() * * *-------------------------------------------------------------------------*/ + static void biDiagonalReductionRight( float singularVectors[][MAX_OUTPUT_CHANNELS], const int16_t nChannelsL, @@ -618,12 +624,6 @@ static void biDiagonalReductionRight( } -/*------------------------------------------------------------------------- - * biDiagonalReductionRight() - * - * - *-------------------------------------------------------------------------*/ - /*------------------------------------------------------------------------- * singularVectorsAccumulationLeft() * diff --git a/lib_dec/ivas_tcx_core_dec.c b/lib_dec/ivas_tcx_core_dec.c index ee4e4598ecd3949af3c29c36437659c2138ed2d7..634ac0f6d7d77e7991bddddb74137efdbdf8ec26 100644 --- a/lib_dec/ivas_tcx_core_dec.c +++ b/lib_dec/ivas_tcx_core_dec.c @@ -179,11 +179,7 @@ void stereo_tcx_core_dec( Word16 Aind[M + 1], lspind[M]; /*Synth*/ -#ifdef FIX_1320_STACK_CPE_DECODER float synth_buf[OLD_SYNTH_INTERNAL_DEC + L_FRAME_PLUS_INTERNAL + M]; -#else - float synth_buf[OLD_SYNTH_SIZE_DEC + L_FRAME_PLUS + M]; -#endif float *synth; float synth_bufFB[OLD_SYNTH_SIZE_DEC + L_FRAME_PLUS + M]; float *synthFB; @@ -250,18 +246,14 @@ void stereo_tcx_core_dec( synthFB = synth_bufFB + hTcxDec->old_synth_lenFB; mvr2r( hTcxDec->old_synth, synth_buf, hTcxDec->old_synth_len ); mvr2r( hTcxDec->old_synthFB, synth_bufFB, hTcxDec->old_synth_lenFB ); -#ifdef FIX_1320_STACK_CPE_DECODER set_zero( synth, L_FRAME_PLUS_INTERNAL + M ); -#else - set_zero( synth, L_FRAME_PLUS + M ); -#endif set_zero( synthFB, L_FRAME_PLUS + M ); #ifdef DEBUG_MODE_INFO_PLC dbgwrite( synth_buf, sizeof( float ), OLD_SYNTH_SIZE_DEC + L_FRAME_PLUS + M, 1, "res/synth_buf_init" ); dbgwrite( synth_bufFB, sizeof( float ), OLD_SYNTH_SIZE_DEC + L_FRAME_PLUS + M, 1, "res/synthFB_buf_init" ); -#endif +#endif /*--------------------------------------------------------------------------------* * BITSTREAM DECODING *--------------------------------------------------------------------------------*/ @@ -296,18 +288,7 @@ void stereo_tcx_core_dec( { int16_t tcx_lpc_cdk; -#ifdef FIX_1384_MSAN_stereo_tcx_core_enc tcx_lpc_cdk = tcxlpc_get_cdk( st->coder_type ); -#else - if ( bfi && st->use_partial_copy && st->rf_frame_type == RF_TCXFD ) - { - tcx_lpc_cdk = tcxlpc_get_cdk( GENERIC ); - } - else - { - tcx_lpc_cdk = tcxlpc_get_cdk( st->coder_type ); - } -#endif mvr2r( st->lsf_old, &lsf[0], M ); mvr2r( st->lsp_old, &lsp[0], M ); @@ -406,12 +387,6 @@ void stereo_tcx_core_dec( lsp2a_stab( st->lsp_old, st->old_Aq_12_8, M ); } -#ifndef FIX_1384_MSAN_stereo_tcx_core_enc - if ( st->enablePlcWaveadjust && bfi ) - { - st->hPlcInfo->nbLostCmpt++; - } -#endif /*--------------------------------------------------------------------------------* * TD-TCX concealment *--------------------------------------------------------------------------------*/ @@ -527,31 +502,24 @@ void stereo_tcx_core_dec( } } +#ifdef DEBUG_MODE_TCX + { + int16_t tmp[L_FRAME48k]; + + for ( i = 0; i < st->L_frame; i++ ) + { + tmp[i] = (int16_t) ( synth[i] + 0.5f ); + } + dbgwrite( tmp, sizeof( int16_t ), st->L_frame, 1, "./res/stereo_tcx_dec_synth.pcm" ); + } +#endif + /*--------------------------------------------------------------------------------* * Post-processing *--------------------------------------------------------------------------------*/ if ( st->core == TCX_10_CORE || st->core == TCX_20_CORE ) { -#ifndef FIX_1384_MSAN_stereo_tcx_core_enc - if ( st->enablePlcWaveadjust || /* bfi */ - ( st->last_total_brate >= HQ_48k && /* recovery */ - st->last_codec_mode == MODE2 ) ) - { - /* waveform adjustment */ - concealment_signal_tuning( st, bfi, synthFB, st->last_core_bfi ); - - if ( ( bfi || st->prev_bfi ) && st->hPlcInfo->Pitch && st->hPlcInfo->concealment_method == TCX_NONTONAL ) - { - lerp( synthFB, synth, st->L_frame, hTcxDec->L_frameTCX ); - - if ( !bfi && st->prev_bfi ) - { - st->hPlcInfo->Pitch = 0; - } - } - } -#endif if ( !bfi && st->hTonalMDCTConc != NULL ) { TonalMDCTConceal_SaveTimeSignal( st->hTonalMDCTConc, synthFB, hTcxDec->L_frameTCX ); @@ -675,12 +643,6 @@ void stereo_tcx_core_dec( if ( !bfi ) { -#ifndef FIX_1384_MSAN_stereo_tcx_core_enc - if ( st->enablePlcWaveadjust ) - { - st->hPlcInfo->nbLostCmpt = 0; - } -#endif if ( param[1 + NOISE_FILL_RANGES] != 0 ) { set_f( pitch_buf, hTcxLtpDec->tcxltp_pitch_int + (float) hTcxLtpDec->tcxltp_pitch_fr / (float) st->pit_res_max, NB_SUBFR16k ); @@ -837,11 +799,7 @@ static void dec_prm_tcx( getTCXMode( st, st, 0 /* <- MCT_flag */ ); /* last_core for error concealment */ -#ifdef FIX_1384_MSAN_stereo_tcx_core_enc if ( st->element_mode != IVAS_CPE_MDCT ) -#else - if ( !st->use_partial_copy && st->element_mode != IVAS_CPE_MDCT ) -#endif { st->last_core_from_bs = get_next_indice( st, 1 ); /* Store decoder memory of last_core */ if ( st->last_core == ACELP_CORE && st->last_core_from_bs != ACELP_CORE ) @@ -867,24 +825,16 @@ static void dec_prm_tcx( } } -#ifndef FIX_1384_MSAN_stereo_tcx_core_enc - if ( !st->use_partial_copy ) + if ( st->element_mode != IVAS_CPE_MDCT ) { -#endif - if ( st->element_mode != IVAS_CPE_MDCT ) - { - getTCXWindowing( st->core, st->last_core, st->element_mode, st->hTcxCfg, st ); - } - st->flagGuidedAcelp = 0; - - if ( st->dec_glr ) - { - st->dec_glr_idx = -1; - } -#ifndef FIX_1384_MSAN_stereo_tcx_core_enc + getTCXWindowing( st->core, st->last_core, st->element_mode, st->hTcxCfg, st ); } -#endif + st->flagGuidedAcelp = 0; + if ( st->dec_glr ) + { + st->dec_glr_idx = -1; + } #ifdef DEBUG_MODE_TCX fprintf( pF, "\t TCX Header: %d bits: %d %d %d %d\n", st->next_bit_pos - start_bit_pos, st->tcxonly, st->core, st->tcxonly ? st->clas_dec : st->hTcxCfg->coder_type, st->hTcxCfg->tcx_curr_overlap_mode ); nbits_tcx = st->next_bit_pos; @@ -906,7 +856,6 @@ static void dec_prm_tcx( * TCX20/10 parameters *--------------------------------------------------------------------------------*/ -#ifdef FIX_1384_MSAN_stereo_tcx_core_enc getTCXparam( st, st, hm_cfg, param, bits_common, start_bit_pos, NULL, NULL, NULL, -1 ); if ( *total_nbbits - bitsRead[0] < ( st->next_bit_pos - start_bit_pos ) ) @@ -916,27 +865,11 @@ static void dec_prm_tcx( } bitsRead[0] = st->next_bit_pos - start_bit_pos; -#else - if ( st->use_partial_copy == 0 ) - { - getTCXparam( st, st, hm_cfg, param, bits_common, start_bit_pos, NULL, NULL, NULL, -1 ); - } - - if ( !st->use_partial_copy ) - { - if ( *total_nbbits - bitsRead[0] < ( st->next_bit_pos - start_bit_pos ) ) - { - st->BER_detect = 1; - st->next_bit_pos = start_bit_pos + *total_nbbits - bitsRead[0]; - } - - bitsRead[0] = st->next_bit_pos - start_bit_pos; - } -#endif return; } + /*-----------------------------------------------------------------* * Function stereo_tcx_dec_mode_switch_reconf() * diff --git a/lib_dec/jbm_pcmdsp_apa.c b/lib_dec/jbm_pcmdsp_apa.c index baaa6e13c9954c62026bdda5be521c3d100fa66c..84dd867403bf40dd1df5e19528dc5276d0cb6cbe 100644 --- a/lib_dec/jbm_pcmdsp_apa.c +++ b/lib_dec/jbm_pcmdsp_apa.c @@ -562,11 +562,7 @@ uint8_t apa_exec( ) { uint16_t i; -#ifdef JBM_MEMORY_OPT float frm_in[APA_BUF]; /* NOTE: this buffer could be smaller if alocated dynamically based on the actual sampling rate and number of channels */ -#else - float 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; diff --git a/lib_dec/jbm_pcmdsp_apa.h b/lib_dec/jbm_pcmdsp_apa.h index 6d35fa8b505e1641a631ff6708aa4a01fd06cdd1..3fc00e97255373cfcb89181d190fe00bbc4c397b 100644 --- a/lib_dec/jbm_pcmdsp_apa.h +++ b/lib_dec/jbm_pcmdsp_apa.h @@ -50,14 +50,9 @@ */ /* size of IO buffers (a_in[], a_out[]) for apa_exec() */ -#ifdef JBM_MEMORY_OPT #define APA_BUF_PER_CHANNEL ( IVAS_MAX_FRAME_SIZE * 2 ) /* == twice the max. frame length */ #define APA_MAX_NUM_CHANNELS ( 12 ) /* == MAX_TRANSPORT_CHANNELS */ -#else -#define APA_BUF_PER_CHANNEL ( IVAS_MAX_FRAME_SIZE * 3 ) -#define APA_MAX_NUM_CHANNELS 16 -#endif -#define APA_BUF ( APA_BUF_PER_CHANNEL * APA_MAX_NUM_CHANNELS ) +#define APA_BUF ( APA_BUF_PER_CHANNEL * APA_MAX_NUM_CHANNELS ) /* min/max sampling rate [Hz] */ #define APA_MIN_RATE 1000 diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 57e3ad0307631c2595c62ea19a57d74d9920168f..d8a602beb091edc727cf3211d122c4be7c22f721 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -30,9 +30,6 @@ *******************************************************************************************************/ -#include -#include -#include #include "lib_dec.h" #include "ivas_cnst.h" #include "ivas_prot.h" @@ -44,8 +41,11 @@ #include "jbm_jb4sb.h" #include "jbm_pcmdsp_apa.h" #include "jbm_pcmdsp_fifo.h" +#include +#include #ifdef DEBUGGING #include "debug.h" +#include #endif #include "wmc_auto.h" @@ -85,9 +85,6 @@ struct IVAS_DEC int16_t tsm_max_scaling; int16_t timeScalingDone; /* have we done already one TSM in a 20ms frame? */ float tsm_quality; -#ifndef JBM_MEMORY_OPT - float *apaExecBuffer; /* Buffer for APA scaling */ -#endif PCMDSP_APA_HANDLE hTimeScaler; bool needNewFrame; bool hasBeenFedFrame; @@ -100,7 +97,7 @@ struct IVAS_DEC int16_t CNG; /* RXDTX handler: CNG=1, nonCNG=0 */ uint16_t nSamplesFlushed; - int16_t *flushbuffer; + void *flushbuffer; IVAS_DEC_PCM_TYPE pcmType; bool hasBeenPreparedRendering; }; @@ -127,9 +124,9 @@ static PCM_RESOLUTION pcm_type_API_to_internal( const IVAS_DEC_PCM_TYPE pcmType static void *pcm_buffer_offset( void *buffer, const IVAS_DEC_PCM_TYPE pcmType, const int32_t offset ); static ivas_error set_pcm_buffer_to_zero( void *buffer, const IVAS_DEC_PCM_TYPE pcmType, const int16_t nZeroSamples ); static ivas_error isar_set_split_rend_setup( ISAR_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, const ISAR_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, ISAR_SPLIT_REND_BITS_DATA *splitRendBits ); -static ivas_error ivas_create_handle_isar( ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend_out ); static ivas_error ivas_dec_reconfig_split_rend( Decoder_Struct *st_ivas ); static ivas_error ivas_dec_init_split_rend( Decoder_Struct *st_ivas ); +static ivas_error ivas_create_handle_isar( ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend_out ); static void ivas_destroy_handle_isar( ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend_out ); static int16_t get_render_frame_size_ms( IVAS_RENDER_FRAMESIZE render_framesize ); #ifdef FIX_1119_SPLIT_RENDERING_VOIP @@ -138,6 +135,7 @@ static int16_t ivas_dec_split_rend_cldfb_in( const RENDERER_TYPE renderer_type ) #endif static void update_voip_rendered20ms( IVAS_DEC_HANDLE hIvasDec, const int16_t nSamplesRendered ); + /*---------------------------------------------------------------------* * IVAS_DEC_Open() * @@ -166,11 +164,9 @@ ivas_error IVAS_DEC_Open( { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS decoder handle" ); } + hIvasDec = *phIvasDec; hIvasDec->hVoIP = NULL; -#ifndef JBM_MEMORY_OPT - hIvasDec->apaExecBuffer = NULL; -#endif hIvasDec->hTimeScaler = NULL; hIvasDec->tsm_scale = 100; hIvasDec->tsm_max_scaling = 0; @@ -264,6 +260,7 @@ ivas_error IVAS_DEC_Open( return IVAS_ERR_WRONG_PARAMS; } + /*-------------------------------------------------------------------------* * isar_set_split_rend_setup() * @@ -274,7 +271,7 @@ static ivas_error isar_set_split_rend_setup( ISAR_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, const ISAR_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, - ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ ) { splitRendBits->bits_read = 0; @@ -286,12 +283,6 @@ static ivas_error isar_set_split_rend_setup( splitRendBits->isar_frame_size_ms = 0; splitRendBits->lc3plus_highres = 0; -#ifndef TMP_FIX_SPLIT_REND - if ( ( hSplitBinRend->hMultiBinCldfbData = (ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for split rendering structure" ); - } -#endif ISAR_PRE_REND_GetMultiBinPoseData( hSplitBinConfig, &hSplitBinRend->splitrend.multiBinPoseData, ( hCombinedOrientationData != NULL ) ? hCombinedOrientationData->sr_pose_pred_axis : DEFAULT_AXIS ); if ( hCombinedOrientationData != NULL ) @@ -355,23 +346,23 @@ void IVAS_DEC_Close( ( *phIvasDec )->hVoIP = NULL; } +#ifndef IVAS_RTPDUMP /* destroy Split binaural renderer (ISAR) handle */ ivas_destroy_handle_isar( &( *phIvasDec )->st_ivas->hSplitBinRend ); +#endif if ( ( *phIvasDec )->st_ivas ) { +#ifdef IVAS_RTPDUMP + /* destroy Split binaural renderer (ISAR) handle */ + ivas_destroy_handle_isar( &( *phIvasDec )->st_ivas->hSplitBinRend ); +#endif ivas_destroy_dec( ( *phIvasDec )->st_ivas ); ( *phIvasDec )->st_ivas = NULL; } apa_exit( &( *phIvasDec )->hTimeScaler ); -#ifndef JBM_MEMORY_OPT - if ( ( *phIvasDec )->apaExecBuffer != NULL ) - { - free( ( *phIvasDec )->apaExecBuffer ); - } -#endif if ( ( *phIvasDec )->flushbuffer != NULL ) { free( ( *phIvasDec )->flushbuffer ); @@ -451,22 +442,22 @@ static ivas_error create_flush_buffer( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_Configure( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const uint32_t sampleRate, /* i : output sampling frequency */ - const IVAS_AUDIO_CONFIG outputConfig, /* i : output configuration */ - const IVAS_RENDER_FRAMESIZE renderFramesize, /* i : rendering frame size */ - const bool customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ - const bool hrtfReaderEnabled, /* i : enable HRTF binary file input */ - const bool enableHeadRotation, /* i : enable head rotation for binaural output */ - const bool enableExternalOrientation, /* i : enable external orientations */ - const IVAS_HEAD_ORIENT_TRK_T orientation_tracking, /* i : head orientation tracking type */ - const bool renderConfigEnabled, /* i : enable Renderer config. file for binaural output */ - const bool non_diegetic_pan_enabled, /* i : enabled diegetic panning */ - const float non_diegetic_pan_gain, /* i : non diegetic panning gain */ - const bool dpidEnabled, /* i : enable directivity pattern option */ - const uint16_t acousticEnvironmentId, /* i : Acoustic environment ID */ - const bool objEditEnabled, /* i : enable object editing */ - const bool delayCompensationEnabled /* i : enable delay compensation */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const uint32_t sampleRate, /* i : output sampling frequency */ + const AUDIO_CONFIG outputConfig, /* i : output configuration */ + const IVAS_RENDER_FRAMESIZE renderFramesize, /* i : rendering frame size */ + const bool customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ + const bool hrtfReaderEnabled, /* i : enable HRTF binary file input */ + const bool enableHeadRotation, /* i : enable head rotation for binaural output */ + const bool enableExternalOrientation, /* i : enable external orientations */ + const IVAS_HEAD_ORIENT_TRK_T orientation_tracking, /* i : head orientation tracking type */ + const bool renderConfigEnabled, /* i : enable Renderer config. file for binaural output */ + const bool non_diegetic_pan_enabled, /* i : enabled diegetic panning */ + const float non_diegetic_pan_gain, /* i : non diegetic panning gain */ + const bool dpidEnabled, /* i : enable directivity pattern option */ + const uint16_t acousticEnvironmentId, /* i : Acoustic environment ID */ + const bool objEditEnabled, /* i : enable object editing */ + const bool delayCompensationEnabled /* i : enable delay compensation */ ) { Decoder_Struct *st_ivas; @@ -567,11 +558,11 @@ ivas_error IVAS_DEC_Configure( /*---------------------------------------------------------------------* * IVAS_DEC_EnableSplitRendering( ) * - * Intitialize Split rendering + * Update IVAS decoder config. if Split rendering is enabled *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_EnableSplitRendering( - IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ ) { DECODER_CONFIG_HANDLE hDecoderConfig; @@ -593,7 +584,7 @@ ivas_error IVAS_DEC_EnableSplitRendering( /*---------------------------------------------------------------------* * get_render_framesize_ms( ) * - * Get the 5ms flag + * Get render framesize in ms *---------------------------------------------------------------------*/ static int16_t get_render_frame_size_ms( @@ -606,7 +597,7 @@ static int16_t get_render_frame_size_ms( /*---------------------------------------------------------------------* * IVAS_DEC_SetRenderFramesize( ) * - * Get the 5ms flag + * Set render framesize *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_SetRenderFramesize( @@ -625,6 +616,7 @@ ivas_error IVAS_DEC_SetRenderFramesize( { hIvasDec->st_ivas->hExtOrientationData->num_subframes = (int16_t) render_framesize; } + if ( hIvasDec->st_ivas->hCombinedOrientationData != NULL ) { hIvasDec->st_ivas->hCombinedOrientationData->num_subframes = (int16_t) render_framesize; @@ -633,10 +625,11 @@ ivas_error IVAS_DEC_SetRenderFramesize( return IVAS_ERR_OK; } + /*---------------------------------------------------------------------* * IVAS_DEC_GetGetRenderFramesize( ) * - * Get the 5ms flag + * Get render framesize *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_GetRenderFramesize( @@ -696,6 +689,7 @@ ivas_error IVAS_DEC_GetRenderFramesizeSamples( return IVAS_ERR_OK; } + /*---------------------------------------------------------------------* * IVAS_DEC_GetGetRenderFramesizeMs( ) * @@ -717,6 +711,7 @@ ivas_error IVAS_DEC_GetRenderFramesizeMs( return IVAS_ERR_OK; } + /*---------------------------------------------------------------------* * IVAS_DEC_GetGetReferencesUpdateFrequency( ) * @@ -741,7 +736,7 @@ ivas_error IVAS_DEC_GetReferencesUpdateFrequency( /*---------------------------------------------------------------------* * IVAS_DEC_GetGetNumOrientationSubframes( ) * - * Get the number of subframes for head/ecernal orientation per render frame + * Get the number of subframes for head/external orientation per render frame *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_GetNumOrientationSubframes( @@ -788,6 +783,7 @@ ivas_error IVAS_DEC_EnableVoIP( hIvasDec->Opt_VOIP = 1; #endif hDecoderConfig->Opt_tsm = 1; + if ( hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) { hDecoderConfig->nchan_out = audioCfg2channels( hDecoderConfig->output_config ); @@ -867,24 +863,19 @@ ivas_error IVAS_DEC_FeedFrame_Serial( { ivas_error error; -#ifdef FIX_1388_MSAN_ivas_init_decoder if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } -#endif - if ( !hIvasDec->isInitialized ) { /* Once first frame is fed, finish initialization in EVS Mono. * In IVAS mode, initialization is done in ivas_dec(). */ if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) { -#ifdef FIX_1388_MSAN_ivas_init_decoder hIvasDec->st_ivas->hDecoderConfig->ivas_total_brate = ACELP_8k00; -#endif if ( ( error = ivas_init_decoder( hIvasDec->st_ivas ) ) != IVAS_ERR_OK ) { return error; @@ -897,12 +888,7 @@ ivas_error IVAS_DEC_FeedFrame_Serial( st->prev_use_partial_copy = 0; hIvasDec->st_ivas->hDecoderConfig->ivas_total_brate = hIvasDec->hVoIP->hCurrentDataUnit->dataSize * FRAMES_PER_SEC; } -#ifndef FIX_1388_MSAN_ivas_init_decoder - else - { - hIvasDec->st_ivas->hDecoderConfig->ivas_total_brate = ACELP_8k00; - } -#endif + hIvasDec->isInitialized = true; } } @@ -1152,7 +1138,7 @@ ivas_error IVAS_DEC_ReadFormat( /*---------------------------------------------------------------------* * IVAS_DEC_GetSamplesDecoder( ) * - * Main function to decode transport channels, do TSM and feed to renderer. + * Main function to run setup, decode transport channels, do TSM and feed to renderer. *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_GetSamplesDecoder( @@ -1181,11 +1167,8 @@ ivas_error IVAS_DEC_GetSamplesDecoder( } st_ivas = hIvasDec->st_ivas; -#ifdef JBM_MEMORY_OPT + isInitialized_voip = hIvasDec->hTimeScaler != NULL; -#else - isInitialized_voip = hIvasDec->apaExecBuffer != NULL; -#endif if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) /* wait for the first good frame */ { @@ -1232,7 +1215,7 @@ ivas_error IVAS_DEC_GetSamplesDecoder( * JBM *-----------------------------------------------------------------*/ - if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) + if ( st_ivas->hDecoderConfig->Opt_tsm ) { if ( nTransportChannels != hIvasDec->nTransportChannelsOld ) { @@ -1247,17 +1230,11 @@ ivas_error IVAS_DEC_GetSamplesDecoder( return IVAS_ERR_UNKNOWN; } -#ifdef JBM_MEMORY_OPT /* convert deinterleaved decoded TC audio channels buffer to an interleaved one */ ivas_buffer_deinterleaved_to_interleaved( st_ivas->p_output_f, nTransportChannels, hIvasDec->nSamplesFrame, st_ivas->hTcBuffer->tc_buffer ); /* time-scale modification */ if ( apa_exec( hIvasDec->hTimeScaler, st_ivas->hTcBuffer->tc_buffer, hIvasDec->nSamplesFrame * nTransportChannels, (uint16_t) hIvasDec->tsm_max_scaling, st_ivas->hTcBuffer->tc_buffer, &nTimeScalerOutSamples ) != 0 ) -#else - ivas_syn_output_f( hIvasDec->st_ivas->p_output_f, hIvasDec->nSamplesFrame, nTransportChannels, hIvasDec->apaExecBuffer ); - - if ( apa_exec( hIvasDec->hTimeScaler, hIvasDec->apaExecBuffer, hIvasDec->nSamplesFrame * nTransportChannels, (uint16_t) hIvasDec->tsm_max_scaling, hIvasDec->apaExecBuffer, &nTimeScalerOutSamples ) != 0 ) -#endif { return IVAS_ERR_UNKNOWN; } @@ -1265,11 +1242,9 @@ ivas_error IVAS_DEC_GetSamplesDecoder( assert( nTimeScalerOutSamples <= APA_BUF ); nSamplesTcsScaled = nTimeScalerOutSamples / nTransportChannels; hIvasDec->timeScalingDone = 1; -#ifdef JBM_MEMORY_OPT /* convert interleaved time-scaled TC audio channels buffer to deinterleaved one */ ivas_buffer_interleaved_to_deinterleaved( st_ivas->hTcBuffer->tc_buffer, nTransportChannels, nSamplesTcsScaled, NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_L_FRAME_NS ) ); -#endif } else { @@ -1280,13 +1255,9 @@ ivas_error IVAS_DEC_GetSamplesDecoder( * Feed decoded transport channels samples to the renderer *-----------------------------------------------------------------*/ -#ifdef JBM_MEMORY_OPT ivas_jbm_dec_feed_tc_to_renderer( st_ivas, nSamplesTcsScaled, &nResidualSamples ); -#else - ivas_jbm_dec_feed_tc_to_renderer( st_ivas, nSamplesTcsScaled, &nResidualSamples, hIvasDec->apaExecBuffer ); -#endif - if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) + if ( st_ivas->hDecoderConfig->Opt_tsm ) { /* feed residual samples to TSM for the next call */ if ( apa_set_renderer_residual_samples( hIvasDec->hTimeScaler, (uint16_t) nResidualSamples ) != 0 ) @@ -1304,15 +1275,15 @@ ivas_error IVAS_DEC_GetSamplesDecoder( * Set editable metadata *-----------------------------------------------------------------*/ - if ( hIvasDec->st_ivas->hIsmMetaData[0] ) + if ( st_ivas->hIsmMetaData[0] ) { - if ( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT || hIvasDec->st_ivas->ivas_format == SBA_ISM_FORMAT ) + if ( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) { - if ( hIvasDec->st_ivas->ism_mode == ISM_MODE_DISC || hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_DISC || hIvasDec->st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + if ( st_ivas->ism_mode == ISM_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { int16_t obj; - ISM_METADATA_HANDLE *hIsmMetaData = hIvasDec->st_ivas->hIsmMetaData; - for ( obj = 0; obj < hIvasDec->st_ivas->nchan_ism; obj++ ) + ISM_METADATA_HANDLE *hIsmMetaData = st_ivas->hIsmMetaData; + for ( obj = 0; obj < st_ivas->nchan_ism; obj++ ) { hIsmMetaData[obj]->edited_azimuth = hIsmMetaData[obj]->azimuth; hIsmMetaData[obj]->edited_elevation = hIsmMetaData[obj]->elevation; @@ -1322,21 +1293,21 @@ ivas_error IVAS_DEC_GetSamplesDecoder( hIsmMetaData[obj]->edited_gain = 1.0f; } - if ( hIvasDec->st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { - hIvasDec->st_ivas->hSbaIsmData->gain_bed = 1.0f; + st_ivas->hSbaIsmData->gain_bed = 1.0f; } } } } - if ( hIvasDec->st_ivas->hParamIsmDec != NULL ) + if ( st_ivas->hParamIsmDec != NULL ) { - if ( hIvasDec->st_ivas->ism_mode == ISM_MODE_PARAM ) + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { int16_t obj = 0; - PARAM_ISM_DEC_HANDLE hParamIsmDec = hIvasDec->st_ivas->hParamIsmDec; - for ( obj = 0; obj < hIvasDec->st_ivas->nchan_ism; obj++ ) + PARAM_ISM_DEC_HANDLE hParamIsmDec = st_ivas->hParamIsmDec; + for ( obj = 0; obj < st_ivas->nchan_ism; obj++ ) { hParamIsmDec->edited_azimuth_values[obj] = hParamIsmDec->azimuth_values[obj]; hParamIsmDec->edited_elevation_values[obj] = hParamIsmDec->elevation_values[obj]; @@ -1351,7 +1322,7 @@ ivas_error IVAS_DEC_GetSamplesDecoder( /*---------------------------------------------------------------------* * IVAS_DEC_GetEditableParameters( ) * - * + * Get editable metadata parameters *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_GetEditableParameters( @@ -1359,12 +1330,11 @@ ivas_error IVAS_DEC_GetEditableParameters( IVAS_EDITABLE_PARAMETERS *hIvasEditableParameters /* o : object editing parameters handle */ ) { - int16_t obj; + int16_t dirac_read_idx, obj; Decoder_Struct *st_ivas; ISM_MODE ism_mode; - int16_t dirac_read_idx; - if ( hIvasEditableParameters == NULL || hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasEditableParameters == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } @@ -1403,6 +1373,7 @@ ivas_error IVAS_DEC_GetEditableParameters( hIvasEditableParameters->ism_metadata[obj].gain = st_ivas->hIsmMetaData[obj]->edited_gain; hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = st_ivas->hIsmMetaData[obj]->non_diegetic_flag; } + if ( ism_mode == ISM_SBA_MODE_DISC ) { hIvasEditableParameters->gain_bed = 1.0f; @@ -1421,7 +1392,7 @@ ivas_error IVAS_DEC_GetEditableParameters( hIvasEditableParameters->ism_metadata[obj].non_diegetic_flag = 0; } } - else if ( hIvasDec->st_ivas->ism_mode == ISM_MODE_NONE ) + else if ( ism_mode == ISM_MODE_NONE ) { hIvasEditableParameters->num_obj = 0; } @@ -1497,7 +1468,7 @@ ivas_error IVAS_DEC_GetEditableParameters( /*---------------------------------------------------------------------* * IVAS_DEC_SetEditableParameters( ) * - * Main function to decode to PCM data + * Set editable metadata parameters *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_SetEditableParameters( @@ -1505,10 +1476,9 @@ ivas_error IVAS_DEC_SetEditableParameters( IVAS_EDITABLE_PARAMETERS hIvasEditableParameters /* i : object editing parameters handle */ ) { - int16_t obj; + int16_t dirac_read_idx, obj; Decoder_Struct *st_ivas; ISM_MODE ism_mode; - int16_t dirac_read_idx; if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { @@ -1531,6 +1501,11 @@ ivas_error IVAS_DEC_SetEditableParameters( return IVAS_ERROR( IVAS_ERR_OBJECTS_EDITING_NOT_SUPPORTED, "Object editing no supported in this operation mode." ); } + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + if ( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) { if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) @@ -1611,7 +1586,7 @@ ivas_error IVAS_DEC_SetEditableParameters( } #endif } - else if ( st_ivas->ivas_format == MASA_ISM_FORMAT && ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) + else if ( st_ivas->ivas_format == MASA_ISM_FORMAT && ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || ism_mode == ISM_MASA_MODE_DISC ) ) { int16_t id_th; float threshold_azi, threshold_ele; @@ -1644,7 +1619,7 @@ ivas_error IVAS_DEC_SetEditableParameters( new_ele = (int16_t) ( hIvasEditableParameters.ism_metadata[obj].elevation - 0.5f ); } - if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) { /* Handle MONO output */ if ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX ) @@ -1716,13 +1691,6 @@ ivas_error IVAS_DEC_SetEditableParameters( st_ivas->hIsmMetaData[obj]->edited_yaw = hIvasEditableParameters.ism_metadata[obj].yaw; st_ivas->hIsmMetaData[obj]->edited_pitch = hIvasEditableParameters.ism_metadata[obj].pitch; st_ivas->hIsmMetaData[obj]->edited_radius = hIvasEditableParameters.ism_metadata[obj].radius; -#ifndef NONBE_FIX_1172_OBJ_EDIT_JBM - st_ivas->hIsmMetaData[obj]->azimuth = hIvasEditableParameters.ism_metadata[obj].azimuth; - st_ivas->hIsmMetaData[obj]->elevation = hIvasEditableParameters.ism_metadata[obj].elevation; - st_ivas->hIsmMetaData[obj]->yaw = hIvasEditableParameters.ism_metadata[obj].yaw; - st_ivas->hIsmMetaData[obj]->pitch = hIvasEditableParameters.ism_metadata[obj].pitch; - st_ivas->hIsmMetaData[obj]->radius = hIvasEditableParameters.ism_metadata[obj].radius; -#endif st_ivas->hIsmMetaData[obj]->edited_gain = hIvasEditableParameters.ism_metadata[obj].gain; st_ivas->hIsmMetaData[obj]->non_diegetic_flag = hIvasEditableParameters.ism_metadata[obj].non_diegetic_flag; } @@ -1750,7 +1718,8 @@ ivas_error IVAS_DEC_SetEditableParameters( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_PrepareRenderer( - IVAS_DEC_HANDLE hIvasDec ) + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +) { if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { @@ -1768,6 +1737,138 @@ ivas_error IVAS_DEC_PrepareRenderer( } +/*---------------------------------------------------------------------* + * IVAS_DEC_GetSamplesRenderer( ) + * + * Main function to render the decoded data to output data + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_GetSamplesRenderer( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t nSamplesAsked, /* i : number of samples wanted by the caller */ + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ + int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ + bool *needNewFrame /* o : indication that the decoder needs a new frame */ +) +{ + ivas_error error; + uint16_t nSamplesRendered, nSamplesRendered_loop; + uint8_t nOutChannels; + Decoder_Struct *st_ivas; + + nSamplesRendered = 0; + nOutChannels = 0; + nSamplesRendered_loop = 0; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + /* the rendering needs to be prepared at this point */ + if ( hIvasDec->hasBeenPreparedRendering == false ) + { + return IVAS_ERR_UNKNOWN; + } + + st_ivas = hIvasDec->st_ivas; + + if ( hIvasDec->updateOrientation ) + { + /*----------------------------------------------------------------* + * Combine orientations + *----------------------------------------------------------------*/ + + if ( ( error = combine_external_and_head_orientations_dec( st_ivas->hHeadTrackData, st_ivas->hExtOrientationData, st_ivas->hCombinedOrientationData ) ) != IVAS_ERR_OK ) + { + return error; + } + + /*----------------------------------------------------------------* + * Binaural split rendering setup + *----------------------------------------------------------------*/ + + if ( st_ivas->hCombinedOrientationData != NULL && ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + isar_set_split_rend_ht_setup( &st_ivas->hSplitBinRend->splitrend, st_ivas->hCombinedOrientationData->Quaternions, st_ivas->hCombinedOrientationData->Rmat ); + } + + hIvasDec->updateOrientation = false; + } + + if ( !hIvasDec->hasBeenFedFrame && hIvasDec->nSamplesAvailableNext == 0 ) + { + /* no frame was fed, do nothing but ask for a frame */ + *needNewFrame = true; + *nOutSamples = 0; + hIvasDec->needNewFrame = true; + return IVAS_ERR_OK; + } + + /* check if we are still at the beginning with bad frames, put out zeroes, keep track of subframes */ + if ( !hIvasDec->isInitialized && st_ivas->bfi ) + { + hIvasDec->hasBeenFedFrame = false; + set_s( pcmBuf, 0, st_ivas->hDecoderConfig->nchan_out * nSamplesAsked ); + nSamplesRendered = nSamplesAsked; + hIvasDec->nSamplesAvailableNext -= nSamplesAsked; + } + else + { + nOutChannels = (uint8_t) st_ivas->hDecoderConfig->nchan_out; + hIvasDec->hasBeenFedFrame = false; + + /* check for possible flushed samples from a rate switch */ + if ( hIvasDec->nSamplesFlushed > 0 ) + { +#ifdef DEBUGGING + assert( hIvasDec->pcmType == pcmType ); +#endif + /* note: offset (rendered samples) is always 0 */ + if ( pcmType == IVAS_DEC_PCM_INT16 ) + { + mvs2s( (int16_t *) hIvasDec->flushbuffer, pcmBuf, hIvasDec->nSamplesFlushed * nOutChannels ); + } + else if ( pcmType == IVAS_DEC_PCM_FLOAT ) + { + mvr2r( (float *) hIvasDec->flushbuffer, pcmBuf, hIvasDec->nSamplesFlushed * nOutChannels ); + } +#ifdef DEBUGGING + else + { + assert( 0 && "wrong PCM type for the flush buffer!" ); + } +#endif + nSamplesRendered = hIvasDec->nSamplesFlushed; + hIvasDec->nSamplesFlushed = 0; + } + + /* render IVAS frames directly to the output buffer */ + if ( ( error = ivas_jbm_dec_render( st_ivas, nSamplesAsked - nSamplesRendered, &nSamplesRendered_loop, &hIvasDec->nSamplesAvailableNext, pcm_type_API_to_internal( pcmType ), pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ) ) ) != IVAS_ERR_OK ) + { + return error; + } + + nSamplesRendered += nSamplesRendered_loop; + } + + if ( hIvasDec->nSamplesAvailableNext == 0 ) + { + *needNewFrame = true; + hIvasDec->needNewFrame = true; + } + else + { + *needNewFrame = false; + } + + *nOutSamples = nSamplesRendered; + + return IVAS_ERR_OK; +} + + #ifdef FIX_1119_SPLIT_RENDERING_VOIP /*---------------------------------------------------------------------* * isar_get_frame_size( ) @@ -1961,150 +2062,18 @@ static ivas_error isar_generate_metadata_and_bitstream( #endif /* FIX_1119_SPLIT_RENDERING_VOIP */ -/*---------------------------------------------------------------------* - * IVAS_DEC_GetSamplesRenderer( ) - * - * Main function to render the decoded data to output data - *---------------------------------------------------------------------*/ - -ivas_error IVAS_DEC_GetSamplesRenderer( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const int16_t nSamplesAsked, /* i : number of samples wanted by the caller */ - const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ - void *pcmBuf, /* o : output synthesis signal */ - int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ - bool *needNewFrame /* o :indication that the decoder needs a new frame */ -) -{ - ivas_error error; - uint16_t nSamplesRendered, nSamplesRendered_loop; - uint8_t nOutChannels; - Decoder_Struct *st_ivas; - - nSamplesRendered = 0; - nOutChannels = 0; - nSamplesRendered_loop = 0; - - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - /* the rendering needs to be prepared at this point */ - if ( hIvasDec->hasBeenPreparedRendering == false ) - { - return IVAS_ERR_UNKNOWN; - } - - st_ivas = hIvasDec->st_ivas; - - if ( hIvasDec->updateOrientation ) - { - /*----------------------------------------------------------------* - * Combine orientations - *----------------------------------------------------------------*/ - - if ( ( error = combine_external_and_head_orientations_dec( hIvasDec->st_ivas->hHeadTrackData, hIvasDec->st_ivas->hExtOrientationData, hIvasDec->st_ivas->hCombinedOrientationData ) ) != IVAS_ERR_OK ) - { - return error; - } - - /*----------------------------------------------------------------* - * Binaural split rendering setup - *----------------------------------------------------------------*/ - - if ( hIvasDec->st_ivas->hCombinedOrientationData != NULL && ( hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) - { - isar_set_split_rend_ht_setup( &hIvasDec->st_ivas->hSplitBinRend->splitrend, hIvasDec->st_ivas->hCombinedOrientationData->Quaternions, hIvasDec->st_ivas->hCombinedOrientationData->Rmat ); - } - - hIvasDec->updateOrientation = false; - } - - if ( !hIvasDec->hasBeenFedFrame && hIvasDec->nSamplesAvailableNext == 0 ) - { - /* no frame was fed, do nothing but ask for a frame */ - *needNewFrame = true; - *nOutSamples = 0; - hIvasDec->needNewFrame = true; - return IVAS_ERR_OK; - } - - /* check if we are still at the beginning with bad frames, put out zeroes, keep track of subframes */ - if ( !hIvasDec->isInitialized && hIvasDec->st_ivas->bfi ) - { - hIvasDec->hasBeenFedFrame = false; - set_s( pcmBuf, 0, hIvasDec->st_ivas->hDecoderConfig->nchan_out * nSamplesAsked ); - nSamplesRendered = nSamplesAsked; - hIvasDec->nSamplesAvailableNext -= nSamplesAsked; - } - else - { - nOutChannels = (uint8_t) hIvasDec->st_ivas->hDecoderConfig->nchan_out; - hIvasDec->hasBeenFedFrame = false; - - /* check for possible flushed samples from a rate switch */ - if ( hIvasDec->nSamplesFlushed > 0 ) - { -#ifdef DEBUGGING - assert( hIvasDec->pcmType == pcmType ); -#endif - /* note: offset (rendered samples) is always 0 */ - if ( pcmType == IVAS_DEC_PCM_INT16 ) - { - mvs2s( (int16_t *) hIvasDec->flushbuffer, pcmBuf, hIvasDec->nSamplesFlushed * nOutChannels ); - } - else if ( pcmType == IVAS_DEC_PCM_FLOAT ) - { - mvr2r( (float *) hIvasDec->flushbuffer, pcmBuf, hIvasDec->nSamplesFlushed * nOutChannels ); - } -#ifdef DEBUGGING - else - { - assert( 0 && "wrong PCM type for the flush buffer!" ); - } -#endif - nSamplesRendered = hIvasDec->nSamplesFlushed; - hIvasDec->nSamplesFlushed = 0; - } - - /* render IVAS frames directly to the output buffer */ - if ( ( error = ivas_jbm_dec_render( st_ivas, nSamplesAsked - nSamplesRendered, &nSamplesRendered_loop, &hIvasDec->nSamplesAvailableNext, pcm_type_API_to_internal( pcmType ), pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ) ) ) != IVAS_ERR_OK ) - { - return error; - } - - nSamplesRendered += nSamplesRendered_loop; - } - - if ( hIvasDec->nSamplesAvailableNext == 0 ) - { - *needNewFrame = true; - hIvasDec->needNewFrame = true; - } - else - { - *needNewFrame = false; - } - - *nOutSamples = nSamplesRendered; - - return IVAS_ERR_OK; -} - - /*---------------------------------------------------------------------* * IVAS_DEC_GetSplitBinauralBitstream( ) * - * + * Get split-rendering bitstream *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_GetSplitBinauralBitstream( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - void *pcmBuf_out, /* o : output synthesis signal for BINAURAL_SPLIT_PCM */ - ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */ - int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ - bool *needNewFrame /* o : indication that the decoder needs a new frame */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + void *pcmBuf_out, /* o : output synthesis signal for BINAURAL_SPLIT_PCM */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */ + int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ + bool *needNewFrame /* o : indication that the decoder needs a new frame */ ) { #ifdef FIX_1119_SPLIT_RENDERING_VOIP @@ -2211,13 +2180,17 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( if ( hIvasDec->flushbuffer == NULL ) { hIvasDec->flushbuffer = (void *) malloc( numPoses * BINAURAL_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( float ) ); + if ( hIvasDec->flushbuffer == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate flush buffer" ); + } hIvasDec->pcmType = IVAS_DEC_PCM_FLOAT; set_zero( (float *) hIvasDec->flushbuffer, numPoses * BINAURAL_CHANNELS * hIvasDec->nSamplesFrame / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES ); } if ( st_ivas->hDecoderConfig->render_framesize != IVAS_RENDER_FRAMESIZE_20MS && - ( hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE || - hIvasDec->st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) + ( st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE || + st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) { numSamplesPerChannelToDecode = (int16_t) ( output_Fs / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ); numSamplesPerChannelToDecode *= (int16_t) st_ivas->hDecoderConfig->render_framesize; @@ -2245,7 +2218,7 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( } } - /* Decode and render */ + /* render */ if ( ( error = IVAS_DEC_GetSamplesRenderer( hIvasDec, numSamplesPerChannelToDecode, IVAS_DEC_PCM_FLOAT, pcmBuf, nOutSamples, needNewFrame ) ) != IVAS_ERR_OK ) { return error; @@ -2353,10 +2326,6 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( #endif ivas_syn_output( pOutput, numSamplesPerChannelToDecode, st_ivas->hDecoderConfig->nchan_out, (int16_t *) pcmBuf_out ); } - -#ifndef TMP_FIX_SPLIT_REND - free( st_ivas->hSplitBinRend->hMultiBinCldfbData ); -#endif #endif return IVAS_ERR_OK; @@ -2472,6 +2441,7 @@ ivas_error IVAS_DEC_GetNumObjects( { int16_t is_masa_ism; is_masa_ism = 0; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; @@ -2536,7 +2506,7 @@ ivas_error IVAS_DEC_GetFormat( /*---------------------------------------------------------------------* * getOutputBufferSize() * - * + * Get size of output buffer in samples *---------------------------------------------------------------------*/ static int16_t getOutputBufferSize( @@ -2550,7 +2520,7 @@ static int16_t getOutputBufferSize( if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) { - return (int16_t) ( st_ivas->hDecoderConfig->output_Fs * ( RENDERER_MAX_OUTPUT_CHANNELS + IVAS_MAX_NUM_OBJECTS ) / FRAMES_PER_SEC ); + return (int16_t) ( st_ivas->hDecoderConfig->output_Fs * ( MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS ) / FRAMES_PER_SEC ); } else if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM ) { @@ -2571,7 +2541,7 @@ static int16_t getOutputBufferSize( /*---------------------------------------------------------------------* * IVAS_DEC_GetOutputBufferSize() * - * + * Returns size of output buffer in samples *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_GetOutputBufferSize( @@ -2633,16 +2603,17 @@ ivas_error IVAS_DEC_GetNumOutputChannels( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_GetObjectMetadata( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_ISM_METADATA *metadata, /* o : struct where metadata decoded in most recently decoded frame will be written */ - const uint16_t zero_flag, /* i : if this flag is enabled, this function outputs a zero-initialized metadata struct */ - const uint16_t objectIdx /* i : index of the queried object */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_ISM_METADATA *metadata, /* o : struct where metadata decoded in most recently decoded frame will be written */ + const uint16_t zero_flag, /* i : if this flag is enabled, this function outputs a zero-initialized metadata struct */ + const uint16_t objectIdx /* i : index of the queried object */ ) { Decoder_Struct *st_ivas; ISM_METADATA_HANDLE hIsmMeta; int16_t is_masa_ism; is_masa_ism = 0; + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; @@ -2656,7 +2627,6 @@ ivas_error IVAS_DEC_GetObjectMetadata( is_masa_ism = 1; } } - if ( st_ivas->ivas_format != ISM_FORMAT && st_ivas->ivas_format != MASA_ISM_FORMAT && st_ivas->ivas_format != SBA_ISM_FORMAT && is_masa_ism == 0 ) { return IVAS_ERR_WRONG_MODE; @@ -2822,7 +2792,7 @@ ivas_error IVAS_DEC_FeedHeadTrackData( /*---------------------------------------------------------------------* * IVAS_DEC_FeedRefRotData( ) * - * Feed the decoder with the reference rotation + * Feed the decoder with the reference rotation data *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_FeedRefRotData( @@ -2976,15 +2946,16 @@ ivas_error IVAS_DEC_FeedCustomLsData( return IVAS_ERR_OK; } + /*---------------------------------------------------------------------* * IVAS_DEC_GetHrtfTDrendHandle( ) * - * + * Get TD binaural renderer handle *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_GetHrtfTDrendHandle( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_DEC_HRTF_HANDLE **hHrtfTD /* o : HRTF handle */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_DEC_HRTF_TD_HANDLE **hHrtfTD /* o : HRTF handle */ ) { if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHrtfTD == NULL ) @@ -3001,7 +2972,7 @@ ivas_error IVAS_DEC_GetHrtfTDrendHandle( /*---------------------------------------------------------------------* * IVAS_DEC_GetHrtfCRendHandle( ) * - * + * Get Crend binaural renderer handle *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_GetHrtfCRendHandle( @@ -3023,7 +2994,7 @@ ivas_error IVAS_DEC_GetHrtfCRendHandle( /*---------------------------------------------------------------------* * IVAS_DEC_GetHrtfFastConvHandle( ) * - * + * Get FastConv binaural renderer handle *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_GetHrtfFastConvHandle( @@ -3045,7 +3016,7 @@ ivas_error IVAS_DEC_GetHrtfFastConvHandle( /*---------------------------------------------------------------------* * IVAS_DEC_GetHrtfParamBinHandle( ) * - * + * Get Parametric binaural renderer handle *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_GetHrtfParamBinHandle( @@ -3063,11 +3034,10 @@ ivas_error IVAS_DEC_GetHrtfParamBinHandle( return IVAS_ERR_OK; } - /*---------------------------------------------------------------------* * IVAS_DEC_GetHrtfStatisticsHandle( ) * - * + * Get HRTF statistics (room effect) binaural renderer handle *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_GetHrtfStatisticsHandle( @@ -3157,6 +3127,7 @@ ivas_error IVAS_DEC_HRTF_binary_open( return IVAS_ERR_OK; } + /*---------------------------------------------------------------------* * IVAS_DEC_HRTF_binary_close( ) * @@ -3249,6 +3220,7 @@ static ivas_error copyRendererConfigStruct( mvr2r( hRCin->roomAcoustics.pAcoustic_dsr, hRCout->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); mvr2r( hRCin->directivity, hRCout->directivity, 3 * MAX_NUM_OBJECTS ); mvr2r( hRCin->distAtt, hRCout->distAtt, 3 ); + hRCout->split_rend_config = hRCin->split_rend_config; hRCout->roomAcoustics.use_er = hRCin->roomAcoustics.use_er; @@ -3261,7 +3233,7 @@ static ivas_error copyRendererConfigStruct( /*---------------------------------------------------------------------* * IVAS_DEC_GetRenderConfig( ) * - * + * Return renderer configuration parameters handle *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_GetRenderConfig( @@ -3281,12 +3253,12 @@ ivas_error IVAS_DEC_GetRenderConfig( /*---------------------------------------------------------------------* * IVAS_DEC_GetDefaultRenderConfig( ) * - * + * Return default renderer configuration parameters *---------------------------------------------------------------------*/ /*! r: error code*/ ivas_error IVAS_DEC_GetDefaultRenderConfig( - IVAS_RENDER_CONFIG_HANDLE hRCout /* o : Render config handle */ + IVAS_RENDER_CONFIG_HANDLE hRCout /* o : Render config handle */ ) { RENDER_CONFIG_DATA RCin; @@ -3305,7 +3277,7 @@ ivas_error IVAS_DEC_GetDefaultRenderConfig( /*---------------------------------------------------------------------* * IVAS_DEC_FeedRenderConfig( ) * - * + * Set renderer configuration (acoustic environment) parameters *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_FeedRenderConfig( @@ -3314,6 +3286,7 @@ ivas_error IVAS_DEC_FeedRenderConfig( ) { RENDER_CONFIG_HANDLE hRenderConfig; + Decoder_Struct *st_ivas; ivas_error error; if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hRenderConfig == NULL ) @@ -3322,6 +3295,8 @@ ivas_error IVAS_DEC_FeedRenderConfig( } hRenderConfig = hIvasDec->st_ivas->hRenderConfig; + st_ivas = hIvasDec->st_ivas; + #ifdef DEBUGGING hRenderConfig->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_NONE; if ( renderConfig.renderer_type_override == IVAS_RENDER_TYPE_OVERRIDE_FASTCONV ) @@ -3355,54 +3330,42 @@ ivas_error IVAS_DEC_FeedRenderConfig( /* Re-initialize reverb instance if already available */ /* TD renderer Jot reverberator */ - if ( hIvasDec->st_ivas->hReverb != NULL ) + if ( st_ivas->hReverb != NULL ) { - if ( ( error = ivas_reverb_open( &hIvasDec->st_ivas->hReverb, hIvasDec->st_ivas->hHrtfStatistics, hRenderConfig, hIvasDec->st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_reverb_open( &st_ivas->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) { return error; } } /* CREND Jot reverberator */ - if ( hIvasDec->st_ivas->hCrendWrapper != NULL && hIvasDec->st_ivas->hCrendWrapper->hCrend[0] != NULL && hIvasDec->st_ivas->hCrendWrapper->hCrend[0]->hReverb != NULL ) + if ( st_ivas->hCrendWrapper != NULL && st_ivas->hCrendWrapper->hCrend[0] != NULL && st_ivas->hCrendWrapper->hCrend[0]->hReverb != NULL ) { - if ( ( error = ivas_reverb_open( &hIvasDec->st_ivas->hCrendWrapper->hCrend[0]->hReverb, hIvasDec->st_ivas->hHrtfStatistics, hRenderConfig, hIvasDec->st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_reverb_open( &st_ivas->hCrendWrapper->hCrend[0]->hReverb, st_ivas->hHrtfStatistics, hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) { return error; } } - /* FB reverberator */ - if ( hIvasDec->st_ivas->hDiracDecBin[0] != NULL && hIvasDec->st_ivas->hDiracDecBin[0]->hReverb != NULL ) + /* Parametric renderer reverberator */ + if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->hReverb != NULL ) { - ivas_binaural_reverb_close( &( hIvasDec->st_ivas->hDiracDecBin[0]->hReverb ) ); - if ( ( error = ivas_binaural_reverb_init( &( hIvasDec->st_ivas->hDiracDecBin[0]->hReverb ), - hIvasDec->st_ivas->hHrtfStatistics, - hIvasDec->st_ivas->hSpatParamRendCom->num_freq_bands, - CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, - &( hRenderConfig->roomAcoustics ), - hIvasDec->st_ivas->hDecoderConfig->output_Fs, - NULL, - NULL, - NULL ) ) != IVAS_ERR_OK ) + ivas_binaural_reverb_close( &( st_ivas->hDiracDecBin[0]->hReverb ) ); + + if ( ( error = ivas_binaural_reverb_init( &( st_ivas->hDiracDecBin[0]->hReverb ), st_ivas->hHrtfStatistics, st_ivas->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, + &( hRenderConfig->roomAcoustics ), st_ivas->hDecoderConfig->output_Fs, NULL, NULL, NULL ) ) != IVAS_ERR_OK ) { return error; } } - /* Fastconv CLDFB reverberator */ - if ( hIvasDec->st_ivas->hBinRenderer != NULL && hIvasDec->st_ivas->hBinRenderer->hReverb != NULL ) + /* FastConv renderer reverberator */ + if ( st_ivas->hBinRenderer != NULL && st_ivas->hBinRenderer->hReverb != NULL ) { - ivas_binaural_reverb_close( &( hIvasDec->st_ivas->hBinRenderer->hReverb ) ); - if ( ( error = ivas_binaural_reverb_init( &( hIvasDec->st_ivas->hBinRenderer->hReverb ), - hIvasDec->st_ivas->hHrtfStatistics, - hIvasDec->st_ivas->hBinRenderer->conv_band, - hIvasDec->st_ivas->hBinRenderer->timeSlots, - &( hRenderConfig->roomAcoustics ), - hIvasDec->st_ivas->hDecoderConfig->output_Fs, - NULL, - NULL, - NULL ) ) != IVAS_ERR_OK ) + ivas_binaural_reverb_close( &( st_ivas->hBinRenderer->hReverb ) ); + + if ( ( error = ivas_binaural_reverb_init( &( st_ivas->hBinRenderer->hReverb ), st_ivas->hHrtfStatistics, st_ivas->hBinRenderer->conv_band, st_ivas->hBinRenderer->timeSlots, + &( hRenderConfig->roomAcoustics ), st_ivas->hDecoderConfig->output_Fs, NULL, NULL, NULL ) ) != IVAS_ERR_OK ) { return error; } @@ -3419,9 +3382,9 @@ ivas_error IVAS_DEC_FeedRenderConfig( hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; } - if ( is_split_rendering_enabled( hIvasDec->st_ivas->hDecoderConfig, hRenderConfig ) ) + if ( is_split_rendering_enabled( st_ivas->hDecoderConfig, hRenderConfig ) ) { - if ( ( error = isar_split_rend_validate_config( &hRenderConfig->split_rend_config, ( hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + if ( ( error = isar_split_rend_validate_config( &hRenderConfig->split_rend_config, ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) { return error; } @@ -3434,7 +3397,7 @@ ivas_error IVAS_DEC_FeedRenderConfig( /*---------------------------------------------------------------------* * IVAS_DEC_GetDelay( ) * - * + * Return IVAS decoder delay in nanoseconds *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_GetDelay( @@ -3459,7 +3422,9 @@ ivas_error IVAS_DEC_GetDelay( st_ivas = hIvasDec->st_ivas; hDecoderConfig = st_ivas->hDecoderConfig; + nSamples[1] = NS2SA( hDecoderConfig->output_Fs, get_delay( DEC, hDecoderConfig->output_Fs, st_ivas->ivas_format, st_ivas->cldfbSynDec[0], hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ); + nSamples[2] = (int16_t) roundf( (float) st_ivas->binaural_latency_ns * hDecoderConfig->output_Fs / 1000000000.f ); nSamples[0] = nSamples[1] + nSamples[2]; @@ -3478,7 +3443,7 @@ ivas_error IVAS_DEC_GetDelay( /*---------------------------------------------------------------------* * IVAS_DEC_HasDecodedFirstGoodFrame( ) * - * + * Return flag indicating if the decoder has decoded a good frame *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_HasDecodedFirstGoodFrame( @@ -3523,12 +3488,18 @@ static bool isSidFrame( } +/*---------------------------------------------------------------------* + * bsCompactToSerial( ) + * + * Bitstream conversion to Byte format + *---------------------------------------------------------------------*/ + static void bsCompactToSerial( const uint8_t *compact, uint16_t *serial, const uint16_t num_bits ) { - /* Bitstream conversion is not counted towards complexity and memory usage */ +/* Bitstream conversion is not counted towards complexity and memory usage */ #define WMC_TOOL_SKIP uint32_t i; uint8_t byte = 0; @@ -3646,6 +3617,7 @@ ivas_error IVAS_DEC_VoIP_FeedFrame( return IVAS_ERR_OK; } + /*---------------------------------------------------------------------* * IVAS_DEC_VoIP_SetScale( ) * @@ -3663,7 +3635,7 @@ ivas_error IVAS_DEC_VoIP_SetScale( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm == false ) + if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm == 0 ) { return IVAS_ERR_TSM_NOT_ENABLED; } @@ -3724,6 +3696,7 @@ ivas_error IVAS_DEC_EnableTsm( * Negative values would yield cross phased pasting * When not setting the minimum quality with this function the default * value used is 1.0f + * *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_TSM_SetQuality( @@ -3783,10 +3756,10 @@ ivas_error IVAS_DEC_VoIP_GetSamples JbmTraceFileWriterFn jbmWriterFn, void *jbmWriter, #endif - bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */ - uint16_t *nSamplesRendered, /* o : number of samples rendered */ - bool *parametersAvailableForEditing, - const uint32_t systemTimestamp_ms /* i : current system timestamp */ + bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */ + uint16_t *nSamplesRendered, /* o : number of samples rendered */ + bool *parametersAvailableForEditing, /* o : indicates whether objects editing is available */ + const uint32_t systemTimestamp_ms /* i : current system timestamp */ ) { Decoder_Struct *st_ivas; @@ -3852,7 +3825,6 @@ ivas_error IVAS_DEC_VoIP_GetSamples 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 ) @@ -3868,7 +3840,7 @@ ivas_error IVAS_DEC_VoIP_GetSamples dbgwrite( &maxScaling, sizeof( uint32_t ), 1, 1, "./res/JBM_maxScale.dat" ); #endif - /* avoid time scaling multiple times in one sound card slot */ + /* avoid time scaling multiple times within one 20ms frame*/ if ( scale != 100U ) { if ( hIvasDec->timeScalingDone ) @@ -3961,7 +3933,7 @@ ivas_error IVAS_DEC_VoIP_GetSamples /* codec mode to use not known yet - simply output silence */ /* directly set output zero */ int16_t nSamplesToZero = min( nSamplesPerChannel, hIvasDec->nSamplesAvailableNext ); - set_pcm_buffer_to_zero( pcm_buffer_offset( pcmBuf, pcmType, *nSamplesRendered * nOutChannels ), pcmType, nSamplesToZero * nOutChannels ); + set_pcm_buffer_to_zero( pcm_buffer_offset( pcmBuf, pcmType, ( *nSamplesRendered ) * nOutChannels ), pcmType, nSamplesToZero * nOutChannels ); *nSamplesRendered += nSamplesToZero; hIvasDec->nSamplesAvailableNext -= nSamplesToZero; update_voip_rendered20ms( hIvasDec, nSamplesToZero ); @@ -3979,11 +3951,12 @@ ivas_error IVAS_DEC_VoIP_GetSamples #ifdef FIX_1119_SPLIT_RENDERING_VOIP if ( ( error = IVAS_DEC_GetSamplesDecoder( hIvasDec, splitRendBits ) ) != IVAS_ERR_OK ) #else - if ( ( error = IVAS_DEC_GetSamplesDecoder( hIvasDec, 0, 0 ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_GetSamplesDecoder( hIvasDec, 0, NULL ) ) != IVAS_ERR_OK ) #endif { return error; } + *bitstreamReadDone = false; *parametersAvailableForEditing = true; return IVAS_ERR_OK; @@ -3995,7 +3968,6 @@ ivas_error IVAS_DEC_VoIP_GetSamples /* check if we still need to prepare the renderer */ if ( hIvasDec->hasBeenPreparedRendering == false ) { - if ( ( error = IVAS_DEC_PrepareRenderer( hIvasDec ) ) != IVAS_ERR_OK ) { return error; @@ -4164,7 +4136,7 @@ ivas_error IVAS_DEC_VoIP_GetSplitBinauralBitstream( /*---------------------------------------------------------------------* * update_voip_rendered20ms( ) * - * Function to flush remaining audio in VoIP + * Update the number of samples that have been rendered since the last 20ms render border *---------------------------------------------------------------------*/ static void update_voip_rendered20ms( @@ -4190,21 +4162,20 @@ static void update_voip_rendered20ms( /*---------------------------------------------------------------------* * IVAS_DEC_VoIP_Flush( ) * - * Function to flush remaining audio in VoIP + * Function to flush remaining audio samples in VoIP *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_Flush( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const int16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ - const IVAS_DEC_PCM_TYPE pcmType, - void *pcmBuf, - int16_t *nSamplesFlushed /* o : number of samples flushed */ + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ + int16_t *nSamplesFlushed /* o : number of samples flushed */ ) { ivas_error error; uint16_t nSamplesToRender; uint16_t nSamplesFlushedLocal; - nSamplesFlushedLocal = 0; // temp. hack if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { @@ -4245,8 +4216,9 @@ ivas_error IVAS_DEC_Flush( *---------------------------------------------------------------------*/ bool IVAS_DEC_VoIP_IsEmpty( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const int16_t nSamplesAsked ) + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t nSamplesAsked /* i : number of output samples asked */ +) { if ( hIvasDec == NULL || hIvasDec->hVoIP == NULL ) { @@ -4281,13 +4253,13 @@ ivas_error IVAS_DEC_VoIP_Get_CA_offset( /*---------------------------------------------------------------------* - * IVAS_DEC_Close_VoIP( ) - * + * ivas_destroy_handle_VoIP( ) * + * Deallocate VoIP handle *---------------------------------------------------------------------*/ static void ivas_destroy_handle_VoIP( - IVAS_DEC_VOIP *hVoIP /* i/o: IVAS decoder handle */ + IVAS_DEC_VOIP *hVoIP /* i/o: VoIP decoder handle */ ) { JB4_Destroy( &hVoIP->hJBM ); @@ -4356,6 +4328,7 @@ static void store_JbmData( ivas_error IVAS_DEC_GetJbmData( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ IVAS_JBM_TRACE_DATA *JbmTraceData /* o : JBM Trace data */ + ) { if ( hIvasDec == NULL || hIvasDec->hVoIP == NULL || JbmTraceData == NULL ) @@ -4605,6 +4578,11 @@ ivas_error IVAS_DEC_PrintConfig( #ifdef DEBUGGING +/*---------------------------------------------------------------------* + * IVAS_DEC_PrintConfigWithBitstream( ) + * + * + *---------------------------------------------------------------------*/ #define WMC_TOOL_SKIP void IVAS_DEC_PrintConfigWithBitstream( IVAS_DEC_HANDLE hIvasDec, @@ -4630,6 +4608,13 @@ void IVAS_DEC_PrintConfigWithBitstream( return; } + +/*---------------------------------------------------------------------* + * IVAS_DEC_PrintConfigWithVoipBitstream( ) + * + * + *---------------------------------------------------------------------*/ + void IVAS_DEC_PrintConfigWithVoipBitstream( IVAS_DEC_HANDLE hIvasDec, const bool quietModeEnabled, @@ -4907,6 +4892,7 @@ static ivas_error input_format_API_to_internal( return IVAS_ERR_OK; } + /*---------------------------------------------------------------------* * apa_setup() * @@ -4918,9 +4904,6 @@ static ivas_error apa_setup( const bool isInitialized_voip, const uint16_t nTransportChannels ) { -#ifndef JBM_MEMORY_OPT - int16_t apa_buffer_size; -#endif uint16_t l_ts; l_ts = (uint16_t) hIvasDec->st_ivas->hTcBuffer->n_samples_granularity; @@ -4928,16 +4911,10 @@ static ivas_error apa_setup( if ( !isInitialized_voip ) { DECODER_CONFIG_HANDLE hDecoderConfig; - uint16_t wss, css; float startQuality; startQuality = hIvasDec->tsm_quality; -#ifndef JBM_MEMORY_OPT - apa_buffer_size = APA_BUF_PER_CHANNEL; - /* get current renderer type*/ - -#endif hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; if ( hDecoderConfig->output_Fs == 8000 ) @@ -4981,14 +4958,6 @@ static ivas_error apa_setup( return IVAS_ERR_INIT_ERROR; } } -#ifndef JBM_MEMORY_OPT - if ( ( hIvasDec->apaExecBuffer = malloc( sizeof( float ) * apa_buffer_size * nTransportChannels ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); - } - - set_zero( hIvasDec->apaExecBuffer, apa_buffer_size * nTransportChannels ); -#endif } else { @@ -4996,15 +4965,6 @@ static ivas_error apa_setup( { return IVAS_ERR_INIT_ERROR; } -#ifndef JBM_MEMORY_OPT - apa_buffer_size = APA_BUF_PER_CHANNEL; - free( hIvasDec->apaExecBuffer ); - if ( ( hIvasDec->apaExecBuffer = malloc( sizeof( float ) * apa_buffer_size * nTransportChannels ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate VoIP handle" ); - } - set_zero( hIvasDec->apaExecBuffer, apa_buffer_size * nTransportChannels ); -#endif } hIvasDec->nTransportChannelsOld = nTransportChannels; @@ -5019,14 +4979,14 @@ static ivas_error apa_setup( * *---------------------------------------------------------------------*/ -ivas_error -IVAS_DEC_GetSplitRendBitstreamHeader( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - ISAR_SPLIT_REND_CODEC *pCodec, /* o: pointer to codec setting */ - ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o: pointer to pose correction mode */ - int16_t *pIsar_frame_size_ms, /* o: pointer to isar frame size setting */ - int16_t *pCodec_frame_size_ms, /* o: pointer to codec frame size setting */ - int16_t *pLc3plusHighRes ) +ivas_error IVAS_DEC_GetSplitRendBitstreamHeader( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + ISAR_SPLIT_REND_CODEC *pCodec, /* o : pointer to codec setting */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o : pointer to pose correction mode */ + int16_t *pIsar_frame_size_ms, /* o : pointer to ISAR frame size setting */ + int16_t *pCodec_frame_size_ms, /* o : pointer to codec frame size setting */ + int16_t *pLc3plusHighRes /* o : pointer to LC3plus High-Res setting */ +) { if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { @@ -5195,7 +5155,7 @@ PCM_RESOLUTION pcm_type_API_to_internal( /*-------------------------------------------------------------------* * ivas_create_handle_isar() * - * Initialize IVAS decoder split rend handle + * Initialize IVAS decoder split-rendering handle *-------------------------------------------------------------------*/ static ivas_error ivas_create_handle_isar( @@ -5261,10 +5221,8 @@ static void ivas_destroy_handle_isar( } } #else -#ifdef TMP_FIX_SPLIT_REND free( ( *hSplitBinRend )->hMultiBinCldfbData ); ( *hSplitBinRend )->hMultiBinCldfbData = NULL; -#endif #endif ISAR_PRE_REND_close( &( *hSplitBinRend )->splitrend, NULL ); @@ -5273,12 +5231,10 @@ static void ivas_destroy_handle_isar( { free( ( *hSplitBinRend )->hCldfbDataOut ); ( *hSplitBinRend )->hCldfbDataOut = NULL; -#ifdef FIX_1319_STACK_SBA_DECODER - - free( ( *hSplitBinRend ) ); - ( *hSplitBinRend ) = NULL; -#endif } + + free( ( *hSplitBinRend ) ); + ( *hSplitBinRend ) = NULL; } return; @@ -5291,8 +5247,9 @@ static void ivas_destroy_handle_isar( * *---------------------------------------------------------------------*/ -int16_t IVAS_DEC_is_split_rendering_enabled( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ +/*! r: decoder error code */ +ivas_error IVAS_DEC_is_split_rendering_enabled( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ int16_t *isSplitRend /* o : flag to indicate if split rendering is enabled */ ) { @@ -5304,11 +5261,13 @@ int16_t IVAS_DEC_is_split_rendering_enabled( } st_ivas = hIvasDec->st_ivas; + *isSplitRend = is_split_rendering_enabled( st_ivas->hDecoderConfig, st_ivas->hRenderConfig ); return IVAS_ERR_OK; } + /*-------------------------------------------------------------------* * ivas_dec_reconfig_split_rend() * @@ -5468,7 +5427,7 @@ static int16_t ivas_dec_split_rend_cldfb_in( /*-------------------------------------------------------------------* * ivas_dec_init_split_rend() * - * IVAS decoder split rend init + * IVAS decoder split rendering initialization *-------------------------------------------------------------------*/ static ivas_error ivas_dec_init_split_rend( @@ -5522,13 +5481,11 @@ static ivas_error ivas_dec_init_split_rend( } } #else -#ifdef TMP_FIX_SPLIT_REND /* note: this is intra-frame heap memory */ if ( ( st_ivas->hSplitBinRend->hMultiBinCldfbData = (ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for split rendering structure" ); } -#endif ISAR_PRE_REND_GetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, ( st_ivas->hHeadTrackData != NULL ) ? st_ivas->hHeadTrackData->sr_pose_pred_axis : DEFAULT_AXIS ); #endif @@ -5557,11 +5514,12 @@ static ivas_error ivas_dec_init_split_rend( /*---------------------------------------------------------------------* * IVAS_DEC_is_split_rendering_coded_out() * - * + * Return flag to indicate if split rendering is enabled *---------------------------------------------------------------------*/ -int16_t IVAS_DEC_is_split_rendering_coded_out( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ +/*! r: decoder error code */ +ivas_error IVAS_DEC_is_split_rendering_coded_out( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ int16_t *isSplitCoded /* o : flag to indicate if split rendering is enabled */ ) { @@ -5584,3 +5542,132 @@ int16_t IVAS_DEC_is_split_rendering_coded_out( return IVAS_ERR_OK; } + +/*---------------------------------------------------------------------* + * IVAS_DEC_feedSinglePIorientation( ) + * + * Feed a single orientation PI data to external orientation handle. + *---------------------------------------------------------------------*/ + +static ivas_error IVAS_DEC_feedSinglePIorientation( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + bool isOrientationSaved, /* i : flag to indicate if an orientation for this PI type was previously saved */ + IVAS_QUATERNION *savedOrientation /* i : previously saved orientation for this PI type */ +) +{ + int16_t i; + ivas_error error = IVAS_ERR_OK; + IVAS_QUATERNION savedInvOrientation; + + if ( isOrientationSaved ) + { + if ( !hIvasDec->st_ivas->hExtOrientationData ) + { + if ( ( error = ivas_external_orientation_open( &( hIvasDec->st_ivas->hExtOrientationData ), hIvasDec->st_ivas->hDecoderConfig->render_framesize ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + if ( !hIvasDec->st_ivas->hCombinedOrientationData ) + { + if ( ( error = ivas_combined_orientation_open( &( hIvasDec->st_ivas->hCombinedOrientationData ), hIvasDec->st_ivas->hDecoderConfig->output_Fs, hIvasDec->st_ivas->hDecoderConfig->render_framesize ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + QuaternionInverse( *savedOrientation, &savedInvOrientation ); + + /* use the new PI orientation or the previously saved orientation in processing */ + for ( i = 0; i < hIvasDec->st_ivas->hExtOrientationData->num_subframes; i++ ) + { + QuaternionProduct( hIvasDec->st_ivas->hExtOrientationData->Quaternions[i], savedInvOrientation, + &hIvasDec->st_ivas->hExtOrientationData->Quaternions[i] ); + hIvasDec->st_ivas->hExtOrientationData->enableExternalOrientation[i] = true; + } + hIvasDec->updateOrientation = true; + } + return error; +} + + +#ifdef RTP_S4_251135_CR26253_0016_REV1 +/*---------------------------------------------------------------------* + * IVAS_DEC_setDiegeticInput( ) + * + * Set isDiegeticInput flag for combined orientation handle based on PI data. + *---------------------------------------------------------------------*/ + +static void IVAS_DEC_setDiegeticInputPI( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const bool *diegeticPIValues /* i : diegetic values for the input stream */ +) +{ + if ( hIvasDec->st_ivas->hCombinedOrientationData != NULL ) + { + int8_t i; + for ( i = 0; i < ( 1 + IVAS_MAX_NUM_OBJECTS ); i++ ) + { + hIvasDec->st_ivas->hCombinedOrientationData->isDiegeticInputPI[i] = diegeticPIValues[i]; + } + hIvasDec->st_ivas->hCombinedOrientationData->isDiegeticInputPISet = true; + } +} +#endif + +#ifdef IVAS_RTPDUMP +ivas_error IVAS_RTP_FeedPiDataToDecoder( IVAS_DEC_HANDLE hIvasDec, PIDATA_TS *piData, uint32_t numPiData ) +{ + ivas_error error = IVAS_ERR_OK; + while ( numPiData-- ) + { + uint32_t piDataType = piData->data.noPiData.piDataType; + switch ( piDataType ) + { + case IVAS_PI_SCENE_ORIENTATION: + { + IVAS_QUATERNION *quat = &piData->data.scene.orientation; +#ifdef DEBUGGING + fprintf( stdout, "PI_SCENE_ORIENTATION : %f, %f, %f, %f\n", quat->w, quat->x, quat->y, quat->z ); +#endif + error = IVAS_DEC_feedSinglePIorientation( hIvasDec, true, quat ); + } + break; + + case IVAS_PI_DEVICE_ORIENTATION_COMPENSATED: + { + IVAS_QUATERNION *quat = &piData->data.deviceCompensated.orientation; +#ifdef DEBUGGING + fprintf( stdout, "PI_DEVICE_ORIENTATION : %f, %f, %f, %f\n", quat->w, quat->x, quat->y, quat->z ); +#endif + error = IVAS_DEC_feedSinglePIorientation( hIvasDec, true, quat ); + } + break; + +#ifdef RTP_S4_251135_CR26253_0016_REV1 + case IVAS_PI_DIEGETIC_TYPE: + { +#ifdef DEBUGGING + fprintf( stdout, "PI_DIEGETIC_TYPE : %d, %d, %d, %d, %d\n", piData->data.digeticIndicator.isDiegetic[0], piData->data.digeticIndicator.isDiegetic[1], piData->data.digeticIndicator.isDiegetic[2], piData->data.digeticIndicator.isDiegetic[3], piData->data.digeticIndicator.isDiegetic[4] ); +#endif + IVAS_DEC_setDiegeticInputPI( hIvasDec, piData->data.digeticIndicator.isDiegetic ); + } + break; +#endif + + default: + { + /* NOT HANDLED PI DATA - DO NOTHING */ + } + break; + } + if ( error != IVAS_ERR_OK ) + { + return error; + } + piData++; + } + return error; +} +#endif diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 22805c7a4226906076b150b9a7fd9f27fb1551ac..d0d2b501d847425d71c701665cda87ba15f71d36 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -71,6 +71,7 @@ typedef enum _IVAS_DEC_PCM_TYPE IVAS_DEC_PCM_INVALID } IVAS_DEC_PCM_TYPE; + /* bitstream formats that can be consumed */ typedef enum _IVAS_DEC_BS_FORMAT { @@ -108,22 +109,22 @@ ivas_error IVAS_DEC_Open( /*! r: error code */ ivas_error IVAS_DEC_Configure( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const uint32_t sampleRate, /* i : output sampling frequency */ - const IVAS_AUDIO_CONFIG outputConfig, /* i : output configuration */ - const IVAS_RENDER_FRAMESIZE renderFramesize, /* i : rendering frame size */ - const bool customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ - const bool hrtfReaderEnabled, /* i : enable HRTF binary file input */ - const bool enableHeadRotation, /* i : enable head rotation for binaural output */ - const bool enableExternalOrientation, /* i : enable external orientations */ - const IVAS_HEAD_ORIENT_TRK_T orientation_tracking, /* i : head orientation tracking type */ - const bool renderConfigEnabled, /* i : enable Renderer config. file for binaural output */ - const bool non_diegetic_pan_enabled, /* i : enabled diegetic panning */ - const float non_diegetic_pan_gain, /* i : non diegetic panning gain */ - const bool dpidEnabled, /* i : enable directivity pattern option */ - const uint16_t acousticEnvironmentId, /* i : Acoustic environment ID */ - const bool objEditEnabled, /* i : enable object editing */ - const bool delayCompensationEnabled /* i : enable delay compensation */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const uint32_t sampleRate, /* i : output sampling frequency */ + const IVAS_AUDIO_CONFIG outputConfig, /* i : audio configuration */ + const IVAS_RENDER_FRAMESIZE renderFramesize,/* i : rendering frame size */ + const bool customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ + const bool hrtfReaderEnabled, /* i : enable HRTF binary file input */ + const bool enableHeadRotation, /* i : enable head rotation for binaural output */ + const bool enableExternalOrientation, /* i : enable external orientations */ + const IVAS_HEAD_ORIENT_TRK_T orientation_tracking, /* i : head orientation tracking type */ + const bool renderConfigEnabled, /* i : enable Renderer config. file for binaural output */ + const bool non_diegetic_pan_enabled, /* i : enabled diegetic panning */ + const float non_diegetic_pan_gain, /* i : non diegetic panning gain */ + const bool dpidEnabled, /* i : enable directivity pattern option */ + const uint16_t acousticEnvironmentId, /* i : Acoustic environment ID */ + const bool objEditEnabled, /* i : enable object editing */ + const bool delayCompensationEnabled /* i : enable delay compensation */ ); void IVAS_DEC_Close( @@ -148,6 +149,7 @@ ivas_error IVAS_DEC_ReadFormat( IVAS_AUDIO_CONFIG *hrtf_set_audio_cfg /* o : HRTF set audio config. */ ); +/*! r: decoder error code */ ivas_error IVAS_DEC_GetSamplesDecoder( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ #ifndef FIX_1119_SPLIT_RENDERING_VOIP @@ -156,6 +158,20 @@ ivas_error IVAS_DEC_GetSamplesDecoder( ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ ); +ivas_error IVAS_DEC_GetEditableParameters( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_EDITABLE_PARAMETERS *hIvasEditableParameters /* o : object editing parameters handle */ +); + +ivas_error IVAS_DEC_SetEditableParameters( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_EDITABLE_PARAMETERS hIvasEditableParameters /* i : object editing parameters handle */ +); + +ivas_error IVAS_DEC_PrepareRenderer( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +); + /*! r: decoder error code */ ivas_error IVAS_DEC_GetSamplesRenderer( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ @@ -166,20 +182,6 @@ ivas_error IVAS_DEC_GetSamplesRenderer( bool *needNewFrame /* o : indication that the decoder needs a new frame */ ); -ivas_error IVAS_DEC_GetEditableParameters( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_EDITABLE_PARAMETERS *hIvasEditableParameters /* o : object editing parameters handle */ -); - -ivas_error IVAS_DEC_SetEditableParameters( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_EDITABLE_PARAMETERS hIvasEditableParameters /* i : object editing parameters handle */ -); - -ivas_error IVAS_DEC_PrepareRenderer( - IVAS_DEC_HANDLE hIvasDec -); - ivas_error IVAS_DEC_GetSplitBinauralBitstream( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ void *pcmBuf_out, /* o : output synthesis signal for BINAURAL_SPLIT_PCM */ @@ -190,12 +192,12 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( /*! r: decoder error code */ ivas_error IVAS_DEC_GetSplitRendBitstreamHeader( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - ISAR_SPLIT_REND_CODEC *pCodec, /* o : pointer to codec setting */ - ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o : pointer to pose correction mode */ - int16_t *pIsar_frame_size_ms, /* o : pointer to isar frame size setting */ - int16_t *pCodec_frame_size_ms, /* o : pointer to codec frame size setting */ - int16_t *pLc3plusHighRes /* o : pointer to LC3plus High-Res setting */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + ISAR_SPLIT_REND_CODEC *pCodec, /* o : pointer to codec setting */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o : pointer to pose correction mode */ + int16_t *pIsar_frame_size_ms, /* o : pointer to ISAR frame size setting */ + int16_t *pCodec_frame_size_ms, /* o : pointer to codec frame size setting */ + int16_t *pLc3plusHighRes /* o : pointer to LC3plus High-Res setting */ ); /*! r: decoder error code */ @@ -207,13 +209,15 @@ ivas_error IVAS_DEC_GetCldfbSamples( int16_t *nOutSamples /* o : number of samples per channel written to output buffer */ ); -int16_t IVAS_DEC_is_split_rendering_enabled( - IVAS_DEC_HANDLE hIvasDec, /* i : IVAS decoder handle */ +/*! r: decoder error code */ +ivas_error IVAS_DEC_is_split_rendering_enabled( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ int16_t *isSplitRend /* o : flag to indicate if split rendering is enabled */ ); -int16_t IVAS_DEC_is_split_rendering_coded_out( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ +/*! r: decoder error code */ +ivas_error IVAS_DEC_is_split_rendering_coded_out( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ int16_t *isSplitCoded /* o : flag to indicate if split rendering is enabled */ ); @@ -287,26 +291,26 @@ ivas_error IVAS_DEC_EnableTsm( IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ ); -#endif +/*! r: error code */ ivas_error IVAS_DEC_TSM_SetQuality( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const float quality /* i : target TSM quality */ + const float quality /* i : target TSM quality */ ); - +#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 */ - const IVAS_DEC_PCM_TYPE pcmType, - void *pcmBuf, + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ #ifdef SUPPORT_JBM_TRACEFILE JbmTraceFileWriterFn jbmWriterFn, - void* jbmWriter, + void *jbmWriter, #endif - bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */ - uint16_t *nSamplesRendered, /* o : number of samples rendered */ - bool *parametersAvailableForEditing, - const uint32_t systemTimestamp_ms /* i : current system timestamp */ + bool *bitstreamReadDone, /* o : flag indicating that bitstream was read */ + uint16_t *nSamplesRendered, /* o : number of samples rendered */ + bool *parametersAvailableForEditing, /* o : indicates whether objects editing is available */ + const uint32_t systemTimestamp_ms /* i : current system timestamp */ ); #ifdef FIX_1119_SPLIT_RENDERING_VOIP @@ -330,8 +334,8 @@ ivas_error IVAS_DEC_VoIP_GetSplitBinauralBitstream( ivas_error IVAS_DEC_Flush( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const int16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ - const IVAS_DEC_PCM_TYPE pcmType, - void *pcmBuf, + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ int16_t *nSamplesFlushed /* o : number of samples flushed */ ); @@ -350,33 +354,33 @@ ivas_error IVAS_DEC_EnableSplitRendering( ); ivas_error IVAS_DEC_SetRenderFramesize( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const IVAS_RENDER_FRAMESIZE render_framesize /* i : render framesize */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_RENDER_FRAMESIZE render_framesize /* i : render framesize */ ); ivas_error IVAS_DEC_GetRenderFramesize( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_RENDER_FRAMESIZE *render_framesize /* o : render framesize */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_RENDER_FRAMESIZE *render_framesize /* o : render framesize */ ); ivas_error IVAS_DEC_GetRenderFramesizeSamples( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t *render_framesize /* o : render framesize in samples */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *render_framesize /* o : render framesize in samples */ ); ivas_error IVAS_DEC_GetReferencesUpdateFrequency( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t *update_frequency /* o : update frequency */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *update_frequency /* o : update frequency */ ); ivas_error IVAS_DEC_GetNumOrientationSubframes( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t *num_subframes /* o : render framesize */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *num_subframes /* o : render framesize */ ); ivas_error IVAS_DEC_GetRenderFramesizeMs( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - uint32_t *render_framesize /* o : render framesize in samples */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + uint32_t *render_framesize /* o : render framesize in samples */ ); #ifdef DEBUGGING @@ -437,23 +441,23 @@ ivas_error IVAS_DEC_FeedCustomLsData( /*! r: error code */ ivas_error IVAS_DEC_GetHrtfTDrendHandle( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_DEC_HRTF_HANDLE **hHrtfTD /* o : HRTF handle */ + IVAS_DEC_HRTF_TD_HANDLE **hHrtfTD /* o : HRTF handle */ ); /*! r: error code */ ivas_error IVAS_DEC_GetHrtfCRendHandle( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ -IVAS_DEC_HRTF_CREND_HANDLE **hSetOfHRTF /* o : Set of HRTF handle */ + IVAS_DEC_HRTF_CREND_HANDLE **hHrtfCrend /* o : Crend HRTF handle */ ); ivas_error IVAS_DEC_GetHrtfFastConvHandle( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_DEC_HRTF_FASTCONV_HANDLE **hHrtfFastConv /* o : FASTCONV HRTF handle */ + IVAS_DEC_HRTF_FASTCONV_HANDLE **hHrtfFastConv/* o : FASTCONV HRTF handle */ ); ivas_error IVAS_DEC_GetHrtfParamBinHandle( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_DEC_HRTF_PARAMBIN_HANDLE **hHrtfParambin /* o : Parametric binauralizer HRTF handle */ + IVAS_DEC_HRTF_PARAMBIN_HANDLE **hHrtfParambin/* o : Parametric binauralizer HRTF handle */ ); ivas_error IVAS_DEC_GetHrtfStatisticsHandle( @@ -553,6 +557,11 @@ void IVAS_DEC_PrintDisclaimer( void ); +#ifdef IVAS_RTPDUMP +#include "ivas_rtp_pi_data.h" +ivas_error IVAS_RTP_FeedPiDataToDecoder( IVAS_DEC_HANDLE hIvasDec, PIDATA_TS *piData, uint32_t numPiData ); +#endif + /* clang-format on */ #endif diff --git a/lib_dec/pitch_extr.c b/lib_dec/pitch_extr.c index 24d8d081f8e49f23738ece5bbb55b66aed92c49d..83a71c91488fd6d40786a2d0fbc9c99f7ea4c2de 100644 --- a/lib_dec/pitch_extr.c +++ b/lib_dec/pitch_extr.c @@ -163,7 +163,9 @@ void pitch_pred_linear_fit( { Word32 t1, t2, t3, t4, t5, t6, t7; Word16 e1, e2, e3, e4, e5, e6, e7; +#ifdef BASOP_NOGLOB Flag Overflow; +#endif t1 = L_mult0( pg_fx[4], pg_fx[3] ); /*Q24*/ /* t1 = pg[4]*pg[3] */ e1 = 7; t2 = L_add( L_deposit_l( pg_fx[3] ), L_shl( L_deposit_l( pg_fx[4] ), 2 ) ); /*Q12*/ @@ -185,8 +187,12 @@ void pitch_pred_linear_fit( t6 = BASOP_Util_Add_Mant32Exp( t3, e3, t4, e4, &e6 ); t7 = BASOP_Util_Add_Mant32Exp( t5, e5, t6, e6, &e7 ); /*Q31,e7*/ sum0_q = norm_l( t7 ); +#ifdef BASOP_NOGLOB sum0 = round_fx_o( L_shl( t7, sum0_q ), &Overflow ); /*Q15,e7-sum0_q*/ - sum0_q = add( 15, sub( sum0_q, e7 ) ); /* sum0 is now Qsum0_q*/ +#else + sum0 = round_fx( L_shl( t7, sum0_q ) ); /*Q15,e7-sum0_q*/ +#endif + sum0_q = add( 15, sub( sum0_q, e7 ) ); /* sum0 is now Qsum0_q*/ } pit = 0; diff --git a/lib_dec/pvq_core_dec.c b/lib_dec/pvq_core_dec.c index b8904d534c7d93ee9bc1ed874c59b3b88d1948e1..dcb22cb630eb973e51fb63c141bed1480093938d 100644 --- a/lib_dec/pvq_core_dec.c +++ b/lib_dec/pvq_core_dec.c @@ -98,6 +98,7 @@ static void pvq_decode_band( } set_s( g_part_s, -32768, Np ); + if ( Np > 1 ) { decode_energies( st, hPVQ, Np, dim_part, bits_part, g_part_s, band_bits_tot, bits_left, sfmsize, strict_bits ); @@ -114,11 +115,16 @@ static void pvq_decode_band( { g_part[j] = -( (float) g_part_s[j] ) / 32768; /* note: here g_part needs to be become exactly 1.0(float) thus in BASOP Word16 g_part_s is in the negative Q15 domain */ + + /* aligned to BASOP to avoid USAN undefined negation warning for -(-32768) */ g_part_s[j] = negate( g_part_s[j] ); } + srt_vec_ind( g_part_s, sg_part, idx_sort, Np ); + + for ( j = 0; j < Np; j++ ) { js = idx_sort[Np - 1 - j]; @@ -396,7 +402,9 @@ static void densitySymbolIndexDecode( int16_t r_dim = opp_sz; int16_t l_dim = near_sz; int16_t alpha; +#ifdef BASOP_NOGLOB Flag Overflow; +#endif /* BASOP_NOGLOB */ if ( ( 0xFFFE & density ) == 0 ) { /* odd density exit */ @@ -405,12 +413,17 @@ static void densitySymbolIndexDecode( } #define WMC_TOOL_SKIP angle = atan2_fx( SQRT_DIM_fx[r_dim], SQRT_DIM_fx[l_dim] ); +#ifndef BASOP_NOGLOB + angle = shl( angle, 1 ); +#else /* BASOP_NOGLOB */ angle = shl_o( angle, 1, &Overflow ); +#endif /* BASOP_NOGLOB */ angle = mult_r( angle, 20861 ); c = mult_r( res, angle ); #undef WMC_TOOL_SKIP res_c = res - c; + if ( c == 0 ) { tot = res * ( res + 1 ) + 1; @@ -434,6 +447,7 @@ static void densitySymbolIndexDecode( if ( dec_freq < tot - ( res + 1 ) - ( res - ( c + 1 ) ) * ( res - c ) * c + c + 1 ) { alpha = ( res_c - 1 + (int16_t) floor_sqrt_exact( (uint32_t) ( res_c * ( res_c + 4 * dec_freq - 2 ) + 1 ) ) ) / ( 2 * res_c ); + sym_freq = 2 * alpha * res_c + 1; cum_freq = alpha * ( ( alpha - 1 ) * res_c + 1 ); } diff --git a/lib_dec/swb_bwe_dec.c b/lib_dec/swb_bwe_dec.c index e26072db4a208ab088995417056c1f3374291a60..05a0ac2249e90e4c32cad4212c97c1e6326cf038 100644 --- a/lib_dec/swb_bwe_dec.c +++ b/lib_dec/swb_bwe_dec.c @@ -499,7 +499,9 @@ int16_t swb_bwe_gain_deq( { Word16 tmp, frac, exp; Word32 L_tmp; +#ifdef BASOP_NOGLOB Flag Overflow; +#endif tmp = add( (int16_t) ( SWB_fenv[n_band] * 256 ), (int16_t) ( Mean_env[n_band] * 256 ) ); /*Q8 */ L_tmp = L_mult( tmp, 21771 ); /* 0.166096 in Q17 -> Q26 */ @@ -510,8 +512,12 @@ int16_t swb_bwe_gain_deq( /* output of Pow2() will be: */ /* 16384 < Pow2() <= 32767 */ exp = sub( exp, 13 ); +#ifdef BASOP_NOGLOB tmp = shl_o( tmp, add( exp, 1 ), &Overflow ); /*Q1 */ - SWB_fenv[n_band] = (float) tmp * 0.5f; /*Q1 */ +#else + tmp = shl( tmp, add( exp, 1 ) ); /*Q1 */ +#endif + SWB_fenv[n_band] = (float) tmp * 0.5f; /*Q1 */ } if ( hqswb_clas == HQ_GEN_FB ) diff --git a/lib_dec/swb_tbe_dec.c b/lib_dec/swb_tbe_dec.c index 0442f9eb7758e0287c1de4930ee8c40cf88d5483..8f88f5150ebef113dc4cf2447652be9f52f9fec1 100644 --- a/lib_dec/swb_tbe_dec.c +++ b/lib_dec/swb_tbe_dec.c @@ -348,6 +348,7 @@ void wb_tbe_dec( { scale = (float) sqrt( curr_pow / prev_pow ); } + for ( i = 0; i < L_SHB_LAHEAD / 4 - 1; i++ ) { shaped_wb_excitation[i] *= scale; @@ -1067,6 +1068,7 @@ void swb_tbe_dec( } mvr2r( shaped_shb_excitationTemp, &shaped_shb_excitation[L_SHB_LAHEAD], L_FRAME16k ); + prev_pow = sum2_f( shaped_shb_excitation, L_SHB_LAHEAD + 10 ); curr_pow = sum2_f( shaped_shb_excitation + L_SHB_LAHEAD + 10, L_SHB_LAHEAD + 10 ); diff --git a/lib_dec/syn_outp.c b/lib_dec/syn_outp.c index 0720d38c978e2d8915a8f68ed46272b91a99ef0a..43b7a755882f64343e1633dc10581f26d41b58b5 100644 --- a/lib_dec/syn_outp.c +++ b/lib_dec/syn_outp.c @@ -45,6 +45,9 @@ #include "wmc_auto.h" +/* Note: syn_output() is replaced by ivas_syn_output() in IVAS */ + + /*-------------------------------------------------------------------* * AGC_dec() * diff --git a/lib_dec/tonalMDCTconcealment.c b/lib_dec/tonalMDCTconcealment.c index bad470db9d286cf18c63da9c36ab594edae4f72a..a2cf111e8ff5de93efdc93209d134699bc882d06 100644 --- a/lib_dec/tonalMDCTconcealment.c +++ b/lib_dec/tonalMDCTconcealment.c @@ -545,7 +545,7 @@ void TonalMDCTConceal_InsertNoise( for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ ) { - mdctSpectrum[l] = 0; + mdctSpectrum[l] = 0.0f; } } /* actual fadeout is done in this case */ diff --git a/lib_dec/waveadjust_fec_dec.c b/lib_dec/waveadjust_fec_dec.c index 1edae90e4d3fe9fb109210b068e61d7bf8a41e3e..4b79824c10b7879c9729c7b9199ab99217972898 100644 --- a/lib_dec/waveadjust_fec_dec.c +++ b/lib_dec/waveadjust_fec_dec.c @@ -742,7 +742,6 @@ void concealment_decode( /* sign randomization */ for ( i = 0; i < hPlcInfo->L_frameTCX; i++ ) { - int16_t rnd; rnd = own_random( seed ); sign = ( rnd >= 0 ) - ( rnd < 0 ); diff --git a/lib_enc/acelp_core_enc.c b/lib_enc/acelp_core_enc.c index dfa6766d4dd15257bf09f5f1f148d252f98723b2..ccc96242b19b326a4b65592e24c62e04118e7cb0 100644 --- a/lib_enc/acelp_core_enc.c +++ b/lib_enc/acelp_core_enc.c @@ -381,6 +381,7 @@ ivas_error acelp_core_enc( /*-----------------------------------------------------------------* * After inactive period, use the most up-to-date ISPs *-----------------------------------------------------------------*/ + if ( st->hDtxEnc != NULL && ( st->last_core_brate == FRAME_NO_DATA || st->last_core_brate == SID_2k40 ) ) { mvr2r( st->hDtxEnc->lspCNG, st->lsp_old, M ); @@ -694,12 +695,7 @@ ivas_error acelp_core_enc( if ( !st->Opt_SC_VBR && ( st->idchan == 0 || st->element_mode != IVAS_CPE_TD || ( st->idchan == 1 && st->element_mode == IVAS_CPE_TD && st->tdm_LRTD_flag ) ) ) { /* Apply a non linearity to the SHB excitation */ - non_linearity( bwe_exc, bwe_exc_extended, st->hBWE_TD->old_bwe_exc_extended, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale, st->coder_type, voice_factors, st->L_frame -#ifdef NONBE_1328_FIX_NON_LINEARITY - , - st->element_mode -#endif - ); + non_linearity( bwe_exc, bwe_exc_extended, st->hBWE_TD->old_bwe_exc_extended, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale, st->coder_type, voice_factors, st->L_frame, st->element_mode ); } if ( st->core_brate == SID_2k40 || st->core_brate == FRAME_NO_DATA ) diff --git a/lib_enc/acelp_core_switch_enc.c b/lib_enc/acelp_core_switch_enc.c index 07717c60903424a49442a9195df7c5d325d3f6bd..f5742b373bd205f9de3b502ada620185da608a99 100644 --- a/lib_enc/acelp_core_switch_enc.c +++ b/lib_enc/acelp_core_switch_enc.c @@ -123,11 +123,32 @@ void acelp_core_switch_enc( } } +#ifdef FIX_I4_OL_PITCH + if ( st->last_codec_mode == MODE1 ) + { + /* in MODE1 T_op is at 12.8 kHz */ + if ( st->last_L_frame != L_FRAME ) /* ACELP@16k core -> convert T_op to 16 kHz */ + { + T_op[0] = (short) ( 1.25f * T_op[0] + 0.5f ); + T_op[1] = (short) ( 1.25f * T_op[1] + 0.5f ); + } + } + else + { + /* in MODE2 T_op is at 16 kHz */ + if ( st->last_L_frame == L_FRAME ) /* ACELP@12.8k core -> convert T_op to 12.8 kHz */ + { + T_op[0] = (short) ( 0.8f * T_op[0] + 0.5f ); + T_op[1] = (short) ( 0.8f * T_op[1] + 0.5f ); + } + } +#else if ( st->last_L_frame != L_FRAME ) /* ACELP@16k core */ { T_op[0] = (short) ( 1.25f * T_op[0] + 0.5f ); T_op[1] = (short) ( 1.25f * T_op[1] + 0.5f ); } +#endif /*----------------------------------------------------------------* * Excitation encoding *----------------------------------------------------------------*/ diff --git a/lib_enc/amr_wb_enc.c b/lib_enc/amr_wb_enc.c index df5e82f8bb5bd0da0b79ab9f11c37c481e62b4d4..1a507f4736eb0b6c6fea8a631b8325a16f60f16d 100644 --- a/lib_enc/amr_wb_enc.c +++ b/lib_enc/amr_wb_enc.c @@ -108,8 +108,6 @@ void amr_wb_enc( LPD_state_HANDLE hLPDmem = st->hLPDmem; - push_wmops( "amr_wb_enc" ); - /*------------------------------------------------------------------* * Initialization *------------------------------------------------------------------*/ @@ -552,8 +550,6 @@ void amr_wb_enc( dbgwrite( snr_[0], sizeof( float ), 320, 1, "res/snr" ); #endif - pop_wmops(); - return; } diff --git a/lib_enc/cod_tcx.c b/lib_enc/cod_tcx.c index 9a890ae3c9f4deb10580190b4f37b9ebbc844971..87e703d16051d917003691d7ea6f89b87164f69b 100644 --- a/lib_enc/cod_tcx.c +++ b/lib_enc/cod_tcx.c @@ -332,7 +332,6 @@ void TNSAnalysisStereo( pFilter[0]->order = pFilter[1]->order = maxOrder; } -#ifdef FIX_1349_TNS_CRASH else { pFilter[0]->filterType = TNS_FILTER_OFF; @@ -340,7 +339,6 @@ void TNSAnalysisStereo( sts[0]->hTcxEnc->tnsData[k].nFilters = 0; sts[1]->hTcxEnc->tnsData[k].nFilters = 0; } -#endif } } } diff --git a/lib_enc/core_enc_switch.c b/lib_enc/core_enc_switch.c old mode 100644 new mode 100755 diff --git a/lib_enc/dtx.c b/lib_enc/dtx.c index c553fe2f888b12b338b1b3bb448a9247e918c823..8c2ec5f7ab818ffecf670560c2be72ca43d58f4f 100644 --- a/lib_enc/dtx.c +++ b/lib_enc/dtx.c @@ -142,7 +142,6 @@ void dtx( last_br_cng_flag ) { st->total_brate = st->last_total_brate_cng; - if ( !( st->total_brate == ACELP_7k20 && st->Opt_SC_VBR ) ) { st->Opt_SC_VBR = 0; @@ -158,6 +157,7 @@ void dtx( last_br_flag ) { st->total_brate = st->last_total_brate; + if ( !( st->total_brate == ACELP_7k20 && st->Opt_SC_VBR ) ) { st->Opt_SC_VBR = 0; diff --git a/lib_enc/enc_acelp_tcx_main.c b/lib_enc/enc_acelp_tcx_main.c index 8851d9be5e0c358e9470583a923ad7836d14c09b..f2dc342a0e0f2854faa2c579cb2aee3b7704a682 100644 --- a/lib_enc/enc_acelp_tcx_main.c +++ b/lib_enc/enc_acelp_tcx_main.c @@ -99,12 +99,7 @@ void enc_acelp_tcx_main( /* Apply non linearity to the SHB excitation */ if ( st->core == ACELP_CORE && st->igf ) { - non_linearity( ptr_bwe_exc, bwe_exc_extended, st->hBWE_TD->old_bwe_exc_extended, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale, st->coder_type, voice_factors, st->L_frame -#ifdef NONBE_1328_FIX_NON_LINEARITY - , - st->element_mode -#endif - ); + non_linearity( ptr_bwe_exc, bwe_exc_extended, st->hBWE_TD->old_bwe_exc_extended, L_FRAME32k, &st->hBWE_TD->bwe_non_lin_prev_scale, st->coder_type, voice_factors, st->L_frame, st->element_mode ); /* update the old_BWE_exc memory */ mvr2r( &old_bwe_exc[L_FRAME32k], st->hBWE_TD->old_bwe_exc, PIT16k_MAX * 2 ); diff --git a/lib_enc/evs_enc.c b/lib_enc/evs_enc.c index d22e3d3fdd5eb1241e4c01362189bcb32f1d7ce2..576462cd7d04051f737377b9419ade73078f910f 100644 --- a/lib_enc/evs_enc.c +++ b/lib_enc/evs_enc.c @@ -95,7 +95,9 @@ ivas_error evs_enc( int16_t padBits; float realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; /* real buffer */ float imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; /* imag buffer */ - int16_t pitch_orig[3]; /* original open-loop pitch values that might be altered in core_acelp_tcx20_switching() within MODE2 */ +#ifndef FIX_I4_OL_PITCH + int16_t pitch_orig[3]; /* original open-loop pitch values that might be altered in core_acelp_tcx20_switching() within MODE2 */ +#endif ivas_error error; error = IVAS_ERR_OK; @@ -168,7 +170,11 @@ ivas_error evs_enc( * Pre-processing *---------------------------------------------------------------------*/ +#ifdef FIX_I4_OL_PITCH + pre_proc( st, input_frame, old_inp_12k8, old_inp_16k, &inp, fr_bands, Etot, &ener, A, Aw, epsP, lsp_new, lsp_mid, &vad_hover_flag, &attack_flag, new_inp_resamp16k, &Voicing_flag, realBuffer, imagBuffer, &hq_core_type ); +#else pre_proc( st, input_frame, old_inp_12k8, old_inp_16k, &inp, fr_bands, &ener, pitch_orig, A, Aw, epsP, lsp_new, lsp_mid, &vad_hover_flag, &attack_flag, new_inp_resamp16k, &Voicing_flag, realBuffer, imagBuffer, &hq_core_type ); +#endif if ( st->mdct_sw == MODE2 ) { @@ -257,10 +263,12 @@ ivas_error evs_enc( core_switching_post_enc( st, old_inp_12k8, old_inp_16k, A ); +#ifndef FIX_I4_OL_PITCH if ( st->core == HQ_CORE ) { mvs2s( pitch_orig, st->pitch, 3 ); /* original open-loop pitch values might be altered in core_acelp_tcx20_switching() */ } +#endif } else /* MODE2 */ @@ -285,7 +293,9 @@ ivas_error evs_enc( /* Call main encoding function */ enc_acelp_tcx_main( st, old_inp_16k + L_INP_MEM, Aw, lsp_new, lsp_mid, bwe_exc_extended, voice_factors, pitch_buf, vad_hover_flag ); +#ifndef FIX_I4_OL_PITCH mvs2s( pitch_orig, st->pitch, 3 ); /* populate the original OL pitch values back */ +#endif /*---------------------------------------------------------------------* * Postprocessing for Mode 1/2 switching diff --git a/lib_enc/ext_sig_ana.c b/lib_enc/ext_sig_ana.c old mode 100644 new mode 100755 diff --git a/lib_enc/hq_classifier_enc.c b/lib_enc/hq_classifier_enc.c index 7d5efe2e43d0f49625a4c900dfc7194c2d4dfb5d..aa251290194100859c0b6e173baf6c79b2844d34 100644 --- a/lib_enc/hq_classifier_enc.c +++ b/lib_enc/hq_classifier_enc.c @@ -573,7 +573,6 @@ static int16_t hf_spectrum_sparseness( inv_rms = 0.0f; crest_mod = 0.0f; maximum( A, L_SPEC_HB, &Amax ); - if ( Amax == 0 ) { /* For all-zero input the crest is 1.0 */ @@ -626,7 +625,6 @@ static int16_t hf_spectrum_sparseness( crest = Amax * inv_rms; crest_mod = crest_mod * inv_rms; } - *crest_lp = HQ_CREST_FAC_SM * ( *crest_lp ) + ( 1.0f - HQ_CREST_FAC_SM ) * crest; *crest_mod_lp = HQ_CREST_FAC_SM * ( *crest_mod_lp ) + ( 1.0f - HQ_CREST_FAC_SM ) * crest_mod; diff --git a/lib_enc/hq_lr_enc.c b/lib_enc/hq_lr_enc.c index a66fa37d055968718714d2ea3111dcd240ad5fc2..13637fdbd2873f7c1c7b4a7ccc854ee4d6b2511b 100644 --- a/lib_enc/hq_lr_enc.c +++ b/lib_enc/hq_lr_enc.c @@ -195,7 +195,9 @@ void hq_lr_enc( Word32 L_band_energy[BANDS_MAX], L_band_energy_tmp[BANDS_MAX]; UWord16 lo; Word16 Q_band_energy; +#ifdef BASOP_NOGLOB Flag Overflow; +#endif /* BASOP_NOGLOB */ BSTR_ENC_HANDLE hBstr = st->hBstr; HQ_ENC_HANDLE hHQ_core = st->hHQ_core; @@ -337,7 +339,7 @@ void hq_lr_enc( #ifdef BASOP_NOGLOB Ep_fx[i] = L_shl_o( L_tmp, s_max( sub( exp, 6 ), -31 ), &Overflow ); /* Q -6 */ #else - Ep_fx[i] = L_shl( L_tmp, s_max( sub( exp, 6 ), -31 ) ); /* Q -6 */ + Ep_fx[i] = L_shl( L_tmp, s_max( sub( exp, 6 ), -31 ) ); /* Q -6 */ #endif Ep[i] = (float) ( Ep_fx[i] / pow( 2.0, -6 ) ); } @@ -412,7 +414,11 @@ void hq_lr_enc( } ELSE { +#ifdef BASOP_NOGLOB Ep_avrgL_fx = L_add_o( Ep_avrgL_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ +#else + Ep_avrgL_fx = L_add( Ep_avrgL_fx, Ep_tmp_fx[i] ); /*Q15 */ +#endif IF( L_sub( Ep_tmp_fx[i], Ep_peak_fx ) > 0 ) { Ep_peak_fx = Ep_tmp_fx[i]; @@ -531,10 +537,17 @@ void hq_lr_enc( move16(); } Mpy_32_16_ss( Ep_avrg_fx, tmp, &L_tmp, &lo ); +#ifndef BASOP_NOGLOB + L_tmp = L_shl( L_tmp, sub( 14, exp ) ); /*Q(13+exp-15 +14-exp+2 = 14) */ + L_tmp = L_max( L_tmp, 16384 ); /*14 */ + tmp = extract_l( L_min( L_tmp, beta_fx ) ); /*14 */ + alpha_fx = shl( mult( alpha_fx, tmp ), 1 ); /*14+14-15 +1=14 */ +#else /* BASOP_NOGLOB */ L_tmp = L_shl_o( L_tmp, sub( 14, exp ), &Overflow ); /*Q(13+exp-15 +14-exp+2 = 14) */ L_tmp = L_max( L_tmp, 16384 ); /*14 */ tmp = extract_l( L_min( L_tmp, beta_fx ) ); /*14 */ alpha_fx = shl( mult( alpha_fx, tmp ), 1 ); /*14+14-15 +1=14 */ +#endif /* BASOP_NOGLOB */ } ELSE { @@ -577,7 +590,11 @@ void hq_lr_enc( { IF( sub( i, lowband ) >= 0 ) { +#ifdef BASOP_NOGLOB Ep_avrg_fx = L_add_o( Ep_avrg_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ +#else + Ep_avrg_fx = L_add( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ +#endif } ELSE { @@ -616,8 +633,13 @@ void hq_lr_enc( Mpy_32_16_ss( Ep_peak_fx, tmp, &L_tmp, &lo ); Mpy_32_16_ss( L_tmp, lowband, &L_tmp, &lo ); Mpy_32_16_ss( L_tmp, 18842, &L_tmp, &lo ); - L_tmp = L_shl_o( L_tmp, sub( 27, exp ), &Overflow ); /*Q14 0.5 */ - tmp2 = extract_l( L_min( L_tmp, 19661 ) ); /*14 */ +#ifndef BASOP_NOGLOB + L_tmp = L_shl( L_tmp, sub( 27, exp ) ); /*Q14 0.5 */ + tmp2 = extract_l( L_min( L_tmp, 19661 ) ); /*14 */ +#else /* BASOP_NOGLOB */ + L_tmp = L_shl_o( L_tmp, sub( 27, exp ), &Overflow ); /*Q14 0.5 */ + tmp2 = extract_l( L_min( L_tmp, 19661 ) ); /*14 */ +#endif /* BASOP_NOGLOB */ Mpy_32_16_ss( L_band_energy_tmp[i], tmp2, &L_tmp, &lo ); L_band_energy_tmp[i] = L_shl( L_tmp, 1 ); /*Q_band_energy */ } @@ -643,7 +665,11 @@ void hq_lr_enc( bit_budget = sub( bit_budget, 2 ); /* bits in high bands to indicate the last 2 subbands is allocated bits or not */ FOR( i = 0; i < bands; i++ ) { +#ifndef BASOP_NOGLOB + Ep_tmp_fx[i] = L_shl( Ep_tmp_fx[i], 2 ); +#else /* BASOP_NOGLOB */ Ep_tmp_fx[i] = L_shl_o( Ep_tmp_fx[i], 2, &Overflow ); +#endif /* BASOP_NOGLOB */ } IF( st->core_brate == ACELP_13k20 ) { @@ -677,7 +703,11 @@ void hq_lr_enc( IF( sub( i, lowband ) >= 0 && add( sub( i, bands ), p2a_bands ) < 0 ) { Ep_vari_fx = L_add( Ep_vari_fx, L_abs( L_sub( Ep_tmp_fx[i], Ep_tmp_fx[sub( i, 1 )] ) ) ); /*Q15 */ - Ep_avrg_fx = L_add_o( Ep_avrg_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ +#ifndef BASOP_NOGLOB + Ep_avrg_fx = L_add( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ +#else /* BASOP_NOGLOB */ + Ep_avrg_fx = L_add_o( Ep_avrg_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ +#endif /* BASOP_NOGLOB */ } IF( sub( i, highband ) >= 0 ) @@ -710,7 +740,11 @@ void hq_lr_enc( tmp = sub( bands, p2a_bands ); tmp = sub( tmp, lowband ); /*Q0 */ - tmp1 = extract_h( L_shl_o( Ep_avrg_fx, 1, &Overflow ) ); /*Q0 */ +#ifndef BASOP_NOGLOB + tmp1 = extract_h( L_shl( Ep_avrg_fx, 1 ) ); /*Q0 */ +#else + tmp1 = extract_h( L_shl_o( Ep_avrg_fx, 1, &Overflow ) ); /*Q0 */ +#endif IF( tmp1 != 0 ) { exp = norm_s( tmp1 ); @@ -749,7 +783,11 @@ void hq_lr_enc( { tmp = sub( tmp, lowband ); Mpy_32_16_ss( Ep_tmp_fx[i], tmp, &L_tmp, &lo ); - tmp = extract_h( L_shl_o( L_tmp, 16, &Overflow ) ); /*Q0 */ +#ifndef BASOP_NOGLOB + tmp = extract_h( L_shl( L_tmp, 16 ) ); /*Q0 */ +#else /* BASOP_NOGLOB */ + tmp = extract_h( L_shl_o( L_tmp, 16, &Overflow ) ); /*Q0 */ +#endif /* BASOP_NOGLOB */ IF( tmp != 0 ) { exp = norm_s( tmp ); @@ -774,7 +812,11 @@ void hq_lr_enc( { tmp = sub( tmp, lowband ); - tmp1 = extract_h( L_shl_o( Ep_avrg_fx, 1, &Overflow ) ); /*Q0 */ +#ifndef BASOP_NOGLOB + tmp1 = extract_h( L_shl( Ep_avrg_fx, 1 ) ); /*Q0 */ +#else + tmp1 = extract_h( L_shl_o( Ep_avrg_fx, 1, &Overflow ) ); /*Q0 */ +#endif IF( tmp1 != 0 ) { exp = norm_s( tmp1 ); @@ -812,11 +854,19 @@ void hq_lr_enc( { IF( sub( i, lowband ) >= 0 ) { - Ep_avrg_fx = L_add_o( Ep_avrg_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ +#ifndef BASOP_NOGLOB + Ep_avrg_fx = L_add( Ep_avrg_fx, Ep_tmp_fx[i] ); /*Q15 */ +#else /* BASOP_NOGLOB */ + Ep_avrg_fx = L_add_o( Ep_avrg_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ +#endif /* BASOP_NOGLOB */ } ELSE { +#ifndef BASOP_NOGLOB + Ep_avrgL_fx = L_add( Ep_avrgL_fx, Ep_tmp_fx[i] ); /*Q15 */ +#else /* BASOP_NOGLOB */ Ep_avrgL_fx = L_add_o( Ep_avrgL_fx, Ep_tmp_fx[i], &Overflow ); /*Q15 */ +#endif /* BASOP_NOGLOB */ IF( L_sub( Ep_tmp_fx[i], Ep_peak_fx ) > 0 ) { Ep_peak_fx = Ep_tmp_fx[i]; @@ -836,7 +886,11 @@ void hq_lr_enc( move16(); FOR( i = 0; i < lowband; i++ ) { - tmp = extract_h( L_shl_o( Ep_avrgL_fx, 1, &Overflow ) ); /*Q0 */ +#ifndef BASOP_NOGLOB + tmp = extract_h( L_shl( Ep_avrgL_fx, 1 ) ); /*Q0 */ +#else + tmp = extract_h( L_shl_o( Ep_avrgL_fx, 1, &Overflow ) ); /*Q0 */ +#endif IF( tmp != 0 ) { exp = norm_s( tmp ); diff --git a/lib_enc/init_enc.c b/lib_enc/init_enc.c old mode 100644 new mode 100755 diff --git a/lib_enc/ivas_core_enc.c b/lib_enc/ivas_core_enc.c index cdf012b3f6740ab5eebb87cccf036d44ca340b23..35ac987a064c4d27d12092b879e8998d51c5d2ab 100644 --- a/lib_enc/ivas_core_enc.c +++ b/lib_enc/ivas_core_enc.c @@ -90,9 +90,7 @@ ivas_error ivas_core_enc( float *inp[CPE_CHANNELS]; float new_inp_resamp16k[CPE_CHANNELS][L_FRAME16k]; /* new input signal @16kHz, non pre-emphasised, used by the WB TBE/BWE */ float old_syn_12k8_16k[CPE_CHANNELS][L_FRAME16k]; /* ACELP core synthesis at 12.8kHz or 16kHz to be used by the SWB BWE */ - float *shb_speech; - float *hb_speech; - float *new_swb_speech; + float *shb_speech, *hb_speech, *new_swb_speech; float new_swb_speech_buffer[L_FRAME48k + STEREO_DFT_OVL_MAX]; float bwe_exc_extended[CPE_CHANNELS][L_FRAME32k + NL_BUFF_OFFSET]; float voice_factors[CPE_CHANNELS][NB_SUBFR16k]; @@ -272,7 +270,6 @@ ivas_error ivas_core_enc( } } - /*---------------------------------------------------------------------* * MDCT stereo: joint TCX Core Encoding *---------------------------------------------------------------------*/ @@ -314,7 +311,6 @@ ivas_error ivas_core_enc( } } - /*---------------------------------------------------------------------* * Postprocessing, BWEs and Updates *---------------------------------------------------------------------*/ diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index b24fab48e5cf02dfec9433cb2ef062dcd207e8f2..597275de1e6b29f003b324d45bcda4939d6b9b8d 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -34,6 +34,7 @@ #include "options.h" #ifdef DEBUGGING #include "debug.h" +#include #endif #include "cnst.h" #include "ivas_cnst.h" @@ -43,9 +44,6 @@ #include "ivas_prot.h" #include "wmc_auto.h" #include -#ifdef DEBUG_MODE_INFO -#include "string.h" -#endif /*---------------------------------------------------------------* @@ -111,13 +109,9 @@ ivas_error pre_proc_front_ivas( const int16_t force_front_vad, /* i : flag to force VAD decision */ const int16_t front_vad_dtx_flag, /* i : front-VAD DTX flag to overwrite VAD decision*/ const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - const int32_t last_ivas_total_brate, /* i : last IVAS total bitrate */ + const int16_t MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ + const int32_t last_ivas_total_brate, /* i : last IVAS total bitrate */ const int32_t ivas_total_brate /* i : IVAS total bitrate - for setting the DTX */ -#ifdef DEBUG_MODE_INFO - , - const int16_t ch_idx -#endif ) { float *inp_12k8, *new_inp_12k8; /* pointers to current frame and new data */ @@ -228,12 +222,12 @@ ivas_error pre_proc_front_ivas( } #ifdef DEBUG_MODE_INFO - if ( !( hCPE != NULL && hCPE->hStereoTD != NULL && ch_idx > 0 ) ) + if ( !( hCPE != NULL && hCPE->hStereoTD != NULL && n > 0 ) ) { /* for TD stereo only write out first channel. The existence of a second channel can vary, this is just easier to handle */ int16_t tmp_dmx_in[L_FRAME48k]; mvr2s( signal_in - NS2SA( st->input_Fs, ACELP_LOOK_NS ), tmp_dmx_in, input_frame ); - dbgwrite( tmp_dmx_in, sizeof( int16_t ), input_frame, 1, strcat( fname( debug_dir, "ivas_input_dmx", 0, ch_idx + 1, ENC ), ".pcm" ) ); + dbgwrite( tmp_dmx_in, sizeof( int16_t ), input_frame, 1, strcat( fname( debug_dir, "ivas_input_dmx", 0, n + 1, ENC ), ".pcm" ) ); } #endif @@ -459,16 +453,6 @@ ivas_error pre_proc_front_ivas( st->vad_flag = wb_vad( st, fr_bands, &i, &i, &i, &snr_sum_he, &localVAD_HE_SAD, &( st->flag_noisy_speech_snr ), NULL, NULL, -1000.0f, -1000.0f ); -#ifdef DEBUG_FORCE_DIR - if ( st->force_dir[0] != '\0' ) - { - dbgread( &st->vad_flag, sizeof( int16_t ), 1, fname( st->force_dir, "force_vad_flag.enf", -1, -1, -1 ) ); - } - else - { - dbgwrite( &st->vad_flag, sizeof( int16_t ), 1, 1, "res/force_vad_flag.enf" ); - } -#endif if ( force_front_vad == 1 || front_vad_flag == 1 ) { @@ -517,17 +501,6 @@ ivas_error pre_proc_front_ivas( st->bwidth = hCPE->hCoreCoder[0]->bwidth; } -#ifdef DEBUG_FORCE_DIR - if ( st->force_dir[0] != '\0' ) - { - dbgread( &st->bwidth, sizeof( int16_t ), 1, fname( st->force_dir, "force_bwidth.enf", -1, -1, -1 ) ); - } - else - { - dbgwrite( &st->bwidth, sizeof( int16_t ), 1, 1, "res/force_bwidth.enf" ); - } -#endif - /*----------------------------------------------------------------* * Noise energy down-ward update and total noise energy estimation * Long-term energies and relative frame energy updates @@ -728,19 +701,6 @@ ivas_error pre_proc_front_ivas( st->coder_type = find_uv( st, pitch_fr, voicing_fr, inp_12k8, ee, &dE1X, corr_shift, *relE, Etot, hp_E, &flag_spitch, last_core_orig, hStereoClassif ); -#ifdef DEBUG_FORCE_DIR - if ( st->force_dir[0] != '\0' ) - { - dbgread( &st->coder_type, sizeof( int16_t ), 1, fname( st->force_dir, "force_coder_type.enf", -1, -1, -1 ) ); - dbgread( &st->coder_type_raw, sizeof( int16_t ), 1, fname( st->force_dir, "force_coder_type_raw.enf", -1, -1, -1 ) ); - } - else - { - dbgwrite( &st->coder_type, sizeof( int16_t ), 1, 1, "res/force_coder_type.enf" ); - dbgwrite( &st->coder_type_raw, sizeof( int16_t ), 1, 1, "res/force_coder_type_raw.enf" ); - } -#endif - /*-----------------------------------------------------------------* * channel aware mode configuration * *-----------------------------------------------------------------*/ @@ -777,17 +737,6 @@ ivas_error pre_proc_front_ivas( smc_dec = ivas_smc_gmm( st, hStereoClassif, localVAD_HE_SAD, Etot, lsp_new, *cor_map_sum, epsP, PS, non_staX, *relE, &high_lpn_flag, flag_spitch ); -#ifdef DEBUG_FORCE_DIR - if ( st->force_dir[0] != '\0' ) - { - dbgread( &smc_dec, sizeof( int16_t ), 1, fname( st->force_dir, "force_smc_dec_loc1.enf", -1, -1, -1 ) ); - } - else - { - dbgwrite( &smc_dec, sizeof( int16_t ), 1, 1, "res/force_smc_dec_loc1.enf" ); - } -#endif - #ifdef DEBUGGING if ( st->idchan == 0 ) { @@ -896,23 +845,6 @@ ivas_error pre_proc_front_ivas( ivas_smc_mode_selection( st, element_brate, smc_dec, *relE, Etot, attack_flag, inp_12k8, S_map, flag_spitch ); } -#ifdef DEBUG_FORCE_DIR - if ( st->force_dir[0] != '\0' ) - { - dbgread( &smc_dec, sizeof( int16_t ), 1, fname( st->force_dir, "force_smc_dec_loc2.enf", -1, -1, -1 ) ); - dbgread( &st->sp_aud_decision0, sizeof( int16_t ), 1, fname( st->force_dir, "force_sp_aud_decision0.enf", -1, -1, -1 ) ); - dbgread( &st->sp_aud_decision1, sizeof( int16_t ), 1, fname( st->force_dir, "force_sp_aud_decision1.enf", -1, -1, -1 ) ); - dbgread( &st->sp_aud_decision2, sizeof( int16_t ), 1, fname( st->force_dir, "force_sp_aud_decision2.enf", -1, -1, -1 ) ); - } - else - { - dbgwrite( &smc_dec, sizeof( int16_t ), 1, 1, "res/force_smc_dec_loc2.enf" ); - dbgwrite( &st->sp_aud_decision0, sizeof( int16_t ), 1, 1, "res/force_sp_aud_decision0.enf" ); - dbgwrite( &st->sp_aud_decision1, sizeof( int16_t ), 1, 1, "res/force_sp_aud_decision1.enf" ); - dbgwrite( &st->sp_aud_decision2, sizeof( int16_t ), 1, 1, "res/force_sp_aud_decision2.enf" ); - } -#endif - /*----------------------------------------------------------------* * Final VAD correction (when HE-SAD is used instead of the normal VAD, * rewrite the VAD flag by VAD flag with DTX hangover for further processing) diff --git a/lib_enc/ivas_corecoder_enc_reconfig.c b/lib_enc/ivas_corecoder_enc_reconfig.c index dcab606086f7b436f08fd4df8909e30a2a91107b..08cac66ffb30f1cd233974dcc5b3d34bd0c42fc2 100644 --- a/lib_enc/ivas_corecoder_enc_reconfig.c +++ b/lib_enc/ivas_corecoder_enc_reconfig.c @@ -173,6 +173,7 @@ ivas_error ivas_corecoder_enc_reconfig( #if defined( DEBUGGING ) && defined( DBG_BITSTREAM_ANALYSIS ) strncpy( temp_ind_list[i].function_name, hBstr->ind_list[i].function_name, 100 ); #endif + hBstr->ind_list[i].nb_bits = -1; } @@ -458,7 +459,6 @@ ivas_error ivas_corecoder_enc_reconfig( } else if ( st_ivas->hMCT != NULL && st_ivas->nCPE > 1 ) { - if ( ( error = mct_enc_reconfigure( st_ivas, nchan_transport_old_real != nchan_transport_real ) ) != IVAS_ERR_OK ) { return error; diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index 0ab918ac762b5352bb2ae13e141eafe937a317d7..188ea1ea348c0e50e88c660a3e0024d08008bee2 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -161,9 +161,6 @@ ivas_error ivas_cpe_enc( #ifdef DEBUGGING sts[n]->force = hEncoderConfig->force; sts[n]->id_element = cpe_id + st_ivas->nSCE; -#ifdef DEBUG_FORCE_DIR - sts[n]->force_dir = hEncoderConfig->force_dir; -#endif #endif } @@ -182,19 +179,6 @@ ivas_error ivas_cpe_enc( { hCPE->element_mode = select_stereo_mode( hCPE, ivas_format ); } -#ifdef DEBUG_FORCE_DIR - else - { - if ( hCPE->hCoreCoder[0]->force_dir[0] != '\0' ) - { - dbgread( &hCPE->element_mode, sizeof( int16_t ), 1, fname( hCPE->hCoreCoder[0]->force_dir, "force_element_mode.enf", -1, -1, -1 ) ); - } - else - { - dbgwrite( &hCPE->element_mode, sizeof( int16_t ), 1, 1, "res/force_element_mode.enf" ); - } - } -#endif stereo_mode_combined_format_enc( st_ivas, hCPE ); @@ -301,6 +285,7 @@ ivas_error ivas_cpe_enc( sts[n]->element_mode = hCPE->element_mode; } + if ( hCPE->element_mode != IVAS_CPE_MDCT && ( hCPE->element_brate != hCPE->last_element_brate || hCPE->last_element_mode != hCPE->element_mode || sts[0]->ini_frame == 0 || ( ivas_total_brate != hEncoderConfig->last_ivas_total_brate ) || sts[0]->last_core_brate <= SID_2k40 ) ) /* If the last frame was SID or NO_DATA, we need to run stereo_dft_config here since VAD decision is not known yet */ { @@ -376,21 +361,6 @@ ivas_error ivas_cpe_enc( { #ifdef DEBUGGING hCPE->hStereoMdct->mdct_stereo_mode_cmdl = hEncoderConfig->mdct_stereo_mode_cmdl; -#ifdef DEBUG_FORCE_MDCT_STEREO_MODE - /*set all other members to defined states */ - hCPE->hStereoMdct->fDualMono = 0; - hCPE->hStereoMdct->fMSstereo = 0; - - if ( hCPE->hStereoMdct->mdct_stereo_mode_cmdl == SMDCT_FORCE_LR ) - { - hCPE->hStereoMdct->fDualMono = 1; - } - else if ( hCPE->hStereoMdct->mdct_stereo_mode_cmdl == SMDCT_FORCE_MS ) - { - hCPE->hStereoMdct->fMSstereo = 1; - } -#endif - #endif initMdctStereoEncData( hCPE->hStereoMdct, ivas_format, hCPE->element_mode, hCPE->element_brate, max_bwidth, 0, NULL, 0 ); hCPE->hStereoMdct->isSBAStereoMode = ( ( ivas_format == SBA_FORMAT || ivas_format == SBA_ISM_FORMAT ) && ( st_ivas->nchan_transport == 2 ) ); @@ -420,6 +390,7 @@ ivas_error ivas_cpe_enc( #ifdef DEBUG_MODE_DFT hCPE->hStereoDft->res_cod_bits = (int16_t) ( ( hCPE->element_brate ) / FRAMES_PER_SEC - 0.8f * sts[0]->bits_frame_nominal ); #endif + /* Update DFT Stereo memories */ stereo_dft_enc_update( hCPE->hStereoDft, max_bwidth ); @@ -492,6 +463,10 @@ ivas_error ivas_cpe_enc( } #ifdef DEBUG_MODE_INFO + for ( n = 0; n < n_CoreChannels; n++ ) + { + dbgwrite( sts[0]->input - NS2SA( sts[0]->input_Fs, ACELP_LOOK_NS ), sizeof( float ), input_frame, 1, fname( debug_dir, "input_DMX", n, sts[n]->id_element, ENC ) ); + } dbgwrite( &hCPE->element_mode, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "element_mode", 0, sts[0]->id_element, ENC ) ); #endif @@ -508,12 +483,7 @@ ivas_error ivas_cpe_enc( error = pre_proc_front_ivas( NULL, hCPE, hCPE->element_brate, nb_bits_metadata, input_frame, n, old_inp_12k8[n], old_inp_16k[n], &ener[n], &relE[n], A[n], Aw[n], epsP[n], lsp_new[n], lsp_mid[n], &vad_hover_flag[n], &attack_flag[n], realBuffer[n], imagBuffer[n], old_wsp[n], pitch_fr[n], voicing_fr[n], &loc_harm[n], &cor_map_sum[n], &vad_flag_dtx[n], enerBuffer[n], - fft_buff[n], A[0], lsp_new[0], currFlatness[n], tdm_ratio_idx, fr_bands, Etot_LR, lf_E, localVAD_HE_SAD, band_energies_LR, 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_flag : 0, 0, 0, ivas_format, st_ivas->hMCT != NULL, hEncoderConfig->last_ivas_total_brate, ivas_total_brate -#ifdef DEBUG_MODE_INFO - , - ( st_ivas->nSCE + ( cpe_id * CPE_CHANNELS ) + n ) -#endif - ); + fft_buff[n], A[0], lsp_new[0], currFlatness[n], tdm_ratio_idx, fr_bands, Etot_LR, lf_E, localVAD_HE_SAD, band_energies_LR, 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_flag : 0, 0, 0, ivas_format, st_ivas->hMCT != NULL, hEncoderConfig->last_ivas_total_brate, ivas_total_brate ); if ( error != IVAS_ERR_OK ) { return error; @@ -1094,20 +1064,6 @@ ivas_error create_cpe_enc( #ifdef DEBUGGING hCPE->hStereoMdct->mdct_stereo_mode_cmdl = st_ivas->hEncoderConfig->mdct_stereo_mode_cmdl; -#ifdef DEBUG_FORCE_MDCT_STEREO_MODE - /*set all other members to defined states */ - hCPE->hStereoMdct->fDualMono = 0; - hCPE->hStereoMdct->fMSstereo = 0; - - if ( hCPE->hStereoMdct->mdct_stereo_mode_cmdl == SMDCT_FORCE_LR ) - { - hCPE->hStereoMdct->fDualMono = 1; - } - else if ( hCPE->hStereoMdct->mdct_stereo_mode_cmdl == SMDCT_FORCE_MS ) - { - hCPE->hStereoMdct->fMSstereo = 1; - } -#endif #endif initMdctStereoEncData( hCPE->hStereoMdct, ivas_format, hCPE->element_mode, hCPE->element_brate, max_bwidth, 0, NULL, 1 ); hCPE->hStereoMdct->isSBAStereoMode = ( ( ivas_format == SBA_FORMAT || ivas_format == SBA_ISM_FORMAT ) && ( st_ivas->nchan_transport == 2 ) ); diff --git a/lib_enc/ivas_decision_matrix_enc.c b/lib_enc/ivas_decision_matrix_enc.c index 65a98f87d069fc0727f273d6bfca545c9fbe33fa..d9898c51b79512bf9a161a37ebb1794690380b0f 100644 --- a/lib_enc/ivas_decision_matrix_enc.c +++ b/lib_enc/ivas_decision_matrix_enc.c @@ -166,17 +166,6 @@ void ivas_decision_matrix_enc( } } -#ifdef DEBUG_FORCE_DIR - if ( st->force_dir[0] != '\0' ) - { - dbgread( &st->core, sizeof( int16_t ), 1, fname( st->force_dir, "force_core_loc1.enf", -1, -1, -1 ) ); - } - else - { - dbgwrite( &st->core, sizeof( int16_t ), 1, 1, "res/force_core_loc1.enf" ); - } -#endif - /* do not allow TD stereo ACELP core -> DFT stereo TCX core switching as it is on the WC complexity path */ if ( ( ( st->last_core == ACELP_CORE && last_element_mode == IVAS_CPE_TD && st->element_mode == IVAS_CPE_DFT ) || ( st->tdm_LRTD_flag == 1 && st->total_brate <= IVAS_16k4 ) ) && st->core == TCX_20_CORE && st->total_brate <= MAX_ACELP_BRATE ) /* Override TCX in case of LRTD && primary channel has low bitrate*/ { @@ -212,7 +201,7 @@ void ivas_decision_matrix_enc( { st->core = ACELP_CORE; } - else if ( st->force == FORCE_TCX20 || st->force == FORCE_TCX10 ) /* Initalizations should always happen with TCX20*/ + else if ( st->force == FORCE_TCX ) { st->core = TCX_20_CORE; } @@ -227,12 +216,14 @@ void ivas_decision_matrix_enc( if ( st->core == TCX_20_CORE && st->total_brate < STEREO_TCX_MIN_RATE ) { st->core = ACELP_CORE; + /* In TD stereo below 24.4 kbps we cannot overwrite the `coder_type` when it is set to TRANSITION, */ /* as it is used for TD stereo bit allocation. To ensure consistent bit allocation, it must remain unchanged on the decoder side. */ if ( st->idchan == 0 && !( element_brate < IVAS_24k4 && st->coder_type == TRANSITION && st->element_mode == IVAS_CPE_TD ) ) { st->coder_type = AUDIO; } + st->sp_aud_decision2 = 0; if ( st->low_rate_mode ) @@ -247,17 +238,6 @@ void ivas_decision_matrix_enc( st->core = TCX_20_CORE; } -#ifdef DEBUG_FORCE_DIR - if ( st->force_dir[0] != '\0' ) - { - dbgread( &st->core, sizeof( int16_t ), 1, fname( st->force_dir, "force_core_loc2.enf", -1, -1, -1 ) ); - } - else - { - dbgwrite( &st->core, sizeof( int16_t ), 1, 1, "res/force_core_loc2.enf" ); - } -#endif - /*---------------------------------------------------------------------* * Select ACELP and GSC extension layer *---------------------------------------------------------------------*/ @@ -292,19 +272,6 @@ void ivas_decision_matrix_enc( } } } - -#ifdef DEBUG_FORCE_DIR - if ( st->force_dir[0] != '\0' ) - { - dbgread( &st->extl, sizeof( int16_t ), 1, fname( st->force_dir, "force_extl.enf", -1, -1, -1 ) ); - dbgread( &st->extl_brate, sizeof( int32_t ), 1, fname( st->force_dir, "force_extl_brate.enf", -1, -1, -1 ) ); - } - else - { - dbgwrite( &st->extl, sizeof( int16_t ), 1, 1, "res/force_extl.enf" ); - dbgwrite( &st->extl_brate, sizeof( int32_t ), 1, 1, "res/force_extl_brate.enf" ); - } -#endif } /* SWB and FB */ @@ -367,19 +334,6 @@ void ivas_decision_matrix_enc( st->extl_brate = 0; } -#ifdef DEBUG_FORCE_DIR - if ( st->force_dir[0] != '\0' ) - { - dbgread( &st->extl, sizeof( int16_t ), 1, fname( st->force_dir, "force_extl.enf", -1, -1, -1 ) ); - dbgread( &st->extl_brate, sizeof( int32_t ), 1, fname( st->force_dir, "force_extl_brate.enf", -1, -1, -1 ) ); - } - else - { - dbgwrite( &st->extl, sizeof( int16_t ), 1, 1, "res/force_extl.enf" ); - dbgwrite( &st->extl_brate, sizeof( int32_t ), 1, 1, "res/force_extl_brate.enf" ); - } -#endif - /* set IC-BWE bitrate */ if ( st->element_mode == IVAS_CPE_TD && ( st->idchan == 0 ) && !st->tdm_LRTD_flag ) { diff --git a/lib_enc/ivas_dirac_enc.c b/lib_enc/ivas_dirac_enc.c index 1a6290580b8d8ff7fbaa47617969fac39b5a12d9..fc74cfeb052b7df96c02a06e4cbfa1bdb65eb80b 100644 --- a/lib_enc/ivas_dirac_enc.c +++ b/lib_enc/ivas_dirac_enc.c @@ -291,7 +291,7 @@ ivas_error ivas_dirac_enc( const int16_t input_frame, /* i : input frame length */ const int16_t dtx_vad, /* i : DTX vad flag */ const IVAS_FORMAT ivas_format, /* i : ivas format */ - const int16_t nchan_transport, /* i : number of transport channels */ + const int16_t nchan_transport, /* i : number of transport channels */ const int16_t hodirac_flag /* i : hodirac flag */ ) { diff --git a/lib_enc/ivas_front_vad.c b/lib_enc/ivas_front_vad.c index cb355ef4a640551f996be758f9f1e11528613562..bfe47d07a57c5c2c50e2adfe27e4f8c87c9435b2 100644 --- a/lib_enc/ivas_front_vad.c +++ b/lib_enc/ivas_front_vad.c @@ -422,9 +422,7 @@ ivas_error front_vad_spar( } noise_est_down( fr_bands[0], hFrontVad->hNoiseEst->bckr, tmpN, tmpE, st->min_band, st->max_band, &hFrontVad->hNoiseEst->totalNoise, Etot[0], &hFrontVad->hNoiseEst->Etot_last, &hFrontVad->hNoiseEst->Etot_v_h2 ); - corr_shift = correlation_shift( hFrontVad->hNoiseEst->totalNoise ); - dtx( st, hEncoderConfig->last_ivas_total_brate, hEncoderConfig->ivas_total_brate, vad_flag_dtx[0], inp_12k8 ); /* linear prediction analysis */ diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc.c index 2143af94d2ef37c7473a1e99d9cd2eea56d7d49f..336e5fcbfe905367258a625a89215ad678aba837 100644 --- a/lib_enc/ivas_init_enc.c +++ b/lib_enc/ivas_init_enc.c @@ -287,9 +287,6 @@ void copy_encoder_config( #ifdef DEBUGGING st->force = st_ivas->hEncoderConfig->force; -#ifdef DEBUG_FORCE_DIR - st->force_dir = st_ivas->hEncoderConfig->force_dir; -#endif #endif st->element_mode = st_ivas->hEncoderConfig->element_mode_init; @@ -468,7 +465,8 @@ ivas_error ivas_init_encoder( { st_ivas->ind_list[i].nb_bits = -1; } -#ifdef BITSTERAM_ANALYSIS + +#if defined( DEBUGGING ) && defined( DBG_BITSTREAM_ANALYSIS ) for ( i = 0; i < st_ivas->ivas_max_num_indices; i++ ) { memset( st_ivas->ind_list[i].function_name, 'A', 100 * sizeof( char ) ); @@ -754,13 +752,13 @@ ivas_error ivas_init_encoder( else { /* allocate and initialize MCT core coder */ + { int16_t n_all; n_all = st_ivas->nchan_transport + st_ivas->hEncoderConfig->nchan_ism; st_ivas->nCPE = ( n_all + 1 ) >> 1; } - for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) { if ( ( error = create_cpe_enc( st_ivas, cpe_id, ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS ) ) != IVAS_ERR_OK ) @@ -784,7 +782,7 @@ ivas_error ivas_init_encoder( { st_ivas->mc_mode = ivas_mc_mode_select( hEncoderConfig->mc_input_setup, ivas_total_brate ); - if ( ( error = ivas_create_lfe_lpf_enc( &st_ivas->hLfeLpf, hEncoderConfig->input_Fs ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_create_lfe_lpf_enc( &st_ivas->hLfeLpf, input_Fs ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_enc/ivas_ism_enc.c b/lib_enc/ivas_ism_enc.c index e2df76f1c2a1ea94646763658eee2788a182717c..d3db3490fab0b60c9e72444c63f47917924c0c37 100644 --- a/lib_enc/ivas_ism_enc.c +++ b/lib_enc/ivas_ism_enc.c @@ -150,9 +150,6 @@ ivas_error ivas_ism_enc( #ifdef DEBUGGING st->force = st_ivas->hEncoderConfig->force; st->id_element = sce_id; -#ifdef DEBUG_FORCE_DIR - st->force_dir = st_ivas->hEncoderConfig->force_dir; -#endif #endif /*---------------------------------------------------------------* @@ -171,10 +168,6 @@ ivas_error ivas_ism_enc( st->bits_frame_nominal = (int16_t) ( ( hSCE->element_brate / FRAMES_PER_SEC ) - ISM_NB_BITS_METADATA_NOMINAL ); -#ifdef DEBUG_MODE_INFO - dbgwrite( &st->element_mode, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "element_mode", 0, st->id_element, ENC ) ); -#endif - /*----------------------------------------------------------------* * Front Pre-processing *----------------------------------------------------------------*/ @@ -186,12 +179,7 @@ ivas_error ivas_ism_enc( error = pre_proc_front_ivas( hSCE, NULL, hSCE->element_brate, nb_bits_metadata[sce_id], input_frame, 0, old_inp_12k8[sce_id][0], old_inp_16k[sce_id][0], &ener[sce_id][0], &relE[sce_id][0], A[sce_id][0], Aw[sce_id][0], epsP[sce_id][0], lsp_new[sce_id][0], lsp_mid[sce_id][0], &vad_hover_flag[sce_id][0], &attack_flag[sce_id][0], realBuffer[sce_id][0], imagBuffer[sce_id][0], old_wsp[sce_id][0], pitch_fr[sce_id][0], voicing_fr[sce_id][0], &loc_harm[sce_id][0], &cor_map_sum[sce_id][0], &vad_flag_dtx[sce_id][0], enerBuffer[sce_id][0], - fft_buff[sce_id][0], A[sce_id][0], lsp_new[sce_id][0], currFlatness[0], 0, fr_bands, Etot_LR, lf_E, localVAD_HE_SAD, NULL, 0, 0, 0, 0, ISM_FORMAT, 0, st_ivas->hEncoderConfig->last_ivas_total_brate, st_ivas->hEncoderConfig->ivas_total_brate -#ifdef DEBUG_MODE_INFO - , - st->id_element -#endif - ); + fft_buff[sce_id][0], A[sce_id][0], lsp_new[sce_id][0], currFlatness[0], 0, fr_bands, Etot_LR, lf_E, localVAD_HE_SAD, NULL, 0, 0, 0, 0, ISM_FORMAT, 0, st_ivas->hEncoderConfig->last_ivas_total_brate, st_ivas->hEncoderConfig->ivas_total_brate ); if ( error != IVAS_ERR_OK ) { return error; @@ -431,21 +419,7 @@ ivas_error ivas_ism_enc( } } } - - for ( sce_id = 0; sce_id < nchan_transport_ism; sce_id++ ) - { - float tmpF; - int16_t id; - - st = st_ivas->hSCE[sce_id]->hCoreCoder[0]; - id = st->id_element; - - tmpF = st->element_brate / 1000.0f; - dbgwrite( &tmpF, sizeof( float ), 1, input_frame, fname( debug_dir, "element_brate", 0, id, ENC ) ); - } - #endif - pop_wmops(); return error; diff --git a/lib_enc/ivas_ism_metadata_enc.c b/lib_enc/ivas_ism_metadata_enc.c index 06b0e4b996492fded6eeaa92fdad3dc9e57ca8ed..a8c224d1768aabfe47aa0117aa0a9393e1181c01 100644 --- a/lib_enc/ivas_ism_metadata_enc.c +++ b/lib_enc/ivas_ism_metadata_enc.c @@ -296,18 +296,6 @@ ivas_error ivas_ism_metadata_enc( } } -#ifdef DEBUG_FORCE_DIR - if ( hSCE[0]->hCoreCoder[0]->force_dir[0] != '\0' ) - { - dbgread( ism_imp, sizeof( int16_t ), nchan_ism, fname( hSCE[0]->hCoreCoder[0]->force_dir, "force_ism_imp.enf", -1, -1, -1 ) ); - } - else - { - dbgwrite( ism_imp, sizeof( int16_t ), nchan_ism, 1, "res/force_ism_imp.enf" ); - } -#endif - - /*----------------------------------------------------------------* * Write ISM common signaling *----------------------------------------------------------------*/ diff --git a/lib_enc/ivas_masa_enc.c b/lib_enc/ivas_masa_enc.c index 7a4a250fe898f829c6b543f808f86c84bd9a4a50..0da38f8e2e6ab52f01bef0aeb72fe0c138885db5 100644 --- a/lib_enc/ivas_masa_enc.c +++ b/lib_enc/ivas_masa_enc.c @@ -482,7 +482,6 @@ ivas_error ivas_masa_encode( push_next_indice( hMetaData, hQMetaData->no_directions - 1, 1 ); hQMetaData->metadata_max_bits -= 1; } - /* write subframe mode */ push_next_indice( hMetaData, hQMetaData->q_direction[0].cfg.nblocks == 1 ? 1 : 0, MASA_SUBFRAME_BITS ); hQMetaData->metadata_max_bits -= MASA_SUBFRAME_BITS; @@ -2637,7 +2636,6 @@ void ivas_merge_masa_metadata( float total_diff_nrg; float eneBand; float energyMerged[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - OMASA_ENCODER_ENERGY_HANDLE hOmasaEnergy = hMasa->data.hOmasaData->hOmasaEnergy; numCodingBands = hMasa->config.numCodingBands; @@ -2680,7 +2678,7 @@ void ivas_merge_masa_metadata( total_diff_nrg = eneBand * hMeta->common_meta.diffuse_to_total_ratio[sf][band]; /* criterion is mean of ISM ratio and new ratio */ - energyTimesRatioISM = ( hOMasaMeta->directional_meta[0].energy_ratio[sf][band] + ( 1.0f - total_diff_nrg / ( EPSILON + eneBand + hOmasaEnergy->energy_ism[sf][band] ) ) ) / 2.0f * hOmasaEnergy->energy_ism[sf][band]; + energyTimesRatioISM = ( hOMasaMeta->directional_meta[0].energy_ratio[sf][band] + ( 1.0f - total_diff_nrg / ( EPSILON + eneBand + hOmasaEnergy->energy_ism[sf][band] ) ) ) / 2.0f * hMasa->data.hOmasaData->hOmasaEnergy->energy_ism[sf][band]; /* Determine combined metadata based on the weights */ merge_dest = -1; @@ -3451,7 +3449,6 @@ static void ivas_encode_masaism_metadata( for ( band = 0; band < omasa_nbands; band++ ) { energy_ism += hOmasaEnergy->energy_ism[sf][band]; - for ( obj = 0; obj < nchan_ism; obj++ ) { energy_ism_ind[obj] += hOmasaEnergy->energy_ism[sf][band] * hOmasaEnergy->energy_ratio_ism[sf][band][obj]; @@ -3669,7 +3666,6 @@ static void ivas_encode_masaism_metadata( } } - calculate_nbits_meta( nchan_ism, hOmasaEnergy->q_energy_ratio_ism, hOmasaData->masa_to_total_energy_ratio, numSf, numCodingBands, bits_ism, idx_separated_object, ism_imp ); /* quantize directions */ diff --git a/lib_enc/ivas_mc_param_enc.c b/lib_enc/ivas_mc_param_enc.c index 26cf981ca6431119232de6eebc1726997959f5ed..25314cd89e0e7b1f7ceea01620ff1e4c10869f19 100644 --- a/lib_enc/ivas_mc_param_enc.c +++ b/lib_enc/ivas_mc_param_enc.c @@ -62,7 +62,6 @@ static void ivas_param_mc_parameter_quantizer( const float *x, const int16_t L, static void ivas_param_mc_transient_detection( PARAM_MC_ENC_HANDLE hParamMC, TRAN_DET_HANDLE hTranDet, int16_t *bAttackPresent, int16_t *attackIdx ); - static void ivas_param_mc_quantize_iccs( PARAM_MC_ENC_HANDLE hParamMC, float Cy[MAX_LS_CHANNELS][MAX_LS_CHANNELS], const int16_t freq_idx, const int16_t nchan_input, int16_t *ICC_idx_out ); static void ivas_param_mc_quantize_ilds( PARAM_MC_ENC_HANDLE hParamMC, float Cy[MAX_LS_CHANNELS][MAX_LS_CHANNELS], float Cx[PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], const int16_t freq_idx, const int16_t nchan_input, const int16_t nchan_transport, int16_t *ILD_idx_out, float ILD_q[PARAM_MC_SZ_ILD_MAP] ); @@ -940,7 +939,7 @@ static void ivas_param_mc_quantize_ilds( const int16_t freq_idx, /* i : frequency index being processed */ const int16_t nchan_input, /* i : number of input channels */ const int16_t nchan_transport, /* i : number of transport channels */ - int16_t *ILD_idx_out, /* o : ILD indices */ + int16_t *ILD_idx_out, /* o : ILD indices */ float ILD_q[PARAM_MC_SZ_ILD_MAP] /* o : Quanzited ILD matrix */ ) { diff --git a/lib_enc/ivas_mct_core_enc.c b/lib_enc/ivas_mct_core_enc.c index 59e04c5cb8849fa830744ff7e2a0a3e0188c9f2c..4a46bd7b2f7045b8568f50b98bf97c8e550a9707 100644 --- a/lib_enc/ivas_mct_core_enc.c +++ b/lib_enc/ivas_mct_core_enc.c @@ -524,6 +524,7 @@ void ivas_mct_core_enc( { nAvailBits -= IVAS_FORMAT_SIGNALING_NBITS_EXTENDED; nAvailBits -= SBA_ORDER_BITS + SBA_PLANAR_BITS; + /*MCT is used at bitrates > 80 kbps and additional 1 bit is present at these bitrates*/ if ( ivas_format == SBA_ISM_FORMAT ) { @@ -602,7 +603,9 @@ void ivas_mct_core_enc( #ifdef DEBUGGING format_bits = ( ivas_format == MC_FORMAT ? IVAS_FORMAT_SIGNALING_NBITS + MC_LS_SETUP_BITS : IVAS_FORMAT_SIGNALING_NBITS_EXTENDED + SBA_ORDER_BITS + SBA_PLANAR_BITS ); + format_bits += ( ivas_format == SBA_ISM_FORMAT ); + mct_bits += hMCT->nBitsMCT + hMCT->nchan_out_woLFE; assert( ( total_brate + ( NBITS_BWIDTH + format_bits + mct_bits + sba_meta + lfe_bits ) * FRAMES_PER_SEC ) == ivas_total_brate ); #endif diff --git a/lib_enc/ivas_mct_enc.c b/lib_enc/ivas_mct_enc.c old mode 100644 new mode 100755 diff --git a/lib_enc/ivas_omasa_enc.c b/lib_enc/ivas_omasa_enc.c index d38980016aad4e7bf4b1f4699f941d291e058dc3..660b4d2a0d422524c0b2f0af54caf8c9604687d8 100644 --- a/lib_enc/ivas_omasa_enc.c +++ b/lib_enc/ivas_omasa_enc.c @@ -1029,7 +1029,6 @@ static void ivas_omasa_energy_and_ratio_est( /* Reset variable */ for ( i = 0; i < hOMasa->nbands; i++ ) { - set_zero( hOmasaEnergy->energy_ratio_ism[block_m_idx][i], nchan_ism ); } set_zero( hOmasaEnergy->energy_ism[block_m_idx], num_freq_bands ); diff --git a/lib_enc/ivas_osba_enc.c b/lib_enc/ivas_osba_enc.c index 438edc41cc635a41eb92da1f8ec75b53cf111504..993954560791bb819e23e8bf56bad7e3fc1a9ce8 100644 --- a/lib_enc/ivas_osba_enc.c +++ b/lib_enc/ivas_osba_enc.c @@ -182,12 +182,12 @@ ivas_error ivas_osba_enc_reconfig( ivas_error error; ENCODER_CONFIG_HANDLE hEncoderConfig; + error = IVAS_ERR_OK; hEncoderConfig = st_ivas->hEncoderConfig; ivas_total_brate = hEncoderConfig->ivas_total_brate; int16_t nchan_transport; - if ( ivas_total_brate != hEncoderConfig->last_ivas_total_brate ) { DIRAC_ENC_HANDLE hDirAC = st_ivas->hDirAC; @@ -329,8 +329,8 @@ ivas_error ivas_osba_enc_reconfig( /*-----------------------------------------------------------------* * Allocate, initialize, and configure SCE/CPE/MCT handles *-----------------------------------------------------------------*/ - nchan_transport = st_ivas->nchan_transport; + nchan_transport = st_ivas->nchan_transport; if ( old_ism_mode == ISM_MODE_NONE && st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { { @@ -342,7 +342,6 @@ ivas_error ivas_osba_enc_reconfig( { nchan_transport_old += st_ivas->hEncoderConfig->nchan_ism; - nchan_transport = st_ivas->nchan_transport; } else if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) @@ -478,5 +477,7 @@ static void ivas_osba_render_ism_to_sba( } } + /* Gain with loudness-matching gains */ + return; } diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc.c index 09a209840a108c5ed725aa10fcda493e2f7d4fc1..6f436f8add78229639989b812d2736b3e6eb6fac 100644 --- a/lib_enc/ivas_qmetadata_enc.c +++ b/lib_enc/ivas_qmetadata_enc.c @@ -46,6 +46,7 @@ #include #endif + /*-----------------------------------------------------------------------* * Local function prototypes *-----------------------------------------------------------------------*/ @@ -958,7 +959,7 @@ void ivas_qmetadata_enc_sid_encode( BSTR_ENC_HANDLE hMetaData, /* i/o: metadata bitstream handle */ IVAS_QMETADATA *q_metadata, /* i/o: metadata handle */ const int16_t masa_sid_descriptor, /* i : description of MASA SID coding structure */ - const int16_t nchan_transport, /* i : number of transport channels */ + const int16_t nchan_transport, /* i : number of transport channels */ const int16_t ivas_format /* i : IVAS format */ ) { @@ -1293,7 +1294,7 @@ void reset_metadata_spatial( #endif hMetaData->nb_bits_tot += hMetaData->ind_list[j].nb_bits; hMetaData->ind_list[i].nb_bits = -1; -#if defined( DEBUGGING ) && defined( DBG_BITSTREAM_ANALYSIS ) +#ifdef DBG_BISTREAM_ANALYSIS sprintf( hMetaData->ind_list[i].function_name, "RESET in reset_metadata_spatial" ); #endif } @@ -5755,6 +5756,7 @@ static float direction_distance( } #endif + static int16_t divide_GR_orders( const int16_t *q_idx, const int16_t GR1, @@ -6047,11 +6049,14 @@ void ivas_omasa_encode_masa_to_total( float data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; float q_dct_data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; float step = STEP_M2T; + int16_t q_idx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; float dct_data_tmp[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; float dct_data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; + int16_t bits_pos, nb_bits; int16_t n_streams, len_stream; + Word32 q_dct_data_fx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS], dct_data_tmp_fx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS]; diff --git a/lib_enc/ivas_sce_enc.c b/lib_enc/ivas_sce_enc.c index 0f7e80cc13de84a7ee51f407ae61703a285ce4f4..5d1f56ab30c3243eb0f0187e1b32761ee14979d7 100644 --- a/lib_enc/ivas_sce_enc.c +++ b/lib_enc/ivas_sce_enc.c @@ -120,9 +120,6 @@ ivas_error ivas_sce_enc( #ifdef DEBUGGING st->force = st_ivas->hEncoderConfig->force; st->id_element = sce_id; -#ifdef DEBUG_FORCE_DIR - st->force_dir = st_ivas->hEncoderConfig->force_dir; -#endif #endif /*---------------------------------------------------------------* @@ -170,11 +167,13 @@ ivas_error ivas_sce_enc( /* set flag for sampling rate of OL S/M classifier */ flag_16k_smc = 0; if ( ivas_format == SBA_FORMAT && ( st_ivas->hEncoderConfig->ivas_total_brate == IVAS_24k4 || st_ivas->hEncoderConfig->ivas_total_brate == IVAS_32k ) && hSCE->element_brate == hSCE->last_element_brate ) + { flag_16k_smc = 1; } #ifdef DEBUG_MODE_INFO + dbgwrite( st->input - NS2SA( st->input_Fs, ACELP_LOOK_NS ), sizeof( float ), input_frame, 1, "res/input_DMX" ); dbgwrite( &st->element_mode, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "element_mode", 0, st->id_element, ENC ) ); #endif @@ -190,12 +189,7 @@ ivas_error ivas_sce_enc( &ener[0], &relE[0], A[0], Aw[0], epsP[0], lsp_new[0], lsp_mid[0], &vad_hover_flag[0], &attack_flag[0], realBuffer[0], imagBuffer[0], old_wsp[0], pitch_fr[0], voicing_fr[0], &loc_harm[0], &cor_map_sum[0], &vad_flag_dtx[0], enerBuffer[0], fft_buff[0], A[0], lsp_new[0], currFlatness[0], 0, fr_bands, Etot_LR, lf_E, localVAD_HE_SAD, NULL, flag_16k_smc, - st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_flag : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->force_front_vad : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_dtx_flag : 0, ivas_format, 0, st_ivas->hEncoderConfig->last_ivas_total_brate, st_ivas->hEncoderConfig->ivas_total_brate -#ifdef DEBUG_MODE_INFO - , - st->id_element -#endif - ); + st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_flag : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->force_front_vad : 0, st_ivas->hSpar != NULL ? st_ivas->hSpar->front_vad_dtx_flag : 0, ivas_format, 0, st_ivas->hEncoderConfig->last_ivas_total_brate, st_ivas->hEncoderConfig->ivas_total_brate ); if ( error != IVAS_ERR_OK ) { return error; diff --git a/lib_enc/ivas_spar_md_enc.c b/lib_enc/ivas_spar_md_enc.c index ca9dfdea04877df00fba992e98e0c9c641137c21..55902edde63c5337b0081b031e7357c66c8615fe 100644 --- a/lib_enc/ivas_spar_md_enc.c +++ b/lib_enc/ivas_spar_md_enc.c @@ -424,7 +424,6 @@ static void ivas_band_mixing( } } } - return; } @@ -894,6 +893,7 @@ ivas_error ivas_spar_md_enc_process( hMdEnc->mixer_mat[i][j][b + 1] = prior_mixer[i][j][b + 1]; } } + mvr2r( P_quant_re_prior[b], hMdEnc->spar_md.band_coeffs[b].P_quant_re, FOA_CHANNELS - 1 ); mvr2r( P_quant_re_prior[b + 1], hMdEnc->spar_md.band_coeffs[b + 1].P_quant_re, FOA_CHANNELS - 1 ); } @@ -1721,6 +1721,7 @@ static void ivas_write_parameter_bitstream_dtx( float pr_min_max[2]; int16_t zero_pad_bits, sid_bits_len; int16_t sba_spar_bitlen; + sid_bits_len = hMetaData->nb_bits_tot; pr_min_max[0] = pSpar_md->min_max[0]; pr_min_max[1] = pSpar_md->min_max[1]; @@ -1778,6 +1779,7 @@ static void ivas_write_parameter_bitstream_dtx( sid_bits_len = hMetaData->nb_bits_tot - sid_bits_len; sba_spar_bitlen = ivas_sba_spar_sid_bitlen( num_dmx[0] ); zero_pad_bits = sba_spar_bitlen - sid_bits_len; + assert( zero_pad_bits >= 0 ); if ( num_dmx[0] == 2 ) { diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index e5ca0102a4ea3c00b5d0c49b1cc14ba118460ecf..2620fb3e976a67c8a2649eb75eee07cd0b51d03d 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -39,10 +39,6 @@ #include "ivas_cnst.h" #include "stat_enc.h" #include "ivas_stat_com.h" -#ifdef DEBUG_FORCE_DIR -#include "debug.h" -#endif - /*----------------------------------------------------------------------------------* * DFT Stereo encoder structures @@ -806,7 +802,6 @@ typedef struct ivas_omasa_encoder_energy_struct } OMASA_ENCODER_ENERGY_STATE, *OMASA_ENCODER_ENERGY_HANDLE; - typedef struct ivas_omasa_encoder_data_struct { OMASA_ENCODER_ENERGY_HANDLE hOmasaEnergy; @@ -1213,9 +1208,6 @@ typedef struct encoder_config_structure int16_t stereo_mode_cmdl; /* stereo mode forced from the command-line */ int16_t force; /* parameter to force specific "core" of the Core-Coder*/ int16_t mdct_stereo_mode_cmdl; /* mdct stereo mode forced from command-line, employed only when DEBUG_FORCE_MDCT_STEREO_MODE is activated */ -#ifdef DEBUG_FORCE_DIR - char force_dir[FORCE_DIR_MAX_LENGTH]; /* directory containing external binary files for modes/parameters enforcement (empty string indicates no enforcement) */ -#endif #ifdef DEBUG_AGC_ENCODER_CMD_OPTION int16_t Opt_AGC_ON; /* flag indicating AGC operation in SBA */ #endif diff --git a/lib_enc/ivas_stereo_classifier.c b/lib_enc/ivas_stereo_classifier.c index e992ed790417ddb9a5174b4e7d7434a7b022dd57..597341d003a0fc8891627eafd008401f69c07d04 100644 --- a/lib_enc/ivas_stereo_classifier.c +++ b/lib_enc/ivas_stereo_classifier.c @@ -190,17 +190,6 @@ int16_t select_stereo_mode( } } -#ifdef DEBUG_FORCE_DIR - if ( hCPE->hCoreCoder[0]->force_dir[0] != '\0' ) - { - dbgread( &element_mode, sizeof( int16_t ), 1, fname( hCPE->hCoreCoder[0]->force_dir, "force_element_mode.enf", -1, -1, -1 ) ); - } - else - { - dbgwrite( &element_mode, sizeof( int16_t ), 1, 1, "res/force_element_mode.enf" ); - } -#endif - if ( hCPE->last_element_mode != element_mode ) { if ( hCPE->last_element_mode != IVAS_CPE_DFT && hCPE->last_element_mode != IVAS_CPE_TD ) @@ -633,17 +622,6 @@ void unclr_classifier_td( dbgwrite( &hStereoClassif->unclr_decision, sizeof( int16_t ), 1, 1, "res/unclr_dec_hyst.x" ); #endif -#ifdef DEBUG_FORCE_DIR - if ( hCPE->hCoreCoder[0]->force_dir[0] != '\0' ) - { - dbgread( &hStereoClassif->unclr_decision, sizeof( int16_t ), 1, fname( hCPE->hCoreCoder[0]->force_dir, "force_unclr_decision.enf", -1, -1, -1 ) ); - } - else - { - dbgwrite( &hStereoClassif->unclr_decision, sizeof( int16_t ), 1, 1, "res/force_unclr_decision.enf" ); - } -#endif - return; } @@ -734,17 +712,6 @@ void unclr_classifier_dft( dbgwrite( &hStereoClassif->unclr_decision, sizeof( int16_t ), 1, 1, "res/unclr_dec_hyst.x" ); #endif -#ifdef DEBUG_FORCE_DIR - if ( hCPE->hCoreCoder[0]->force_dir[0] != '\0' ) - { - dbgread( &hStereoClassif->unclr_decision, sizeof( int16_t ), 1, fname( hCPE->hCoreCoder[0]->force_dir, "force_unclr_decision.enf", -1, -1, -1 ) ); - } - else - { - dbgwrite( &hStereoClassif->unclr_decision, sizeof( int16_t ), 1, 1, "res/force_unclr_decision.enf" ); - } -#endif - return; } @@ -835,6 +802,14 @@ void xtalk_classifier_td( minimum( hStereoClassif->xtalk_score_buf, XTALK_SCORE_BUF_LEN, &scr_min ); maximum( hStereoClassif->xtalk_score_buf, XTALK_SCORE_BUF_LEN, &scr_max ); +#ifdef DEBUG_MODE_TD + edge_type = 0; + edge_detect( hStereoClassif->xtalk_score_buf, XTALK_SCORE_BUF_LEN, -0.2f, 1.0f, &edge, &edge_type ); + edge_0_1 = lin_interp( 1 - edge, 1.0f, 1.0f, 0.6f, 0.0f, 1 ); + dbgwrite( &score, sizeof( float ), 1, 1, "res/score.x" ); + dbgwrite( &edge_0_1, sizeof( float ), 1, 1, "res/edge_0_1.x" ); +#endif + if ( ( ( scr_min < 0.0f && scr_max > 0.2f ) || ( scr_max - scr_min > 0.5f ) ) ) { /* test rising edge (use 0 as edge_type because of newer->older buffer samples ordering) */ @@ -856,6 +831,7 @@ void xtalk_classifier_td( edge_0_1 = 0.0f; } + /* weight raw score based on rising edge detector */ wedge = lin_interp( edge_0_1, 0.0f, 0.9f, 1.0f, 0.5f, 1 ); @@ -879,17 +855,6 @@ void xtalk_classifier_td( dbgwrite( &hStereoClassif->xtalk_decision, sizeof( int16_t ), 1, 1, "res/xtalk_dec_hyst.x" ); #endif -#ifdef DEBUG_FORCE_DIR - if ( hCPE->hCoreCoder[0]->force_dir[0] != '\0' ) - { - dbgread( &hStereoClassif->xtalk_decision, sizeof( int16_t ), 1, fname( hCPE->hCoreCoder[0]->force_dir, "force_xtalk_decision.enf", -1, -1, -1 ) ); - } - else - { - dbgwrite( &hStereoClassif->xtalk_decision, sizeof( int16_t ), 1, 1, "res/force_xtalk_decision.enf" ); - } -#endif - return; } @@ -1018,6 +983,13 @@ void xtalk_classifier_dft( minimum( hStereoClassif->xtalk_score_buf, XTALK_SCORE_BUF_LEN, &scr_min ); maximum( hStereoClassif->xtalk_score_buf, XTALK_SCORE_BUF_LEN, &scr_max ); +#ifdef DEBUG_MODE_TD + edge = redge_detect( hStereoClassif->xtalk_score_buf, XTALK_SCORE_BUF_LEN, -0.2f, 1.0f ); + edge_0_1 = lin_interp( 1 - edge, 1.0f, 1.0f, 0.83f, 0.0f, 1 ); + dbgwrite( &score, sizeof( float ), 1, 1, "res/score.x" ); + dbgwrite( &edge_0_1, sizeof( float ), 1, 1, "res/edge_0_1.x" ); +#endif + if ( scr_min < 0.2f && scr_max > 0.0f ) { edge = redge_detect( hStereoClassif->xtalk_score_buf, XTALK_SCORE_BUF_LEN, -0.2f, 1.0f ); @@ -1028,6 +1000,7 @@ void xtalk_classifier_dft( edge_0_1 = 0.0f; } + /* weight raw score based on rising edge detector */ wedge = lin_interp( edge_0_1, 0.0f, 0.95f, 1.0f, 0.3f, 1 ); hStereoClassif->xtalk_wscore = wedge * hStereoClassif->xtalk_wscore + ( 1 - wedge ) * score; @@ -1050,28 +1023,17 @@ void xtalk_classifier_dft( hStereoClassif->xtalk_decision = 1; } - /* updates */ - hItd->prev_m1 = m1; - hItd->prev_m2 = m2; - hItd->prev_itd1 = itd; - hItd->prev_itd2 = itd2; - #ifdef DEBUG_MODE_TD dbgwrite( &hStereoClassif->xtalk_wscore, sizeof( float ), 1, 1, "res/xtalk_wscore.x" ); dbgwrite( &dec, sizeof( int16_t ), 1, 1, "res/xtalk_dec.x" ); dbgwrite( &hStereoClassif->xtalk_decision, sizeof( int16_t ), 1, 1, "res/xtalk_dec_hyst.x" ); #endif -#ifdef DEBUG_FORCE_DIR - if ( hCPE->hCoreCoder[0]->force_dir[0] != '\0' ) - { - dbgread( &hStereoClassif->xtalk_decision, sizeof( int16_t ), 1, fname( hCPE->hCoreCoder[0]->force_dir, "force_xtalk_decision.enf", -1, -1, -1 ) ); - } - else - { - dbgwrite( &hStereoClassif->xtalk_decision, sizeof( int16_t ), 1, 1, "res/force_xtalk_decision.enf" ); - } -#endif + /* updates */ + hItd->prev_m1 = m1; + hItd->prev_m2 = m2; + hItd->prev_itd1 = itd; + hItd->prev_itd2 = itd2; return; } diff --git a/lib_enc/ivas_stereo_dft_enc.c b/lib_enc/ivas_stereo_dft_enc.c index d374aef6bed2a3599be527b36480dd56696beb6f..e59dfa7c98607f6ac5ea789d39c12b3c6b720bee 100644 --- a/lib_enc/ivas_stereo_dft_enc.c +++ b/lib_enc/ivas_stereo_dft_enc.c @@ -140,11 +140,9 @@ void stereo_dft_quantize_res_gains( } #ifdef DEBUGGING -#ifndef DISABLE_DFT_STEREO_ASSERT /* the following assertions should be satisfied by the input data: */ assert( 1 - gg * gg + EPSILON >= rr * rr / 2 ); assert( gg <= 1 ); -#endif #endif gg = min( gg, 1 - EPSILON ); diff --git a/lib_enc/ivas_stereo_dft_td_itd.c b/lib_enc/ivas_stereo_dft_td_itd.c old mode 100644 new mode 100755 diff --git a/lib_enc/ivas_stereo_dmx_evs.c b/lib_enc/ivas_stereo_dmx_evs.c index edcc9f5fbca3c449e00f9fb9389fd470d0a0eadf..bf516cb97439c21daef70b57c2be26dcbd254cd5 100644 --- a/lib_enc/ivas_stereo_dmx_evs.c +++ b/lib_enc/ivas_stereo_dmx_evs.c @@ -1366,8 +1366,6 @@ void stereo_dmx_evs_enc( STEREO_DMX_EVS_PRC prev_prc; STEREO_DMX_EVS_PHA_HANDLE hPHA; - push_wmops( "stereo_dmx_evs_enc" ); - if ( is_binaural ) { /* use of is_binaural flag is to be considered */ @@ -1679,7 +1677,6 @@ void stereo_dmx_evs_enc( mvr2s( p_dmx_data, data, n_samples ); - pop_wmops(); return; } diff --git a/lib_enc/ivas_stereo_mdct_core_enc.c b/lib_enc/ivas_stereo_mdct_core_enc.c old mode 100644 new mode 100755 index 1332dbbfcc3870945c4b08b0fbc39f012c6b8e3f..5a0c175db5beb23474d2d6a72539f217a6dcc7ba --- a/lib_enc/ivas_stereo_mdct_core_enc.c +++ b/lib_enc/ivas_stereo_mdct_core_enc.c @@ -189,7 +189,15 @@ void stereo_mdct_core_enc( if ( hCPE->hCoreCoder[0]->igf ) { +#ifdef DEBUGGING + int16_t orig_mdct_stereo_mode_cmdl = hCPE->hStereoMdct->mdct_stereo_mode_cmdl; + hCPE->hStereoMdct->mdct_stereo_mode_cmdl = SMDCT_MS_DECISION; +#endif initMdctStereoEncData( hCPE->hStereoMdct, STEREO_FORMAT, IVAS_CPE_MDCT, hCPE->element_brate, hCPE->hCoreCoder[0]->bwidth, hCPE->hCoreCoder[0]->igf, hCPE->hCoreCoder[0]->hIGFEnc->igfData.igfInfo.grid, 0 ); +#ifdef DEBUGGING + hCPE->hStereoMdct->mdct_stereo_mode_cmdl = orig_mdct_stereo_mode_cmdl; +#endif + stereo_mdct_init_igf_start_band( &( hCPE->hStereoMdct->stbParamsTCX20 ), 1.0f, hCPE->hCoreCoder[0]->bwidth, hCPE->element_brate ); stereo_mdct_init_igf_start_band( &( hCPE->hStereoMdct->stbParamsTCX10 ), 0.5f, hCPE->hCoreCoder[0]->bwidth, hCPE->element_brate ); stereo_mdct_init_igf_start_band( &( hCPE->hStereoMdct->stbParamsTCX20afterACELP ), 1.25f, hCPE->hCoreCoder[0]->bwidth, hCPE->element_brate ); diff --git a/lib_enc/ivas_stereo_mdct_stereo_enc.c b/lib_enc/ivas_stereo_mdct_stereo_enc.c old mode 100644 new mode 100755 index e3ff04f86b8eca897406e1151535eadab2da4747..d97697434da3ff65ea66c67691ab0226cd639a84 --- a/lib_enc/ivas_stereo_mdct_stereo_enc.c +++ b/lib_enc/ivas_stereo_mdct_stereo_enc.c @@ -1154,6 +1154,21 @@ void initMdctStereoEncData( set_s( hStereoMdct->IGFStereoMode, -1, 2 ); +#ifdef DEBUG_FORCE_MDCT_STEREO_MODE + /*set all other members to defined states */ + hStereoMdct->fDualMono = 0; + hStereoMdct->fMSstereo = 0; + + if ( hStereoMdct->mdct_stereo_mode_cmdl == SMDCT_FORCE_LR ) + { + hStereoMdct->fDualMono = 1; + } + else if ( hStereoMdct->mdct_stereo_mode_cmdl == SMDCT_FORCE_MS ) + { + hStereoMdct->fMSstereo = 1; + } +#endif + hStereoMdct->split_ratio = SMDCT_EQUAL_RATIO_RANGE; set_s( hStereoMdct->global_ild, SMDCT_ILD_RANGE >> 1, 2 ); diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc.c index 175dedd085dee9493466513b1401624dae9b62bb..60a79ea77175adc78bb7826d2e48ca883156209c 100644 --- a/lib_enc/ivas_tcx_core_enc.c +++ b/lib_enc/ivas_tcx_core_enc.c @@ -336,10 +336,7 @@ void stereo_tcx_core_enc( } } - -#ifdef FIX_1384_MSAN_stereo_tcx_core_enc st->acelp_cfg.midLpc = 0; -#endif last_core_orig = st->last_core; for ( n = 0; n < n_subframes; n++ ) { diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 157b8ce7add41c31f99ea6a64a5b5a671ee43eef..7088abc5111e84e926f3ddde35e588a6aff336d1 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -1240,6 +1240,7 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( { st_ivas->ind_list[i].nb_bits = -1; } + #if defined( DEBUGGING ) && defined( DBG_BITSTREAM_ANALYSIS ) for ( i = 0; i < st_ivas->ivas_max_num_indices; i++ ) { @@ -1330,9 +1331,6 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( } else { -#ifdef DEBUG_MODE_INFO - dbgwrite( inputBuffer, sizeof( int16_t ), inputBufferSize, 1, strcat( fname( debug_dir, "ivas_input_dmx", 0, 1, ENC ), ".pcm" ) ); -#endif if ( ( error = evs_enc( hCoreCoder, inputBuffer, st_ivas->mem_hp20_in[0], inputBufferSize ) ) != IVAS_ERR_OK ) { return error; @@ -1468,10 +1466,6 @@ ivas_error IVAS_ENC_SetChannelAwareConfig( ivas_error IVAS_ENC_SetForcedMode( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ const IVAS_ENC_FORCED_MODE forcedMode /* i : forced coding mode */ -#ifdef DEBUG_FORCE_DIR - , - const char *forcedModeDir /* i : directory containing external binary files for modes/parameters enforcement */ -#endif ) { int16_t newForced; @@ -1483,27 +1477,6 @@ ivas_error IVAS_ENC_SetForcedMode( return error; } -#ifdef DEBUG_FORCE_DIR - hIvasEnc->st_ivas->hEncoderConfig->force_dir[0] = '\0'; - if ( forcedMode < IVAS_ENC_FORCE_FILE ) - { - if ( ( error = forcedModeApiToInternal( forcedMode, &newForced ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( hIvasEnc->st_ivas->hEncoderConfig->force != newForced ) - { - hIvasEnc->st_ivas->hEncoderConfig->force = newForced; - hIvasEnc->switchingActive = true; - } - } - else if ( forcedMode == IVAS_ENC_FORCE_DIR ) - { - strcpy( hIvasEnc->st_ivas->hEncoderConfig->force_dir, forcedModeDir ); - hIvasEnc->st_ivas->hEncoderConfig->force = IVAS_ENC_FORCE_UNFORCED; - } -#else if ( ( error = forcedModeApiToInternal( forcedMode, &newForced ) ) != IVAS_ERR_OK ) { return error; @@ -1514,7 +1487,6 @@ ivas_error IVAS_ENC_SetForcedMode( hIvasEnc->st_ivas->hEncoderConfig->force = newForced; hIvasEnc->switchingActive = true; } -#endif return IVAS_ERR_OK; } @@ -2360,11 +2332,8 @@ static ivas_error forcedModeApiToInternal( case IVAS_ENC_FORCE_GSC: *forcedModeInternal = FORCE_GSC; break; - case IVAS_ENC_FORCE_TCX10: - *forcedModeInternal = FORCE_TCX10; - break; - case IVAS_ENC_FORCE_TCX20: - *forcedModeInternal = FORCE_TCX20; + case IVAS_ENC_FORCE_TCX: + *forcedModeInternal = FORCE_TCX; break; case IVAS_ENC_FORCE_HQ: *forcedModeInternal = FORCE_HQ; diff --git a/lib_enc/lib_enc.h b/lib_enc/lib_enc.h index 567db4a9745c45c1a02ec3d62d849118c35bdcb6..af9f68e07bd1aa7715996cab1cff3119cbf7513b 100644 --- a/lib_enc/lib_enc.h +++ b/lib_enc/lib_enc.h @@ -127,13 +127,8 @@ typedef enum _IVAS_ENC_FORCED_MODE IVAS_ENC_FORCE_MUSIC, IVAS_ENC_FORCE_ACELP, IVAS_ENC_FORCE_GSC, - IVAS_ENC_FORCE_TCX10, - IVAS_ENC_FORCE_TCX20, + IVAS_ENC_FORCE_TCX, IVAS_ENC_FORCE_HQ, -#ifdef DEBUG_FORCE_DIR - IVAS_ENC_FORCE_FILE, - IVAS_ENC_FORCE_DIR, -#endif IVAS_ENC_FORCE_UNFORCED, IVAS_ENC_FORCE_UNDEFINED = 0xffff } IVAS_ENC_FORCED_MODE; @@ -334,9 +329,6 @@ ivas_error IVAS_ENC_SetChannelAwareConfig( ivas_error IVAS_ENC_SetForcedMode( IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ const IVAS_ENC_FORCED_MODE forcedMode /* i : forced coding mode */ -#ifdef DEBUG_FORCE_DIR - ,const char *forcedModeDir /* i : directory containing external binary files for modes/parameters enforcement */ -#endif ); #endif diff --git a/lib_enc/pre_proc.c b/lib_enc/pre_proc.c index 09f126c59d043befcffed51b9ce6a1c1b7c19e2f..919c2b59023dcb01b783dd0a008997bf011d1bd6 100644 --- a/lib_enc/pre_proc.c +++ b/lib_enc/pre_proc.c @@ -53,14 +53,16 @@ *--------------------------------------------------------------------*/ void pre_proc( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t input_frame, /* i : frame length */ - float old_inp_12k8[], /* i/o: buffer of old input signal */ - float old_inp_16k[], /* i/o: buffer of old input signal @ 16kHz */ - float **inp, /* o : ptr. to inp. signal in the current frame*/ - float fr_bands[2 * NB_BANDS], /* i : energy in frequency bands */ - float *ener, /* o : residual energy from Levinson-Durbin */ - int16_t pitch_orig[3], /* o : open-loop pitch values for quantization */ + Encoder_State *st, /* i/o: encoder state structure */ + const int16_t input_frame, /* i : frame length */ + float old_inp_12k8[], /* i/o: buffer of old input signal */ + float old_inp_16k[], /* i/o: buffer of old input signal @ 16kHz */ + float **inp, /* o : ptr. to inp. signal in the current frame*/ + float fr_bands[2 * NB_BANDS], /* i : energy in frequency bands */ + float *ener, /* o : residual energy from Levinson-Durbin */ +#ifndef FIX_I4_OL_PITCH + int16_t pitch_orig[3], /* o : open-loop pitch values for quantization */ +#endif float A[NB_SUBFR16k * ( M + 1 )], /* i/o: A(z) unquantized for the 4 subframes */ float Aw[NB_SUBFR16k * ( M + 1 )], /* i/o: weighted A(z) unquantized for subframes */ float epsP[M + 1], /* i/o: LP prediction errors */ @@ -849,7 +851,9 @@ void pre_proc( * ACELP/TCX20 Switching Decision *-----------------------------------------------------------------*/ +#ifndef FIX_I4_OL_PITCH mvs2s( st->pitch, pitch_orig, 3 ); +#endif if ( st->codec_mode == MODE2 ) { diff --git a/lib_enc/pvq_core_enc.c b/lib_enc/pvq_core_enc.c index 17d4dab1ea41281b1d13fe3931a89d6b766a2eab..fa2bf2b1ae08a5f9b5aa7bc5b9d44b3c842be4b9 100644 --- a/lib_enc/pvq_core_enc.c +++ b/lib_enc/pvq_core_enc.c @@ -419,12 +419,18 @@ static void densityIndexSymbolEncode( int32_t cum_freq, tot; int16_t densityPlOne, densitySubC; int16_t densitySubIndex, nearFlag; +#ifdef BASOP_NOGLOB Flag Overflow; +#endif /* BASOP_NOGLOB */ if ( ( 0xFFFE & density ) != 0 ) /* even */ { angle = atan2_fx( SQRT_DIM_fx[opp_sz], SQRT_DIM_fx[near_sz] ); +#ifndef BASOP_NOGLOB + angle = shl( angle, 1 ); +#else /* BASOP_NOGLOB */ angle = shl_o( angle, 1, &Overflow ); +#endif /* BASOP_NOGLOB */ angle = mult_r( angle, 20861 ); c = mult_r( density, angle ); diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h old mode 100644 new mode 100755 index 202d2293396454fddb21d3157f796bb9d98f3494..4d6fe1134b9949118a1002114335f8c0b140ec0a --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -1177,9 +1177,6 @@ typedef struct enc_core_structure int16_t inactive_coder_type_flag; /* inactive coder type flag (0 = AVQ / 1 = GSC) */ #ifdef DEBUGGING int16_t force; /* flag indicating specific signal type (0 = speech, 1 = music, -1 = N/A) */ -#ifdef DEBUG_FORCE_DIR - char *force_dir; /* directory containing external binary files for modes/parameters enforcement (empty string indicates no enforcement) */ -#endif #endif int16_t ini_frame; /* initialization frames counter */ diff --git a/lib_enc/swb_bwe_enc.c b/lib_enc/swb_bwe_enc.c index b35fcd97d122d388d8e57d1de64222102719e622..8157f83372462218e04d10dec4cfb25b40ff14d4 100644 --- a/lib_enc/swb_bwe_enc.c +++ b/lib_enc/swb_bwe_enc.c @@ -1795,9 +1795,11 @@ void hq_generic_hf_encoding( { Word16 tmp, frac, exp; Word32 L_tmp; +#ifdef BASOP_NOGLOB Flag Overflow; Overflow = 0; +#endif tmp = add( (int16_t) ( hq_generic_fenv[n_band] * 256 ), (int16_t) ( Mean_env[n_band] * 256 ) ); /*Q8 */ L_tmp = L_mult( tmp, 21771 ); /* 0.166096 in Q17 -> Q26 */ @@ -1808,7 +1810,11 @@ void hq_generic_hf_encoding( /* output of Pow2() will be: */ /* 16384 < Pow2() <= 32767 */ exp = sub( exp, 13 ); +#ifdef BASOP_NOGLOB tmp = shl_o( tmp, add( exp, 1 ), &Overflow ); /*Q1 */ +#else + tmp = shl( tmp, add( exp, 1 ) ); /*Q1 */ +#endif hq_generic_fenv[n_band] = (float) tmp * 0.5f; /*Q1 */ } diff --git a/lib_enc/transient_detection.c b/lib_enc/transient_detection.c index 7c169d9015a8b87adab8b1fc6f73132c22a56011..8195edc3752ef8f75268e45fa747af360d13274b 100644 --- a/lib_enc/transient_detection.c +++ b/lib_enc/transient_detection.c @@ -324,18 +324,6 @@ void SetTCXModeInfo( hTcxEnc->tcxMode = NO_TCX; } } - -#ifdef DEBUGGING - if ( st->force == FORCE_TCX10 ) - { - hTcxEnc->tcxMode = TCX_10; - } - else if ( st->force == FORCE_TCX20 ) - { - hTcxEnc->tcxMode = TCX_20; - } -#endif - /* set the left window overlap */ if ( st->last_core == ACELP_CORE || st->last_core == AMR_WB_CORE ) { diff --git a/lib_isar/isar_PredDecoder.c b/lib_isar/isar_PredDecoder.c index f547e3cb08d97c41fd43b9ea318a5962794778bc..58941d26fcca3e535582fbf24671903a30579d0c 100644 --- a/lib_isar/isar_PredDecoder.c +++ b/lib_isar/isar_PredDecoder.c @@ -39,6 +39,7 @@ #include "isar_rom_lcld_tables.h" #include "wmc_auto.h" + /*-------------------------------------------------------------------* * Function CreatePredictionDecoder() * @@ -63,6 +64,7 @@ ivas_error CreatePredictionDecoder( psPredictionDecoder->iNumBlocks = iNumBlocks; psPredictionDecoder->iNumSubSets = LCLD_BLOCKS_PER_FRAME / psPredictionDecoder->iNumBlocks; psPredictionDecoder->iSubSetId = 0; + /* PLC_IMPROVEMENT */ if ( ( psPredictionDecoder->ppiDecodingFailedPrev = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) { @@ -76,6 +78,7 @@ ivas_error CreatePredictionDecoder( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); } + for ( n = 0; n < iChannels; n++ ) { int32_t k; @@ -98,6 +101,7 @@ ivas_error CreatePredictionDecoder( psPredictionDecoder->ppiDecodingFailedPrev[n][k] = 0; } } + if ( ( psPredictionDecoder->piPredChanEnable = (int32_t *) malloc( sizeof( int32_t ) * iChannels ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); @@ -240,6 +244,7 @@ void DeletePredictionDecoder( return; } + /*-------------------------------------------------------------------* * Function ReadPredictors() * @@ -269,6 +274,7 @@ int16_t ReadPredictors( { psPredictionDecoder->iSubSetId = 0; } + for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) { psPredictionDecoder->piPredChanEnable[c] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, psPredictionDecoder->iNumSubSets ); @@ -337,7 +343,12 @@ int16_t ReadPredictors( } -/* PLC_IMPROVEMENT */ +/*-------------------------------------------------------------------* + * Function SetDecodingPassed() + * + * + *-------------------------------------------------------------------*/ + void SetDecodingPassed( PredictionDecoder *psPredictionDecoder ) { @@ -354,6 +365,12 @@ void SetDecodingPassed( } +/*-------------------------------------------------------------------* + * Function AnyDecodingUnresolved() + * + * + *-------------------------------------------------------------------*/ + int32_t AnyDecodingUnresolved( PredictionDecoder *psPredictionDecoder ) { @@ -368,15 +385,21 @@ int32_t AnyDecodingUnresolved( } } } - return 0; } +/*-------------------------------------------------------------------* + * Function UpdateDecodingFailedStatus() + * + * + *-------------------------------------------------------------------*/ + void UpdateDecodingFailedStatus( PredictionDecoder *psPredictionDecoder ) { int32_t n, ch; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) { for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) @@ -389,7 +412,14 @@ void UpdateDecodingFailedStatus( } -void UpdateDecodingUnresolved( PredictionDecoder *psPredictionDecoder ) +/*-------------------------------------------------------------------* + * Function UpdateDecodingUnresolved() + * + * + *-------------------------------------------------------------------*/ + +void UpdateDecodingUnresolved( + PredictionDecoder *psPredictionDecoder ) { int32_t n, ch; @@ -427,6 +457,7 @@ void ApplyInversePredictors( float ***pppfImag ) { int32_t c; + for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) { if ( psPredictionDecoder->piPredChanEnable[c] > 0 ) diff --git a/lib_isar/isar_PredEncoder.c b/lib_isar/isar_PredEncoder.c index 1a8426b94049857b19c57ec775a82f008db040be..4f2831254e00eb6e0028697ec61b76b932a2d8c0 100644 --- a/lib_isar/isar_PredEncoder.c +++ b/lib_isar/isar_PredEncoder.c @@ -55,6 +55,7 @@ static void activate_bit( return; } + /*-------------------------------------------------------------------* * Function deactivate_bit() * @@ -70,6 +71,13 @@ static void deactivate_bit( return; } + +/*-------------------------------------------------------------------* + * Function UpdatePredictionSubSetId() + * + * + *-------------------------------------------------------------------*/ + void UpdatePredictionSubSetId( PredictionEncoder *psPredictionEncoder ) { @@ -81,6 +89,7 @@ void UpdatePredictionSubSetId( return; } + /*-------------------------------------------------------------------* * Function CreatePredictionEncoder() * @@ -503,6 +512,8 @@ void ComputePredictors( } } } + + return; } diff --git a/lib_isar/isar_cnst.h b/lib_isar/isar_cnst.h index 88a26196aa36b780329b73d4b21c6e80e41be3df..b7065bac4cbb78325df48cf9008b212e883afae3 100644 --- a/lib_isar/isar_cnst.h +++ b/lib_isar/isar_cnst.h @@ -62,21 +62,21 @@ typedef enum } ISAR_SPLIT_REND_POSE_TYPE; -#define CLDFB_PLC_XF 2 /* Length of cross-fade into first good frame after frame loss in CLDFB cols. */ - -#define SPLIT_REND_MAX_YAW_ONLY_POSES 2 -#define SPLIT_REND_MAX_PITCH_ONLY_POSES 2 -#define SPLIT_REND_MAX_ROLL_ONLY_POSES 2 -#define SPLIT_REND_MAX_ONE_AXIS_MD_POSES 2 -#define MAX_EXTRAPOLATION_ANGLE 15.0f /* this means additional 15 degrees can be extrapolated on top of MD probing poses*/ - -#define MAX_HEAD_ROT_POSES ( 2 + SPLIT_REND_MAX_YAW_ONLY_POSES + SPLIT_REND_MAX_PITCH_ONLY_POSES + SPLIT_REND_MAX_ROLL_ONLY_POSES ) -#define MAX_SPLIT_REND_MD_BANDS 20 -#define MAX_SPLIT_MD_SUBFRAMES 1 -#define COMPLEX_MD_BAND_THRESH MAX_SPLIT_REND_MD_BANDS -#define COMPLEX_MD_BAND_THRESH_LOW 4 -#define COMPLEX_MD_BAND_THRESH_HIGH 10 -#define SPLIT_REND_RO_MD_BAND_THRESH 4 +#define CLDFB_PLC_XF 2 /* Length of cross-fade into first good frame after frame loss in CLDFB cols. */ + +#define SPLIT_REND_MAX_YAW_ONLY_POSES 2 +#define SPLIT_REND_MAX_PITCH_ONLY_POSES 2 +#define SPLIT_REND_MAX_ROLL_ONLY_POSES 2 +#define SPLIT_REND_MAX_ONE_AXIS_MD_POSES 2 +#define MAX_EXTRAPOLATION_ANGLE 15.0f /* this means additional 15 degrees can be extrapolated on top of MD probing poses*/ + +#define MAX_HEAD_ROT_POSES ( 2 + SPLIT_REND_MAX_YAW_ONLY_POSES + SPLIT_REND_MAX_PITCH_ONLY_POSES + SPLIT_REND_MAX_ROLL_ONLY_POSES ) +#define MAX_SPLIT_REND_MD_BANDS 20 +#define MAX_SPLIT_MD_SUBFRAMES 1 +#define COMPLEX_MD_BAND_THRESH MAX_SPLIT_REND_MD_BANDS +#define COMPLEX_MD_BAND_THRESH_LOW 4 +#define COMPLEX_MD_BAND_THRESH_HIGH 10 +#define SPLIT_REND_RO_MD_BAND_THRESH 4 #define ISAR_SPLIT_REND_NUM_QUANT_STRATS 4 #define ISAR_SPLIT_REND_PRED_63QUANT_PNTS 63 @@ -86,11 +86,11 @@ typedef enum #define ISAR_SPLIT_REND_PRED_MIN_VAL -1.4f #define ISAR_SPLIT_REND_PRED_MAX_VAL 1.4f -#define ISAR_SPLIT_REND_PITCH_G_MIN_VAL 0.5f -#define ISAR_SPLIT_REND_PITCH_G_MAX_VAL 1.5f -#define ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS ISAR_SPLIT_REND_D_QUANT_PNTS -#define ISAR_SPLIT_REND_D_MIN_VAL 0.0f -#define ISAR_SPLIT_REND_D_MAX_VAL 1.0f +#define ISAR_SPLIT_REND_PITCH_G_MIN_VAL 0.5f +#define ISAR_SPLIT_REND_PITCH_G_MAX_VAL 1.5f +#define ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS ISAR_SPLIT_REND_D_QUANT_PNTS +#define ISAR_SPLIT_REND_D_MIN_VAL 0.0f +#define ISAR_SPLIT_REND_D_MAX_VAL 1.0f #define ISAR_SPLIT_REND_PRED_ROLL_Q_STEP ( ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) / ( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) ) #define ISAR_SPLIT_REND_PRED_ROLL_1BYQ_STEP ( ( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) ) @@ -99,28 +99,28 @@ typedef enum #define ISAR_SPLIT_REND_PRED63_Q_STEP ( ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) / ( ISAR_SPLIT_REND_PRED_63QUANT_PNTS - 1 ) ) #define ISAR_SPLIT_REND_PRED63_1BYQ_STEP ( ( ISAR_SPLIT_REND_PRED_63QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PRED_MAX_VAL - ISAR_SPLIT_REND_PRED_MIN_VAL ) ) -#define ISAR_SPLIT_REND_D_Q_STEP ( ( ISAR_SPLIT_REND_D_MAX_VAL - ISAR_SPLIT_REND_D_MIN_VAL ) / ( ISAR_SPLIT_REND_D_QUANT_PNTS - 1 ) ) -#define ISAR_SPLIT_REND_D_1BYQ_STEP ( ( ISAR_SPLIT_REND_D_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_D_MAX_VAL - ISAR_SPLIT_REND_D_MIN_VAL ) ) -#define ISAR_SPLIT_REND_PITCH_G_Q_STEP ( ( ISAR_SPLIT_REND_PITCH_G_MAX_VAL - ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) / ( ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 ) ) -#define ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP ( ( ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PITCH_G_MAX_VAL - ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) ) +#define ISAR_SPLIT_REND_D_Q_STEP ( ( ISAR_SPLIT_REND_D_MAX_VAL - ISAR_SPLIT_REND_D_MIN_VAL ) / ( ISAR_SPLIT_REND_D_QUANT_PNTS - 1 ) ) +#define ISAR_SPLIT_REND_D_1BYQ_STEP ( ( ISAR_SPLIT_REND_D_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_D_MAX_VAL - ISAR_SPLIT_REND_D_MIN_VAL ) ) +#define ISAR_SPLIT_REND_PITCH_G_Q_STEP ( ( ISAR_SPLIT_REND_PITCH_G_MAX_VAL - ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) / ( ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 ) ) +#define ISAR_SPLIT_REND_PITCH_G_1BYQ_STEP ( ( ISAR_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 ) / ( ISAR_SPLIT_REND_PITCH_G_MAX_VAL - ISAR_SPLIT_REND_PITCH_G_MIN_VAL ) ) -#define ISAR_SPLIT_REND_HEAD_POSE_BITS 9 -#define ISAR_SPLIT_REND_DOF_BITS 2 -#define ISAR_SPLIT_REND_HQ_MODE_BITS 1 -#define ISAR_SPLIT_REND_ROT_AXIS_BITS 3 -#define ISAR_SPLIT_REND_RO_FLAG_BITS 1 +#define ISAR_SPLIT_REND_HEAD_POSE_BITS 9 +#define ISAR_SPLIT_REND_DOF_BITS 2 +#define ISAR_SPLIT_REND_HQ_MODE_BITS 1 +#define ISAR_SPLIT_REND_ROT_AXIS_BITS 3 +#define ISAR_SPLIT_REND_RO_FLAG_BITS 1 -#define ISAR_LC3PLUS_MAX_NUM_DECODERS 2 +#define ISAR_LC3PLUS_MAX_NUM_DECODERS 2 /*----------------------------------------------------------------------------------* * Split rendering bitrate constants *----------------------------------------------------------------------------------*/ -#define SPLIT_REND_256k 256000 -#define SPLIT_REND_320k 320000 -#define SPLIT_REND_384k 384000 -#define SPLIT_REND_512k 512000 -#define SPLIT_REND_768k 768000 +#define SPLIT_REND_256k 256000 +#define SPLIT_REND_320k 320000 +#define SPLIT_REND_384k 384000 +#define SPLIT_REND_512k 512000 +#define SPLIT_REND_768k 768000 /* == ISAR_MAX_SPLIT_REND_BITRATE */ #endif /*ISAR_CNST_H */ diff --git a/lib_isar/isar_lc3plus_dec.c b/lib_isar/isar_lc3plus_dec.c index 5f7d1d2cf69d9a6ec72fd5a503eea9650b95d964..0455144381e2b9cf8f8f30b55b53841dbe4a2246 100644 --- a/lib_isar/isar_lc3plus_dec.c +++ b/lib_isar/isar_lc3plus_dec.c @@ -48,8 +48,8 @@ *------------------------------------------------------------------------*/ ivas_error ISAR_LC3PLUS_DEC_Open( - const LC3PLUS_CONFIG config, /* i : LC3plus decoder configuration */ - ISAR_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */ + const LC3PLUS_CONFIG config, /* i : LC3plus decoder configuration */ + ISAR_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */ ) { LC3PLUS_Error err; @@ -71,7 +71,6 @@ ivas_error ISAR_LC3PLUS_DEC_Open( return IVAS_ERROR( IVAS_ERR_INIT_ERROR, "Maximum number of channels exceeds ISAR_LC3PLUS_MAX_NUM_DECODERS\n" ); } - ( *handle )->num_decs = 0; ( *handle )->pcm_conversion_buffer = NULL; ( *handle )->handles = NULL; @@ -129,6 +128,7 @@ ivas_error ISAR_LC3PLUS_DEC_Open( } err = lc3plus_dec_init( ( *handle )->handles[iCh], config.samplerate, 1, LC3PLUS_PLC_ADVANCED, config.high_res_mode_enabled ); + if ( LC3PLUS_OK != err ) { ISAR_LC3PLUS_DEC_Close( handle ); @@ -149,7 +149,6 @@ ivas_error ISAR_LC3PLUS_DEC_Open( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); } - ( *handle )->selective_decoding_states[iCh]->has_skipped_a_frame = 0; ( *handle )->selective_decoding_states[iCh]->shall_decode_cached_frame = 0; ( *handle )->selective_decoding_states[iCh]->frame_action = DEC_ACTION_DECODE_AND_USE; @@ -160,7 +159,9 @@ ivas_error ISAR_LC3PLUS_DEC_Open( ISAR_LC3PLUS_DEC_Close( handle ); return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); } + ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity = 400 /*LC3plus max non-HR octet count*/; + if ( ( ( *handle )->bitstream_caches[iCh]->bitstream_cache = malloc( ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity ) ) == NULL ) { ISAR_LC3PLUS_DEC_Close( handle ); @@ -203,6 +204,7 @@ ivas_error ISAR_LC3PLUS_DEC_GetDelay( { return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "ISAR_LC3PLUS_DEC_HANDLE is NULL\n" ); } + if ( NULL == delayInSamples ) { return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "delayInSamples is NULL\n" ); @@ -475,6 +477,7 @@ static ivas_error isar_LC3PLUS_DEC_Decode_or_Conceal_internal( /* reset skipping state, must be set by the user before each decode call*/ handle->selective_decoding_states[iDec]->frame_action = DEC_ACTION_DECODE_AND_USE; } /* for each dec/channel */ + return IVAS_ERR_OK; } diff --git a/lib_isar/isar_lc3plus_dec.h b/lib_isar/isar_lc3plus_dec.h index be5b22d459f5060da018d85b47005134fd05b7fc..d5cb37aaa917dfc2dc004a1ca7b64a6ad6eb3d20 100644 --- a/lib_isar/isar_lc3plus_dec.h +++ b/lib_isar/isar_lc3plus_dec.h @@ -78,7 +78,7 @@ typedef struct ISAR_LC3PLUS_DEC_HANDLE } * ISAR_LC3PLUS_DEC_HANDLE; ivas_error ISAR_LC3PLUS_DEC_Open( - const LC3PLUS_CONFIG config, /* i : decoder configuration */ + const LC3PLUS_CONFIG config, /* i : decoder configuration */ ISAR_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */ ); diff --git a/lib_isar/isar_lc3plus_enc.c b/lib_isar/isar_lc3plus_enc.c index 707dcda003463e02d49c1118c09ddc386e2827b9..4be070b95778c1be5796d5a6a5d434d40d3b556d 100644 --- a/lib_isar/isar_lc3plus_enc.c +++ b/lib_isar/isar_lc3plus_enc.c @@ -40,8 +40,9 @@ static const LC3PLUS_RTP_FDL s_fdl_request = LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA; -static int32_t limit_per_channel_bitrate( LC3PLUS_CONFIG config, - int32_t per_channel_bitrate ) +static int32_t limit_per_channel_bitrate( + LC3PLUS_CONFIG config, + const int32_t per_channel_bitrate ) { if ( config.high_res_mode_enabled ) { @@ -77,6 +78,7 @@ static int32_t limit_per_channel_bitrate( LC3PLUS_CONFIG config, return -1; } + /*-------------------------------------------------------------------* * Function ISAR_LC3PLUS_ENC_Open() * @@ -103,6 +105,7 @@ ivas_error ISAR_LC3PLUS_ENC_Open( { return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid number of channels\n" ); } + if ( config.lc3plus_frame_duration_us != 2500 && config.lc3plus_frame_duration_us != 5000 && config.lc3plus_frame_duration_us != 10000 ) { return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid lc3plus_frame_duration_us\n" ); @@ -111,6 +114,7 @@ ivas_error ISAR_LC3PLUS_ENC_Open( { return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid isar_frame_duration_us\n" ); } + encoder_size = lc3plus_enc_get_size( config.samplerate, 1 ); if ( 0 == encoder_size ) { @@ -121,6 +125,7 @@ ivas_error ISAR_LC3PLUS_ENC_Open( { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); } + ( *handle )->config = config; ( *handle )->frame_type_descriptors = NULL; @@ -137,6 +142,7 @@ ivas_error ISAR_LC3PLUS_ENC_Open( ( *handle )->handles[i] = NULL; } ( *handle )->num_encs = config.channels; + num_lc3plus_media_times_per_ivas_frame = config.isar_frame_duration_us / config.lc3plus_frame_duration_us; ( *handle )->fdl_request = s_fdl_request; ( *handle )->num_ftds = config.channels * num_lc3plus_media_times_per_ivas_frame; @@ -189,7 +195,9 @@ ivas_error ISAR_LC3PLUS_ENC_Open( for ( uint32_t iEnc = 0; iEnc < ( *handle )->num_encs; ++iEnc ) { int32_t ftd_index = iEnc + iMediaTime * ( *handle )->num_encs; + ( *handle )->frame_type_descriptors[ftd_index].frame_data_length = 0; /* will be set to the correct value in IVAS_LC3PLUS_ENC_SetBitrate */ + if ( 0 != LC3PLUS_RTP_ftd_bwr_from_samplerate( &( *handle )->frame_type_descriptors[ftd_index].bwr, config.samplerate, config.high_res_mode_enabled ) ) { ISAR_LC3PLUS_ENC_Close( handle ); @@ -232,6 +240,7 @@ ivas_error ISAR_LC3PLUS_ENC_Open( ISAR_LC3PLUS_ENC_Close( handle ); return ivas_err; } + return IVAS_ERR_OK; } @@ -278,10 +287,12 @@ ivas_error IVAS_LC3PLUS_ENC_SetBitrate( } minPayloadOverhead = fdrLength + ( numSubframes * LC3PLUS_RTP_FTD_MIN_SIZE ); targetLc3PlusBitratePerChannel = ( availableOctetsPerIsarFrame - minPayloadOverhead ) / handle->config.channels * 8 * lc3plusPacketRate / numLc3plusMediaTimesPerIvasFrame; + if ( targetLc3PlusBitratePerChannel <= 0 ) { return IVAS_ERROR( IVAS_ERR_LC3PLUS_INVALID_BITRATE, "available LC3plus bitrate <= 0\n" ); } + targetLc3PlusBitratePerChannel = limit_per_channel_bitrate( handle->config, targetLc3PlusBitratePerChannel ); targetLc3PlusOctetCount = targetLc3PlusBitratePerChannel / 8 / lc3plusPacketRate; /* check resulting octet count. If it requires larger than 1-byte length fields, decrease the bitrate by enough to make room for the additional length field */ @@ -304,7 +315,7 @@ ivas_error IVAS_LC3PLUS_ENC_SetBitrate( } } - // update FTD settings after bitrate change + /* update FTD settings after bitrate change */ for ( int32_t iMediaTime = 0; iMediaTime < numLc3plusMediaTimesPerIvasFrame; ++iMediaTime ) { for ( uint32_t iEnc = 0; iEnc < handle->num_encs; ++iEnc ) @@ -392,6 +403,7 @@ ivas_error ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( int32_t iMediaTime; int32_t ftd_frame_data_length_size, lc3plus_frame_data_length; int32_t ftd_index; + if ( NULL == handle ) { return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); @@ -411,6 +423,7 @@ ivas_error ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( } num_lc3plus_media_times_per_ivas_frame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; + *bsSize = 0; int32_t fdl_request_length; rtp_err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, handle->fdl_request ); @@ -419,13 +432,16 @@ ivas_error ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid LC3plus frame_data_length request\n" ); } *bsSize += fdl_request_length; + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) { if ( NULL == handle->handles[iEnc] ) { return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus encoder handle is NULL\n" ); } + lc3plus_frame_data_length = lc3plus_enc_get_num_bytes( handle->handles[iEnc] ); + for ( iMediaTime = 0; iMediaTime < num_lc3plus_media_times_per_ivas_frame; ++iMediaTime ) { ftd_index = iEnc + iMediaTime * handle->num_encs; @@ -462,10 +478,12 @@ void ISAR_LC3PLUS_ENC_Close( { return; } + if ( NULL != ( *handle )->frame_type_descriptors ) { free( ( *handle )->frame_type_descriptors ); } + for ( uint32_t iEnc = 0; iEnc < ( *handle )->num_encs; iEnc++ ) { if ( NULL != ( *handle )->handles[iEnc] ) @@ -474,6 +492,7 @@ void ISAR_LC3PLUS_ENC_Close( free( ( *handle )->handles[iEnc] ); } } + if ( NULL != ( *handle )->pcm_conversion_buffer ) { free( ( *handle )->pcm_conversion_buffer ); @@ -528,6 +547,7 @@ ivas_error ISAR_LC3PLUS_ENC_Encode( { return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); } + num_media_times = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; numSamplesPerLC3plusChannel = handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / num_media_times; @@ -537,7 +557,6 @@ ivas_error ISAR_LC3PLUS_ENC_Encode( { return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( rtpErr ), "LC3PLUS_RTP_payload_serialize failed\n" ); } - for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) { for ( uint32_t iMediaTime = 0; iMediaTime < num_media_times; iMediaTime++ ) @@ -553,14 +572,17 @@ ivas_error ISAR_LC3PLUS_ENC_Encode( push_wmops( "lc3plus_enc16" ); err = lc3plus_enc16( handle->handles[iEnc], &handle->pcm_conversion_buffer, handle->frame_type_descriptors[ftdIndex].frame_data, &num_bytes, NULL ); pop_wmops(); + if ( err != LC3PLUS_OK ) { return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc16 failed\n" ); } + if ( 0 == num_bytes ) { return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc16 did not produce output\n" ); } + if ( num_bytes != (int32_t) handle->frame_type_descriptors[ftdIndex].frame_data_length ) { return IVAS_ERROR( IVAS_ERR_INTERNAL, "payload format and lc3plus enc bitrate are not aligned\n" ); diff --git a/lib_isar/isar_lc3plus_payload.c b/lib_isar/isar_lc3plus_payload.c index 2493aa6a30eb9ca3ab8f493dc1dad4e057666b98..a7f74e049367e178931bdb0e84081c9b88ee1d8d 100644 --- a/lib_isar/isar_lc3plus_payload.c +++ b/lib_isar/isar_lc3plus_payload.c @@ -36,7 +36,14 @@ #include "isar_lc3plus_payload.h" #include "options.h" -static LC3PLUS_RTP_ERR s_frame_duration_ms_from_fdi( int32_t *frame_duration_us, const LC3PLUS_RTP_FTD_FDI fdi ) + +/*------------------------------------------------------------------------- + * Local functions + *------------------------------------------------------------------------*/ + +static LC3PLUS_RTP_ERR s_frame_duration_ms_from_fdi( + int32_t *frame_duration_us, + const LC3PLUS_RTP_FTD_FDI fdi ) { if ( NULL == frame_duration_us ) { @@ -57,10 +64,14 @@ static LC3PLUS_RTP_ERR s_frame_duration_ms_from_fdi( int32_t *frame_duration_us, default: return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; } + return LC3PLUS_RTP_ERR_NO_ERROR; } -static LC3PLUS_RTP_ERR s_sampling_rate_hz_from_bwr( int32_t *sample_rate_hz, const LC3PLUS_RTP_FTD_BWR bwr ) + +static LC3PLUS_RTP_ERR s_sampling_rate_hz_from_bwr( + int32_t *sample_rate_hz, + const LC3PLUS_RTP_FTD_BWR bwr ) { if ( NULL == sample_rate_hz ) { @@ -95,10 +106,14 @@ static LC3PLUS_RTP_ERR s_sampling_rate_hz_from_bwr( int32_t *sample_rate_hz, con default: return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; } + return LC3PLUS_RTP_ERR_NO_ERROR; } -static LC3PLUS_RTP_ERR s_high_resolution_flag_from_bwr( int16_t *high_resolution_flag, const LC3PLUS_RTP_FTD_BWR bwr ) + +static LC3PLUS_RTP_ERR s_high_resolution_flag_from_bwr( + int16_t *high_resolution_flag, + const LC3PLUS_RTP_FTD_BWR bwr ) { if ( NULL == high_resolution_flag ) { @@ -133,10 +148,20 @@ static LC3PLUS_RTP_ERR s_high_resolution_flag_from_bwr( int16_t *high_resolution default: return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; } + return LC3PLUS_RTP_ERR_NO_ERROR; } -LC3PLUS_RTP_ERR LC3PLUS_RTP_frame_data_length_get_size( int32_t *length, const LC3PLUS_RTP_FDL frameDataLengthValue ) + +/*------------------------------------------------------------------------- + * LC3PLUS_RTP_frame_data_length_get_size() + * + * + *------------------------------------------------------------------------*/ + +LC3PLUS_RTP_ERR LC3PLUS_RTP_frame_data_length_get_size( + int32_t *length, + const LC3PLUS_RTP_FDL frameDataLengthValue ) { if ( frameDataLengthValue == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || frameDataLengthValue == LC3PLUS_RTP_FDL_SPEECH_BAD || frameDataLengthValue == LC3PLUS_RTP_FDL_SPEECH_SID ) { @@ -158,10 +183,14 @@ LC3PLUS_RTP_ERR LC3PLUS_RTP_frame_data_length_get_size( int32_t *length, const L { return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; } + return LC3PLUS_RTP_ERR_NO_ERROR; } -static LC3PLUS_RTP_ERR s_frame_data_length_pack( const LC3PLUS_RTP_FDL frameDataLengthValue, uint8_t *dst ) + +static LC3PLUS_RTP_ERR s_frame_data_length_pack( + const LC3PLUS_RTP_FDL frameDataLengthValue, + uint8_t *dst ) { int32_t frame_data_length_size; LC3PLUS_RTP_ERR err; @@ -193,41 +222,56 @@ static LC3PLUS_RTP_ERR s_frame_data_length_pack( const LC3PLUS_RTP_FDL frameData *dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE; *dst = frameDataLengthValueToWrite >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE; } + return LC3PLUS_RTP_ERR_NO_ERROR; } -static int32_t s_get_size_from_fdl( const LC3PLUS_RTP_FDL fdl ) + +static int32_t s_get_size_from_fdl( + const LC3PLUS_RTP_FDL fdl ) { if ( fdl >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && fdl <= LC3PLUS_RTP_FDL_LENGTH_3_MAX ) { return fdl; } + return 0; } -static bool s_fdl_is_magic_value( const LC3PLUS_RTP_FDL fdl ) + +static bool s_fdl_is_magic_value( + const LC3PLUS_RTP_FDL fdl ) { if ( fdl == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || fdl == LC3PLUS_RTP_FDL_SPEECH_SID || fdl == LC3PLUS_RTP_FDL_SPEECH_BAD ) { return true; } + return false; } -static bool s_fdl_value_is_valid_request( const LC3PLUS_RTP_FDL fdl_request ) + +static bool s_fdl_value_is_valid_request( + const LC3PLUS_RTP_FDL fdl_request ) { /* LC3PLUS_RTP_FDL_SPEECH_SID && LC3PLUS_RTP_FDL_SPEECH_SID are not valid values for the FDL request */ if ( fdl_request == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || ( fdl_request >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && fdl_request <= LC3PLUS_RTP_FDL_LENGTH_3_MAX ) ) { return true; } + return false; } -static LC3PLUS_RTP_ERR s_frame_data_length_parse( LC3PLUS_RTP_FDL *frame_data_length_value, const uint8_t *src, const size_t remaining_capacity ) + +static LC3PLUS_RTP_ERR s_frame_data_length_parse( + LC3PLUS_RTP_FDL *frame_data_length_value, + const uint8_t *src, + const size_t remaining_capacity ) { int32_t frame_data_length_size; LC3PLUS_RTP_ERR err; + if ( NULL == src || NULL == frame_data_length_value || remaining_capacity < 1 ) { return LC3PLUS_RTP_ERR_NULL_PTR; @@ -256,14 +300,21 @@ static LC3PLUS_RTP_ERR s_frame_data_length_parse( LC3PLUS_RTP_FDL *frame_data_le { return err; } + return LC3PLUS_RTP_ERR_NO_ERROR; } -static LC3PLUS_RTP_ERR s_parse_ftd( const uint8_t *p_read, LC3PLUS_RTP_FTD *receiver_ftd, int32_t *num_bytes_read, const size_t remaining_capacity ) + +static LC3PLUS_RTP_ERR s_parse_ftd( + const uint8_t *p_read, + LC3PLUS_RTP_FTD *receiver_ftd, + int32_t *num_bytes_read, + const size_t remaining_capacity ) { int32_t frame_data_block_size; LC3PLUS_RTP_FDL fdl; LC3PLUS_RTP_ERR err; + if ( NULL == p_read || NULL == receiver_ftd || NULL == num_bytes_read || remaining_capacity < LC3PLUS_RTP_FTD_MIN_SIZE ) { return LC3PLUS_RTP_ERR_NULL_PTR; @@ -296,9 +347,17 @@ static LC3PLUS_RTP_ERR s_parse_ftd( const uint8_t *p_read, LC3PLUS_RTP_FTD *rece return err; } *num_bytes_read += length_field_size; + return LC3PLUS_RTP_ERR_NO_ERROR; } + +/*------------------------------------------------------------------------- + * LC3PLUS_RTP_payload_serialize() + * + * + *------------------------------------------------------------------------*/ + LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_serialize( uint8_t *serialized_buffer, const size_t serialized_buffer_capacity, @@ -395,9 +454,11 @@ LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_serialize( } *packed_buffer_actual_size = bytes_written + lc3plus_frame_size_sum; assert( *packed_buffer_actual_size <= serialized_buffer_capacity ); + return LC3PLUS_RTP_ERR_NO_ERROR; } + static LC3PLUS_RTP_ERR s_ftds_parse( LC3PLUS_RTP_FTD *receiver_ftds, const int32_t receiver_ftds_num_max, @@ -426,6 +487,7 @@ static LC3PLUS_RTP_ERR s_ftds_parse( { return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; } + { int32_t num_bytes_read_sum = 0; const int32_t min_num_bytes_per_ftd = 2; @@ -519,9 +581,17 @@ static LC3PLUS_RTP_ERR s_ftds_parse( p_read++; } } + return LC3PLUS_RTP_ERR_NO_ERROR; } + +/*------------------------------------------------------------------------- + * LC3PLUS_RTP_payload_deserialize() + * + * + *------------------------------------------------------------------------*/ + LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_deserialize( LC3PLUS_RTP_PAYLOAD *payload, uint8_t *serialized_buffer, @@ -722,10 +792,21 @@ LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_deserialize( { return LC3PLUS_RTP_ERR_GENERIC_ERROR; } + return LC3PLUS_RTP_ERR_NO_ERROR; } -LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_bwr_from_samplerate( LC3PLUS_RTP_FTD_BWR *bwr, const int32_t sampling_rate, const int32_t high_res_enabled ) + +/*------------------------------------------------------------------------- + * LC3PLUS_RTP_ftd_bwr_from_samplerate() + * + * + *------------------------------------------------------------------------*/ + +LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_bwr_from_samplerate( + LC3PLUS_RTP_FTD_BWR *bwr, + const int32_t sampling_rate, + const int32_t high_res_enabled ) { if ( NULL == bwr ) { @@ -793,7 +874,16 @@ LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_bwr_from_samplerate( LC3PLUS_RTP_FTD_BWR *bwr, c return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; } -LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( LC3PLUS_RTP_FTD_FDI *fdi, const int32_t frame_duration_us ) + +/*------------------------------------------------------------------------- + * LC3PLUS_RTP_ftd_fdi_from_frame_duration_us() + * + * + *------------------------------------------------------------------------*/ + +LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( + LC3PLUS_RTP_FTD_FDI *fdi, + const int32_t frame_duration_us ) { if ( NULL == fdi ) { diff --git a/lib_isar/isar_lcld_decoder.c b/lib_isar/isar_lcld_decoder.c index deca0167a1a7c0be7f2051f92859e2b8ebe12bd2..8d6931541fb0319ba9f8e0cab9dd67077a3e5583 100644 --- a/lib_isar/isar_lcld_decoder.c +++ b/lib_isar/isar_lcld_decoder.c @@ -59,6 +59,7 @@ typedef struct TableNode int32_t *piDifference; int32_t *piLength; } TableNode; + typedef struct TableList { TableNode *poOrderedTop; @@ -101,28 +102,41 @@ struct LCLD_DECODER PredictionDecoder *psPredictionDecoder; - NoiseGen *psNoiseGen; }; + +/*------------------------------------------------------------------------------------------* + * Local functions declarations + *------------------------------------------------------------------------------------------*/ + static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, const int32_t num, const uint16_t ( *ppuiEncTable )[2], const int32_t iSize, const int32_t iReadLength, uint32_t *iTables ); + static TableNode *CreateTableList( const int32_t iReadLength ); + static void DeleteTableList( TableList *ptable_list, int32_t iTables ); + static TableNode *GetNextTable( const int32_t iIndex, TableList *table_list, TableNode *poParent, const int32_t iReadLength, uint32_t *iTablesCreated ); + static void AddcodeTableList( TableList *ptable_list, const int32_t iLength, const int32_t iCode, const int32_t iCodeIndex, const int32_t iReadLength, uint32_t *iTables ); + static void CompleteTables( LCLDDecoder *psLCLDDecoder, const int32_t n, TableList *ptable_list, const int32_t iReadLength, const int32_t iTablesCreated ); +/*------------------------------------------------------------------------------------------* + * Local functions + *------------------------------------------------------------------------------------------*/ + static TableNode *CreateTableList( const int32_t iReadLength ) { int32_t n; int32_t iMaxTables; TableNode *ptable_top; + iMaxTables = 1 << iReadLength; ptable_top = (TableNode *) malloc( sizeof( TableNode ) ); - ptable_top->ppoNextTable = - (TableNode **) malloc( iMaxTables * sizeof( TableNode * ) ); + ptable_top->ppoNextTable = (TableNode **) malloc( iMaxTables * sizeof( TableNode * ) ); ptable_top->piCodeIndex = (int32_t *) malloc( iMaxTables * sizeof( int32_t ) ); ptable_top->piDifference = (int32_t *) malloc( iMaxTables * sizeof( int32_t ) ); ptable_top->piLength = (int32_t *) malloc( iMaxTables * sizeof( int32_t ) ); @@ -146,9 +160,8 @@ static void DeleteTableList( TableNode *node; node = ptable_list->poOrderedTop; - while ( ( iTables ) ) + while ( iTables ) { - TableNode *node1 = node; node = node1->poOrderedNext; if ( node1->piCodeIndex != NULL ) @@ -218,14 +231,12 @@ static void CompleteTables( const int32_t iReadLength, const int32_t iTablesCreated ) { - int32_t iMaxTables; int32_t j; TableNode *poNode; iMaxTables = 1 << iReadLength; - psLCLDDecoder->c_apauiHuffDecTable_RAM[n] = - malloc( iTablesCreated * iMaxTables * sizeof( uint32_t ) ); + psLCLDDecoder->c_apauiHuffDecTable_RAM[n] = malloc( iTablesCreated * iMaxTables * sizeof( uint32_t ) ); poNode = ptable_list->poOrderedTop; for ( j = 0; j < iTablesCreated; j++ ) @@ -263,8 +274,8 @@ static void AddcodeTableList( int32_t iIndex; int32_t iCodeLow; int32_t iCodeHigh; - TableNode *poNode; + poNode = ptable_list->poOrderedTop; iMask = ( 1 << iReadLength ) - 1; iCurrentLength = iLength; @@ -304,12 +315,13 @@ static void CreateDecodeTable( int32_t n; uint32_t **ppsort_enc_table; TableList *ptable_list; + ptable_list = (TableList *) malloc( sizeof( TableList ) ); ppsort_enc_table = (uint32_t **) malloc( iSize * sizeof( int32_t * ) ); + for ( n = 0; n < iSize; n++ ) { - ppsort_enc_table[n] = (uint32_t *) malloc( 3 * sizeof( int32_t ) ); ppsort_enc_table[n][0] = (uint32_t) ppuiEncTable[n][0]; ppsort_enc_table[n][1] = (uint32_t) ppuiEncTable[n][1]; @@ -743,6 +755,7 @@ void DeleteLCLDDecoder( return; } + /*------------------------------------------------------------------------------------------* * Local function declarations * @@ -768,15 +781,24 @@ static int32_t ReadHuff( const uint32_t ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZ static int32_t ReadRMSEnvelope( const int32_t iChannels, const int32_t *piNumGroups, const int32_t iNumBands, int32_t ***pppiRMSEnvelope, ISAR_SPLIT_REND_BITS_HANDLE pBits ); static int32_t ReadAllocInformation( int32_t *piAllocOffset, ISAR_SPLIT_REND_BITS_HANDLE pBits ); + static int32_t ReadLCLDData( const int32_t *piNumGroups, int32_t **ppiGroupLengths, const int32_t iNumBands, const int32_t iNumChannels, int32_t **ppiDecodingUnresolved, int32_t **ppiPredEnable, const int32_t iNumSubSets, const int32_t iSubSetId, int32_t ***pppiAlloc, int32_t ***pppiSignReal, int32_t ***pppiSignImag, int32_t ***pppiQReal, int32_t ***pppiQImag, int32_t **ppiDecodingFailed, ISAR_SPLIT_REND_BITS_HANDLE pBits, uint32_t ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] ); + static void ComputeAllocation( const int32_t iChannels, const int32_t *piNumGroups, const int32_t iNumBands, int32_t ***pppiSMR, const int32_t iAllocOffset, int32_t ***pppiAlloc ); +/*------------------------------------------------------------------------------------------* + * function LSetDecodingUnresolved() + * + * + *------------------------------------------------------------------------------------------*/ + void SetDecodingUnresolved( LCLDDecoder *psLCLDDecoder ) { int32_t n, ch; PredictionDecoder *psPredictionDecoder = psLCLDDecoder->psPredictionDecoder; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) { for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) @@ -791,11 +813,18 @@ void SetDecodingUnresolved( } +/*------------------------------------------------------------------------------------------* + * function AnyDecodingFailedPrev() + * + * + *------------------------------------------------------------------------------------------*/ + int16_t AnyDecodingFailedPrev( LCLDDecoder *psLCLDDecoder ) { int32_t n, ch; PredictionDecoder *psPredictionDecoder = psLCLDDecoder->psPredictionDecoder; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) { for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) @@ -806,13 +835,22 @@ int16_t AnyDecodingFailedPrev( } } } + return 0; } -int16_t AnyDecodingFailed( LCLDDecoder *psLCLDDecoder ) +/*------------------------------------------------------------------------------------------* + * function AnyDecodingFailed() + * + * + *------------------------------------------------------------------------------------------*/ + +int16_t AnyDecodingFailed( + LCLDDecoder *psLCLDDecoder ) { int32_t n, ch; PredictionDecoder *psPredictionDecoder = psLCLDDecoder->psPredictionDecoder; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) { for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) @@ -828,19 +866,38 @@ int16_t AnyDecodingFailed( LCLDDecoder *psLCLDDecoder ) } +/*------------------------------------------------------------------------------------------* + * function GetDecodingFailedStatus() + * + * + *------------------------------------------------------------------------------------------*/ + int32_t **GetDecodingFailedStatus( LCLDDecoder *psLCLDDecoder ) { return psLCLDDecoder->psPredictionDecoder->ppiDecodingFailed; } -int16_t GetNumSubSets( LCLDDecoder *psLCLDDecoder ) + +/*------------------------------------------------------------------------------------------* + * function GetNumSubSets() + * + * + *------------------------------------------------------------------------------------------*/ + +int16_t GetNumSubSets( + LCLDDecoder *psLCLDDecoder ) { - return (int16_t) - psLCLDDecoder->psPredictionDecoder->iNumSubSets; + return (int16_t) psLCLDDecoder->psPredictionDecoder->iNumSubSets; } +/*------------------------------------------------------------------------------------------* + * function GetDecodingFailedPrevStatus() + * + * + *------------------------------------------------------------------------------------------*/ + int32_t **GetDecodingFailedPrevStatus( LCLDDecoder *psLCLDDecoder ) { @@ -848,6 +905,12 @@ int32_t **GetDecodingFailedPrevStatus( } +/*------------------------------------------------------------------------------------------* + * function UnpackReal() + * + * + *------------------------------------------------------------------------------------------*/ + static void UnpackReal( const int32_t iChannels, const int32_t iNumBlocks, @@ -871,8 +934,11 @@ static void UnpackReal( } } } + + return; } + /*------------------------------------------------------------------------------------------* * Function DecodeLCLDFrame() * @@ -881,7 +947,7 @@ static void UnpackReal( int32_t DecodeLCLDFrame( LCLDDecoder *psLCLDDecoder, - ISAR_SPLIT_REND_BITS_HANDLE pBits, + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ float ***pppfLCLDReal, float ***pppfLCLDImag ) { @@ -902,7 +968,6 @@ int32_t DecodeLCLDFrame( ReadRMSEnvelope( psLCLDDecoder->iChannels, (const int32_t *) psLCLDDecoder->piNumGroups, psLCLDDecoder->iNumBands, psLCLDDecoder->pppiRMSEnvelope, pBits ); - ReadAllocInformation( &psLCLDDecoder->iAllocOffset, pBits ); if ( psLCLDDecoder->iChannels == 2 && psLCLDDecoder->iCommonGrouping == 1 ) @@ -1060,6 +1125,7 @@ static void ApplyRMSEnvelope( return; } + static void ReplaceSign( const int32_t iNumBlocks, const int32_t iNumLCLDBands, @@ -1192,6 +1258,7 @@ static void InvMSCoding( int32_t n; int32_t phaseIdx; float fPred; + phaseIdx = piLRPhaseDiffs[bMSPred] - PHASE_MIN_VAL; fPred = dequantPred( piMSPredCoefs[bMSPred] ); for ( n = 0; n < piBandwidths[b]; n++ ) @@ -1240,7 +1307,6 @@ static void InvMSCoding( } -/* Currently only the number of bands in frame */ static int32_t ReadHeaderInformation( int32_t *piNumBands, ISAR_SPLIT_REND_BITS_HANDLE pBits ) @@ -1322,7 +1388,9 @@ static int32_t ReadMSInformation( } } } + anyNonZero = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + if ( anyNonZero ) { piLRPhaseDiffs[0] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, PHASE_BAND0_BITS ); @@ -1343,7 +1411,9 @@ static int32_t ReadMSInformation( piLRPhaseDiffs[n] = 0; } } + anyNonZero = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + if ( anyNonZero ) { piMSPredCoefs[0] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, PRED_BAND0_BITS ); @@ -1381,6 +1451,7 @@ static int32_t ReadMSInformation( return iBitsRead; } + static int32_t ReadGroupInformation( const int32_t iChannels, const int32_t iNumBlocks, @@ -1583,6 +1654,7 @@ static int32_t ReadAllocInformation( return iBitsRead; } + static int32_t ReadLCLDData( const int32_t *piNumGroups, int32_t **ppiGroupLengths, @@ -1741,6 +1813,7 @@ static int32_t ReadLCLDData( return iBitsRead; } + static void ComputeAllocation( const int32_t iChannels, const int32_t *piNumGroups, diff --git a/lib_isar/isar_lcld_encoder.c b/lib_isar/isar_lcld_encoder.c index b4710f0a40eadccf9ba95b570aee1e490a355990..fdf0bee4e72e9b90c4e47a32490d13754814b662 100644 --- a/lib_isar/isar_lcld_encoder.c +++ b/lib_isar/isar_lcld_encoder.c @@ -79,10 +79,10 @@ struct LCLD_ENCODER int32_t ***pppiQLCLDReal; int32_t ***pppiQLCLDImag; - PredictionEncoder *psPredictionEncoder; }; + /*------------------------------------------------------------------------------------------* * Function Quantize() * @@ -96,6 +96,7 @@ static int32_t Quantize( const int32_t iMaxVal ) { int32_t iVal; + if ( fVal > 0.0f ) { iVal = (int32_t) ( fScale * fVal + 0.5f ); @@ -111,6 +112,7 @@ static int32_t Quantize( return iVal; } + /*------------------------------------------------------------------------------------------* * Function UnQuantize() * @@ -123,6 +125,7 @@ static float UnQuantize( const int32_t iSign ) { float fVal; + if ( iSign == 0 ) { fVal = fScale * (float) iVal; @@ -131,9 +134,11 @@ static float UnQuantize( { fVal = -fScale * (float) iVal; } + return fVal; } + static void PackReal( const int32_t iChannels, const int32_t iNumBlocks, @@ -141,6 +146,7 @@ static void PackReal( float ***pppfImag ) { int32_t ch, b, n; + for ( ch = 0; ch < iChannels; ch++ ) { for ( b = 0; b < LCLD_BANDS; b++ ) @@ -154,6 +160,8 @@ static void PackReal( } } } + + return; } /*------------------------------------------------------------------------------------------* @@ -207,6 +215,7 @@ ivas_error CreateLCLDEncoder( psLCLDEncoder->iNumBlocks = iNumBlocks; } psLCLDEncoder->iMSMode = 0; + if ( ( psLCLDEncoder->piMSFlags = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); @@ -251,7 +260,6 @@ ivas_error CreateLCLDEncoder( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - if ( ( psLCLDEncoder->pppiLCLDSignReal = (int32_t ***) malloc( psLCLDEncoder->iChannels * sizeof( int32_t ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); @@ -272,7 +280,6 @@ ivas_error CreateLCLDEncoder( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); } - for ( n = 0; n < iChannels; n++ ) { int32_t k; @@ -415,6 +422,7 @@ void DeleteLCLDEncoder( } free( psLCLDEncoder->ppiGroupLengths ); } + if ( psLCLDEncoder->pppiRMSEnvelope != NULL ) { for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) @@ -526,6 +534,7 @@ void DeleteLCLDEncoder( return; } + /*------------------------------------------------------------------------------------------* * Local function declarations *------------------------------------------------------------------------------------------*/ @@ -550,6 +559,7 @@ static int32_t WriteLCLDData( const int32_t *piNumGroups, int32_t **ppiGroupLeng static int32_t ComputeAllocation( const int32_t iChannels, const int32_t *piNumGroups, int32_t **ppiGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, float ***pppfReal, float ***pppfImag, int32_t ***pppiSMR, const int32_t iAvailableBits, int32_t *piAllocOffset, int32_t ***pppiAlloc, int32_t ***pppiQReal, int32_t ***pppiQImag, int32_t ***pppiSignReal, int32_t ***pppiSignImag, PredictionEncoder *psPredictionEncoder ); + /*------------------------------------------------------------------------------------------* * Function EncodeLCLDFrame() * @@ -564,7 +574,7 @@ int32_t EncodeLCLDFrame( const int32_t available_bits, ISAR_SPLIT_REND_BITS_HANDLE pBits ) { - int32_t n; + int32_t k, n; int32_t iAvailableBits, iBitsWritten; int32_t iNumMSBands = 0; int32_t iAudioBitsWritten; @@ -599,7 +609,6 @@ int32_t EncodeLCLDFrame( } } - /* Compute Grouping and RMS Envelopes */ if ( psLCLDEncoder->iChannels == 2 && psLCLDEncoder->iCommonGrouping == 1 ) { @@ -661,17 +670,14 @@ int32_t EncodeLCLDFrame( pBits ); } - iBitsWritten += WritePredictors( psLCLDEncoder->psPredictionEncoder, pBits ); iBitsWritten += WriteGroupInformation( psLCLDEncoder->iChannels, psLCLDEncoder->iCommonGrouping, (const int32_t *) psLCLDEncoder->piNumGroups, psLCLDEncoder->ppiGroupLengths, pBits ); iBitsWritten += WriteRMSEnvelope( psLCLDEncoder->iChannels, (const int32_t *) psLCLDEncoder->piNumGroups, psLCLDEncoder->iNumBands, psLCLDEncoder->pppiRMSEnvelope, pBits ); - if ( psLCLDEncoder->iChannels == 2 && psLCLDEncoder->iCommonGrouping == 1 ) { - int32_t k; for ( k = 0; k < psLCLDEncoder->piNumGroups[0]; k++ ) { PerceptualModelStereo( psLCLDEncoder->iNumBands, @@ -688,7 +694,6 @@ int32_t EncodeLCLDFrame( { for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) { - int32_t k; for ( k = 0; k < psLCLDEncoder->piNumGroups[n]; k++ ) { PerceptualModel( psLCLDEncoder->iNumBands, @@ -712,6 +717,7 @@ int32_t EncodeLCLDFrame( fprintf( fid, "%d %d\n", psLCLDEncoder->psPredictionEncoder->iSubSetId, psLCLDEncoder->psPredictionEncoder->piPredChanEnable[n] ); } #endif + iAvailableBits -= iBitsWritten; ComputeAllocation( psLCLDEncoder->iChannels, (const int32_t *) psLCLDEncoder->piNumGroups, @@ -1035,6 +1041,7 @@ static int32_t MSModeCalculation( fprintf( fid, "%d %d %d %d %d\n", iMsInfoBits, piMsPredInfoBits[MS_PHASE_AND_PRED], piMsPredInfoBits[MS_PRED_ONLY], piMsPredInfoBits[MS_PHASE_ONLY], iActualInfoBits ); } #endif + if ( *piMSMode != MS_OFF ) { iFBOffset = 0; @@ -1153,6 +1160,7 @@ static void RemoveRMSEnvelope( return; } + static void QuantizeSpectrumDPCM_Opt( const int32_t iNumGroups, const int32_t *piGroupLengths, @@ -1267,6 +1275,7 @@ static void QuantizeSpectrumDPCM_Opt( return; } + static int32_t CountLCLDBits( const int32_t iNumGroups, const int32_t *piGroupLengths, @@ -1299,8 +1308,10 @@ static int32_t CountLCLDBits( { const uint16_t( *pauiHuffmanTable )[2] = NULL; const uint16_t( *pauiHuffmanTableDPCM )[2] = NULL; + pauiHuffmanTable = c_apauiHuffEncTabels[iAlloc]; pauiHuffmanTableDPCM = c_apauiHuffEncTabels[ALLOC_TABLE_SIZE + iAlloc]; + for ( m = 0; m < piBandwidths[b]; m++ ) { int32_t iQuantValue1; @@ -1387,6 +1398,7 @@ static int32_t WriteMSInformation( #ifdef DEBUG_WRITE_MS_PRED int32_t iBitsWrittenTmp = 0; #endif + iBitsWritten = 0; ISAR_SPLIT_REND_BITStream_write_int32( pBits, iMSMode, 2 ); iBitsWritten += 2; @@ -1423,6 +1435,7 @@ static int32_t WriteMSInformation( break; } } + ISAR_SPLIT_REND_BITStream_write_int32( pBits, anyNonZero, 1 ); iBitsWritten++; @@ -1617,6 +1630,7 @@ static int32_t WriteAllocInformation( return iBitsWritten; } + static int32_t WriteLCLDData( const int32_t *piNumGroups, int32_t **ppiGroupLengths, @@ -1747,6 +1761,7 @@ static int32_t WriteLCLDData( return iBitsWritten; } + static int32_t ComputeAllocation( const int32_t iChannels, const int32_t *piNumGroups, @@ -1882,12 +1897,13 @@ static int32_t ComputeAllocation( } } +#ifdef DEBUGGING /* printf("%d\n",*piAllocOffset); printf("%d\t%d\t%d\n",pppiAlloc[0][0][0],pppiAlloc[0][0][1],pppiAlloc[0][0][22]); printf("%d\t%d\t%d\t%d\n",*piAllocOffset,iAvailableBits,iBitsUsed,iAvailableBits - iBitsUsed); */ - +#endif return iBitsUsed; } diff --git a/lib_isar/isar_lcld_prot.h b/lib_isar/isar_lcld_prot.h index 114a8fb82fd2d2282b1b3d71e53e37fd1e10cadc..3e9c0527a91e33c318265825b91e905cd57ac05e 100644 --- a/lib_isar/isar_lcld_prot.h +++ b/lib_isar/isar_lcld_prot.h @@ -248,6 +248,7 @@ typedef struct PREDICTION_ENCODER int32_t **ppiA1Mag; int32_t **ppiA1Phase; + } PredictionEncoder; ivas_error CreatePredictionEncoder( diff --git a/lib_isar/isar_prot.h b/lib_isar/isar_prot.h index a81c5d34826e51e0e9f880d6ef0fa657c4be6cec..53d70184f04a4bb3a684912de2dcebd1343bf5ca 100644 --- a/lib_isar/isar_prot.h +++ b/lib_isar/isar_prot.h @@ -400,6 +400,7 @@ void isar_init_split_rend_handles( SPLIT_REND_WRAPPER *hSplitRendWrapper /* i/o: Split renderer pre-renderer handle */ ); + /* clang-format on */ #endif /* ISAR_PROT_H */ diff --git a/lib_isar/isar_rom_lcld_tables.c b/lib_isar/isar_rom_lcld_tables.c index 414f234ab419d9df9212138335ee142e8cc23c6e..7656bde34534b96b91aea80b23188419a4b8979d 100644 --- a/lib_isar/isar_rom_lcld_tables.c +++ b/lib_isar/isar_rom_lcld_tables.c @@ -37,6 +37,11 @@ #include "isar_lcld_prot.h" /* clang-format off */ + +/*----------------------------------------------------------------------* + * ISAR binaural rendering LCLD ROM tables + *-----------------------------------------------------------------------*/ + const int32_t c_aiNumLcldBandsPerBand[MAX_BANDS_48] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 21, 24, 27, 31, 37, 43, 50, 60 }; diff --git a/lib_isar/isar_rom_lcld_tables.h b/lib_isar/isar_rom_lcld_tables.h index c398402a436bb36dbbc38450542015a7f35dc7d0..652b545c54231d6a8cb44194a58bd50d397c12d9 100644 --- a/lib_isar/isar_rom_lcld_tables.h +++ b/lib_isar/isar_rom_lcld_tables.h @@ -36,10 +36,9 @@ #include #include "options.h" -#ifndef M_PI +#ifndef M_PI #define M_PI 3.14159265358979323846264338327950288f - #endif #define LCLD_BLOCKS_PER_FRAME ( 16 ) @@ -125,6 +124,11 @@ extern const int32_t c_aaiSpreadFunction48[MAX_BANDS_48 * MAX_BANDS_48]; #define PRED_QUANT_FILTER_PHASE_MIN ( -16 ) #define PRED_QUANT_FILTER_PHASE_MAX ( 15 ) + +/*----------------------------------------------------------------------* + * ISAR binaural rendering LCLD ROM tables + *-----------------------------------------------------------------------*/ + extern const uint16_t c_aauiLCLDHuffEnc1[16][2]; extern const uint16_t c_aauiLCLDHuffEnc2[16][2]; extern const uint16_t c_aauiLCLDHuffEnc3[25][2]; diff --git a/lib_isar/isar_rom_post_rend.c b/lib_isar/isar_rom_post_rend.c index 92034813dc5c749a736f1663f0e647a58bc8862b..73eb03e75f7ecbda8d4f9c3feb7fe7b67422a697 100644 --- a/lib_isar/isar_rom_post_rend.c +++ b/lib_isar/isar_rom_post_rend.c @@ -42,7 +42,7 @@ /*----------------------------------------------------------------------* - * Binuaral split rendering ROM tables + * ISAR binaural split post-rendering ROM tables *-----------------------------------------------------------------------*/ /* rotations in this array are relative to ref rotation */ diff --git a/lib_isar/isar_rom_post_rend.h b/lib_isar/isar_rom_post_rend.h index 0f111244de887b1306fc127b3e74add88e777a1a..a3e89945cb6a8e74f48ec5100c4b09e2f8782d9a 100644 --- a/lib_isar/isar_rom_post_rend.h +++ b/lib_isar/isar_rom_post_rend.h @@ -42,7 +42,7 @@ /*----------------------------------------------------------------------* - * Binuaral split rendering ROM tables + * ISAR binarual split post-rendering ROM tables *-----------------------------------------------------------------------*/ extern const float isar_split_rend_relative_yaw_pos_angles[SPLIT_REND_MAX_YAW_ONLY_POSES]; diff --git a/lib_isar/isar_splitRend_lcld_dec.c b/lib_isar/isar_splitRend_lcld_dec.c index 4d0f7eee4b356562f4ef2bc8d69f6cd1a5550b9f..3c7fd6ba03db8a1773c634aae5fbe05fee1bc80d 100644 --- a/lib_isar/isar_splitRend_lcld_dec.c +++ b/lib_isar/isar_splitRend_lcld_dec.c @@ -48,7 +48,7 @@ *------------------------------------------------------------------------*/ ivas_error isar_splitBinLCLDDecOpen( - ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, /* i/o: ISAR LCLD decoder handle */ const int32_t iSampleRate, const int16_t iChannels, const int16_t iNumBlocks, @@ -126,7 +126,8 @@ ivas_error isar_splitBinLCLDDecOpen( *------------------------------------------------------------------------*/ void isar_splitBinLCLDDecClose( - ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec ) + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec /* o : ISAR LCLD decoder handle */ +) { int16_t n; @@ -168,11 +169,12 @@ void isar_splitBinLCLDDecClose( *------------------------------------------------------------------------*/ void isar_splitBinLCLDDecProcess( - ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec, - ISAR_SPLIT_REND_BITS_HANDLE pBits, - float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t bfi ) + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec, /* i/o: ISAR LCLD decoder handle */ + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Binaural signals, real part */ + float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Binaural signals, imag. part */ + const int16_t bfi /* i : BFI flag */ +) { int16_t k, n; int16_t itr; diff --git a/lib_isar/isar_splitRend_lcld_enc.c b/lib_isar/isar_splitRend_lcld_enc.c index 412e220adc701bfbbfca67b12459dd15595bdc43..1ecb83887b7927708f7c161cb6655b9cfc9e557f 100644 --- a/lib_isar/isar_splitRend_lcld_enc.c +++ b/lib_isar/isar_splitRend_lcld_enc.c @@ -47,7 +47,7 @@ *------------------------------------------------------------------------*/ ivas_error isar_splitBinLCLDEncOpen( - ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, /* o : ISAR LCLD handle */ const int32_t iSampleRate, const int16_t iChannels, const int32_t iDataRate, @@ -120,7 +120,8 @@ ivas_error isar_splitBinLCLDEncOpen( *------------------------------------------------------------------------*/ void isar_splitBinLCLDEncClose( - ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc ) + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc /* i/o: ISAR LCLD handle */ +) { if ( ( *hSplitBinLCLDEnc ) != NULL ) { @@ -156,7 +157,7 @@ void isar_splitBinLCLDEncClose( *------------------------------------------------------------------------*/ void isar_splitBinLCLDEncProcess( - ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc, + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc, /* i/o: ISAR LCLD encoder handle */ #ifdef FIX_1119_SPLIT_RENDERING_VOIP float *Cldfb_In_Real[][CLDFB_NO_COL_MAX], /* i/o: Binaural signals, real part */ float *Cldfb_In_Imag[][CLDFB_NO_COL_MAX], /* i/o: Binaural signals, imag. part */ diff --git a/lib_isar/isar_splitRendererPLC.c b/lib_isar/isar_splitRendererPLC.c index 82803ff398b13533ed21f1c0c7b6c921ac777066..fd2e00e68c7bc4d4687a3627937a0d18d11c33f1 100644 --- a/lib_isar/isar_splitRendererPLC.c +++ b/lib_isar/isar_splitRendererPLC.c @@ -317,7 +317,7 @@ static void adaptive_polar_ext_plc( *------------------------------------------------------------------------*/ ivas_error isar_splitBinRendPLCOpen( - ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC, + ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC, /* i/o: ISAR PLC handle */ const int16_t iNumSubSets ) { ivas_error error; @@ -347,7 +347,8 @@ ivas_error isar_splitBinRendPLCOpen( *------------------------------------------------------------------------*/ void isar_splitBinRendPLCClose( - ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC ) + ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC /* i/o: ISAR PLC handle */ +) { if ( ( *phSplitRendPLC ) != NULL ) { @@ -501,7 +502,6 @@ void isar_splitBinRendPLC( } } - /* Check bf counter */ fade_start_cntr = SR_PLC_FADE_START * CLDFB_NO_COL_MAX / iNumCols; mute_cntr = SR_PLC_MUTE * CLDFB_NO_COL_MAX / iNumCols; diff --git a/lib_isar/isar_splitRendererPost.c b/lib_isar/isar_splitRendererPost.c index 8e9ac34dd04ceb25a7688a7df3b0daf876f1ede5..b452ec90f188871ee5a1e70b65db9fa901fe86a8 100644 --- a/lib_isar/isar_splitRendererPost.c +++ b/lib_isar/isar_splitRendererPost.c @@ -45,16 +45,12 @@ #endif #include "wmc_auto.h" + /*---------------------------------------------------------------------* * Local function declarations *---------------------------------------------------------------------*/ -static void isar_SplitRenderer_PostRenderer( - ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinPostRenderer, /* i/o: binaural renderer handle */ - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - float Cldfb_RealBuffer_Ref_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ - float Cldfb_ImagBuffer_Ref_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ - const IVAS_QUATERNION Quaternion_act ); +static void isar_SplitRenderer_PostRenderer( ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinPostRenderer, MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, float Cldfb_RealBuffer_Ref_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer_Ref_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], const IVAS_QUATERNION Quaternion_act ); /*------------------------------------------------------------------------- @@ -64,9 +60,10 @@ static void isar_SplitRenderer_PostRenderer( *------------------------------------------------------------------------*/ ivas_error isar_splitBinPostRendOpen( - ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const int32_t output_Fs ) + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend, /* i/o: binaural post-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ + const int32_t output_Fs /* i : output sampling rate */ +) { ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinRend; ivas_error error; @@ -133,7 +130,8 @@ ivas_error isar_splitBinPostRendOpen( *------------------------------------------------------------------------*/ void isar_splitBinPostRendClose( - ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend ) + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend /* i/o: binaural post-renderer handle */ +) { int16_t ch; @@ -182,7 +180,7 @@ void isar_splitBinPostRendClose( static int16_t isar_split_rend_huffman_decode_opt( isar_split_rend_huffman_cfg_t *huff_cfg, - ISAR_SPLIT_REND_BITS_HANDLE pBits, + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ const int16_t *idx_trav_list ) { int32_t i, ind, code, num_bits, code_b, num_bits_read; @@ -220,6 +218,7 @@ static int16_t isar_split_rend_huffman_decode_opt( return (int16_t) ind; } + /*-----------------------------------------------------------------------------------------* * Function isar_split_rend_unquant_md() * @@ -311,9 +310,9 @@ static void isar_split_rend_unquant_md( *-----------------------------------------------------------------------------------------*/ static void isar_splitBinPostRendMdBase2Dec( - ISAR_SPLIT_REND_BITS_HANDLE pBits, - ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, /* i/o: binaural post-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ const int16_t num_subframes, const int16_t pred_real_bands_yaw, const int16_t pred_imag_bands_yaw, @@ -455,9 +454,9 @@ static void isar_splitBinPostRendMdBase2Dec( *-----------------------------------------------------------------------------------------*/ static void isar_splitBinPostRendMdHuffDec( - ISAR_SPLIT_REND_BITS_HANDLE pBits, - ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, /* i/o: binaural post-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ const int16_t num_subframes, const int16_t pred_real_bands_yaw, const int16_t pred_imag_bands_yaw, @@ -595,9 +594,9 @@ static void isar_splitBinPostRendMdHuffDec( *-----------------------------------------------------------------------------------------*/ void isar_splitBinPostRendMdDec( - ISAR_SPLIT_REND_BITS_HANDLE pBits, - ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, /* i/o: binaural post-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* i/o: pose correction data handle */ #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG , BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend @@ -1007,6 +1006,7 @@ static void wrap_around_angle( { ( *a ) = ( *a ) + 360; } + return; } @@ -1027,6 +1027,7 @@ static void wrap_around_ypr( wrap_around_angle( &Quaternions->y ); wrap_around_angle( &Quaternions->z ); } + return; } @@ -1119,7 +1120,7 @@ static void get_nearest_pose_ind( *-----------------------------------------------------------------------------------------*/ static void get_interpolation_vars( - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ const IVAS_QUATERNION *Quaternions_ref, const IVAS_QUATERNION *Quaternions_act, int16_t interp_yaw_pose_idx[2], @@ -1397,8 +1398,8 @@ static void interpolate_rend_md( *-----------------------------------------------------------------------------------------*/ static void isar_SplitRenderer_PostRenderer( - ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinPostRenderer, /* i/o: binaural renderer handle */ - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinPostRenderer, /* i/o: binaural renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ const IVAS_QUATERNION Quaternion_act ) @@ -1460,7 +1461,6 @@ static void isar_SplitRenderer_PostRenderer( } } - #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES - 1; pos_idx++ ) { @@ -1497,9 +1497,6 @@ static void isar_SplitRenderer_PostRenderer( } } -#endif - -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) #else pos_idx = 0; @@ -1632,8 +1629,8 @@ static void isar_SplitRenderer_PostRenderer( fname ); } } -#endif +#endif pop_wmops(); return; } @@ -1646,8 +1643,8 @@ static void isar_SplitRenderer_PostRenderer( *-----------------------------------------------------------------------------------------*/ static void isar_rend_CldfbSplitPostRendProcessTdIn( - ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, /* i/o: binaural post-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ const IVAS_QUATERNION QuaternionPost, float output[][L_FRAME48k] ) { @@ -1697,8 +1694,8 @@ static void isar_rend_CldfbSplitPostRendProcessTdIn( *-----------------------------------------------------------------------------------------*/ void isar_rend_CldfbSplitPostRendProcess( - ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, /* i/o: binaural post-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ const IVAS_QUATERNION QuaternionPost, float Cldfb_RealBuffer_Binaural[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer_Binaural[][CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], @@ -1747,7 +1744,8 @@ void isar_rend_CldfbSplitPostRendProcess( *-----------------------------------------------------------------------------------------*/ void isar_init_split_post_rend_handles( - ISAR_SPLIT_POST_REND_WRAPPER *hSplitRendWrapper ) + ISAR_SPLIT_POST_REND_WRAPPER *hSplitRendWrapper /* i/o: Split renderer post-renderer handle */ +) { hSplitRendWrapper->hBinHrSplitPostRend = NULL; hSplitRendWrapper->hSplitBinLCLDDec = NULL; diff --git a/lib_isar/isar_splitRendererPre.c b/lib_isar/isar_splitRendererPre.c index 734daae97719236aa4b692e5948eb65d5393e438..370e02398d5a9cb2eae31418e531083b7490fd94 100644 --- a/lib_isar/isar_splitRendererPre.c +++ b/lib_isar/isar_splitRendererPre.c @@ -64,6 +64,7 @@ static void isar_SplitRenderer_GetRotMd( ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinH const int16_t low_res, const int16_t ro_md_flag ); + /*------------------------------------------------------------------------- * Local functions * @@ -512,6 +513,7 @@ static void isar_split_rend_quant_md( { hMd->pred_mat_re[ch1][ch1] = hMd->pred_mat_re2[ch1]; } + hMd->pred_mat_re[1][0] = 0.0f; hMd->pred_mat_re[0][1] = 0.0f; @@ -573,11 +575,14 @@ static void isar_split_rend_quant_md( return; } -static void get_lr_gains( float cov_in[][BINAURAL_CHANNELS], - float cov_out[][BINAURAL_CHANNELS], - float gains[BINAURAL_CHANNELS] ) + +static void get_lr_gains( + float cov_in[][BINAURAL_CHANNELS], + float cov_out[][BINAURAL_CHANNELS], + float gains[BINAURAL_CHANNELS] ) { int16_t i; + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) { gains[i] = cov_in[i][i]; @@ -591,9 +596,11 @@ static void get_lr_gains( float cov_in[][BINAURAL_CHANNELS], gains[i] = sqrtf( gains[i] ); } } + return; } + static void ComputeCoeffs( float cov_ii_re[][BINAURAL_CHANNELS], float cov_ii_im[][BINAURAL_CHANNELS], @@ -616,7 +623,9 @@ static void ComputeCoeffs( if ( pose_type == PITCH_ONLY ) { float gd_tmp[BINAURAL_CHANNELS]; + get_lr_gains( cov_ii_re, cov_oo_re, gd_tmp ); + hMd->gd = gd_tmp[0]; hMd->gd2 = gd_tmp[1]; } @@ -625,19 +634,23 @@ static void ComputeCoeffs( if ( real_only ) { float gd_tmp[BINAURAL_CHANNELS]; + get_lr_gains( cov_ii_re, cov_oo_re, gd_tmp ); + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) { hMd->pred_mat_re[i][i] = gd_tmp[i]; hMd->pred_mat_re2[i] = gd_tmp[i]; set_zero( hMd->pred_mat_im[i], BINAURAL_CHANNELS ); } + hMd->pred_mat_re[1][0] = 0.0f; hMd->pred_mat_re[0][1] = 0.0f; } else { get_lr_gains( cov_ii_re, cov_oo_re, hMd->pred_mat_re2 ); + cov_norm_fact = GetNormFact( cov_ii_re, cov_ii_im, cov_io_re, cov_io_im, cov_oo_re ); /* normalize the covariance */ @@ -717,8 +730,8 @@ static void ComputeCoeffs( static void get_base2_bits( - const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i : binaural pre-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ const int16_t num_subframes, const int16_t num_quant_strats, const int16_t pred_real_bands_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS], @@ -781,8 +794,8 @@ static void get_base2_bits( static void isar_SplitRenderer_code_md_base2( - const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i : binaural pre-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ const int16_t num_subframes, const int16_t pred_real_bands_yaw, const int16_t pred_imag_bands_yaw, @@ -791,7 +804,8 @@ static void isar_SplitRenderer_code_md_base2( const int16_t bands_pitch, const int16_t pred_real_bands_roll, const int16_t pred_imag_bands_roll, - ISAR_SPLIT_REND_BITS_HANDLE pBits ) + ISAR_SPLIT_REND_BITS_HANDLE pBits /* i/o: ISAR bits handle */ +) { int16_t pos_idx, b, ch1, ch2, sf_idx; int16_t min_pred_idx, min_gd_idx, min_p_gd_idx, pred_code_len, gd_code_len, p_gd_code_len, num_poses; @@ -828,7 +842,6 @@ static void isar_SplitRenderer_code_md_base2( { if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) { - for ( b = 0; b < pred_imag_bands_yaw; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; @@ -860,6 +873,7 @@ static void isar_SplitRenderer_code_md_base2( ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_code_len ); } } + for ( b = 0; b < d_bands_yaw; b++ ) { hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; @@ -939,8 +953,8 @@ static void isar_SplitRenderer_code_md_base2( static void isar_SplitRenderer_code_md_huff( - const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i : binaural pre-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ const int16_t num_subframes, const int16_t pred_real_bands_yaw, const int16_t pred_imag_bands_yaw, @@ -949,7 +963,8 @@ static void isar_SplitRenderer_code_md_huff( const int16_t bands_pitch, const int16_t pred_real_bands_roll, const int16_t pred_imag_bands_roll, - ISAR_SPLIT_REND_BITS_HANDLE pBits ) + ISAR_SPLIT_REND_BITS_HANDLE pBits /* i/o: ISAR bits handle */ +) { int16_t pos_idx, b, ch1, ch2, sf_idx, num_poses; int16_t sym_adj_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; @@ -1099,13 +1114,14 @@ static void isar_SplitRenderer_code_md_huff( static void isar_SplitRenderer_quant_code( - const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, - const IVAS_QUATERNION headPosition, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - ISAR_SPLIT_REND_BITS_HANDLE pBits, - const int16_t low_res_pre_rend_rot, - const int16_t ro_md_flag, - const int32_t target_md_bits ) + const ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i : binaural pre-renderer handle */ + const IVAS_QUATERNION headPosition, /* i : head rotation QUATERNION */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + const int16_t low_res_pre_rend_rot, /* i : low time resolution pre-renderer flag */ + const int16_t ro_md_flag, /* i : real only metadata for yaw flag */ + const int32_t target_md_bits /* i : ISAR MD bitrate */ +) { int16_t q, num_subframes, sf_idx, pos_idx, b, num_quant_strats; int32_t overhead_bits, quant_strat_bits, huff_bits, start_bit; @@ -1132,11 +1148,13 @@ static void isar_SplitRenderer_quant_code( ISAR_SPLIT_REND_BITStream_write_int32( pBits, pMultiBinPoseData->dof, ISAR_SPLIT_REND_DOF_BITS ); ISAR_SPLIT_REND_BITStream_write_int32( pBits, pMultiBinPoseData->hq_mode, ISAR_SPLIT_REND_HQ_MODE_BITS ); + rot_axis_code = isar_renderSplitGetCodeFromRot_axis( pMultiBinPoseData->dof, pMultiBinPoseData->rot_axis, &num_bits ); if ( num_bits > 0 ) { ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) rot_axis_code, num_bits ); } + ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) ro_md_flag, ISAR_SPLIT_REND_RO_FLAG_BITS ); /* code ref pose*/ @@ -1163,13 +1181,13 @@ static void isar_SplitRenderer_quant_code( isar_split_rend_get_quant_params( MAX_SPLIT_REND_MD_BANDS, pred_real_bands_yaw, pred_imag_bands_yaw, pred_quant_pnts_yaw, pred_quantstep_yaw, pred_1byquantstep_yaw, d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, ro_md_flag, &num_quant_strats ); + quant_strat_bits = (int32_t) ceilf( log2f( num_quant_strats ) ); overhead_bits = pBits->bits_written - overhead_bits + quant_strat_bits + 1; /* 1 for base2 vs huff */ get_base2_bits( hBinHrSplitPreRend, pMultiBinPoseData, num_subframes, num_quant_strats, pred_real_bands_yaw, pred_imag_bands_yaw, - pred_quant_pnts_yaw, - d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, base2bits ); + pred_quant_pnts_yaw, d_bands_yaw, bands_pitch, pred_real_bands_roll, pred_imag_bands_roll, base2bits ); for ( q = 0; q < num_quant_strats; q++ ) { @@ -1255,8 +1273,7 @@ static void isar_SplitRenderer_quant_code( ISAR_SPLIT_REND_BITStream_write_int32( pBits, q, quant_strat_bits ); isar_SplitRenderer_code_md_base2( hBinHrSplitPreRend, pMultiBinPoseData, num_subframes, pred_real_bands_yaw[q], pred_imag_bands_yaw[q], - pred_quant_pnts_yaw[q], - d_bands_yaw[q], bands_pitch[q], pred_real_bands_roll[q], pred_imag_bands_roll[q], pBits ); + pred_quant_pnts_yaw[q], d_bands_yaw[q], bands_pitch[q], pred_real_bands_roll[q], pred_imag_bands_roll[q], pBits ); } break; } @@ -1339,8 +1356,8 @@ static void isar_SplitRenderer_quant_code( } } } -#endif +#endif return; } @@ -1362,7 +1379,8 @@ static void isar_SplitRenderer_GetRotMd( float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ #endif const int16_t low_res, - const int16_t ro_md_flag ) + const int16_t ro_md_flag /* i : Flag to indicate real only metadata for yaw */ +) { float cov_ii_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; float cov_oo_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; @@ -1566,8 +1584,8 @@ void isar_rend_CldfbSplitPreRendProcess( *------------------------------------------------------------------------*/ ivas_error isar_splitBinPreRendOpen( - ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend, /* i/o: binaural pre-renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* o : pose correction data handle */ #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG , const int32_t output_Fs @@ -1605,8 +1623,8 @@ ivas_error isar_splitBinPreRendOpen( } } } -#endif +#endif for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) { for ( sf_idx = 0; sf_idx < MAX_SPLIT_MD_SUBFRAMES; sf_idx++ ) @@ -1630,8 +1648,8 @@ ivas_error isar_splitBinPreRendOpen( { return error; } -#endif +#endif *hBinHrSplitPreRend = hBinRend; return IVAS_ERR_OK; @@ -1645,7 +1663,8 @@ ivas_error isar_splitBinPreRendOpen( *------------------------------------------------------------------------*/ void isar_splitBinPreRendClose( - ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend ) + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend /* i/o: binaural pre-renderer handle */ +) { if ( ( *hBinHrSplitPreRend ) != NULL ) { @@ -1684,11 +1703,13 @@ void isar_splitBinPreRendClose( *-------------------------------------------------------------------------*/ void isar_set_split_rend_ht_setup( - SPLIT_REND_WRAPPER *hSplitrend, - IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES], - float Rmat[MAX_PARAM_SPATIAL_SUBFRAMES][3][3] ) + SPLIT_REND_WRAPPER *hSplitrend, /* i/o: Split renderer pre-renderer handle */ + IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES], /* i/o: External orientation in quaternions */ + float Rmat[MAX_PARAM_SPATIAL_SUBFRAMES][3][3] /* o : real-space rotation matrix */ +) { int16_t sf, i, j; + if ( hSplitrend->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { for ( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) @@ -1716,7 +1737,8 @@ void isar_set_split_rend_ht_setup( *------------------------------------------------------------------------*/ void isar_init_split_rend_handles( - SPLIT_REND_WRAPPER *hSplitRendWrapper ) + SPLIT_REND_WRAPPER *hSplitRendWrapper /* i/o: Split renderer pre-renderer handle */ +) { int16_t i; @@ -1736,6 +1758,7 @@ void isar_init_split_rend_handles( return; } + /*------------------------------------------------------------------------- * Function split_renderer_open_lc3plus() * @@ -1743,10 +1766,11 @@ void isar_init_split_rend_handles( *------------------------------------------------------------------------*/ ivas_error split_renderer_open_lc3plus( - SPLIT_REND_WRAPPER *hSplitRendWrapper, - const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, - const int32_t output_Fs, - const IVAS_RENDER_FRAMESIZE isar_frame_size ) + SPLIT_REND_WRAPPER *hSplitRendWrapper, /* i/o: Split renderer pre-renderer handle */ + const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i : Split renderer pre-renderer config */ + const int32_t output_Fs, /* i : output sampling rate */ + const IVAS_RENDER_FRAMESIZE isar_frame_size /* i : IVAS frame size */ +) { ivas_error error; int16_t i, delayBufferLength; @@ -1772,9 +1796,7 @@ ivas_error split_renderer_open_lc3plus( config.high_res_mode_enabled = ( pSplitRendConfig->lc3plus_highres != 0 ); config.channels = BINAURAL_CHANNELS; - if ( ( error = ISAR_LC3PLUS_ENC_Open( config, - isar_get_lc3plus_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode, config.channels, config.lc3plus_frame_duration_us ), - &hSplitRendWrapper->hLc3plusEnc ) ) != IVAS_ERR_OK ) + if ( ( error = ISAR_LC3PLUS_ENC_Open( config, isar_get_lc3plus_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode, config.channels, config.lc3plus_frame_duration_us ), &hSplitRendWrapper->hLc3plusEnc ) ) != IVAS_ERR_OK ) { return error; } @@ -1788,7 +1810,7 @@ ivas_error split_renderer_open_lc3plus( /* Alocate buffers for delay compensation */ if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) { - delayBufferLength = (int16_t) ( output_Fs / (int32_t) FRAMES_PER_SECOND + hSplitRendWrapper->lc3plusDelaySamples ); + delayBufferLength = (int16_t) ( output_Fs / (int32_t) FRAMES_PER_SEC + hSplitRendWrapper->lc3plusDelaySamples ); for ( i = 0; i < hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++i ) { if ( ( hSplitRendWrapper->lc3plusDelayBuffers[i] = malloc( delayBufferLength * sizeof( float ) ) ) == NULL ) @@ -1828,10 +1850,11 @@ ivas_error split_renderer_open_lc3plus( *------------------------------------------------------------------------*/ ivas_error splitRendLc3plusEncodeAndWrite( - SPLIT_REND_WRAPPER *hSplitBin, - ISAR_SPLIT_REND_BITS_HANDLE pBits, - const int32_t available_bits, - float *in[] ) + SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renderer handle */ + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + const int32_t available_bits, /* i : available bit-budget */ + float *in[] /* i/o: PCM in/out buffer */ +) { ivas_error error; int16_t i; @@ -1860,7 +1883,6 @@ ivas_error splitRendLc3plusEncodeAndWrite( return error; } - /* Write bitstream */ if ( ( error = ISAR_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8], lc3plusBitstreamSize ) ) != IVAS_ERR_OK ) { @@ -1872,9 +1894,11 @@ ivas_error splitRendLc3plusEncodeAndWrite( pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; pBits->codec_frame_size_ms = (int16_t) ( hSplitBin->hLc3plusEnc->config.lc3plus_frame_duration_us / 1000 ); pBits->isar_frame_size_ms = (int16_t) ( hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000 ); + return IVAS_ERR_OK; } + /*------------------------------------------------------------------------- * Function isar_renderMultiTDBinToSplitBinaural() * @@ -1882,17 +1906,18 @@ ivas_error splitRendLc3plusEncodeAndWrite( *------------------------------------------------------------------------*/ ivas_error isar_renderMultiTDBinToSplitBinaural( - SPLIT_REND_WRAPPER *hSplitBin, - const IVAS_QUATERNION headPosition, - const int32_t SplitRendBitRate, - const int16_t isar_frame_size_ms, - const int16_t codec_frame_size_ms, - ISAR_SPLIT_REND_BITS_HANDLE pBits, - const int16_t max_bands, - float *in[], - const int16_t low_res_pre_rend_rot, - const int16_t pcm_out_flag, - const int16_t ro_md_flag ) + SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renderer handle */ + const IVAS_QUATERNION headPosition, /* i : head rotation QUATERNION */ + const int32_t SplitRendBitRate, /* i : ISAR bitrate */ + const int16_t isar_frame_size_ms, /* i : ISAR bit stream frame size in ms */ + const int16_t codec_frame_size_ms, /* i : ISAR frame length in ms */ + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + const int16_t max_bands, /* i : CLDFB bands */ + float *in[], /* i/o: PCM in/out buffer */ + const int16_t low_res_pre_rend_rot, /* i : low time resolution pre-renderer flag */ + const int16_t pcm_out_flag, /* i : flag to indicate PCM output */ + const int16_t ro_md_flag /* i : real only metadata for yaw flag */ +) { ivas_error error; int32_t bit_len, available_bits, target_md_bits; @@ -1930,7 +1955,7 @@ ivas_error isar_renderMultiTDBinToSplitBinaural( if ( useLc3plus ) { /*this should always have the time resolution of pose correction MD. Note that this does not change frame size of LC3plus*/ - int16_t frame_size = (int16_t) ( hSplitBin->hLc3plusEnc->config.samplerate / (int32_t) FRAMES_PER_SECOND ); + int16_t frame_size = (int16_t) ( hSplitBin->hLc3plusEnc->config.samplerate / (int32_t) FRAMES_PER_SEC ); for ( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) { @@ -1988,7 +2013,6 @@ ivas_error isar_renderMultiTDBinToSplitBinaural( { target_md_bits = isar_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000; - isar_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, @@ -2040,6 +2064,7 @@ ivas_error isar_renderMultiTDBinToSplitBinaural( { available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written; } + if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, available_bits, in ) ) != IVAS_ERR_OK ) { return error; diff --git a/lib_isar/isar_splitRenderer_utils.c b/lib_isar/isar_splitRenderer_utils.c index 962e52ff19264cc19a08cb9f33ca6a30a9648f41..d9b3d361a1354de0ea2f8451c29003695d37b0d0 100644 --- a/lib_isar/isar_splitRenderer_utils.c +++ b/lib_isar/isar_splitRenderer_utils.c @@ -236,7 +236,8 @@ void isar_split_rend_init_huff_cfg( void set_fix_rotation_mat( float fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS], - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* i/o: pose correction data handle */ +) { float yaw_a, cos_yaw, sin_yaw; int16_t pos_idx; @@ -265,8 +266,9 @@ void set_fix_rotation_mat( *------------------------------------------------------------------------*/ void set_pose_types( - ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1], - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) + ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1], /* o : ISAR pose type */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* i : pose correction data handle */ +) { int16_t pos_idx; @@ -345,17 +347,19 @@ void isar_SplitRenderer_getdiagdiff( * *------------------------------------------------------------------------*/ +/*! r: parameter value */ int32_t ISAR_SPLIT_REND_BITStream_read_int32( - ISAR_SPLIT_REND_BITS_HANDLE pBits, - const int32_t bits ) + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + const int32_t bits /* i : number of bits to be read */ +) { int32_t val, k, bit_val; #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG assert( ( pBits->bits_written - pBits->bits_read ) >= bits ); assert( bits <= 32 ); -#endif +#endif /* write bit by bit */ val = 0; for ( k = bits - 1; k >= 0; k-- ) @@ -376,9 +380,10 @@ int32_t ISAR_SPLIT_REND_BITStream_read_int32( *------------------------------------------------------------------------*/ void ISAR_SPLIT_REND_BITStream_write_int32( - ISAR_SPLIT_REND_BITS_HANDLE pBits, - const int32_t val, - const int32_t bits ) + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits handle */ + const int32_t val, /* i : parameter value */ + const int32_t bits /* i : number of bits to be written */ +) { int32_t mask, k; @@ -462,9 +467,11 @@ void isar_log_cldfb2wav_data( * *------------------------------------------------------------------------*/ +/*! r: ISAR MD bitrate */ int32_t isar_get_split_rend_md_target_brate( - const int32_t SplitRendBitRate, - const int16_t pcm_out_flag ) + const int32_t SplitRendBitRate, /* i : ISAR bitrate */ + const int16_t pcm_out_flag /* i : flag to indicate PCM output */ +) { int32_t md_bitrate; @@ -508,9 +515,11 @@ int32_t isar_get_split_rend_md_target_brate( * *------------------------------------------------------------------------*/ +/*! r: LCLD codec bitrate */ int32_t isar_get_lcld_bitrate( - const int32_t SplitRendBitRate, - const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode ) + const int32_t SplitRendBitRate, /* i : ISAR bitrate */ + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode /* i : ISAR pose correction mode */ +) { if ( poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { @@ -542,6 +551,7 @@ int32_t isar_get_lcld_bitrate( return -1; } + /*------------------------------------------------------------------------- * Function isar_get_lc3plus_bitrate() * @@ -549,20 +559,22 @@ int32_t isar_get_lcld_bitrate( *------------------------------------------------------------------------*/ int32_t isar_get_lc3plus_bitrate( - const int32_t SplitRendBitRate, - const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, - const int32_t nChannels, - const int32_t codecFrameDurationUs ) + const int32_t SplitRendBitRate, /* i : ISAR bitrate */ + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, /* i : ISAR pose correction mode */ + const int32_t nChannels, /* i : number of channels */ + const int32_t codecFrameDurationUs /* i : ISAR frame length in us */ +) { int32_t bitrate; + bitrate = isar_get_lcld_bitrate( SplitRendBitRate, poseCorrectionMode ); + /* Check for LC3plus LEA 48_6 LC3 compatibility mode signalling */ if ( ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE == poseCorrectionMode && bitrate == 256000 && nChannels == 2 && codecFrameDurationUs == 10000 ) { - - bitrate = 2 * 126000; } + return bitrate; } @@ -574,8 +586,9 @@ int32_t isar_get_lc3plus_bitrate( *------------------------------------------------------------------------*/ ivas_error isar_split_rend_validate_config( - const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, - const int16_t is_pcm_out ) + const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i/o: Split renderer pre-renderer config */ + const int16_t pcm_out_flag /* i : flag to indicate PCM output */ +) { /* Valid DOF range is 0-3 */ if ( pSplitRendConfig->dof < 0 || pSplitRendConfig->dof > 3 ) @@ -610,7 +623,7 @@ ivas_error isar_split_rend_validate_config( } /* Validate bitrate */ - if ( is_pcm_out == 0 ) + if ( pcm_out_flag == 0 ) { switch ( pSplitRendConfig->splitRendBitRate ) { @@ -736,6 +749,7 @@ void isar_split_rend_get_quant_params( return; } + /*------------------------------------------------------------------------- * Function isar_renderSplitGetRot_axisNumBits() * @@ -754,9 +768,11 @@ int16_t isar_renderSplitGetRot_axisNumBits( { num_bits = 0; } + return num_bits; } + /*------------------------------------------------------------------------- * Function isar_renderSplitGetRot_axisFromCode() * @@ -792,6 +808,7 @@ ISAR_SPLIT_REND_ROT_AXIS isar_renderSplitGetRot_axisFromCode( return rot_axis; } + /*------------------------------------------------------------------------- * Function isar_renderSplitGetCodeFromRot_axis() * @@ -804,6 +821,7 @@ int16_t isar_renderSplitGetCodeFromRot_axis( int16_t *num_bits ) { int16_t code = 0; + if ( dof == 1 ) { code = (int16_t) rot_axis; @@ -828,6 +846,7 @@ int16_t isar_renderSplitGetCodeFromRot_axis( return code; } + /*------------------------------------------------------------------------- * Function isar_renderSplitGetMultiBinPoseData() * @@ -835,9 +854,10 @@ int16_t isar_renderSplitGetCodeFromRot_axis( *------------------------------------------------------------------------*/ void isar_renderSplitGetMultiBinPoseData( - const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const ISAR_SPLIT_REND_ROT_AXIS rot_axis ) + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i : Split renderer pre-renderer config */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ +) { int16_t pos_idx, num_yaw_poses, num_pitch_poses, num_roll_poses; const float *relative_yaw_angles; @@ -971,8 +991,9 @@ void isar_renderSplitGetMultiBinPoseData( *------------------------------------------------------------------------*/ void isar_renderSplitUpdateNoCorrectionPoseData( - const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i : Split renderer pre-renderer config */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* i/o: pose correction data handle */ +) { pMultiBinPoseData->num_poses = 1; assert( pSplit_rend_config->dof == 0 ); @@ -991,7 +1012,8 @@ void isar_renderSplitUpdateNoCorrectionPoseData( *------------------------------------------------------------------------*/ void isar_init_multi_bin_pose_data( - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData /* i/o: pose correction data handle */ +) { int16_t pos_idx; @@ -1009,6 +1031,13 @@ void isar_init_multi_bin_pose_data( return; } + +/*------------------------------------------------------------------------- + * Function isar_framesize_to_ms() + * + * + *------------------------------------------------------------------------*/ + ivas_error isar_framesize_to_ms( const IVAS_RENDER_FRAMESIZE frame_size, /* i : frame size enum */ int16_t *ms /* o : frame size in ms */ @@ -1041,7 +1070,7 @@ ivas_error isar_framesize_to_ms( ivas_error isar_split_rend_choose_default_codec( ISAR_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */ - int16_t *pIsar_frame_size_ms, /* i/o: pointer to isar frame size setting */ + int16_t *pIsar_frame_size_ms, /* i/o: pointer to ISAR frame size setting */ int16_t *pCodec_frame_size_ms, /* i/o: pointer to codec frame size setting */ const int16_t cldfb_in_flag, /* i : flag indicating rendering in TD */ const int16_t pcm_out_flag, /* i : flag to indicate PCM output */ @@ -1075,13 +1104,16 @@ ivas_error isar_split_rend_choose_default_codec( return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unknown split codec value" ); } } - if ( *pIsar_frame_size_ms == 0 ) /* isar frame size hasn't been set yet - use default for current configuration */ + + if ( *pIsar_frame_size_ms == 0 ) /* ISAR frame size hasn't been set yet - use default for current configuration */ { *pIsar_frame_size_ms = 20; } + return IVAS_ERR_OK; } + /*-------------------------------------------------------------------* * Function get_bit() * diff --git a/lib_isar/isar_stat.h b/lib_isar/isar_stat.h index 4ed75ee97e81e4ff1ebacd476bfc4f36f5732eb3..b244370dd3eceed843c49f02de1087c21a0e0b9e 100644 --- a/lib_isar/isar_stat.h +++ b/lib_isar/isar_stat.h @@ -350,9 +350,9 @@ typedef struct { float *real; float *imag; - int32_t capacity; - int32_t write_pos; - int32_t read_pos; + uint32_t capacity; + uint32_t write_pos; + uint32_t read_pos; int16_t is_full; } ISAR_CLDFB_RINGBUF, *ISAR_CLDFB_RINGBUF_HANDLE; diff --git a/lib_isar/lib_isar_post_rend.c b/lib_isar/lib_isar_post_rend.c index 0170c2b52c694f8756500dd185432b140fdb3860..5dcc099fd705e6b3c940a932d4d5d0b2a5c46149 100644 --- a/lib_isar/lib_isar_post_rend.c +++ b/lib_isar/lib_isar_post_rend.c @@ -33,7 +33,6 @@ #include "options.h" #include "lib_isar_post_rend.h" -#include "isar_stat.h" #include "isar_prot.h" #include "prot.h" #include "ivas_prot.h" @@ -53,14 +52,6 @@ * Local types *-------------------------------------------------------------------*/ -/* EFAP wrapper to simplify writing panning gains to a vector that includes LFE channels */ -typedef struct -{ - EFAP_HANDLE hEfap; - AUDIO_CONFIG speakerConfig; - const LSSETUP_CUSTOM_STRUCT *pCustomLsSetup; /* Pointer to main custom LS struct from renderer handle - doesn't need freeing */ -} EFAP_WRAPPER; - /* Lightweight helper struct that gathers all information required for rendering * any config to any other config. Used to simplify signatures of rendering functions. * @@ -75,7 +66,7 @@ typedef struct const ISAR_POST_REND_HeadRotData *pHeadRotData; const int16_t *pSplitRendBFI; const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRenderConfig; -} rendering_context; +} rendering_context_isar; /* Common base for input structs */ typedef struct @@ -84,13 +75,13 @@ typedef struct ISAR_POST_REND_InputId id; IVAS_REND_AudioBuffer inputBuffer; float gain; /* Linear, not in dB */ - rendering_context ctx; + rendering_context_isar ctx; int32_t numNewSamplesPerChannel; /* Used to keep track how much new audio was fed before rendering current frame */ -} input_base; +} input_base_isar; typedef struct { - input_base base; + input_base_isar base; ISAR_SPLIT_POST_REND_WRAPPER splitPostRendWrapper; float *bufferData; int16_t numCachedSamples; /* Number of decoded samples in bufferData that have not yet been played out */ @@ -120,14 +111,17 @@ struct ISAR_POST_REND int16_t num_subframes; }; + /*-------------------------------------------------------------------* - * isar_getAudioConfigType() + * ISAR_POST_REND_AudioConfigType() * * *-------------------------------------------------------------------*/ +/*! r: ISAR audio type */ ISAR_POST_REND_AudioConfigType isar_getAudioConfigType( - const AUDIO_CONFIG config ) + const AUDIO_CONFIG config /* i : audio configuration */ +) { ISAR_POST_REND_AudioConfigType type; @@ -147,10 +141,6 @@ ISAR_POST_REND_AudioConfigType isar_getAudioConfigType( } -/*-------------------------------------------------------------------* - * Local function prototypes - *-------------------------------------------------------------------*/ - /*-------------------------------------------------------------------* * Local functions *-------------------------------------------------------------------*/ @@ -168,6 +158,7 @@ static ivas_error allocateInputBaseBufferData( return IVAS_ERR_OK; } + static void freeInputBaseBufferData( float **data ) { @@ -207,6 +198,7 @@ static void convertBitsBufferToInternalBitsBuff( return; } + static void convertInternalBitsBuffToBitsBuffer( ISAR_POST_REND_BitstreamBuffer *hOutBits, const ISAR_SPLIT_REND_BITS_DATA bits ) @@ -224,6 +216,7 @@ static void convertInternalBitsBuffToBitsBuffer( return; } + static void copyBufferTo2dArray( const IVAS_REND_AudioBuffer buffer, float array[][L_FRAME48k] ) @@ -246,6 +239,7 @@ static void copyBufferTo2dArray( return; } + static void accumulate2dArrayToBuffer( float array[][L_FRAME48k], const IVAS_REND_AudioBuffer *buffer ) @@ -265,13 +259,14 @@ static void accumulate2dArrayToBuffer( return; } +#ifndef DISABLE_LIMITER + /*-------------------------------------------------------------------* * limitRendererOutput() * * In-place saturation control for multichannel buffers with adaptive release time *-------------------------------------------------------------------*/ -#ifndef DISABLE_LIMITER /*! r: number of clipped output samples */ static int32_t limitRendererOutput( IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ @@ -316,8 +311,8 @@ static int32_t limitRendererOutput( return numClipping; } -#endif +#endif /*-------------------------------------------------------------------* * validateOutputSampleRate() @@ -412,10 +407,10 @@ static ivas_error initHeadRotation( static void initRendInputBase( - input_base *inputBase, + input_base_isar *inputBase, const AUDIO_CONFIG inConfig, const IVAS_REND_InputId id, - const rendering_context rendCtx, + const rendering_context_isar rendCtx, float *dataBuf, const int16_t dataBufSize ) { @@ -437,10 +432,10 @@ static void initRendInputBase( } -static rendering_context getRendCtx( +static rendering_context_isar getRendCtx( ISAR_POST_REND_HANDLE hIvasRend ) { - rendering_context ctx; + rendering_context_isar ctx; /* Note: when refactoring this, always take the ADDRESS of a member of the * renderer struct, so that the context stores a POINTER to the member, even @@ -460,7 +455,7 @@ static ivas_error getRendInputNumChannels( int16_t *numInChannels ) { /* Using a void pointer for this function to be reusable for any input type (input_ism, input_mc, input_sba). - Assumptions: - input_base is always the first member in the input struct */ + Assumptions: - input_base_isar is always the first member in the input struct */ (void) rendInput; *numInChannels = 2; @@ -475,7 +470,7 @@ static ivas_error updateSplitPostRendPanGains( ISAR_SPLIT_REND_CONFIG_DATA *hRendCfg ) { ivas_error error; - rendering_context rendCtx; + rendering_context_isar rendCtx; LC3PLUS_CONFIG config; int16_t iNumBlocksPerFrame, iNumLCLDIterationsPerFrame; @@ -512,8 +507,7 @@ static ivas_error updateSplitPostRendPanGains( } else if ( hRendCfg->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) { - if ( ( error = ISAR_LC3PLUS_DEC_Open( config, - &inputSplitPostRend->splitPostRendWrapper.hLc3plusDec ) ) != IVAS_ERR_OK ) + if ( ( error = ISAR_LC3PLUS_DEC_Open( config, &inputSplitPostRend->splitPostRendWrapper.hLc3plusDec ) ) != IVAS_ERR_OK ) { return error; } @@ -535,7 +529,7 @@ static ivas_error setRendInputActiveSplitPostRend( ISAR_SPLIT_REND_CONFIG_DATA *hRendCfg ) { ivas_error error; - rendering_context rendCtx; + rendering_context_isar rendCtx; AUDIO_CONFIG outConfig; input_split_post_rend *inputSplitPostRend; @@ -563,7 +557,7 @@ static ivas_error setRendInputActiveSplitPostRend( static void clearInputSplitRend( input_split_post_rend *inputSplitRend ) { - rendering_context rendCtx; + rendering_context_isar rendCtx; rendCtx = inputSplitRend->base.ctx; @@ -597,13 +591,13 @@ static void clearInputSplitRend( *------------------------------------------------------------------------*/ ivas_error ISAR_POST_REND_open( - ISAR_POST_REND_HANDLE *phIvasRend, /* i/o: Pointer to renderer handle */ - const int32_t outputSampleRate, /* i : output sampling rate */ - const IVAS_AUDIO_CONFIG outConfig, /* i : output audio config */ - const bool asHrtfBinary, /* i : load hrtf binary file */ - const int16_t nonDiegeticPan, /* i : non-diegetic object flag */ - const float nonDiegeticPanGain, /* i : non-diegetic panning gain */ - const int16_t num_subframes /* i : number of subframes */ + ISAR_POST_REND_HANDLE *phIvasRend, /* i/o: Pointer to renderer handle */ + const int32_t outputSampleRate, /* i : output sampling rate */ + const IVAS_AUDIO_CONFIG outConfig, /* i : output audio config */ + const bool asHrtfBinary, /* i : load hrtf binary file */ + const int16_t nonDiegeticPan, /* i : non-diegetic object flag */ + const float nonDiegeticPanGain, /* i : non-diegetic panning gain */ + const int16_t num_subframes /* i : number of subframes */ ) { int16_t i; @@ -682,8 +676,8 @@ ivas_error ISAR_POST_REND_open( *-------------------------------------------------------------------*/ ivas_error ISAR_POST_REND_NumOutChannels( - ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ - int16_t *numOutChannels /* o : number of output channels */ + ISAR_POST_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ + int16_t *numOutChannels /* o : number of output channels */ ) { /* Validate function arguments */ @@ -716,7 +710,7 @@ static ivas_error getInputById( { int32_t inputIndex; IVAS_REND_AudioConfigType configType; - input_base *pInputBase; + input_base_isar *pInputBase; /* Reverse makeInputId() */ inputIndex = ( inputId & 0xFF ) - 1; @@ -752,6 +746,7 @@ static ivas_error getInputById( return IVAS_ERR_OK; } + /*-------------------------------------------------------------------* * ISAR_POST_REND_SetInputGain() * @@ -764,7 +759,7 @@ ivas_error ISAR_POST_REND_SetInputGain( const float gain /* i : linear gain (not in dB) */ ) { - input_base *inputBase; + input_base_isar *inputBase; ivas_error error; /* Validate function arguments */ @@ -784,6 +779,7 @@ ivas_error ISAR_POST_REND_SetInputGain( return IVAS_ERR_OK; } + static ivas_error getConstInputById( ISAR_POST_REND_CONST_HANDLE hIvasRend, const ISAR_POST_REND_InputId inputId, @@ -791,7 +787,7 @@ static ivas_error getConstInputById( { int32_t inputIndex; IVAS_REND_AudioConfigType configType; - const input_base *pInputBase; + const input_base_isar *pInputBase; /* Reverse makeInputId() */ inputIndex = ( inputId & 0xFF ) - 1; @@ -837,21 +833,21 @@ static ivas_error findFreeInputSlot( /* Using a void pointer and a separately provided size is a hack for this function to be reusable for arrays of any input type (input_ism, input_mc, input_sba, input_masa). Assumptions: - - input_base is always the first member in the input struct + - input_base_isar is always the first member in the input struct - provided size is correct */ int32_t i; bool canAddInput; const uint8_t *pByte; - const input_base *pInputBase; + const input_base_isar *pInputBase; canAddInput = false; /* Find first unused input in array */ for ( i = 0, pByte = inputs; i < maxInputs; ++i, pByte += inputStructSize ) { - pInputBase = (const input_base *) pByte; + pInputBase = (const input_base_isar *) pByte; if ( pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID ) { @@ -886,6 +882,7 @@ ivas_error ISAR_POST_REND_AddInput( int32_t maxNumInputsOfType; void *inputsArray; int32_t inputStructSize; + ivas_error ( *activateInput )( void *, AUDIO_CONFIG, IVAS_REND_InputId, ISAR_SPLIT_REND_CONFIG_DATA * ); int32_t inputIndex; @@ -914,6 +911,7 @@ ivas_error ISAR_POST_REND_AddInput( } *inputId = makeInputId( inConfig, inputIndex ); + if ( ( error = activateInput( (uint8_t *) inputsArray + inputStructSize * inputIndex, inConfig, *inputId, &hIvasRend->splitRenderConfig ) ) != IVAS_ERR_OK ) { return error; @@ -936,7 +934,7 @@ ivas_error ISAR_POST_REND_GetInputNumChannels( ) { ivas_error error; - const input_base *pInput; + const input_base_isar *pInput; /* Validate function arguments */ if ( hIvasRend == NULL || numChannels == NULL ) @@ -1027,7 +1025,7 @@ ivas_error ISAR_POST_REND_FeedInputAudio( ) { ivas_error error; - input_base *inputBase; + input_base_isar *inputBase; int16_t numInputChannels; int16_t cldfb2tdSampleFact; @@ -1158,6 +1156,7 @@ int16_t ISAR_POST_REND_GetRenderConfig( return IVAS_ERR_OK; } + /*-------------------------------------------------------------------* * ISAR_POST_REND_FeedSplitBinauralBitstream() * @@ -1171,7 +1170,7 @@ ivas_error ISAR_POST_REND_FeedSplitBinauralBitstream( ) { ivas_error error; - input_base *inputBase; + input_base_isar *inputBase; input_split_post_rend *inputSplitPostRend; /* Validate function arguments */ @@ -1248,8 +1247,8 @@ ivas_error ISAR_POST_REND_SetHeadRotation( *-------------------------------------------------------------------*/ ivas_error ISAR_POST_REND_SetSplitRendBFI( - ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - const int16_t bfi /* i: BFI flag */ + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const int16_t bfi /* i : BFI flag */ ) { hIvasRend->splitRendBFI = bfi; @@ -1262,7 +1261,6 @@ ivas_error ISAR_POST_REND_SetSplitRendBFI( * Local functions *-------------------------------------------------------------------*/ - static ivas_error splitBinLc3plusDecode( ISAR_SPLIT_POST_REND_WRAPPER *hSplitBin, ISAR_SPLIT_REND_BITS_HANDLE bits, @@ -1288,6 +1286,7 @@ static ivas_error splitBinLc3plusDecode( { ++bits->bits_read; } + /* Size is in bytes */ assert( ( bits->bits_written - bits->bits_read ) % 8 == 0 ); lc3plusBitstreamSize = ( bits->bits_written - bits->bits_read ) / 8; @@ -1349,7 +1348,6 @@ static ivas_error renderSplitBinauralWithPostRot( hSplitBin = &splitBinInput->splitPostRendWrapper; convertBitsBufferToInternalBitsBuff( *splitBinInput->hBits, &bits ); - iNumLCLDIterationsPerFrame = 1; iNumBlocksPerFrame = CLDFB_NO_COL_MAX; if ( splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec != NULL ) @@ -1393,6 +1391,7 @@ static ivas_error renderSplitBinauralWithPostRot( { isPostRendInputCldfb = 1; } + numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * bits.isar_frame_size_ms / 1000 ) - outBufNumSamplesPerChannel; outBufNumColPerChannel = MAX_PARAM_SPATIAL_SUBFRAMES; @@ -1436,8 +1435,7 @@ static ivas_error renderSplitBinauralWithPostRot( } else { - if ( ( error = splitBinLc3plusDecode( hSplitBin, &bits, tmpCrendBuffer, - SplitRendBFI ) ) != IVAS_ERR_OK ) + if ( ( error = splitBinLc3plusDecode( hSplitBin, &bits, tmpCrendBuffer, SplitRendBFI ) ) != IVAS_ERR_OK ) { return error; } @@ -1571,6 +1569,7 @@ static ivas_error renderSplitBinauralWithPostRot( return error; } + static ivas_error renderInputSplitBin( input_split_post_rend *splitBinInput, const AUDIO_CONFIG outConfig, @@ -1602,6 +1601,7 @@ static ivas_error renderInputSplitBin( return error; } + static ivas_error renderActiveInputsSplitBin( ISAR_POST_REND_HANDLE hIvasRend, IVAS_REND_AudioBuffer outAudio ) @@ -1696,6 +1696,7 @@ ivas_error ISAR_POST_REND_getSamples( return IVAS_ERR_OK; } + /*-------------------------------------------------------------------* * ISAR_POST_REND_GetSplitBinauralSamples() * @@ -1703,8 +1704,8 @@ ivas_error ISAR_POST_REND_getSamples( *-------------------------------------------------------------------*/ ivas_error ISAR_POST_REND_GetSplitBinauralSamples( - ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ bool *needNewFrame ) { ivas_error error; @@ -1753,25 +1754,32 @@ void ISAR_POST_REND_Close( } +/*-------------------------------------------------------------------* + * ISAR_REND_SetSplitRendBitstreamHeader() + * + * + *-------------------------------------------------------------------*/ + ivas_error ISAR_REND_SetSplitRendBitstreamHeader( - ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ - const ISAR_SPLIT_REND_CODEC codec, /* o: codec setting */ - const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, /* o: pose correction mode */ - const int16_t codec_frame_size_ms /* i: codec frame size setting */ - , - const int16_t isar_frame_size_ms, /* i: isar codec frame size setting */ - const int16_t lc3plus_highres /* i: LC3plus Hig-Res setting. Ignored if codec is not LC3plus */ + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + const ISAR_SPLIT_REND_CODEC codec, /* o : codec setting */ + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, /* o : pose correction mode */ + const int16_t codec_frame_size_ms, /* i : codec frame size setting */ + const int16_t isar_frame_size_ms, /* i : ISAR codec frame size setting */ + const int16_t lc3plus_highres /* i : LC3plus Hig-Res setting. Ignored if codec is not LC3plus */ ) { if ( hIvasRend == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + hIvasRend->splitRenderConfig.codec = codec; hIvasRend->splitRenderConfig.isar_frame_size_ms = isar_frame_size_ms; hIvasRend->splitRenderConfig.codec_frame_size_ms = codec_frame_size_ms; hIvasRend->splitRenderConfig.poseCorrectionMode = poseCorrection; hIvasRend->splitRenderConfig.lc3plus_highres = lc3plus_highres; + return IVAS_ERR_OK; } @@ -1788,8 +1796,15 @@ int32_t ISAR_POST_REND_GetNoCLipping( return hIvasRend->numClipping; } + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_GetCntFramesLimited() + * + * + *-------------------------------------------------------------------*/ + int32_t ISAR_POST_REND_GetCntFramesLimited( - ISAR_POST_REND_CONST_HANDLE hIvasRend ) + ISAR_POST_REND_HANDLE hIvasRend ) { if ( hIvasRend->hLimiter == NULL ) { diff --git a/lib_isar/lib_isar_post_rend.h b/lib_isar/lib_isar_post_rend.h index ce701d577cbb020797b65158ba94fbe8405588af..e1f91a47690167ece73060b96a24329a4d4454d2 100644 --- a/lib_isar/lib_isar_post_rend.h +++ b/lib_isar/lib_isar_post_rend.h @@ -38,14 +38,14 @@ /*---------------------------------------------------------------------* - * Renderer constants + * ISAR post-renderer constants *---------------------------------------------------------------------*/ #define RENDERER_MAX_ISAR_MD_INPUTS 1 #define RENDERER_MAX_BIN_INPUTS 1 /*---------------------------------------------------------------------* - * Renderer structures + * ISAR post-renderer structures *---------------------------------------------------------------------*/ typedef struct @@ -93,7 +93,7 @@ typedef enum _ISAR_POST_REND_COMPLEXITY_LEVEL /* clang-format off */ /*----------------------------------------------------------------------------------* - * Renderer function prototypes + * ISAR post-renderer function prototypes *----------------------------------------------------------------------------------*/ /* Functions to be called before rendering */ @@ -179,13 +179,13 @@ ivas_error ISAR_POST_REND_SetHeadRotation( ivas_error ISAR_POST_REND_SetSplitRendBFI( ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - const int16_t bfi /* i: BFI flag */ + const int16_t bfi /* i : BFI flag */ ); ivas_error ISAR_POST_REND_getSamples( ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ + IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ ); /* Functions to be called after rendering */ @@ -196,21 +196,20 @@ void ISAR_POST_REND_Close( ivas_error ISAR_REND_SetSplitRendBitstreamHeader( ISAR_POST_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ - const ISAR_SPLIT_REND_CODEC codec, /* o: codec setting */ - const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, /* o: pose correction mode */ - const int16_t codec_frame_size_ms /* i: codec frame size setting */ - , - const int16_t isar_frame_size_ms, /* i: isar frame size setting */ - const int16_t lc3plus_highres /* i: LC3plus Hig-Res setting. Ignored if codec is not LC3plus */ + const ISAR_SPLIT_REND_CODEC codec, /* o : codec setting */ + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, /* o : pose correction mode */ + const int16_t codec_frame_size_ms, /* i : codec frame size setting */ + const int16_t isar_frame_size_ms, /* i : ISAR codec frame size setting */ + const int16_t lc3plus_highres /* i : LC3plus Hig-Res setting. Ignored if codec is not LC3plus */ ); #ifdef DEBUGGING int32_t ISAR_POST_REND_GetNoCLipping( - ISAR_POST_REND_HANDLE hIvasRend /* i : Renderer handle */ + ISAR_POST_REND_HANDLE hIvasRend /* i : Renderer handle */ ); int32_t ISAR_POST_REND_GetCntFramesLimited( - ISAR_POST_REND_CONST_HANDLE hIvasRend /* i : Renderer handle */ + ISAR_POST_REND_HANDLE hIvasRend /* i : Renderer handle */ ); #endif diff --git a/lib_isar/lib_isar_pre_rend.c b/lib_isar/lib_isar_pre_rend.c index ddb663f2245026ab9175f5037901cf50f8dac9db..5318d217b26a49fc302653656ce747b162b54988 100644 --- a/lib_isar/lib_isar_pre_rend.c +++ b/lib_isar/lib_isar_pre_rend.c @@ -46,22 +46,6 @@ #include "wmc_auto.h" -/*-------------------------------------------------------------------* - * Local constants - *-------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------* - * Local types - *-------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------* - * Local function prototypes - *-------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------* - * Local functions - *-------------------------------------------------------------------*/ - /*------------------------------------------------------------------------- * Function ISAR_PRE_REND_open() * @@ -69,25 +53,20 @@ *------------------------------------------------------------------------*/ ivas_error ISAR_PRE_REND_open( - SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */ - ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i/o: Split renderer pre-renerer config */ - const int32_t output_Fs, /* i: output sampling rate */ - const int16_t cldfb_in_flag, /* i: Flag to indicate CLDFB or time doamin input */ - const int16_t pcm_out_flag, /* i: Flag to indicate PCM output */ - const IVAS_RENDER_FRAMESIZE ivas_frame_size, /* i: IVAS frame size */ - const int16_t mixed_td_cldfb_flag /* i: Flag to indicate combined TD and CLDFB input */ + SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renderer handle */ + ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i/o: Split renderer pre-renderer config */ + const int32_t output_Fs, /* i : output sampling rate */ + const int16_t cldfb_in_flag, /* i : Flag to indicate CLDFB or time doamin input */ + const int16_t pcm_out_flag, /* i : Flag to indicate PCM output */ + const IVAS_RENDER_FRAMESIZE ivas_frame_size, /* i : IVAS frame size */ + const int16_t mixed_td_cldfb_flag /* i : Flag to indicate combined TD and CLDFB input */ ) { ivas_error error, ch, num_ch; uint8_t isCldfbNeeded = 0; - int16_t cldfb_in_flag_local = cldfb_in_flag; - if ( ( error = isar_split_rend_choose_default_codec( &( pSplitRendConfig->codec ), - &pSplitRendConfig->isar_frame_size_ms, - &pSplitRendConfig->codec_frame_size_ms, - cldfb_in_flag_local, - pcm_out_flag, (int16_t) ivas_frame_size ) ) != IVAS_ERR_OK ) + if ( ( error = isar_split_rend_choose_default_codec( &( pSplitRendConfig->codec ), &pSplitRendConfig->isar_frame_size_ms, &pSplitRendConfig->codec_frame_size_ms, cldfb_in_flag_local, pcm_out_flag, (int16_t) ivas_frame_size ) ) != IVAS_ERR_OK ) { return error; } @@ -136,9 +115,7 @@ ivas_error ISAR_PRE_REND_open( for ( ch = 0; ch < num_ch; ch++ ) { - if ( ( error = openCldfb( &( hSplitBinRend->hCldfbHandles->cldfbAna[ch] ), - CLDFB_ANALYSIS, - output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + if ( ( error = openCldfb( &( hSplitBinRend->hCldfbHandles->cldfbAna[ch] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) { return error; } @@ -155,12 +132,11 @@ ivas_error ISAR_PRE_REND_open( if ( pSplitRendConfig->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { - if ( ( error = isar_splitBinPreRendOpen( &hSplitBinRend->hBinHrSplitPreRend, &hSplitBinRend->multiBinPoseData #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - , - OutSampleRate + if ( ( error = isar_splitBinPreRendOpen( &hSplitBinRend->hBinHrSplitPreRend, &hSplitBinRend->multiBinPoseData, OutSampleRate ) ) != IVAS_ERR_OK ) +#else + if ( ( error = isar_splitBinPreRendOpen( &hSplitBinRend->hBinHrSplitPreRend, &hSplitBinRend->multiBinPoseData ) ) != IVAS_ERR_OK ) #endif - ) ) != IVAS_ERR_OK ) { return error; } @@ -170,8 +146,7 @@ ivas_error ISAR_PRE_REND_open( { if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) { - if ( ( error = split_renderer_open_lc3plus( hSplitBinRend, pSplitRendConfig, output_Fs, - ivas_frame_size ) ) != IVAS_ERR_OK ) + if ( ( error = split_renderer_open_lc3plus( hSplitBinRend, pSplitRendConfig, output_Fs, ivas_frame_size ) ) != IVAS_ERR_OK ) { return error; } @@ -191,6 +166,7 @@ ivas_error ISAR_PRE_REND_open( return IVAS_ERR_OK; } + /*------------------------------------------------------------------------- * Function ISAR_PRE_REND_close() * @@ -198,8 +174,8 @@ ivas_error ISAR_PRE_REND_open( *------------------------------------------------------------------------*/ void ISAR_PRE_REND_close( - SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */ - IVAS_REND_AudioBuffer *pSplitRendEncBuffer /* i/o: Split renderer data buffer */ + SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renderer handle */ + IVAS_REND_AudioBuffer *pSplitRendEncBuffer /* i/o: Split renderer data buffer */ ) { int16_t i; @@ -270,6 +246,7 @@ void ISAR_PRE_REND_close( return; } + /*-------------------------------------------------------------------------* * ISAR_PRE_REND_GetMultiBinPoseData() * @@ -277,14 +254,17 @@ void ISAR_PRE_REND_close( *-------------------------------------------------------------------------*/ void ISAR_PRE_REND_GetMultiBinPoseData( - const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i: Split renderer pre-renerer config */ - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ - const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i: Rotation axis */ + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i : Split renderer pre-renderer config */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i : Rotation axis */ ) { isar_renderSplitGetMultiBinPoseData( pSplit_rend_config, pMultiBinPoseData, rot_axis ); + + return; } + /*------------------------------------------------------------------------- * Function ISAR_PRE_REND_MultiBinToSplitBinaural() * @@ -303,8 +283,8 @@ ivas_error ISAR_PRE_REND_MultiBinToSplitBinaural( float *Cldfb_In_BinReal[][CLDFB_NO_COL_MAX], /* i/o: CLDFB real buffer */ float *Cldfb_In_BinImag[][CLDFB_NO_COL_MAX], /* i/o: CLDFB imag buffer */ #else - float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB real buffer */ - float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB imag buffer */ + float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB real buffer */ + float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB imag buffer */ #endif const int16_t max_bands, /* i : CLDFB bands */ float *output[], /* i/o: PCM in/out buffer */ @@ -330,17 +310,7 @@ ivas_error ISAR_PRE_REND_MultiBinToSplitBinaural( { /*TD input*/ /*if CLDFB handles have been allocated then assume valid multi binaural input in out[][] buffer and perform CLDFB analysis*/ - error = isar_renderMultiTDBinToSplitBinaural( hSplitBin, - headPosition, - SplitRendBitRate, - isar_frame_size_ms, - codec_frame_size_ms, - pBits, - max_bands, - output, - low_res_pre_rend_rot, - pcm_out_flag, - ro_md_flag ); + error = isar_renderMultiTDBinToSplitBinaural( hSplitBin, headPosition, SplitRendBitRate, isar_frame_size_ms, codec_frame_size_ms, pBits, max_bands, output, low_res_pre_rend_rot, pcm_out_flag, ro_md_flag ); pop_wmops(); return error; @@ -392,7 +362,6 @@ ivas_error ISAR_PRE_REND_MultiBinToSplitBinaural( cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * num_slots, hSplitBin->hCldfbHandles->cldfbSyn[ch] ); } - if ( pBits->pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) { available_bits = isar_get_lc3plus_bitrate( SplitRendBitRate, hSplitBin->multiBinPoseData.poseCorrectionMode, hSplitBin->hLc3plusEnc->config.channels, hSplitBin->hLc3plusEnc->config.lc3plus_frame_duration_us ) / FRAMES_PER_SEC; @@ -401,6 +370,7 @@ ivas_error ISAR_PRE_REND_MultiBinToSplitBinaural( { available_bits = ( SplitRendBitRate / FRAMES_PER_SEC ) - pBits->bits_written; } + if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, available_bits, output ) ) != IVAS_ERR_OK ) { return error; diff --git a/lib_isar/lib_isar_pre_rend.h b/lib_isar/lib_isar_pre_rend.h index f11530e09668fdf8283435026408f0bdf110a792..e1124a714cba32b68e23c2f900692d1f82e0efbf 100644 --- a/lib_isar/lib_isar_pre_rend.h +++ b/lib_isar/lib_isar_pre_rend.h @@ -37,48 +37,54 @@ #include "isar_prot.h" +/* clang-format off */ +/*----------------------------------------------------------------------------------* + * ISAR pre-renderer function prototypes + *----------------------------------------------------------------------------------*/ + ivas_error ISAR_PRE_REND_open( - SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */ - ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i/o: Split renderer pre-renerer config */ - const int32_t output_Fs, /* i: output sampling rate */ - const int16_t cldfb_in_flag, /* i: Flag to indicate CLDFB or time doamin input */ - const int16_t pcm_out_flag, /* i: Flag to indicate PCM output */ - const IVAS_RENDER_FRAMESIZE ivas_frame_size, /* i: IVAS frame size */ - const int16_t mixed_td_cldfb_flag /* i: Flag to indicate combined TD and CLDFB input */ + SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */ + ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, /* i/o: Split renderer pre-renerer config */ + const int32_t output_Fs, /* i : output sampling rate */ + const int16_t cldfb_in_flag, /* i : Flag to indicate CLDFB or time doamin input */ + const int16_t pcm_out_flag, /* i : Flag to indicate PCM output */ + const IVAS_RENDER_FRAMESIZE ivas_frame_size, /* i : IVAS frame size */ + const int16_t mixed_td_cldfb_flag /* i : Flag to indicate combined TD and CLDFB input */ ); void ISAR_PRE_REND_close( - SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renerer handle */ - IVAS_REND_AudioBuffer *pSplitRendEncBuffer /* i/o: Split renderer data buffer */ + SPLIT_REND_WRAPPER *hSplitBinRend, /* i/o: Split renderer pre-renderer handle */ + IVAS_REND_AudioBuffer *pSplitRendEncBuffer /* i/o: Split renderer data buffer */ ); void ISAR_PRE_REND_GetMultiBinPoseData( - const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i: Split renderer pre-renerer config */ - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ - const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i: Rotation axis */ + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i : Split renderer pre-renderer config */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i : Rotation axis */ ); ivas_error ISAR_PRE_REND_MultiBinToSplitBinaural( - SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renerer handle */ - const IVAS_QUATERNION headPosition, /* i: head rotation QUATERNION */ - const int32_t SplitRendBitRate, /* i: Split renderer bitrate */ - ISAR_SPLIT_REND_CODEC splitCodec, /* i/o: Split renderer codec */ - const int16_t isar_frame_size_ms, /* i: ISAR framesize */ - int16_t codec_frame_size_ms, /* i/o: ISAR transport codec framesize */ - ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits struct handle */ + SPLIT_REND_WRAPPER *hSplitBin, /* i/o: Split renderer pre-renerer handle */ + const IVAS_QUATERNION headPosition, /* i : head rotation QUATERNION */ + const int32_t SplitRendBitRate, /* i : Split renderer bitrate */ + ISAR_SPLIT_REND_CODEC splitCodec, /* i/o: Split renderer codec */ + const int16_t isar_frame_size_ms, /* i : ISAR framesize */ + int16_t codec_frame_size_ms, /* i/o: ISAR transport codec framesize */ + ISAR_SPLIT_REND_BITS_HANDLE pBits, /* i/o: ISAR bits struct handle */ #ifdef FIX_1119_SPLIT_RENDERING_VOIP - float *Cldfb_In_BinReal[][CLDFB_NO_COL_MAX], /* i/o: CLDFB real buffer */ - float *Cldfb_In_BinImag[][CLDFB_NO_COL_MAX], /* i/o: CLDFB imag buffer */ + float* Cldfb_In_BinReal[][CLDFB_NO_COL_MAX], /* i/o: CLDFB real buffer */ + float* Cldfb_In_BinImag[][CLDFB_NO_COL_MAX], /* i/o: CLDFB imag buffer */ #else - float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB real buffer */ - float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB imag buffer */ + float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB real buffer */ + float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o: CLDFB imag buffer */ #endif - const int16_t max_bands, /* i: CLDFB bands */ - float *output[], /* i/o: PCM in/out buffer */ - const int16_t low_res_pre_rend_rot, /* i: low time resolution pre-renderer flag */ - const int16_t cldfb_in_flag, /* i: Flag to indicate CLDFB or time doamin input */ - const int16_t pcm_out_flag, /* i: Flag to indicate PCM output */ - const int16_t ro_md_flag /* i: Flag to indicate real only metadata for yaw */ + const int16_t max_bands, /* i : CLDFB bands */ + float *output[], /* i/o: PCM in/out buffer */ + const int16_t low_res_pre_rend_rot, /* i : low time resolution pre-renderer flag */ + const int16_t cldfb_in_flag, /* i : Flag to indicate CLDFB or time doamin input */ + const int16_t pcm_out_flag, /* i : Flag to indicate PCM output */ + const int16_t ro_md_flag /* i : Flag to indicate real only metadata for yaw */ ); +/* clang-format on */ #endif /* LIB_ISAR_PRE_REND_H */ diff --git a/lib_lc3plus/lc3plus.c b/lib_lc3plus/lc3plus.c index c8a529021a9a18248bf85d8e7a2276d2a1d2261d..594683cd2c7ea80bec716871779ed4e1b0d8b0e1 100644 --- a/lib_lc3plus/lc3plus.c +++ b/lib_lc3plus/lc3plus.c @@ -79,7 +79,7 @@ static int lc3plus_frame_size_supported(LC3PLUS_FrameDuration frame_dms) return 1; default: break; } - + return 0; } diff --git a/lib_rend/ivas_cldfb_ring_buffer.c b/lib_rend/ivas_cldfb_ring_buffer.c index 669227540e063f5d156efa86fd99ad5676c27867..5d1d2a055cbb50b71f732330d2091d252b3bf1d7 100644 --- a/lib_rend/ivas_cldfb_ring_buffer.c +++ b/lib_rend/ivas_cldfb_ring_buffer.c @@ -75,7 +75,7 @@ static int16_t ivas_cldfb_ringbuf_IsFull( /*---------------------------------------------------------------------* * ivas_CLDFB_RINGBUF_Open() * - * Allocates a ring buffer for CLDFB data with the given capacity of CLDFB columns. + * Allocate a ring buffer for CLDFB data with the given capacity of CLDFB columns. * Each column is expected to contain at most CLDFB_NO_CHANNELS_MAX frequency bands. * * May return IVAS_ERR_FAILED_ALLOC on failed allocation, or IVAS_ERR_OK otherwise. @@ -88,7 +88,7 @@ ivas_error ivas_CLDFB_RINGBUF_Open( ISAR_CLDFB_RINGBUF_HANDLE h; int32_t capacity; - capacity = (int32_t) capacity_columns * CLDFB_NO_CHANNELS_MAX; + capacity = capacity_columns * CLDFB_NO_CHANNELS_MAX; if ( ( h = malloc( sizeof( ISAR_CLDFB_RINGBUF ) ) ) == NULL ) { @@ -119,7 +119,7 @@ ivas_error ivas_CLDFB_RINGBUF_Open( /*---------------------------------------------------------------------* * ivas_CLDFB_RINGBUF_Close() * - * Dellocates CLDFB ring buffer. The given handle will be set to NULL. + * Dellocate CLDFB ring buffer. The given handle will be set to NULL. *---------------------------------------------------------------------*/ void ivas_CLDFB_RINGBUF_Close( @@ -190,7 +190,7 @@ void ivas_CLDFB_RINGBUF_Push( /*---------------------------------------------------------------------* * ivas_CLDFB_RINGBUF_Pop() * - * Pops a single column from the front of the CLDFB ring buffer into real and imag arrays. + * Pop a single column from the front of the CLDFB ring buffer into real and imag arrays. *---------------------------------------------------------------------*/ void ivas_CLDFB_RINGBUF_Pop( @@ -229,7 +229,7 @@ void ivas_CLDFB_RINGBUF_Pop( * Returns total number of buffered samples (including number of channels) *---------------------------------------------------------------------*/ -static int32_t ivas_cldfb_ringbuf_total_size( +static uint32_t ivas_cldfb_ringbuf_total_size( ISAR_CLDFB_RINGBUF_HANDLE h ) { if ( ivas_cldfb_ringbuf_IsFull( h ) ) @@ -265,8 +265,8 @@ void ivas_CLDFB_RINGBUF_GetByIdx( const int16_t col_idx ) { int32_t idx = col_idx * CLDFB_NO_CHANNELS_MAX; - int32_t num_floats = ivas_cldfb_ringbuf_total_size( h ); - int32_t offset; + int32_t num_floats = (int32_t) ivas_cldfb_ringbuf_total_size( h ); + uint32_t offset, uidx; assert( -num_floats <= idx && idx <= num_floats ); @@ -280,13 +280,14 @@ void ivas_CLDFB_RINGBUF_GetByIdx( } else { - if ( -idx <= h->write_pos ) + uidx = (uint32_t) -idx; + if ( uidx <= h->write_pos ) { - offset = h->write_pos + idx; + offset = h->write_pos - uidx; } else { - offset = h->write_pos + h->capacity + idx; + offset = h->write_pos + h->capacity - uidx; } } diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index c153f3669c11de767eea8d9e8e086e481f7c3c9d..91346675023091f478cd4a637e93d0347e1d052e 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -46,6 +46,7 @@ #endif #include "wmc_auto.h" + /*------------------------------------------------------------------------- * ivas_Crend_hrtf_init() * @@ -74,15 +75,11 @@ ivas_error ivas_Crend_hrtf_init( { for ( j = 0; j < BINAURAL_CHANNELS; j++ ) { - hHrtf->inv_diffuse_weight[j][i] = 0; hHrtf->num_iterations[i][j] = 0; hHrtf->pIndex_frequency_max[i][j] = NULL; hHrtf->pOut_to_bin_re[i][j] = NULL; hHrtf->pOut_to_bin_im[i][j] = NULL; - hHrtf->pOut_to_bin_re_dyn[i][j] = NULL; - hHrtf->pOut_to_bin_im_dyn[i][j] = NULL; - hHrtf->pIndex_frequency_max_dyn[i][j] = NULL; } } @@ -92,9 +89,6 @@ ivas_error ivas_Crend_hrtf_init( hHrtf->pIndex_frequency_max_diffuse[j] = NULL; hHrtf->pOut_to_bin_diffuse_re[j] = NULL; hHrtf->pOut_to_bin_diffuse_im[j] = NULL; - hHrtf->pIndex_frequency_max_diffuse_dyn[j] = NULL; - hHrtf->pOut_to_bin_diffuse_re_dyn[j] = NULL; - hHrtf->pOut_to_bin_diffuse_im_dyn[j] = NULL; } hHrtf->init_from_rom = 1; @@ -110,15 +104,15 @@ ivas_error ivas_Crend_hrtf_init( *------------------------------------------------------------------------*/ static ivas_error ivas_hrtf_open( - HRTFS_HANDLE *hHrtf_out /* o : HRTF handle */ + HRTFS_CREND_HANDLE *hHrtf_out /* o : HRTF handle */ ) { - HRTFS_HANDLE hHrtf; + HRTFS_CREND_HANDLE hHrtf; ivas_error error; if ( *hHrtf_out == NULL ) { - if ( ( hHrtf = (HRTFS_HANDLE) malloc( sizeof( HRTFS_DATA ) ) ) == NULL ) + if ( ( hHrtf = (HRTFS_CREND_HANDLE) malloc( sizeof( HRTFS_CREND_DATA ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend HRTFS Handle\n" ); } @@ -146,7 +140,7 @@ static ivas_error ivas_hrtf_open( *------------------------------------------------------------------------*/ static void ivas_hrtf_close( - HRTFS_HANDLE *hHrtf /* i/o: HRTF handle */ + HRTFS_CREND_HANDLE *hHrtf /* i/o: Crend HRTF handle */ ) { if ( hHrtf == NULL || *hHrtf == NULL ) @@ -160,6 +154,7 @@ static void ivas_hrtf_close( return; } + /*------------------------------------------------------------------------- * ivas_rend_initCrend() * @@ -307,6 +302,7 @@ static ivas_error ivas_rend_initCrend( if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) { hHrtf->latency_s = CRendBin_Combined_BRIR_latency_s; + hHrtf->max_num_iterations = CRendBin_Combined_BRIR_max_num_iterations_16kHz; hHrtf->index_frequency_max_diffuse = CRendBin_Combined_BRIR_index_frequency_max_diffuse_16kHz; } @@ -418,7 +414,6 @@ static ivas_error ivas_rend_initCrend( if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) { hHrtf->inv_diffuse_weight[j][i] = CRendBin_Combined_BRIR_inv_diffuse_weight_16kHz[j][tmp]; - hHrtf->num_iterations[i][j] = CRendBin_Combined_BRIR_num_iterations_16kHz[tmp][j]; hHrtf->pIndex_frequency_max[i][j] = CRendBin_Combined_BRIR_pIndex_frequency_max_16kHz[tmp][j]; hHrtf->pOut_to_bin_re[i][j] = CRendBin_Combined_BRIR_coeff_re_16kHz[tmp][j]; @@ -427,7 +422,6 @@ static ivas_error ivas_rend_initCrend( else { hHrtf->inv_diffuse_weight[j][i] = CRendBin_Combined_HRIR_inv_diffuse_weight_16kHz[j][tmp]; - hHrtf->num_iterations[i][j] = CRendBin_Combined_HRIR_num_iterations_16kHz[tmp][j]; hHrtf->pIndex_frequency_max[i][j] = CRendBin_Combined_HRIR_pIndex_frequency_max_16kHz[tmp][j]; hHrtf->pOut_to_bin_re[i][j] = CRendBin_Combined_HRIR_coeff_re_16kHz[tmp][j]; @@ -453,7 +447,6 @@ static ivas_error ivas_rend_initCrend( for ( i = 0; i < hHrtf->max_num_ir; i++ ) { - for ( j = 0; j < BINAURAL_CHANNELS; j++ ) { hHrtf->inv_diffuse_weight[j][i] = CRendBin_HOA3_HRIR_inv_diffuse_weight_48kHz[j][i]; @@ -479,7 +472,6 @@ static ivas_error ivas_rend_initCrend( for ( i = 0; i < hHrtf->max_num_ir; i++ ) { - for ( j = 0; j < BINAURAL_CHANNELS; j++ ) { hHrtf->inv_diffuse_weight[j][i] = CRendBin_HOA3_HRIR_inv_diffuse_weight_32kHz[j][i]; @@ -539,7 +531,6 @@ static ivas_error ivas_rend_initCrend( for ( i = 0; i < hHrtf->max_num_ir; i++ ) { - for ( j = 0; j < BINAURAL_CHANNELS; j++ ) { hHrtf->inv_diffuse_weight[j][i] = CRendBin_HOA2_HRIR_inv_diffuse_weight_48kHz[j][i]; @@ -565,7 +556,6 @@ static ivas_error ivas_rend_initCrend( for ( i = 0; i < hHrtf->max_num_ir; i++ ) { - for ( j = 0; j < BINAURAL_CHANNELS; j++ ) { hHrtf->inv_diffuse_weight[j][i] = CRendBin_HOA2_HRIR_inv_diffuse_weight_32kHz[j][i]; @@ -828,7 +818,6 @@ static ivas_error ivas_rend_initCrend( if ( hHrtf->inv_diffuse_weight[0][i] != hHrtf->inv_diffuse_weight[1][i] ) { hHrtf->same_inv_diffuse_weight = 0; - break; } } } @@ -1086,6 +1075,7 @@ ivas_error ivas_rend_initCrendWrapper( ( *pCrend )->binaural_latency_ns = 0; ( *pCrend )->hHrtfCrend = NULL; + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) { ( *pCrend )->hCrend[pos_idx] = NULL; @@ -1168,13 +1158,11 @@ ivas_error ivas_rend_openCrend( { int16_t i, subframe_length; int32_t max_total_ir_len; - HRTFS_HANDLE hHrtf; + HRTFS_CREND_HANDLE hHrtf; CREND_HANDLE hCrend; ivas_error error; int16_t pos_idx; - error = IVAS_ERR_OK; - if ( ( error = ivas_rend_initCrendWrapper( pCrend, num_poses ) ) != IVAS_ERR_OK ) { return error; @@ -1247,6 +1235,7 @@ ivas_error ivas_rend_openCrend( { set_zero_l( hCrend->freq_buffer_re_diffuse[1], max_total_ir_len ); } + if ( ( hCrend->freq_buffer_im_diffuse[0] = (float *) malloc( sizeof( float ) * max_total_ir_len ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); @@ -1275,7 +1264,8 @@ ivas_error ivas_rend_openCrend( hCrend->freq_buffer_re_diffuse[1] = NULL; hCrend->freq_buffer_im_diffuse[1] = NULL; } - max_total_ir_len = (int32_t) ( hHrtf->latency_s * output_Fs + 0.5f ) + subframe_length; + + max_total_ir_len = (int16_t) ( hHrtf->latency_s * output_Fs + 0.5f ) + subframe_length; if ( max_total_ir_len > 0 ) { if ( ( hCrend->lfe_delay_line = (float *) malloc( sizeof( float ) * max_total_ir_len ) ) == NULL ) @@ -1513,13 +1503,8 @@ static ivas_error ivas_rend_crendConvolver( const float *pFreq_filt_re, *pFreq_filt_im; float *pFreq_buf_re = NULL, *pFreq_buf_im = NULL; float *pFreq_buf2_re = NULL, *pFreq_buf2_im = NULL; -#ifdef FIX_RENDERER_STACK - float pOut[2 /*Re,Im*/ * L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; - float tmp_out_re[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES], tmp_out_im[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; -#else float pOut[2 /*Re,Im*/ * L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; float tmp_out_re[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES], tmp_out_im[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; -#endif CREND_HANDLE hCrend; ivas_error error; @@ -1813,9 +1798,9 @@ ivas_error ivas_rend_crendProcessSubframe( if ( hDecoderConfig && combinedOrientationEnabled ) { /* Rotation in SHD for: - MC with elevation (5_1_2 / 5_1_4 / 7_1_4) -> BINAURAL - SBA SPAR -> BINAURAL or BINAURAL_ROOM - */ + MC with elevation (5_1_2 / 5_1_4 / 7_1_4) -> BINAURAL + SBA SPAR -> BINAURAL or BINAURAL_ROOM + */ if ( inConfig == IVAS_AUDIO_CONFIG_FOA || inConfig == IVAS_AUDIO_CONFIG_HOA2 || inConfig == IVAS_AUDIO_CONFIG_HOA3 ) { rotateFrame_shd( hCombinedOrientationData, tc_local, subframe_len, *hIntSetup, 0 ); @@ -1912,7 +1897,6 @@ ivas_error ivas_rend_crendProcessSubframesSplitBin( float tmpInputBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; float *p_tmpInputBuffer[MAX_OUTPUT_CHANNELS]; float tmpSplitBinBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - COMBINED_ORIENTATION_DATA combinedOrientationDataLocal; COMBINED_ORIENTATION_HANDLE pCombinedOrientationDataLocal; diff --git a/lib_rend/ivas_dirac_ana.c b/lib_rend/ivas_dirac_ana.c index 973182504a5cca5f4ab1d3949a9d124f22567756..73c2db15c66c5e3f8ea51c99a22a9844e2cd0381 100644 --- a/lib_rend/ivas_dirac_ana.c +++ b/lib_rend/ivas_dirac_ana.c @@ -231,17 +231,14 @@ void ivas_dirac_ana( float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; float surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - /* Estimate MASA parameters from the SBA signals */ ivas_dirac_param_est_ana( hDirAC, data_in_f, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence, input_frame ); -#ifdef NONBE_1344_REND_MASA_LOW_FS /* Add zeros to higher bands in case of lower sampling rates */ if ( hDirAC->nbands < MASA_FREQUENCY_BANDS ) { ivas_masa_zero_high_bands( hDirAC->nbands, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence ); } -#endif /* Create MASA metadata buffer from the estimated values */ ivas_create_masa_out_meta( hDirAC->hMasaOut, hDirAC->sph_grid16, nchan_transport, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence ); diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index b0578f92c21f6c33462ec2119afdd6813d6bd1af..6a162142e88a00a1031a2e4d3b67b2a4e4a8ce67 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -122,6 +122,7 @@ static void matrixTransp2Mul( float Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS], f static void ivas_masa_ext_rend_parambin_internal( MASA_EXT_REND_HANDLE hMasaExtRend, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, float *output_f[], const int16_t subframe, const SPLIT_REND_WRAPPER *hSplitRendWrapper, float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] ); + /*------------------------------------------------------------------------- * ivas_dirac_dec_init_binaural_data() * @@ -172,10 +173,6 @@ ivas_error ivas_dirac_dec_init_binaural_data( hDiracDecBin->phHrtfParambin = NULL; } - output_Fs = st_ivas->hDecoderConfig->output_Fs; - nBins = st_ivas->hSpatParamRendCom->num_freq_bands; - renderer_type = st_ivas->renderer_type; - for ( j = 0; j < BINAURAL_CHANNELS; j++ ) { for ( k = 0; k < BINAURAL_CHANNELS + MAX_NUM_OBJECTS; k++ ) @@ -198,6 +195,7 @@ ivas_error ivas_dirac_dec_init_binaural_data( set_zero( hDiracDecBin->ChCrossImOutPrev, nBins ); hDiracDecBin->renderStereoOutputInsteadOfBinaural = 0; + for ( bin = 0; bin < nBins; bin++ ) { binCenterFreq = ( (float) bin + CLDFB_HALF_BIN_FREQUENCY_OFFSET ) / (float) nBins * ( (float) output_Fs / 2.0f ); @@ -287,6 +285,7 @@ ivas_error ivas_dirac_dec_init_binaural_data( if ( !hDiracDecBin->useTdDecorr && !( st_ivas->ivas_format == ISM_FORMAT && st_ivas->ism_mode == ISM_MODE_PARAM ) ) { ivas_dirac_dec_get_frequency_axis( frequency_axis, output_Fs, nBins ); + if ( ( error = ivas_dirac_dec_decorr_open( &( hDiracDecBin->h_freq_domain_decorr_ap_params ), &( hDiracDecBin->h_freq_domain_decorr_ap_state ), nBins, @@ -319,7 +318,6 @@ ivas_error ivas_dirac_dec_init_binaural_data( int16_t nchan_to_allocate; int16_t n_samples_granularity; -#ifdef FIX_NCHAN_BUFFERS nchan_to_allocate = BINAURAL_CHANNELS; if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->useTdDecorr ) { @@ -329,10 +327,6 @@ ivas_error ivas_dirac_dec_init_binaural_data( { nchan_to_allocate++; } -#else - nchan_to_allocate = 2 * BINAURAL_CHANNELS; -#endif - if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) { nchan_to_allocate = BINAURAL_CHANNELS + st_ivas->nchan_ism; @@ -402,6 +396,7 @@ ivas_error ivas_dirac_dec_binaural_copy_hrtfs( ) { int16_t i, j; + if ( hHrtfParambin != NULL && *hHrtfParambin != NULL ) { /* Tables already loaded from file */ @@ -457,24 +452,15 @@ void ivas_dirac_dec_binaural_render( uint16_t nchan_out; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; float *output_f_local[MAX_OUTPUT_CHANNELS]; -#ifndef FIX_RENDERER_STACK - float output_f_local_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - int16_t output_length; -#endif hSpatParamRendCom = st_ivas->hSpatParamRendCom; nchan_out = BINAURAL_CHANNELS; #ifdef DEBUGGING assert( hSpatParamRendCom ); #endif - for ( ch = 0; ch < nchan_out; ch++ ) { -#ifdef FIX_RENDERER_STACK output_f_local[ch] = output_f[ch]; -#else - output_f_local[ch] = output_f_local_buff[ch]; -#endif } slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); @@ -492,9 +478,6 @@ void ivas_dirac_dec_binaural_render( #ifdef DEBUGGING assert( slots_to_render == 0 ); -#endif -#ifndef FIX_RENDERER_STACK - output_length = 0; #endif for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) { @@ -506,19 +489,10 @@ void ivas_dirac_dec_binaural_render( output_f_local[ch] += n_samples_sf; } -#ifndef FIX_RENDERER_STACK - output_length += n_samples_sf; -#endif /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); } -#ifndef FIX_RENDERER_STACK - for ( ch = 0; ch < nchan_out; ch++ ) - { - mvr2r( output_f_local_buff[ch], output_f[ch], output_length ); - } -#endif if ( hSpatParamRendCom->slots_rendered == hSpatParamRendCom->num_slots ) { hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % hSpatParamRendCom->dirac_md_buffer_length; @@ -786,7 +760,6 @@ static void ivas_dirac_dec_binaural_internal( max_band_decorr = hDiracDecBin->h_freq_domain_decorr_ap_params->max_band_decorr; } - ivas_dirac_dec_binaural_formulate_input_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, subframe, subFrameTotalEne, IIReneLimiter ); @@ -1143,6 +1116,7 @@ static void ivas_dirac_dec_binaural_formulate_input_covariance_matrices( return; } + static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, @@ -1244,6 +1218,7 @@ static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices( uint16_t ismDirIndex; ismDirIndex = dirIndex - hSpatParamRendCom->numParametricDirections; assert( hMasaIsmData != NULL && "hMasaIsmData should not be NULL if we use it" ); + if ( hMasaIsmData->ism_dir_is_edited[ismDirIndex] ) { aziDeg = hMasaIsmData->azimuth_ism_edited[ismDirIndex]; @@ -1789,6 +1764,7 @@ static void ivas_dirac_dec_binaural_process_output( if ( recompute == 1 ) { ivas_dirac_dec_decorrelate_slot( hDiracDecBin, nBins, slot, inRe, inIm, decSlotRe, decSlotIm ); + for ( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { mvr2r( decSlotRe[chA], decorrRe[chA][slot], CLDFB_NO_CHANNELS_MAX ); @@ -2418,7 +2394,7 @@ static void formulate2x2MixingMatrix( matrixMul( tmpRe, tmpIm, Kxre, Kxim, Are, Aim ); /* Find nearest orthonormal matrix P to A = Ky' * G_hat * Q * Kx - For matrix A that is P = A(A'A)^0.5 + For matrix A that is P = A(A'A)^0.5 */ matrixTransp1Mul( Are, Aim, Are, Aim, tmpRe, tmpIm ); @@ -2946,7 +2922,6 @@ void ivas_omasa_preProcessStereoTransportsForEditedObjects( float masaEneThisCh[2]; float ratioAccNewDivisor; - gainMasaPow2 = 1.0f; if ( masaGainEdited ) { @@ -2980,6 +2955,7 @@ void ivas_omasa_preProcessStereoTransportsForEditedObjects( panGainsOut[ismDirIndex][ch] = panGainsIn[ismDirIndex][ch]; } } + /* Determine pan enes */ for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { @@ -3135,13 +3111,13 @@ void ivas_omasa_preProcessStereoTransportsForEditedObjects( ratioAccNew += ratio; } - /* Todo: Remove this comment with port 408 which would bring this back. - * No sense to break the code with port 251. */ /* Limit target energies to non-negative values */ +#ifdef NONBE_1399_1400_FIX_OBJ_EDIT_ISSUES for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { totalTargetEneCh[ch] = max( totalTargetEneCh[ch], 0.0f ); } +#endif /* due to rounding, the sum may exceed 1.0f ever so slightly, so clip it */ ratioAccOrig = min( ratioAccOrig, 1.0f ); @@ -3331,6 +3307,7 @@ void ivas_omasa_preProcessStereoTransportsForEditedObjects( return; } + static void ivas_masa_ext_rend_parambin_internal( MASA_EXT_REND_HANDLE hMasaExtRend, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, @@ -3450,8 +3427,9 @@ static void ivas_masa_ext_rend_parambin_internal( ivas_dirac_dec_binaural_formulate_input_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, subframe, subFrameTotalEne, IIReneLimiter ); + ivas_dirac_dec_binaural_formulate_target_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Rmat, subframe, - hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0, subFrameTotalEne, IIReneLimiter, NULL ); ivas_dirac_dec_binaural_determine_processing_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat, subframe, diff --git a/lib_rend/ivas_efap.c b/lib_rend/ivas_efap.c index 13baefbd739b396f7d4e33f70edefdeaea7b0311..fae6d952dff354867fa3f1422a9ad264c8dda00a 100644 --- a/lib_rend/ivas_efap.c +++ b/lib_rend/ivas_efap.c @@ -175,7 +175,7 @@ ivas_error efap_init_data( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for EFAP handle\n" ) ); } - /* Memory Allocation and update for aziSpk & eleSpk arrays*/ + /* Memory allocation and update for aziSpk & eleSpk arrays*/ if ( ( efap->aziSpk = (float *) malloc( num_speaker_nodes * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for EFAP speaker azimuths\n" ) ); @@ -211,7 +211,6 @@ ivas_error efap_init_data( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for EFAP bufferS\n" ) ); } - /*-----------------------------------------------------------------* * Initialize values *-----------------------------------------------------------------*/ diff --git a/lib_rend/ivas_hrtf.c b/lib_rend/ivas_hrtf.c index 45355249189f90fe3eb736131cbeb49203bc73fa..66c3ca0206ee88ba7c445604527bc07f456f4e33 100644 --- a/lib_rend/ivas_hrtf.c +++ b/lib_rend/ivas_hrtf.c @@ -203,6 +203,7 @@ void ivas_HRTF_CRend_binary_close( free( *hHrtfCrend ); *hHrtfCrend = NULL; + return; } @@ -379,6 +380,5 @@ ivas_error ivas_HRTF_statistics_init( *hHrtfStatistics = HrtfStatistics; - return IVAS_ERR_OK; } diff --git a/lib_rend/ivas_masa_merge.c b/lib_rend/ivas_masa_merge.c index 997cdc84d156e3f5efa171a446baf87e2bc75f7f..4432133cd4206f10ba9d42cafe73ded976b474b3 100644 --- a/lib_rend/ivas_masa_merge.c +++ b/lib_rend/ivas_masa_merge.c @@ -37,9 +37,7 @@ #include "ivas_prot.h" #include "ivas_cnst.h" #include "prot.h" -#ifdef NONBE_1344_REND_MASA_LOW_FS #include "ivas_rom_com.h" -#endif #include "wmc_auto.h" @@ -329,9 +327,7 @@ ivas_error masaPrerendOpen( { MASA_PREREND_HANDLE hMasaPrerend; int16_t i; -#ifdef NONBE_1344_REND_MASA_LOW_FS int16_t maxBin; -#endif ivas_error error; error = IVAS_ERR_OK; @@ -342,7 +338,6 @@ ivas_error masaPrerendOpen( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA prerenderer\n" ) ); } -#ifdef NONBE_1344_REND_MASA_LOW_FS /* Determine the number of bands and band grouping */ hMasaPrerend->nbands = MASA_FREQUENCY_BANDS; mvs2s( MASA_band_grouping_24, hMasaPrerend->band_grouping, MASA_FREQUENCY_BANDS + 1 ); @@ -357,7 +352,6 @@ ivas_error masaPrerendOpen( break; } } -#endif hMasaPrerend->num_Cldfb_instances = numTransports; for ( i = 0; i < hMasaPrerend->num_Cldfb_instances; i++ ) diff --git a/lib_rend/ivas_mcmasa_ana.c b/lib_rend/ivas_mcmasa_ana.c index 2f67607e9457a4ee100cceed1d482183c5fd0479..1ed545b4fe13a2493b9341ad3a358fc6ed11a27d 100644 --- a/lib_rend/ivas_mcmasa_ana.c +++ b/lib_rend/ivas_mcmasa_ana.c @@ -393,13 +393,11 @@ void ivas_mcmasa_ana( /* Analysis */ ivas_mcmasa_param_est_ana( hMcMasa, data_f, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence, input_frame, nchan_inp ); -#ifdef NONBE_1344_REND_MASA_LOW_FS /* Add zeros to higher bands in case of lower sampling rates */ if ( hMcMasa->nbands < MASA_FREQUENCY_BANDS ) { ivas_masa_zero_high_bands( hMcMasa->nbands, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence ); } -#endif /* Create MASA metadata buffer from the estimated values */ ivas_create_masa_out_meta( hMcMasa->hMasaOut, hMcMasa->sph_grid16, nchan_transport, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence ); @@ -1141,7 +1139,6 @@ void ivas_create_masa_out_meta( } -#ifdef NONBE_1344_REND_MASA_LOW_FS /*------------------------------------------------------------------------- * ivas_masa_zero_high_bands() * @@ -1173,4 +1170,3 @@ void ivas_masa_zero_high_bands( return; } -#endif diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index b9dafaed566fa0928d9d54acfdea320204e576c7..a4e15c79dea1ae54e130d550b50e21d8c296049a 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -463,6 +463,7 @@ ivas_error TDREND_GetMix( { TDREND_SRC_REND_UpdateFiltersFromSpatialParams( hBinRendererTd, SrcRend_p, SrcSpatial_p, Src_p->hrf_left_prev, Src_p->hrf_right_prev, hrf_left_delta, hrf_right_delta, &intp_count, &Src_p->filterlength, &Src_p->itd, &Src_p->Gain, Src_p ); + /* For large ITD values at lower sampling rate, check if the transition can be done */ if ( Src_p->itd * Src_p->previtd < 0 ) { @@ -533,16 +534,10 @@ ivas_error TDREND_Update_object_positions( const ISM_METADATA_HANDLE *hIsmMetaData /* i : Input metadata for ISM objects */ ) { -#ifndef NONBE_1377_REND_DIRATT_CONF - TDREND_DirAtten_t *DirAtten_p; -#endif int16_t nS; float Pos[3]; float Dir[3]; ivas_error error; -#ifndef NONBE_1377_REND_DIRATT_CONF - DirAtten_p = hBinRendererTd->DirAtten_p; -#endif /* For each source, write the frame data to the source object*/ for ( nS = 0; nS < num_src; nS++ ) @@ -559,12 +554,6 @@ ivas_error TDREND_Update_object_positions( return error; } -#ifndef NONBE_1377_REND_DIRATT_CONF - if ( ( error = TDREND_MIX_SRC_SetDirAtten( hBinRendererTd, nS, DirAtten_p ) ) != IVAS_ERR_OK ) - { - return error; - } -#endif if ( ( error = TDREND_MIX_SRC_SetGain( hBinRendererTd, nS, hIsmMetaData[nS]->gain ) ) != IVAS_ERR_OK ) { return error; @@ -674,17 +663,13 @@ ivas_error TDREND_Update_listener_orientation( *---------------------------------------------------------------------*/ ivas_error ivas_td_binaural_open_ext( - TDREND_WRAPPER *pTDRend, - AUDIO_CONFIG inConfig, - RENDER_CONFIG_DATA *hRendCfg, /* i : Renderer configuration */ - LSSETUP_CUSTOM_STRUCT *customLsInput, -#ifdef NONBE_1377_REND_DIRATT_CONF - const int32_t outFs, /* i: output sampling rate */ - const int16_t object_id /* i: Object ID */ + TDREND_WRAPPER *pTDRend, /* i/o: TD Renderer wrapper structure */ + const AUDIO_CONFIG inConfig, /* i : input audio configuration */ + RENDER_CONFIG_DATA *hRendCfg, /* i : Renderer configuration */ + LSSETUP_CUSTOM_STRUCT *customLsInput, /* i : Input custom loudspeaker layout */ + const int32_t outFs, /* i : output sampling rate */ + const int16_t object_id /* i : Object ID */ ) -#else - const int32_t outFs ) -#endif { int16_t nchan_transport; AUDIO_CONFIG transport_config; @@ -721,11 +706,7 @@ ivas_error ivas_td_binaural_open_ext( if ( NULL != hRendCfg ) { -#ifdef NONBE_1377_REND_DIRATT_CONF directivity = hRendCfg->directivity + 3 * object_id; -#else - directivity = hRendCfg->directivity; -#endif distAtt = hRendCfg->distAtt; } @@ -805,6 +786,7 @@ ivas_error ivas_td_binaural_renderer_ext( hIsmMetaData[0]->pitch = currentPos->pitch; hIsmMetaData[0]->radius = currentPos->radius; hIsmMetaData[0]->gain = 1.0f; + hIsmMetaData[0]->non_diegetic_flag = currentPos->non_diegetic_flag; } diff --git a/lib_rend/ivas_objectRenderer_hrFilt.c b/lib_rend/ivas_objectRenderer_hrFilt.c index fc677c98e0aca0677f1882611900f538c39b776f..4e27200a4a843f0101a3d9fe9b6133823122c4ab 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt.c +++ b/lib_rend/ivas_objectRenderer_hrFilt.c @@ -516,12 +516,15 @@ void BSplineModelEvalDealloc( if ( model->modelROM ) { + free( (void *) model->azimBsShape ); /* void* cast needed to please both gcc and Visual studio compilers. Deallocating const float** should be fine and gcc agrees, but Visual studio complains. */ + for ( i = 0; i < model->elevDim3; i++ ) { free( model->azimKSeq[i] ); } free( model->azimKSeq ); + if ( modelEval != NULL ) { free( modelEval->hrfModL ); diff --git a/lib_rend/ivas_objectRenderer_mix.c b/lib_rend/ivas_objectRenderer_mix.c index 597a44b6ebf1ea4173fcb5d05715704253ad787a..3c63594709cdeabcb1d12542c63f31f628cd5784 100644 --- a/lib_rend/ivas_objectRenderer_mix.c +++ b/lib_rend/ivas_objectRenderer_mix.c @@ -38,11 +38,13 @@ #include "ivas_error.h" #include "wmc_auto.h" #include "ivas_rom_rend.h" +#include "ivas_rom_binaural_crend_head.h" #include #ifdef DEBUGGING #include "debug.h" #endif + /*------------------------------------------------------------------------- * Local functions declaration *-------------------------------------------------------------------------*/ @@ -129,7 +131,6 @@ void TDREND_MIX_Dealloc( { TDREND_SRC_Dealloc( hBinRendererTd->Sources[i] ); } - /* Deallocate Listener and RendListener */ if ( hBinRendererTd->Listener_p != NULL ) { @@ -166,8 +167,10 @@ void TDREND_MIX_Dealloc( hBinRendererTd->HrFiltSet_p->RightFiltSet_p = NULL; } } + if ( hBinRendererTd->HrFiltSet_p->ModelParams.modelROM == 1 ) { + free( hBinRendererTd->HrFiltSet_p ); hBinRendererTd->HrFiltSet_p = NULL; *hBinRendererTd->pHrFiltSet_p = NULL; @@ -381,7 +384,6 @@ static ivas_error DefaultBSplineModel( model = &( HrFiltSet_p->ModelParams ); modelITD = &( HrFiltSet_p->ModelParamsITD ); - /* Set ROM flag for correct deallocation */ model->modelROM = TRUE; @@ -409,6 +411,7 @@ static ivas_error DefaultBSplineModel( } model->azimBsShape[0] = (const float *) defaultHRIR_rom_azimBsShape; + if ( ( model->azimKSeq = (float **) malloc( model->elevDim3 * sizeof( float * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) ); @@ -482,6 +485,7 @@ static ivas_error DefaultBSplineModel( modelITD->azimSegSamples = defaultHRIR_rom_ITD_model_configuration[3]; modelITD->elevBsLen = defaultHRIR_rom_ITD_elevBsLen; modelITD->elevBsStart = defaultHRIR_rom_ITD_elevBsStart; + modelITD->elevKSeq = defaultHRIR_rom_ITD_elevKSeq; modelITD->azimBsLen = defaultHRIR_rom_ITD_azimBsLen; @@ -495,6 +499,7 @@ static ivas_error DefaultBSplineModel( HRTF_model_precalc( model ); HrFiltSet_p->latency_s = defaultHRIR_rom_latency_s; + HrFiltSet_p->SampleRate = output_Fs; HrFiltSet_p->FiltLength = HrFiltSet_p->ModelParams.K; diff --git a/lib_rend/ivas_objectRenderer_sfx.c b/lib_rend/ivas_objectRenderer_sfx.c index 1f774bb0fcb04ca30307ad1af0aa60c7097d6f4a..5873ebd96aef56346b9c4c25dadadfe55769b882 100644 --- a/lib_rend/ivas_objectRenderer_sfx.c +++ b/lib_rend/ivas_objectRenderer_sfx.c @@ -39,11 +39,6 @@ #include "wmc_auto.h" -/*---------------------------------------------------------------------* - * Local constants - *---------------------------------------------------------------------*/ - - /*---------------------------------------------------------------------* * Local function prototypes *---------------------------------------------------------------------*/ @@ -56,6 +51,7 @@ static void sincResample( const float *input, float *output, const int16_t lengt * * Apply ITD by delaying late channel *---------------------------------------------------------------------*/ + void TDREND_Apply_ITD( float *input, /* i : Input subframe to be time adjusted */ float *out_left, /* o : Output left channel with ITD applied */ @@ -163,6 +159,7 @@ void TDREND_Apply_ITD( * The sinc resampling reads SFX_SPAT_BIN_SINC_M (5) samples outside of * the target frame. *---------------------------------------------------------------------*/ + static void sincResample( const float *input, /*i : Input signal */ float *output, /*o : Output signal */ @@ -188,7 +185,6 @@ static void sincResample( return; } - /* Compute fractional time step */ t_step = (float) ( length_in ) / (float) ( length_out ); t_frac = 0; @@ -216,6 +212,7 @@ static void sincResample( p_forward++; p_backward--; } + output[i] = tmp; /* Advance fractional time */ diff --git a/lib_rend/ivas_objectRenderer_sources.c b/lib_rend/ivas_objectRenderer_sources.c index 4d3dfcc42ff0b7fa1c3cbeb6654d43446f3fc8e1..355c5e13be3f08a18e9a2ae62a8d025deed3a1bf 100644 --- a/lib_rend/ivas_objectRenderer_sources.c +++ b/lib_rend/ivas_objectRenderer_sources.c @@ -104,7 +104,7 @@ ivas_error TDREND_MIX_SRC_SetPos( --------------------------------------------------------------------*/ ivas_error TDREND_MIX_SRC_SetDir( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ const float *Vec_p /* i : Direction vector */ ) @@ -156,7 +156,7 @@ ivas_error TDREND_MIX_SRC_SetGain( --------------------------------------------------------------------*/ ivas_error TDREND_MIX_SRC_SetDirAtten( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ const TDREND_DirAtten_t *DirAtten_p /* i : Directional attenuation specifier */ ) diff --git a/lib_rend/ivas_omasa_ana.c b/lib_rend/ivas_omasa_ana.c index 22dfafef1c596a633410239701e439c5021cb33e..d43c24f63b4cc17b1af58d6a2ffe9b22bb378c1a 100644 --- a/lib_rend/ivas_omasa_ana.c +++ b/lib_rend/ivas_omasa_ana.c @@ -261,13 +261,11 @@ void ivas_omasa_ana( /* Estimate MASA parameters from the objects */ ivas_omasa_param_est_ana( hOMasa, data_in_f, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence, input_frame, nchan_ism ); -#ifdef NONBE_1344_REND_MASA_LOW_FS /* Add zeros to higher bands in case of lower sampling rates */ if ( hOMasa->nbands < MASA_FREQUENCY_BANDS ) { ivas_masa_zero_high_bands( hOMasa->nbands, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence ); } -#endif /* Create MASA metadata buffer from the estimated values */ ivas_create_masa_out_meta( hOMasa->hMasaOut, hOMasa->sph_grid16, nchan_transport, elevation_m_values, azimuth_m_values, energyRatio, spreadCoherence, surroundingCoherence ); @@ -490,7 +488,6 @@ static void ivas_omasa_dmx( float g1, g2; float data_out_f[MASA_MAX_TRANSPORT_CHANNELS][L_FRAME48k]; - for ( i = 0; i < nchan_transport; i++ ) { set_zero( data_out_f[i], input_frame ); @@ -498,7 +495,6 @@ static void ivas_omasa_dmx( for ( i = 0; i < nchan_ism; i++ ) { -#ifdef NONBE_1362_FIX_OMASA_TO_MASA1_RENDERING if ( nchan_transport == 1 ) { v_add( data_out_f[0], data_in_f[i], data_out_f[0], input_frame ); @@ -525,27 +521,6 @@ static void ivas_omasa_dmx( prev_gains[i][j] = gains[j]; } } -#else - azimuth = ism_azimuth[i]; - elevation = ism_elevation[i]; - - ivas_ism_get_stereo_gains( azimuth, elevation, &gains[0], &gains[1] ); - - /* Downmix using the panning gains */ - for ( j = 0; j < nchan_transport; j++ ) - { - if ( fabsf( gains[j] ) > 0.0 || fabsf( prev_gains[i][j] ) > 0.0f ) - { - for ( k = 0; k < input_frame; k++ ) - { - g1 = interpolator[k]; - g2 = 1.0f - g1; - data_out_f[j][k] += ( g1 * gains[j] + g2 * prev_gains[i][j] ) * data_in_f[i][k]; - } - } - prev_gains[i][j] = gains[j]; - } -#endif } for ( i = 0; i < nchan_transport; i++ ) diff --git a/lib_rend/ivas_orient_trk.c b/lib_rend/ivas_orient_trk.c index dde64113d62fa907104c9b37d934a3e72ff73aab..0bab4c34e05020f8a91f9f505c911ea996e4f76d 100644 --- a/lib_rend/ivas_orient_trk.c +++ b/lib_rend/ivas_orient_trk.c @@ -195,7 +195,6 @@ void QuaternionSlerp( r->y = ( s1 * r1.y + s2 * r2.y ) / sinPhi; r->z = ( s1 * r1.z + s2 * r2.z ) / sinPhi; } - QuaternionNormalize( *r, r ); return; diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index 3c27b85625937c53f88f691a7cde44e912e8c5ff..01e1d77231ff06fc84f35a4ca20448a53e8b2729 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -271,11 +271,7 @@ int16_t ivas_get_nchan_buffers_dec( output_config = st_ivas->hDecoderConfig->output_config; -#ifdef FIX_NCHAN_BUFFERS nchan_out_buff = st_ivas->nchan_transport; -#else - nchan_out_buff = MAX_OUTPUT_CHANNELS; -#endif if ( st_ivas->ivas_format == MONO_FORMAT ) { @@ -287,107 +283,35 @@ int16_t ivas_get_nchan_buffers_dec( } else if ( st_ivas->ivas_format == ISM_FORMAT ) { -#ifdef FIX_NCHAN_BUFFERS nchan_out_buff = max( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_ism ); if ( st_ivas->ism_mode == ISM_MODE_PARAM || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) { nchan_out_buff = max( nchan_out_buff, audioCfg2channels( st_ivas->intern_config ) ); } -#else - nchan_out_buff = st_ivas->nchan_ism; - - if ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM ) - { - nchan_out_buff = max( nchan_out_buff, st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ); - } - else if ( output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) - { - nchan_out_buff = max( audioCfg2channels( st_ivas->transport_config ), audioCfg2channels( st_ivas->intern_config ) ); - nchan_out_buff = max( nchan_out_buff, audioCfg2channels( output_config ) ); - } -#endif } else if ( st_ivas->ivas_format == SBA_FORMAT ) { -#ifdef FIX_NCHAN_BUFFERS int16_t nchan_internal; nchan_internal = ivas_sba_get_nchan_metadata( sba_analysis_order, ivas_total_brate ); nchan_out_buff = max( nchan_internal, st_ivas->hDecoderConfig->nchan_out ); -#else - int16_t nchan_internal; - nchan_internal = ivas_sba_get_nchan_metadata( sba_analysis_order, ivas_total_brate ); - nchan_out_buff = st_ivas->hDecoderConfig->nchan_out; - - if ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM ) - { - nchan_out_buff = max( nchan_out_buff, st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ); - } - else if ( output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) - { - nchan_out_buff = max( audioCfg2channels( st_ivas->transport_config ), audioCfg2channels( st_ivas->intern_config ) ); - nchan_out_buff = max( nchan_out_buff, audioCfg2channels( output_config ) ); - } - nchan_out_buff = max( nchan_out_buff, nchan_internal ); -#endif } else if ( st_ivas->ivas_format == MASA_FORMAT ) { -#ifdef FIX_NCHAN_BUFFERS nchan_out_buff = max( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_transport ); if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->useTdDecorr ) { nchan_out_buff = 2 * BINAURAL_CHANNELS; } -#else - nchan_out_buff = CPE_CHANNELS; - - if ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM ) - { - nchan_out_buff = max( nchan_out_buff, st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ); - } - else if ( output_config == IVAS_AUDIO_CONFIG_STEREO || output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - nchan_out_buff = 2 * CPE_CHANNELS; - } - else if ( output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) - { - nchan_out_buff = max( nchan_out_buff, audioCfg2channels( st_ivas->intern_config ) ); - nchan_out_buff = max( nchan_out_buff, audioCfg2channels( output_config ) ); - } - if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL && st_ivas->nchan_ism > 0 ) - { - nchan_out_buff = st_ivas->nchan_ism + CPE_CHANNELS; - } -#endif } else if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) { -#ifdef FIX_NCHAN_BUFFERS nchan_out_buff = max( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_transport + st_ivas->nchan_ism ); -#else - nchan_out_buff = st_ivas->nchan_ism + CPE_CHANNELS; - - if ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM ) - { - nchan_out_buff = max( nchan_out_buff, st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ); - } - 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_out_buff = max( nchan_out_buff, BINAURAL_CHANNELS + st_ivas->nchan_ism ); - } - else if ( output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) - { - nchan_out_buff = max( nchan_out_buff, audioCfg2channels( st_ivas->intern_config ) ); - nchan_out_buff = max( nchan_out_buff, audioCfg2channels( output_config ) ); - } -#endif } else if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) { -#ifdef FIX_NCHAN_BUFFERS int16_t nchan_internal; nchan_internal = ivas_sba_get_nchan_metadata( sba_analysis_order, ivas_total_brate ); @@ -408,49 +332,9 @@ int16_t ivas_get_nchan_buffers_dec( { nchan_out_buff = max( nchan_out_buff, audioCfg2channels( st_ivas->intern_config ) ); } -#else - int16_t nchan_internal; - nchan_internal = ivas_sba_get_nchan_metadata( sba_analysis_order, ivas_total_brate ); - nchan_out_buff = st_ivas->nchan_ism + st_ivas->nchan_transport; - - if ( st_ivas->hMCT != NULL ) - { - nchan_out_buff = ( ( nchan_out_buff + 1 ) >> 1 ) << 1; /* ensure odd number of channels in MCT */ - } - - if ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM ) - { - nchan_out_buff = max( nchan_out_buff, st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ); - } - else if ( output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) - { - nchan_out_buff = max( nchan_out_buff, audioCfg2channels( st_ivas->intern_config ) ); - nchan_out_buff = max( nchan_out_buff, audioCfg2channels( output_config ) ); - - if ( st_ivas->renderer_type == RENDERER_OSBA_AMBI || st_ivas->renderer_type == RENDERER_OSBA_LS ) - { - nchan_out_buff = max( nchan_out_buff + st_ivas->nchan_ism, audioCfg2channels( output_config ) ); /* needed for ivas_sba_upmixer_renderer() */ - } - else - { - nchan_out_buff = max( nchan_out_buff + st_ivas->nchan_ism, audioCfg2channels( output_config ) ); /* needed for ivas_spar_dec_upmixer_sf() which is based on 'nchan_out' */ - } - } - else if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) - { - nchan_out_buff = st_ivas->hDecoderConfig->nchan_out + st_ivas->nchan_ism; /*take into account sba_ch_idx' in ivas_dec() */ - } - - if ( !( output_config == IVAS_AUDIO_CONFIG_MONO || output_config == IVAS_AUDIO_CONFIG_STEREO ) ) - { - nchan_out_buff = max( nchan_out_buff, nchan_internal + st_ivas->nchan_ism ); - } - nchan_out_buff = min( nchan_out_buff, MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS ); -#endif } else if ( st_ivas->ivas_format == MC_FORMAT ) { -#ifdef FIX_NCHAN_BUFFERS nchan_out_buff = max( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_transport ); if ( st_ivas->hOutSetup.separateChannelEnabled ) @@ -466,19 +350,6 @@ int16_t ivas_get_nchan_buffers_dec( { nchan_out_buff = max( nchan_out_buff, audioCfg2channels( st_ivas->intern_config ) ); } -#else - nchan_out_buff = st_ivas->hDecoderConfig->nchan_out; - - if ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM ) - { - nchan_out_buff = max( nchan_out_buff, st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ); - } - else if ( output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) - { - nchan_out_buff = max( audioCfg2channels( st_ivas->transport_config ), audioCfg2channels( st_ivas->intern_config ) ); - nchan_out_buff = max( nchan_out_buff, audioCfg2channels( output_config ) ); - } -#endif } if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) @@ -497,18 +368,12 @@ int16_t ivas_get_nchan_buffers_dec( *-------------------------------------------------------------------*/ ivas_error ivas_output_buff_dec( - float *p_output_f[], /* i/o: output audio buffers */ -#ifdef FIX_1330_JBM_MEMORY - const int16_t nchan_out_buff, /* i : number of output channels */ - const int16_t Opt_tsm, /* i : TSM option flag */ - DECODER_TC_BUFFER_HANDLE hTcBuffer /* i : TSM buffer handle */ -#else - const int16_t nchan_out_buff_old, /* i : previous frame number of output channels */ - const int16_t nchan_out_buff /* i : number of output channels */ -#endif + float *p_output_f[], /* i/o: output audio buffers */ + const int16_t nchan_out_buff, /* i : number of output channels */ + const int16_t Opt_tsm, /* i : TSM option flag */ + DECODER_TC_BUFFER_HANDLE hTcBuffer /* i : TSM buffer handle */ ) { -#ifdef FIX_1330_JBM_MEMORY int16_t ch, nchan_tc_jbm, nsamp_to_allocate, n_samp_full, offset; for ( ch = 0; ch < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; ch++ ) @@ -566,37 +431,6 @@ ivas_error ivas_output_buff_dec( offset += n_samp_full; } } -#else - int16_t ch; - - if ( nchan_out_buff > nchan_out_buff_old ) - { - for ( ch = nchan_out_buff_old; ch < nchan_out_buff; ch++ ) - { -#ifdef FIX_NCHAN_BUFFERS -#ifdef DEBUGGING - if ( p_output_f[ch] != NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Memory for floating-point output audio buffer is already allocated!\n" ) ); - } -#endif -#endif - /* note: these are intra-frame heap memories */ - if ( ( p_output_f[ch] = (float *) malloc( ( 48000 / FRAMES_PER_SEC ) * sizeof( float ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for floating-point output audio buffer!\n" ) ); - } - } - } - else - { - for ( ch = nchan_out_buff; ch < nchan_out_buff_old; ch++ ) - { - free( p_output_f[ch] ); - p_output_f[ch] = NULL; - } - } -#endif return IVAS_ERR_OK; } diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index a92070391a440d4bb42f7f82ae29b9bebfa3dc38..56cd7bed4d49b4e1968916cbe3ca19ccaf962741 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -77,6 +77,16 @@ int16_t ivas_get_nchan_buffers_dec( const int32_t ivas_total_brate /* i : total IVAS bitrate */ ); +/*! r: flag to indicate if split rendering is enabled */ +int16_t is_split_rendering_enabled( + const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ + const IVAS_RENDER_CONFIG_HANDLE hRenderConfig /* i : Render config data structure */ +); + +ivas_error get_channel_config( + const AUDIO_CONFIG config, + char *str +); /*----------------------------------------------------------------------------------* * TD decorr. function prototypes @@ -647,16 +657,12 @@ ivas_error ivas_td_binaural_open_unwrap( ); ivas_error ivas_td_binaural_open_ext( - TDREND_WRAPPER *pTDRend, - const AUDIO_CONFIG inConfig, + TDREND_WRAPPER *pTDRend, /* i/o: TD Renderer wrapper structure */ + const AUDIO_CONFIG inConfig, /* i : input audio configuration */ RENDER_CONFIG_DATA *hRendCfg, /* i : Renderer configuration */ - LSSETUP_CUSTOM_STRUCT *customLsInput, -#ifdef NONBE_1377_REND_DIRATT_CONF - const int32_t output_Fs, /* i: output sampling rate */ - const int16_t object_id /* i: Object ID */ -#else - const int32_t output_Fs -#endif + LSSETUP_CUSTOM_STRUCT *customLsInput, /* i : Input custom loudspeaker layout */ + const int32_t output_Fs, /* i : output sampling rate */ + const int16_t object_id /* i : Object ID */ ); void ivas_td_binaural_close( @@ -902,7 +908,7 @@ void ivas_rend_closeCrend( CREND_WRAPPER_HANDLE *pCrend ); -ivas_error ivas_Crend_hrtf_init( +ivas_error ivas_Crend_hrtf_init( HRTFS_CREND_DATA *hHrtf /* i/o: Crend HRTF handle */ ); @@ -911,7 +917,6 @@ ivas_error ivas_rend_initCrendWrapper( const int16_t num_poses ); - ivas_error ivas_rend_crendProcessSubframe( const CREND_WRAPPER *pCrend, /* i/o: Crend wrapper handle */ const AUDIO_CONFIG inConfig, /* i : input audio configuration */ @@ -933,7 +938,6 @@ ivas_error ivas_rend_crendProcessSubframe( * Reverberator *----------------------------------------------------------------------------------*/ - ivas_error ivas_binaural_reverb_init( REVERB_STRUCT_HANDLE *hReverbPr, /* i/o: binaural reverb handle */ const HRTFS_STATISTICS_HANDLE hHrtfStatistics, /* i : HRTF statistics handle */ @@ -942,12 +946,10 @@ ivas_error ivas_binaural_reverb_init( const IVAS_ROOM_ACOUSTICS_CONFIG_DATA *roomAcoustics, /* i/o: room acoustics parameters */ const int32_t sampling_rate, /* i : sampling rate */ const float *defaultTimes, /* i : default reverberation times */ - const float *defaultEne /* i : default reverberation energies */ - , + const float *defaultEne, /* i : default reverberation energies */ float *earlyEne /* i/o: Early part energies to be modified */ ); - void ivas_binaural_reverb_close( REVERB_STRUCT_HANDLE *hReverb /* i/o: binaural reverb handle */ ); @@ -1346,6 +1348,7 @@ ivas_error ivas_render_config_init_from_rom( * Quaternion operations *----------------------------------------------------------------------------------*/ +#ifndef IVAS_RTPDUMP void QuaternionProduct( const IVAS_QUATERNION q1, const IVAS_QUATERNION q2, @@ -1357,6 +1360,7 @@ void QuaternionInverse( IVAS_QUATERNION *const r ); +#endif void QuaternionSlerp( const IVAS_QUATERNION q1, const IVAS_QUATERNION q2, @@ -1474,16 +1478,14 @@ void ivas_create_masa_out_meta( float surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS] /* i : Estimated surround coherence */ ); -#ifdef NONBE_1344_REND_MASA_LOW_FS void ivas_masa_zero_high_bands( - const int16_t nbands, /* i : Number of frequency bands with estimated values */ - float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i/o : Estimated elevation */ - float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i/o : Estimated azimuth */ - float energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i/o : Estimated direct-to-total ratio */ - float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i/o : Estimated spread coherence */ - float surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS] /* i/o : Estimated surround coherence */ + const int16_t nbands, /* i : Number of frequency bands with estimated values */ + float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i/o: Estimated elevation */ + float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i/o: Estimated azimuth */ + float energyRatio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i/o: Estimated direct-to-total ratio */ + float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i/o: Estimated spread coherence */ + float surroundingCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS] /* i/o: Estimated surround coherence */ ); -#endif ivas_error ivas_dirac_ana_open( DIRAC_ANA_HANDLE *hDirACPtr, /* i/o: DIRAC data handle pointer */ @@ -1553,19 +1555,6 @@ ivas_error ivas_rend_crendProcessSubframesSplitBin( const int32_t output_Fs /* i : output sampling rate */ ); -ivas_error ivas_rend_crendProcessSplitBin( - const CREND_WRAPPER *pCrend, - const AUDIO_CONFIG inConfig, - const AUDIO_CONFIG outConfig, - const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const DECODER_CONFIG_HANDLE hDecoderConfig, - const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, - const IVAS_OUTPUT_SETUP_HANDLE hIntSetup, - EFAP_HANDLE hEFAPdata, - float *output[], - const int32_t output_Fs -); - ivas_error ivas_rend_openMultiBinCrend( CREND_WRAPPER_HANDLE *pCrend, const AUDIO_CONFIG inConfig, @@ -1610,8 +1599,8 @@ void ivas_rend_closeCldfbRend( ivas_error ivas_TD_RINGBUF_Open( TD_RINGBUF_HANDLE *ph, /* i/o: Ring buffer handle */ - const int16_t capacity_per_channel, /* i : Number of samples stored per channel */ - const int16_t num_channels /* i : Number of channels */ + const uint32_t capacity_per_channel, /* i : Number of samples stored per channel */ + const uint16_t num_channels /* i : Number of channels */ ); void ivas_TD_RINGBUF_Close( @@ -1622,46 +1611,46 @@ void ivas_TD_RINGBUF_Close( void ivas_TD_RINGBUF_PushInterleaved( TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */ const float *data, /* i : Input audio in interleaved channels layout */ - const int16_t num_samples_per_channel /* i : Number of samples per channel to push */ + const uint32_t num_samples_per_channel /* i : Number of samples per channel to push */ ); void ivas_TD_RINGBUF_PushChannels( TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */ const float *p_channels[], /* i : Array of pointers to each input channel */ - const int16_t num_samples_per_channel /* i : Number of samples per channel to store */ + const uint32_t num_samples_per_channel /* i : Number of samples per channel to store */ ); void ivas_TD_RINGBUF_PushConstant( TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */ const float value, /* i : Value to push */ - const int16_t num_samples_per_channel /* i : Number of samples per channel to push */ + const uint32_t num_samples_per_channel /* i : Number of samples per channel to push */ ); void ivas_TD_RINGBUF_PopChannels( TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */ float *p_channels[], /* i : Array of pointers to each output channel */ - const int16_t num_samples_per_channel /* i : Number of samples per channel to pop */ + const uint32_t num_samples_per_channel /* i : Number of samples per channel to pop */ ); #else void ivas_TD_RINGBUF_Push( TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */ const float *data, /* i : Input data */ - const uint16_t num_samples_per_channel /* i : Number of samples per channel to store */ + const uint32_t num_samples_per_channel /* i : Number of samples per channel to store */ ); void ivas_TD_RINGBUF_PushZeros( TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */ - const uint16_t num_samples_per_channel /* i : Number of zeros per channel to store */ + const uint32_t num_samples_per_channel /* i : Number of zeros per channel to store */ ); void ivas_TD_RINGBUF_Pop( TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */ float *data, /* i : Output data */ - const uint16_t num_samples_per_channel /* i : Number of samples per channel to retrieve*/ + const uint32_t num_samples_per_channel /* i : Number of samples per channel to retrieve*/ ); #endif -int16_t ivas_TD_RINGBUF_Size( +uint32_t ivas_TD_RINGBUF_Size( const TD_RINGBUF_HANDLE h /* i : Ring buffer handle */ ); diff --git a/lib_rend/ivas_reflections.c b/lib_rend/ivas_reflections.c index 4423bfdd1c76ecfb9e9711751c8a67ad51a97237..564f57f171c53083dbf5cd5013cd8084b118118a 100644 --- a/lib_rend/ivas_reflections.c +++ b/lib_rend/ivas_reflections.c @@ -63,7 +63,6 @@ static uint16_t LC_mixing_5_1_4[9] = { 0, 1, 2, 3, 4, 0, 1, 3, 4 }; static uint16_t LC_mixing_7_1_4[11] = { 0, 1, 2, 3, 4, 3, 4, 0, 1, 3, 4 }; - /*-----------------------------------------------------------------------------------------* * Function ivas_er_init() * diff --git a/lib_rend/ivas_render_config.c b/lib_rend/ivas_render_config.c index 0cb6062fd4aac09296bab9129a5423e56f38fb4c..c3a39b426e39a0c1f372a5e0f88464c1c7e4c18b 100644 --- a/lib_rend/ivas_render_config.c +++ b/lib_rend/ivas_render_config.c @@ -35,7 +35,6 @@ #include "prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_rend.h" -#include "ivas_rom_TdBinauralRenderer.h" #ifdef DEBUGGING #include "debug.h" #endif @@ -105,10 +104,12 @@ ivas_error ivas_render_config_init_from_rom( ) { int16_t i; + if ( hRenderConfig == NULL || *hRenderConfig == NULL ) { return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "Unexpected null pointer while attempting to fill renderer configuration from ROM" ); } + #ifdef DEBUGGING ( *hRenderConfig )->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_NONE; #endif @@ -130,10 +131,13 @@ ivas_error ivas_render_config_init_from_rom( ( *hRenderConfig )->directivity[i * 3 + 1] = 360.0f; /* Back cone */ ( *hRenderConfig )->directivity[i * 3 + 2] = 1.0f; /* Back attenuation */ } + ( *hRenderConfig )->distAtt[0] = 15.75f; /* Default max dist */ ( *hRenderConfig )->distAtt[1] = 1.0f; /* Default ref dist */ ( *hRenderConfig )->distAtt[2] = 1.0f; /* Default rolloff factor */ - ( *hRenderConfig )->split_rend_config.splitRendBitRate = SPLIT_REND_768k; + + /* ISAR-related parameters */ + ( *hRenderConfig )->split_rend_config.splitRendBitRate = ISAR_MAX_SPLIT_REND_BITRATE; ( *hRenderConfig )->split_rend_config.dof = 3; ( *hRenderConfig )->split_rend_config.hq_mode = 0; ( *hRenderConfig )->split_rend_config.codec_delay_ms = 0; diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb.c index ffb0177946cb9351bfc10a840827b24f01344de1..cbc12cebdc6478f6c99a00f029dc788d5562c221 100644 --- a/lib_rend/ivas_reverb.c +++ b/lib_rend/ivas_reverb.c @@ -79,10 +79,10 @@ #define MAX_NR_OUTPUTS ( 2 ) -const int16_t init_loop_delay[IVAS_REV_MAX_NR_BRANCHES] = { 37, 31, 29, 23, 19, 17, 13, 11 }; -const int16_t default_loop_delay_48k[IVAS_REV_MAX_NR_BRANCHES] = { 2309, 1861, 1523, 1259, 1069, 919, 809, 719 }; -const int16_t default_loop_delay_32k[IVAS_REV_MAX_NR_BRANCHES] = { 1531, 1237, 1013, 839, 709, 613, 541, 479 }; -const int16_t default_loop_delay_16k[IVAS_REV_MAX_NR_BRANCHES] = { 769, 619, 509, 421, 353, 307, 269, 239 }; +static const int16_t init_loop_delay[IVAS_REV_MAX_NR_BRANCHES] = { 37, 31, 29, 23, 19, 17, 13, 11 }; +static const int16_t default_loop_delay_48k[IVAS_REV_MAX_NR_BRANCHES] = { 2309, 1861, 1523, 1259, 1069, 919, 809, 719 }; +static const int16_t default_loop_delay_32k[IVAS_REV_MAX_NR_BRANCHES] = { 1531, 1237, 1013, 839, 709, 613, 541, 479 }; +static const int16_t default_loop_delay_16k[IVAS_REV_MAX_NR_BRANCHES] = { 769, 619, 509, 421, 353, 307, 269, 239 }; /*------------------------------------------------------------------------------------------* * Local Struct definition @@ -682,8 +682,6 @@ static ivas_error initialize_reverb_filters( { ivas_error error; - error = IVAS_ERR_OK; - /* init correlation and coloration filters */ if ( ( error = ivas_reverb_t2f_f2t_init( &hReverb->fft_filter_ols, hReverb->fft_size, hReverb->fft_subblock_size ) ) != IVAS_ERR_OK ) { @@ -710,7 +708,7 @@ static ivas_error initialize_reverb_filters( return error; } - return error; + return IVAS_ERR_OK; } @@ -953,10 +951,8 @@ static void set_reverb_acoustic_data( const int16_t nr_fc_input, const int16_t nr_fc_fft_filter ) { - int16_t bin_idx; float ln_1e6_inverted, delay_diff, exp_argument; - /* interpolate input table data for T60 and DSR to the FFT filter grid */ ivas_reverb_interpolate_acoustic_data( nr_fc_input, pRoomAcoustics->pFc_input, pRoomAcoustics->pAcoustic_rt60, pRoomAcoustics->pAcoustic_dsr, nr_fc_fft_filter, pParams->pFc, pParams->pRt60, pParams->pDsr ); @@ -1039,6 +1035,7 @@ static ivas_error setup_FDN_branches( * * Allocate and initialize FDN reverberation handle *------------------------------------------------------------------------*/ + ivas_error ivas_reverb_open( REVERB_HANDLE *hReverb, /* i/o: Reverberator handle */ const HRTFS_STATISTICS_HANDLE hHrtfStatistics, /* i : HRTF statistics handle */ @@ -1047,7 +1044,6 @@ ivas_error ivas_reverb_open( ) { ivas_error error; - REVERB_HANDLE pState = *hReverb; int16_t nr_coefs, branch_idx; float *pCoef_a, *pCoef_b; @@ -1062,7 +1058,6 @@ ivas_error ivas_reverb_open( int16_t fft_hist_size, transition_start, transition_length; int16_t nr_fc_input, nr_fc_fft_filter; - error = IVAS_ERR_OK; output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC ); subframe_len = output_frame / MAX_PARAM_SPATIAL_SUBFRAMES; predelay_bf_len = output_frame; @@ -1180,7 +1175,6 @@ ivas_error ivas_reverb_open( } } - if ( pState->do_corr_filter ) { /* Computing correlation filters on the basis of target IA coherence */ @@ -1243,7 +1237,7 @@ ivas_error ivas_reverb_open( *hReverb = pState; - return error; + return IVAS_ERR_OK; } @@ -1862,11 +1856,11 @@ static ivas_error ivas_binaural_reverb_open( return IVAS_ERR_OK; } + /*------------------------------------------------------------------------- * ivas_binaural_reverb_init() * - * Allocate and initialize binaural room reverberator handle - * for CLDFB renderers + * Initialize binaural room reverberator handle for FastConv renderer *------------------------------------------------------------------------*/ ivas_error ivas_binaural_reverb_init( @@ -1886,16 +1880,15 @@ ivas_error ivas_binaural_reverb_init( float revTimes[CLDFB_NO_CHANNELS_MAX]; float revEne[CLDFB_NO_CHANNELS_MAX]; - error = IVAS_ERR_OK; - if ( roomAcoustics != NULL ) { - if ( ( error = ivas_reverb_prepare_cldfb_params( roomAcoustics, hHrtfStatistics, sampling_rate, revTimes, revEne ) ) != IVAS_ERR_OK ) { return error; } - preDelay = (int16_t) roundf( 48000.0f * roomAcoustics->acousticPreDelay / CLDFB_NO_CHANNELS_MAX ); + + /* Convert preDelay from seconds to CLDFB slots as needed by binaural reverb */ + preDelay = (int16_t) roundf( roomAcoustics->acousticPreDelay * CLDFB_SLOTS_PER_SECOND ); } else { @@ -1928,6 +1921,7 @@ ivas_error ivas_binaural_reverb_init( adjustedEarlyEne = earlyEne[bin] + revEne[bin] * energyModifier; earlyEne[bin] = adjustedEarlyEne; /* Store already here */ } + adjustedLateEne = revEne[bin] * ( 1.0f - energyModifier ); /* Store adjusted room effect parameters to be used in reverb processing */ @@ -1941,6 +1935,7 @@ ivas_error ivas_binaural_reverb_init( return error; } + /*------------------------------------------------------------------------- * ivas_binaural_reverb_close() * diff --git a/lib_rend/ivas_reverb_utils.c b/lib_rend/ivas_reverb_utils.c index 9c4f590a01d21f0e584af1d8e29277d789171339..855d47673cf13a6c40daa4be91eb53e95b1b4739 100644 --- a/lib_rend/ivas_reverb_utils.c +++ b/lib_rend/ivas_reverb_utils.c @@ -75,7 +75,6 @@ static void ivas_reverb_set_energies( const float *avg_pwr_l, const float *avg_p *-----------------------------------------------------------------------------------------*/ ivas_error ivas_reverb_prepare_cldfb_params( - const IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pInput_params, const HRTFS_STATISTICS_HANDLE hHrtfStatistics, const int32_t output_Fs, @@ -137,8 +136,7 @@ static void ivas_reverb_set_energies( int16_t freq_idx; const int16_t cldfb_freq_halfstep = IVAS_MAX_SAMPLING_RATE / ( 4 * IVAS_CLDFB_NO_CHANNELS_MAX ); float input_fc[FFT_SPECTRUM_SIZE]; - float output_fc[CLDFB_NO_CHANNELS_MAX]; - + float output_fc[IVAS_CLDFB_NO_CHANNELS_MAX]; const int16_t avg_pwr_len = sampling_rate == 16000 ? LR_IAC_LENGTH_NR_FC_16KHZ : LR_IAC_LENGTH_NR_FC; for ( freq_idx = 0; freq_idx < avg_pwr_len; freq_idx++ ) @@ -150,5 +148,6 @@ static void ivas_reverb_set_energies( { output_fc[freq_idx] = (float) ( ( 2 * freq_idx + 1 ) * cldfb_freq_halfstep ); } + ivas_reverb_interpolate_acoustic_data( avg_pwr_len, input_fc, avg_pwr_l, avg_pwr_r, IVAS_CLDFB_NO_CHANNELS_MAX, output_fc, avg_pwr_left, avg_pwr_right ); } diff --git a/lib_rend/ivas_rom_TdBinauralRenderer.c b/lib_rend/ivas_rom_TdBinauralRenderer.c index 54c530a92e156194cc56afae22b8d60700e70c63..40a60e9f263b0ba40bcb01709f611f765839727a 100644 --- a/lib_rend/ivas_rom_TdBinauralRenderer.c +++ b/lib_rend/ivas_rom_TdBinauralRenderer.c @@ -30,14 +30,17 @@ *******************************************************************************************************/ +/* clang-format off */ + +#include #include "options.h" #ifdef DEBUGGING #include "debug.h" #endif +#include "cnst.h" #include "ivas_cnst.h" #include "wmc_auto.h" -/* clang-format off */ #define WMC_TOOL_SKIP /*------------------------------------------------------------------------- @@ -48,7 +51,6 @@ /* Generated on 31-Jul-2024 with Matlab version 9.9.0.2037887 (R2020b) Update 8 by tmu on MACI64 */ #endif - const float defaultHRIR_rom_latency_s = 0.000020834f; const int16_t defaultHRIR_rom_model_configuration[6] = { 1, /* UseItdModel */ @@ -10184,5 +10186,6 @@ const float defaultHRIR_rom_ITD_elevKSeq[16] = { -90.000000f, -78.000000f, -66.000000f, -54.000000f, -42.000000f, -30.000000f, -18.000000f, -6.000000f, 6.000000f, 18.000000f, 30.000000f, 42.000000f, 54.000000f, 66.000000f, 78.000000f, 90.000000f, }; -/* clang-format on */ #undef WMC_TOOL_SKIP + +/* clang-format on */ diff --git a/lib_rend/ivas_rom_binauralRenderer.c b/lib_rend/ivas_rom_binauralRenderer.c index 632ff2826837ec585decb0a1b6fd0ed5e3e2f95b..9253002407ddfb1fcd180e235d0725caff9ebbbd 100644 --- a/lib_rend/ivas_rom_binauralRenderer.c +++ b/lib_rend/ivas_rom_binauralRenderer.c @@ -30,14 +30,17 @@ *******************************************************************************************************/ +#include #include "options.h" #ifdef DEBUGGING #include "debug.h" #endif +#include "cnst.h" #include "ivas_cnst.h" #include "wmc_auto.h" /* clang-format off */ + #define WMC_TOOL_SKIP #ifdef DEBUGGING @@ -47506,5 +47509,6 @@ const float parametricEarlyPartEneCorrection[CLDFB_NO_CHANNELS_MAX] = { 0x1.0c0000p-6, 0x1.5e0000p-5, 0x1.3d0000p-4, 0x1.0f0000p-4, 0x1.580000p-5, 0x1.480000p-6, 0x1.000000p-7, 0x1.800000p-9, 0x1.000000p-10, 0x1.000000p-12 }; -/* clang-format on */ #undef WMC_TOOL_SKIP + +/* clang-format on */ diff --git a/lib_rend/ivas_rom_binaural_crend_head.c b/lib_rend/ivas_rom_binaural_crend_head.c index b46a1059476a1a66f3dd480684144e476fce03b0..d10337663ada338ee666295c2055971e1a0f653f 100644 --- a/lib_rend/ivas_rom_binaural_crend_head.c +++ b/lib_rend/ivas_rom_binaural_crend_head.c @@ -30,6 +30,8 @@ *******************************************************************************************************/ +/* clang-format off */ + /*------------------------------------------------------------------------- * Binaural rendering related ROM tables *------------------------------------------------------------------------*/ @@ -38,13 +40,17 @@ /* Tables generated by scripts/binauralRenderer_interface/generate_cren_ivas_tables.c, see mixer_conv_sofa_to_rom_table_converter_readme.txt */ /* Can be replaced by your own generated HRIR or BRIR tables */ + + #include #include "ivas_cnst.h" /* clang-format off */ + #define WMC_TOOL_SKIP + /********************** CRendBin_Combined_HRIR **********************/ const float CRendBin_Combined_HRIR_latency_s = 0x1.5d8ap-16; @@ -7409,5 +7415,6 @@ const float defaultHRIR_right_avg_power_16kHz[LR_IAC_LENGTH_NR_FC_16KHZ] = 0x1.a2ap-2, 0x1.8bdp-2, 0x1.74ep-2, 0x1.5e8p-2, 0x1.496p-2, 0x1.361p-2, 0x1.24ep-2, 0x1.161p-2, 0x1.09ep-2, 0x1.00bp-2, 0x1.f6p-3, 0x1.f2p-3}; + #undef WMC_TOOL_SKIP -/* clang-format on */ + diff --git a/lib_rend/ivas_rom_binaural_crend_head.h b/lib_rend/ivas_rom_binaural_crend_head.h index 4777ef0aa9d90b245cab430c7bfd16b85796b731..e445561b7b81c2373ffb4afcf3155e46fc9f219d 100644 --- a/lib_rend/ivas_rom_binaural_crend_head.h +++ b/lib_rend/ivas_rom_binaural_crend_head.h @@ -30,21 +30,25 @@ *******************************************************************************************************/ +/* clang-format off */ + /*------------------------------------------------------------------------- - * Binaural rendering related ROM tables - *------------------------------------------------------------------------*/ +* Binaural rendering related ROM tables +*------------------------------------------------------------------------*/ /* Binaural rendering data set based on HRIRs */ /* Tables generated by scripts/binauralRenderer_interface/generate_cren_ivas_tables.c, see mixer_conv_sofa_to_rom_table_converter_readme.txt */ /* Can be replaced by your own generated HRIR or BRIR tables */ + #ifndef _IVAS_ROM_BINAURAL_CREND_HEAD_ #define _IVAS_ROM_BINAURAL_CREND_HEAD_ #include "ivas_cnst.h" + /********************** CRendBin_Combined_HRIR **********************/ extern const float CRendBin_Combined_HRIR_latency_s; @@ -58,8 +62,8 @@ extern const uint16_t CRendBin_Combined_HRIR_pIndex_frequency_max_48kHz[HRTF_LS_ extern const uint16_t CRendBin_Combined_HRIR_index_frequency_max_diffuse_48kHz; extern const float CRendBin_Combined_HRIR_inv_diffuse_weight_48kHz[BINAURAL_CHANNELS][HRTF_LS_CHANNELS]; extern const uint16_t *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; -extern const float CRendBin_Combined_HRIR_coeff_re_48kHz[HRTF_LS_CHANNELS][BINAURAL_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; -extern const float CRendBin_Combined_HRIR_coeff_im_48kHz[HRTF_LS_CHANNELS][BINAURAL_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_Combined_HRIR_coeff_re_48kHz[HRTF_LS_CHANNELS][BINAURAL_CHANNELS][L_FRAME48k/MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_Combined_HRIR_coeff_im_48kHz[HRTF_LS_CHANNELS][BINAURAL_CHANNELS][L_FRAME48k/MAX_PARAM_SPATIAL_SUBFRAMES]; extern const float *CRendBin_Combined_HRIR_coeff_diffuse_re_48kHz[BINAURAL_CHANNELS]; extern const float *CRendBin_Combined_HRIR_coeff_diffuse_im_48kHz[BINAURAL_CHANNELS]; @@ -72,8 +76,8 @@ extern const uint16_t CRendBin_Combined_HRIR_pIndex_frequency_max_32kHz[HRTF_LS_ extern const uint16_t CRendBin_Combined_HRIR_index_frequency_max_diffuse_32kHz; extern const float CRendBin_Combined_HRIR_inv_diffuse_weight_32kHz[BINAURAL_CHANNELS][HRTF_LS_CHANNELS]; extern const uint16_t *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; -extern const float CRendBin_Combined_HRIR_coeff_re_32kHz[HRTF_LS_CHANNELS][BINAURAL_CHANNELS][L_FRAME32k / MAX_PARAM_SPATIAL_SUBFRAMES]; -extern const float CRendBin_Combined_HRIR_coeff_im_32kHz[HRTF_LS_CHANNELS][BINAURAL_CHANNELS][L_FRAME32k / MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_Combined_HRIR_coeff_re_32kHz[HRTF_LS_CHANNELS][BINAURAL_CHANNELS][L_FRAME32k/MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_Combined_HRIR_coeff_im_32kHz[HRTF_LS_CHANNELS][BINAURAL_CHANNELS][L_FRAME32k/MAX_PARAM_SPATIAL_SUBFRAMES]; extern const float *CRendBin_Combined_HRIR_coeff_diffuse_re_32kHz[BINAURAL_CHANNELS]; extern const float *CRendBin_Combined_HRIR_coeff_diffuse_im_32kHz[BINAURAL_CHANNELS]; @@ -86,12 +90,13 @@ extern const uint16_t CRendBin_Combined_HRIR_pIndex_frequency_max_16kHz[HRTF_LS_ extern const uint16_t CRendBin_Combined_HRIR_index_frequency_max_diffuse_16kHz; extern const float CRendBin_Combined_HRIR_inv_diffuse_weight_16kHz[BINAURAL_CHANNELS][HRTF_LS_CHANNELS]; extern const uint16_t *CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; -extern const float CRendBin_Combined_HRIR_coeff_re_16kHz[HRTF_LS_CHANNELS][BINAURAL_CHANNELS][L_FRAME16k / MAX_PARAM_SPATIAL_SUBFRAMES]; -extern const float CRendBin_Combined_HRIR_coeff_im_16kHz[HRTF_LS_CHANNELS][BINAURAL_CHANNELS][L_FRAME16k / MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_Combined_HRIR_coeff_re_16kHz[HRTF_LS_CHANNELS][BINAURAL_CHANNELS][L_FRAME16k/MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_Combined_HRIR_coeff_im_16kHz[HRTF_LS_CHANNELS][BINAURAL_CHANNELS][L_FRAME16k/MAX_PARAM_SPATIAL_SUBFRAMES]; extern const float *CRendBin_Combined_HRIR_coeff_diffuse_re_16kHz[BINAURAL_CHANNELS]; extern const float *CRendBin_Combined_HRIR_coeff_diffuse_im_16kHz[BINAURAL_CHANNELS]; + /********************** CRendBin_FOA_HRIR **********************/ extern const float CRendBin_FOA_HRIR_latency_s; @@ -105,8 +110,8 @@ extern const uint16_t CRendBin_FOA_HRIR_pIndex_frequency_max_48kHz[FOA_CHANNELS] extern const uint16_t CRendBin_FOA_HRIR_index_frequency_max_diffuse_48kHz; extern const float CRendBin_FOA_HRIR_inv_diffuse_weight_48kHz[BINAURAL_CHANNELS][FOA_CHANNELS]; extern const uint16_t *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; -extern const float CRendBin_FOA_HRIR_coeff_re_48kHz[FOA_CHANNELS][BINAURAL_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; -extern const float CRendBin_FOA_HRIR_coeff_im_48kHz[FOA_CHANNELS][BINAURAL_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_FOA_HRIR_coeff_re_48kHz[FOA_CHANNELS][BINAURAL_CHANNELS][L_FRAME48k/MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_FOA_HRIR_coeff_im_48kHz[FOA_CHANNELS][BINAURAL_CHANNELS][L_FRAME48k/MAX_PARAM_SPATIAL_SUBFRAMES]; extern const float *CRendBin_FOA_HRIR_coeff_diffuse_re_48kHz[BINAURAL_CHANNELS]; extern const float *CRendBin_FOA_HRIR_coeff_diffuse_im_48kHz[BINAURAL_CHANNELS]; @@ -119,8 +124,8 @@ extern const uint16_t CRendBin_FOA_HRIR_pIndex_frequency_max_32kHz[FOA_CHANNELS] extern const uint16_t CRendBin_FOA_HRIR_index_frequency_max_diffuse_32kHz; extern const float CRendBin_FOA_HRIR_inv_diffuse_weight_32kHz[BINAURAL_CHANNELS][FOA_CHANNELS]; extern const uint16_t *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; -extern const float CRendBin_FOA_HRIR_coeff_re_32kHz[FOA_CHANNELS][BINAURAL_CHANNELS][L_FRAME32k / MAX_PARAM_SPATIAL_SUBFRAMES]; -extern const float CRendBin_FOA_HRIR_coeff_im_32kHz[FOA_CHANNELS][BINAURAL_CHANNELS][L_FRAME32k / MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_FOA_HRIR_coeff_re_32kHz[FOA_CHANNELS][BINAURAL_CHANNELS][L_FRAME32k/MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_FOA_HRIR_coeff_im_32kHz[FOA_CHANNELS][BINAURAL_CHANNELS][L_FRAME32k/MAX_PARAM_SPATIAL_SUBFRAMES]; extern const float *CRendBin_FOA_HRIR_coeff_diffuse_re_32kHz[BINAURAL_CHANNELS]; extern const float *CRendBin_FOA_HRIR_coeff_diffuse_im_32kHz[BINAURAL_CHANNELS]; @@ -133,12 +138,13 @@ extern const uint16_t CRendBin_FOA_HRIR_pIndex_frequency_max_16kHz[FOA_CHANNELS] extern const uint16_t CRendBin_FOA_HRIR_index_frequency_max_diffuse_16kHz; extern const float CRendBin_FOA_HRIR_inv_diffuse_weight_16kHz[BINAURAL_CHANNELS][FOA_CHANNELS]; extern const uint16_t *CRendBin_FOA_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; -extern const float CRendBin_FOA_HRIR_coeff_re_16kHz[FOA_CHANNELS][BINAURAL_CHANNELS][L_FRAME16k / MAX_PARAM_SPATIAL_SUBFRAMES]; -extern const float CRendBin_FOA_HRIR_coeff_im_16kHz[FOA_CHANNELS][BINAURAL_CHANNELS][L_FRAME16k / MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_FOA_HRIR_coeff_re_16kHz[FOA_CHANNELS][BINAURAL_CHANNELS][L_FRAME16k/MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_FOA_HRIR_coeff_im_16kHz[FOA_CHANNELS][BINAURAL_CHANNELS][L_FRAME16k/MAX_PARAM_SPATIAL_SUBFRAMES]; extern const float *CRendBin_FOA_HRIR_coeff_diffuse_re_16kHz[BINAURAL_CHANNELS]; extern const float *CRendBin_FOA_HRIR_coeff_diffuse_im_16kHz[BINAURAL_CHANNELS]; + /********************** CRendBin_HOA2_HRIR **********************/ extern const float CRendBin_HOA2_HRIR_latency_s; @@ -152,8 +158,8 @@ extern const uint16_t CRendBin_HOA2_HRIR_pIndex_frequency_max_48kHz[HOA2_CHANNEL extern const uint16_t CRendBin_HOA2_HRIR_index_frequency_max_diffuse_48kHz; extern const float CRendBin_HOA2_HRIR_inv_diffuse_weight_48kHz[BINAURAL_CHANNELS][HOA2_CHANNELS]; extern const uint16_t *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; -extern const float CRendBin_HOA2_HRIR_coeff_re_48kHz[HOA2_CHANNELS][BINAURAL_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; -extern const float CRendBin_HOA2_HRIR_coeff_im_48kHz[HOA2_CHANNELS][BINAURAL_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_HOA2_HRIR_coeff_re_48kHz[HOA2_CHANNELS][BINAURAL_CHANNELS][L_FRAME48k/MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_HOA2_HRIR_coeff_im_48kHz[HOA2_CHANNELS][BINAURAL_CHANNELS][L_FRAME48k/MAX_PARAM_SPATIAL_SUBFRAMES]; extern const float *CRendBin_HOA2_HRIR_coeff_diffuse_re_48kHz[BINAURAL_CHANNELS]; extern const float *CRendBin_HOA2_HRIR_coeff_diffuse_im_48kHz[BINAURAL_CHANNELS]; @@ -166,8 +172,8 @@ extern const uint16_t CRendBin_HOA2_HRIR_pIndex_frequency_max_32kHz[HOA2_CHANNEL extern const uint16_t CRendBin_HOA2_HRIR_index_frequency_max_diffuse_32kHz; extern const float CRendBin_HOA2_HRIR_inv_diffuse_weight_32kHz[BINAURAL_CHANNELS][HOA2_CHANNELS]; extern const uint16_t *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; -extern const float CRendBin_HOA2_HRIR_coeff_re_32kHz[HOA2_CHANNELS][BINAURAL_CHANNELS][L_FRAME32k / MAX_PARAM_SPATIAL_SUBFRAMES]; -extern const float CRendBin_HOA2_HRIR_coeff_im_32kHz[HOA2_CHANNELS][BINAURAL_CHANNELS][L_FRAME32k / MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_HOA2_HRIR_coeff_re_32kHz[HOA2_CHANNELS][BINAURAL_CHANNELS][L_FRAME32k/MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_HOA2_HRIR_coeff_im_32kHz[HOA2_CHANNELS][BINAURAL_CHANNELS][L_FRAME32k/MAX_PARAM_SPATIAL_SUBFRAMES]; extern const float *CRendBin_HOA2_HRIR_coeff_diffuse_re_32kHz[BINAURAL_CHANNELS]; extern const float *CRendBin_HOA2_HRIR_coeff_diffuse_im_32kHz[BINAURAL_CHANNELS]; @@ -180,12 +186,13 @@ extern const uint16_t CRendBin_HOA2_HRIR_pIndex_frequency_max_16kHz[HOA2_CHANNEL extern const uint16_t CRendBin_HOA2_HRIR_index_frequency_max_diffuse_16kHz; extern const float CRendBin_HOA2_HRIR_inv_diffuse_weight_16kHz[BINAURAL_CHANNELS][HOA2_CHANNELS]; extern const uint16_t *CRendBin_HOA2_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; -extern const float CRendBin_HOA2_HRIR_coeff_re_16kHz[HOA2_CHANNELS][BINAURAL_CHANNELS][L_FRAME16k / MAX_PARAM_SPATIAL_SUBFRAMES]; -extern const float CRendBin_HOA2_HRIR_coeff_im_16kHz[HOA2_CHANNELS][BINAURAL_CHANNELS][L_FRAME16k / MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_HOA2_HRIR_coeff_re_16kHz[HOA2_CHANNELS][BINAURAL_CHANNELS][L_FRAME16k/MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_HOA2_HRIR_coeff_im_16kHz[HOA2_CHANNELS][BINAURAL_CHANNELS][L_FRAME16k/MAX_PARAM_SPATIAL_SUBFRAMES]; extern const float *CRendBin_HOA2_HRIR_coeff_diffuse_re_16kHz[BINAURAL_CHANNELS]; extern const float *CRendBin_HOA2_HRIR_coeff_diffuse_im_16kHz[BINAURAL_CHANNELS]; + /********************** CRendBin_HOA3_HRIR **********************/ extern const float CRendBin_HOA3_HRIR_latency_s; @@ -199,8 +206,8 @@ extern const uint16_t CRendBin_HOA3_HRIR_pIndex_frequency_max_48kHz[HOA3_CHANNEL extern const uint16_t CRendBin_HOA3_HRIR_index_frequency_max_diffuse_48kHz; extern const float CRendBin_HOA3_HRIR_inv_diffuse_weight_48kHz[BINAURAL_CHANNELS][HOA3_CHANNELS]; extern const uint16_t *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_48kHz[BINAURAL_CHANNELS]; -extern const float CRendBin_HOA3_HRIR_coeff_re_48kHz[HOA3_CHANNELS][BINAURAL_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; -extern const float CRendBin_HOA3_HRIR_coeff_im_48kHz[HOA3_CHANNELS][BINAURAL_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_HOA3_HRIR_coeff_re_48kHz[HOA3_CHANNELS][BINAURAL_CHANNELS][L_FRAME48k/MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_HOA3_HRIR_coeff_im_48kHz[HOA3_CHANNELS][BINAURAL_CHANNELS][L_FRAME48k/MAX_PARAM_SPATIAL_SUBFRAMES]; extern const float *CRendBin_HOA3_HRIR_coeff_diffuse_re_48kHz[BINAURAL_CHANNELS]; extern const float *CRendBin_HOA3_HRIR_coeff_diffuse_im_48kHz[BINAURAL_CHANNELS]; @@ -213,8 +220,8 @@ extern const uint16_t CRendBin_HOA3_HRIR_pIndex_frequency_max_32kHz[HOA3_CHANNEL extern const uint16_t CRendBin_HOA3_HRIR_index_frequency_max_diffuse_32kHz; extern const float CRendBin_HOA3_HRIR_inv_diffuse_weight_32kHz[BINAURAL_CHANNELS][HOA3_CHANNELS]; extern const uint16_t *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_32kHz[BINAURAL_CHANNELS]; -extern const float CRendBin_HOA3_HRIR_coeff_re_32kHz[HOA3_CHANNELS][BINAURAL_CHANNELS][L_FRAME32k / MAX_PARAM_SPATIAL_SUBFRAMES]; -extern const float CRendBin_HOA3_HRIR_coeff_im_32kHz[HOA3_CHANNELS][BINAURAL_CHANNELS][L_FRAME32k / MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_HOA3_HRIR_coeff_re_32kHz[HOA3_CHANNELS][BINAURAL_CHANNELS][L_FRAME32k/MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_HOA3_HRIR_coeff_im_32kHz[HOA3_CHANNELS][BINAURAL_CHANNELS][L_FRAME32k/MAX_PARAM_SPATIAL_SUBFRAMES]; extern const float *CRendBin_HOA3_HRIR_coeff_diffuse_re_32kHz[BINAURAL_CHANNELS]; extern const float *CRendBin_HOA3_HRIR_coeff_diffuse_im_32kHz[BINAURAL_CHANNELS]; @@ -227,12 +234,13 @@ extern const uint16_t CRendBin_HOA3_HRIR_pIndex_frequency_max_16kHz[HOA3_CHANNEL extern const uint16_t CRendBin_HOA3_HRIR_index_frequency_max_diffuse_16kHz; extern const float CRendBin_HOA3_HRIR_inv_diffuse_weight_16kHz[BINAURAL_CHANNELS][HOA3_CHANNELS]; extern const uint16_t *CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_16kHz[BINAURAL_CHANNELS]; -extern const float CRendBin_HOA3_HRIR_coeff_re_16kHz[HOA3_CHANNELS][BINAURAL_CHANNELS][L_FRAME16k / MAX_PARAM_SPATIAL_SUBFRAMES]; -extern const float CRendBin_HOA3_HRIR_coeff_im_16kHz[HOA3_CHANNELS][BINAURAL_CHANNELS][L_FRAME16k / MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_HOA3_HRIR_coeff_re_16kHz[HOA3_CHANNELS][BINAURAL_CHANNELS][L_FRAME16k/MAX_PARAM_SPATIAL_SUBFRAMES]; +extern const float CRendBin_HOA3_HRIR_coeff_im_16kHz[HOA3_CHANNELS][BINAURAL_CHANNELS][L_FRAME16k/MAX_PARAM_SPATIAL_SUBFRAMES]; extern const float *CRendBin_HOA3_HRIR_coeff_diffuse_re_16kHz[BINAURAL_CHANNELS]; extern const float *CRendBin_HOA3_HRIR_coeff_diffuse_im_16kHz[BINAURAL_CHANNELS]; + /********************** CRendBin_Combined_BRIR **********************/ extern const float CRendBin_Combined_BRIR_latency_s; diff --git a/lib_rend/ivas_rom_rend.c b/lib_rend/ivas_rom_rend.c index b14a5303a0f40b052ce7224d39247b7346f6abec..3f4b906bd6fdaa8159f22abe9ed3fb2686c3fd6e 100644 --- a/lib_rend/ivas_rom_rend.c +++ b/lib_rend/ivas_rom_rend.c @@ -163,15 +163,9 @@ const float ap_lattice_coeffs_3[DIRAC_DECORR_FILTER_LEN_3*DIRAC_MAX_NUM_DECORR_F const float * const ap_lattice_coeffs[DIRAC_DECORR_NUM_SPLIT_BANDS] = { -#ifdef CODE_IMPROVEMENTS ap_lattice_coeffs_1, ap_lattice_coeffs_2, ap_lattice_coeffs_3, -#else - &ap_lattice_coeffs_1[0], - &ap_lattice_coeffs_2[0], - &ap_lattice_coeffs_3[0], -#endif }; const float ap_split_frequencies[DIRAC_DECORR_NUM_SPLIT_BANDS + 1] = @@ -183,11 +177,13 @@ const int16_t sba_map_tc[11] = { 0, 1, 2, 3, 4, 8, 9, 15, 5, 6, 7 }; + const int16_t sba_map_tc_512[11] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15 }; + /*----------------------------------------------------------------------------------* * FASTCONV and PARAMETRIC binaural renderer ROM tables *----------------------------------------------------------------------------------*/ @@ -386,6 +382,7 @@ const float ivas_reverb_default_DSR[IVAS_REVERB_DEFAULT_N_BANDS] = 6.2001e-08f, 2.8483e-08f, 2.6267e-08f }; + /*----------------------------------------------------------------------------------* * Renderer SBA & MC enc/dec matrices *----------------------------------------------------------------------------------*/ @@ -394,6 +391,7 @@ const float ivas_reverb_default_DSR[IVAS_REVERB_DEFAULT_N_BANDS] = const float ls_azimuth_CICP1[1] = { 0.0f }; const float ls_elevation_CICP1[1] = { 0.0f }; + /*----------------------------------------------------------------------------------* * EFAP ROM tables *----------------------------------------------------------------------------------*/ diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 241b2ae5dac39aaa9e8451cd4e1fee7c46dc74fc..95361e116a0128101eb30f9a3d1f73ee0213f0a4 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -49,17 +49,10 @@ * Local funtion declarations *-----------------------------------------------------------------------*/ -static ivas_error combine_external_and_head_orientations( - IVAS_QUATERNION *headRotQuaternions, - IVAS_VECTOR3 *listenerPos, - ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis*/ - EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData ); -static void external_target_interpolation( - EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, - const int16_t i ); +static ivas_error combine_external_and_head_orientations( IVAS_QUATERNION *headRotQuaternions, IVAS_VECTOR3 *listenerPos, ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData ); + +static void external_target_interpolation( EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, const int16_t i ); static bool are_orientations_same( const IVAS_QUATERNION *orientation1, const IVAS_QUATERNION *orientation2 ); @@ -178,6 +171,7 @@ void QuatToRotMat( return; } + /*------------------------------------------------------------------------- * rad2deg() * @@ -712,6 +706,7 @@ ivas_error ivas_external_orientation_open( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for external orientation memory\n" ) ); } ( *hExtOrientationData )->num_subframes = num_subframes; + /* Enable head rotation and disable external orientation as default */ for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { @@ -721,6 +716,7 @@ ivas_error ivas_external_orientation_open( ( *hExtOrientationData )->numFramesToTargetOrientation[i] = 0; ( *hExtOrientationData )->Quaternions[i] = identity; } + return IVAS_ERR_OK; } @@ -828,6 +824,14 @@ ivas_error ivas_combined_orientation_open( ( *hCombinedOrientationData )->subframe_idx = 0; ( *hCombinedOrientationData )->subframe_size = (int16_t) ( fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ); ( *hCombinedOrientationData )->cur_subframe_samples_rendered = 0; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + + for ( i = 0; i < ( 1 + IVAS_MAX_NUM_OBJECTS ); i++ ) + { + ( *hCombinedOrientationData )->isDiegeticInputPI[i] = true; + } + ( *hCombinedOrientationData )->isDiegeticInputPISet = false; +#endif return IVAS_ERR_OK; } @@ -882,9 +886,7 @@ ivas_error combine_external_and_head_orientations_dec( sr_pose_pred_axis = DEFAULT_AXIS; } - return combine_external_and_head_orientations( pHeadRotQuaternion, listenerPos, - sr_pose_pred_axis, - hExtOrientationData, hCombinedOrientationData ); + return combine_external_and_head_orientations( pHeadRotQuaternion, listenerPos, sr_pose_pred_axis, hExtOrientationData, hCombinedOrientationData ); } @@ -906,20 +908,10 @@ ivas_error combine_external_and_head_orientations_rend( int16_t i; sr_pose_pred_axis = DEFAULT_AXIS; -#ifdef FIX_1383_HEAD_TRACK_SANITIZER if ( hHeadTrackData->headRotEnabled ) { headRotQuaternions = hHeadTrackData->headPositions; listenerPos = hHeadTrackData->Pos; -#else - if ( hHeadTrackData != NULL ) - { - if ( hHeadTrackData->headRotEnabled ) - { - headRotQuaternions = hHeadTrackData->headPositions; - listenerPos = hHeadTrackData->Pos; - } -#endif sr_pose_pred_axis = hHeadTrackData->sr_pose_pred_axis; } else if ( hExtOrientationData != NULL ) @@ -934,9 +926,7 @@ ivas_error combine_external_and_head_orientations_rend( } } - return combine_external_and_head_orientations( headRotQuaternions, listenerPos, - sr_pose_pred_axis, - hExtOrientationData, hCombinedOrientationData ); + return combine_external_and_head_orientations( headRotQuaternions, listenerPos, sr_pose_pred_axis, hExtOrientationData, hCombinedOrientationData ); } @@ -999,11 +989,30 @@ ivas_error combine_external_and_head_orientations( } else if ( hExtOrientationData == NULL && headRotQuaternions != NULL ) { +#ifdef RTP_S4_251135_CR26253_0016_REV1 + /* Disable head rotation if diegetic PI data indicating non-diegetic audio is received */ + if ( hCombinedOrientationData->isDiegeticInputPISet && !hCombinedOrientationData->isDiegeticInputPI[0] && !hCombinedOrientationData->isDiegeticInputPI[1] && !hCombinedOrientationData->isDiegeticInputPI[2] && !hCombinedOrientationData->isDiegeticInputPI[3] && !hCombinedOrientationData->isDiegeticInputPI[4] ) + { + for ( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + hCombinedOrientationData->Quaternions[i] = identity; + } + } + else + { + /* Head rotation only */ + for ( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + hCombinedOrientationData->Quaternions[i] = headRotQuaternions[i]; + } + } +#else /* Head rotation only */ for ( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) { hCombinedOrientationData->Quaternions[i] = headRotQuaternions[i]; } +#endif } if ( hExtOrientationData != NULL ) @@ -1080,6 +1089,40 @@ ivas_error combine_external_and_head_orientations( hCombinedOrientationData->Quaternion_frozen_head = identity; hCombinedOrientationData->isHeadRotationFrozen = 0; } +#ifdef RTP_S4_251135_CR26253_0016_REV1 + /* Disable head rotation if diegetic PI data indicating non-diegetic audio is received */ + if ( hCombinedOrientationData->isDiegeticInputPISet && !hCombinedOrientationData->isDiegeticInputPI[0] && !hCombinedOrientationData->isDiegeticInputPI[1] && !hCombinedOrientationData->isDiegeticInputPI[2] && !hCombinedOrientationData->isDiegeticInputPI[3] && !hCombinedOrientationData->isDiegeticInputPI[4] ) + { + continue; + } + else + { + /* Use the most recent head rotation */ + if ( hExtOrientationData->enableHeadRotation[i] == 1 ) + { + if ( hExtOrientationData->enableExternalOrientation[i] > 0 ) + { + QuaternionProduct( hCombinedOrientationData->Quaternions[i], headRotQuaternions[i], &hCombinedOrientationData->Quaternions[i] ); + } + else + { + hCombinedOrientationData->Quaternions[i] = headRotQuaternions[i]; + } + } + /* Use the freezed head rotation */ + else if ( hExtOrientationData->enableHeadRotation[i] == 2 ) + { + if ( hExtOrientationData->enableExternalOrientation[i] > 0 ) + { + QuaternionProduct( hCombinedOrientationData->Quaternions[i], hCombinedOrientationData->Quaternion_frozen_head, &hCombinedOrientationData->Quaternions[i] ); + } + else + { + hCombinedOrientationData->Quaternions[i] = hCombinedOrientationData->Quaternion_frozen_head; + } + } + } +#else /* Use the most recent head rotation */ if ( hExtOrientationData->enableHeadRotation[i] == 1 ) { @@ -1104,6 +1147,7 @@ ivas_error combine_external_and_head_orientations( hCombinedOrientationData->Quaternions[i] = hCombinedOrientationData->Quaternion_frozen_head; } } +#endif /* Reset the combined orientations to identity */ if ( hExtOrientationData->enableHeadRotation[i] == 0 && hExtOrientationData->enableExternalOrientation[i] == 0 ) @@ -1186,12 +1230,32 @@ ivas_error combine_external_and_head_orientations( } } +#ifdef DEBUG_MODE_ORIENTATION + for ( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + dbgwrite( &hCombinedOrientationData->enableCombinedOrientation[i], sizeof( int16_t ), 1, 1, "res/dec_orientation_enabled.dat" ); + dbgwrite( &( hCombinedOrientationData->Quaternions[i].w ), sizeof( float ), 1, 1, "res/dec_orientation_quaternion_w.dat" ); + dbgwrite( &( hCombinedOrientationData->Quaternions[i].x ), sizeof( float ), 1, 1, "res/dec_orientation_quaternion_x.dat" ); + dbgwrite( &( hCombinedOrientationData->Quaternions[i].y ), sizeof( float ), 1, 1, "res/dec_orientation_quaternion_y.dat" ); + dbgwrite( &( hCombinedOrientationData->Quaternions[i].z ), sizeof( float ), 1, 1, "res/dec_orientation_quaternion_z.dat" ); + } +#endif hCombinedOrientationData->sr_pose_pred_axis = sr_pose_pred_axis; hCombinedOrientationData->subframe_idx = 0; hCombinedOrientationData->cur_subframe_samples_rendered = 0; hCombinedOrientationData->subframe_idx_start = 0; hCombinedOrientationData->cur_subframe_samples_rendered_start = 0; +#ifdef IVAS_RTPDUMP + /* Reset external orientations */ + if ( hExtOrientationData != NULL ) + { + for ( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + hExtOrientationData->Quaternions[i] = identity; + } + } +#endif return IVAS_ERR_OK; } diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index e248c7bdc38c5a41b4f17b6f4aaab2af94668a5f..6730875f6c39f5bc185b2323ca286e20576bc899 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -494,6 +494,7 @@ typedef struct ivas_diffuse_distribution_data_structure } DIFFUSE_DISTRIBUTION_DATA, *DIFFUSE_DISTRIBUTION_HANDLE; +/* Parametric binaural renderer HRTF structure */ typedef struct ivas_hrtf_parambin_struct { float hrtfShCoeffsRe[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]; @@ -628,7 +629,7 @@ typedef struct EFAP } EFAP, *EFAP_HANDLE; /*----------------------------------------------------------------------------------* - * Orientation tracking structure + * Head rotation data structure *----------------------------------------------------------------------------------*/ typedef struct ivas_orient_trk_state_t @@ -645,16 +646,12 @@ typedef struct ivas_orient_trk_state_t } ivas_orient_trk_state_t; -/*----------------------------------------------------------------------------------* - * Head rotation data structure - *----------------------------------------------------------------------------------*/ - typedef struct { int8_t headRotEnabled; - IVAS_QUATERNION headPositions[MAX_PARAM_SPATIAL_SUBFRAMES]; - IVAS_VECTOR3 Pos[MAX_PARAM_SPATIAL_SUBFRAMES]; - float crossfade[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; + IVAS_QUATERNION headPositions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + float crossfade[L_FRAME48k / IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; ivas_orient_trk_state_t *hOrientationTracker; @@ -681,25 +678,6 @@ typedef struct ivas_binaural_head_track_struct } HEAD_TRACK_DATA, *HEAD_TRACK_DATA_HANDLE; -/*----------------------------------------------------------------------------------* - * External orientation data structure - *----------------------------------------------------------------------------------*/ - -typedef struct ivas_external_orientation_struct -{ - int8_t enableHeadRotation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable, 2 - freeze to previous rotation */ - int8_t enableExternalOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable, 2 - freeze to previous orientation */ - int8_t enableRotationInterpolation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable */ - int16_t numFramesToTargetOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* Number of frames until target orientation is reached */ - IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; /* External orientation in quaternions */ - int16_t num_subframes; - -} EXTERNAL_ORIENTATION_DATA, *EXTERNAL_ORIENTATION_HANDLE; - -/*----------------------------------------------------------------------------------* - * Combined orientation data structure for the external orienations and head orientation - *----------------------------------------------------------------------------------*/ - typedef struct ivas_combined_orientation_struct { int16_t enableCombinedOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; @@ -732,8 +710,27 @@ typedef struct ivas_combined_orientation_struct int16_t cur_subframe_samples_rendered; int16_t subframe_idx_start; int16_t cur_subframe_samples_rendered_start; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + bool isDiegeticInputPI[1 + IVAS_MAX_NUM_OBJECTS]; + bool isDiegeticInputPISet; +#endif } COMBINED_ORIENTATION_DATA, *COMBINED_ORIENTATION_HANDLE; +/*----------------------------------------------------------------------------------* + * External orientation data structure + *----------------------------------------------------------------------------------*/ + +typedef struct ivas_external_orientation_struct +{ + int8_t enableHeadRotation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable, 2 - freeze to previous rotation */ + int8_t enableExternalOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable, 2 - freeze to previous orientation */ + int8_t enableRotationInterpolation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable */ + int16_t numFramesToTargetOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* Number of frames until target orientation is reached */ + IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; /* External orientation in quaternions */ + int16_t num_subframes; + +} EXTERNAL_ORIENTATION_DATA, *EXTERNAL_ORIENTATION_HANDLE; + /*----------------------------------------------------------------------------------* * Reverberator structure @@ -817,7 +814,6 @@ typedef struct ivas_reverb_state_t uint16_t fft_subblock_size; /* fft block processing size */ uint16_t num_fft_subblocks; /* number of fft subblocks */ uint16_t full_block_size; /* full block processing size */ - } REVERB_DATA, *REVERB_HANDLE; @@ -1157,6 +1153,7 @@ typedef struct int32_t binaural_latency_ns; BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd; TDREND_HRFILT_FiltSet_t **hHrtfTD; + } TDREND_WRAPPER, *TDREND_WRAPPER_HANDLE; @@ -1189,7 +1186,7 @@ typedef struct ivas_hrtf_crend_structure uint16_t *pIndex_frequency_max_dyn[MAX_INTERN_CHANNELS][BINAURAL_CHANNELS]; uint16_t *pIndex_frequency_max_diffuse_dyn[BINAURAL_CHANNELS]; -} HRTFS_DATA, *HRTFS_HANDLE, HRTFS_CREND_DATA, *HRTFS_CREND_HANDLE; // VE: all instance of HRTFS_DATAand *HRTFS_HANDLE should be renamed to HRTFS_CREND_DATA and *HRTFS_CREND_HANDLE +} HRTFS_CREND_DATA, *HRTFS_CREND_HANDLE; /* Main Crend structure */ typedef struct ivas_crend_state_t @@ -1216,7 +1213,7 @@ typedef struct ivas_binaural_crend_wrapper_struct { int32_t binaural_latency_ns; CREND_HANDLE hCrend[MAX_HEAD_ROT_POSES]; - HRTFS_HANDLE hHrtfCrend; + HRTFS_CREND_HANDLE hHrtfCrend; } CREND_WRAPPER, *CREND_WRAPPER_HANDLE; @@ -1260,13 +1257,16 @@ typedef struct ivas_hrtf_fastconv_struct float ***rightReal; float ***rightImag; int16_t n_channels; + int16_t allocate_init_flag; /*Memory allocation flag 0: if the hrtf pointers are allocated at application level , 1: of allocated at ivas_binaural_hrtf_open() */ uint16_t ntaps; + float fastconvReverberationTimes[CLDFB_NO_CHANNELS_MAX]; float fastconvReverberationEneCorrections[CLDFB_NO_CHANNELS_MAX]; } HRTFS_FASTCONV, *HRTFS_FASTCONV_HANDLE; + typedef struct ivas_hrtf_statistics_struct { const float *average_energy_l; @@ -1276,6 +1276,7 @@ typedef struct ivas_hrtf_statistics_struct float *average_energy_r_dyn; float *inter_aural_coherence_dyn; int16_t fromROM; /* Flag that indicates that the pointers point to tables in ROM (controls init/dealloc).*/ + } HRTFS_STATISTICS, *HRTFS_STATISTICS_HANDLE; @@ -1381,11 +1382,11 @@ typedef struct typedef struct { - float *data; /* samples in interleaved layout, e.g. for channels A, B, C, samples are stored: A1, B1, C1, A2, B2, C2, ... */ - int32_t capacity; /* max number of float values that can be stored */ - int16_t num_channels; - int32_t write_pos; - int32_t read_pos; + float *data; /* samples in interleaved layout */ + uint32_t capacity; + uint16_t num_channels; + uint32_t write_pos; + uint32_t read_pos; int16_t is_full; } TD_RINGBUF_DATA, *TD_RINGBUF_HANDLE; @@ -1530,10 +1531,8 @@ typedef struct ivas_dirac_ana_data_structure typedef struct ivas_masa_prerend_data_structure { -#ifdef NONBE_1344_REND_MASA_LOW_FS int16_t nbands; int16_t band_grouping[MASA_FREQUENCY_BANDS + 1]; -#endif /* CLDFB analysis */ int16_t num_Cldfb_instances; diff --git a/lib_rend/ivas_td_ring_buffer.c b/lib_rend/ivas_td_ring_buffer.c index 98b3e4d15b8de980fcf8fa1b3d289ed1147ea48a..f1fdab3af8143b15aaa1583ea998bca7d1c72a18 100644 --- a/lib_rend/ivas_td_ring_buffer.c +++ b/lib_rend/ivas_td_ring_buffer.c @@ -31,7 +31,6 @@ *******************************************************************************************************/ #include -#include #include #include "ivas_error_utils.h" #include "ivas_prot_rend.h" @@ -43,13 +42,7 @@ * Local function prototypes *-----------------------------------------------------------------------*/ -/*---------------------------------------------------------------------* - * ivas_td_ringbuf_total_size() - * - * Returns total number of buffered samples (including number of channels) - *---------------------------------------------------------------------*/ - -static int32_t ivas_td_ringbuf_total_size( +static uint32_t ivas_td_ringbuf_total_size( TD_RINGBUF_HANDLE h ) { if ( h->is_full ) @@ -68,7 +61,7 @@ static int32_t ivas_td_ringbuf_total_size( static int16_t ivas_td_ringbuf_has_space_for_num_samples( TD_RINGBUF_HANDLE h, - const int32_t num_samples ) + const uint32_t num_samples ) { return (int16_t) ( ivas_td_ringbuf_total_size( h ) + num_samples <= h->capacity ); } @@ -76,20 +69,20 @@ static int16_t ivas_td_ringbuf_has_space_for_num_samples( #ifdef FIX_1119_SPLIT_RENDERING_VOIP static void ivas_td_ringbuf_push_interleaved( - TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */ - const float *data, /* i : Input audio in interleaved channels layout */ - const int16_t num_samples_per_channel, /* i : Number of samples per channel to push */ - const int16_t read_stride /* i: : 1 for normal operation, 0 for reading from a single input value */ + TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */ + const float *data, /* i : Input audio in interleaved channels layout */ + const uint32_t num_samples_per_channel, /* i : Number of samples per channel to push */ + const uint16_t read_stride /* i: : 1 for normal operation, 0 for reading from a single input value */ ) { - int32_t s, read_s; + uint32_t s, read_s; assert( h != NULL ); assert( data != NULL ); assert( read_stride == 0 || read_stride == 1 ); - assert( ivas_td_ringbuf_has_space_for_num_samples( h, (int32_t) num_samples_per_channel * h->num_channels ) ); + assert( ivas_td_ringbuf_has_space_for_num_samples( h, num_samples_per_channel * h->num_channels ) ); - for ( s = 0, read_s = 0; s < (int32_t) num_samples_per_channel * h->num_channels; ++s, read_s += read_stride ) + for ( s = 0, read_s = 0; s < num_samples_per_channel * h->num_channels; ++s, read_s += read_stride ) { h->data[h->write_pos] = data[read_s]; ++h->write_pos; @@ -117,21 +110,21 @@ static void ivas_td_ringbuf_push_interleaved( /*---------------------------------------------------------------------* * ivas_TD_RINGBUF_Open() * - * Allocates a ring buffer for TD data with the given capacity of TD samples per channel. + * Allocate a ring buffer for TD data with the given capacity of TD samples per channel. * * May return IVAS_ERR_FAILED_ALLOC on failed allocation, or IVAS_ERR_OK otherwise. *---------------------------------------------------------------------*/ ivas_error ivas_TD_RINGBUF_Open( - TD_RINGBUF_HANDLE *ph, /* i/o: Ring buffer handle */ - const int16_t capacity_per_channel, /* i : Number of samples stored per channel */ - const int16_t num_channels /* i : Number of channels */ + TD_RINGBUF_HANDLE *ph, /* i/o: Ring buffer handle */ + const uint32_t capacity_per_channel, /* i : Number of samples stored per channel */ + const uint16_t num_channels /* i : Number of channels */ ) { TD_RINGBUF_HANDLE h; - int32_t capacity; + uint32_t capacity; - capacity = (int32_t) capacity_per_channel * num_channels; + capacity = capacity_per_channel * num_channels; h = malloc( sizeof( TD_RINGBUF_DATA ) ); if ( h == NULL ) @@ -160,7 +153,8 @@ ivas_error ivas_TD_RINGBUF_Open( /*---------------------------------------------------------------------* * ivas_TD_RINGBUF_Close() * - * Dellocates TD ring buffer. The given handle will be set to NULL. + * Dellocate TD ring buffer. The given handle will be set to NULL. + *---------------------------------------------------------------------*/ void ivas_TD_RINGBUF_Close( @@ -196,13 +190,13 @@ void ivas_TD_RINGBUF_Close( /*---------------------------------------------------------------------* * ivas_TD_RINGBUF_PushInterleaved() * - * Pushes samples from a buffer with interleaved channel layout onto the back of the TD ring buffer. + * Push samples from a buffer with interleaved channel layout onto the back of the TD ring buffer. *---------------------------------------------------------------------*/ void ivas_TD_RINGBUF_PushInterleaved( - TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */ - const float *data, /* i : Input audio in interleaved channels layout */ - const int16_t num_samples_per_channel /* i : Number of samples per channel to push */ + TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */ + const float *data, /* i : Input audio in interleaved channels layout */ + const uint32_t num_samples_per_channel /* i : Number of samples per channel to push */ ) { ivas_td_ringbuf_push_interleaved( h, data, num_samples_per_channel, 1 ); @@ -214,13 +208,13 @@ void ivas_TD_RINGBUF_PushInterleaved( /*---------------------------------------------------------------------* * ivas_TD_RINGBUF_PushChannels() * - * Pushes samples from channel pointers onto the back of the TD ring buffer. + * Push samples from channel pointers onto the back of the TD ring buffer. *---------------------------------------------------------------------*/ void ivas_TD_RINGBUF_PushChannels( - TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */ - const float *p_channels[], /* i : Array of pointers to each input channel */ - const int16_t num_samples_per_channel /* i : Number of samples per channel to push */ + TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */ + const float *p_channels[], /* i : Array of pointers to each input channel */ + const uint32_t num_samples_per_channel /* i : Number of samples per channel to push */ ) #else /*---------------------------------------------------------------------* @@ -233,12 +227,12 @@ void ivas_TD_RINGBUF_PushChannels( void ivas_TD_RINGBUF_Push( TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */ const float *data, /* i : Input data */ - const uint16_t num_samples_per_channel /* i : Number of samples per channel to store */ + const uint32_t num_samples_per_channel /* i : Number of samples per channel to store */ ) #endif { - int32_t s; - int16_t c; + uint32_t s; + uint16_t c; #ifdef FIX_1119_SPLIT_RENDERING_VOIP assert( h != NULL ); @@ -248,7 +242,7 @@ void ivas_TD_RINGBUF_Push( assert( p_channels[c] != NULL ); } #endif - assert( ivas_td_ringbuf_has_space_for_num_samples( h, (int32_t) num_samples_per_channel * h->num_channels ) ); + assert( ivas_td_ringbuf_has_space_for_num_samples( h, num_samples_per_channel * h->num_channels ) ); for ( s = 0; s < num_samples_per_channel; ++s ) { @@ -281,13 +275,13 @@ void ivas_TD_RINGBUF_Push( /*---------------------------------------------------------------------* * ivas_TD_RINGBUF_PushConstant() * - * Pushes samples with a constant value onto the back of the TD ring buffer. + * Push samples with a constant value onto the back of the TD ring buffer. *---------------------------------------------------------------------*/ void ivas_TD_RINGBUF_PushConstant( - TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */ - const float value, /* i : Value to push */ - const int16_t num_samples_per_channel /* i : Number of samples per channel to push */ + TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */ + const float value, /* i : Value to push */ + const uint32_t num_samples_per_channel /* i : Number of samples per channel to push */ ) { ivas_td_ringbuf_push_interleaved( h, &value, num_samples_per_channel, 0 ); @@ -303,10 +297,11 @@ void ivas_TD_RINGBUF_PushConstant( void ivas_TD_RINGBUF_PushZeros( TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */ - const uint16_t num_samples_per_channel /* i : Number of zeros per channel to store */ + const uint32_t num_samples_per_channel /* i : Number of zeros per channel to store */ ) { - uint16_t c, s; + uint32_t s; + uint16_t c; assert( ivas_td_ringbuf_has_space_for_num_samples( h, num_samples_per_channel * h->num_channels ) ); if ( !num_samples_per_channel ) @@ -342,13 +337,13 @@ void ivas_TD_RINGBUF_PushZeros( /*---------------------------------------------------------------------* * ivas_TD_RINGBUF_PopChannels() * - * Pops samples from the front of the TD ring buffer to an array of channel pointers. + * Pop samples from the front of the TD ring buffer to an array of channel pointers. *---------------------------------------------------------------------*/ void ivas_TD_RINGBUF_PopChannels( - TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */ - float *p_channels[], /* i : Array of pointers to each output channel */ - const int16_t num_samples_per_channel /* i : Number of samples per channel to pop */ + TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */ + float *p_channels[], /* i : Array of pointers to each output channel */ + const uint32_t num_samples_per_channel /* i : Number of samples per channel to pop */ ) #else /*---------------------------------------------------------------------* @@ -360,12 +355,12 @@ void ivas_TD_RINGBUF_PopChannels( void ivas_TD_RINGBUF_Pop( TD_RINGBUF_HANDLE h, /* i/o: Ring buffer handle */ float *data, /* i : Output data */ - const uint16_t num_samples_per_channel /* i : Number of samples per channel to retrieve */ + const uint32_t num_samples_per_channel /* i : Number of samples per channel to retrieve */ ) #endif { - int32_t s; - int16_t c; + uint32_t s; + uint16_t c; #ifdef FIX_1119_SPLIT_RENDERING_VOIP assert( h != NULL ); @@ -375,7 +370,7 @@ void ivas_TD_RINGBUF_Pop( assert( p_channels[c] != NULL ); } #endif - assert( ivas_td_ringbuf_total_size( h ) >= (int32_t) num_samples_per_channel * h->num_channels ); + assert( ivas_td_ringbuf_total_size( h ) >= num_samples_per_channel * h->num_channels ); for ( s = 0; s < num_samples_per_channel; ++s ) { @@ -417,9 +412,9 @@ void ivas_TD_RINGBUF_Pop( * Returns number of buffered samples per channel. *---------------------------------------------------------------------*/ -int16_t ivas_TD_RINGBUF_Size( +uint32_t ivas_TD_RINGBUF_Size( const TD_RINGBUF_HANDLE h /* i : Ring buffer handle */ ) { - return (int16_t) ( ivas_td_ringbuf_total_size( h ) / h->num_channels ); + return ivas_td_ringbuf_total_size( h ) / (uint32_t) h->num_channels; } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index d0be488f83b84f2b39ac0d7287f6e3c673db6473..4bb1024aae19eae7aa5e70822b9296b8052eef83 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -44,7 +44,9 @@ #include #include #include "wmc_auto.h" +#ifdef RENDERER_MD_SYNC_DELAY_TO_INTEGER #include +#endif /*-------------------------------------------------------------------* @@ -103,7 +105,7 @@ typedef struct float gain; /* Linear, not in dB */ rendering_context ctx; int32_t numNewSamplesPerChannel; /* Used to keep track how much new audio was fed before rendering current frame */ - int16_t delayNumSamples; + int32_t delayNumSamples; } input_base; typedef struct @@ -123,10 +125,12 @@ typedef struct float nonDiegeticPanGain; OMASA_ANA_HANDLE hOMasa; uint16_t total_num_objects; -#ifdef NONBE_1377_REND_DIRATT_CONF int16_t object_id; -#endif +#ifdef RENDERER_MD_SYNC_DELAY_TO_INTEGER int16_t ism_metadata_delay_ms; +#else + float ism_metadata_delay_ms; +#endif } input_ism; typedef struct @@ -186,10 +190,10 @@ typedef struct typedef struct hrtf_handles { - IVAS_DEC_HRTF_CREND_HANDLE hSetOfHRTF; + IVAS_DEC_HRTF_CREND_HANDLE hHrtfCrend; IVAS_DEC_HRTF_FASTCONV_HANDLE hHrtfFastConv; IVAS_DEC_HRTF_PARAMBIN_HANDLE hHrtfParambin; - IVAS_DEC_HRTF_HANDLE hHrtfTD; + IVAS_DEC_HRTF_TD_HANDLE hHrtfTD; IVAS_DEC_HRTF_STATISTICS_HANDLE hHrtfStatistics; } hrtf_handles; @@ -235,8 +239,11 @@ struct IVAS_REND *-------------------------------------------------------------------*/ static ivas_error initMasaExtRenderer( input_masa *inputMasa, const AUDIO_CONFIG outConfig, const RENDER_CONFIG_DATA *hRendCfg, hrtf_handles *hHrtfs ); + static void freeMasaExtRenderer( MASA_EXT_REND_HANDLE *hMasaExtRendOut ); + static void renderSbaToMultiBinauralCldfb( input_sba *sbaInput, float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const int16_t low_res_pre_rend_rot, const int16_t num_subframes ); + static ivas_error renderSbaToMultiBinaural( input_sba *sbaInput, const AUDIO_CONFIG outConfig, float out[][L_FRAME48k] ); /*-------------------------------------------------------------------* @@ -442,13 +449,12 @@ static void accumulate2dArrayToBuffer( writePtr = buffer->data; for ( chnlIdx = 0; chnlIdx < buffer->config.numChannels; ++chnlIdx ) - for ( chnlIdx = 0; chnlIdx < buffer->config.numChannels; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < buffer->config.numSamplesPerChannel; ++smplIdx ) { - for ( smplIdx = 0; smplIdx < buffer->config.numSamplesPerChannel; ++smplIdx ) - { - *writePtr++ += array[chnlIdx][smplIdx]; - } + *writePtr++ += array[chnlIdx][smplIdx]; } + } return; } @@ -506,7 +512,6 @@ static int32_t limitRendererOutput( } #endif - /*-------------------------------------------------------------------* * validateOutputAudioConfig() * @@ -617,7 +622,6 @@ static ivas_error validateOutputSampleRate( } else { - /* Otherwise rendering to binaural, support the same set as IVAS decoder */ switch ( sampleRate ) { @@ -1480,8 +1484,9 @@ static ivas_error alignInputDelay( { ivas_error error; input_ism *inputIsm; - int16_t maxGlobalDelaySamples, numSamplesToPop, numSamplesToPush; - uint16_t ringBufferSize, preDelay; + int16_t maxGlobalDelaySamples; + int32_t numSamplesToPush, numSamplesToPop; + uint32_t ringBufferSize, preDelay; #ifdef FIX_1119_SPLIT_RENDERING_VOIP int16_t i; const float *p_read_channels[MAX_INPUT_CHANNELS]; @@ -1519,7 +1524,11 @@ static ivas_error alignInputDelay( if ( getAudioConfigType( inputBase->inConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED ) { inputIsm = (input_ism *) inputBase; +#ifdef RENDERER_MD_SYNC_DELAY_TO_INTEGER inputIsm->ism_metadata_delay_ms = (int16_t) roundf( inputIsm->ism_metadata_delay_ms + maxGlobalDelayNs / 1e6f ); +#else + inputIsm->ism_metadata_delay_ms = maxGlobalDelayNs / 1e6f; +#endif } } } @@ -1529,7 +1538,7 @@ static ivas_error alignInputDelay( /* push in the new input data and pop to retrieve a complete input frame * if we are flushing the inputs, we don't push in any new data */ numSamplesToPush = flushInputs ? 0 : inputAudio.config.numSamplesPerChannel; - numSamplesToPop = flushInputs ? ivas_TD_RINGBUF_Size( inputBase->delayBuffer ) : inputAudio.config.numSamplesPerChannel; + numSamplesToPop = flushInputs ? ivas_TD_RINGBUF_Size( inputBase->delayBuffer ) : (uint32_t) inputAudio.config.numSamplesPerChannel; #ifdef FIX_1119_SPLIT_RENDERING_VOIP for ( i = 0; i < inputAudio.config.numChannels; ++i ) @@ -1623,6 +1632,7 @@ static ivas_error setRendInputActiveIsm( for ( i = 0; i < (int16_t) ( sizeof( inputIsm->splitTdRendWrappers ) / sizeof( *inputIsm->splitTdRendWrappers ) ); ++i ) { + inputIsm->splitTdRendWrappers[i] = defaultTdRendWrapper(); inputIsm->splitTdRendWrappers[i].hHrtfTD = &hrtfs->hHrtfTD; } @@ -1633,11 +1643,7 @@ static ivas_error setRendInputActiveIsm( if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { -#ifdef NONBE_1377_REND_DIRATT_CONF if ( ( error = ivas_td_binaural_open_ext( &inputIsm->tdRendWrapper, inConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate, inputIsm->object_id ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_td_binaural_open_ext( &inputIsm->tdRendWrapper, inConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -1645,11 +1651,7 @@ static ivas_error setRendInputActiveIsm( /* Open TD renderer wrappers */ for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) { -#ifdef NONBE_1377_REND_DIRATT_CONF if ( ( error = ivas_td_binaural_open_ext( &inputIsm->splitTdRendWrappers[i], inConfig, hRendCfg, NULL, *inputIsm->base.ctx.pOutSampleRate, inputIsm->object_id ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_td_binaural_open_ext( &inputIsm->splitTdRendWrappers[i], inConfig, hRendCfg, NULL, *inputIsm->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -1667,11 +1669,7 @@ static ivas_error setRendInputActiveIsm( } else { -#ifdef NONBE_1377_REND_DIRATT_CONF if ( ( error = ivas_td_binaural_open_ext( &inputIsm->tdRendWrapper, inConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate, inputIsm->object_id ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_td_binaural_open_ext( &inputIsm->tdRendWrapper, inConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -1685,7 +1683,7 @@ static ivas_error setRendInputActiveIsm( } else if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) { - if ( ( error = ivas_rend_openCrend( &inputIsm->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, hrtfs->hSetOfHRTF, hrtfs->hHrtfStatistics, *rendCtx.pOutSampleRate, 1, rendCtx.pSplitRendWrapper != NULL ? rendCtx.pSplitRendWrapper->multiBinPoseData.num_poses : 1 ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_openCrend( &inputIsm->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, hrtfs->hHrtfCrend, hrtfs->hHrtfStatistics, *rendCtx.pOutSampleRate, 1, rendCtx.pSplitRendWrapper != NULL ? rendCtx.pSplitRendWrapper->multiBinPoseData.num_poses : 1 ) ) != IVAS_ERR_OK ) { return error; } @@ -2428,11 +2426,7 @@ static ivas_error initMcBinauralRendering( if ( useTDRend && inputMc->tdRendWrapper.hBinRendererTd == NULL ) { -#ifdef NONBE_1377_REND_DIRATT_CONF if ( ( error = ivas_td_binaural_open_ext( &inputMc->tdRendWrapper, inConfig, hRendCfg, &inputMc->customLsInput, outSampleRate, 0 ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_td_binaural_open_ext( &inputMc->tdRendWrapper, inConfig, hRendCfg, &inputMc->customLsInput, outSampleRate ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -2442,11 +2436,7 @@ static ivas_error initMcBinauralRendering( /* Open TD renderer wrappers */ for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) { -#ifdef NONBE_1377_REND_DIRATT_CONF if ( ( error = ivas_td_binaural_open_ext( &inputMc->splitTdRendWrappers[i], inConfig, hRendCfg, &inputMc->customLsInput, outSampleRate, 0 ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_td_binaural_open_ext( &inputMc->splitTdRendWrappers[i], inConfig, hRendCfg, &inputMc->customLsInput, outSampleRate ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -2622,6 +2612,7 @@ static ivas_error setRendInputActiveMc( setZeroPanMatrix( inputMc->panGains ); inputMc->customLsInput = defaultCustomLs(); inputMc->tdRendWrapper = defaultTdRendWrapper(); + if ( hrtfs->hHrtfTD ) { inputMc->tdRendWrapper.binaural_latency_ns = (int32_t) ( hrtfs->hHrtfTD->latency_s * 1000000000.f ); @@ -2641,6 +2632,7 @@ static ivas_error setRendInputActiveMc( for ( i = 0; i < (int16_t) ( sizeof( inputMc->splitTdRendWrappers ) / sizeof( *inputMc->splitTdRendWrappers ) ); ++i ) { + inputMc->splitTdRendWrappers[i] = defaultTdRendWrapper(); if ( hrtfs->hHrtfTD ) { inputMc->splitTdRendWrappers[i].binaural_latency_ns = (int32_t) ( hrtfs->hHrtfTD->latency_s * 1000000000.f ); @@ -2650,8 +2642,7 @@ static ivas_error setRendInputActiveMc( if ( getAudioConfigType( outConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) { - if ( ( error = initMcBinauralRendering( inputMc, inConfig, outConfig, hRendCfg, hrtfs->hSetOfHRTF, hrtfs->hHrtfStatistics, FALSE ) ) != IVAS_ERR_OK ) - + if ( ( error = initMcBinauralRendering( inputMc, inConfig, outConfig, hRendCfg, hrtfs->hHrtfCrend, hrtfs->hHrtfStatistics, FALSE ) ) != IVAS_ERR_OK ) { return error; } @@ -2858,7 +2849,6 @@ static ivas_error updateSbaPanGains( } case IVAS_AUDIO_CONFIG_BINAURAL: case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: - { if ( hRendCfg->split_rend_config.rendererSelection == IVAS_BIN_RENDERER_TYPE_FASTCONV ) { if ( ( error = ivas_rend_openCldfbRend( &inputSba->cldfbRendWrapper, inConfig, outConfig, &rendCtx.pSplitRendWrapper->multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) @@ -2873,8 +2863,7 @@ static ivas_error updateSbaPanGains( return error; } } - } - break; + break; case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: if ( ( error = initSbaPanGainsForMcOut( inputSba, IVAS_AUDIO_CONFIG_7_1_4, NULL ) ) != IVAS_ERR_OK ) { @@ -2929,9 +2918,7 @@ static ivas_error setRendInputActiveSba( const AUDIO_CONFIG inConfig, const IVAS_REND_InputId id, RENDER_CONFIG_DATA *hRendCfg, - hrtf_handles *hrtfs - -) + hrtf_handles *hrtfs ) { ivas_error error; rendering_context rendCtx; @@ -2972,7 +2959,7 @@ static ivas_error setRendInputActiveSba( } } - if ( ( error = updateSbaPanGains( inputSba, outConfig, hRendCfg, hrtfs->hSetOfHRTF, hrtfs->hHrtfStatistics ) ) != IVAS_ERR_OK ) + if ( ( error = updateSbaPanGains( inputSba, outConfig, hRendCfg, hrtfs->hHrtfCrend, hrtfs->hHrtfStatistics ) ) != IVAS_ERR_OK ) { return error; } @@ -3054,7 +3041,6 @@ static ivas_error setRendInputActiveMasa( { return error; } - inputMasa->metadataHasBeenFed = false; } @@ -3088,15 +3074,16 @@ static void clearInputMasa( *------------------------------------------------------------------------*/ ivas_error IVAS_REND_Open( - IVAS_REND_HANDLE *phIvasRend, - const int32_t outputSampleRate, - const AUDIO_CONFIG outConfig, - const bool asHrtfBinary, - const int16_t nonDiegeticPan, - const float nonDiegeticPanGain, - const int16_t Opt_Headrotation, - const int16_t Opt_ExternalOrientation, - const int16_t num_subframes ) + IVAS_REND_HANDLE *phIvasRend, /* i/o: Pointer to renderer handle */ + const int32_t outputSampleRate, /* i : output sampling rate */ + const IVAS_AUDIO_CONFIG outConfig, /* i : output audio config */ + const bool asHrtfBinary, /* i : load hrtf binary file */ + const int16_t nonDiegeticPan, /* i : non-diegetic object flag */ + const float nonDiegeticPanGain, /* i : non-diegetic panning gain */ + const int16_t Opt_Headrotation, /* i : indicates whether head-rotation is used */ + const int16_t Opt_ExternalOrientation, /* i : indicates whether external orientations are used */ + const int16_t num_subframes /* i : number of subframes */ +) { int16_t i; int16_t j; @@ -3186,6 +3173,7 @@ ivas_error IVAS_REND_Open( } /* Initialize inputs */ + hIvasRend->splitRendWrapper = NULL; if ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { @@ -3260,10 +3248,11 @@ ivas_error IVAS_REND_Open( hIvasRend->inputsMasa[i].hMasaExtRend = NULL; } + hIvasRend->hHrtfs.hHrtfFastConv = NULL; hIvasRend->hHrtfs.hHrtfParambin = NULL; hIvasRend->hHrtfs.hHrtfTD = NULL; - hIvasRend->hHrtfs.hSetOfHRTF = NULL; + hIvasRend->hHrtfs.hHrtfCrend = NULL; hIvasRend->hHrtfs.hHrtfStatistics = NULL; if ( asHrtfBinary ) { @@ -3271,7 +3260,7 @@ ivas_error IVAS_REND_Open( { return error; } - if ( ( error = ivas_HRTF_CRend_binary_open( &( hIvasRend->hHrtfs.hSetOfHRTF ) ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_HRTF_CRend_binary_open( &( hIvasRend->hHrtfs.hHrtfCrend ) ) ) != IVAS_ERR_OK ) { return error; } @@ -3283,7 +3272,6 @@ ivas_error IVAS_REND_Open( { return error; } - if ( ( error = ivas_HRTF_statistics_binary_open( &( hIvasRend->hHrtfs.hHrtfStatistics ) ) ) != IVAS_ERR_OK ) { return error; @@ -3441,6 +3429,7 @@ ivas_error IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( /* Input inactive, skip. */ continue; } + if ( ( error = updateSbaPanGains( inputSba, hIvasRend->outputConfig, hIvasRend->hRendererConfig, NULL, NULL ) ) != IVAS_ERR_OK ) { return error; @@ -3627,7 +3616,7 @@ static ivas_error getConstInputById( return IVAS_ERR_OK; } -#ifdef CODE_IMPROVEMENTS + static void *getInputByIndex( void *inputsArray, const size_t index, @@ -3646,62 +3635,37 @@ static void *getInputByIndex( default: break; } + /* this should be unreachable */ assert( 0 ); /* include a final return to make the linter happy and avoid problems with wmc_tool (see #1355) */ return NULL; } -#endif + static ivas_error findFreeInputSlot( -#ifdef CODE_IMPROVEMENTS void *inputs, const IVAS_REND_AudioConfigType inputType, -#else - const void *inputs, - const int32_t inputStructSize, -#endif const int32_t maxInputs, int32_t *inputIndex ) { -#ifdef CODE_IMPROVEMENTS /* Using a void pointer and a separately provided type is a hack for this function to be reusable for arrays of any input type (input_ism, input_mc, input_sba, input_masa). Assumptions: - input_base is always the first member in the input struct - memory alignments of original input type and input_base are the same */ -#else - /* Using a void pointer and a separately provided size is a hack for this function - to be reusable for arrays of any input type (input_ism, input_mc, input_sba, input_masa). - Assumptions: - - input_base is always the first member in the input struct - - provided size is correct - */ -#endif - int32_t i; bool canAddInput; -#ifndef CODE_IMPROVEMENTS - const uint8_t *pByte; -#endif const input_base *pInputBase; canAddInput = false; /* Find first unused input in array */ -#ifdef CODE_IMPROVEMENTS for ( i = 0; i < maxInputs; ++i ) -#else - for ( i = 0, pByte = inputs; i < maxInputs; ++i, pByte += inputStructSize ) -#endif { -#ifdef CODE_IMPROVEMENTS pInputBase = (const input_base *) getInputByIndex( inputs, i, inputType ); -#else - pInputBase = (const input_base *) pByte; -#endif if ( pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID ) { @@ -3720,6 +3684,12 @@ static ivas_error findFreeInputSlot( } +/*------------------------------------------------------------------------- + * Function getCldfbRendFlag() + * + * + *------------------------------------------------------------------------*/ + static int16_t getCldfbRendFlag( IVAS_REND_HANDLE hIvasRend, /* i : Renderer handle */ const IVAS_REND_AudioConfigType new_configType ) @@ -3744,7 +3714,6 @@ static int16_t getCldfbRendFlag( { numSbaInputs += ( hIvasRend->inputsSba[i].base.inConfig == IVAS_AUDIO_CONFIG_INVALID && new_configType != IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) ? 0 : 1; } - if ( ( numMasaInputs > 0 ) || ( numSbaInputs > 0 && hIvasRend->hRendererConfig->split_rend_config.rendererSelection == IVAS_BIN_RENDERER_TYPE_FASTCONV ) ) { isCldfbRend = 1; @@ -3846,15 +3815,12 @@ ivas_error IVAS_REND_AddInput( ivas_error error; int32_t maxNumInputsOfType; void *inputsArray; -#ifdef CODE_IMPROVEMENTS IVAS_REND_AudioConfigType inputType; -#else - int32_t inputStructSize; -#endif - ivas_error ( *activateInput )( void *, AUDIO_CONFIG, IVAS_REND_InputId, RENDER_CONFIG_DATA *, hrtf_handles *hrtfs ); + ivas_error ( *activateInput )( void *, AUDIO_CONFIG, IVAS_REND_InputId, RENDER_CONFIG_DATA *, hrtf_handles * ); void ( *setInputDelay )( void *, bool ); int32_t inputIndex; bool splitPreRendCldfb; + splitPreRendCldfb = false; /* Validate function arguments */ @@ -3879,50 +3845,35 @@ ivas_error IVAS_REND_AddInput( { return error; } + /*assumes that input has been added which means codec has been set to either lcld or lc3plus (even if render config specified default)*/ splitPreRendCldfb = ( hIvasRend->hRendererConfig->split_rend_config.codec == ISAR_SPLIT_REND_CODEC_LCLD ); } -#ifdef CODE_IMPROVEMENTS inputType = getAudioConfigType( inConfig ); switch ( inputType ) -#else - switch ( getAudioConfigType( inConfig ) ) -#endif { case IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED: maxNumInputsOfType = RENDERER_MAX_ISM_INPUTS; inputsArray = hIvasRend->inputsIsm; -#ifndef CODE_IMPROVEMENTS - inputStructSize = sizeof( *hIvasRend->inputsIsm ); -#endif activateInput = setRendInputActiveIsm; setInputDelay = setRendInputDelayIsm; break; case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: maxNumInputsOfType = RENDERER_MAX_MC_INPUTS; inputsArray = hIvasRend->inputsMc; -#ifndef CODE_IMPROVEMENTS - inputStructSize = sizeof( *hIvasRend->inputsMc ); -#endif activateInput = setRendInputActiveMc; setInputDelay = setRendInputDelayMc; break; case IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS: maxNumInputsOfType = RENDERER_MAX_SBA_INPUTS; inputsArray = hIvasRend->inputsSba; -#ifndef CODE_IMPROVEMENTS - inputStructSize = sizeof( *hIvasRend->inputsSba ); -#endif activateInput = setRendInputActiveSba; setInputDelay = setRendInputDelaySba; break; case IVAS_REND_AUDIO_CONFIG_TYPE_MASA: maxNumInputsOfType = RENDERER_MAX_MASA_INPUTS; inputsArray = hIvasRend->inputsMasa; -#ifndef CODE_IMPROVEMENTS - inputStructSize = sizeof( *hIvasRend->inputsMasa ); -#endif activateInput = setRendInputActiveMasa; setInputDelay = setRendInputDelayMasa; break; @@ -3930,30 +3881,19 @@ ivas_error IVAS_REND_AddInput( return IVAS_ERR_INVALID_INPUT_FORMAT; } - /* Find first free input in array corresponding to input type */ -#ifdef CODE_IMPROVEMENTS + /* Find first free input in array corresponding to input type */ if ( ( error = findFreeInputSlot( inputsArray, inputType, maxNumInputsOfType, &inputIndex ) ) != IVAS_ERR_OK ) -#else - if ( ( error = findFreeInputSlot( inputsArray, inputStructSize, maxNumInputsOfType, &inputIndex ) ) != IVAS_ERR_OK ) -#endif { return error; } *inputId = makeInputId( inConfig, inputIndex ); -#ifdef CODE_IMPROVEMENTS if ( ( error = activateInput( getInputByIndex( inputsArray, inputIndex, inputType ), inConfig, *inputId, hIvasRend->hRendererConfig, &hIvasRend->hHrtfs ) ) != IVAS_ERR_OK ) -#else - if ( ( error = activateInput( (uint8_t *) inputsArray + inputStructSize * inputIndex, inConfig, *inputId, hIvasRend->hRendererConfig, &hIvasRend->hHrtfs ) ) != IVAS_ERR_OK ) -#endif { return error; } -#ifdef CODE_IMPROVEMENTS + setInputDelay( getInputByIndex( inputsArray, inputIndex, inputType ), splitPreRendCldfb ); -#else - setInputDelay( (uint8_t *) inputsArray + inputStructSize * inputIndex, splitPreRendCldfb ); -#endif /* set global maximum delay after adding an input */ setMaxGlobalDelayNs( hIvasRend ); @@ -4018,8 +3958,7 @@ ivas_error IVAS_REND_ConfigureCustomInputLoudspeakerLayout( inputMc->base.inConfig, hIvasRend->outputConfig, hIvasRend->hRendererConfig, - hIvasRend->hHrtfs.hSetOfHRTF, - + hIvasRend->hHrtfs.hHrtfCrend, hIvasRend->hHrtfs.hHrtfStatistics, FALSE ) ) != IVAS_ERR_OK ) { @@ -4035,7 +3974,7 @@ ivas_error IVAS_REND_ConfigureCustomInputLoudspeakerLayout( return IVAS_ERR_OK; } -#ifdef NONBE_1377_REND_DIRATT_CONF + /*-------------------------------------------------------------------* * IVAS_REND_SetObjectIDs() * @@ -4061,7 +4000,6 @@ ivas_error IVAS_REND_SetObjectIDs( return IVAS_ERR_OK; } -#endif /*-------------------------------------------------------------------* @@ -4328,6 +4266,7 @@ ivas_error IVAS_REND_GetDelay( *nSamples = 0; *timeScale = hIvasRend->sampleRateOut; + max_latency_ns = getMaxGlobalDelayNs( hIvasRend ); *nSamples = latencyNsToSamples( hIvasRend->sampleRateOut, max_latency_ns ); @@ -4335,7 +4274,6 @@ ivas_error IVAS_REND_GetDelay( return IVAS_ERR_OK; } - /*-------------------------------------------------------------------* * IVAS_REND_FeedInputAudio() * @@ -4613,7 +4551,7 @@ ivas_error IVAS_REND_GetRenderConfig( mvr2r( hRCin->roomAcoustics.pAcoustic_rt60, hRCout->roomAcoustics.pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); mvr2r( hRCin->roomAcoustics.pAcoustic_dsr, hRCout->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); - hRCout->split_rend_config.splitRendBitRate = SPLIT_REND_768k; + hRCout->split_rend_config.splitRendBitRate = ISAR_MAX_SPLIT_REND_BITRATE; hRCout->split_rend_config.dof = 3; hRCout->split_rend_config.hq_mode = 0; hRCout->split_rend_config.codec_delay_ms = 0; @@ -4627,9 +4565,7 @@ ivas_error IVAS_REND_GetRenderConfig( hRCout->roomAcoustics.use_er = hRCin->roomAcoustics.use_er; hRCout->roomAcoustics.lowComplexity = hRCin->roomAcoustics.lowComplexity; -#ifdef FIX_1053_REVERB_RECONFIGURATION mvr2r( hRCin->distAtt, hRCout->distAtt, 3 ); -#endif return IVAS_ERR_OK; } @@ -4662,7 +4598,6 @@ ivas_error IVAS_REND_FeedRenderConfig( #ifdef DEBUGGING hRenderConfig->renderer_type_override = renderConfig.renderer_type_override; #endif - hRenderConfig->roomAcoustics.nBands = renderConfig.roomAcoustics.nBands; hRenderConfig->roomAcoustics.acousticPreDelay = renderConfig.roomAcoustics.acousticPreDelay; hRenderConfig->roomAcoustics.inputPreDelay = renderConfig.roomAcoustics.inputPreDelay; @@ -4670,9 +4605,7 @@ ivas_error IVAS_REND_FeedRenderConfig( mvr2r( renderConfig.roomAcoustics.pAcoustic_rt60, hRenderConfig->roomAcoustics.pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); mvr2r( renderConfig.roomAcoustics.pAcoustic_dsr, hRenderConfig->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); mvr2r( renderConfig.directivity, hRenderConfig->directivity, 3 * MAX_NUM_OBJECTS ); -#ifdef FIX_1053_REVERB_RECONFIGURATION mvr2r( renderConfig.distAtt, hRenderConfig->distAtt, 3 ); -#endif hRenderConfig->roomAcoustics.use_er = 0; if ( renderConfig.roomAcoustics.use_er == 1 ) @@ -4725,7 +4658,7 @@ ivas_error IVAS_REND_FeedRenderConfig( { ivas_binaural_reverb_close( &pMasaInput->hMasaExtRend->hDiracDecBin[0]->hReverb ); - if ( ( error = ivas_binaural_reverb_init( &pMasaInput->hMasaExtRend->hDiracDecBin[0]->hReverb, // Todo 1892 + if ( ( error = ivas_binaural_reverb_init( &pMasaInput->hMasaExtRend->hDiracDecBin[0]->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, pMasaInput->hMasaExtRend->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, @@ -4738,11 +4671,12 @@ ivas_error IVAS_REND_FeedRenderConfig( return error; } } + if ( pMasaInput->hMasaExtRend->hReverb != NULL ) { ivas_binaural_reverb_close( &pMasaInput->hMasaExtRend->hReverb ); - if ( ( error = ivas_binaural_reverb_init( &pMasaInput->hMasaExtRend->hReverb, // Todo 1892 + if ( ( error = ivas_binaural_reverb_init( &pMasaInput->hMasaExtRend->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, pMasaInput->hMasaExtRend->hSpatParamRendCom->num_freq_bands, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, @@ -4775,7 +4709,7 @@ ivas_error IVAS_REND_FeedRenderConfig( } } - if ( pMcInput->crendWrapper != NULL && pMcInput->crendWrapper->hCrend[0] != NULL && pMcInput->crendWrapper->hCrend[0]->hReverb != NULL ) + if ( pMcInput->crendWrapper != NULL && pMcInput->crendWrapper->hCrend[0] && pMcInput->crendWrapper->hCrend[0]->hReverb != NULL ) { if ( ( error = ivas_reverb_open( &pMcInput->crendWrapper->hCrend[0]->hReverb, hIvasRend->hHrtfs.hHrtfStatistics, hRenderConfig, *pMcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) { @@ -4884,7 +4818,7 @@ ivas_error IVAS_REND_SetHeadRotation( hIvasRend->inputsMc[i].base.inConfig, hIvasRend->outputConfig, hIvasRend->hRendererConfig, - hIvasRend->hHrtfs.hSetOfHRTF, + hIvasRend->hHrtfs.hHrtfCrend, hIvasRend->hHrtfs.hHrtfStatistics, TRUE ) ) != IVAS_ERR_OK ) { @@ -4948,12 +4882,10 @@ ivas_error IVAS_REND_DisableHeadRotation( hIvasRend->inputsMc[i].base.inConfig, hIvasRend->outputConfig, hIvasRend->hRendererConfig, - hIvasRend->hHrtfs.hSetOfHRTF, - + hIvasRend->hHrtfs.hHrtfCrend, hIvasRend->hHrtfs.hHrtfStatistics, TRUE ) ) != IVAS_ERR_OK ) { - return error; } } @@ -4971,8 +4903,9 @@ ivas_error IVAS_REND_DisableHeadRotation( *-------------------------------------------------------------------*/ ivas_error IVAS_REND_SetSplitRendBFI( - IVAS_REND_HANDLE hIvasRend, - const int16_t bfi ) + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const int16_t bfi /* i : bad frame indicator */ +) { hIvasRend->splitRendBFI = bfi; @@ -5562,9 +5495,13 @@ static ivas_error renderIsmToBinaural( int16_t ism_md_subframe_update_ext; push_wmops( "renderIsmToBinaural" ); - /* Metadata Delay to sync with audio delay converted from ms to 5ms (1000/50/4) subframe index */ +#ifdef RENDERER_MD_SYNC_DELAY_TO_INTEGER ism_md_subframe_update_ext = (int16_t) roundf( ismInput->ism_metadata_delay_ms / (float) BINAURAL_RENDERING_FRAME_SIZE_MS ); +#else + ism_md_subframe_update_ext = (int16_t) roundf( ismInput->ism_metadata_delay_ms / ( 1000.f / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ) ); +#endif + copyBufferTo2dArray( ismInput->base.inputBuffer, tmpTDRendBuffer ); if ( ( error = ivas_td_binaural_renderer_ext( &ismInput->tdRendWrapper, ismInput->base.inConfig, NULL, ismInput->base.ctx.pCombinedOrientationData, &ismInput->currentPos, ismInput->hReverb, ism_md_subframe_update_ext, @@ -5580,6 +5517,7 @@ static ivas_error renderIsmToBinaural( return IVAS_ERR_OK; } + static int16_t getNumSubframesInBuffer( const IVAS_REND_AudioBuffer *buffer, const int32_t sampleRate ) @@ -5595,6 +5533,7 @@ static int16_t getNumSubframesInBuffer( return (int16_t) ( buffer->config.numSamplesPerChannel / ( sampleRate / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES * cldfb2tdSampleFact ) ); } + static ivas_error renderIsmToBinauralRoom( input_ism *ismInput, IVAS_REND_AudioBuffer outAudio ) @@ -5739,7 +5678,6 @@ static ivas_error renderIsmToBinauralRoom( mvr2r( currentPanGains, ismInput->prev_pan_gains, MAX_OUTPUT_CHANNELS ); } - /* render 7_1_4 with BRIRs */ if ( ( error = ivas_rend_crendProcessSubframe( ismInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, NULL, NULL, NULL, NULL, NULL, p_tmpRendBuffer, p_tmpRendBuffer, ismInput->base.inputBuffer.config.numSamplesPerChannel, *ismInput->base.ctx.pOutSampleRate, 0 ) ) != IVAS_ERR_OK ) @@ -5767,7 +5705,12 @@ static ivas_error renderIsmToBinauralReverb( push_wmops( "renderIsmToBinauralRoom" ); /* Metadata Delay to sync with audio delay converted from ms to 5ms (1000/50/4) subframe index */ +#ifdef RENDERER_MD_SYNC_DELAY_TO_INTEGER ism_md_subframe_update_ext = (int16_t) roundf( ismInput->ism_metadata_delay_ms / (float) BINAURAL_RENDERING_FRAME_SIZE_MS ); +#else + ism_md_subframe_update_ext = (int16_t) roundf( ismInput->ism_metadata_delay_ms / ( 1000.f / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ) ); +#endif + copyBufferTo2dArray( ismInput->base.inputBuffer, tmpRendBuffer ); if ( ( error = ivas_td_binaural_renderer_ext( &ismInput->tdRendWrapper, ismInput->base.inConfig, NULL, ismInput->base.ctx.pCombinedOrientationData, &ismInput->currentPos, ismInput->hReverb, @@ -5946,7 +5889,11 @@ static ivas_error renderIsmToSplitBinaural( pMultiBinPoseData = &pSplitRendWrapper->multiBinPoseData; /* Metadata Delay to sync with audio delay converted from ms to 5ms (1000/50/4) subframe index */ +#ifdef RENDERER_MD_SYNC_DELAY_TO_INTEGER ism_md_subframe_update_ext = (int16_t) roundf( ismInput->ism_metadata_delay_ms / (float) BINAURAL_RENDERING_FRAME_SIZE_MS ); +#else + ism_md_subframe_update_ext = (int16_t) roundf( ismInput->ism_metadata_delay_ms / ( 1000.f / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ) ); +#endif pCombinedOrientationData = *ismInput->base.ctx.pCombinedOrientationData; @@ -6325,7 +6272,6 @@ static ivas_error renderMcToBinaural( accumulate2dArrayToBuffer( tmpRendBuffer, &outAudio ); if ( ( error = renderLfeToBinaural( mcInput, outConfig, outAudio ) ) != IVAS_ERR_OK ) - { return error; } @@ -6391,8 +6337,7 @@ static ivas_error renderMcToBinauralRoom( tmpRotBuffer.data = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); set_zero( tmpRotBuffer.data, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); - if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, - mcInput->rot_gains_prev[0], mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) + if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, mcInput->rot_gains_prev[0], mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) { return error; } @@ -6471,8 +6416,7 @@ static ivas_error renderMcCustomLsToBinauralRoom( tmpRotBuffer.data = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); set_zero( tmpRotBuffer.data, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); - if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, - mcInput->rot_gains_prev[0], mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) + if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, mcInput->rot_gains_prev[0], mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) { return error; } @@ -6688,7 +6632,6 @@ static ivas_error renderMcToSplitBinaural( * 4. LFE mixing * 5. tmpSplitBinBuffer accumulated to outBuffer */ - /* copy input for in-place rotation */ set_zero( tmpRotBuffer.data, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); @@ -6872,6 +6815,7 @@ static void renderSbaToSba( return; } + static ivas_error renderSbaToMultiBinaural( input_sba *sbaInput, const AUDIO_CONFIG outConfig, @@ -7000,23 +6944,19 @@ static ivas_error renderSbaToSplitBinaural( ivas_error error; float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - int16_t low_res_pre_rend_rot; - - low_res_pre_rend_rot = 1; push_wmops( "renderSbaToSplitBinaural" ); - error = IVAS_ERR_OK; if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == IVAS_BIN_RENDERER_TYPE_FASTCONV ) { - renderSbaToMultiBinauralCldfb( sbaInput, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, low_res_pre_rend_rot, + renderSbaToMultiBinauralCldfb( sbaInput, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, 1, getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) ); accumulateCLDFBArrayToBuffer( Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, &outAudio ); } else { - if ( ( renderSbaToMultiBinaural( sbaInput, outConfig, tmpCrendBuffer ) ) != IVAS_ERR_OK ) + if ( ( error = renderSbaToMultiBinaural( sbaInput, outConfig, tmpCrendBuffer ) ) != IVAS_ERR_OK ) { return error; } @@ -7025,9 +6965,10 @@ static ivas_error renderSbaToSplitBinaural( } pop_wmops(); - return error; + return IVAS_ERR_OK; } + static ivas_error renderSbaToBinaural( input_sba *sbaInput, const AUDIO_CONFIG outConfig, @@ -7161,9 +7102,7 @@ static ivas_error renderSbaToBinauralRoom( mvr2r( sbaInput->base.inputBuffer.data, tmpRotBuffer.data, tmpRotBuffer.config.numChannels * tmpRotBuffer.config.numSamplesPerChannel ); if ( ( error = rotateFrameSba( sbaInput->base.inputBuffer, sbaInput->base.inConfig, sbaInput->base.ctx.pHeadRotData, - sbaInput->base.ctx.pCombinedOrientationData, - sbaInput->rot_gains_prev[0], - tmpRotBuffer ) ) != IVAS_ERR_OK ) + sbaInput->base.ctx.pCombinedOrientationData, sbaInput->rot_gains_prev[0], tmpRotBuffer ) ) != IVAS_ERR_OK ) { return error; } @@ -7397,19 +7336,11 @@ static void renderMasaToMasa( } /* Compute channel energy for metadata processing */ -#ifdef NONBE_1344_REND_MASA_LOW_FS for ( band_m_idx = 0; band_m_idx < masaInput->hMasaPrerend->nbands; band_m_idx++ ) -#else - for ( band_m_idx = 0; band_m_idx < MASA_FREQUENCY_BANDS; band_m_idx++ ) -#endif { -#ifdef NONBE_1344_REND_MASA_LOW_FS brange[0] = masaInput->hMasaPrerend->band_grouping[band_m_idx]; brange[1] = masaInput->hMasaPrerend->band_grouping[band_m_idx + 1]; -#else - brange[0] = MASA_band_grouping_24[band_m_idx]; - brange[1] = MASA_band_grouping_24[band_m_idx + 1]; -#endif + for ( j = brange[0]; j < brange[1]; j++ ) { for ( i = 0; i < numAnalysisChannels; i++ ) @@ -7778,7 +7709,11 @@ ivas_error IVAS_REND_SetTotalNumberOfObjects( ivas_error IVAS_REND_SetIsmMetadataDelay( IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ +#ifdef RENDERER_MD_SYNC_DELAY_TO_INTEGER const int16_t sync_md_delay /* i : ISM Metadata Delay in ms to sync with audio delay */ +#else + const float sync_md_delay /* i : ISM Metadata Delay in ms to sync with audio delay */ +#endif ) { int16_t i; @@ -7908,7 +7843,6 @@ static ivas_error getSamplesInternal( return IVAS_ERR_OK; } - /*-------------------------------------------------------------------* * IVAS_REND_GetSamples() * @@ -8092,23 +8026,31 @@ ivas_error IVAS_REND_GetSplitBinauralBitstream( return IVAS_ERR_OK; } + +/*-------------------------------------------------------------------* + * IVAS_REND_GetSplitRendBitstreamHeader() + * + * + *-------------------------------------------------------------------*/ + ivas_error IVAS_REND_GetSplitRendBitstreamHeader( - IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ - ISAR_SPLIT_REND_CODEC *pCodec, /* o: pointer to codec setting */ - ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o: pointer to pose correction mode */ - int16_t *pCodec_frame_size_ms /* o: pointer to codec frame size setting */ - , - int16_t *pIsar_frame_size_ms /* o: pointer to isar frame size setting */ + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + ISAR_SPLIT_REND_CODEC *pCodec, /* o : pointer to codec setting */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o : pointer to pose correction mode */ + int16_t *pCodec_frame_size_ms, /* o : pointer to codec frame size setting */ + int16_t *pIsar_frame_size_ms /* o : pointer to ISAR frame size setting */ ) { if ( hIvasRend == NULL || hIvasRend->hRendererConfig == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + *pCodec = hIvasRend->hRendererConfig->split_rend_config.codec; *pCodec_frame_size_ms = hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms; *pIsar_frame_size_ms = hIvasRend->hRendererConfig->split_rend_config.isar_frame_size_ms; *poseCorrection = hIvasRend->hRendererConfig->split_rend_config.poseCorrectionMode; + return IVAS_ERR_OK; } @@ -8150,6 +8092,7 @@ void IVAS_REND_Close( for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) { clearInputSba( &hIvasRend->inputsSba[i] ); + hIvasRend->hHrtfs.hHrtfFastConv = NULL; } for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) { @@ -8179,7 +8122,7 @@ void IVAS_REND_Close( /* Parametric binauralizer HRTF filters */ ivas_HRTF_binary_close( &( hIvasRend->hHrtfs.hHrtfTD ) ); - ivas_HRTF_CRend_binary_close( &( hIvasRend->hHrtfs.hSetOfHRTF ) ); + ivas_HRTF_CRend_binary_close( &( hIvasRend->hHrtfs.hHrtfCrend ) ); ivas_HRTF_fastconv_binary_close( &( hIvasRend->hHrtfs.hHrtfFastConv ) ); ivas_HRTF_parambin_binary_close( &( hIvasRend->hHrtfs.hHrtfParambin ) ); ivas_HRTF_statistics_close( &( hIvasRend->hHrtfs.hHrtfStatistics ) ); @@ -8234,6 +8177,7 @@ ivas_error IVAS_REND_openCldfb( return IVAS_ERR_OK; } + /*-------------------------------------------------------------------* * IVAS_REND_closeCldfb() * @@ -8315,8 +8259,7 @@ void IVAS_REND_cldfbSynthesis_wrapper( * *-------------------------------------------------------------------*/ -int32_t -IVAS_REND_GetNoCLipping( +int32_t IVAS_REND_GetNoCLipping( IVAS_REND_CONST_HANDLE hIvasRend ) { return hIvasRend->numClipping; @@ -8334,15 +8277,16 @@ int32_t IVAS_REND_GetCntFramesLimited( } #endif + /*---------------------------------------------------------------------* - * IVAS_REND_GetHrtfHandle( ) + * IVAS_REND_GetHrtfTdHandle( ) * * *---------------------------------------------------------------------*/ -ivas_error IVAS_REND_GetHrtfHandle( - IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ - IVAS_DEC_HRTF_HANDLE **hHrtfTD /* o : HRTF handle */ +ivas_error IVAS_REND_GetHrtfTdHandle( + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + IVAS_DEC_HRTF_TD_HANDLE **hHrtfTD /* o : TD rend. HRTF handle */ ) { if ( hIvasRend == NULL || hIvasRend->hHrtfs.hHrtfTD == NULL ) @@ -8364,15 +8308,15 @@ ivas_error IVAS_REND_GetHrtfHandle( ivas_error IVAS_REND_GetHrtfCRendHandle( IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ - IVAS_DEC_HRTF_CREND_HANDLE **hSetOfHRTF /* o : Set of HRTF handle */ + IVAS_DEC_HRTF_CREND_HANDLE **hHrtfCrend /* o : Crend HRTF handle */ ) { - if ( hIvasRend == NULL || hIvasRend->hHrtfs.hSetOfHRTF == NULL ) + if ( hIvasRend == NULL || hIvasRend->hHrtfs.hHrtfCrend == NULL ) { return IVAS_ERR_WRONG_PARAMS; } - *hSetOfHRTF = &hIvasRend->hHrtfs.hSetOfHRTF; + *hHrtfCrend = &hIvasRend->hHrtfs.hHrtfCrend; return IVAS_ERR_OK; } @@ -8421,7 +8365,6 @@ ivas_error IVAS_REND_GetHrtfParamBinHandle( return IVAS_ERR_OK; } - /*---------------------------------------------------------------------* * IVAS_REND_GetHrtfStatisticsHandle( ) * @@ -8951,6 +8894,7 @@ static ivas_error ivas_masa_ext_rend_parambin_init( return error; } } + /* External renderer uses constant regularization factor */ hDiracDecBin->reqularizationFactor = 0.4f; @@ -9088,6 +9032,7 @@ static ivas_error initMasaExtRenderer( return error; } } + if ( ( error = ivas_masa_ext_rend_parambin_init( inputMasa, hRendCfg, hrtfs->hHrtfStatistics ) ) != IVAS_ERR_OK ) { return error; diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 4b6e7340fd99c3cef14ae580255151d15c443811..4d84f194f9ba18c7127b5e385a52e50de64fe3b7 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -35,7 +35,7 @@ #include "common_api_types.h" #include -#include "ivas_stat_rend.h" + /*---------------------------------------------------------------------* * Renderer constants @@ -70,6 +70,7 @@ typedef struct int16_t isar_frame_size_ms; int16_t lc3plus_highres; } IVAS_REND_BitstreamBufferConfig; + typedef struct { IVAS_REND_BitstreamBufferConfig config; @@ -151,11 +152,9 @@ ivas_error IVAS_REND_ConfigureCustomInputLoudspeakerLayout( const IVAS_CUSTOM_LS_DATA layout /* i : custom loudspeaker layout for input */ ); -#ifdef NONBE_1377_REND_DIRATT_CONF ivas_error IVAS_REND_SetObjectIDs( IVAS_REND_HANDLE hIvasRend /* i/o: Renderer handle */ ); -#endif ivas_error IVAS_REND_SetInputGain( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ @@ -195,15 +194,15 @@ ivas_error IVAS_REND_GetDelay( ); /*! r: error code */ -ivas_error IVAS_REND_GetHrtfHandle( +ivas_error IVAS_REND_GetHrtfTdHandle( IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS render handle */ - IVAS_DEC_HRTF_HANDLE **hHrtfTD /* o : HRTF handle */ + IVAS_DEC_HRTF_TD_HANDLE **hHrtfTD /* o : TD rend. HRTF handle */ ); /*! r: error code */ ivas_error IVAS_REND_GetHrtfCRendHandle( IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ - IVAS_DEC_HRTF_CREND_HANDLE **hSetOfHRTF /* o : Set of HRTF handle */ + IVAS_DEC_HRTF_CREND_HANDLE **hHrtfCrend /* o : Crend HRTF handle */ ); ivas_error IVAS_REND_GetHrtfFastConvHandle( @@ -217,8 +216,8 @@ ivas_error IVAS_REND_GetHrtfParamBinHandle( ); ivas_error IVAS_REND_GetHrtfStatisticsHandle( - IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ - IVAS_DEC_HRTF_STATISTICS_HANDLE **hHrtfStatistics /* o : HRTF statistics handle */ + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + IVAS_DEC_HRTF_STATISTICS_HANDLE **hHrtfStatistics /* o : HRTF statistics handle */ ); /* Functions to be called during rendering */ @@ -258,7 +257,6 @@ ivas_error IVAS_REND_GetRenderConfig( const IVAS_RENDER_CONFIG_HANDLE hRCout /* o : Render configuration handle */ ); - ivas_error IVAS_REND_FeedRenderConfig( IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ const IVAS_RENDER_CONFIG_DATA renderConfig /* i : Render configuration struct */ @@ -267,7 +265,7 @@ ivas_error IVAS_REND_FeedRenderConfig( ivas_error IVAS_REND_FeedSplitBinauralBitstream( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ const IVAS_REND_InputId inputId, /* i : ID of the input */ - IVAS_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */ + IVAS_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */ ); ivas_error IVAS_REND_GetSplitBinauralSamples( @@ -285,9 +283,9 @@ ivas_error IVAS_REND_GetSplitBinauralBitstream( ivas_error IVAS_REND_GetSplitRendBitstreamHeader( IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ ISAR_SPLIT_REND_CODEC *pCodec, /* o : pointer to codec setting */ - ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o: pointer to pose correction mode */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o : pointer to pose correction mode */ int16_t *pCodec_frame_size_ms, /* o : pointer to codec frame size setting */ - int16_t *pIsar_frame_size_ms /* o : pointer to isar frame size setting */ + int16_t *pIsar_frame_size_ms /* o : pointer to ISAR frame size setting */ ); ivas_error IVAS_REND_SetHeadRotation( @@ -330,8 +328,9 @@ ivas_error IVAS_REND_SetReferenceVector( ); ivas_error IVAS_REND_SetSplitRendBFI( - IVAS_REND_HANDLE hIvasRend, - const int16_t bfi); + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const int16_t bfi /* i : bad frame indicator */ +); ivas_error IVAS_REND_SetExternalOrientation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ @@ -353,16 +352,16 @@ ivas_error IVAS_REND_GetCombinedOrientation( ); ivas_error IVAS_REND_GetMasaMetadata( - IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ IVAS_MASA_DECODER_EXT_OUT_META_HANDLE *hMasaExtOutMeta, /* o : pointer to handle, which will be set to point to analyzed MASA metadata */ - const IVAS_REND_AudioConfigType inputType /* i : Input type */ + const IVAS_REND_AudioConfigType inputType /* i : Input type */ ); ivas_error IVAS_REND_MergeMasaMetadata( - IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ IVAS_MASA_DECODER_EXT_OUT_META_HANDLE *hMasaExtOutMeta, /* o : pointer to handle, which will be set to point to merged metadata */ - const IVAS_REND_AudioConfigType inputType1, /* i : Input type 1 */ - const IVAS_REND_AudioConfigType inputType2 /* i : Input type 2 */ + const IVAS_REND_AudioConfigType inputType1, /* i : Input type 1 */ + const IVAS_REND_AudioConfigType inputType2 /* i : Input type 2 */ ); ivas_error IVAS_REND_SetTotalNumberOfObjects( @@ -372,7 +371,11 @@ ivas_error IVAS_REND_SetTotalNumberOfObjects( ivas_error IVAS_REND_SetIsmMetadataDelay( IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ +#ifdef RENDERER_MD_SYNC_DELAY_TO_INTEGER const int16_t sync_md_delay /* i : Metadata Delay in ms to sync with audio delay */ +#else + const float sync_md_delay /* i : Metadata Delay in ms to sync with audio delay */ +#endif ); ivas_error IVAS_REND_GetNumAllObjects( @@ -381,8 +384,8 @@ ivas_error IVAS_REND_GetNumAllObjects( ); ivas_error IVAS_REND_GetSamples( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ ); /* Functions to be called after rendering */ @@ -433,6 +436,7 @@ int32_t IVAS_REND_GetCntFramesLimited( ); #endif + /* Disclaimer and info printing */ void IVAS_REND_PrintInputConfig( @@ -446,7 +450,6 @@ ivas_error IVAS_REND_PrintConfig( void IVAS_REND_PrintDisclaimer( void ); - /* clang-format on */ #endif diff --git a/lib_util/aeid_file_reader.h b/lib_util/aeid_file_reader.h index f72465b1fb7c2cc01f18f5a7dd566f843fcd8628..69a8be67ca9e5e741a7d5406dce6010e17b20695 100644 --- a/lib_util/aeid_file_reader.h +++ b/lib_util/aeid_file_reader.h @@ -35,7 +35,6 @@ #include "common_api_types.h" -#ifdef FIX_1053_REVERB_RECONFIGURATION struct aeidFileReader; typedef struct aeidFileReader aeidFileReader; @@ -84,6 +83,5 @@ const char *aeidFileReader_getFilePath( aeidFileReader *aeidReader /* i : aeidFileReader handle */ ); -#endif #endif /* IVAS_AEID_FILE_READER_H */ diff --git a/lib_util/audio_file_reader.c b/lib_util/audio_file_reader.c index 0b6e44660de1d29b008868b1d847522f052bc56a..92bfe8978993ec074d8c9da86549a4d567b52073 100644 --- a/lib_util/audio_file_reader.c +++ b/lib_util/audio_file_reader.c @@ -33,7 +33,6 @@ #include "audio_file_reader.h" #include "tinywavein_c.h" - struct AudioFileReader { FILE *rawFile; diff --git a/lib_util/bitstream_reader.c b/lib_util/bitstream_reader.c index 00fb6d9f342ce12f916786d13dfb235050ee4f26..c6fe784fbde9de4ec48281e50048066bc9909f19 100644 --- a/lib_util/bitstream_reader.c +++ b/lib_util/bitstream_reader.c @@ -33,7 +33,6 @@ #include "bitstream_reader.h" #include "g192.h" #include "mime_io.h" -#include "ivas_error.h" #include "ivas_error_utils.h" #include #include diff --git a/lib_util/cmdl_tools.c b/lib_util/cmdl_tools.c index 344f3cc9f50963cfa7b985be106e32596159ee2b..625db1273342f1b56eb20e12c5e31ffbf5ec7bc5 100644 --- a/lib_util/cmdl_tools.c +++ b/lib_util/cmdl_tools.c @@ -194,9 +194,7 @@ void remove_cr( str[p] = c; p += ( c == '\r' ) ? 0 : 1; } - str[p] = 0; - return; } diff --git a/lib_util/g192.c b/lib_util/g192.c index a96a8ee56dc1ea4997e164f35c70beedd178dad7..a5eb030a4fd4bb37dcb9fbd96d7f8b67d0e61121 100644 --- a/lib_util/g192.c +++ b/lib_util/g192.c @@ -482,7 +482,11 @@ G192_ERROR G192_WriteVoipFrame_short( const uint16_t *serial, const int16_t numBits, uint16_t const rtpSequenceNumber, +#ifdef IVAS_RTPDUMP + uint32_t const rtpTimeStamp, +#else uint16_t const rtpTimeStamp, +#endif uint32_t const rcvTime_ms ) { int16_t G192_HEADER[2], G192_DATA[IVAS_MAX_BITS_PER_FRAME]; diff --git a/lib_util/g192.h b/lib_util/g192.h index 751f1324fb286131ba1cd8fd23d68622e69fce3c..0c22b739b9ff372d2939c423615a13458d31e7fd 100644 --- a/lib_util/g192.h +++ b/lib_util/g192.h @@ -93,7 +93,13 @@ G192_ERROR G192_Writer_Open_filename( G192_HANDLE *phG192, const char *filename G192_ERROR G192_WriteFrame( G192_HANDLE const hG192, const uint16_t *serial, const int16_t numBits ); -G192_ERROR G192_WriteVoipFrame_short( G192_HANDLE const hG192, const uint16_t *serial, const int16_t num_bits, uint16_t const rtpSequenceNumber, uint16_t const rtpTimeStamp, uint32_t const rcvTime_ms ); +G192_ERROR G192_WriteVoipFrame_short( G192_HANDLE const hG192, const uint16_t *serial, const int16_t num_bits, uint16_t const rtpSequenceNumber, +#ifdef IVAS_RTPDUMP + uint32_t const rtpTimeStamp, +#else + uint16_t const rtpTimeStamp, +#endif + uint32_t const rcvTime_ms ); G192_ERROR G192_Writer_Close( G192_HANDLE *phG192 ); diff --git a/lib_util/hrtf_file_reader.c b/lib_util/hrtf_file_reader.c index 73f9b5fc9376ffefd7fe8dd9d1bfb0ed6df9a170..164120d79dba7e7b422967b01a79a287bf68572c 100644 --- a/lib_util/hrtf_file_reader.c +++ b/lib_util/hrtf_file_reader.c @@ -191,6 +191,7 @@ static ivas_error check_hrtf_binary_header( { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Header of HRTF binary file not compliant (renderer type)" ); } + /* Check the output format of the decoder */ if ( ( hrtf_header->input_cfg != BINAURAL_INPUT_AUDIO_CONFIG_COMBINED ) && ( hrtf_header->input_cfg != BINAURAL_INPUT_AUDIO_CONFIG_HOA3 ) && ( hrtf_header->input_cfg != BINAURAL_INPUT_AUDIO_CONFIG_HOA2 ) && ( hrtf_header->input_cfg != BINAURAL_INPUT_AUDIO_CONFIG_FOA ) && ( hrtf_header->input_cfg != BINAURAL_INPUT_AUDIO_CONFIG_UNDEFINED ) ) @@ -273,7 +274,6 @@ static BINAURAL_INPUT_AUDIO_CONFIG audio_cfg_2_binaural_cfg( return hrtf_set_binaural_cfg; } - /*-------------------------------------------------------------------* * TDREND_LoadBSplineBinaryITD() * @@ -429,7 +429,6 @@ static ivas_error TDREND_LoadBSplineBinaryITD( return IVAS_ERR_OK; } - /*-------------------------------------------------------------------* * TDREND_LoadBSplineBinary() * @@ -437,8 +436,8 @@ static ivas_error TDREND_LoadBSplineBinaryITD( --------------------------------------------------------------------*/ static ivas_error TDREND_LoadBSplineBinary( - IVAS_DEC_HRTF_HANDLE HrFiltSet_p, /* i/o: HR filter model parameter structure */ - FILE *f_hrtf /* i : HR filter data file handle */ + IVAS_DEC_HRTF_TD_HANDLE HrFiltSet_p, /* i/o: HR filter model parameter structure */ + FILE *f_hrtf /* i : HR filter data file handle */ ) { ModelParams_t *model; @@ -512,6 +511,7 @@ static ivas_error TDREND_LoadBSplineBinary( free( v_tmp16 ); model->azimDim3_dyn = (int16_t *) malloc( model->elevDim3 * sizeof( int16_t ) ); model->azim_start_idx_dyn = (int16_t *) malloc( model->elevDim3 * sizeof( int16_t ) ); + model->azimKSeq = (float **) malloc( model->elevDim3 * sizeof( float * ) ); if ( model->azimDim3_dyn == NULL || model->azim_start_idx_dyn == NULL || model->azimKSeq == NULL ) { @@ -803,7 +803,6 @@ static ivas_error load_reverb_from_binary( { if ( hrtf_header.frequency != sampleRate ) { - free( hrtf_data ); return IVAS_ERR_INVALID_HRTF_SAMPLING_RATE; } } @@ -816,7 +815,8 @@ static ivas_error load_reverb_from_binary( hHrtfStatistics->average_energy_l_dyn = (float *) malloc( lr_iac_len * sizeof( float ) ); hHrtfStatistics->average_energy_r_dyn = (float *) malloc( lr_iac_len * sizeof( float ) ); hHrtfStatistics->inter_aural_coherence_dyn = (float *) malloc( lr_iac_len * sizeof( float ) ); - if ( hHrtfStatistics->average_energy_l_dyn == NULL || hHrtfStatistics->average_energy_l_dyn == NULL || hHrtfStatistics->inter_aural_coherence_dyn == NULL ) + + if ( hHrtfStatistics->average_energy_l_dyn == NULL || hHrtfStatistics->average_energy_r_dyn == NULL || hHrtfStatistics->inter_aural_coherence_dyn == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate memory for hrtf data" ); } @@ -851,6 +851,7 @@ static ivas_error load_reverb_from_binary( return IVAS_ERR_OK; } + /*---------------------------------------------------------------------* * load_reverb_binary() * @@ -873,6 +874,7 @@ ivas_error load_reverb_binary( return load_reverb_from_binary( hHrtfStatistics, sampleRate, hrtfReader->file ); } + /*-------------------------------------------------------------------* * TDREND_MIX_LoadHRTF() * @@ -880,9 +882,9 @@ ivas_error load_reverb_binary( --------------------------------------------------------------------*/ static ivas_error TDREND_MIX_LoadHRTF( - FILE *f_hrtf, /* i/o: File pointer to HRTF file */ - const int32_t sampleRate, /* i : sample rate */ - IVAS_DEC_HRTF_HANDLE HrFiltSet_p /* o : Loaded HR filter set */ + FILE *f_hrtf, /* i/o: File pointer to HRTF file */ + const int32_t sampleRate, /* i : sample rate */ + IVAS_DEC_HRTF_TD_HANDLE HrFiltSet_p /* o : Loaded HR filter set */ ) { int16_t tmp; @@ -936,7 +938,6 @@ static ivas_error TDREND_MIX_LoadHRTF( hrtf_data = (char *) malloc( hrtf_data_size_max ); if ( hrtf_data == NULL ) { - free( hrtf_data ); return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate memory for hrtf data" ); } @@ -944,13 +945,11 @@ static ivas_error TDREND_MIX_LoadHRTF( { if ( read_hrtf_binary_header( &hrtf_header, f_hrtf ) != IVAS_ERR_OK ) { - free( hrtf_data ); return IVAS_ERROR( IVAS_ERR_FAILED_FILE_READ, "HRTF binary file not compliant (number of HRTF)" ); } if ( ( header_check_result = check_hrtf_binary_header( &hrtf_header ) ) != IVAS_ERR_OK ) { - free( hrtf_data ); return header_check_result; } @@ -959,7 +958,6 @@ static ivas_error TDREND_MIX_LoadHRTF( { if ( fread( hrtf_data, 1, hrtf_header.data_size, f_hrtf ) != hrtf_header.data_size ) { - free( hrtf_data ); return IVAS_ERROR( IVAS_ERR_FAILED_FILE_READ, "Error in HRTF file reading" ); } } @@ -967,7 +965,6 @@ static ivas_error TDREND_MIX_LoadHRTF( { if ( hrtf_header.frequency != sampleRate ) { - free( hrtf_data ); return IVAS_ERR_INVALID_HRTF_SAMPLING_RATE; } } @@ -1009,7 +1006,7 @@ static ivas_error TDREND_MIX_LoadHRTF( *---------------------------------------------------------------------*/ ivas_error load_TDrend_HRTF_binary( - IVAS_DEC_HRTF_HANDLE hHrtf, /* i/o: HRTF handle */ + IVAS_DEC_HRTF_TD_HANDLE hHrtf, /* i/o: TD rend. HRTF handle */ const int32_t sampleRate, /* i : sample rate */ const hrtfFileReader *hrtfReader /* i : pointer to hrtfFileReader handle */ ) @@ -1032,7 +1029,7 @@ ivas_error load_TDrend_HRTF_binary( *---------------------------------------------------------------------*/ void destroy_td_hrtf( - IVAS_DEC_HRTF_HANDLE *hHrtf /* i/o: HRTF handle */ + IVAS_DEC_HRTF_TD_HANDLE *hHrtf /* i/o: TD rend. HRTF handle */ ) { int16_t i; @@ -1102,8 +1099,8 @@ void destroy_td_hrtf( *---------------------------------------------------------------------*/ static ivas_error create_Crend_HRTF_from_rawdata( - HRTFS_HANDLE *hHRTF, /* i/o: HRTF CRend handle */ - char *hrtf_data /* i : pointer to binary file */ + HRTFS_CREND_HANDLE *hHRTF, /* i/o: HRTF CRend handle */ + char *hrtf_data /* i : pointer to binary file */ ) { int16_t i, j, k; @@ -1115,7 +1112,6 @@ static ivas_error create_Crend_HRTF_from_rawdata( ivas_error error; Word16 factorQ; - if ( hrtf_data == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; @@ -1215,13 +1211,13 @@ static ivas_error create_Crend_HRTF_from_rawdata( ( *hHRTF )->inv_diffuse_weight[0][i] = ( *( (Word16 *) ( hrtf_data_rptr ) ) ) * powf( 2.f, -1.f * factorQ ); hrtf_data_rptr += sizeof( Word16 ); } + for ( i = 0; i < ( *hHRTF )->max_num_ir; i++ ) { ( *hHRTF )->inv_diffuse_weight[1][i] = ( *( (Word16 *) ( hrtf_data_rptr ) ) ) * powf( 2.f, -1.f * factorQ ); hrtf_data_rptr += sizeof( Word16 ); } - /* max_total_num_fsamp_per_iteration */ max_total_num_fsamp_per_iteration = *( (uint32_t *) ( hrtf_data_rptr ) ); hrtf_data_rptr += sizeof( uint32_t ); @@ -1767,7 +1763,6 @@ ivas_error load_fastconv_HRTF_from_binary( return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Could not create FastConv HRTF from binary file" ); } asFastconv = 1; - break; /* read just one set */ } else @@ -1873,6 +1868,7 @@ ivas_error load_parambin_HRTF_from_binary( } } free( hrtf_data ); + if ( asParam ) { return IVAS_ERR_OK; @@ -1906,7 +1902,6 @@ ivas_error load_Crend_HRTF_from_binary( ivas_hrtfs_file_header_t hrtfs_file_header; int16_t hrtf_id; bool load = false; - int16_t asCrend = 0; BINAURAL_INPUT_AUDIO_CONFIG hrtf_set_binaural_cfg; /* convert audio config. to HRTF binaural config */ @@ -1967,7 +1962,6 @@ ivas_error load_Crend_HRTF_from_binary( { if ( hrtf_header.frequency != sampleRate ) { - free( hrtf_data ); return IVAS_ERR_INVALID_HRTF_SAMPLING_RATE; } @@ -1982,7 +1976,7 @@ ivas_error load_Crend_HRTF_from_binary( free( hrtf_data ); return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Could not create HRTF from binary file" ); } - asCrend = 1; + break; /* read just one set */ } else @@ -1992,14 +1986,8 @@ ivas_error load_Crend_HRTF_from_binary( } free( hrtf_data ); - if ( asCrend ) - { - return IVAS_ERR_OK; - } - else - { - return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Could not create HRTF from binary file" ); - } + + return IVAS_ERR_OK; } @@ -2050,6 +2038,7 @@ void destroy_crend_hrtf( free( ( *hHrtfCrend )->pOut_to_bin_diffuse_im_dyn[j] ); } } + free( *hHrtfCrend ); *hHrtfCrend = NULL; } diff --git a/lib_util/hrtf_file_reader.h b/lib_util/hrtf_file_reader.h index 27dc8d179e0ed6087d05df53131d50e146238f55..938b5c1595024042c0ebc845fdfe9439d11b9c1c 100644 --- a/lib_util/hrtf_file_reader.h +++ b/lib_util/hrtf_file_reader.h @@ -48,8 +48,20 @@ typedef enum HRTF_READER_RENDERER_BINAURAL_MIXER_CONV, HRTF_READER_RENDERER_BINAURAL_MIXER_CONV_ROOM, HRTF_READER_RENDERER_BINAURAL_REVERB_ALL + } HRTF_READER_RENDERER_TYPE; +typedef enum +{ + BINAURAL_INPUT_AUDIO_CONFIG_INVALID, + BINAURAL_INPUT_AUDIO_CONFIG_COMBINED, /* 5_1, 5_1_2, 5_1_4, 7_1, 7_1_4 */ + BINAURAL_INPUT_AUDIO_CONFIG_HOA3, /* HOA3 */ + BINAURAL_INPUT_AUDIO_CONFIG_HOA2, /* HOA2 */ + BINAURAL_INPUT_AUDIO_CONFIG_FOA, /* FOA */ + BINAURAL_INPUT_AUDIO_CONFIG_UNDEFINED /* Not used */ + +} BINAURAL_INPUT_AUDIO_CONFIG; + typedef struct ivas_hrtfs_header_t { int32_t rend_type; @@ -87,7 +99,7 @@ void hrtfFileReader_close( *---------------------------------------------------------------------*/ ivas_error load_TDrend_HRTF_binary( - IVAS_DEC_HRTF_HANDLE hHrtf, /* i/o: HRTF handle */ + IVAS_DEC_HRTF_TD_HANDLE hHrtf, /* i/o: TD rend. HRTF handle */ const int32_t sampleRate, /* i : sample rate */ const hrtfFileReader *hrtfReader /* i : pointer to hrtfFileReader handle */ ); @@ -118,7 +130,6 @@ ivas_error load_Crend_HRTF_from_binary( const int32_t sampleRate /* i : sample rate */ ); - /*---------------------------------------------------------------------* * destroy_crend_hrtf() * @@ -181,7 +192,7 @@ void destroy_parambin_hrtf( *---------------------------------------------------------------------*/ void destroy_td_hrtf( - IVAS_DEC_HRTF_HANDLE *hHRTF /* i/o: HRTF handle */ + IVAS_DEC_HRTF_TD_HANDLE *hHRTF /* i/o: TD rend. HRTF handle */ ); /*---------------------------------------------------------------------* @@ -194,5 +205,4 @@ void destroy_hrtf_statistics( IVAS_DEC_HRTF_STATISTICS_HANDLE *hHrtfStatistics /* i/o: HRTF statistics handle */ ); - #endif /* IVAS_HRTF_FILE_READER_H */ diff --git a/lib_util/ivas_bpool.c b/lib_util/ivas_bpool.c new file mode 100644 index 0000000000000000000000000000000000000000..9db909f535e17a2911ab7e809c3a27caaf277edd --- /dev/null +++ b/lib_util/ivas_bpool.c @@ -0,0 +1,153 @@ +/****************************************************************************************************** + + (C) 2022-2025 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 +#include "ivas_bpool.h" +#include "ivas_error_utils.h" +#include "mutex.h" + +struct BPOOL +{ + mtx_t lock; + uint32_t bufferSize; + uint32_t numBuffers; + uint32_t numFreeBuffers; + void **freeBuffers; +}; + +ivas_error BPOOL_Create( BPOOL_HANDLE *pHandle, size_t bufferSize, uint32_t numBuffers ) +{ + uint32_t n; + uint8_t *base = NULL; + BPOOL_HANDLE handle; + size_t allocSize = sizeof( struct BPOOL ); + + if ( pHandle == NULL ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid pointer to Buffer Pool Handle" ); + } + + *pHandle = NULL; + + allocSize += bufferSize * numBuffers; /* pool memory */ + allocSize += sizeof( void * ) * numBuffers; /* free buffers stack */ + + base = calloc( allocSize, sizeof( uint8_t ) ); + if ( base == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Couldn't allocate Buffer pool" ); + } + + handle = (BPOOL_HANDLE) base; + base += sizeof( struct BPOOL ); + + mtx_init( &handle->lock, 0 ); + handle->bufferSize = bufferSize; + handle->numBuffers = numBuffers; + handle->numFreeBuffers = numBuffers; + handle->freeBuffers = (void **) base; + base += ( sizeof( void * ) * numBuffers ); + for ( n = 0; n < numBuffers; n++ ) + { + handle->freeBuffers[n] = base; + base += bufferSize; + } + + *pHandle = handle; + return IVAS_ERR_OK; +} + +void BPOOL_Destroy( BPOOL_HANDLE *pHandle ) +{ + if ( ( pHandle != NULL ) && ( *pHandle != NULL ) ) + { + mtx_destroy( &( *pHandle )->lock ); + free( *pHandle ); + *pHandle = NULL; + } +} + +ivas_error BPOOL_GetBuffer( BPOOL_HANDLE handle, void **dataPtr ) +{ + uint32_t idx = 0; + bool isFree = false; + + if ( handle == NULL || dataPtr == NULL ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid pointer args in GetBuffer" ); + } + + mtx_lock( &handle->lock ); + isFree = ( handle->numFreeBuffers > 0 ); + if ( isFree ) + { + idx = --handle->numFreeBuffers; + } + mtx_unlock( &handle->lock ); + + if ( !isFree ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNDERFLOW, "Underflow, no free buffers in pool" ); + } + + *dataPtr = handle->freeBuffers[idx]; + return IVAS_ERR_OK; +} + +/* return the buffer back to pool */ +ivas_error BPOOL_FreeBuffer( BPOOL_HANDLE handle, void *dataPtr ) +{ + uint32_t idx; + + if ( handle == NULL || dataPtr == NULL ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid pointer args in GetBuffer" ); + } + + mtx_lock( &handle->lock ); + idx = handle->numFreeBuffers++; + mtx_unlock( &handle->lock ); + + handle->freeBuffers[idx] = dataPtr; + + return IVAS_ERR_OK; +} + +/* return the number of free buffers available atm in the pool */ +uint32_t BPOOL_AvailableBuffers( BPOOL_HANDLE handle ) +{ + uint32_t numFreeBuffers; + mtx_lock( &handle->lock ); + numFreeBuffers = handle->numFreeBuffers; + mtx_unlock( &handle->lock ); + return numFreeBuffers; +} diff --git a/lib_util/ivas_bpool.h b/lib_util/ivas_bpool.h new file mode 100644 index 0000000000000000000000000000000000000000..30cf4962b5198fd2a22a522061e8ce4cff2be915 --- /dev/null +++ b/lib_util/ivas_bpool.h @@ -0,0 +1,57 @@ +/****************************************************************************************************** + + (C) 2022-2025 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_BPOOL_H +#define IVAS_BPOOL_H + +#include +#include "common_api_types.h" + +/* Forward declaraiton of opaque buffer pool handle */ +typedef struct BPOOL *BPOOL_HANDLE; + +/* Create a buffer pool with given element size and max number of buffers */ +ivas_error BPOOL_Create( BPOOL_HANDLE *pHandle, size_t bufferSize, uint32_t numBuffers ); + +/* Destroy the buffer pool and all free-up all allocated memory */ +void BPOOL_Destroy( BPOOL_HANDLE *pHandle ); + +/* request a buffer from the pool */ +ivas_error BPOOL_GetBuffer( BPOOL_HANDLE handle, void **dataPtr ); + +/* return the buffer back to pool */ +ivas_error BPOOL_FreeBuffer( BPOOL_HANDLE handle, void *dataPtr ); + +/* return the number of free buffers available atm in the pool */ +uint32_t BPOOL_AvailableBuffers( BPOOL_HANDLE handle ); + +#endif /* IVAS_BPOOL_H */ diff --git a/lib_util/ivas_queue.c b/lib_util/ivas_queue.c new file mode 100644 index 0000000000000000000000000000000000000000..b17cf3e21a6e0222b439ba0826780dd031551670 --- /dev/null +++ b/lib_util/ivas_queue.c @@ -0,0 +1,137 @@ +/****************************************************************************************************** + + (C) 2022-2025 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 "ivas_queue.h" +#include "ivas_error_utils.h" +#include "mutex.h" + +struct QUEUE +{ + mtx_t lock; + NODE *front; + NODE *back; + uint32_t size; +}; + +ivas_error QUEUE_Create( QUEUE_HANDLE *pHandle ) +{ + QUEUE_HANDLE handle = NULL; + *pHandle = NULL; + + if ( pHandle == NULL ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid pointer to Buffer Pool Handle" ); + } + + handle = calloc( 1, sizeof( struct QUEUE ) ); + if ( handle != NULL ) + { + mtx_init( &handle->lock, 0 ); + } + + *pHandle = handle; + return IVAS_ERR_OK; +} + +/* Destroy the queue and free-up all allocated memory */ +void QUEUE_Destroy( QUEUE_HANDLE *pHandle ) +{ + if ( ( pHandle != NULL ) && ( *pHandle != NULL ) ) + { + mtx_destroy( &( *pHandle )->lock ); + free( *pHandle ); + *pHandle = NULL; + } +} + +void QUEUE_Push( QUEUE_HANDLE handle, NODE *node ) +{ + mtx_lock( &handle->lock ); + if ( handle->back == NULL ) + { + handle->front = node; + } + else + { + handle->back->next = node; + } + handle->back = node; + handle->size++; + mtx_unlock( &handle->lock ); +} + +/* return the buffer back to pool */ +NODE *QUEUE_Pop( QUEUE_HANDLE handle ) +{ + NODE *node; + mtx_lock( &handle->lock ); + node = handle->front; + handle->front = handle->front->next; + if ( NULL == handle->front ) + { + handle->back = NULL; + } + handle->size--; + mtx_unlock( &handle->lock ); + return node; +} + +/* returns the first element in the queue */ +NODE *QUEUE_Front( QUEUE_HANDLE handle ) +{ + NODE *node; + mtx_lock( &handle->lock ); + node = handle->front; + mtx_unlock( &handle->lock ); + return node; +} + +/* returns the last element in the queue */ +NODE *QUEUE_Back( QUEUE_HANDLE handle ) +{ + NODE *node; + mtx_lock( &handle->lock ); + node = handle->back; + mtx_unlock( &handle->lock ); + return node; +} + +/* return the number of elements in the queue */ +size_t QUEUE_Size( QUEUE_HANDLE handle ) +{ + uint32_t numNodes; + mtx_lock( &handle->lock ); + numNodes = handle->size; + mtx_unlock( &handle->lock ); + return numNodes; +} diff --git a/lib_util/ivas_queue.h b/lib_util/ivas_queue.h new file mode 100644 index 0000000000000000000000000000000000000000..1c6b77504e501b6f0ec680839cd52f3f10b04ca8 --- /dev/null +++ b/lib_util/ivas_queue.h @@ -0,0 +1,68 @@ +/****************************************************************************************************** + + (C) 2022-2025 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_QUEUE_H +#define IVAS_QUEUE_H + +#include +#include "common_api_types.h" + +typedef struct NODE +{ + struct NODE *next; +} NODE; + +/* Forward declaraiton of opaque queue handle */ +typedef struct QUEUE *QUEUE_HANDLE; + +/* Create a queue with given element size and max number of buffers */ +ivas_error QUEUE_Create( QUEUE_HANDLE *pHandle ); + +/* Destroy the queue and all free-up all allocated memory */ +void QUEUE_Destroy( QUEUE_HANDLE *pHandle ); + +/* push a buffer to a queue */ +void QUEUE_Push( QUEUE_HANDLE handle, NODE *data ); + +/* pop the buffer from the front */ +NODE *QUEUE_Pop( QUEUE_HANDLE handle ); + +/* returns the first element from the front */ +NODE *QUEUE_Front( QUEUE_HANDLE handle ); + +/* returns the last element from the back */ +NODE *QUEUE_Back( QUEUE_HANDLE handle ); + +/* return the number of elements in the queue */ +size_t QUEUE_Size( QUEUE_HANDLE handle ); + +#endif /* IVAS_QUEUE_H */ diff --git a/lib_util/ivas_rtp_api.h b/lib_util/ivas_rtp_api.h new file mode 100644 index 0000000000000000000000000000000000000000..8e551c5ffcf303a9314a438aaa12eadb7357c086 --- /dev/null +++ b/lib_util/ivas_rtp_api.h @@ -0,0 +1,607 @@ +/****************************************************************************************************** + + (C) 2022-2025 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_RTP_API_H +#define IVAS_RTP_API_H + +#include +#include "common_api_types.h" + +/* + * +-----------------------+---------------------+--------------------+----------+ + * | RTP Header (+ HDREXT) | payload header | frame data | PI data | + * +-----------------------+---------------------+--------------------+----------+ + * \--------------------\ /------------------------------/ + * IVAS payload + * + * This api provides a mechanism to generate/unpack the IVAS payload. The RTP Header + * and header extension fields must be handled by caller. + * + * IVAS General Payload structure + * =============================== + * + * 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 + * H H H H F H + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |1| T | D |1| ET1 |x x x x|1| ET2 |x x x x|0|1|0 1| BR |1| ET3 |x x x x|… + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * \--------------/\--------------/\--------------/\--------------/\--------------/ + * Initial E byte Subsqnt Ebyte1 Subsqnt Ebyte2 ToC1 Subsqnt Ebyte3 + * + * H F + * +-+-+-+-+-+-+-+-+-------------------------- ---+-------------------- ---+-------+ + * …|0|0|0 1| BR | IVAS frame 1 ... | IVAS frame 2 ... |PI data| + * +-+-+-+-+-+-+-+-+-------------------------- ---+-------------------- ---+-------+ + * \--------------/ + * ToC2 + * + */ + +#define IVAS_MAX_FRAMES_PER_RTP_PACKET ( 8 ) /* Max supported frames per RTP packet */ + +/* It is difficult to decide the RTP Payload buffer's capacity intrinsically however computing + * using the maximum frame size and all currently supported PI data present gives a crude + * estimate or RTP packet size per frame. The additional PI data is assumed to add upto a 20% + * overhead in bitrate for the computation. + */ +#define NOMINAL_BUFFER_SIZE( numFramesPerPacket ) ( ( IVAS_MAX_BITS_PER_FRAME + ( IVAS_MAX_BITS_PER_FRAME / 5 ) ) * ( numFramesPerPacket ) / 8 ) + +#define DEFAULT_MAX_PACKET_BYTES ( 1400 ) /* Typical MTU size of 4G/5G Cellular Interfaces */ + +#define NO_BITRATE_REQ ( 0u ) /* If no bitrate is requested from remote */ + +/* IVAS Codec Types */ +typedef enum +{ + IVAS_RTP_EVS, /* EVS */ + IVAS_RTP_IVAS /* IVAS */ +} IVAS_RTP_CODEC; + +/* IVAS Bandwidth Requests */ +typedef enum +{ + IVAS_BANDWIDTH_NB, /* Narrowband */ + IVAS_BANDWIDTH_WB, /* Wideband*/ + IVAS_BANDWIDTH_SWB, /* SuperWideband*/ + IVAS_BANDWIDTH_FB, /* Fullband */ + IVAS_BANDWIDTH_NO_REQ, /* No Preference */ +} IVAS_RTP_BANDWIDTH; + +/* Channel Aware Coding */ +typedef enum +{ + IVAS_RTP_CA_LO_O2, /* FER=LO, OFFSET=2 */ + IVAS_RTP_CA_LO_O3, /* FER=LO, OFFSET=3 */ + IVAS_RTP_CA_LO_O5, /* FER=LO, OFFSET=5 */ + IVAS_RTP_CA_LO_O7, /* FER=LO, OFFSET=7 */ + IVAS_RTP_CA_HI_O2, /* FER=HI, OFFSET=2 */ + IVAS_RTP_CA_HI_O3, /* FER=HI, OFFSET=3 */ + IVAS_RTP_CA_HI_O5, /* FER=HI, OFFSET=5 */ + IVAS_RTP_CA_HI_O7, /* FER=HI, OFFSET=7 */ + IVAS_RTP_CA_NO_REQ /* No request */ +} IVAS_RTP_CA_MODE; + +/* Coded Format Requests */ +typedef enum +{ + IVAS_FMT_STEREO, /* Stereo */ + IVAS_FMT_SBA, /* Scene Based Audio */ + IVAS_FMT_MASA, /* Metadata Assisted Spatial Audio */ + IVAS_FMT_ISM, /* Object Based Audio */ + IVAS_FMT_MC, /* Multichannel Audio */ + IVAS_FMT_OMASA, /* Object + MASA */ + IVAS_FMT_OSBA, /* Object + SBA */ + IVAS_FMT_NO_REQ, /* No preference */ +} IVAS_RTP_FORMAT; + +#ifdef RTP_S4_251135_CR26253_0016_REV1 +/* Coded Subformat Requests */ +typedef enum +{ + IVAS_SUBFMT_FOA_PLANAR, + IVAS_SUBFMT_HOA2_PLANAR, + IVAS_SUBFMT_HOA3_PLANAR, + IVAS_SUBFMT_FOA, + IVAS_SUBFMT_HOA2, + IVAS_SUBFMT_HOA3, + IVAS_SUBFMT_MASA1, + IVAS_SUBFMT_MASA2, + IVAS_SUBFMT_ISM1, + IVAS_SUBFMT_ISM2, + IVAS_SUBFMT_ISM3, + IVAS_SUBFMT_ISM4, + IVAS_SUBFMT_ISM1_EXTENDED_METADATA, + IVAS_SUBFMT_ISM2_EXTENDED_METADATA, + IVAS_SUBFMT_ISM3_EXTENDED_METADATA, + IVAS_SUBFMT_ISM4_EXTENDED_METADATA, + IVAS_SUBFMT_MC_5_1, + IVAS_SUBFMT_MC_7_1, + IVAS_SUBFMT_MC_5_1_2, + IVAS_SUBFMT_MC_5_1_4, + IVAS_SUBFMT_MC_7_1_4, + IVAS_SUBFMT_RESERVED_21, + IVAS_SUBFMT_RESERVED_22, + IVAS_SUBFMT_RESERVED_23, + IVAS_SUBFMT_RESERVED_24, + IVAS_SUBFMT_RESERVED_25, + IVAS_SUBFMT_RESERVED_26, + IVAS_SUBFMT_RESERVED_27, + IVAS_SUBFMT_RESERVED_28, + IVAS_SUBFMT_RESERVED_29, + IVAS_SUBFMT_RESERVED_30, + IVAS_SUBFMT_RESERVED_31, + IVAS_SUBFMT_OMASA_ISM1_1TC, + IVAS_SUBFMT_OMASA_ISM2_1TC, + IVAS_SUBFMT_OMASA_ISM3_1TC, + IVAS_SUBFMT_OMASA_ISM4_1TC, + IVAS_SUBFMT_OMASA_ISM1_2TC, + IVAS_SUBFMT_OMASA_ISM2_2TC, + IVAS_SUBFMT_OMASA_ISM3_2TC, + IVAS_SUBFMT_OMASA_ISM4_2TC, + IVAS_SUBFMT_OSBA_ISM1_FOA_PLANAR, + IVAS_SUBFMT_OSBA_ISM2_FOA_PLANAR, + IVAS_SUBFMT_OSBA_ISM3_FOA_PLANAR, + IVAS_SUBFMT_OSBA_ISM4_FOA_PLANAR, + IVAS_SUBFMT_OSBA_ISM1_FOA, + IVAS_SUBFMT_OSBA_ISM2_FOA, + IVAS_SUBFMT_OSBA_ISM3_FOA, + IVAS_SUBFMT_OSBA_ISM4_FOA, + IVAS_SUBFMT_OSBA_ISM1_HOA2_PLANAR, + IVAS_SUBFMT_OSBA_ISM2_HOA2_PLANAR, + IVAS_SUBFMT_OSBA_ISM3_HOA2_PLANAR, + IVAS_SUBFMT_OSBA_ISM4_HOA2_PLANAR, + IVAS_SUBFMT_OSBA_ISM1_HOA2, + IVAS_SUBFMT_OSBA_ISM2_HOA2, + IVAS_SUBFMT_OSBA_ISM3_HOA2, + IVAS_SUBFMT_OSBA_ISM4_HOA2, + IVAS_SUBFMT_OSBA_ISM1_HOA3_PLANAR, + IVAS_SUBFMT_OSBA_ISM2_HOA3_PLANAR, + IVAS_SUBFMT_OSBA_ISM3_HOA3_PLANAR, + IVAS_SUBFMT_OSBA_ISM4_HOA3_PLANAR, + IVAS_SUBFMT_OSBA_ISM1_HOA3, + IVAS_SUBFMT_OSBA_ISM2_HOA3, + IVAS_SUBFMT_OSBA_ISM3_HOA3, + IVAS_SUBFMT_OSBA_ISM4_HOA3, + IVAS_SUBFMT_NO_REQ +} IVAS_RTP_SUBFORMAT; + +/* Split Rendering Requests */ +typedef struct +{ + uint32_t valid : 1; /* is split rendering request valid */ + uint32_t diegetic : 1; /* enabling diegetic support for Split Rendering */ + uint32_t yaw : 1; /* transmission metadata for correction around yaw axis */ + uint32_t pitch : 1; /* transmission metadata for correction around pitch axis */ + uint32_t roll : 1; /* transmission metadata for correction around roll axis */ + uint32_t reserved : 27; /* reserved */ +} IVAS_RTP_SPLITRENDER; +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ + +/* Remote Requests Types (Keys) */ +typedef enum +{ + IVAS_REQUEST_CODEC, /* Request codec type, value of type IVAS_RTP_CODEC */ + IVAS_REQUEST_BITRATE, /* Request bitrate, value of type uint32_t in kbps */ + IVAS_REQUEST_BANDWIDTH, /* Request bandwidth, value of type IVAS_RTP_BANDWIDTH */ + IVAS_REQUEST_FORMAT, /* Request format, value of type IVAS_RTP_FORMAT */ + IVAS_REQUEST_CA_MODE, /* Request channel awareness, value of type IVAS_RTP_CA_MODE */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + IVAS_REQUEST_SUBFORMAT, /* Request subFormat, value of type IVAS_RTP_SUBFORMAT */ + IVAS_REQUEST_SR_CONFIG, /* Request spit rendering, value of type IVAS_RTP_SPLITRENDER */ +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ + IVAS_REQUEST_MAX /* Max number of requests */ +} IVAS_RTP_REQUEST_TYPE; + +/* Remote Request Values */ +typedef union +{ + uint32_t bitrate; /* bitrate in kbps when request type is IVAS_REQUEST_BITRATE */ + IVAS_RTP_CODEC codec; /* codec id when request type is IVAS_REQUEST_CODEC */ + IVAS_RTP_BANDWIDTH bandwidth; /* badwidth when request type is IVAS_REQUEST_BANDWIDTH */ + IVAS_RTP_FORMAT formatType; /* format type when request type is IVAS_REQUEST_FORMAT */ + IVAS_RTP_CA_MODE caMode; /* channel aware mode when request type is IVAS_REQUEST_CA_MODE */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + IVAS_RTP_SUBFORMAT subFormatType; /* sub-format type when request type is IVAS_REQUEST_SUBFORMAT */ + IVAS_RTP_SPLITRENDER srConfig; /* split rendering config when request type is IVAS_REQUEST_SR_CONFIG */ +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ +} IVAS_RTP_REQUEST_VALUE; + +/* Template for pi data types, all defined pi data follow this template + * for example scene orientation pi data can be represented as :- + * + * typedef struct { + * size_t size; // sizeof(IVAS_PIDATA_SCENE_ORIENTATION) + * uint32_t piDataType; // IVAS_PI_SCENE_ORIENTATION + * float w, x, y, z; // pi data of scene orientation in quaternions + * } IVAS_PIDATA_SCENE_ORIENTATION; + * + */ +typedef struct +{ + size_t size; /* size of this structure */ + uint32_t piDataType; /* IVAS PI data type */ + uint8_t data[1]; /* Variable length array */ +} IVAS_PIDATA_GENERIC; + +/* Generic data buffer for sending/receiving coded frames / rtp payloads + * data buffer is owned and initialized by caller, rtp api will ensure + * buffer write does not exceed capacity. + */ +typedef struct +{ + size_t capacity; /* allocated size of the data buffer */ + size_t length; /* length of the initialized data in the buffer */ + uint8_t *buffer; /* pointer to the payload buffer */ +} IVAS_DATA_BUFFER; + +#ifdef RTP_S4_251135_CR26253_0016_REV1 +typedef enum +{ + IVAS_SR_TRANSPORT_LCLD, + IVAS_SR_TRANSPORT_LC3PLUS +} IVAS_RTP_SR_TRANSPORT; + +typedef struct +{ + bool valid; /* Valid Split Rendering Info for/in the ToC */ + bool diegetic; /* SR content digetic */ + uint32_t bitrateKbps; /* SR bitrate in kbps */ + IVAS_RTP_SR_TRANSPORT codec; /* SR Transport Codec used*/ +} IVAS_RTP_SR_INFO; +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ + +/**********************************************/ +/* IVAS RTP PACKER API */ +/**********************************************/ + +/* Forward declaration of rtp pack/unpack handle types */ +typedef struct IVAS_RTP_PACK *IVAS_RTP_PACK_HANDLE; /* rtp packer handle type */ + +/* Initial configuration for rtp packer + * - maxFramesPerPacket is used to define if more than one frame should be packed + * in the same rtp packet. If zero, will use IVAS_MAX_FRAMES_PER_RTP_PACKET. + */ +typedef struct +{ + uint32_t maxFramesPerPacket; /* maximum no of frame per packet desired during the session */ +} IVAS_RTP_PACK_CONFIG; + +/* Open an instance of the RTP packer and return a handle to rtp packer on success + * error code is retured on failure and handle is set to NULL + */ +ivas_error IVAS_RTP_PACK_Open( + IVAS_RTP_PACK_HANDLE *phIvasPack, /* i/o: pointer to an IVAS rtp packer handle to be opened */ + const IVAS_RTP_PACK_CONFIG *config /* i : pointer to initial config for RTP Packer */ +); + +/* Close and free an existing instance of rtp packer */ +void IVAS_RTP_PACK_Close( + IVAS_RTP_PACK_HANDLE *phIvasPack /* i/o : pointer to an IVAS rtp packer handle to be closed */ +); + +/* Update the RTP Header structure */ +#ifdef FIXED_RTP_SEQUENCE_NUM +ivas_error IVAS_RTP_PACK_UpdateHeader( + IVAS_RTP_PACK_HANDLE hIvasPack, /* i/o: pointer to an IVAS rtp packer handle to be opened */ + uint16_t seqNumInitVal, /* i : Initial sequence number to be used for 1st packet */ + uint32_t ssrc, /* i : Unique 32-bit Source ID as negotiated during SDP */ + uint8_t numCC, /* i : numCC indicates no. of contributing sources */ + uint32_t *csrc, /* i : SSRCs of contributing Sources for a mixed stream */ + uint16_t extHeaderId, /* i : extension header ID */ + uint16_t numExtensionBytes, /* i : length of the extension data */ + uint8_t *extData /* i : extension data pointer */ +); +#else +ivas_error IVAS_RTP_PACK_UpdateHeader( + IVAS_RTP_PACK_HANDLE hIvasPack, /* i/o: pointer to an IVAS rtp packer handle to be opened */ + uint32_t ssrc, /* i : Unique 32-bit Source ID as negotiated during SDP */ + uint8_t numCC, /* i : numCC indicates no. of contributing sources */ + uint32_t *csrc, /* i : SSRCs of contributing Sources for a mixed stream */ + uint16_t extHeaderId, /* i : extension header ID */ + uint16_t numExtensionBytes, /* i : length of the extension data */ + uint8_t *extData /* i : extension data pointer */ +); +#endif + +/* Add requests for remote sender using a key value pair api + * each key must be provided with a corresponding value type + * + * Cross validation of some key,value pairs will not be done + * in this API. E.g. Codec ID and supported bitrates/bandwidths + * will not be performed at this level. + */ +ivas_error IVAS_RTP_PACK_PushRemoteRequest( + IVAS_RTP_PACK_HANDLE hIvasPack, /* i/o : IVAS rtp packer handle */ + IVAS_RTP_REQUEST_TYPE reqType, /* i : remote request type */ + IVAS_RTP_REQUEST_VALUE reqValue /* i : value of the requested type */ +); + +/* Push a single IVAS/EVS frame to rtp packer + * + * If multiple frames per RTP packet are desired, multiple frames must be explicitly + * pushed before a call to IVAS_RTP_PACK_GetPayload to generate a rtp payload. + * + * It is possible to have variable frames per packet until maxFramesPerPacket frames + * if IVAS_RTP_PACK_GetPayload is invoked asyncronously w.r.t this api. + * + */ +ivas_error IVAS_RTP_PACK_PushFrame( + IVAS_RTP_PACK_HANDLE hIvasPack, /* i/o : IVAS rtp packer handle */ + IVAS_RTP_CODEC codecId, /* i : Codec type (IVAS/EVS) */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + const IVAS_RTP_SR_INFO *srInfo, /* i : Split Rendering Info (NULL if absent) */ +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ + const IVAS_DATA_BUFFER *frameBuffer /* i : packed frame bitstream for IVAS/EVS */ +); + +/* Get the number of frames in the FiFo currently */ +uint32_t IVAS_RTP_PACK_GetNumFrames( + IVAS_RTP_PACK_HANDLE hIvasPack /* i/o : IVAS rtp packer handle */ +); + +/* Push single PI data to rtp packer + * + * Provide PI data for a current RTP packet. All PI data is locally cached in the packer + * and set to the rtp payload with policy defined in initial configuration during call to + * IVAS_RTP_PACK_GetPayload. + * + */ +ivas_error IVAS_RTP_PACK_PushPiData( + IVAS_RTP_PACK_HANDLE hIvasPack, /* i/o : IVAS rtp packer handle */ + const IVAS_PIDATA_GENERIC *data /* i : pointer to the PIData stucture */ +); + +/* Generate a rtp payload using available pushed frames + * + * Available remote requests, pi data and frames will be packed into a rtp payload. The + * capacity field of payload is used to limits the maximum RTP packet size. + * + */ +ivas_error IVAS_RTP_PACK_GetPayload( + IVAS_RTP_PACK_HANDLE hIvasPack, /* i/o : IVAS rtp packer handle */ + IVAS_DATA_BUFFER *payload, /* o : encapsulated rtp payload */ + uint32_t *numFramesInPayload /* o : no. of frames in payload */ +); + +/* Generate a rtp packet using available pushed frames + * + * Available remote requests, pi data and frames will be packed into a rtp packet. If no + * frame is pushed before call to this api, NO_DATA_FRAME will be generated + * Takes care of updates to the RTP Header + * + */ +ivas_error IVAS_RTP_PACK_GetPacket( + IVAS_RTP_PACK_HANDLE hIvasPack, /* i/o : IVAS rtp packer handle */ + IVAS_DATA_BUFFER *packet, /* o : encapsulated rtp packet */ + uint32_t *numFramesInPacket /* o : no. of frames in packet */ +); + +/**********************************************/ +/* IVAS RTP UNPACKER API */ +/**********************************************/ + +/* Forward declaration of rtp unpack handle types */ +typedef struct IVAS_RTP_UNPACK *IVAS_RTP_UNPACK_HANDLE; /* rtp unpacker handle type */ + +/* Initial configuration for rtp unpacker + * - maxFramesPerPacket is used to define maximum supported frames per rtp packet + * to allow for internal memory allocaton, if zero, will use IVAS_MAX_FRAMES_PER_RTP_PACKET + */ + +typedef struct +{ + uint32_t maxFramesPerPacket; /* maximum no of frame per packet expected during the session */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + uint32_t srCodecFrameSizeMs; /* split rendering transport codec frame size in ms (5/10/20) set by sdp negotiation */ +#endif +} IVAS_RTP_UNPACK_CONFIG; + +/* Open an instance of the RTP unpacker and return a handle to rtp unpacker on success + * error code is retured on failure and handle is set to NULL + */ +ivas_error IVAS_RTP_UNPACK_Open( + IVAS_RTP_UNPACK_HANDLE *phIvasUnpack, /* i/o : rtp unpacker handle */ + const IVAS_RTP_UNPACK_CONFIG *config /* i : initial configuration for rtp unpacker */ +); + +/* Close and free an existing instance of rtp unpacker */ +void IVAS_RTP_UNPACK_Close( + IVAS_RTP_UNPACK_HANDLE *phIvasUnpack /* i/o : IVAS rtp unpacker handle */ +); + +/* Push a received rtp Ivas Payload to unpacker to extract number of frames, pi data and + * any remote request present in the payload. Caller must extract RTP header and header + * extension and feed Ivas Payload alongwith RTP Timestamp and sequence number. + * + * In case of DTX transmission modes, the number of frames in packet will be reduced by + * the number of NO_DATA frame received. All PullFrame calls for non NO_DATA frames shall + * be reported with timestamp jump indicating missing/NO_DATA IVAS frames. + * + * It is important to ensure IVAS_RTP_UNPACK_PushPayload, IVAS_RTP_UNPACK_PullFrame and + * IVAS_RTP_UNPACK_PullNextPiData API are invoked in same thread context or in a thread + * safe manner else a race condition can arise if new packet is pushed while frames/pidata + * are still being pulled out. The IVAS_RTP_UNPACK_PushPayload will gererate an error if + * new paylod is pushed before all frames/pidata are pulled out. + * + * Example usage : - + * ================== + * err = IVAS_RTP_UNPACK_PushPayload(hIvasUnpack, payload, rtpTs, seqNum, + * &nFrames, &nPiData, &reqBitmap); + * if (err != IVAS_ERR_OK) { return err; } + * + * // Read the frames in payload and feed to decoder + * while (nFrames-- > 0) { + * err = IVAS_RTP_UNPACK_PullFrame(hIvasUnpack, &recCodecId, &srInfo, &frame, &frameTs, &seqNum, &SpeechLostIndicated); + * if (err != IVAS_ERR_OK) { return err; } + * err = IVAS_DEC_VoIP_FeedFrame(hIvasDec, frame.buffer, frame.length, seqNum, frameTs, rcvTime, isGoodFrame); + * if (err != IVAS_ERR_OK) { return err; } + * } + * + * // Read PI Data + * while (nPiData-- > 0) { + * err = IVAS_RTP_UNPACK_PullNextPiData(hIvasUnpack, &piData, &piTs); + * if (err != IVAS_ERR_OK) { return err; } + * // handle pi data based on fwd/rev pi data types + * handlePIData(&piData, piTs) + * } + * + * // Read remote requests + * for (req = 0; req < IVAS_REQUEST_MAX; req++) { + * if (reqBitmap & (1u << req)) { + * err = IVAS_RTP_UNPACK_GetRequest(hIvasUnpack, req, &value); + * if (err != IVAS_ERR_OK) { return err; } + * switch(req) { + * case IVAS_REQUEST_CODEC : handleCodec(value.codec); break; + * case IVAS_REQUEST_BITRATE : handleBitrate(value.bitrate); break; + * case IVAS_REQUEST_BANDWIDTH : handleBandwidth(value.bandwidth); break; + * case IVAS_REQUEST_FORMAT : handleFormat(value.formatType); break; + * case IVAS_REQUEST_SUBFORMAT : handleSubFormat(value.subFormatType); break; + * case IVAS_REQUEST_CA_MODE : handleCAModevalue.caMode); break; + * case IVAS_REQUEST_SR_CONFIG : handleSRConfig(value.srConfig); break; + * } + * } + * } + * + */ +ivas_error IVAS_RTP_UNPACK_PushPayload( + IVAS_RTP_UNPACK_HANDLE hIvasUnpack, /* i/o : IVAS rtp unpacker handle */ + const IVAS_DATA_BUFFER *payload, /* i : received rtp payload */ + uint32_t timestamp, /* i : timestamp in RTP Clock @ 16KHz from rtp header */ + uint16_t sequenceNumber, /* i : sequence number from rtp header */ + uint32_t *numFramesInPacket, /* o : number of IVAS/EVS frames in rtp packet */ + uint32_t *numPiDataInPacket, /* o : number of PI data received in rtp packet */ + uint32_t *remoteRequestBitmap /* o : bitmap of available request in this packet */ +); + +/* Push a received rtp Ivas Packet to unpacker to extract number of frames, pi data and + * any remote request present in the Packet. + * + * In case of DTX transmission modes, the number of frames in packet will be reduced by + * the number of NO_DATA frame received. All PullFrame calls for non NO_DATA frames shall + * be reported with timestamp jump indicating missing/NO_DATA IVAS frames. + * + * It is important to ensure IVAS_RTP_UNPACK_PushPacket, IVAS_RTP_UNPACK_PullFrame and + * IVAS_RTP_UNPACK_PullNextPiData API are invoked in same thread context or in a thread + * safe manner else a race condition can arise if new packet is pushed while frames/pidata + * are still being pulled out. The IVAS_RTP_UNPACK_PushPacket will gererate an error if + * new packet is pushed before all frames/pidata are pulled out. + * + * Example usage : - + * ================== + * err = IVAS_RTP_UNPACK_PushPacket(hIvasUnpack, packet, &nFrames, &nPiData, &reqBitmap); + * if (err != IVAS_ERR_OK) { return err; } + * + * // Read the frames in packet and feed to decoder + * while (nFrames-- > 0) { + * err = IVAS_RTP_UNPACK_PullFrame(hIvasUnpack, &recCodecId, &srInfo, &frame, &frameTs, &seqNum, &SpeechLostIndicated); + * if (err != IVAS_ERR_OK) { return err; } + * err = IVAS_DEC_VoIP_FeedFrame(hIvasDec, frame.buffer, frame.length, seqNum, frameTs, rcvTime, isGoodFrame); + * if (err != IVAS_ERR_OK) { return err; } + * } + * + * // Read PI Data + * while (nPiData-- > 0) { + * err = IVAS_RTP_UNPACK_PullNextPiData(hIvasUnpack, &piData, &piTs); + * if (err != IVAS_ERR_OK) { return err; } + * // handle pi data based on fwd/rev pi data types + * handlePIData(&piData, piTs) + * } + * + * // Read remote requests + * for (req = 0; req < IVAS_REQUEST_MAX; req++) { + * if (reqBitmap & (1u << req)) { + * err = IVAS_RTP_UNPACK_GetRequest(hIvasUnpack, req, &value); + * if (err != IVAS_ERR_OK) { return err; } + * switch(req) { + * case IVAS_REQUEST_CODEC : handleCodec(value.codec); break; + * case IVAS_REQUEST_BITRATE : handleBitrate(value.bitrate); break; + * case IVAS_REQUEST_BANDWIDTH : handleBandwidth(value.bandwidth); break; + * case IVAS_REQUEST_FORMAT : handleFormat(value.formatType); break; + * case IVAS_REQUEST_SUBFORMAT : handleSubFormat(value.subFormatType); break; + * case IVAS_REQUEST_CA_MODE : handleCAModevalue.caMode); break; + * case IVAS_REQUEST_SR_CONFIG : handleSRConfig(value.srConfig); break; + * } + * } + * } + */ +ivas_error IVAS_RTP_UNPACK_PushPacket( + IVAS_RTP_UNPACK_HANDLE hIvasUnpack, /* i/o : IVAS rtp unpacker handle */ + const IVAS_DATA_BUFFER *packet, /* i : received rtp Packet */ + uint32_t *numFramesInPacket, /* o : number of IVAS/EVS frames in rtp packet */ + uint32_t *numPiDataInPacket, /* o : number of PI data received in rtp packet */ + uint32_t *remoteRequestBitmap /* o : bitmap of available request in this packet */ +); + +/* Fetch requests from sender using a key value pair api + * each key must be provided with a corresponding value storage type + * + * On call to IVAS_RTP_UNPACK_PushPayload(), remoteRequestBitmap can be used + * an indicator of new request available this frame + * + */ +ivas_error IVAS_RTP_UNPACK_GetRequest( + IVAS_RTP_UNPACK_HANDLE hIvasUnpack, /* i/o : IVAS rtp packer handle */ + IVAS_RTP_REQUEST_TYPE type, /* i : remote request type */ + IVAS_RTP_REQUEST_VALUE *value /* o : pointer of the requested type */ +); + +/* Extract a single IVAS/EVS frame from provided rtp payload alongwith rtp timestamp + * and sequence number + * + * If multiple frames per RTP packet are available, multiple calls to IVAS_RTP_UNPACK_PullFrame + * are needed. + */ +ivas_error IVAS_RTP_UNPACK_PullFrame( + IVAS_RTP_UNPACK_HANDLE hIvasUnpack, /* i/o : IVAS rtp unpacker handle */ + IVAS_RTP_CODEC *receivedCodecId, /* o : Codec type (IVAS/EVS) */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + IVAS_RTP_SR_INFO *srInfo, /* o : Split Rendering Info */ +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ + IVAS_DATA_BUFFER *frameBuffer, /* o : packed frame bitstream for IVAS/EVS */ + int16_t *frameSizeInBits, /* o : exact frame size in bits (AMRWB IO) */ + uint32_t *timestamp, /* o : timestamp in RTP Clock @ 16KHz */ + uint16_t *sequenceNumber, /* o : sequence number from rtp header */ + bool *speechLostIndicated, /* o : Is current frame indicated as Lost */ + bool *isAMRWB_IOmode /* o : Is AMRWB_IO mode EVS frame */ +); + +/* Pull a single PI data from rtp unpacker instance for current packet + * Each Pi data is accompanied with a corresponding timestamp + */ +ivas_error IVAS_RTP_UNPACK_PullNextPiData( + IVAS_RTP_UNPACK_HANDLE hIvasUnpack, /* i/o : IVAS rtp unpacker handle */ + IVAS_PIDATA_GENERIC *data, /* o : output data buffer for the Pi data */ + size_t capacity, /* i : capacity of pi data buffer in bytes */ + uint32_t *timestamp /* o : timestamp in RTP Clock @ 16KHz */ +); + +#endif /* IVAS_RTP_API_H */ diff --git a/lib_util/ivas_rtp_file.c b/lib_util/ivas_rtp_file.c new file mode 100644 index 0000000000000000000000000000000000000000..f7d6d5d86717a7caf5f416ae15513390a8a978de --- /dev/null +++ b/lib_util/ivas_rtp_file.c @@ -0,0 +1,936 @@ +/****************************************************************************************************** + + (C) 2022-2025 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 +#include "ivas_rtp_file.h" +#include "ivas_error_utils.h" + +struct IVAS_RTP_FILE +{ + bool isFileWriter; + FILE *f_rtpstream; +}; + +static ivas_error IvasRtpFile_Open( + const char *filePath, /* i : path to CA config file */ + bool isFileWriter, /* i : instance is a file writer else reader */ + IVAS_RTP_FILE_HANDLE *phRtpFile /* o : pointer to an IVAS file reader handle */ +) +{ + const char *mode = isFileWriter ? "wb" : "rb"; + FILE *f_rtpstream = fopen( filePath, mode ); + if ( f_rtpstream == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_FILE_OPEN, "could not open: %s\n", filePath ); + } + + *phRtpFile = calloc( 1, sizeof( struct IVAS_RTP_FILE ) ); + if ( *phRtpFile != NULL ) + { + ( *phRtpFile )->isFileWriter = isFileWriter; + ( *phRtpFile )->f_rtpstream = f_rtpstream; + } + + return IVAS_ERR_OK; +} + +static ivas_error IvasRtpFile_Close( + IVAS_RTP_FILE_HANDLE *phReader /* i : pointer to an IVAS file reader handle */ +) +{ + if ( phReader != NULL && *phReader != NULL ) + { + if ( ( *phReader )->f_rtpstream != NULL ) + { + fclose( ( *phReader )->f_rtpstream ); + ( *phReader )->f_rtpstream = NULL; + } + free( *phReader ); + *phReader = NULL; + } + + return IVAS_ERR_OK; +} + +static ivas_error IvasRtpFile_Write( + IVAS_RTP_FILE_HANDLE hRtpFile, /* i : pointer to an IVAS file writer handle */ + const uint8_t *packet, /* i : rtp packet to be written to rtpdump file */ + size_t numBytes ) /* i : size in bytes of the rtp packet */ +{ + ivas_error error = IVAS_ERR_OK; + if ( hRtpFile->isFileWriter ) + { + uint32_t length = (uint32_t) numBytes; /* Max packet length is < 32 bits*/ + fwrite( &length, sizeof( uint32_t ), 1, hRtpFile->f_rtpstream ); + fwrite( packet, sizeof( uint8_t ), numBytes, hRtpFile->f_rtpstream ); + } + else + { + error = IVAS_ERR_WRONG_PARAMS; + } + return error; +} + +static ivas_error IvasRtpFile_Read( + IVAS_RTP_FILE_HANDLE hRtpFile, /* i : pointer to an IVAS file reader handle */ + uint8_t *packet, /* o : read rtp packet */ + size_t *numBytes, /* o : no of bytes in packet */ + size_t capacity /* i : max capacity of the packet buffer */ +) +{ + size_t nread = 0; + uint32_t length = 0; + if ( hRtpFile->isFileWriter ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "File open for writing cannot be read" ); + } + + nread = fread( &length, sizeof( uint32_t ), 1, hRtpFile->f_rtpstream ); /* Read Packet Length */ + if ( nread == 0 ) + { + return IVAS_ERR_END_OF_FILE; + } + + *numBytes = length; + if ( ( *numBytes ) > capacity ) + { + fprintf( stderr, "RTP packet > buffer capacity %lu bytes\n", capacity ); + return IVAS_ERR_INVALID_OUTPUT_BUFFER_SIZE; + } + + nread = fread( packet, sizeof( uint8_t ), ( *numBytes ), hRtpFile->f_rtpstream ); /* Read Packet */ + if ( nread < ( *numBytes ) ) + { + return IVAS_ERR_END_OF_FILE; + } + + return IVAS_ERR_OK; +} + +static const char *const PiDataNames[IVAS_PI_MAX_ID] = { + "SCENE_ORIENTATION", "DEVICE_ORIENTATION_COMPENSATED", "DEVICE_ORIENTATION_UNCOMPENSATED", + "ACOUSTIC_ENVIRONMENT", "AUDIO_DESCRIPTION", "ISM_NUM", "ISM_ID", "ISM_GAIN", "ISM_ORIENTATION", + "ISM_POSITION", "ISM_DISTANCE_ATTENUATION", "ISM_DIRECTIVITY", "DIEGETIC_TYPE", "DYNAMIC_AUDIO_SUPPRESSION_INDICATION", + "AUDIO_FOCUS_INDICATION", "RESERVED15", "PLAYBACK_DEVICE_ORIENTATION", "HEAD_ORIENTATION", "LISTENER_POSITION", + "DYNAMIC_AUDIO_SUPPRESSION_REQUEST", "AUDIO_FOCUS_REQUEST", "PI_LATENCY", "R_ISM_ID", "R_ISM_GAIN", + "R_ISM_ORIENTATION", "R_ISM_POSITION", "R_ISM_DIRECTION", "RESERVED27", "RESERVED28", "RESERVED29", + "RESERVED30", "NO_DATA" +}; + +void IVAS_RTP_LogPiData( + FILE *f_piDataOut, /* i/o : Output json file handle to dump PI data for debug/test */ + const PIDATA_TS *piData, /* i : PI Data + Timestamp array containing all PI data in current packet */ + uint32_t nPiDataPresent /* i : Number of valid elements in the piData array */ +) +{ + uint32_t timestamp = ~0u; + if ( f_piDataOut == NULL || piData == NULL || nPiDataPresent == 0 ) + { + return; + } + + if ( ftell( f_piDataOut ) > 2 ) + { + fprintf( f_piDataOut, ",\n" ); + } + + while ( nPiDataPresent-- > 0 ) + { + const PIDATA_TS *cur = piData++; + + if ( timestamp != ( ~0u ) && timestamp != cur->timestamp ) + { + fprintf( f_piDataOut, "\n\t},\n\t\"%d\": {\n", cur->timestamp ); + } + else if ( timestamp != cur->timestamp ) + { + fprintf( f_piDataOut, "\t\"%d\": {\n", cur->timestamp ); + } + else + { + fprintf( f_piDataOut, ",\n" ); + } + fprintf( f_piDataOut, "\t\t\"%s\" : ", PiDataNames[cur->data.noPiData.piDataType] ); + switch ( cur->data.noPiData.piDataType ) + { + case IVAS_PI_SCENE_ORIENTATION: + case IVAS_PI_DEVICE_ORIENTATION_COMPENSATED: + case IVAS_PI_DEVICE_ORIENTATION_UNCOMPENSATED: +#ifdef RTP_S4_251135_CR26253_0016_REV1 + case IVAS_PI_PLAYBACK_DEVICE_ORIENTATION: + case IVAS_PI_HEAD_ORIENTATION: + case IVAS_PI_R_ISM_ORIENTATION: +#endif + { + fprintf( f_piDataOut, "{\n\t\t\t\"w\": %f,\n\t\t\t\"x\": %f,\n\t\t\t\"y\": %f,\n\t\t\t\"z\": %f \n\t\t}", + cur->data.scene.orientation.w, cur->data.scene.orientation.x, cur->data.scene.orientation.y, cur->data.scene.orientation.z ); + } + break; + + case IVAS_PI_ACOUSTIC_ENVIRONMENT: + { + fprintf( f_piDataOut, "{\n\t\t\t\"aeid\": %d", cur->data.acousticEnv.aeid ); + if ( cur->data.acousticEnv.availLateReverb ) + { + fprintf( f_piDataOut, ",\n\t\t\t\"rt60\": [ %f, %f, %f ],\n", cur->data.acousticEnv.rt60[0], cur->data.acousticEnv.rt60[1], cur->data.acousticEnv.rt60[2] ); + fprintf( f_piDataOut, "\t\t\t\"dsr\": [ %f, %f, %f ]", cur->data.acousticEnv.dsr[0], cur->data.acousticEnv.dsr[1], cur->data.acousticEnv.dsr[2] ); + } + if ( cur->data.acousticEnv.availEarlyReflections ) + { + fprintf( f_piDataOut, ",\n\t\t\t\"dim\": [ %f, %f, %f ],\n", cur->data.acousticEnv.roomDimensions.x, cur->data.acousticEnv.roomDimensions.y, cur->data.acousticEnv.roomDimensions.z ); + fprintf( f_piDataOut, "\t\t\t\"abscoeff\": [ %f, %f, %f, %f, %f, %f ]", cur->data.acousticEnv.absorbCoeffs[0], cur->data.acousticEnv.absorbCoeffs[1], cur->data.acousticEnv.absorbCoeffs[2], cur->data.acousticEnv.absorbCoeffs[3], cur->data.acousticEnv.absorbCoeffs[4], cur->data.acousticEnv.absorbCoeffs[5] ); + } + fprintf( f_piDataOut, "\n\t\t}" ); + } + break; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + case IVAS_PI_LISTENER_POSITION: + case IVAS_PI_R_ISM_POSITION: + { + fprintf( f_piDataOut, "{\n\t\t\t\"x\": %f,\n\t\t\t\"y\": %f,\n\t\t\t\"z\": %f \n\t\t}", + cur->data.listnerPosition.position.x, cur->data.listnerPosition.position.y, cur->data.listnerPosition.position.z ); + } + break; + case IVAS_PI_AUDIO_DESCRIPTION: + { + uint32_t nEntries = cur->data.audioDesc.nValidEntries; + const IVAS_AUDIO_ID *audioId = cur->data.audioDesc.audioId; + + fprintf( f_piDataOut, "[\n" ); + while ( nEntries-- > 0 ) + { + fprintf( f_piDataOut, "\t\t\t{\n" ); + fprintf( f_piDataOut, "\t\t\t\t\"isSpeech\": %s,\n", audioId->speech ? "true" : "false" ); + fprintf( f_piDataOut, "\t\t\t\t\"isMusic\": %s,\n", audioId->music ? "true" : "false" ); + fprintf( f_piDataOut, "\t\t\t\t\"isAmbiance\": %s,\n", audioId->ambiance ? "true" : "false" ); + fprintf( f_piDataOut, "\t\t\t\t\"isEditable\": %s,\n", audioId->editable ? "true" : "false" ); + fprintf( f_piDataOut, "\t\t\t\t\"isBinaural\": %s\n", audioId->binaural ? "true" : "false" ); + fprintf( f_piDataOut, "\t\t\t}%c\n", ( nEntries == 0 ) ? ' ' : ',' ); + audioId++; + } + fprintf( f_piDataOut, "\t\t]" ); + } + break; + case IVAS_PI_DIEGETIC_TYPE: + { + const bool *isDiegetic = cur->data.digeticIndicator.isDiegetic; + fprintf( f_piDataOut, "{\n" ); + fprintf( f_piDataOut, "\t\t\t\"isDigetic\": [\n" ); + fprintf( f_piDataOut, "\t\t\t\t%s,\n", isDiegetic[0] ? "true" : "false" ); + fprintf( f_piDataOut, "\t\t\t\t%s,\n", isDiegetic[1] ? "true" : "false" ); + fprintf( f_piDataOut, "\t\t\t\t%s,\n", isDiegetic[2] ? "true" : "false" ); + fprintf( f_piDataOut, "\t\t\t\t%s,\n", isDiegetic[3] ? "true" : "false" ); + fprintf( f_piDataOut, "\t\t\t\t%s\n", isDiegetic[4] ? "true" : "false" ); + fprintf( f_piDataOut, "\t\t\t]\n\t\t}" ); + } + break; + case IVAS_PI_AUDIO_FOCUS_INDICATION: + { + fprintf( f_piDataOut, "{" ); + if ( cur->data.focusIndication.availDirection ) + { + fprintf( f_piDataOut, "\n\t\t\t\"direction\": {\n" ); + fprintf( f_piDataOut, "\t\t\t\t\t\t\"w\": %f,\n\t\t\t\t\t\t\"x\": %f,\n\t\t\t\t\t\t\"y\": %f,\n\t\t\t\t\t\t\"z\": %f \n\t\t\t}", + cur->data.focusIndication.direction.w, cur->data.focusIndication.direction.x, cur->data.focusIndication.direction.y, cur->data.focusIndication.direction.z ); + if ( cur->data.focusIndication.availLevel ) + { + fprintf( f_piDataOut, "," ); + } + } + if ( cur->data.focusIndication.availLevel ) + { + fprintf( f_piDataOut, "\n\t\t\t\"level\": %d", cur->data.focusIndication.flvl ); + } + fprintf( f_piDataOut, "\n\t\t}" ); + } + break; + case IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION_REQUEST: + { + const IVAS_PIDATA_DYNAMIC_SUPPRESSION *das = &cur->data.dynSuppressionRequest; + fprintf( f_piDataOut, "{\n" ); + fprintf( f_piDataOut, "\t\t\t\"preferSpeech\": %s,\n", das->speech ? "true" : "false" ); + fprintf( f_piDataOut, "\t\t\t\"preferMusic\": %s,\n", das->music ? "true" : "false" ); + fprintf( f_piDataOut, "\t\t\t\"preferAmbiance\": %s,\n", das->ambiance ? "true" : "false" ); + fprintf( f_piDataOut, "\t\t\t\"level\": %d", das->sli ); + fprintf( f_piDataOut, "\n\t\t}" ); + } + break; + case IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION_INDICATION: + { + const IVAS_PIDATA_DYNAMIC_SUPPRESSION *das = &cur->data.dynSuppressionIndication; + fprintf( f_piDataOut, "{\n" ); + fprintf( f_piDataOut, "\t\t\t\"preferSpeech\": %s,\n", das->speech ? "true" : "false" ); + fprintf( f_piDataOut, "\t\t\t\"preferMusic\": %s,\n", das->music ? "true" : "false" ); + fprintf( f_piDataOut, "\t\t\t\"preferAmbiance\": %s,\n", das->ambiance ? "true" : "false" ); + fprintf( f_piDataOut, "\t\t\t\"level\": %d", das->sli ); + fprintf( f_piDataOut, "\n\t\t}" ); + } + break; + case IVAS_PI_AUDIO_FOCUS_REQUEST: + { + fprintf( f_piDataOut, "{" ); + if ( cur->data.focusRequest.availDirection ) + { + fprintf( f_piDataOut, "\n\t\t\t\"direction\": {\n" ); + fprintf( f_piDataOut, "\t\t\t\t\t\t\"w\": %f,\n\t\t\t\t\t\t\"x\": %f,\n\t\t\t\t\t\t\"y\": %f,\n\t\t\t\t\t\t\"z\": %f \n\t\t\t}", + cur->data.focusRequest.direction.w, cur->data.focusRequest.direction.x, cur->data.focusRequest.direction.y, cur->data.focusRequest.direction.z ); + if ( cur->data.focusRequest.availLevel ) + { + fprintf( f_piDataOut, "," ); + } + } + if ( cur->data.focusRequest.availLevel ) + { + fprintf( f_piDataOut, "\n\t\t\t\"level\": %d", cur->data.focusRequest.flvl ); + } + fprintf( f_piDataOut, "\n\t\t}" ); + } + break; + case IVAS_PI_RESERVED15: + case IVAS_PI_RESERVED27: + case IVAS_PI_RESERVED28: + case IVAS_PI_RESERVED29: + case IVAS_PI_RESERVED30: + { + fprintf( f_piDataOut, "{}" ); + } + break; + case IVAS_PI_ISM_NUM: + case IVAS_PI_ISM_ID: + case IVAS_PI_ISM_GAIN: + case IVAS_PI_ISM_ORIENTATION: + case IVAS_PI_ISM_POSITION: + case IVAS_PI_ISM_DISTANCE_ATTENUATION: + case IVAS_PI_ISM_DIRECTIVITY: + case IVAS_PI_PI_LATENCY: + case IVAS_PI_R_ISM_ID: + case IVAS_PI_R_ISM_GAIN: + case IVAS_PI_R_ISM_DIRECTION: +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ + case IVAS_PI_NO_DATA: + { + fprintf( f_piDataOut, "{}" ); + } + break; + } + timestamp = cur->timestamp; + } + fprintf( f_piDataOut, "\n\t}" ); +} + +void IVAS_RTP_WriteExtPiData( + FILE *f_piDataOut, /* i/o : Output csv file handle to dump PI data for external output */ + const PIDATA_TS *piData, /* i : PI Data + Timestamp array containing all PI data in current packet */ + uint32_t nPiDataPresent, /* i : Number of valid elements in the piData array */ + uint16_t numObj /* i : Number of objects */ +) +{ + if ( f_piDataOut == NULL || piData == NULL || nPiDataPresent == 0 ) + { + return; + } + + int i = 0; + + while ( nPiDataPresent-- > 0 ) + { + const PIDATA_TS *cur = piData++; + + /* The writing follows the pattern of: timestamp, PI DATA TYPE, PI DATA */ + + fprintf( f_piDataOut, "%d,%s,", cur->timestamp, PiDataNames[cur->data.noPiData.piDataType] ); + switch ( cur->data.noPiData.piDataType ) + { + case IVAS_PI_SCENE_ORIENTATION: + { + fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.scene.orientation.w, cur->data.scene.orientation.x, cur->data.scene.orientation.y, cur->data.scene.orientation.z ); + } + break; + case IVAS_PI_DEVICE_ORIENTATION_COMPENSATED: + { + fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.deviceCompensated.orientation.w, cur->data.deviceCompensated.orientation.x, cur->data.deviceCompensated.orientation.y, cur->data.deviceCompensated.orientation.z ); + } + break; + case IVAS_PI_DEVICE_ORIENTATION_UNCOMPENSATED: + { + fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.deviceUnCompensated.orientation.w, cur->data.deviceUnCompensated.orientation.x, cur->data.deviceUnCompensated.orientation.y, cur->data.deviceUnCompensated.orientation.z ); + } + break; + case IVAS_PI_ACOUSTIC_ENVIRONMENT: + { + fprintf( f_piDataOut, "%d", cur->data.acousticEnv.aeid ); + if ( cur->data.acousticEnv.availLateReverb ) + { + fprintf( f_piDataOut, ",%f,%f,%f", cur->data.acousticEnv.rt60[0], cur->data.acousticEnv.rt60[1], cur->data.acousticEnv.rt60[2] ); + fprintf( f_piDataOut, ",%f,%f,%f", cur->data.acousticEnv.dsr[0], cur->data.acousticEnv.dsr[1], cur->data.acousticEnv.dsr[2] ); + } + if ( cur->data.acousticEnv.availEarlyReflections ) + { + fprintf( f_piDataOut, ",%f,%f,%f", cur->data.acousticEnv.roomDimensions.x, cur->data.acousticEnv.roomDimensions.y, cur->data.acousticEnv.roomDimensions.z ); + fprintf( f_piDataOut, ",%f,%f,%f,%f,%f,%f", cur->data.acousticEnv.absorbCoeffs[0], cur->data.acousticEnv.absorbCoeffs[1], cur->data.acousticEnv.absorbCoeffs[2], cur->data.acousticEnv.absorbCoeffs[3], cur->data.acousticEnv.absorbCoeffs[4], cur->data.acousticEnv.absorbCoeffs[5] ); + } + } + break; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + case IVAS_PI_AUDIO_DESCRIPTION: + { + uint32_t nEntries = cur->data.audioDesc.nValidEntries; + const IVAS_AUDIO_ID *audioId = cur->data.audioDesc.audioId; + + while ( nEntries-- > 0 ) + { + fprintf( f_piDataOut, "%d,%d,%d,%d,%d", audioId->speech, audioId->music, audioId->ambiance, audioId->editable, audioId->binaural ); + audioId++; + } + } + break; + case IVAS_PI_ISM_NUM: + { + fprintf( f_piDataOut, "%d", cur->data.ismNum.numObjects ); + } + break; + case IVAS_PI_ISM_ID: + { + for ( i = 0; i < numObj; ++i ) + { + if ( i != 0 ) + { + fprintf( f_piDataOut, "," ); + } + fprintf( f_piDataOut, "%d", cur->data.ismId.id[i] ); + } + } + break; + case IVAS_PI_ISM_GAIN: + { + for ( i = 0; i < numObj; ++i ) + { + if ( i != 0 ) + { + fprintf( f_piDataOut, "," ); + } + fprintf( f_piDataOut, "%d", cur->data.ismGain.dB[i] ); + } + } + break; + case IVAS_PI_ISM_ORIENTATION: + { + for ( i = 0; i < numObj; ++i ) + { + if ( i != 0 ) + { + fprintf( f_piDataOut, "," ); + } + fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.ismOrientation.orientation[i].w, cur->data.ismOrientation.orientation[i].x, cur->data.ismOrientation.orientation[i].y, cur->data.ismOrientation.orientation[i].z ); + } + } + break; + case IVAS_PI_ISM_POSITION: + { + for ( i = 0; i < numObj; ++i ) + { + if ( i != 0 ) + { + fprintf( f_piDataOut, "," ); + } + fprintf( f_piDataOut, "%f,%f,%f", cur->data.ismPosition.position[i].x, cur->data.ismPosition.position[i].y, cur->data.ismPosition.position[i].z ); + } + } + break; + case IVAS_PI_ISM_DISTANCE_ATTENUATION: + { + for ( i = 0; i < numObj; ++i ) + { + if ( i != 0 ) + { + fprintf( f_piDataOut, "," ); + } + fprintf( f_piDataOut, "%f,%f,%f", cur->data.ismAttenuation.distAtten[i].ref_dist, cur->data.ismAttenuation.distAtten[i].max_dist, cur->data.ismAttenuation.distAtten[i].roll ); + } + } + break; + case IVAS_PI_ISM_DIRECTIVITY: + { + for ( i = 0; i < numObj; ++i ) + { + if ( i != 0 ) + { + fprintf( f_piDataOut, "," ); + } + fprintf( f_piDataOut, "%d,%d,%f", cur->data.ismDirectivity.directivity[i].innerConeAngle, cur->data.ismDirectivity.directivity[i].outerConeAngle, cur->data.ismDirectivity.directivity[i].outerAttenuationdB ); + } + } + break; + case IVAS_PI_DIEGETIC_TYPE: + { + const bool *isDiegetic = cur->data.digeticIndicator.isDiegetic; + fprintf( f_piDataOut, "%d,%d,%d,%d,%d", isDiegetic[0], isDiegetic[1], isDiegetic[2], isDiegetic[3], isDiegetic[4] ); + } + break; + case IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION_INDICATION: + { + const IVAS_PIDATA_DYNAMIC_SUPPRESSION *das = &cur->data.dynSuppressionIndication; + fprintf( f_piDataOut, "%d,%d,%d,%d", das->speech, das->music, das->ambiance, das->sli ); + } + break; + case IVAS_PI_AUDIO_FOCUS_INDICATION: + { + if ( cur->data.focusIndication.availDirection ) + { + fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.focusIndication.direction.w, cur->data.focusIndication.direction.x, cur->data.focusIndication.direction.y, cur->data.focusIndication.direction.z ); + if ( cur->data.focusIndication.availLevel ) + { + fprintf( f_piDataOut, "," ); + } + } + if ( cur->data.focusIndication.availLevel ) + { + fprintf( f_piDataOut, "%d", cur->data.focusIndication.flvl ); + } + } + break; + case IVAS_PI_PLAYBACK_DEVICE_ORIENTATION: + { + fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.playbackOrientation.orientation.w, cur->data.playbackOrientation.orientation.x, cur->data.playbackOrientation.orientation.y, cur->data.playbackOrientation.orientation.z ); + } + break; + case IVAS_PI_HEAD_ORIENTATION: + { + fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.headOrientation.orientation.w, cur->data.headOrientation.orientation.x, cur->data.headOrientation.orientation.y, cur->data.headOrientation.orientation.z ); + } + break; + case IVAS_PI_LISTENER_POSITION: + { + fprintf( f_piDataOut, "%f,%f,%f", cur->data.listnerPosition.position.x, cur->data.listnerPosition.position.y, cur->data.listnerPosition.position.z ); + } + break; + case IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION_REQUEST: + { + const IVAS_PIDATA_DYNAMIC_SUPPRESSION *das = &cur->data.dynSuppressionRequest; + fprintf( f_piDataOut, "%d,%d,%d,%d", das->speech, das->music, das->ambiance, das->sli ); + } + break; + case IVAS_PI_AUDIO_FOCUS_REQUEST: + { + + if ( cur->data.focusRequest.availDirection ) + { + fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.focusRequest.direction.w, cur->data.focusRequest.direction.x, cur->data.focusRequest.direction.y, cur->data.focusRequest.direction.z ); + if ( cur->data.focusRequest.availLevel ) + { + fprintf( f_piDataOut, "," ); + } + } + if ( cur->data.focusRequest.availLevel ) + { + fprintf( f_piDataOut, "%d", cur->data.focusRequest.flvl ); + } + } + break; + case IVAS_PI_PI_LATENCY: + { + fprintf( f_piDataOut, "%d", cur->data.piLatency.latency ); + } + break; + case IVAS_PI_R_ISM_ID: + { + fprintf( f_piDataOut, "%d", cur->data.ismEditId.id ); + } + break; + case IVAS_PI_R_ISM_GAIN: + { + fprintf( f_piDataOut, "%d", cur->data.ismEditGain.piDataType ); + } + break; + case IVAS_PI_R_ISM_ORIENTATION: + { + fprintf( f_piDataOut, "%f,%f,%f,%f", cur->data.ismEditOrientation.orientation.w, cur->data.ismEditOrientation.orientation.x, cur->data.ismEditOrientation.orientation.y, cur->data.ismEditOrientation.orientation.z ); + } + break; + case IVAS_PI_R_ISM_POSITION: + { + fprintf( f_piDataOut, "%f,%f,%f", cur->data.ismEditPosition.position.x, cur->data.ismEditPosition.position.y, cur->data.ismEditPosition.position.z ); + } + break; + case IVAS_PI_R_ISM_DIRECTION: + { + fprintf( f_piDataOut, "%f,%f", cur->data.ismEditDirection.azimuth, cur->data.ismEditDirection.elevation ); + } + break; + case IVAS_PI_RESERVED15: + case IVAS_PI_RESERVED27: + case IVAS_PI_RESERVED28: + case IVAS_PI_RESERVED29: + case IVAS_PI_RESERVED30: + break; +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ + } + fprintf( f_piDataOut, "\n" ); + } +} + +const char *IVAS_RTP_GetExtPiFilePath( IVAS_RTP *rtp ) +{ + return rtp->piExtFilename; +} + +void IVAS_RTP_Term( + IVAS_RTP *rtp /* i/o : IVAS RTP File reader/writer handle */ +) +{ + if ( NULL != rtp ) + { + if ( rtp->hPack != NULL ) + { + /* Complete the last packet */ + if ( IVAS_RTP_PACK_GetNumFrames( rtp->hPack ) != 0 ) + { + ivas_error error = IVAS_ERR_OK; + uint32_t numFramesInPayload = 0; + + if ( ( error = IVAS_RTP_PACK_GetPacket( rtp->hPack, &rtp->rtpPacket, &numFramesInPayload ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while packing RTP Packet\n", ivas_error_to_string( error ) ); + } + else if ( numFramesInPayload > 0 ) + { + if ( ( error = IvasRtpFile_Write( rtp->hRtpFile, rtp->rtpPacket.buffer, rtp->rtpPacket.length ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while writing RTP packet\n", ivas_error_to_string( error ) ); + } + } + } + IVAS_RTP_PACK_Close( &rtp->hPack ); + } + + if ( rtp->hUnpack != NULL ) + { + IVAS_RTP_UNPACK_Close( &rtp->hUnpack ); + } + + if ( rtp->f_piDataOut != NULL ) + { + fprintf( rtp->f_piDataOut, "\n}\n" ); + fclose( rtp->f_piDataOut ); + rtp->f_piDataOut = NULL; + } + + if ( rtp->f_piExtOut != NULL ) + { + fclose( rtp->f_piExtOut ); + rtp->f_piExtOut = NULL; + } + + if ( rtp->hRtpFile != NULL ) + { + IvasRtpFile_Close( &rtp->hRtpFile ); + } + } +} + +ivas_error IVAS_RTP_WRITER_Init( + IVAS_RTP *rtp, /* i/o : IVAS RTP File writer handle */ + const char *outputBitstreamFilename, /* i : RTP Dump filename */ +#ifdef FIXED_RTP_SEQUENCE_NUM + uint32_t numFramesPerPacket, /* i : No. of frames per packet desired */ + uint32_t SSRC, /* i : SSRC for RTP Header */ + uint16_t seqNumInitVal /* i : Initial seq number in rtp header */ +#else + uint32_t numFramesPerPacket /* i : No. of frames per packet desired */ +#endif +) +{ +#ifndef FIXED_RTP_SEQUENCE_NUM + uint32_t SSRC = ( rand() & 0xFFFF ) | ( (uint32_t) rand() << 16 ); +#endif + ivas_error error = IVAS_ERR_OK; + + memset( rtp, 0, sizeof( IVAS_RTP ) ); + + rtp->packCfg.maxFramesPerPacket = numFramesPerPacket; + rtp->rtpPacket.buffer = rtp->packet; + rtp->rtpPacket.capacity = sizeof( rtp->packet ); + + error = IVAS_RTP_PACK_Open( &rtp->hPack, &rtp->packCfg ); + if ( error == IVAS_ERR_OK ) + { + /* Open the output file for RTPDump writing */ + error = IvasRtpFile_Open( outputBitstreamFilename, true, &rtp->hRtpFile ); + if ( error != IVAS_ERR_OK ) + { + return error; + } + +#ifdef FIXED_RTP_SEQUENCE_NUM + error = IVAS_RTP_PACK_UpdateHeader( rtp->hPack, seqNumInitVal, SSRC, 0, NULL, 0, 0, NULL ); +#else + error = IVAS_RTP_PACK_UpdateHeader( rtp->hPack, SSRC, 0, NULL, 0, 0, NULL ); +#endif + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "error in IVAS_RTP_PACK_UpdateHeader(): %d\n", error ); + } + } + + return error; +} + +ivas_error IVAS_RTP_READER_Init( + IVAS_RTP *rtp, /* i/o : IVAS RTP File reader handle */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + uint32_t srCodecFrameSizeMs, /* i : SR Codec Framesize in ms */ +#endif + const char *inputBitstreamFilename, /* i : Input rtpdump filename */ + const char *piOutputFilename, /* i : Output PI data json filename */ + bool isExtOutput, /* i : External output mode */ + const char *outputWavFilename /* i : name of the output audio file */ +) +{ + ivas_error error = IVAS_ERR_OK; + + memset( rtp, 0, sizeof( IVAS_RTP ) ); + + rtp->unpackCfg.maxFramesPerPacket = IVAS_MAX_FRAMES_PER_RTP_PACKET; + rtp->unpackCfg.srCodecFrameSizeMs = srCodecFrameSizeMs; + rtp->rtpPacket.buffer = rtp->packet; + rtp->rtpPacket.capacity = sizeof( rtp->packet ); + + error = IVAS_RTP_UNPACK_Open( &rtp->hUnpack, &rtp->unpackCfg ); + if ( error == IVAS_ERR_OK ) + { + error = IvasRtpFile_Open( inputBitstreamFilename, false, &rtp->hRtpFile ); + if ( error != IVAS_ERR_OK ) + { + return error; + } + + if ( piOutputFilename != NULL ) + { + rtp->f_piDataOut = fopen( piOutputFilename, "w" ); + if ( rtp->f_piDataOut == NULL ) + { + fprintf( stderr, "could not open: %s\n", piOutputFilename ); + return IVAS_ERR_FAILED_FILE_OPEN; + } + fprintf( rtp->f_piDataOut, "{\n" ); + } + + if ( isExtOutput ) + { + char ext_pi[12]; + + /* sizeof( ext_pi ) accounts for terminating NULL, don't subtract extra 1 */ + const int32_t maxNameLenWithoutExt = FILENAME_MAX - (int32_t) sizeof( ext_pi ); + strncpy( rtp->piExtFilename, outputWavFilename, maxNameLenWithoutExt ); + snprintf( ext_pi, sizeof( ext_pi ), ".pidata.csv" ); + + /* strlen( metadata_filename[0] ) doesn't account for terminating NULL, subtract extra 1 */ + const int32_t maxNumCharactersToAppend = FILENAME_MAX - (int32_t) strlen( rtp->piExtFilename ) - 1; + strncat( rtp->piExtFilename, ext_pi, maxNumCharactersToAppend ); + + rtp->f_piExtOut = fopen( rtp->piExtFilename, "w" ); + if ( rtp->f_piExtOut == NULL ) + { + fprintf( stderr, "could not open: %s\n", rtp->piExtFilename ); + return IVAS_ERR_FAILED_FILE_OPEN; + } + } + } + + return error; +} + +ivas_error IVAS_RTP_WriteNextFrame( + IVAS_RTP *rtp, /* i/o : IVAS RTP File writer handle */ + uint8_t *au, /* i : IVAS Compressed AU (Packed frame) */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + const IVAS_RTP_SR_INFO *srInfo, /* i : Split rendering info in present, else NULL */ +#endif + int16_t auSizeBits, /* i : Frame size in bits */ + bool isMono, /* i : input was evs(true) or ivas(false) */ + bool forcePacket /* i : force packets with whatever frames pushed so far */ +) +{ + ivas_error error = IVAS_ERR_OK; + uint32_t nProcPiData = 0; + IVAS_DATA_BUFFER packedFrame = { 0, 0, NULL }; + + packedFrame.capacity = ( auSizeBits + 7 ) / 8; + packedFrame.length = ( auSizeBits + 7 ) / 8; + packedFrame.buffer = (uint8_t *) au; + rtp->rtpPacket.length = 0; + + /* Push Encoded Stream to */ + error = IVAS_RTP_PACK_PushFrame( rtp->hPack, + isMono ? IVAS_RTP_EVS : IVAS_RTP_IVAS, +#ifdef RTP_S4_251135_CR26253_0016_REV1 + srInfo, +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ + &packedFrame ); + if ( error != IVAS_ERR_OK ) + { + return error; + } + + while ( rtp->nWrittenPiData > 0 ) + { + PIDATA_TS *piDataTs = &rtp->piData[nProcPiData++]; + if ( ( error = IVAS_RTP_PACK_PushPiData( rtp->hPack, (const IVAS_PIDATA_GENERIC *) &piDataTs->data ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while pushing scene orientation\n", ivas_error_to_string( error ) ); + return error; + } + rtp->nWrittenPiData--; + } + + if ( forcePacket || IVAS_RTP_PACK_GetNumFrames( rtp->hPack ) == rtp->packCfg.maxFramesPerPacket ) + { + uint32_t numFramesInPayload = 0; + + /* Generate RTP Packet */ + if ( ( error = IVAS_RTP_PACK_GetPacket( rtp->hPack, &rtp->rtpPacket, &numFramesInPayload ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while packing RTP Header\n", ivas_error_to_string( error ) ); + return error; + } + + if ( ( error = IvasRtpFile_Write( rtp->hRtpFile, rtp->rtpPacket.buffer, rtp->rtpPacket.length ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while writing RTP packet\n", ivas_error_to_string( error ) ); + return error; + } + } + + return error; +} + +ivas_error IVAS_RTP_ReadNextFrame( + IVAS_RTP *rtp, /* i/o : IVAS RTP File reader handle */ + uint8_t *au, /* o : Read next IVAS Compressed AU (Packed frame) */ + int16_t *auSizeBits, /* o : Reported Frame size in bits */ + uint32_t *rtpTimeStamp, /* o : RTP Timestamp for this frame */ + uint16_t *rtpSequenceNumber, /* o : RTP sequence number for this packet */ + uint32_t *nextPacketRcvTime_ms, /* i/o : Clock indicating packet receive times need in JBM */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + IVAS_RTP_SR_INFO *srInfo, /* o : Split Rendering info if SR RTP frame unpacked */ +#endif + bool *qBit /* o : AMRWB Q bite as indicated in the RTP packet */ +) +{ + ivas_error error = IVAS_ERR_OK; + IVAS_DATA_BUFFER packedFrame; + IVAS_RTP_CODEC codecId = IVAS_RTP_IVAS; + bool isAMRWB_IOmode = false; + + packedFrame.length = 0; + packedFrame.buffer = au; + packedFrame.capacity = ( IVAS_MAX_BITS_PER_FRAME / 8 ); + if ( rtp->numFramesInPacket == 0 ) + { + rtp->rtpPacket.length = 0; + if ( ( error = IvasRtpFile_Read( rtp->hRtpFile, rtp->rtpPacket.buffer, &rtp->rtpPacket.length, rtp->rtpPacket.capacity ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ( error = IVAS_RTP_UNPACK_PushPacket( rtp->hUnpack, &rtp->rtpPacket, + &rtp->numFramesInPacket, &rtp->numPiDataInPacket, + &rtp->remoteRequestBitmap ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "failed to unpack RTP packet error = %s\n", ivas_error_to_string( error ) ); + return error; + } + + rtp->nReadPiData = 0; + rtp->nProcPiData = 0; + + /* Pre-read all PI data */ + while ( rtp->numPiDataInPacket != 0 ) + { + PIDATA_TS *piData = &rtp->piData[rtp->nReadPiData]; + if ( ( error = IVAS_RTP_UNPACK_PullNextPiData( rtp->hUnpack, (IVAS_PIDATA_GENERIC *) &piData->data, sizeof( piData->data ), &piData->timestamp ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "failed to pull PI Data, error = %s\n", ivas_error_to_string( error ) ); + return error; + } + rtp->nReadPiData++; + rtp->numPiDataInPacket--; + } + IVAS_RTP_LogPiData( rtp->f_piDataOut, rtp->piData, rtp->nReadPiData ); + } + +#ifdef RTP_S4_251135_CR26253_0016_REV1 + error = IVAS_RTP_UNPACK_PullFrame( rtp->hUnpack, &codecId, &rtp->srInfo, &packedFrame, auSizeBits, rtpTimeStamp, rtpSequenceNumber, &rtp->speechLostIndicated, &isAMRWB_IOmode ); +#else + error = IVAS_RTP_UNPACK_PullFrame( rtp->hUnpack, &codecId, &packedFrame, auSizeBits, rtpTimeStamp, rtpSequenceNumber, &rtp->speechLostIndicated, &isAMRWB_IOmode ); +#endif + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "failed to pull frame after unpack\n" ); + return error; + } + + rtp->restartNeeded = false; + if ( *auSizeBits == 0 ) + { + /* NO_DATA_FRAME/SPEECH_LOST for IVAS and EVS is indicated by same bits + Do not restart decoder on codec/amrwb mode change in this case */ + } + else + { + rtp->restartNeeded = ( rtp->codecId != codecId ) || + ( codecId == IVAS_RTP_EVS && ( rtp->isAMRWB_IOmode != isAMRWB_IOmode ) ); + + if ( rtp->restartNeeded ) + { + fprintf( stdout, "\nRTP packet codec changed %s -> %s\n", + ( rtp->codecId == IVAS_RTP_EVS ) ? ( rtp->isAMRWB_IOmode ? "AMRWB_IO" : "EVS" ) : "IVAS", + ( codecId == IVAS_RTP_EVS ) ? ( isAMRWB_IOmode ? "AMRWB_IO" : "EVS" ) : "IVAS" ); + } + + rtp->codecId = codecId; + rtp->isAMRWB_IOmode = isAMRWB_IOmode; + } + +#ifdef RTP_S4_251135_CR26253_0016_REV1 + if ( srInfo != NULL ) + { + *srInfo = rtp->srInfo; + } +#endif + *qBit = !rtp->speechLostIndicated; + rtp->numFramesInPacket--; + rtp->numFramesProduced++; + *nextPacketRcvTime_ms += 20; + + return IVAS_ERR_OK; +} diff --git a/lib_util/ivas_rtp_file.h b/lib_util/ivas_rtp_file.h new file mode 100644 index 0000000000000000000000000000000000000000..70f8c99f0e076eaf4d4c9633513864bfbe6e763e --- /dev/null +++ b/lib_util/ivas_rtp_file.h @@ -0,0 +1,95 @@ +/****************************************************************************************************** + + (C) 2022-2025 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_RTP_FILE_H +#define IVAS_RTP_FILE_H + +#include "common_api_types.h" +#include "ivas_rtp_api.h" +#include "ivas_rtp_pi_data.h" + +typedef struct IVAS_RTP_FILE *IVAS_RTP_FILE_HANDLE; + +typedef struct +{ + uint8_t packet[NOMINAL_BUFFER_SIZE( IVAS_MAX_FRAMES_PER_RTP_PACKET )]; + PIDATA_TS piData[IVAS_PI_MAX_ID * IVAS_MAX_FRAMES_PER_RTP_PACKET]; + + IVAS_RTP_FILE_HANDLE hRtpFile; + FILE *f_piDataOut; + FILE *f_piExtOut; + char piExtFilename[FILENAME_MAX]; + IVAS_RTP_CODEC codecId; + uint32_t nWrittenPiData; + uint32_t nReadPiData; + uint32_t nProcPiData; + uint32_t numFramesInPacket; + uint32_t numPiDataInPacket; + uint32_t remoteRequestBitmap; + bool speechLostIndicated; + bool restartNeeded; + bool isAMRWB_IOmode; + size_t numFramesProduced; + + IVAS_DATA_BUFFER rtpPacket; + IVAS_RTP_PACK_HANDLE hPack; + IVAS_RTP_UNPACK_HANDLE hUnpack; + IVAS_RTP_PACK_CONFIG packCfg; + IVAS_RTP_UNPACK_CONFIG unpackCfg; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + IVAS_RTP_SR_INFO srInfo; +#endif +} IVAS_RTP; + +#ifdef FIXED_RTP_SEQUENCE_NUM +ivas_error IVAS_RTP_WRITER_Init( IVAS_RTP *rtp, const char *outputBitstreamFilename, uint32_t numFramesPerPacket, uint32_t SSRC, uint16_t seqNumInitVal ); +#else +ivas_error IVAS_RTP_WRITER_Init( IVAS_RTP *rtp, const char *outputBitstreamFilename, uint32_t numFramesPerPacket ); +#endif +#ifdef RTP_S4_251135_CR26253_0016_REV1 +ivas_error IVAS_RTP_READER_Init( IVAS_RTP *rtp, uint32_t srCodecFrameSizeMs, const char *inputBitstreamFilename, const char *piOutputFilename, bool isExtOutput, const char *outputWavFilename ); +#else +ivas_error IVAS_RTP_READER_Init( IVAS_RTP *rtp, const char *inputBitstreamFilename, const char *piOutputFilename, bool isExtOutput, const char *outputWavFilename ); +#endif +void IVAS_RTP_Term( IVAS_RTP *rtp ); +#ifdef RTP_S4_251135_CR26253_0016_REV1 +ivas_error IVAS_RTP_WriteNextFrame( IVAS_RTP *rtp, uint8_t *au, const IVAS_RTP_SR_INFO *srInfo, int16_t auSizeBits, bool isMono, bool forcePacket ); +ivas_error IVAS_RTP_ReadNextFrame( IVAS_RTP *rtp, uint8_t *au, int16_t *auSizeBits, uint32_t *rtpTimeStamp, uint16_t *rtpSequenceNumber, uint32_t *nextPacketRcvTime_ms, IVAS_RTP_SR_INFO *srInfo, bool *qBit ); +#else +ivas_error IVAS_RTP_WriteNextFrame( IVAS_RTP *rtp, uint8_t *au, int16_t auSizeBits, bool isMono, bool forcePacket ); +ivas_error IVAS_RTP_ReadNextFrame( IVAS_RTP *rtp, uint8_t *au, int16_t *auSizeBits, uint32_t *rtpTimeStamp, uint16_t *rtpSequenceNumber, uint32_t *nextPacketRcvTime_ms, bool *qBit ); +#endif +void IVAS_RTP_LogPiData( FILE *f_piDataOut, const PIDATA_TS *piData, uint32_t nPiDataPresent ); +void IVAS_RTP_WriteExtPiData( FILE *f_piDataOut, const PIDATA_TS *piData, uint32_t nPiDataPresent, uint16_t numObj ); +const char *IVAS_RTP_GetExtPiFilePath( IVAS_RTP *rtp ); + +#endif /* IVAS_RTP_FILE_H */ diff --git a/lib_util/ivas_rtp_internal.h b/lib_util/ivas_rtp_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..dc3dd9c1292ced08e6e6edd6b2b0b30a8d917fe2 --- /dev/null +++ b/lib_util/ivas_rtp_internal.h @@ -0,0 +1,148 @@ +/****************************************************************************************************** + + (C) 2022-2025 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_RTP_INTERNAL_H +#define IVAS_RTP_INTERNAL_H + +#include "ivas_rtp_api.h" +#include "ivas_rtp_pi_data.h" + +#ifdef IVAS_RTPDUMP + +enum MASK_BITS +{ + MASK_1BIT = 0x1, + MASK_2BIT = 0x3, + MASK_3BIT = 0x7, + MASK_4BIT = 0xF, + MASK_5BIT = 0x1F, + MASK_6BIT = 0x3F, + MASK_7BIT = 0x7F, + MASK_8BIT = 0xFF, + +}; + +/* tables */ +#define NBITS_AEID ( 7 ) +#define NBITS_RT60 ( 5 ) +#define NBITS_DSR ( 6 ) +#define NBITS_DIM ( 4 ) +#define NBITS_ABS ( 2 ) + +#define MASK_AEID ( ( 1u << NBITS_AEID ) - 1 ) +#define MASK_RT60 ( ( 1u << NBITS_RT60 ) - 1 ) +#define MASK_DSR ( ( 1u << NBITS_DSR ) - 1 ) +#define MASK_DIM ( ( 1u << NBITS_DIM ) - 1 ) +#define MASK_ABS ( ( 1u << NBITS_ABS ) - 1 ) + +#define MAX_PI_POSITION_METERS ( 327.68f ) +#define FLOAT_FROM_Q15( q15Val ) ( (float) ( q15Val ) / 32768.0f ) + +extern const float mapDSR[1u << NBITS_DSR]; +extern const float mapRT60[1u << NBITS_RT60]; +extern const float mapRoomDims[1u << NBITS_DIM]; +extern const float mapAbsorbtion[1u << NBITS_ABS]; + +enum IVAS_RTP_HEADER_BITS +{ + + EBYTE_TOC_HEADER_BIT = 0x80, /* Ebyte/ToC indicator H bit, 1 = EByte, 0 = ToC */ + + TOC_HEADER_FOLLOWS = 0x40, /* ToC header byte is followed by another header byte */ + TOC_INDICATE_NO_DATA_AMRWB = 0x3F, /* ToC byte indicates NO_DATA in DTX mode for AMRWB */ + TOC_INDICATE_NO_DATA = 0x0F, /* ToC header byte indicates NO_DATA in DTX mode */ + TOC_INDICATE_IVAS = 0x10, /* ToC header byte indicates IVAS data */ + TOC_INDICATE_EVS = 0x00, /* ToC header byte indicates EVS data */ + TOC_INDICATE_AMRWB = 0x30, /* ToC header byte indicates AMR-WB IO data */ + TOC_INDICATE_ARMWB_Q = 0x20, /* ToC header byte indicates AMR-WB IO lost frame */ + TOC_INDICATE_SR = 0x1E, /* Indicate Split Rendering in ToC bytes */ + + EBYTE_CMR_T_EVS_NB = 0x80, /* Initial E-byte indicating EVS NarrowBand modes */ + EBYTE_CMR_T_EVS_IO = 0x90, /* Initial E-byte indicating EVS AMRWB IO modes */ + EBYTE_CMR_T_EVS_WB = 0xA0, /* Initial E-byte indicating EVS WideBand modes */ + EBYTE_CMR_T_EVS_SWB = 0xB0, /* Initial E-byte indicating EVS SuperWideBand modes */ + EBYTE_CMR_T_EVS_FB = 0xC0, /* Initial E-byte indicating EVS FullBand modes */ + EBYTE_CMR_T_EVS_CA_WB = 0xD0, /* Initial E-byte indicating EVS CA WideBand modes */ + EBYTE_CMR_T_EVS_CA_SWB = 0xE0, /* Initial E-byte indicating EVS CA SuperWideBand modes */ + EBYTE_CMR_T_IVAS = 0xF0, /* Initial E-byte indicating IVAS modes */ + EBYTE_CMR_T_NO_REQ = 0xFF, /* If no bitrate and no CA mode requested for IVAS/EVS */ + +#ifdef RTP_S4_251135_CR26253_0016_REV1 + EBYTE_BANDWIDTH_REQUEST = 0x80, /* Subsequent E-byte for Bandwidth Request */ + EBYTE_FORMAT_REQUEST = 0x90, /* Subsequent E-byte for Format Request */ + EBYTE_SUBFORMAT_REQUEST = 0x9F, /* Subsequent E-byte for SubFormat Request */ + EBYTE_PI_INDICATOR = 0xA0, /* Subsequent E-byte for PI Indicator */ + EBYTE_SR_REQUEST = 0xB0, /* Subsequent E-byte for Split Rendering Request */ +#else + EBYTE_BANDWIDTH_REQUEST = 0x40, /* Subsequent E-byte for Bandwidth Request */ + EBYTE_FORMAT_REQUEST = 0x50, /* Subsequent E-byte for Format Request */ + EBYTE_SUBFORMAT_REQUEST = 0x9F, /* Subsequent E-byte for SubFormat Request */ + EBYTE_PI_INDICATOR = 0x60, /* Subsequent E-byte for PI Indicator */ + EBYTE_SR_REQUEST = 0x70, /* Subsequent E-byte for Split Rendering Request */ +#endif + + PI_HEADER_PF_LAST = 0x00, /* Last PI header of the Payload in PI Header */ + PI_HEADER_PF_NOT_LAST = 0x80, /* Another PI header follows after this in PI Header */ + PI_HEADER_PM_NOT_LAST = 0x20, /* PI Frame Marker, not the last PI Header in current frame */ + PI_HEADER_PM_LAST = 0x40, /* PI Frame Marker, the last PI Header in current frame */ + PI_HEADER_PM_GENERIC = 0x60, /* PI Frame Marker, Generic applied to all frames */ + + PI_AD_SPEECH_INDICATED = 0x80, /* Audio Description indicate Speech in Audio data */ + PI_AD_MUSIC_INDICATED = 0x40, /* Audio Description indicate Misuc in Audio data */ + PI_AD_AMBIANCE_INDICATED = 0x20, /* Audio Description indicate Ambiance in Audio data */ + PI_AD_EDITABLE_INDICATED = 0x10, /* Audio Description indicate metadata is editable */ + PI_AD_BINAURAL_INDICATED = 0x8, /* Audio Description indicate Stereo stream in Binaural */ + +}; + + +#define ERR_CHECK_RETURN( err ) \ + { \ + if ( ( err ) != IVAS_ERR_OK ) \ + { \ + return ( err ); \ + } \ + } + + +typedef struct +{ + uint32_t size; + uint8_t data[IVAS_PI_MAX_DATA_SIZE]; +} PIDATA_PACKED; + +ivas_error PI_PackData( const IVAS_PIDATA_GENERIC *piData, PIDATA_PACKED *packed, uint8_t pmBits ); +ivas_error PI_UnPackData( uint8_t piDataType, uint32_t piSize, const uint8_t *piDataBuffer, IVAS_PIDATA_GENERIC *piData ); + +#endif /* IVAS_RTPDUMP */ + +#endif /* IVAS_RTP_INTERNAL_H */ diff --git a/lib_util/ivas_rtp_payload.c b/lib_util/ivas_rtp_payload.c new file mode 100644 index 0000000000000000000000000000000000000000..98846adf847ea0b9cd930dd35ee18abd03f14564 --- /dev/null +++ b/lib_util/ivas_rtp_payload.c @@ -0,0 +1,1884 @@ +/****************************************************************************************************** + + (C) 2022-2025 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 +#include +#ifndef FIXED_RTP_SEQUENCE_NUM +#include +#endif +#include "common_api_types.h" + +#ifdef IVAS_RTPDUMP + +#include "ivas_rtp_internal.h" +#include "ivas_bpool.h" +#include "ivas_queue.h" +#include "ivas_error_utils.h" +#include "mutex.h" + +#define IVAS_MAX_BYTES_PER_FRAME ( ( IVAS_MAX_BITS_PER_FRAME + 7 ) >> 3 ) +#define MAX_TOC_PER_FRAME ( 2u ) /* Main ToC Byte + SR-ToC byte */ + +/* Generic RTP Header + Header Extension data structure */ +typedef struct +{ + uint32_t ssrc; /* synchronization source id as negotiated in SDP */ + uint8_t version; /* version of RTP protocol, currently 2 */ + bool padding; /* false = no padding, true = zeoo padded payload (last byte = padding count) */ + bool extension; /* true = extension header is present before payload */ + uint8_t CC; /* if some streams mixed together, CC indicates no. of contributing sources (4 bits) */ + bool marker; /* Marker bit field */ + uint8_t payloadType; /* 7-bit payload type field indicating IVAS */ + uint16_t seqNumber; /* 16-bit sequence number for RTP packets */ + uint32_t timestamp; /* timer ticks @ 16KHz clock corrsponding to 1st frame in the Payload */ + uint32_t CSRC[15]; /* SSRC of contributing Sources for a mixed stream */ + uint16_t extHeaderId; /* extension header ID */ + uint16_t numExtUnits; /* length of the extension data in 32-bit words */ + uint8_t *extData; /* Extension data pointer */ +} RTP_HEADER; + +typedef struct +{ + PIDATA_PACKED piData[IVAS_PI_MAX_ID]; /* pi data per frame */ + uint32_t piDataBitmap; /* bitmap showing available pi */ + uint32_t numPiDataAvailable; /* number of pi data available */ +} PIDATA_FRAME; + +static void initRequests( IVAS_RTP_REQUEST_VALUE *requests ) +{ + requests[IVAS_REQUEST_CODEC].codec = IVAS_RTP_IVAS; + requests[IVAS_REQUEST_BITRATE].bitrate = 0; + requests[IVAS_REQUEST_BANDWIDTH].bandwidth = IVAS_BANDWIDTH_NO_REQ; + requests[IVAS_REQUEST_FORMAT].formatType = IVAS_FMT_NO_REQ; + requests[IVAS_REQUEST_CA_MODE].caMode = IVAS_RTP_CA_NO_REQ; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + requests[IVAS_REQUEST_SUBFORMAT].subFormatType = IVAS_SUBFMT_NO_REQ; + requests[IVAS_REQUEST_SR_CONFIG].srConfig.valid = false; +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ +} + +static void initPiDataFrame( PIDATA_FRAME *piDataFrm ) +{ + /* Add NO_PI_DATA by default */ + piDataFrm->numPiDataAvailable = 1; + piDataFrm->piDataBitmap = ( 1u << IVAS_PI_NO_DATA ); + piDataFrm->piData[IVAS_PI_NO_DATA].size = 2; + piDataFrm->piData[IVAS_PI_NO_DATA].data[0] = ( IVAS_PI_NO_DATA ); /* PF/PM populated during final packing */ + piDataFrm->piData[IVAS_PI_NO_DATA].data[1] = 0; /* NO_PI_DATA is 0 bytes */ +} + +typedef struct FRAME_NODE +{ + struct FRAME_NODE *next; /* next node */ + PIDATA_FRAME piDataFrame; /* PI data for this frame */ + uint8_t au[IVAS_MAX_BYTES_PER_FRAME]; /* ivas/evs packed frame (AU) */ + uint8_t toc[MAX_TOC_PER_FRAME]; /* ToC bytes for this frame */ + uint32_t auNumBits; /* Actual frame size in bits */ + uint32_t tocNumBytes; /* valid ToC bytes (1 or 2) */ +} FRAME_NODE; + +static void initFrameNode( FRAME_NODE *node ) +{ + node->next = NULL; + initPiDataFrame( &node->piDataFrame ); + node->auNumBits = 0; + node->tocNumBytes = 0; +} + +struct IVAS_RTP_PACK +{ + mtx_t apilock; /* Lock to handle concurrent API invocation */ + bool amrwbIOMode; /* If EVS is an AMRWB-IO mode frame */ + RTP_HEADER header; /* RTP Header Params */ + BPOOL_HANDLE packNodePool; /* Buffer pool to allocate FRAME_NODEs */ + PIDATA_FRAME piDataCache; /* temporary cache for PI data pushed before any frame is available in Queue */ + IVAS_RTP_PACK_CONFIG initConfig; /* Initial Configuration for Unpacker */ + IVAS_RTP_REQUEST_VALUE requests[IVAS_REQUEST_MAX]; /* Requests Storage */ + QUEUE_HANDLE frameQ; /* frames queue for FRAME_NODEs */ +}; + +typedef struct +{ + IVAS_RTP_CODEC codecId; /* Coded frame type (IVAS/EVS) */ + uint32_t auNumBits; /* Actual frame size in bits */ + bool speechLostIndicated; /* Speech Lost indicated */ + bool isAMRWB_IOmode; /* EVS frame is AMRWB_IO */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + IVAS_RTP_SR_INFO srInfo; /* Split Rendering Info */ +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ +} TOC_INFO; + +typedef struct PIDATA_NODE +{ + struct PIDATA_NODE *next; /* next node is first element */ + PIDATA data; /* unpacked pi data per frame */ + uint32_t timestamp; /* rtp timestamp of this frame */ +} PIDATA_NODE; + +typedef struct UNPACK_NODE +{ + struct UNPACK_NODE *next; /* next node is first element */ + uint8_t au[IVAS_MAX_BYTES_PER_FRAME]; /* ivas/evs packed frame (AU) */ + TOC_INFO toc; /* unpacked ToC information */ + uint32_t timestamp; /* timestamp of this frame */ + uint16_t seqNumber; /* sequence number of the packet */ +} UNPACK_NODE; + +struct IVAS_RTP_UNPACK +{ + mtx_t apilock; /* Lock to handle concurrent API invocation */ + size_t maxNumberOfFrames; + size_t maxNumberOfPiData; + RTP_HEADER header; + BPOOL_HANDLE unpackNodePool; + BPOOL_HANDLE piDataPool; + IVAS_RTP_UNPACK_CONFIG initConfig; + IVAS_RTP_REQUEST_VALUE requests[IVAS_REQUEST_MAX]; + uint32_t numPiDataAvailable; /* number of pi data available */ + QUEUE_HANDLE frameQ; /* frame queue */ + QUEUE_HANDLE piDataQ; /* pi data queue */ +}; + +static const uint32_t ivasFrameSizeInBits[] = { + 264, 328, 488, 640, 960, 1280, 1600, 1920, 2560, 3200, 3840, 5120, 7680, 10240, 0, 104 +}; + +static const uint32_t evsFrameSizeInBits[] = { + 56, 144, 160, 192, 264, 328, 488, 640, 960, 1280, 1920, 2560, 48 +}; + +static const uint32_t amrWBIOFrameSizeInBits[] = { + 132, 177, 253, 285, 317, 365, 397, 461, 477, 35 +}; + + +/* Update the RTP Header structure */ +ivas_error IVAS_RTP_PACK_UpdateHeader( + IVAS_RTP_PACK_HANDLE hPack, /* i/o: pointer to an IVAS rtp packer handle to be opened */ +#ifdef FIXED_RTP_SEQUENCE_NUM + uint16_t seqNumInitVal, /* i : Initial sequence number to be used for 1st packet */ +#endif + uint32_t ssrc, /* i : Unique 32-bit Source ID as negotiated during SDP */ + uint8_t numCC, /* i : numCC indicates no. of contributing sources */ + uint32_t *csrc, /* i : SSRCs of contributing Sources for a mixed stream */ + uint16_t extHeaderId, /* i : extension header ID */ + uint16_t numExtensionBytes, /* i : length of the extension data */ + uint8_t *extData /* i : extension data pointer */ +) +{ + RTP_HEADER *header = &hPack->header; + + if ( numCC > 15 ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "CC must be less than 16" ); + } + +#ifdef FIXED_RTP_SEQUENCE_NUM + header->seqNumber = seqNumInitVal; +#endif + header->ssrc = ssrc; + header->CC = numCC; + if ( csrc != NULL ) + { + memcpy( header->CSRC, csrc, numCC & 0xF ); + } + + if ( ( numExtensionBytes > 0 ) && ( extData != NULL ) ) + { + header->extHeaderId = extHeaderId; + header->extData = realloc( header->extData, numExtensionBytes ); + if ( header->extData == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "failed to allocate extdata" ); + } + memcpy( header->extData, extData, numExtensionBytes ); + header->extension = true; + header->numExtUnits = numExtensionBytes / sizeof( uint32_t ); + } + else + { + header->numExtUnits = 0; + header->extension = false; + } + + return IVAS_ERR_OK; +} + +static void InitRtpHeader( + RTP_HEADER *header /* RTP header structure */ +) +{ +#ifdef FIXED_RTP_SEQUENCE_NUM + memset( header, 0, sizeof( *header ) ); + header->version = 2; +#else + time_t t; + memset( header, 0, sizeof( *header ) ); + srand( (uint32_t) time( &t ) ); + header->version = 2; + header->seqNumber = rand() & 0xFFFF; +#endif +} + +static ivas_error PackRtpHeader( + RTP_HEADER *header, + IVAS_DATA_BUFFER *buf ) +{ + uint32_t nBytes = 0; + uint8_t CC = header->CC & MASK_4BIT; + uint32_t *CSRC = header->CSRC; + bool extension = header->extension && ( NULL != header->extData ); + uint32_t extensionLength = header->extension ? ( 1 + header->numExtUnits ) : 0; /* in u32 words */ + uint32_t packedLength = 12 + ( 4 * CC ) + ( 4 * extensionLength ); + + buf->length = 0; + if ( packedLength > buf->capacity ) + { + return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient output buffer for RTP header packing" ); + } + + /* + +---+---+---+---+---+---+---+---+ + | V | V | P | X | CC (4 - bits) | + +---+---+---+---+---+---+---+---+ + */ + buf->buffer[nBytes++] = ( header->version << 6 ) | + ( (uint8_t) header->padding << 5 ) | + ( (uint8_t) extension << 4 ) | + CC; + /* + +---+---+---+---+---+---+---+---+ + | M | PT (7 - bits) | + +---+---+---+---+---+---+---+---+ + */ + buf->buffer[nBytes++] = ( (uint8_t) header->marker << 7 ) | + ( header->payloadType & MASK_7BIT ); + /* + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | SEQUENCE NUMBER (16 bit) | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + */ + buf->buffer[nBytes++] = (uint8_t) ( header->seqNumber >> 8 ); + buf->buffer[nBytes++] = (uint8_t) ( header->seqNumber ); + + /* Timestamp (32-bit) */ + buf->buffer[nBytes++] = (uint8_t) ( header->timestamp >> 24 ); + buf->buffer[nBytes++] = (uint8_t) ( header->timestamp >> 16 ); + buf->buffer[nBytes++] = (uint8_t) ( header->timestamp >> 8 ); + buf->buffer[nBytes++] = (uint8_t) ( header->timestamp >> 0 ); + + /* SSRC (32-bit) */ + buf->buffer[nBytes++] = (uint8_t) ( header->ssrc >> 24 ); + buf->buffer[nBytes++] = (uint8_t) ( header->ssrc >> 16 ); + buf->buffer[nBytes++] = (uint8_t) ( header->ssrc >> 8 ); + buf->buffer[nBytes++] = (uint8_t) ( header->ssrc >> 0 ); + + /* CSRC Identifiers */ + while ( CC ) + { + /* CSRC[n] (32-bit) */ + uint32_t id = *CSRC++; + buf->buffer[nBytes++] = (uint8_t) ( id >> 24 ); + buf->buffer[nBytes++] = (uint8_t) ( id >> 16 ); + buf->buffer[nBytes++] = (uint8_t) ( id >> 8 ); + buf->buffer[nBytes++] = (uint8_t) ( id >> 0 ); + CC--; + } + + if ( extension ) + { + buf->buffer[nBytes++] = (uint8_t) ( header->extHeaderId >> 8 ); + buf->buffer[nBytes++] = (uint8_t) ( header->extHeaderId >> 0 ); + buf->buffer[nBytes++] = (uint8_t) ( header->numExtUnits >> 8 ); + buf->buffer[nBytes++] = (uint8_t) ( header->numExtUnits >> 0 ); + + memcpy( &buf->buffer[nBytes], header->extData, header->numExtUnits * 4 ); + nBytes += header->numExtUnits; + } + + buf->length = nBytes; + return IVAS_ERR_OK; +} + +static void UpdateRtpHeader( + RTP_HEADER *header, /* RTP header structure */ + uint32_t timestampOffset /* Timestamp offset @ 16KHz clock for next frame */ +) +{ + header->seqNumber++; + header->timestamp += timestampOffset; +} + +static ivas_error UnpackRtpPacket( + const IVAS_DATA_BUFFER *packet, /* Input buffer with RTP Packet */ + RTP_HEADER *header, /* RTP header structure */ + uint32_t *numHeaderBytes /* No. of rtp header bytes */ +) +{ + uint32_t n = 0, nByte = 0, expectedSize = 12; + uint8_t byte; + + if ( packet->length < expectedSize ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNDERFLOW, "Insufficient input buffer for RTP header unpacking" ); + } + + /* + +---+---+---+---+---+---+---+---+ + | V | V | P | X | CC (4 - bits) | + +---+---+---+---+---+---+---+---+ + */ + byte = packet->buffer[nByte++]; + header->version = ( byte >> 6 ) & MASK_2BIT; + header->padding = ( byte >> 5 ) & MASK_1BIT; + header->extension = ( byte >> 4 ) & MASK_1BIT; + header->CC = ( byte & MASK_4BIT ); + + /* + +---+---+---+---+---+---+---+---+ + | M | PT (7 - bits) | + +---+---+---+---+---+---+---+---+ + */ + byte = packet->buffer[nByte++]; + header->marker = ( byte >> 7 ) & MASK_1BIT; + header->payloadType = byte & MASK_7BIT; + + /* + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + | SEQUENCE NUMBER (16 bit) | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + */ + header->seqNumber = (uint16_t) packet->buffer[nByte++] << 8; + header->seqNumber |= (uint16_t) packet->buffer[nByte++] << 8; + + /* Timestamp (32-bit) */ + header->timestamp = ( (uint32_t) packet->buffer[nByte++] << 24 ); + header->timestamp |= ( (uint32_t) packet->buffer[nByte++] << 16 ); + header->timestamp |= ( (uint32_t) packet->buffer[nByte++] << 8 ); + header->timestamp |= ( (uint32_t) packet->buffer[nByte++] ); + + /* SSRC (32-bit) */ + header->ssrc = ( (uint32_t) packet->buffer[nByte++] << 24 ); + header->ssrc |= ( (uint32_t) packet->buffer[nByte++] << 16 ); + header->ssrc |= ( (uint32_t) packet->buffer[nByte++] << 8 ); + header->ssrc |= ( (uint32_t) packet->buffer[nByte++] ); + + expectedSize += ( header->CC ) * 4 + ( header->extension ? 4 : 0 ); + if ( packet->length < expectedSize ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNDERFLOW, "CC indicated but insufficient input buffer" ); + } + + /* CSRC Identifiers */ + for ( n = 0; n < header->CC; n++ ) + { + /* CSRC[n] (32-bit) */ + header->CSRC[n] = ( (uint32_t) packet->buffer[nByte++] << 24 ); + header->CSRC[n] |= ( (uint32_t) packet->buffer[nByte++] << 16 ); + header->CSRC[n] |= ( (uint32_t) packet->buffer[nByte++] << 8 ); + header->CSRC[n] |= ( (uint32_t) packet->buffer[nByte++] ); + } + + if ( header->extension ) + { + header->extHeaderId = ( (uint32_t) packet->buffer[nByte++] << 8 ); + header->extHeaderId |= ( (uint32_t) packet->buffer[nByte++] ); + header->numExtUnits = ( (uint32_t) packet->buffer[nByte++] << 8 ); + header->numExtUnits |= ( (uint32_t) packet->buffer[nByte++] ); + + expectedSize += header->numExtUnits * 4; + if ( packet->length < expectedSize ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNDERFLOW, "Extension Header indicated but insufficient input buffer" ); + } + + header->extData = realloc( header->extData, header->numExtUnits * 4 ); + if ( header->extData == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "failed to allocate extdata" ); + } + memcpy( header->extData, &packet->buffer[nByte], header->numExtUnits * 4 ); + nByte += header->numExtUnits * 4; + } + + *numHeaderBytes = nByte; + return IVAS_ERR_OK; +} + +static ivas_error getBitrateFromCodecAndFrameSize( + IVAS_RTP_CODEC codecId, + uint32_t frameLengthBytes, + uint32_t *bitrateKbps, + uint32_t *frameLenInBits, + uint8_t *tocByte, + bool *isAmrwbIOMode ) +{ + size_t n; + *bitrateKbps = 0; + *frameLenInBits = 0; + if ( codecId == IVAS_RTP_IVAS ) + { + /* Validate the framelength is supported for ivas frame */ + for ( n = 0; n < sizeof( ivasFrameSizeInBits ) / sizeof( ivasFrameSizeInBits[0] ); n++ ) + { + if ( ivasFrameSizeInBits[n] == frameLengthBytes * 8 ) + { + *bitrateKbps = ( frameLengthBytes * IVAS_NUM_FRAMES_PER_SEC * 8 ); /* bitrate in kbps */ + *frameLenInBits = frameLengthBytes * 8; /* frame length in bits */ + *tocByte = TOC_INDICATE_IVAS | ( n & MASK_4BIT ); /* bitrate index */ + return IVAS_ERR_OK; + } + } + return IVAS_ERR_INVALID_BITRATE; + } + else + { + /* Try if frameLength is a supported EVS frame length */ + for ( n = 0; n < sizeof( evsFrameSizeInBits ) / sizeof( evsFrameSizeInBits[0] ); n++ ) + { + if ( evsFrameSizeInBits[n] == frameLengthBytes * 8 ) + { + *bitrateKbps = ( frameLengthBytes * IVAS_NUM_FRAMES_PER_SEC * 8 ); /* bitrate in kbps */ + *frameLenInBits = frameLengthBytes * 8; /* frame length in bits */ + *tocByte = TOC_INDICATE_EVS | ( n & MASK_4BIT ); /* bitrate index */ + return IVAS_ERR_OK; + } + } + /* Try if frameLength is a supported AMRWB-IO frame length */ + for ( n = 0; n < sizeof( amrWBIOFrameSizeInBits ) / sizeof( amrWBIOFrameSizeInBits[0] ); n++ ) + { + uint32_t lengthInBits = amrWBIOFrameSizeInBits[n]; + if ( ( ( lengthInBits + 7 ) / 8 ) == frameLengthBytes ) + { + *isAmrwbIOMode = true; + *bitrateKbps = ( lengthInBits * IVAS_NUM_FRAMES_PER_SEC ); /* bitrate in kbps */ + *frameLenInBits = lengthInBits; /* frame length in bits */ + *tocByte = TOC_INDICATE_AMRWB | ( n & MASK_4BIT ); /* bitrate index */ + return IVAS_ERR_OK; + } + } + return IVAS_ERR_INVALID_BITRATE; + } +} + +ivas_error IVAS_RTP_PACK_Open( + IVAS_RTP_PACK_HANDLE *phPack, /* i/o: pointer to an IVAS rtp packer handle to be opened */ + const IVAS_RTP_PACK_CONFIG *config /* i : pointer to initial config for RTP Packer */ +) +{ + ivas_error error; + IVAS_RTP_PACK_HANDLE hPack; + uint32_t numFramesPerPacket = ( config->maxFramesPerPacket == 0 ) ? IVAS_MAX_FRAMES_PER_RTP_PACKET : config->maxFramesPerPacket; + + if ( phPack == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( numFramesPerPacket > IVAS_MAX_FRAMES_PER_RTP_PACKET ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Max frame per packet exeeds %d", IVAS_MAX_FRAMES_PER_RTP_PACKET ); + } + + *phPack = NULL; + if ( ( hPack = (IVAS_RTP_PACK_HANDLE) calloc( 1, sizeof( struct IVAS_RTP_PACK ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS rtppack handle" ); + } + + error = BPOOL_Create( &hPack->packNodePool, sizeof( FRAME_NODE ), numFramesPerPacket * 4 ); + ERR_CHECK_RETURN( error ); + + error = QUEUE_Create( &hPack->frameQ ); + ERR_CHECK_RETURN( error ); + + mtx_init( &hPack->apilock, 0 ); + hPack->initConfig = *config; + initRequests( hPack->requests ); + InitRtpHeader( &hPack->header ); + initPiDataFrame( &hPack->piDataCache ); + *phPack = hPack; + return IVAS_ERR_OK; +} + +/* Close and free an existing instance of rtp packer */ +void IVAS_RTP_PACK_Close( + IVAS_RTP_PACK_HANDLE *phPack /* i/o : pointer to an IVAS rtp packer handle to be closed */ +) +{ + IVAS_RTP_PACK_HANDLE hPack; + + /* Free all memory */ + if ( phPack == NULL || *phPack == NULL ) + { + return; + } + + hPack = *phPack; + QUEUE_Destroy( &hPack->frameQ ); + mtx_destroy( &hPack->apilock ); + BPOOL_Destroy( &hPack->packNodePool ); + free( hPack->header.extData ); + free( hPack ); + *phPack = NULL; +} + +ivas_error IVAS_RTP_PACK_PushRemoteRequest( + IVAS_RTP_PACK_HANDLE hPack, /* i/o : IVAS rtp packer handle */ + IVAS_RTP_REQUEST_TYPE reqType, /* i : remote request type */ + IVAS_RTP_REQUEST_VALUE reqValue /* i : value of the requested type */ +) +{ + if ( reqType < 0 || reqType >= IVAS_REQUEST_MAX ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid request key provided" ); + } + + /* Sanity on API */ + switch ( reqType ) + { + case IVAS_REQUEST_CODEC: + { + uint32_t codec = reqValue.codec; + if ( codec != IVAS_RTP_IVAS && codec != IVAS_RTP_EVS ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Unsupported codec id provided" ); + } + } + break; + case IVAS_REQUEST_BITRATE: + { + uint32_t bitrate = reqValue.bitrate; + if ( bitrate < 5900 || bitrate > 512000 ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Unsupported bitrate provided" ); + } + } + break; + case IVAS_REQUEST_BANDWIDTH: + { + uint32_t bandwidth = reqValue.bandwidth; + if ( bandwidth > IVAS_BANDWIDTH_NO_REQ ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Unsupported bandwidth provided" ); + } + } + break; + case IVAS_REQUEST_FORMAT: + { + uint32_t format = reqValue.formatType; + if ( format > IVAS_FMT_NO_REQ ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Unsupported format provided" ); + } + } + break; + case IVAS_REQUEST_CA_MODE: + { + uint32_t caMode = reqValue.caMode; + if ( caMode > IVAS_RTP_CA_NO_REQ ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Unsupported channel aware mode provided" ); + } + } + break; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + case IVAS_REQUEST_SUBFORMAT: + { + uint32_t subFormat = reqValue.subFormatType; + if ( subFormat > IVAS_SUBFMT_NO_REQ ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Unsupported subformat provided" ); + } + } + break; + case IVAS_REQUEST_SR_CONFIG: + { + IVAS_RTP_SPLITRENDER srConfig = reqValue.srConfig; + if ( srConfig.reserved != 0 ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Unsupported reserved bits in SR config provided" ); + } + } + break; +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ + default: + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Unsupported request type" ); + } + + hPack->requests[reqType] = reqValue; + + return IVAS_ERR_OK; +} + +static bool isAmrWBIOMode( uint32_t bitrate, uint32_t *idx ) +{ + size_t n; + *idx = 0; + for ( n = 0; n < sizeof( amrWBIOFrameSizeInBits ) / sizeof( amrWBIOFrameSizeInBits[0] ); n++ ) + { + if ( bitrate == ( amrWBIOFrameSizeInBits[n] * IVAS_NUM_FRAMES_PER_SEC ) ) + { + *idx = n; + return true; + } + } + return false; +} + +static uint32_t getBitrateIdx( const uint32_t *table, uint32_t tableLen, uint32_t bitrate ) +{ + size_t n, idx = 0; + + for ( n = 0; n < tableLen; n++ ) + { + if ( bitrate > ( table[n] * IVAS_NUM_FRAMES_PER_SEC ) ) + { + idx = n; + } + else + { + return idx; + } + } + return idx; +} + +static void packEBytes( + IVAS_RTP_PACK_HANDLE hPack, /* i/o : IVAS rtp packer handle */ + bool piDataPresent, /* i : Signals if PI data present */ + size_t maxNumEBytes, /* i : max capacity of eByte buffer */ + uint8_t *eByte, /* o : output buffer for E-Bytes */ + size_t *nBytesWritten /* o : max capacity of eByte buffer */ +) +{ + /* Initial E-byte structure + * 0 1 2 3 4 5 6 7 + * +-+-+-+-+-+-+-+-+ + * |H|T|T|T| BR | + * +-+-+-+-+-+-+-+-+ + */ + uint32_t nByte = 0; + uint8_t T = EBYTE_CMR_T_IVAS; /* IVAS */ + uint8_t BR = 0; + + IVAS_RTP_CODEC codec = hPack->requests[IVAS_REQUEST_CODEC].codec; + IVAS_RTP_BANDWIDTH bandwidth = hPack->requests[IVAS_REQUEST_BANDWIDTH].bandwidth; + uint32_t bitrate = hPack->requests[IVAS_REQUEST_BITRATE].bitrate; + uint32_t bitrateIdx = 0; + + *nBytesWritten = 0; + + if ( codec == IVAS_RTP_EVS ) + { + /* If requesting EVS/AMRWB IO from farend, only Initial E-byte present */ + IVAS_RTP_CA_MODE caMode = hPack->requests[IVAS_REQUEST_CA_MODE].caMode; + + if ( caMode != IVAS_RTP_CA_NO_REQ ) + { + T = ( bandwidth == IVAS_BANDWIDTH_SWB ) ? EBYTE_CMR_T_EVS_CA_SWB : EBYTE_CMR_T_EVS_CA_WB; + BR = caMode & MASK_3BIT; /* only 8 valid values */ + if ( nByte < maxNumEBytes ) + { + eByte[nByte++] = ( T | BR ); + } + } + else if ( bitrate > 0 && isAmrWBIOMode( bitrate, &bitrateIdx ) ) + { + /* AMR WB IO Mode */ + T = EBYTE_CMR_T_EVS_IO; + BR = (uint8_t) bitrateIdx & MASK_4BIT; + if ( nByte < maxNumEBytes ) + { + eByte[nByte++] = ( T | BR ); + } + } + else if ( bitrate > 0 ) + { + /* EVS Modes */ + bitrate = ( bitrate > 128000 ) ? 128000 : bitrate; + bitrate = ( bitrate < 5900 ) ? 5900 : bitrate; + bitrateIdx = getBitrateIdx( evsFrameSizeInBits, sizeof( evsFrameSizeInBits ) / sizeof( evsFrameSizeInBits[0] ), bitrate ); + BR = (uint8_t) bitrateIdx & MASK_4BIT; + + /* If a bandwidth choice cannot be signalled for a given bitrate + preference is given to bitrate choice, bandwidth req is modified */ + switch ( bandwidth ) + { + case IVAS_BANDWIDTH_NB: + T = ( bitrate <= 24400u ) ? EBYTE_CMR_T_EVS_NB : EBYTE_CMR_T_EVS_SWB; + break; + case IVAS_BANDWIDTH_WB: + T = EBYTE_CMR_T_EVS_WB; + break; + case IVAS_BANDWIDTH_SWB: + T = ( bitrate >= 9600u ) ? EBYTE_CMR_T_EVS_SWB : EBYTE_CMR_T_EVS_WB; + break; + case IVAS_BANDWIDTH_FB: + T = ( bitrate >= 16400u ) ? EBYTE_CMR_T_EVS_FB : EBYTE_CMR_T_EVS_WB; + break; + default: /*IVAS_BANDWIDTH_NO_REQ */ + T = ( bitrate >= 9600u ) ? EBYTE_CMR_T_EVS_SWB : EBYTE_CMR_T_EVS_WB; + break; + } + if ( nByte < maxNumEBytes ) + { + eByte[nByte++] = ( T | BR ); + } + } + else if ( piDataPresent ) + { + /* Send an initial E-byte to allow for subsequent PI indication E-byte */ + if ( nByte < maxNumEBytes ) + { + eByte[nByte++] = EBYTE_CMR_T_NO_REQ; + } + } + } + else + { + /* Requesting IVAS from farend, Subsequent E-byte indicate BW, CFR, SR */ + IVAS_RTP_FORMAT format = hPack->requests[IVAS_REQUEST_FORMAT].formatType; + bool isBandwidthProvided = ( bandwidth != IVAS_BANDWIDTH_NO_REQ && bandwidth != IVAS_BANDWIDTH_NB ); + bool isFormatProvided = ( format != IVAS_FMT_NO_REQ ); + bool isSubFormatProvided = false; + bool isSRConfigProvided = false; + +#ifdef RTP_S4_251135_CR26253_0016_REV1 + IVAS_RTP_SUBFORMAT subFormat = hPack->requests[IVAS_REQUEST_SUBFORMAT].subFormatType; + IVAS_RTP_SPLITRENDER srConfig = hPack->requests[IVAS_REQUEST_SR_CONFIG].srConfig; + + isSubFormatProvided = ( subFormat != IVAS_SUBFMT_NO_REQ ); + isSRConfigProvided = srConfig.valid; +#endif + + /* Initial E-Byte only sent if either bitrate requested or subsequent E-byte is requested */ + if ( !( ( bitrate > 0 ) || isBandwidthProvided || isFormatProvided || + isSubFormatProvided || isSRConfigProvided || piDataPresent ) ) + { + return; + } + + if ( bitrate > 0 ) + { + /* Initial E-Byte */ + bitrate = ( bitrate > 512000 ) ? 512000 : bitrate; + bitrate = ( bitrate < 13200 ) ? 13200 : bitrate; + bitrateIdx = getBitrateIdx( ivasFrameSizeInBits, sizeof( ivasFrameSizeInBits ) / sizeof( ivasFrameSizeInBits[0] ), bitrate ); + BR = (uint8_t) bitrateIdx & MASK_4BIT; + if ( nByte < maxNumEBytes ) + { + eByte[nByte++] = ( EBYTE_CMR_T_IVAS | BR ); + } + } + else + { + if ( nByte < maxNumEBytes ) + { + eByte[nByte++] = EBYTE_CMR_T_NO_REQ; + } + } + + /* Subsequent E-bytes - Bandwidth Request */ + if ( isBandwidthProvided && nByte < maxNumEBytes ) + { + uint8_t bw = ( bandwidth - IVAS_BANDWIDTH_WB ) & MASK_2BIT; + eByte[nByte++] = ( EBYTE_BANDWIDTH_REQUEST | bw ); + } + + /* Subsequent E-bytes - Coded Format Request */ + if ( ( isFormatProvided || isSubFormatProvided ) && nByte < maxNumEBytes ) + { + uint8_t fmtEByte = ( EBYTE_FORMAT_REQUEST | ( (uint8_t) format & MASK_3BIT ) ); + eByte[nByte++] = isSubFormatProvided ? EBYTE_SUBFORMAT_REQUEST : fmtEByte; + } +#ifdef RTP_S4_251135_CR26253_0016_REV1 + if ( isSubFormatProvided && nByte < maxNumEBytes ) + { + eByte[nByte++] = ( (uint8_t) subFormat & MASK_6BIT ); /* Requested Coded subFormat */ + } + /* Subsequent E-bytes - Split Renderer Configuration Request */ + if ( isSRConfigProvided && nByte < maxNumEBytes ) + { + eByte[nByte++] = EBYTE_SR_REQUEST | + ( (uint8_t) srConfig.diegetic << 3 ) | ( (uint8_t) srConfig.yaw << 2 ) | + ( (uint8_t) srConfig.pitch << 1 ) | ( (uint8_t) srConfig.roll << 0 ); + } +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ + } + + /* Final E-byte is the PI Indicator E-Byte */ + if ( piDataPresent && ( nByte < maxNumEBytes ) ) + { + eByte[nByte++] = EBYTE_PI_INDICATOR; /* PI Indication */ + } + + *nBytesWritten = nByte; +} + + +#ifdef RTP_S4_251135_CR26253_0016_REV1 +static ivas_error getSRToCByte( + const IVAS_RTP_SR_INFO *srInfo, /* i : Split Rendering Info */ + uint8_t *tocByte /* o : toc byte 2 */ +) +{ + uint8_t bitIdx, codecId, digetic; + if ( srInfo->bitrateKbps < 256000 || srInfo->bitrateKbps > 512000 ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Unsupported bitrate for SR" ); + } + + bitIdx = ( ( srInfo->bitrateKbps / 128000u ) - 1 ) & MASK_2BIT; + codecId = (uint8_t) srInfo->codec; + digetic = srInfo->diegetic ? 1 : 0; + + *tocByte = ( digetic << 6 ) | ( codecId << 5 ) | ( bitIdx << 3 ); + + return IVAS_ERR_OK; +} +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ + +static void addPackedPiDataToFrame( PIDATA_FRAME *piDataFrm, const PIDATA_PACKED *packedPiData, uint32_t piDataType ) +{ + piDataFrm->piData[piDataType].size = packedPiData->size; + memcpy( piDataFrm->piData[piDataType].data, packedPiData->data, packedPiData->size ); + + /* Indicate th PI data type presense in bitmap, If the same pi data type is + already pushed for this frame, it is overwritten with the newer data */ + if ( !( piDataFrm->piDataBitmap & ( 1u << piDataType ) ) ) + { + piDataFrm->piDataBitmap |= ( 1u << piDataType ); + piDataFrm->numPiDataAvailable++; + } + + /* Atleast one valid PI data is now pushed for this frame, clear No PI data + for this frame */ + if ( piDataFrm->piDataBitmap & ( 1u << IVAS_PI_NO_DATA ) ) + { + piDataFrm->piDataBitmap &= ~( 1u << IVAS_PI_NO_DATA ); + piDataFrm->numPiDataAvailable--; + } +} + +ivas_error IVAS_RTP_PACK_PushFrame( + IVAS_RTP_PACK_HANDLE hPack, /* i/o : IVAS rtp packer handle */ + IVAS_RTP_CODEC codecId, /* i : Codec type (IVAS/EVS) */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + const IVAS_RTP_SR_INFO *srInfo, /* i : Split Rendering Info */ +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ + const IVAS_DATA_BUFFER *frameBuffer /* i : packed frame bitstream for IVAS/EVS */ +) +{ + ivas_error error = IVAS_ERR_OK; + uint32_t bitrate = 0; + uint32_t frameLengthInBits = 0; + uint8_t tocByte = 0; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + uint8_t tocByte1 = 0; +#endif + FRAME_NODE *node = NULL; + PIDATA_FRAME *piDataFrame = &hPack->piDataCache; + uint32_t piDataType = 0; + + if ( frameBuffer == NULL || frameBuffer->length == 0 ) + { + /* Indicates a NO_DATA_FRAME in case of DTX mode */ + tocByte = ( hPack->amrwbIOMode ) ? TOC_INDICATE_NO_DATA_AMRWB : TOC_INDICATE_NO_DATA; + } +#ifdef RTP_S4_251135_CR26253_0016_REV1 + else if ( srInfo != NULL && srInfo->valid ) + { + tocByte = TOC_INDICATE_SR; + frameLengthInBits = frameBuffer->length * 8; + error = getSRToCByte( srInfo, &tocByte1 ); + ERR_CHECK_RETURN( error ); + } +#endif + else + { + error = getBitrateFromCodecAndFrameSize( codecId, frameBuffer->length, &bitrate, &frameLengthInBits, &tocByte, &hPack->amrwbIOMode ); + ERR_CHECK_RETURN( error ); + } + + /* Allocate a new frame node for this frame */ + error = BPOOL_GetBuffer( hPack->packNodePool, (void **) &node ); + ERR_CHECK_RETURN( error ); + + initFrameNode( node ); + + /* Set ToC byte & frame */ + node->toc[node->tocNumBytes++] = tocByte; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + if ( srInfo != NULL && srInfo->valid ) + { + node->toc[node->tocNumBytes++] = tocByte1; + } +#endif + + node->auNumBits = frameLengthInBits; + if ( frameBuffer != NULL ) + { + memcpy( node->au, frameBuffer->buffer, frameBuffer->length ); + } + + /* If some Pi data is is Cache add to Frame Node's associated Pi Data */ + mtx_lock( &hPack->apilock ); /* Lock to prevent access to shared cache */ + if ( piDataFrame->numPiDataAvailable ) + { + uint32_t bitmap = piDataFrame->piDataBitmap; + for ( piDataType = 0; piDataType < 32 && ( bitmap != 0 ); piDataType++ ) + { + uint32_t mask = ( 1u << piDataType ); + if ( bitmap & mask ) + { + bitmap &= ~mask; /* Mask out this pi type to indicate processed */ + addPackedPiDataToFrame( &node->piDataFrame, &piDataFrame->piData[piDataType], piDataType ); + } + } + initPiDataFrame( piDataFrame ); /* Reset Cache */ + } + mtx_unlock( &hPack->apilock ); + + /* Add to frames FiFo */ + QUEUE_Push( hPack->frameQ, (NODE *) node ); + + return IVAS_ERR_OK; +} + +uint32_t IVAS_RTP_PACK_GetNumFrames( + IVAS_RTP_PACK_HANDLE hPack /* i/o : IVAS rtp packer handle */ +) +{ + uint32_t nFrames = 0; + if ( hPack ) + { + nFrames = QUEUE_Size( hPack->frameQ ); + } + return nFrames; +} + +/* Push single PI data to rtp packer + * + * Provide PI data for a current RTP Payload. All PI data is locally cached in the packer + * and set to the rtp packet with policy defined in initial configuration during call to + * IVAS_RTP_PACK_GetPacket. + * + */ +ivas_error IVAS_RTP_PACK_PushPiData( + IVAS_RTP_PACK_HANDLE hPack, /* i/o : IVAS rtp packer handle */ + const IVAS_PIDATA_GENERIC *data /* i : pointer to the PIData stucture */ +) +{ + ivas_error error = IVAS_ERR_OK; + PIDATA_PACKED packedPiData; + + if ( data == NULL || + data->piDataType >= IVAS_PI_NO_DATA || /* NO_PI_DATA cannot be provided by user, it is generated in packing */ + data->size > sizeof( PIDATA ) ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Wrong PI Data provided" ); + } + + error = PI_PackData( data, &packedPiData, 0 ); + ERR_CHECK_RETURN( error ); + + mtx_lock( &hPack->apilock ); /* Lock to prevent access to shared cache */ + { + FRAME_NODE *node = (FRAME_NODE *) QUEUE_Back( hPack->frameQ ); + /* use cache if no frame in Queue to associate PI data */ + PIDATA_FRAME *piDataFrm = ( node != NULL ) ? &node->piDataFrame : &hPack->piDataCache; + addPackedPiDataToFrame( piDataFrm, &packedPiData, data->piDataType ); + } + mtx_unlock( &hPack->apilock ); + + return IVAS_ERR_OK; +} + +#define WRITE_BYTE_PAYLOAD_OR_EXIT( payload, byte ) \ + if ( payload->length < payload->capacity ) \ + { \ + uint8_t _byte = ( byte ); \ + payload->buffer[payload->length++] = _byte; \ + } \ + else \ + { \ + error = IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient memory to write RTP Payload" ); \ + goto err_exit; \ + } + +ivas_error IVAS_RTP_PACK_GetPayload( + IVAS_RTP_PACK_HANDLE hPack, /* i/o : IVAS rtp packer handle */ + IVAS_DATA_BUFFER *payload, /* o : encapsulated rtp payload */ + uint32_t *numFramesInPayload /* o : no. of frames in payload */ +) +{ + uint32_t n = 0, numFrame = 0; + ivas_error error = IVAS_ERR_OK; + uint32_t numPiDataPresent = 0; + FRAME_NODE *availableFrameNodes[IVAS_MAX_FRAMES_PER_RTP_PACKET]; + size_t numEBytes = 0; + + if ( payload == NULL ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Output data buffer is NULL" ); + } + + /* Calculate number of frames to pack in this payload */ + numFrame = QUEUE_Size( hPack->frameQ ); + numFrame = ( numFrame > hPack->initConfig.maxFramesPerPacket ) ? hPack->initConfig.maxFramesPerPacket : numFrame; + *numFramesInPayload = numFrame; /* numFrames in Packet */ + + /* Collect all the frame nodes from FiFo */ + for ( n = 0; n < numFrame; n++ ) + { + FRAME_NODE *node = (FRAME_NODE *) QUEUE_Pop( hPack->frameQ ); + if ( node == NULL ) + { + assert( 0 ); /* catastrophic error, implementation issue somewhere */ + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "NULL found in frame nodes" ); + } + /* Calculate number of PI data present in total */ + numPiDataPresent += node->piDataFrame.numPiDataAvailable; + availableFrameNodes[n] = node; + } + + /* IVAS Payload starts with E-Bytes */ + packEBytes( hPack, ( numPiDataPresent > 0 ), payload->capacity, &payload->buffer[payload->length], &numEBytes ); + payload->length += numEBytes; + + /* ToC bytes (atleast 1 byte per frame, 2 if SR )*/ + for ( n = 0; n < numFrame; n++ ) + { + FRAME_NODE *node = availableFrameNodes[n]; + uint8_t fBit = ( n != ( numFrame - 1 ) ) ? TOC_HEADER_FOLLOWS : 0; /* Next ToC present */ + + WRITE_BYTE_PAYLOAD_OR_EXIT( payload, ( node->toc[0] | fBit ) ); +#ifdef RTP_S4_251135_CR26253_0016_REV1 + if ( node->tocNumBytes == 2 ) + { + WRITE_BYTE_PAYLOAD_OR_EXIT( payload, node->toc[1] ); + } +#endif + } + + /* Frame Data */ + for ( n = 0; n < numFrame; n++ ) + { + FRAME_NODE *node = availableFrameNodes[n]; + size_t frameLength = ( node->auNumBits + 7 ) >> 3; /* zero padded length in bytes */ + if ( payload->length + frameLength <= payload->capacity ) + { + memcpy( &payload->buffer[payload->length], node->au, frameLength ); + } + else + { + error = IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient memory to write RTP Payload" ); + goto err_exit; + } + payload->length += frameLength; + } + + /* PI Data */ + if ( numPiDataPresent > 0 ) + { + bool skipPiData = false; + size_t nBytes = payload->length; + uint32_t numPiDataWritten = 0; + + for ( n = 0; n < numFrame; n++ ) + { + uint32_t piDataType = 0; + FRAME_NODE *node = availableFrameNodes[n]; + PIDATA_FRAME *piDataFrame = &node->piDataFrame; + uint32_t bitmap = piDataFrame->piDataBitmap; + uint8_t PM = 0, PF = 0; + + for ( piDataType = 0; piDataType < 32 && ( bitmap != 0 ); piDataType++ ) + { + uint32_t mask = ( 1u << piDataType ); + if ( bitmap & mask ) + { + bitmap &= ~mask; /* Mask out this pi type to indicate processing */ + /* Check if last PI data this frame */ + PM = piDataFrame->piData[piDataType].data[0] & 0x60; + PM = (uint8_t) ( ( bitmap == 0 && PM != PI_HEADER_PM_GENERIC ) ? PI_HEADER_PM_LAST : PM ); + /* Check if last PI data all frames */ + PF = (uint8_t) ( ( bitmap == 0 && ( numPiDataWritten + 1 == numPiDataPresent ) ) ? PI_HEADER_PF_LAST : PI_HEADER_PF_NOT_LAST ); /* Last PI in Payload */ + /* Update the first byte of PI Header with PF/PM */ + piDataFrame->piData[piDataType].data[0] |= ( PF | PM ); + if ( nBytes + piDataFrame->piData[piDataType].size < payload->capacity ) + { + memcpy( &payload->buffer[nBytes], piDataFrame->piData[piDataType].data, piDataFrame->piData[piDataType].size ); + nBytes += piDataFrame->piData[piDataType].size; + } + else + { + skipPiData = true; /* Not enough bytes in output for PI data */ + } + numPiDataWritten++; + } + } + } + if ( !skipPiData ) + { + payload->length = nBytes; /* update payload length after PI packing */ + } + } + +err_exit: + /* Pop frames from Queue */ + for ( n = 0; n < numFrame; n++ ) + { + if ( BPOOL_FreeBuffer( hPack->packNodePool, availableFrameNodes[n] ) != IVAS_ERR_OK ) + { + assert( 0 ); /* catastrophic error if this fails */ + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "frame node could not be freed" ); + } + availableFrameNodes[n] = NULL; + } + + return error; +} + +ivas_error IVAS_RTP_PACK_GetPacket( + IVAS_RTP_PACK_HANDLE hPack, /* i/o : IVAS rtp packer handle */ + IVAS_DATA_BUFFER *packet, /* o : encapsulated rtp packet */ + uint32_t *numFramesInPacket /* o : no. of frames in packet */ +) +{ + ivas_error error = PackRtpHeader( &hPack->header, packet ); + ERR_CHECK_RETURN( error ); + + error = IVAS_RTP_PACK_GetPayload( hPack, packet, numFramesInPacket ); + ERR_CHECK_RETURN( error ); + + UpdateRtpHeader( &hPack->header, ( *numFramesInPacket ) * 320 ); + + return IVAS_ERR_OK; +} + +ivas_error IVAS_RTP_UNPACK_Open( + IVAS_RTP_UNPACK_HANDLE *phUnpack, /* i/o : rtp unpacker handle */ + const IVAS_RTP_UNPACK_CONFIG *config /* i : initial configuration for rtp unpacker */ +) +{ + ivas_error error = IVAS_ERR_OK; + IVAS_RTP_UNPACK_HANDLE hUnpack; + + if ( phUnpack == NULL || config == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + *phUnpack = NULL; + if ( ( hUnpack = (IVAS_RTP_UNPACK_HANDLE) calloc( 1, sizeof( struct IVAS_RTP_UNPACK ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS rtp unpack handle" ); + } + + if ( config->maxFramesPerPacket > IVAS_MAX_FRAMES_PER_RTP_PACKET ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Max frame per packet exeeds %d", IVAS_MAX_FRAMES_PER_RTP_PACKET ); + } + + hUnpack->maxNumberOfFrames = ( config->maxFramesPerPacket == 0 ) ? IVAS_MAX_FRAMES_PER_RTP_PACKET : config->maxFramesPerPacket; + hUnpack->maxNumberOfPiData = hUnpack->maxNumberOfFrames * IVAS_PI_MAX_ID; + + error = BPOOL_Create( &hUnpack->unpackNodePool, sizeof( UNPACK_NODE ), hUnpack->maxNumberOfFrames ); + ERR_CHECK_RETURN( error ); + + error = BPOOL_Create( &hUnpack->piDataPool, sizeof( PIDATA_NODE ), hUnpack->maxNumberOfPiData ); + ERR_CHECK_RETURN( error ); + + error = QUEUE_Create( &hUnpack->frameQ ); + ERR_CHECK_RETURN( error ); + + error = QUEUE_Create( &hUnpack->piDataQ ); + ERR_CHECK_RETURN( error ); + + hUnpack->initConfig = *config; + mtx_init( &hUnpack->apilock, 0 ); + + initRequests( hUnpack->requests ); + + *phUnpack = hUnpack; + return IVAS_ERR_OK; +} + +/* Close and free an existing instance of rtp unpacker */ +void IVAS_RTP_UNPACK_Close( + IVAS_RTP_UNPACK_HANDLE *phUnpack /* i/o : IVAS rtp unpacker handle */ +) +{ + IVAS_RTP_UNPACK_HANDLE hUnpack; + + /* Free all memory */ + if ( phUnpack == NULL || *phUnpack == NULL ) + { + return; + } + + hUnpack = *phUnpack; + mtx_destroy( &hUnpack->apilock ); + QUEUE_Destroy( &hUnpack->frameQ ); + QUEUE_Destroy( &hUnpack->piDataQ ); + BPOOL_Destroy( &hUnpack->piDataPool ); + BPOOL_Destroy( &hUnpack->unpackNodePool ); + free( hUnpack->header.extData ); + free( hUnpack ); + *phUnpack = NULL; +} + +static void setEVSRequests( IVAS_RTP_BANDWIDTH bandwidth, uint32_t bitrate, IVAS_RTP_CA_MODE caMode, IVAS_RTP_REQUEST_VALUE *requests ) +{ + requests[IVAS_REQUEST_CODEC].codec = IVAS_RTP_EVS; + requests[IVAS_REQUEST_CA_MODE].caMode = caMode; + requests[IVAS_REQUEST_BITRATE].bitrate = bitrate; + requests[IVAS_REQUEST_BANDWIDTH].bandwidth = bandwidth; +} + +static uint32_t parseInitialEByte( const IVAS_DATA_BUFFER *payload, uint32_t nBytes, IVAS_RTP_REQUEST_VALUE *requests ) +{ + if ( nBytes < payload->length ) + { + uint8_t byte = payload->buffer[nBytes]; + uint8_t EvsIvasIndicator = ( byte & ( ~MASK_4BIT ) ); + uint8_t BR = ( byte & MASK_4BIT ); + + if ( ( byte & EBYTE_TOC_HEADER_BIT ) == 0 ) + { + return nBytes; + } + + nBytes++; /* Consume this e-byte */ + + switch ( EvsIvasIndicator ) + { + case EBYTE_CMR_T_EVS_NB: + if ( BR < 7 ) + { + uint32_t bitrate = evsFrameSizeInBits[BR] * IVAS_NUM_FRAMES_PER_SEC; + setEVSRequests( IVAS_BANDWIDTH_NB, bitrate, IVAS_RTP_CA_NO_REQ, requests ); + } + break; + case EBYTE_CMR_T_EVS_IO: /* AMRWB-IO */ + if ( BR < 9 ) + { + uint32_t bitrate = amrWBIOFrameSizeInBits[BR] * IVAS_NUM_FRAMES_PER_SEC; + setEVSRequests( IVAS_BANDWIDTH_NO_REQ, bitrate, IVAS_RTP_CA_NO_REQ, requests ); + } + break; + case EBYTE_CMR_T_EVS_CA_WB: + if ( BR < 8 ) + { + uint32_t bitrate = 13200; /* Fixed in CA Mode */ + setEVSRequests( IVAS_BANDWIDTH_WB, bitrate, BR, requests ); + } + break; + case EBYTE_CMR_T_EVS_CA_SWB: + if ( BR < 8 ) + { + uint32_t bitrate = 13200; /* Fixed in CA Mode */ + setEVSRequests( IVAS_BANDWIDTH_SWB, bitrate, BR, requests ); + } + break; + case EBYTE_CMR_T_EVS_WB: + if ( BR < 12 ) + { + uint32_t bitrate = evsFrameSizeInBits[BR] * IVAS_NUM_FRAMES_PER_SEC; + setEVSRequests( IVAS_BANDWIDTH_WB, bitrate, IVAS_RTP_CA_NO_REQ, requests ); + } + break; + case EBYTE_CMR_T_EVS_SWB: /* Intentional fall through */ + if ( BR < 12 && BR > 2 ) + { + uint32_t bitrate = evsFrameSizeInBits[BR] * IVAS_NUM_FRAMES_PER_SEC; + setEVSRequests( IVAS_BANDWIDTH_SWB, bitrate, IVAS_RTP_CA_NO_REQ, requests ); + } + break; + case EBYTE_CMR_T_EVS_FB: + if ( BR < 12 && BR > 4 ) + { + uint32_t bitrate = evsFrameSizeInBits[BR] * IVAS_NUM_FRAMES_PER_SEC; + setEVSRequests( IVAS_BANDWIDTH_FB, bitrate, IVAS_RTP_CA_NO_REQ, requests ); + } + break; + case EBYTE_CMR_T_IVAS: /* IVAS */ + if ( BR != 14 ) + { + requests[IVAS_REQUEST_CODEC].codec = IVAS_RTP_IVAS; + requests[IVAS_REQUEST_BITRATE].bitrate = ( BR == 0xF ) ? 0 : ivasFrameSizeInBits[BR] * IVAS_NUM_FRAMES_PER_SEC; + requests[IVAS_REQUEST_CA_MODE].caMode = IVAS_RTP_CA_NO_REQ; + } + break; + } + } + + return nBytes; +} + +static uint32_t parseSubsequentEByte( const IVAS_DATA_BUFFER *payload, uint32_t nBytes, IVAS_RTP_REQUEST_VALUE *requests, bool *piDataIndicated ) +{ + while ( nBytes < payload->length ) + { + uint8_t byte = payload->buffer[nBytes]; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + uint8_t ET = ( byte & ( ~MASK_4BIT ) ); +#else + uint8_t ET = ( byte & ( ~MASK_3BIT ) ); +#endif + + if ( ( byte & EBYTE_TOC_HEADER_BIT ) == 0 ) + { + return nBytes; + } + + nBytes++; /* Consume this e-byte */ + + switch ( ET ) + { + case EBYTE_BANDWIDTH_REQUEST: /* Bandwidth Request */ + { + requests[IVAS_REQUEST_BANDWIDTH].bandwidth = IVAS_BANDWIDTH_WB + ( byte & MASK_2BIT ); + } + break; + case EBYTE_FORMAT_REQUEST: /* Format Request */ + { +#ifdef RTP_S4_251135_CR26253_0016_REV1 + bool S = ( byte >> 3 ) & MASK_1BIT; + if ( S ) + { + /* Use the next byte to extract SubFormat */ + if ( nBytes < payload->length ) + { + byte = payload->buffer[nBytes++]; + requests[IVAS_REQUEST_SUBFORMAT].subFormatType = byte & MASK_6BIT; + } + } +#endif + requests[IVAS_REQUEST_FORMAT].formatType = byte & MASK_3BIT; + } + break; + case EBYTE_PI_INDICATOR: /* PI Indication */ + *piDataIndicated = true; + break; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + case EBYTE_SR_REQUEST: /* Split Rendering Request */ + { + IVAS_RTP_SPLITRENDER *srConfig = &requests[IVAS_REQUEST_SR_CONFIG].srConfig; + srConfig->diegetic = ( byte >> 3 ) & MASK_1BIT; + srConfig->yaw = ( byte >> 2 ) & MASK_1BIT; + srConfig->pitch = ( byte >> 1 ) & MASK_1BIT; + srConfig->roll = byte & MASK_1BIT; + srConfig->valid = true; + } + break; +#endif + default: /* Reserved for future use - unhandled atm */ + break; + } + } + + return nBytes; +} + +#ifdef RTP_S4_251135_CR26253_0016_REV1 +static ivas_error parseToCByte( const IVAS_DATA_BUFFER *payload, uint32_t *numBytes, uint32_t *numFrames, TOC_INFO *toc, uint32_t maxNumberOfToCBytes, uint32_t srCodecFrameSizeMs ) +#else +static ivas_error parseToCByte( const IVAS_DATA_BUFFER *payload, uint32_t *numBytes, uint32_t *numFrames, TOC_INFO *toc, uint32_t maxNumberOfToCBytes ) +#endif +{ + bool headerFollows = true; + uint32_t nBytes = *numBytes; + + *numFrames = 0; + while ( nBytes < payload->length && headerFollows ) + { + uint8_t byte = payload->buffer[nBytes]; + uint8_t BR = byte & MASK_4BIT; + uint8_t FT = byte & ( ( ~MASK_4BIT ) & MASK_6BIT ); + + headerFollows = ( byte & ( ~MASK_6BIT ) ) == TOC_HEADER_FOLLOWS; + + if ( ( byte & EBYTE_TOC_HEADER_BIT ) != 0 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNSUPPORTED_FRAME, "Expected ToC byte missing" ); + } + + nBytes++; /* Consume this e-byte */ + + if ( *numFrames == maxNumberOfToCBytes ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "No of frames in packet exceed max defined" ); + } + + *numFrames += 1; + memset( toc, 0, sizeof( *toc ) ); + + if ( FT == TOC_INDICATE_ARMWB_Q || FT == TOC_INDICATE_AMRWB ) + { + toc->codecId = IVAS_RTP_EVS; + toc->isAMRWB_IOmode = true; + toc->speechLostIndicated = ( FT == TOC_INDICATE_ARMWB_Q ) ? true : false; /* Q bit = 0 for AMRWB, BR is valid */ + if ( BR <= 9 ) + { + toc->auNumBits = amrWBIOFrameSizeInBits[BR]; + } + else if ( BR < 14 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNSUPPORTED_FRAME, "Reserved bitrate provided in AMRWB ToC" ); + } + else + { + toc->speechLostIndicated = ( BR == 14 ); /* SPEECH_LOST */ + toc->auNumBits = 0; + } + } + else if ( FT == TOC_INDICATE_IVAS ) + { + toc->codecId = IVAS_RTP_IVAS; + if ( BR == 14 ) + { +#ifdef RTP_S4_251135_CR26253_0016_REV1 + /* Read Unconditional SR-ToC byte */ + if ( nBytes < payload->length ) + { + uint8_t SR_BR; + byte = payload->buffer[nBytes++]; + SR_BR = ( byte >> 3 ) & MASK_2BIT; + if ( SR_BR == 0 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNSUPPORTED_FRAME, "Reserved bitrate provided in SR ToC" ); + } + toc->srInfo.valid = true; + toc->srInfo.diegetic = ( byte >> 6 ) & MASK_1BIT; + toc->srInfo.codec = IVAS_SR_TRANSPORT_LCLD + ( ( byte >> 5 ) & MASK_1BIT ); + toc->srInfo.bitrateKbps = ( SR_BR + 1 ) * 128000u; + toc->auNumBits = toc->srInfo.bitrateKbps * srCodecFrameSizeMs / 1000; + } + else + { + return IVAS_ERROR( IVAS_ERR_RTP_UNDERFLOW, "Underflow during ToC SR byte" ); + } +#else + /* Reserved bit not expected */ + return IVAS_ERROR( IVAS_ERR_RTP_UNSUPPORTED_FRAME, "Reserved BR idx reported in ToC" ); +#endif + } + else + { + toc->auNumBits = ivasFrameSizeInBits[BR]; + } + } + else /* EVS */ + { + toc->codecId = IVAS_RTP_EVS; + toc->speechLostIndicated = ( FT == TOC_INDICATE_ARMWB_Q ) ? true : false; /* Q bit = 0 for AMRWB, BR is valid */ + if ( BR < 13 ) + { + toc->auNumBits = evsFrameSizeInBits[BR]; + } + else if ( BR == 13 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNSUPPORTED_FRAME, "Reserved bitrate provided in EVS ToC" ); + } + else + { + toc->speechLostIndicated = ( BR == 14 ); /* SPEECH_LOST */ + toc->auNumBits = 0; + } + } + + toc++; + + /* Handle any frame specific E-Bytes here currently there are none, so we skip any E-Bytes here after */ + if ( headerFollows ) + { + while ( nBytes < payload->length ) + { + byte = payload->buffer[nBytes]; + if ( ( byte & EBYTE_TOC_HEADER_BIT ) == 0 ) + { + break; + } + nBytes++; + } + } + } + + *numBytes = nBytes; + return IVAS_ERR_OK; +} + +static ivas_error parsePIData( IVAS_RTP_UNPACK_HANDLE hUnpack, uint32_t rtpTimestamp, const IVAS_DATA_BUFFER *payload, uint32_t *numBytes, uint32_t *numPiDataInPacket ) +{ + bool PF = true; + uint32_t nBytes = *numBytes; + + while ( PF ) + { + uint8_t piHeader0, PM, piDataType, byte = 0; + uint32_t piSize = 0; + + if ( nBytes + 1 >= payload->length ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNDERFLOW, "Underflow during expected PI Header read" ); + } + + piHeader0 = payload->buffer[nBytes++]; + + PF = ( piHeader0 >> 7 ) & MASK_1BIT; /* New PI header follows this PI Data Frame */ + PM = ( piHeader0 & ( ~MASK_5BIT ) ) & MASK_7BIT; /* PI Marker Bits */ + piDataType = ( piHeader0 & MASK_5BIT ); + + do + { + byte = payload->buffer[nBytes++]; + piSize += byte; + if ( nBytes >= payload->length ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNDERFLOW, "Underflow during reading piSize" ); + } + } while ( byte == 255 ); + + if ( piDataType == IVAS_PI_NO_DATA ) + { + if ( piSize > 0 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "NO_PI_DATA should be 0 sized" ); + } + + /* Do not add a node for NO_DATA */ + } + else if ( nBytes + piSize <= payload->length ) + { + PIDATA_NODE *node = NULL; + ivas_error error = BPOOL_GetBuffer( hUnpack->piDataPool, (void **) &node ); + ERR_CHECK_RETURN( error ); + + node->next = NULL; + + error = PI_UnPackData( piDataType, piSize, &payload->buffer[nBytes], (IVAS_PIDATA_GENERIC *) &node->data ); + ERR_CHECK_RETURN( error ); + + node->timestamp = rtpTimestamp; + + nBytes += piSize; + *numPiDataInPacket += 1; + + QUEUE_Push( hUnpack->piDataQ, (NODE *) node ); + } + else + { + return IVAS_ERROR( IVAS_ERR_RTP_UNDERFLOW, "Underflow during reading pi data" ); + } + + if ( PM == PI_HEADER_PM_LAST ) + { + rtpTimestamp += 16000 / IVAS_NUM_FRAMES_PER_SEC; + } + } + + *numBytes = nBytes; + return IVAS_ERR_OK; +} + +ivas_error IVAS_RTP_UNPACK_PushPayload( + IVAS_RTP_UNPACK_HANDLE hUnpack, /* i/o : IVAS rtp unpacker handle */ + const IVAS_DATA_BUFFER *payload, /* i : received rtp payload */ + uint32_t timestamp, /* i : timestamp in RTP Clock @ 16KHz from rtp header */ + uint16_t sequenceNumber, /* i : sequence number from rtp header */ + uint32_t *numFramesInPacket, /* o : number of IVAS/EVS frames in rtp packet */ + uint32_t *numPiDataInPacket, /* o : number of PI data received in rtp packet */ + uint32_t *remoteRequestBitmap /* o : bitmap of available request in this packet */ +) +{ + ivas_error error = IVAS_ERR_OK; + uint32_t nBytes = 0, numFrames = 0, numPiData = 0, n; + bool piDataIndicated = false; + TOC_INFO toc[IVAS_MAX_FRAMES_PER_RTP_PACKET]; + + IVAS_RTP_REQUEST_VALUE oldRequests[IVAS_REQUEST_MAX]; + + if ( hUnpack == NULL || payload == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( remoteRequestBitmap != NULL ) + { + *remoteRequestBitmap = 0; + } + + if ( numFramesInPacket != NULL ) + { + *numFramesInPacket = 0; + } + + if ( numPiDataInPacket != NULL ) + { + *numPiDataInPacket = 0; + } + + /* Sanity check if any frame or PI data from last packet is still not pulled */ + if ( QUEUE_Size( hUnpack->frameQ ) > 0 || QUEUE_Size( hUnpack->piDataQ ) > 0 ) + { + assert( 0 ); + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Previous packet data should be consumed before next packet is pushed" ); + } + + memcpy( oldRequests, hUnpack->requests, sizeof( oldRequests ) ); + + /* Unpack IVAS Payload, starting with the E-Bytes */ + nBytes = parseInitialEByte( payload, nBytes, hUnpack->requests ); + + /* Unpack any subsequent E-bytes */ + nBytes = parseSubsequentEByte( payload, nBytes, hUnpack->requests, &piDataIndicated ); + + /* Unpack the ToC Bytes => Extract number of frames in packet */ + +#ifdef RTP_S4_251135_CR26253_0016_REV1 + error = parseToCByte( payload, &nBytes, &numFrames, toc, sizeof( toc ) / sizeof( toc[0] ), hUnpack->initConfig.srCodecFrameSizeMs ); +#else + error = parseToCByte( payload, &nBytes, &numFrames, toc, sizeof( toc ) / sizeof( toc[0] ) ); +#endif + ERR_CHECK_RETURN( error ); + + /* Read frame bits */ + for ( n = 0; n < numFrames; n++ ) + { + uint32_t frameSizeBytes; + UNPACK_NODE *node = NULL; + + /* Get a new node */ + error = BPOOL_GetBuffer( hUnpack->unpackNodePool, (void **) &node ); + ERR_CHECK_RETURN( error ); + + node->next = NULL; + node->timestamp = timestamp + ( n * 320 ); + node->seqNumber = sequenceNumber; + node->toc = toc[n]; + + frameSizeBytes = ( node->toc.auNumBits + 7 ) / 8; + if ( nBytes + frameSizeBytes <= payload->length ) + { + memcpy( node->au, &payload->buffer[nBytes], frameSizeBytes ); + nBytes += frameSizeBytes; + } + else + { + return IVAS_ERROR( IVAS_ERR_RTP_UNDERFLOW, "Underflow during expected frame bits" ); + } + + /* Add to frames FiFo */ + QUEUE_Push( hUnpack->frameQ, (NODE *) node ); + } + + if ( piDataIndicated ) + { + error = parsePIData( hUnpack, timestamp, payload, &nBytes, &numPiData ); + if ( error != IVAS_ERR_OK ) + { + /* PI Parsing errors are not fatal => indicate no PI data in packet as workaround */ + numPiData = 0; + } + } + + if ( numFramesInPacket != NULL ) + { + *numFramesInPacket = numFrames; + } + + if ( numPiDataInPacket ) + { + *numPiDataInPacket = numPiData; + } + + if ( remoteRequestBitmap ) + { + for ( n = 0; n < IVAS_REQUEST_MAX; n++ ) + { + bool changed = ( memcmp( &hUnpack->requests[n], &oldRequests[n], sizeof( IVAS_RTP_REQUEST_VALUE ) ) != 0 ); + *remoteRequestBitmap |= changed ? ( 1u << n ) : 0; + } + } + + return IVAS_ERR_OK; +} + +ivas_error IVAS_RTP_UNPACK_PushPacket( + IVAS_RTP_UNPACK_HANDLE hUnpack, /* i/o : IVAS rtp unpacker handle */ + const IVAS_DATA_BUFFER *packet, /* i : received rtp Packet */ + uint32_t *numFramesInPacket, /* o : number of IVAS/EVS frames in rtp packet */ + uint32_t *numPiDataInPacket, /* o : number of PI data received in rtp packet */ + uint32_t *remoteRequestBitmap /* o : bitmap of available request in this packet */ +) +{ + ivas_error error = IVAS_ERR_OK; + uint32_t numHeaderBytes = 0; + IVAS_DATA_BUFFER payload; + + error = UnpackRtpPacket( packet, &hUnpack->header, &numHeaderBytes ); + ERR_CHECK_RETURN( error ); + + /* Offset to RTP Payload */ + payload.capacity = packet->capacity; + payload.buffer = packet->buffer + numHeaderBytes; + payload.length = packet->length - numHeaderBytes; + + return IVAS_RTP_UNPACK_PushPayload( + hUnpack, + &payload, + hUnpack->header.timestamp, + hUnpack->header.seqNumber, + numFramesInPacket, + numPiDataInPacket, + remoteRequestBitmap ); +} + +ivas_error IVAS_RTP_UNPACK_GetRequest( + IVAS_RTP_UNPACK_HANDLE hUnpack, /* i/o : IVAS rtp packer handle */ + IVAS_RTP_REQUEST_TYPE type, /* i : remote request type */ + IVAS_RTP_REQUEST_VALUE *value /* o : pointer of the requested type */ +) +{ + if ( type < 0 || type >= IVAS_REQUEST_MAX ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid request key provided" ); + } + *value = hUnpack->requests[type]; + return IVAS_ERR_OK; +} + +ivas_error IVAS_RTP_UNPACK_PullFrame( + IVAS_RTP_UNPACK_HANDLE hUnpack, /* i/o : IVAS rtp unpacker handle */ + IVAS_RTP_CODEC *receivedCodecId, /* o : Codec type (IVAS/EVS) */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + IVAS_RTP_SR_INFO *srInfo, /* o : Split Rendering Info */ +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ + IVAS_DATA_BUFFER *frameBuffer, /* o : packed frame bitstream for IVAS/EVS */ + int16_t *frameSizeInBits, /* o : exact frame size in bits (AMRWB IO) */ + uint32_t *timestamp, /* o : timestamp in RTP Clock @ 16KHz */ + uint16_t *sequenceNumber, /* o : sequence number from rtp header */ + bool *speechLostIndicated, /* o : Is current frame indicated as Lost */ + bool *isAMRWB_IOmode /* o : Is AMRWB_IO mode EVS frame */ +) +{ + size_t length = 0; + UNPACK_NODE *node = (UNPACK_NODE *) QUEUE_Pop( hUnpack->frameQ ); + + /* Check if a node is available in FiFo */ + if ( node == NULL ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNDERFLOW, "No more frames in unpack fifo" ); + } + + length = ( node->toc.auNumBits + 7 ) / 8; + if ( frameBuffer != NULL && ( length <= frameBuffer->capacity ) ) + { + memcpy( frameBuffer->buffer, node->au, length ); + frameBuffer->length = length; + } + + if ( frameSizeInBits != NULL ) + { + *frameSizeInBits = (int16_t) node->toc.auNumBits; + } + + if ( receivedCodecId != NULL ) + { + *receivedCodecId = node->toc.codecId; + } + +#ifdef RTP_S4_251135_CR26253_0016_REV1 + if ( srInfo != NULL ) + { + *srInfo = node->toc.srInfo; + } +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ + + if ( timestamp != NULL ) + { + *timestamp = node->timestamp; + } + + if ( sequenceNumber != NULL ) + { + *sequenceNumber = node->seqNumber; + } + + if ( speechLostIndicated != NULL ) + { + *speechLostIndicated = node->toc.speechLostIndicated; + } + + if ( isAMRWB_IOmode != NULL ) + { + *isAMRWB_IOmode = node->toc.isAMRWB_IOmode; + } + + return BPOOL_FreeBuffer( hUnpack->unpackNodePool, node ); +} + +ivas_error IVAS_RTP_UNPACK_PullNextPiData( + IVAS_RTP_UNPACK_HANDLE hUnpack, /* i/o : IVAS rtp unpacker handle */ + IVAS_PIDATA_GENERIC *data, /* o : output data buffer for the Pi data */ + size_t capacity, /* i : capacity of pi data buffer in bytes */ + uint32_t *timestamp /* o : timestamp in RTP Clock @ 16KHz */ +) +{ + IVAS_PIDATA_GENERIC *pi = NULL; + PIDATA_NODE *node = (PIDATA_NODE *) QUEUE_Pop( hUnpack->piDataQ ); + + /* Check if a node is available in FiFo */ + if ( node == NULL ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNDERFLOW, "No more pi data in unpack fifo" ); + } + + pi = (IVAS_PIDATA_GENERIC *) &node->data; + + if ( data != NULL && ( pi->size <= capacity ) ) + { + memcpy( data, pi, pi->size ); + } + + if ( timestamp != NULL ) + { + *timestamp = node->timestamp; + } + + return BPOOL_FreeBuffer( hUnpack->piDataPool, node ); +} + +#endif /* IVAS_RTPDUMP */ diff --git a/lib_util/ivas_rtp_pi_data.c b/lib_util/ivas_rtp_pi_data.c new file mode 100644 index 0000000000000000000000000000000000000000..8db9d41f9df241e317cdcf606e0fcc682c4a0a8c --- /dev/null +++ b/lib_util/ivas_rtp_pi_data.c @@ -0,0 +1,849 @@ +/****************************************************************************************************** + + (C) 2022-2025 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 "ivas_error_utils.h" +#include "ivas_rtp_internal.h" + +#ifdef IVAS_RTPDUMP + +/* Generic PI data packing/unpacking functions */ +typedef ivas_error ( *PACK_PI_FN )( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ); +typedef ivas_error ( *UNPACK_PI_FN )( const uint8_t *buffer, uint32_t numDataBytes, IVAS_PIDATA_GENERIC *piData ); + +static __inline uint32_t writeInt16( uint8_t *buffer, uint32_t idx, int16_t val ) +{ + buffer[idx++] = (uint8_t) ( val >> 8 ); + buffer[idx++] = (uint8_t) ( val & 0x00FF ); + return idx; +} + +static __inline int16_t readInt16( const uint8_t *buffer ) +{ + return (int16_t) ( (uint16_t) buffer[0] << 8 ) | ( (uint16_t) buffer[1] ); +} + +/*-----------------------------------------------------------------------* + * ivasPayload_convertToQ15() + * + * Convert a float value into a Q15 encoded value. + *-----------------------------------------------------------------------*/ +static int16_t ivasPayload_convertToQ15( float value ) +{ + value = ( value * 32768.0f ); + value = value > +32767.0f ? +32767.0f : value; + value = value < -32768.0f ? -32768.0f : value; + return (int16_t) ( value ); +} + +static ivas_error packUnsupportedData( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ) +{ + (void) piData; + (void) buffer; + (void) maxDataBytes; + /* Skip packing */ + *nBytesWritten = 0; + return IVAS_ERR_OK; +} + +static ivas_error unpackUnsupportedData( const uint8_t *buffer, uint32_t numDataBytes, IVAS_PIDATA_GENERIC *piData ) +{ + (void) piData; + (void) buffer; + (void) numDataBytes; + /* Skip unpacking */ + return IVAS_ERR_OK; +} + +static ivas_error packNoPiData( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ) +{ + uint32_t nBytes = 0; + (void) piData; + + *nBytesWritten = 0; + + /* NO_PI_DATA is just PI header with no data */ + if ( maxDataBytes < 2 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space in PI data buffer for NO_PI_DATA" ); + } + + buffer[nBytes++] = ( IVAS_PI_NO_DATA ); /* PF/PM populated during final packing */ + buffer[nBytes++] = 0; /* NO_PI_DATA is 0 bytes */ + + *nBytesWritten = nBytes; + return IVAS_ERR_OK; +} + +static ivas_error unpackNoPiData( const uint8_t *buffer, uint32_t numDataBytes, IVAS_PIDATA_GENERIC *piData ) +{ + (void) buffer; + + if ( numDataBytes != 0 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "NO_PI_DATA must be 0 byte" ); + } + + piData->size = sizeof( IVAS_PIDATA_NO_DATA ); + return IVAS_ERR_OK; +} + +static ivas_error packOrientation( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ) +{ + uint32_t nBytes = 0; + const IVAS_PIDATA_ORIENTATION *orientation = (const IVAS_PIDATA_ORIENTATION *) piData; + + *nBytesWritten = 0; + + if ( piData->size != sizeof( IVAS_PIDATA_ORIENTATION ) ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect size in Orientation PI data" ); + } + + if ( ( piData->piDataType != IVAS_PI_SCENE_ORIENTATION ) && ( piData->piDataType != IVAS_PI_DEVICE_ORIENTATION_COMPENSATED ) && ( piData->piDataType != IVAS_PI_DEVICE_ORIENTATION_UNCOMPENSATED ) +#ifdef RTP_S4_251135_CR26253_0016_REV1 + && ( piData->piDataType != IVAS_PI_PLAYBACK_DEVICE_ORIENTATION ) && ( piData->piDataType != IVAS_PI_HEAD_ORIENTATION ) +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ + ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect PI ID in Orientation PI data" ); + } + + /* Orientation data is 8 bytes, header is 2 bytes */ + if ( maxDataBytes < 8 + 2 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack Orientation PI data" ); + } + + buffer[nBytes++] = ( orientation->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ + buffer[nBytes++] = 8; + nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( orientation->orientation.w ) ); + nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( orientation->orientation.x ) ); + nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( orientation->orientation.y ) ); + nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( orientation->orientation.z ) ); + + *nBytesWritten = nBytes; + return IVAS_ERR_OK; +} + +static ivas_error unpackOrientation( const uint8_t *buffer, uint32_t numDataBytes, IVAS_PIDATA_GENERIC *piData ) +{ + IVAS_PIDATA_ORIENTATION *orientation = (IVAS_PIDATA_ORIENTATION *) piData; + + /* Orientation data is 8 bytes */ + if ( numDataBytes != 8 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "Incorrect size to unpack Orientation PI data" ); + } + + piData->size = sizeof( IVAS_PIDATA_ORIENTATION ); + orientation->orientation.w = FLOAT_FROM_Q15( readInt16( &buffer[0] ) ); + orientation->orientation.x = FLOAT_FROM_Q15( readInt16( &buffer[2] ) ); + orientation->orientation.y = FLOAT_FROM_Q15( readInt16( &buffer[4] ) ); + orientation->orientation.z = FLOAT_FROM_Q15( readInt16( &buffer[6] ) ); + + return IVAS_ERR_OK; +} + +static uint32_t getIndexTable( const float *table, uint32_t tableLength, float value ) +{ + uint32_t idx = 0; + if ( value <= table[0] ) + { + return 0; + } + + for ( idx = 1; idx < tableLength; idx++ ) + { + if ( value < table[idx] ) + { + break; + } + } + return idx - 1; +} + +#define GET_IDX( table, nBits, value ) getIndexTable( table, ( 1u << ( nBits ) ), ( value ) ) + +static ivas_error packAcousticEnvironment( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ) +{ + uint32_t nBytes = 0; + uint8_t packedSize = 1; + const IVAS_PIDATA_ACOUSTIC_ENV *aeEnv = (const IVAS_PIDATA_ACOUSTIC_ENV *) piData; + + *nBytesWritten = 0; + + if ( piData->size != sizeof( IVAS_PIDATA_ACOUSTIC_ENV ) ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect size in PI data of type Acoustic Environment" ); + } + + if ( aeEnv->availEarlyReflections ) + { + packedSize = 8; + } + else if ( aeEnv->availLateReverb ) + { + packedSize = 5; + } + + /* Acoustic Env data is packedSize bytes, header is 2 bytes */ + if ( maxDataBytes < (uint32_t) packedSize + 2 ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Insufficient space to pack Orientation PI data" ); + } + + buffer[nBytes++] = ( IVAS_PI_ACOUSTIC_ENVIRONMENT ); /* PF/PM populated during final packing */ + buffer[nBytes++] = packedSize; + + if ( packedSize == 1 ) + { + buffer[nBytes++] = aeEnv->aeid & 0x7F; + } + else + { + uint64_t dWord = (uint64_t) aeEnv->aeid << 57; + + dWord |= (uint64_t) GET_IDX( mapRT60, NBITS_RT60, aeEnv->rt60[IVAS_PI_AE_LOW] ) << 52; + dWord |= (uint64_t) GET_IDX( mapDSR, NBITS_DSR, aeEnv->dsr[IVAS_PI_AE_LOW] ) << 46; + dWord |= (uint64_t) GET_IDX( mapRT60, NBITS_RT60, aeEnv->rt60[IVAS_PI_AE_MID] ) << 41; + dWord |= (uint64_t) GET_IDX( mapDSR, NBITS_DSR, aeEnv->dsr[IVAS_PI_AE_MID] ) << 35; + dWord |= (uint64_t) GET_IDX( mapRT60, NBITS_RT60, aeEnv->rt60[IVAS_PI_AE_HIGH] ) << 30; + dWord |= (uint64_t) GET_IDX( mapDSR, NBITS_DSR, aeEnv->dsr[IVAS_PI_AE_HIGH] ) << 24; + + buffer[nBytes++] = (uint8_t) ( dWord >> 56 ); + buffer[nBytes++] = (uint8_t) ( dWord >> 48 ); + buffer[nBytes++] = (uint8_t) ( dWord >> 40 ); + buffer[nBytes++] = (uint8_t) ( dWord >> 32 ); + buffer[nBytes++] = (uint8_t) ( dWord >> 24 ); + + if ( packedSize > 5 ) + { + dWord |= (uint64_t) GET_IDX( mapRoomDims, NBITS_DIM, aeEnv->roomDimensions.x ) << 20; + dWord |= (uint64_t) GET_IDX( mapRoomDims, NBITS_DIM, aeEnv->roomDimensions.y ) << 16; + dWord |= (uint64_t) GET_IDX( mapRoomDims, NBITS_DIM, aeEnv->roomDimensions.z ) << 12; + dWord |= (uint64_t) GET_IDX( mapAbsorbtion, NBITS_ABS, aeEnv->absorbCoeffs[IVAS_PI_AE_FRONT] ) << 10; + dWord |= (uint64_t) GET_IDX( mapAbsorbtion, NBITS_ABS, aeEnv->absorbCoeffs[IVAS_PI_AE_BACK] ) << 8; + dWord |= (uint64_t) GET_IDX( mapAbsorbtion, NBITS_ABS, aeEnv->absorbCoeffs[IVAS_PI_AE_LEFT] ) << 6; + dWord |= (uint64_t) GET_IDX( mapAbsorbtion, NBITS_ABS, aeEnv->absorbCoeffs[IVAS_PI_AE_RIGHT] ) << 4; + dWord |= (uint64_t) GET_IDX( mapAbsorbtion, NBITS_ABS, aeEnv->absorbCoeffs[IVAS_PI_AE_CEILING] ) << 2; + dWord |= (uint64_t) GET_IDX( mapAbsorbtion, NBITS_ABS, aeEnv->absorbCoeffs[IVAS_PI_AE_FLOOR] ); + + buffer[nBytes++] = (uint8_t) ( dWord >> 16 ); + buffer[nBytes++] = (uint8_t) ( dWord >> 8 ); + buffer[nBytes++] = (uint8_t) ( dWord ); + } + } + + *nBytesWritten = nBytes; + return IVAS_ERR_OK; +} + +static ivas_error unpackAcousticEnvironment( const uint8_t *buffer, uint32_t numDataBytes, IVAS_PIDATA_GENERIC *piData ) +{ + IVAS_PIDATA_ACOUSTIC_ENV *aeEnv = (IVAS_PIDATA_ACOUSTIC_ENV *) piData; + + /* Acooustic Env data is either 1, 5 or 8 bytes */ + if ( numDataBytes != 1 && numDataBytes != 5 && numDataBytes != 8 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "Incorrect size to unpack PI data of type Acoustic Environment" ); + } + + piData->size = sizeof( IVAS_PIDATA_ACOUSTIC_ENV ); + aeEnv->availLateReverb = ( numDataBytes >= 5 ); + aeEnv->availEarlyReflections = ( numDataBytes == 8 ); + + if ( numDataBytes == 1 ) + { + aeEnv->aeid = buffer[0]; + } + else + { + uint64_t dWord = 0ull; + uint32_t n; + for ( n = 0; n < numDataBytes; n++ ) + { + dWord <<= 8; + dWord |= buffer[n]; + } + dWord <<= ( 8 - numDataBytes ) * 8; + + aeEnv->aeid = (uint8_t) ( ( dWord >> 57 ) & MASK_AEID ); + aeEnv->rt60[IVAS_PI_AE_LOW] = mapRT60[( dWord >> 52 ) & MASK_RT60]; + aeEnv->dsr[IVAS_PI_AE_LOW] = mapDSR[( dWord >> 46 ) & MASK_DSR]; + aeEnv->rt60[IVAS_PI_AE_MID] = mapRT60[( dWord >> 41 ) & MASK_RT60]; + aeEnv->dsr[IVAS_PI_AE_MID] = mapDSR[( dWord >> 35 ) & MASK_DSR]; + aeEnv->rt60[IVAS_PI_AE_HIGH] = mapRT60[( dWord >> 30 ) & MASK_RT60]; + aeEnv->dsr[IVAS_PI_AE_HIGH] = mapDSR[( dWord >> 24 ) & MASK_DSR]; + + aeEnv->roomDimensions.x = mapRoomDims[( dWord >> 20 ) & MASK_DIM]; + aeEnv->roomDimensions.y = mapRoomDims[( dWord >> 16 ) & MASK_DIM]; + aeEnv->roomDimensions.z = mapRoomDims[( dWord >> 12 ) & MASK_DIM]; + + aeEnv->absorbCoeffs[IVAS_PI_AE_FRONT] = mapAbsorbtion[( dWord >> 10 ) & MASK_ABS]; + aeEnv->absorbCoeffs[IVAS_PI_AE_BACK] = mapAbsorbtion[( dWord >> 8 ) & MASK_ABS]; + aeEnv->absorbCoeffs[IVAS_PI_AE_LEFT] = mapAbsorbtion[( dWord >> 6 ) & MASK_ABS]; + aeEnv->absorbCoeffs[IVAS_PI_AE_RIGHT] = mapAbsorbtion[( dWord >> 4 ) & MASK_ABS]; + aeEnv->absorbCoeffs[IVAS_PI_AE_CEILING] = mapAbsorbtion[( dWord >> 2 ) & MASK_ABS]; + aeEnv->absorbCoeffs[IVAS_PI_AE_FLOOR] = mapAbsorbtion[( dWord >> 0 ) & MASK_ABS]; + } + + return IVAS_ERR_OK; +} + +#ifdef RTP_S4_251135_CR26253_0016_REV1 +static ivas_error packAudioDescription( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ) +{ + uint32_t n; + uint32_t nBytes = 0; + const IVAS_PIDATA_AUDIO_DESC *audioDesc = (const IVAS_PIDATA_AUDIO_DESC *) piData; + uint32_t packedSize = audioDesc->nValidEntries; /* Each Entry is 1 byte */ + + *nBytesWritten = 0; + + if ( audioDesc->nValidEntries > ( IVAS_MAX_NUM_OBJECTS + 1 ) ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNSUPPORTED_FRAME, "Audio Description cannot have more than 5 entries" ); + } + + /* Audio Description data is max 5 bytes, 2 bytes header */ + if ( maxDataBytes < packedSize + 2 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space in Audio Description PI data buffer" ); + } + + buffer[nBytes++] = ( IVAS_PI_AUDIO_DESCRIPTION ); /* PF/PM populated during final packing */ + buffer[nBytes++] = (uint8_t) packedSize; + + for ( n = 0; n < audioDesc->nValidEntries; n++ ) + { + buffer[nBytes++] = ( audioDesc->audioId[n].speech ? PI_AD_SPEECH_INDICATED : 0 ) | + ( audioDesc->audioId[n].music ? PI_AD_MUSIC_INDICATED : 0 ) | + ( audioDesc->audioId[n].ambiance ? PI_AD_AMBIANCE_INDICATED : 0 ) | + ( audioDesc->audioId[n].editable ? PI_AD_EDITABLE_INDICATED : 0 ) | + ( audioDesc->audioId[n].binaural ? PI_AD_BINAURAL_INDICATED : 0 ); + } + + *nBytesWritten = nBytes; + return IVAS_ERR_OK; +} + +static ivas_error unpackAudioDescription( const uint8_t *buffer, uint32_t numDataBytes, IVAS_PIDATA_GENERIC *piData ) +{ + uint32_t n; + IVAS_PIDATA_AUDIO_DESC *audioDesc = (IVAS_PIDATA_AUDIO_DESC *) piData; + + /* Audio Description data is max 5 bytes */ + if ( numDataBytes > ( IVAS_MAX_NUM_OBJECTS + 1 ) ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "Incorrect size to unpack Orientation PI data" ); + } + + audioDesc->size = sizeof( IVAS_PIDATA_AUDIO_DESC ); + audioDesc->nValidEntries = numDataBytes; + audioDesc->piDataType = IVAS_PI_AUDIO_DESCRIPTION; + + for ( n = 0; n < audioDesc->nValidEntries; n++ ) + { + audioDesc->audioId[n].speech = ( buffer[n] & PI_AD_SPEECH_INDICATED ) != 0; + audioDesc->audioId[n].music = ( buffer[n] & PI_AD_MUSIC_INDICATED ) != 0; + audioDesc->audioId[n].ambiance = ( buffer[n] & PI_AD_AMBIANCE_INDICATED ) != 0; + audioDesc->audioId[n].editable = ( buffer[n] & PI_AD_EDITABLE_INDICATED ) != 0; + audioDesc->audioId[n].binaural = ( buffer[n] & PI_AD_BINAURAL_INDICATED ) != 0; + } + + return IVAS_ERR_OK; +} + +static ivas_error packDynamicSuppression( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ) +{ + uint32_t nBytes = 0; + const IVAS_PIDATA_DYNAMIC_SUPPRESSION *das = (const IVAS_PIDATA_DYNAMIC_SUPPRESSION *) piData; + + *nBytesWritten = 0; + + /* Dynamic Audio Suppression data is 2 bytes, 2 bytes header */ + if ( maxDataBytes < 2 + 2 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space in DAS PI data buffer" ); + } + + buffer[nBytes++] = ( das->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ + buffer[nBytes++] = 2u; + + buffer[nBytes++] = ( das->speech ? PI_AD_SPEECH_INDICATED : 0 ) | + ( das->music ? PI_AD_MUSIC_INDICATED : 0 ) | + ( das->ambiance ? PI_AD_AMBIANCE_INDICATED : 0 ); + buffer[nBytes++] = ( (uint8_t) das->sli & MASK_4BIT ) << 4; + + *nBytesWritten = nBytes; + return IVAS_ERR_OK; +} + +static ivas_error unpackDynamicSuppression( const uint8_t *buffer, uint32_t numDataBytes, IVAS_PIDATA_GENERIC *piData ) +{ + IVAS_PIDATA_DYNAMIC_SUPPRESSION *das = (IVAS_PIDATA_DYNAMIC_SUPPRESSION *) piData; + + /* Dynamic Suppression data is 2 bytes */ + if ( numDataBytes != 2 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "Incorrect size to unpack DAS PI data" ); + } + + das->size = sizeof( IVAS_PIDATA_AUDIO_DESC ); + das->speech = ( buffer[0] & PI_AD_SPEECH_INDICATED ) != 0; + das->music = ( buffer[0] & PI_AD_MUSIC_INDICATED ) != 0; + das->ambiance = ( buffer[0] & PI_AD_AMBIANCE_INDICATED ) != 0; + das->sli = ( buffer[1] >> 4 ); + + return IVAS_ERR_OK; +} + +static ivas_error packListenerPosition( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ) +{ + uint32_t nBytes = 0; + const IVAS_PIDATA_LISTENER_POSITION *listener = (const IVAS_PIDATA_LISTENER_POSITION *) piData; + + *nBytesWritten = 0; + + if ( piData->size != sizeof( IVAS_PIDATA_LISTENER_POSITION ) ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect size in LISTENER POSITION PI data" ); + } + + if ( piData->piDataType != IVAS_PI_LISTENER_POSITION ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect PI ID in LISTENER POSITION PI data" ); + } + + /* Position data is 6 bytes, header is 2 bytes */ + if ( maxDataBytes < 6 + 2 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack LISTENER POSITION PI data" ); + } + + buffer[nBytes++] = ( listener->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ + buffer[nBytes++] = 6; + nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( listener->position.x / MAX_PI_POSITION_METERS ) ); + nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( listener->position.y / MAX_PI_POSITION_METERS ) ); + nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( listener->position.z / MAX_PI_POSITION_METERS ) ); + *nBytesWritten = nBytes; + return IVAS_ERR_OK; +} + +static ivas_error unpackListenerPosition( const uint8_t *buffer, uint32_t numDataBytes, IVAS_PIDATA_GENERIC *piData ) +{ + IVAS_PIDATA_LISTENER_POSITION *listener = (IVAS_PIDATA_LISTENER_POSITION *) piData; + + /* Position data is 6 bytes */ + if ( numDataBytes != 6 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "Incorrect size to unpack LISTENER POSITION PI data" ); + } + + listener->size = sizeof( IVAS_PIDATA_LISTENER_POSITION ); + listener->piDataType = IVAS_PI_LISTENER_POSITION; + listener->position.x = FLOAT_FROM_Q15( readInt16( &buffer[0] ) ) * MAX_PI_POSITION_METERS; + listener->position.y = FLOAT_FROM_Q15( readInt16( &buffer[2] ) ) * MAX_PI_POSITION_METERS; + listener->position.z = FLOAT_FROM_Q15( readInt16( &buffer[4] ) ) * MAX_PI_POSITION_METERS; + return IVAS_ERR_OK; +} + +static ivas_error packDiegetic( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ) +{ + uint32_t nBytes = 0, n; + uint8_t byte = 0; + const IVAS_PIDATA_DIEGETIC *diegetic = (const IVAS_PIDATA_DIEGETIC *) piData; + + *nBytesWritten = 0; + + if ( piData->size != sizeof( IVAS_PIDATA_DIEGETIC ) ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect size in Diegetic Type PI data" ); + } + + if ( piData->piDataType != IVAS_PI_DIEGETIC_TYPE ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect PI ID in Diegetic Type PI data" ); + } + + /* Diegetic data is 1 bytes, header is 2 bytes */ + if ( maxDataBytes < 1 + 2 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack Diegetic Type PI data" ); + } + + /* Valid bits must be based on active bits defined for the input format */ + for ( n = 0; n < ( IVAS_MAX_NUM_OBJECTS + 1 ); n++ ) + { + byte <<= 1; + byte |= ( diegetic->isDiegetic[n] ); + } + byte <<= 3; + + buffer[nBytes++] = ( diegetic->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ + buffer[nBytes++] = 1; + buffer[nBytes++] = byte; + *nBytesWritten = nBytes; + return IVAS_ERR_OK; +} + +static ivas_error unpackDiegetic( const uint8_t *buffer, uint32_t numDataBytes, IVAS_PIDATA_GENERIC *piData ) +{ + uint32_t n; + IVAS_PIDATA_DIEGETIC *diegetic = (IVAS_PIDATA_DIEGETIC *) piData; + uint8_t byte; + + /* Diegetic data is 1 bytes */ + if ( numDataBytes != 1 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "Incorrect size to unpack Diegetic PI data" ); + } + + diegetic->size = sizeof( IVAS_PIDATA_DIEGETIC ); + diegetic->piDataType = IVAS_PI_DIEGETIC_TYPE; + + byte = buffer[0]; + /* Valid bits must be based on active bits defined for the input format */ + for ( n = 0; n < ( IVAS_MAX_NUM_OBJECTS + 1 ); n++ ) + { + diegetic->isDiegetic[n] = ( ( byte >> ( 7 - n ) ) & 1 ) != 0; + } + + return IVAS_ERR_OK; +} + +static ivas_error packAudioFocusCommon( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ) +{ + uint32_t nBytes = 0; + uint8_t packedSize = 1; + const IVAS_PIDATA_AUDIO_FOCUS *audioFocus = (const IVAS_PIDATA_AUDIO_FOCUS *) piData; + + *nBytesWritten = 0; + + if ( piData->size != sizeof( IVAS_PIDATA_AUDIO_FOCUS ) ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect size in PI data of type Audio Focus" ); + } + + if ( audioFocus->availDirection && audioFocus->availLevel ) + { + packedSize = 9; + } + else if ( audioFocus->availDirection ) + { + packedSize = 8; + } + else if ( audioFocus->availLevel ) + { + packedSize = 1; + } + else + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Neither direction or level is available for packing Audio Focus" ); + } + + /* Audio Focus data is packedSize bytes, header is 2 bytes */ + if ( maxDataBytes < (uint32_t) packedSize + 2 ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Insufficient space to pack Audio Focus PI data" ); + } + + buffer[nBytes++] = ( audioFocus->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ + buffer[nBytes++] = packedSize; + + if ( packedSize == 9 || packedSize == 8 ) + { + nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( audioFocus->direction.w ) ); + nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( audioFocus->direction.x ) ); + nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( audioFocus->direction.y ) ); + nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( audioFocus->direction.z ) ); + } + if ( packedSize == 9 || packedSize == 1 ) + { + buffer[nBytes++] = ( (uint8_t) audioFocus->flvl & MASK_4BIT ) << 4; + } + + *nBytesWritten = nBytes; + return IVAS_ERR_OK; +} + +static ivas_error unpackAudioFocusCommon( const uint8_t *buffer, uint32_t numDataBytes, IVAS_PIDATA_GENERIC *piData ) +{ + IVAS_PIDATA_AUDIO_FOCUS *audioFocus = (IVAS_PIDATA_AUDIO_FOCUS *) piData; + + /* Audio Focus data is either 1, 8 or 9 bytes */ + if ( numDataBytes != 1 && numDataBytes != 8 && numDataBytes != 9 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "Incorrect size to unpack PI data of type Audio Focus" ); + } + + piData->size = sizeof( IVAS_PIDATA_AUDIO_FOCUS ); + audioFocus->availDirection = ( numDataBytes >= 8 ); + audioFocus->availLevel = ( numDataBytes == 1 || numDataBytes == 9 ); + + if ( numDataBytes == 1 ) + { + audioFocus->flvl = ( buffer[0] >> 4 ); + } + else + { + audioFocus->direction.w = FLOAT_FROM_Q15( readInt16( &buffer[0] ) ); + audioFocus->direction.x = FLOAT_FROM_Q15( readInt16( &buffer[2] ) ); + audioFocus->direction.y = FLOAT_FROM_Q15( readInt16( &buffer[4] ) ); + audioFocus->direction.z = FLOAT_FROM_Q15( readInt16( &buffer[6] ) ); + + if ( numDataBytes == 9 ) + { + audioFocus->flvl = ( buffer[8] >> 4 ); + } + } + + return IVAS_ERR_OK; +} + + +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ + +static const PACK_PI_FN packPiDataFuntions[IVAS_PI_MAX_ID] = { + packOrientation, /* SCENE_ORIENTATION */ + packOrientation, /* DEVICE_ORIENTATION_COMPENSATED */ + packOrientation, /* DEVICE_ORIENTATION_UNCOMPENSATED */ + packAcousticEnvironment, /* ACOUSTIC_ENVIRONMENT */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + packAudioDescription, /* AUDIO_DESCRIPTION */ +#else + packUnsupportedData, /* AUDIO_DESCRIPTION */ +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ + packUnsupportedData, /* ISM_NUM */ + packUnsupportedData, /* ISM_ID */ + packUnsupportedData, /* ISM_GAIN */ + packUnsupportedData, /* ISM_ORIENTATION */ + packUnsupportedData, /* ISM_POSITION */ + packUnsupportedData, /* ISM_DISTANCE_ATTENUATION */ + packUnsupportedData, /* ISM_DIRECTIVITY */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + packDiegetic, /* DIEGETIC_TYPE */ +#else + packUnsupportedData, /* DIEGETIC_TYPE */ +#endif + packUnsupportedData, /* RESERVED13 */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + packAudioFocusCommon, /* AUDIO_FOCUS_INDICATION */ +#else + packUnsupportedData, /* AUDIO_FOCUS_INDICATION */ +#endif + packUnsupportedData, /* RESERVED15 */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + packOrientation, /* PLAYBACK_DEVICE_ORIENTATION */ + packOrientation, /* HEAD_ORIENTATION */ + packListenerPosition, /* LISTENER_POSITION */ + packDynamicSuppression, /* DYNAMIC_AUDIO_SUPPRESSION */ + packAudioFocusCommon, /* AUDIO_FOCUS_REQUEST */ +#else + packUnsupportedData, /* PLAYBACK_DEVICE_ORIENTATION */ + packUnsupportedData, /* HEAD_ORIENTATION */ + packUnsupportedData, /* LISTENER_POSITION */ + packUnsupportedData, /* DYNAMIC_AUDIO_SUPPRESSION */ + packUnsupportedData, /* AUDIO_FOCUS_DIRECTION */ +#endif + packUnsupportedData, /* PI_LATENCY */ + packUnsupportedData, /* R_ISM_ID */ + packUnsupportedData, /* R_ISM_GAIN */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + packOrientation, /* R_ISM_ORIENTATION */ +#else + packUnsupportedData, /* R_ISM_ORIENTATION */ +#endif + packUnsupportedData, /* R_ISM_POSITION */ + packUnsupportedData, /* R_ISM_DIRECTION */ + packUnsupportedData, /* RESERVED27 */ + packUnsupportedData, /* RESERVED28 */ + packUnsupportedData, /* RESERVED29 */ + packUnsupportedData, /* RESERVED30 */ + packNoPiData /* NO_DATA */ +}; + +static const UNPACK_PI_FN unpackPiDataFuntions[IVAS_PI_MAX_ID] = { + unpackOrientation, /* SCENE_ORIENTATION */ + unpackOrientation, /* DEVICE_ORIENTATION_COMPENSATED */ + unpackOrientation, /* DEVICE_ORIENTATION_UNCOMPENSATED */ + unpackAcousticEnvironment, /* ACOUSTIC_ENVIRONMENT */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + unpackAudioDescription, /* AUDIO_DESCRIPTION */ +#else + unpackUnsupportedData, /* AUDIO_DESCRIPTION */ +#endif + unpackUnsupportedData, /* ISM_NUM */ + unpackUnsupportedData, /* ISM_ID */ + unpackUnsupportedData, /* ISM_GAIN */ + unpackUnsupportedData, /* ISM_ORIENTATION */ + unpackUnsupportedData, /* ISM_POSITION */ + unpackUnsupportedData, /* ISM_DISTANCE_ATTENUATION */ + unpackUnsupportedData, /* ISM_DIRECTIVITY */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + unpackDiegetic, /* DIEGETIC_TYPE */ +#else + unpackUnsupportedData, /* DIEGETIC_TYPE */ +#endif + unpackUnsupportedData, /* RESERVED13 */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + unpackAudioFocusCommon, /* AUDIO_FOCUS_INDICATION */ +#else + unpackUnsupportedData, /* AUDIO_FOCUS_INDICATION */ +#endif + unpackUnsupportedData, /* RESERVED15 */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + unpackOrientation, /* PLAYBACK_DEVICE_ORIENTATION */ + unpackOrientation, /* HEAD_ORIENTATION */ + unpackListenerPosition, /* LISTENER_POSITION */ + unpackDynamicSuppression, /* DYNAMIC_AUDIO_SUPPRESSION */ + unpackAudioFocusCommon, /* AUDIO_FOCUS_REQUEST */ +#else + unpackUnsupportedData, /* PLAYBACK_DEVICE_ORIENTATION */ + unpackUnsupportedData, /* HEAD_ORIENTATION */ + unpackUnsupportedData, /* LISTENER_POSITION */ + unpackUnsupportedData, /* DYNAMIC_AUDIO_SUPPRESSION */ + unpackUnsupportedData, /* AUDIO_FOCUS_DIRECTION */ +#endif + unpackUnsupportedData, /* PI_LATENCY */ + unpackUnsupportedData, /* R_ISM_ID */ + unpackUnsupportedData, /* R_ISM_GAIN */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + unpackOrientation, /* R_ISM_ORIENTATION */ +#else + unpackUnsupportedData, /* R_ISM_ORIENTATION */ +#endif + unpackUnsupportedData, /* R_ISM_POSITION */ + unpackUnsupportedData, /* R_ISM_DIRECTION */ + unpackUnsupportedData, /* RESERVED27 */ + unpackUnsupportedData, /* RESERVED28 */ + unpackUnsupportedData, /* RESERVED29 */ + unpackUnsupportedData, /* RESERVED30 */ + unpackNoPiData /* NO_DATA */ +}; + +static const uint32_t maxPiDataSize[IVAS_PI_MAX_ID] = { + 8, /* IVAS_PI_SCENE_ORIENTATION */ + 8, /* IVAS_PI_DEVICE_ORIENTATION_COMPENSATED */ + 8, /* IVAS_PI_DEVICE_ORIENTATION_UNCOMPENSATED */ + 8, /* IVAS_PI_ACOUSTIC_ENVIRONMENT */ + 5, /* IVAS_PI_AUDIO_DESCRIPTION */ + 1, /* IVAS_PI_ISM_NUM */ + 4, /* IVAS_PI_ISM_ID */ + 4, /* IVAS_PI_ISM_GAIN */ + 32, /* IVAS_PI_ISM_ORIENTATION */ + 24, /* IVAS_PI_ISM_POSITION */ + 12, /* IVAS_PI_ISM_DISTANCE_ATTENUATION */ + 8, /* IVAS_PI_ISM_DIRECTIVITY */ + 1, /* IVAS_PI_DIEGETIC_TYPE */ + 0, /* IVAS_PI_RESERVED13 */ + 9, /* IVAS_PI_AUDIO_FOCUS_INDICATION */ + 0, /* IVAS_PI_RESERVED15 */ + 8, /* IVAS_PI_PLAYBACK_DEVICE_ORIENTATION */ + 8, /* IVAS_PI_HEAD_ORIENTATION */ + 6, /* IVAS_PI_LISTENER_POSITION */ + 2, /* IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION */ + 9, /* IVAS_PI_AUDIO_FOCUS_REQUEST */ + 4, /* IVAS_PI_PI_LATENCY */ + 1, /* IVAS_PI_R_ISM_ID */ + 1, /* IVAS_PI_R_ISM_GAIN */ + 8, /* IVAS_PI_R_ISM_ORIENTATION */ + 6, /* IVAS_PI_R_ISM_POSITION */ + 2, /* IVAS_PI_R_ISM_DIRECTION */ + 0, /* IVAS_PI_RESERVED27 */ + 0, /* IVAS_PI_RESERVED28 */ + 0, /* IVAS_PI_RESERVED29 */ + 0, /* IVAS_PI_RESERVED30 */ + 0, /* IVAS_PI_NO_DATA = 31 */ +}; + +ivas_error PI_PackData( const IVAS_PIDATA_GENERIC *piData, PIDATA_PACKED *packed, uint8_t pmBits ) +{ + uint32_t type = (IVAS_PI_TYPE) ( piData->piDataType & MASK_5BIT ); + ivas_error error = packPiDataFuntions[type]( piData, packed->data, sizeof( packed->data ), &packed->size ); + if ( error == IVAS_ERR_OK ) + { + packed->data[0] |= pmBits; /* Update the PM bits */ + } + assert( packed->size != 0 ); + return error; +} + +ivas_error PI_UnPackData( uint8_t piDataType, uint32_t piSize, const uint8_t *piDataBuffer, IVAS_PIDATA_GENERIC *piData ) +{ + ivas_error error; + + /* Sanitize maximum sizes for each PI Type */ + if ( piSize > maxPiDataSize[piDataType] ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "Max size for PI Data type exceeded" ); + } + + error = unpackPiDataFuntions[piDataType]( piDataBuffer, piSize, piData ); + ERR_CHECK_RETURN( error ); + + /* since some pi data share piData structure, pi id are re-filled after unpacking */ + piData->piDataType = piDataType; + + return IVAS_ERR_OK; +} + +/* PIDATA Tables */ +const float mapRT60[1u << NBITS_RT60] = { + 0.01f, 0.0126f, 0.0159f, 0.02f, 0.0252f, 0.0317f, 0.04f, 0.0504f, + 0.0635f, 0.08f, 0.1008f, 0.1270f, 0.16f, 0.2016f, 0.2540f, 0.32f, + 0.4032f, 0.5080f, 0.64f, 0.8063f, 1.0159f, 1.28f, 1.6127f, 2.0319f, + 2.56f, 3.2254f, 4.0637f, 5.12f, 6.4508f, 8.1275f, 10.24f, 12.9016f +}; + +const float mapDSR[1u << NBITS_DSR] = { + -20.f, -21.f, -22.f, -23.f, -24.f, -25.f, -26.f, -27.f, + -28.f, -29.f, -30.f, -31.f, -32.f, -33.f, -34.f, -35.f, + -36.f, -37.f, -38.f, -39.f, -40.f, -41.f, -42.f, -43.f, + -44.f, -45.f, -46.f, -47.f, -48.f, -49.f, -50.f, -51.f, + -52.f, -53.f, -54.f, -55.f, -56.f, -57.f, -58.f, -59.f, + -60.f, -61.f, -62.f, -63.f, -64.f, -65.f, -66.f, -67.f, + -68.f, -69.f, -70.f, -71.f, -72.f, -73.f, -74.f, -75.f, + -76.f, -77.f, -78.f, -79.f, -80.f, -81.f, -82.f, -83.f +}; + +const float mapRoomDims[1u << NBITS_DIM] = { + 0.5f, 0.707f, 1.f, 1.4141f, 2, 2.8282f, 4.f, 5.6568f, + 8.f, 11.314f, 16.f, 22.627f, 32.f, 45.255f, 64.f, 90.51f +}; + +const float mapAbsorbtion[1u << NBITS_ABS] = { + 0.0800f, 0.1656f, 0.3430f, 0.7101f +}; + + +#endif /* IVAS_RTPDUMP */ diff --git a/lib_util/ivas_rtp_pi_data.h b/lib_util/ivas_rtp_pi_data.h new file mode 100644 index 0000000000000000000000000000000000000000..dc4c7f8bafd5eda274df74b419677fd28ec1c64a --- /dev/null +++ b/lib_util/ivas_rtp_pi_data.h @@ -0,0 +1,472 @@ +/****************************************************************************************************** + + (C) 2022-2025 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_RTP_PI_DATA_H +#define IVAS_RTP_PI_DATA_H + +#include "common_api_types.h" + +#ifdef IVAS_RTPDUMP + +#define IVAS_PI_MAX_DATA_SIZE ( 32 + 2 ) /* max packed PI data bytes + pi header bytes */ + +/* IVAS PI Data Types */ +typedef enum +{ + /* Forward direction PI types */ + IVAS_PI_SCENE_ORIENTATION, /* orientation of audio scene in unit quaternions */ + IVAS_PI_DEVICE_ORIENTATION_COMPENSATED, /* orientation of device in unit quaternions (compensated) */ + IVAS_PI_DEVICE_ORIENTATION_UNCOMPENSATED, /* orientation of device in unit quaternions (un-compensated) */ + IVAS_PI_ACOUSTIC_ENVIRONMENT, /* describe the acoustic environment */ +#ifdef RTP_S4_251135_CR26253_0016_REV1 + IVAS_PI_AUDIO_DESCRIPTION, /* audio content description (voice/music/ambiance) */ + IVAS_PI_ISM_NUM, /* Number of objects */ + IVAS_PI_ISM_ID, /* id of each object */ + IVAS_PI_ISM_GAIN, /* gain of each object */ + IVAS_PI_ISM_ORIENTATION, /* orientation of each object */ + IVAS_PI_ISM_POSITION, /* position of each object */ + IVAS_PI_ISM_DISTANCE_ATTENUATION, /* distance attenuation for each object */ + IVAS_PI_ISM_DIRECTIVITY, /* directivity of each object */ + IVAS_PI_DIEGETIC_TYPE, /* digetic audio indication */ + IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION_INDICATION, /* audio suppression indication */ + IVAS_PI_AUDIO_FOCUS_INDICATION, /* audio focus indication (direction in Quaternions and/or level) */ + IVAS_PI_RESERVED15, /* reserved */ + + /* Reverse direction PI types */ + IVAS_PI_PLAYBACK_DEVICE_ORIENTATION, /* orientation of the playback device in quaternions */ + IVAS_PI_HEAD_ORIENTATION, /* head orientation of the listener in Quaternions */ + IVAS_PI_LISTENER_POSITION, /* position of the listener in 3D space */ + IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION_REQUEST, /* receiver’s preference with respect to audio suppression */ + IVAS_PI_AUDIO_FOCUS_REQUEST, /* direction of interest for the listener in Quaternions and/or audio focus level */ + IVAS_PI_PI_LATENCY, /* round-trip latency for PI frames */ + IVAS_PI_R_ISM_ID, /* id of an object for editing */ + IVAS_PI_R_ISM_GAIN, /* editing request for gain factor for received object */ + IVAS_PI_R_ISM_ORIENTATION, /* editing request for orientation for received object */ + IVAS_PI_R_ISM_POSITION, /* editing request for position for received object */ + IVAS_PI_R_ISM_DIRECTION, /* editing request for direction for received object */ + IVAS_PI_RESERVED27, /* reserved */ + IVAS_PI_RESERVED28, /* reserved */ + IVAS_PI_RESERVED29, /* reserved */ + IVAS_PI_RESERVED30, /* reserved */ +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ + IVAS_PI_NO_DATA = 31, /* Indicates an empty PI data frame */ + IVAS_PI_MAX_ID /* Max number of PI data IDs supprted */ +} IVAS_PI_TYPE; + +/* cartesian coordinates (X,Y,Z) in 3D space */ +typedef struct +{ + float x, y, z; +} IVAS_COORDINATE; + +/* orientation data corresponding to any of the following pi data types :- + * - IVAS_PI_SCENE_ORIENTATION + * - IVAS_PI_DEVICE_ORIENTATION_COMPENSATED + * - IVAS_PI_DEVICE_ORIENTATION_UNCOMPENSATED + * - IVAS_PI_PLAYBACK_DEVICE_ORIENTATION + * - IVAS_PI_HEAD_ORIENTATION + * - IVAS_PI_R_ISM_ORIENTATION + * + * piDataType is used to identify the correct pi data type contained here + */ +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_SCENE_ORIENTATION) */ + uint32_t piDataType; /* one of supported orientation data types */ + IVAS_QUATERNION orientation; /* orientation data expressed as quartenions */ +} IVAS_PIDATA_ORIENTATION; + +/* Acoustic environment corresponding to IVAS_PI_ACOUSTIC_ENVIRONMENT + * + * acoustic environment ID + * late reverb parameters + * - RT60 – indicating the time that it takes for the reflections to reduce 60 dB in energy level, per frequency band + * - DSR – diffuse to source signal energy ratio, per frequency band + * - Pre-delay – delay at which the computation of DSR values was performed + * early reflections + * - 3D rectangular virtual room dimensions + * - Broadband energy absorption coefficient per wall surface + */ +typedef enum +{ + IVAS_PI_AE_LOW, /* center frequency 25 Hz */ + IVAS_PI_AE_MID, /* center frequency 250 Hz */ + IVAS_PI_AE_HIGH, /* center frequency 2.5 kHz */ + IVAS_PI_AE_NUM_BANDS /* number of ae bands */ +} IVAS_PI_AE_BANDS; + +typedef enum +{ + IVAS_PI_AE_FRONT, + IVAS_PI_AE_BACK, + IVAS_PI_AE_LEFT, + IVAS_PI_AE_RIGHT, + IVAS_PI_AE_CEILING, + IVAS_PI_AE_FLOOR, + IVAS_PI_AE_NUM_SURFACE +} IVAS_PI_AE_SURFACE; + +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_ACOUSTIC_ENV) */ + uint32_t piDataType; /* IVAS_PI_ACOUSTIC_ENVIRONMENT */ + bool availLateReverb; /* AE contains only late reverb parameters */ + bool availEarlyReflections; /* AE containing late reverb and simplified early reflections */ + uint8_t aeid; /* seven-bit acoustic environment identifier */ + + /* only valid if availLateReverb==true or availEarlyReflections==true */ + float rt60[IVAS_PI_AE_NUM_BANDS]; /* time for the reflections to reduce 60 dB per band in seconds */ + float dsr[IVAS_PI_AE_NUM_BANDS]; /* diffuse to source signal energy ratio per band in dB */ + + /* only valid if availEarlyReflections==true */ + IVAS_COORDINATE roomDimensions; /* room dimensions in meters length (x), width (y), height (z) */ + float absorbCoeffs[IVAS_PI_AE_NUM_SURFACE]; /* absorption coefficients for all surfaces */ +} IVAS_PIDATA_ACOUSTIC_ENV; + +#ifdef RTP_S4_251135_CR26253_0016_REV1 +/* Audio Description corresponding to IVAS_PI_AUDIO_DESCRIPTION + * Describe the following audio decriptors per object/type :- + * - audio content type is speech/music/ambiance + * - if audio rendering is editable + * - if stereo audio is binaural + * + * number of valid entries decide on basis of audio format:- + * - Stereo/SBA/MASA = 1 entry + * - MultiChannel = 2 entries (1 for center channel + 1 for all other channels) + * - ISM = Number of Object entries ( 1 per object ) + * - OMASA/OSBA = 1 + Num Discrete Coded Objects + * + */ +typedef struct +{ + bool speech; /* audio has voice/speech */ + bool music; /* audio has music */ + bool ambiance; /* audio has background ambiance */ + bool editable; /* rendering audio metadata is editable */ + bool binaural; /* stereo stream is binaural */ +} IVAS_AUDIO_ID; + +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_AUDIO_DESC) */ + uint32_t piDataType; /* IVAS_PI_AUDIO_DESCRIPTION */ + uint32_t nValidEntries; /* Number of valid audio IDs */ + IVAS_AUDIO_ID audioId[1 + IVAS_MAX_NUM_OBJECTS]; /* audio id as per format */ +} IVAS_PIDATA_AUDIO_DESC; + +/* ISM specific PI data related to PI types : - + * + * - IVAS_PI_ISM_NUM + * - IVAS_PI_ISM_ID + * - IVAS_PI_ISM_GAIN + * - IVAS_PI_ISM_ORIENTATION + * - IVAS_PI_ISM_POSITION + * - IVAS_PI_ISM_DISTANCE_ATTENUATION + * - IVAS_PI_ISM_DIRECTIVITY + */ + +/* Number of ISMs */ +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_ISM_NUM) */ + uint32_t piDataType; /* IVAS_PI_ISM_NUM */ + uint32_t numObjects; /* Number of ISM */ +} IVAS_PIDATA_ISM_NUM; + +/* ISM ID */ +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_ISM_ID) */ + uint32_t piDataType; /* IVAS_PI_ISM_ID */ + uint8_t id[IVAS_MAX_NUM_OBJECTS]; /* 8-bit ISM id of object */ +} IVAS_PIDATA_ISM_ID; + +/* ISM gain */ +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_ISM_GAIN) */ + uint32_t piDataType; /* IVAS_PI_ISM_GAIN */ + int8_t dB[IVAS_MAX_NUM_OBJECTS]; /* ISM gain in dB per object [-96, +3] */ +} IVAS_PIDATA_ISM_GAIN; + +/* ISM orientation */ +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_ISM_ORIENTATION) */ + uint32_t piDataType; /* IVAS_PI_ISM_ORIENTATION */ + IVAS_QUATERNION orientation[IVAS_MAX_NUM_OBJECTS]; /* Orientation of audio objects in ISM(s) */ +} IVAS_PIDATA_ISM_ORIENTATION; + +/* ISM position */ +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_ISM_POSITION) */ + uint32_t piDataType; /* IVAS_PI_ISM_POSITION */ + IVAS_COORDINATE position[IVAS_MAX_NUM_OBJECTS]; /* Position of audio objects in ISM(s) */ +} IVAS_PIDATA_ISM_POSITION; + +/* ISM distance attenuation comprising of following gains per ISM + * - reference distance + * - maximum distance + * - roll-off factor + */ +typedef struct +{ + float ref_dist; /* reference distance in meters */ + float max_dist; /* maximum distance in meters */ + float roll; /* roll-off factor values */ +} IVAS_DIST_ATTEN; + +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_ISM_ATTENUATION) */ + uint32_t piDataType; /* IVAS_PI_ISM_DISTANCE_ATTENUATION */ + IVAS_DIST_ATTEN distAtten[IVAS_MAX_NUM_OBJECTS]; /* Distance attenuation of audio objects */ +} IVAS_PIDATA_ISM_ATTENUATION; + +/* ISM Directivity comprising of following per ISM :- + * - inner cone angle determines the size of the main cone directed to the front of the object + * - outer cone angle determines the size of the outer (back) cone + * - outer attenuation gain determines the attenuation outside the outer cone + */ +typedef struct +{ + uint16_t innerConeAngle; /* inner cone angle in degrees (0 - 360) */ + uint16_t outerConeAngle; /* outer cone angle in degrees (0 - 360) */ + float outerAttenuationdB; /* attenuation outside the outer cone in dB */ +} IVAS_ISM_DIRECTIVITY; + +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_ISM_DIRECTIVITY) */ + uint32_t piDataType; /* IVAS_PI_ISM_DIRECTIVITY */ + IVAS_ISM_DIRECTIVITY directivity[IVAS_MAX_NUM_OBJECTS]; /* Directivity of audio objects */ +} IVAS_PIDATA_ISM_DIRECTIVITY; + +/* Diegetic and non-diegetic indication flag as per audio format + * + * number of valid entries decided on basis of audio format:- + * - Stereo/SBA/MASA/MultiChannel = 1 entry + * - ISM = Number of Object entries ( 1 per object ) + * - OMASA/OSBA = 1 (last) + Num Discrete Coded Objects + */ +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_DIEGETIC) */ + uint32_t piDataType; /* IVAS_PI_DIEGETIC_TYPE */ + bool isDiegetic[1 + IVAS_MAX_NUM_OBJECTS]; /* diegetic indication as per audio format */ +} IVAS_PIDATA_DIEGETIC; + +/* Audio focus direction indicates a direction of interest. + * The audio focus level indicates the amount of suppression applied to the + * directions other than the audio focus direction. + */ +typedef enum +{ + IVAS_FLVL_NO_AUDIO_FOCUS = 0, /* Apply no audio focus */ + IVAS_FLVL_FOCUS_LEVEL_LEVEL_1, /* Audio focus level 1 */ + IVAS_FLVL_FOCUS_LEVEL_LEVEL_2, /* Audio focus level 2 */ + IVAS_FLVL_FOCUS_LEVEL_LEVEL_3, /* Audio focus level 3 */ + IVAS_FLVL_FOCUS_LEVEL_LEVEL_4, /* Audio focus level 4 */ + IVAS_FLVL_FOCUS_LEVEL_LEVEL_5, /* Audio focus level 5 */ + IVAS_FLVL_FOCUS_LEVEL_LEVEL_6, /* Audio focus level 6 */ + IVAS_FLVL_FOCUS_LEVEL_LEVEL_7, /* Audio focus level 7 */ + IVAS_FLVL_FOCUS_LEVEL_LEVEL_8, /* Audio focus level 8 */ + IVAS_FLVL_FOCUS_LEVEL_LEVEL_9, /* Audio focus level 9 */ + IVAS_FLVL_FOCUS_LEVEL_LEVEL_10, /* Audio focus level 10 */ + IVAS_FLVL_FOCUS_LEVEL_LEVEL_11, /* Audio focus level 11 */ + IVAS_FLVL_FOCUS_LEVEL_LEVEL_12, /* Audio focus level 12 */ + IVAS_FLVL_MAX_AUDIO_FOCUS, /* Apply max audio focus */ + IVAS_FLVL_DEFAULT_AUDIO_FOCUS, /* Default audio focus */ + IVAS_FLVL_NO_PREFERENCE, /* No preference / No indication */ +} IVAS_FLVL; + +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_AUDIO_FOCUS) */ + uint32_t piDataType; /* IVAS_PI_AUDIO_FOCUS_INDCATION or IVAS_PI_AUDIO_FOCUS_REQUEST */ + bool availDirection; /* audio focus contains direction */ + bool availLevel; /* audio focus contains level */ + IVAS_QUATERNION direction; /* direction data expressed as quarternions */ + IVAS_FLVL flvl; /* audio focus level */ +} IVAS_PIDATA_AUDIO_FOCUS; + +/* Listener position */ +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_LISTENER_POSITION) */ + uint32_t piDataType; /* IVAS_PI_LISTENER_POSITION */ + IVAS_COORDINATE position; /* Position of audio objects in ISM(s) */ +} IVAS_PIDATA_LISTENER_POSITION; + + +/* Dynamic Audio Suppression describes receiver’s preference with respect to the + * type of audio content that should be enhanced and the amount of suppression to + * be applied to the background noise + */ +typedef enum +{ + IVAS_SLI_MIN_SUPPRESSION = 0, /* Apply min suppression */ + IVAS_SLI_SUPPRESSION_LEVEL_1, /* Suppression level 1 */ + IVAS_SLI_SUPPRESSION_LEVEL_2, /* Suppression level 2 */ + IVAS_SLI_SUPPRESSION_LEVEL_3, /* Suppression level 3 */ + IVAS_SLI_SUPPRESSION_LEVEL_4, /* Suppression level 4 */ + IVAS_SLI_SUPPRESSION_LEVEL_5, /* Suppression level 5 */ + IVAS_SLI_SUPPRESSION_LEVEL_6, /* Suppression level 6 */ + IVAS_SLI_SUPPRESSION_LEVEL_7, /* Suppression level 7 */ + IVAS_SLI_SUPPRESSION_LEVEL_8, /* Suppression level 8 */ + IVAS_SLI_SUPPRESSION_LEVEL_9, /* Suppression level 9 */ + IVAS_SLI_SUPPRESSION_LEVEL_10, /* Suppression level 10 */ + IVAS_SLI_SUPPRESSION_LEVEL_11, /* Suppression level 11 */ + IVAS_SLI_MAX_SUPPRESSION, /* Apply max suppression */ + IVAS_SLI_NO_SUPPRESSION, /* Apply no suppression */ + IVAS_SLI_DEFAULT_SUPPRESSION, /* Apply default suppression */ + IVAS_SLI_NO_PREFERENCE, /* No preference / No indication */ +} IVAS_SLI; + +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_DYNAMIC_SUPPRESSION) */ + uint32_t piDataType; /* IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION_REQUEST or IVAS_PI_DYNAMIC_AUDIO_SUPPRESSION_INDICATION */ + bool speech; /* receiver's preference is voice/speech */ + bool music; /* receiver's preference is music */ + bool ambiance; /* receiver's preference is background ambiance */ + IVAS_SLI sli; /* suppression level indicator [0, 15] */ +} IVAS_PIDATA_DYNAMIC_SUPPRESSION; + +/* Reverse PI latency calculated as the elapsed time between the sent reverse PI data + * and received forward PI data. It is based on the receiving device experiencing the + * result of its sent data by receiving the corresponding data in forward direction as + * forward PI data + */ +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_REVERSE_PI_LATENCY) */ + uint32_t piDataType; /* IVAS_PI_PI_LATENCY */ + IVAS_PI_TYPE type; /* Reverse PI used for computation of Latency */ + int32_t latency; /* Latency as 27-bit int on RTP Clock @ 16KHz */ +} IVAS_PIDATA_REVERSE_PI_LATENCY; + +/* ISM specific PI data editing requests */ + +/* ISM ID in editing requests */ +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_ISM_EDIT_ID) */ + uint32_t piDataType; /* IVAS_PI_R_ISM_ID */ + uint8_t id; /* 8-bit ISM id of object to edit */ +} IVAS_PIDATA_ISM_EDIT_ID; + +/* Editing request for ISM gain */ +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_ISM_EDIT_GAIN) */ + uint32_t piDataType; /* IVAS_PI_R_ISM_GAIN */ + int8_t dB; /* Preferred ISM gain in dB [-96, +3] */ +} IVAS_PIDATA_ISM_EDIT_GAIN; + +/* Editing request for ISM orientation */ +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_ISM_EDIT_ORIENTATION) */ + uint32_t piDataType; /* IVAS_PI_R_ISM_ORIENTATION */ + IVAS_QUATERNION orientation; /* orientation editing request for received ISM */ +} IVAS_PIDATA_ISM_EDIT_ORIENTATION; + +/* Editing request for ISM position */ +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_ISM_EDIT_POSITION) */ + uint32_t piDataType; /* IVAS_PI_R_ISM_POSITION */ + IVAS_COORDINATE position; /* Positional editing request for received ISM */ +} IVAS_PIDATA_ISM_EDIT_POSITION; + +/* Editing request for ISM direction */ +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_ISM_EDIT_DIRECTION) */ + uint32_t piDataType; /* IVAS_PI_R_ISM_DIRECTION */ + float azimuth; /* azimuth angle in degrees [-180, 180] */ + float elevation; /* elevation angle in degrees [-90°, 90°] */ +} IVAS_PIDATA_ISM_EDIT_DIRECTION; +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ + +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_NO_DATA) */ + uint32_t piDataType; /* IVAS_PI_NO_DATA */ +} IVAS_PIDATA_NO_DATA; + + +typedef union +{ + IVAS_PIDATA_ORIENTATION scene; + IVAS_PIDATA_ORIENTATION deviceCompensated; + IVAS_PIDATA_ORIENTATION deviceUnCompensated; + IVAS_PIDATA_ACOUSTIC_ENV acousticEnv; +#ifdef RTP_S4_251135_CR26253_0016_REV1 + IVAS_PIDATA_AUDIO_DESC audioDesc; + IVAS_PIDATA_ISM_NUM ismNum; + IVAS_PIDATA_ISM_ID ismId; + IVAS_PIDATA_ISM_GAIN ismGain; + IVAS_PIDATA_ISM_ORIENTATION ismOrientation; + IVAS_PIDATA_ISM_POSITION ismPosition; + IVAS_PIDATA_ISM_ATTENUATION ismAttenuation; + IVAS_PIDATA_ISM_DIRECTIVITY ismDirectivity; + IVAS_PIDATA_DIEGETIC digeticIndicator; + IVAS_PIDATA_DYNAMIC_SUPPRESSION dynSuppressionIndication; + IVAS_PIDATA_AUDIO_FOCUS focusIndication; + + IVAS_PIDATA_ORIENTATION playbackOrientation; + IVAS_PIDATA_ORIENTATION headOrientation; + IVAS_PIDATA_LISTENER_POSITION listnerPosition; + IVAS_PIDATA_DYNAMIC_SUPPRESSION dynSuppressionRequest; + IVAS_PIDATA_AUDIO_FOCUS focusRequest; + IVAS_PIDATA_REVERSE_PI_LATENCY piLatency; + IVAS_PIDATA_ISM_EDIT_ID ismEditId; + IVAS_PIDATA_ISM_EDIT_GAIN ismEditGain; + IVAS_PIDATA_ISM_EDIT_ORIENTATION ismEditOrientation; + IVAS_PIDATA_ISM_EDIT_POSITION ismEditPosition; + IVAS_PIDATA_ISM_EDIT_DIRECTION ismEditDirection; +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ + IVAS_PIDATA_NO_DATA noPiData; +} PIDATA; + +typedef struct +{ + PIDATA data; + uint32_t timestamp; +} PIDATA_TS; + +#endif /* IVAS_RTPDUMP */ + +#endif /* IVAS_RTP_PI_DATA_H */ diff --git a/lib_util/ls_custom_file_reader.c b/lib_util/ls_custom_file_reader.c index f91ce18dce179c7b61df95ddf5b7c6c734321424..d874342c11b839c9526f361f8df35bba42423f25 100644 --- a/lib_util/ls_custom_file_reader.c +++ b/lib_util/ls_custom_file_reader.c @@ -181,6 +181,7 @@ static LS_CUSTOM_FILEREADER_ERROR CustomLoudspeakerLayout_validate( } ( *num_azi ) -= dup_count; + for ( i = 0; i < IVAS_MAX_LS_CHANNELS; i++ ) { azi[i] = azi_tmp[i]; @@ -239,8 +240,9 @@ LS_CUSTOM_FILEREADER_ERROR CustomLsFileReading( { LS_CUSTOM_FILEREADER_ERROR error; - char line[200]; /* > (10 chars * IVAS_MAX_OUTPUT_CHANNELS) i.e. "-999, " */ + char line[200]; /* > (10 chars * IVAS_MAX_LS_CHANNELS) i.e. "-999, " */ const char *tok; + int16_t i, num_azi, num_ele, num_lfe; /* initialize variables */ diff --git a/lib_util/masa_file_reader.c b/lib_util/masa_file_reader.c index 7783cad0561dcce7b09433bf146c7ec341a7d3ba..1122878f8a5c8f84d8f50d73c33d644926bc5084 100644 --- a/lib_util/masa_file_reader.c +++ b/lib_util/masa_file_reader.c @@ -33,9 +33,9 @@ #include "masa_file_reader.h" #include "ivas_prot.h" #include "ivas_stat_com.h" +#include "ivas_rom_com.h" /* load 'ivasmasaFormatDescriptor[8]' */ #include #include -#include "ivas_rom_com.h" /* load 'ivasmasaFormatDescriptor[8]' */ struct MasaFileReader diff --git a/lib_util/masa_file_writer.c b/lib_util/masa_file_writer.c index c1aa3ca37a711a80404c98ac883dcebb7540c173..3f269a68717c6d1a55196bb04c5304bb1315dcb7 100644 --- a/lib_util/masa_file_writer.c +++ b/lib_util/masa_file_writer.c @@ -167,6 +167,7 @@ static void delayMasaMetadata( } } + /* Finalize descriptive meta by using new frame except for number of directions which is the larger of the two */ currentNumberOfDirections = extOutMeta->descriptiveMeta.numberOfDirections; if ( delayStorage->descriptiveMeta.numberOfDirections > extOutMeta->descriptiveMeta.numberOfDirections ) @@ -174,7 +175,9 @@ static void delayMasaMetadata( extOutMeta->descriptiveMeta.numberOfDirections = delayStorage->descriptiveMeta.numberOfDirections; } delayStorage->descriptiveMeta.numberOfDirections = currentNumberOfDirections; + delayStorage->prevDelay = delayNsf; + return; } @@ -246,6 +249,7 @@ ivas_error MasaFileWriter_writeFrame( uint16_t descMetaTemp = 0; int16_t i, sf, dir, numDirections; uint8_t writeTempOther[MASA_FREQUENCY_BANDS]; + /* If delay storage has been reserved, then we are in the normal mode for the decoder * (i.e., no delay compensation for PCM) which means that metadata should be delayed * by two or three subframes (10 or 15 ms). Descriptive metadata is a combined result. */ diff --git a/lib_util/masa_file_writer.h b/lib_util/masa_file_writer.h index 74d098388c0e5acf03f777d75d6868f496bf3c6e..e9f6e062a31b937114d986a036ef7fa8d487ea38 100644 --- a/lib_util/masa_file_writer.h +++ b/lib_util/masa_file_writer.h @@ -34,6 +34,7 @@ #define IVAS_MASA_FILE_WRITER_H #include "common_api_types.h" +#include "options.h" #include diff --git a/lib_util/mime_io.c b/lib_util/mime_io.c index ee2a9c12a5695cb469962508449e0101fcc4794f..1ecd603b32a752b4f819a3636bdedfd1179c4209 100644 --- a/lib_util/mime_io.c +++ b/lib_util/mime_io.c @@ -305,7 +305,9 @@ MIME_ERROR MIME_Writer_Close( } -static bool readByte( FILE *file, uint8_t *value ) +static bool readByte( + FILE *file, + uint8_t *value ) { if ( fread( value, 1, 1, file ) != 1U ) { @@ -314,14 +316,13 @@ static bool readByte( FILE *file, uint8_t *value ) return true; } -static bool readLong( FILE *file, uint16_t *value ) +static bool readLong( + FILE *file, + uint16_t *value ) { char buffer[4] = { 0 }; -#ifdef CODE_IMPROVEMENTS + if ( fread( buffer, 1, 4, file ) != 1U ) -#else - if ( fread( buffer, 4, 1, file ) != 1U ) -#endif { return false; } @@ -346,7 +347,10 @@ static bool readLong( FILE *file, uint16_t *value ) * to the serial bitstream. *-------------------------------------------------------------------*/ -static void byteToSerialReordered( uint8_t byte, uint16_t *serial, const int16_t *sort_indices ) +static void byteToSerialReordered( + uint8_t byte, + uint16_t *serial, + const int16_t *sort_indices ) { for ( uint32_t i = 0; i < 8; ++i ) { @@ -360,8 +364,11 @@ static void byteToSerialReordered( uint8_t byte, uint16_t *serial, const int16_t byte <<= 1; } + + return; } + /*-------------------------------------------------------------------* * byteToSerial() * @@ -369,18 +376,25 @@ static void byteToSerialReordered( uint8_t byte, uint16_t *serial, const int16_t * to the given serial bitstream array. *-------------------------------------------------------------------*/ -static void byteToSerial( uint8_t byte, uint16_t *serial ) +static void byteToSerial( + uint8_t byte, + uint16_t *serial ) { const int16_t indices[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + byteToSerialReordered( byte, serial, indices ); + + return; } -static MIME_ERROR readHeader( MIME_HANDLE hMIME ) + +static MIME_ERROR readHeader( + MIME_HANDLE hMIME ) { const char id[] = "#!EVS_MC1.0\n"; const uint16_t num_char_id = sizeof( id ) - 1; - char buffer[sizeof( id )] = { 0 }; + if ( fread( buffer, sizeof( char ), num_char_id, hMIME->file ) != num_char_id ) { return MIME_READ_ERROR; @@ -398,13 +412,17 @@ static MIME_ERROR readHeader( MIME_HANDLE hMIME ) return MIME_NO_ERROR; } + + /*-------------------------------------------------------------------* * MIME_Reader_Open_filename() * * Open MIME reader *-------------------------------------------------------------------*/ -MIME_ERROR MIME_Reader_Open_filename( MIME_HANDLE *phMIME, const char *filename ) +MIME_ERROR MIME_Reader_Open_filename( + MIME_HANDLE *phMIME, + const char *filename ) { MIME_ERROR error = MIME_NO_ERROR; @@ -440,7 +458,8 @@ MIME_ERROR MIME_Reader_Open_filename( MIME_HANDLE *phMIME, const char *filename * Rewind currently opened file to beginning *-------------------------------------------------------------------*/ -MIME_ERROR MIME_Reader_Rewind( MIME_HANDLE hMIME ) +MIME_ERROR MIME_Reader_Rewind( + MIME_HANDLE hMIME ) { if ( !hMIME || !hMIME->file ) { @@ -455,7 +474,13 @@ MIME_ERROR MIME_Reader_Rewind( MIME_HANDLE hMIME ) return MIME_NO_ERROR; } -static MIME_ERROR readEvsFrame( FILE *file, uint8_t ToC, uint16_t *serial, int16_t *num_bits, int16_t *bfi ) + +static MIME_ERROR readEvsFrame( + FILE *file, + uint8_t ToC, + uint16_t *serial, + int16_t *num_bits, + int16_t *bfi ) { switch ( ToC & 0x0f ) { @@ -524,7 +549,13 @@ static MIME_ERROR readEvsFrame( FILE *file, uint8_t ToC, uint16_t *serial, int16 return MIME_NO_ERROR; } -static MIME_ERROR readAmrWbFrame( FILE *file, uint8_t ToC, uint16_t *serial, int16_t *num_bits, int16_t *bfi ) + +static MIME_ERROR readAmrWbFrame( + FILE *file, + uint8_t ToC, + uint16_t *serial, + int16_t *num_bits, + int16_t *bfi ) { const uint8_t mode = ToC & 0x0f; @@ -595,12 +626,18 @@ static MIME_ERROR readAmrWbFrame( FILE *file, uint8_t ToC, uint16_t *serial, int return MIME_NO_ERROR; } + /*-------------------------------------------------------------------* * MIME_ReadFrame_short() * * Read MIME frame to serial bitstream *-------------------------------------------------------------------*/ -MIME_ERROR MIME_ReadFrame_short( MIME_HANDLE hMIME, uint16_t *serial, int16_t *num_bits, int16_t *bfi ) + +MIME_ERROR MIME_ReadFrame_short( + MIME_HANDLE hMIME, + uint16_t *serial, + int16_t *num_bits, + int16_t *bfi ) { if ( !hMIME ) { @@ -637,12 +674,16 @@ MIME_ERROR MIME_ReadFrame_short( MIME_HANDLE hMIME, uint16_t *serial, int16_t *n return MIME_NO_ERROR; } + + /*-------------------------------------------------------------------* * MIME_Reader_Close() * * Close MIME reader *-------------------------------------------------------------------*/ -MIME_ERROR MIME_Reader_Close( MIME_HANDLE *phMIME ) + +MIME_ERROR MIME_Reader_Close( + MIME_HANDLE *phMIME ) { if ( phMIME == NULL || *phMIME == NULL ) { diff --git a/lib_util/mutex.h b/lib_util/mutex.h new file mode 100644 index 0000000000000000000000000000000000000000..82094b61c823e909f22282f982413abe037489f6 --- /dev/null +++ b/lib_util/mutex.h @@ -0,0 +1,104 @@ +/****************************************************************************************************** + + (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +/*==================================================================================== + EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 + ====================================================================================*/ + +#ifndef _MUTEX_H +#define _MUTEX_H + +#if defined( __unix__ ) || defined( __linux__ ) || ( defined( __MACH__ ) && defined( __APPLE__ ) ) +#include +typedef pthread_mutex_t mtx_t; +#define _USE_POSIX ( 1 ) +#elif defined( _WIN32 ) || defined( _WIN64 ) +#include +typedef CRITICAL_SECTION mtx_t; +#define _USE_WIN ( 1 ) +#else +typedef int mtx_t; +#warning Mutex implementation to be defined for this platform here. +#endif + +static __inline int mtx_init( mtx_t *mutex, int type ) +{ + int err = 0; + (void) type; +#ifdef _USE_POSIX + err = pthread_mutex_init( mutex, NULL ); +#elif defined( _USE_WIN ) + InitializeCriticalSection( mutex ); +#else + (void) mutex; +#endif + return err; +} + +static __inline void mtx_destroy( mtx_t *mutex ) +{ +#if _USE_POSIX + pthread_mutex_destroy( mutex ); +#elif defined( _USE_WIN ) + DeleteCriticalSection( mutex ); +#else + (void) mutex; +#endif +} + +static __inline int mtx_lock( mtx_t *mutex ) +{ + int err = 0; +#if _USE_POSIX + err = pthread_mutex_lock( mutex ); +#elif defined( _USE_WIN ) + EnterCriticalSection( mutex ); +#else + (void) mutex; +#endif + return err; +} + +static __inline int mtx_unlock( mtx_t *mutex ) +{ + int err = 0; +#if _USE_POSIX + err = pthread_mutex_unlock( mutex ); +#elif defined( _USE_WIN ) + LeaveCriticalSection( mutex ); +#else + (void) mutex; +#endif + return err; +} + +#endif /* _MUTEX_H */ diff --git a/lib_util/obj_edit_file_reader.c b/lib_util/obj_edit_file_reader.c index 5f28818f6f9e96cb60d2c68053fb860e09c7b2f1..2dde08ecc3936931f11956757739ede7521439a9 100644 --- a/lib_util/obj_edit_file_reader.c +++ b/lib_util/obj_edit_file_reader.c @@ -30,12 +30,19 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ +#include "obj_edit_file_reader.h" #include #include -#include "obj_edit_file_reader.h" -#include "prot.h" +#ifndef min +#define min( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) ) +#endif + +#ifndef max +#define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) +#endif + /*-----------------------------------------------------------------------* * ObjectEditFileReader_open() * diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 57f500a671a63d4d44638eb03e02559697301e2e..7729efbc7cb0ffe9ca4174f7aa12ea7012c5a67c 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -85,7 +85,6 @@ #define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) #endif - /*------------------------------------------------------------------------------------------* * Local Type definitions *------------------------------------------------------------------------------------------*/ @@ -663,36 +662,13 @@ static ivas_error read_bin_code_word( } } } - return IVAS_ERR_INVALID_RENDER_CONFIG; } - -/*-------------------------------------------------------------------* - * usdequant_rend_cfg() - * - * Uniform scalar de-quantizer routine - *-------------------------------------------------------------------*/ - -static float usdequant_rend_cfg( - const uint32_t idx, /* i : quantizer index */ - const float qlow, /* i : lowest codebook entry (index 0) */ - const float delta /* i : quantization step */ -) -{ - float g; - - g = idx * delta + qlow; - - return ( g ); -} - - /*-----------------------------------------------------------------------------------------* * Function get_bin_count_or_index() * Gets a count or index *-----------------------------------------------------------------------------------------*/ - static ivas_error get_bin_count_or_index( RenderConfigReader *this, /* i/o : Renderer config reader handle */ uint32_t *pResult /* o : Count or index value */ @@ -990,6 +966,25 @@ static ivas_error read_txt_bool( } +/*-------------------------------------------------------------------* + * usdequant_rend_cfg() + * + * Uniform scalar de-quantizer routine + *-------------------------------------------------------------------*/ + +static float usdequant_rend_cfg( + const uint32_t idx, /* i : quantizer index */ + const float qlow, /* i : lowest codebook entry (index 0) */ + const float delta /* i : quantization step */ +) +{ + float g; + + g = idx * delta + qlow; + + return ( g ); +} + /*-----------------------------------------------------------------------------------------* * Function get_bin_angle() * Gets an angle value in degrees [0,360] @@ -1013,7 +1008,6 @@ static ivas_error get_bin_angle( return IVAS_ERR_OK; } - /*-----------------------------------------------------------------------------------------* * Function get_bin_outer_attenuation () * Gets an outer attenuation value [3.1623e-05,1.0], or in dB: [-90,0] @@ -1041,7 +1035,6 @@ static ivas_error get_bin_outer_attenuation( return IVAS_ERR_OK; } - /*-----------------------------------------------------------------------------------------* * Function get_bin_max_dist () * Gets a Maximum Distance value [1.0, 64.0] @@ -1065,7 +1058,6 @@ static ivas_error get_bin_max_dist( return IVAS_ERR_OK; } - /*-----------------------------------------------------------------------------------------* * Function get_bin_ref_dist () * Gets a Reference Distance value [0.1, 6.4] @@ -1089,7 +1081,6 @@ static ivas_error get_bin_ref_dist( return IVAS_ERR_OK; } - /*-----------------------------------------------------------------------------------------* * Function get_bin_rolloff () * Gets a Rollof Factor [0.0, 4.0] @@ -1243,6 +1234,7 @@ ivas_error RenderConfigReader_checkValues( int16_t wall_idx; int16_t i; + /* Verify the number of frequency bands in the config input data */ if ( ( pRoom_acoustics->nBands > N_BANDS_MAX ) || ( pRoom_acoustics->nBands < N_BANDS_MIN ) ) { @@ -2415,6 +2407,7 @@ ivas_error RenderConfigReader_read( errorHandler( item, ERROR_VALUE_INVALID ); return IVAS_ERR_INVALID_RENDER_CONFIG; } + if ( i >= pRenderConfigReader->nFG || pRenderConfigReader->pFG[i].pFc == NULL ) { return IVAS_ERR_INVALID_RENDER_CONFIG; @@ -2857,6 +2850,7 @@ ivas_error RenderConfigReader_read( free( pValue ); } + else if ( strcmp( chapter, "GENERAL" ) == 0 && strlen( pParams ) != 0 ) { params_idx = 0; @@ -3048,7 +3042,7 @@ ivas_error RenderConfigReader_getDirectivity( float *directivity /* o : Target directivity */ ) { - uint16_t i, n, m; + uint16_t n, m, i; uint16_t last_specified_id; bool idExists; @@ -3089,6 +3083,7 @@ ivas_error RenderConfigReader_getDirectivity( id[n] = last_specified_id; } + for ( n = 0; n < IVAS_MAX_NUM_OBJECTS; n++ ) { idExists = false; @@ -3101,7 +3096,6 @@ ivas_error RenderConfigReader_getDirectivity( { directivity[n * 3 + i] = pRenderConfigReader->pDP[m].pDirectivity[i]; } - break; } } @@ -3111,11 +3105,9 @@ ivas_error RenderConfigReader_getDirectivity( } } } - return IVAS_ERR_OK; } - /*------------------------------------------------------------------------------------------* * RenderConfigReader_getDistanceAttenuation() * diff --git a/lib_util/rotation_file_reader.c b/lib_util/rotation_file_reader.c index 6c62290b002e4c9a6aeb9d268c10a6aeb369b0fb..cbf36e42ba56ae54f35834971d6bcae38d81d100 100644 --- a/lib_util/rotation_file_reader.c +++ b/lib_util/rotation_file_reader.c @@ -174,14 +174,12 @@ ivas_error ExternalOrientationFileReading( } ( externalOrientationReader->frameCounter )++; -#ifdef FIX_1370_EXTERNAL_ORIENTATION_CHECK /* Only Quaternion orientations are supported, raise an error if Euler angles are detected in the input */ if ( w == -3.0f ) { return IVAS_ERR_EXTERNAL_ORIENTATION_INVALID_FORMAT; } -#endif pQuaternion->w = w; pQuaternion->x = x; diff --git a/lib_util/rtpdump.c b/lib_util/rtpdump.c index dfa15a9dad28c3a94facac817cb5fb56fe85eb6e..f89b36f82a686192ec0f843251a56bf23312dec1 100644 --- a/lib_util/rtpdump.c +++ b/lib_util/rtpdump.c @@ -80,11 +80,7 @@ static unsigned char *parseByte( unsigned char *buffer, unsigned char *value ) static int readLong( FILE *file, unsigned int *value ) { char buffer[4] = { 0 }; -#ifdef CODE_IMPROVEMENTS if ( fread( buffer, 1, 4, file ) != 1U ) -#else - if ( fread( buffer, 4, 1, file ) != 1U ) -#endif { return -1; } @@ -100,11 +96,7 @@ static int readLong( FILE *file, unsigned int *value ) static int readShort( FILE *file, unsigned short *value ) { char buffer[2] = { 0 }; -#ifdef CODE_IMPROVEMENTS if ( fread( buffer, 1, 2, file ) != 1U ) -#else - if ( fread( buffer, 2, 1, file ) != 1U ) -#endif { return -1; } @@ -118,10 +110,17 @@ static int readShort( FILE *file, unsigned short *value ) static int writeLong( FILE *file, unsigned int value ) { char buffer[4] = { 0 }; +#ifdef IVAS_RTPDUMP + buffer[3] = (char) ( value & 0xff ); + buffer[2] = (char) ( ( value >> 8 ) & 0xff ); + buffer[1] = (char) ( ( value >> 16 ) & 0xff ); + buffer[0] = (char) ( ( value >> 24 ) & 0xff ); +#else buffer[3] = value & 0xff; buffer[2] = ( value >> 8 ) & 0xff; buffer[1] = ( value >> 16 ) & 0xff; buffer[0] = ( value >> 24 ) & 0xff; +#endif if ( fwrite( buffer, 4, 1, file ) != 1U ) { return -1; @@ -133,8 +132,13 @@ static int writeLong( FILE *file, unsigned int value ) static int writeShort( FILE *file, unsigned short value ) { char buffer[2] = { 0 }; +#ifdef IVAS_RTPDUMP + buffer[1] = (char) ( value & 0xff ); + buffer[0] = (char) ( ( value >> 8 ) & 0xff ); +#else buffer[1] = value & 0xff; buffer[0] = ( value >> 8 ) & 0xff; +#endif if ( fwrite( buffer, 2, 1, file ) != 1U ) { return -1; diff --git a/lib_util/split_rend_bfi_file_reader.c b/lib_util/split_rend_bfi_file_reader.c index 6a86738e026d04149cf714d2b5b99e830a883b83..07b71e2219933dd8738a02d5be5a3b2b2c40f2f2 100644 --- a/lib_util/split_rend_bfi_file_reader.c +++ b/lib_util/split_rend_bfi_file_reader.c @@ -97,8 +97,9 @@ ivas_error SplitRendBFIFileReader_open( *-----------------------------------------------------------------------*/ ivas_error SplitRendBFIFileReading( - SplitRendBFIFileReader *SplitRendBFIReader, /* i/o: SplitRendBFIFileReader handle */ - int16_t *bfi ) + SplitRendBFIFileReader *SplitRendBFIReader, /* i/o: SplitRendBFIFileReader handle */ + int16_t *bfi /* o : bad frame indicator */ +) { if ( SplitRendBFIReader->txtfile ? 1 != fscanf( SplitRendBFIReader->bfiFile, "%hd", bfi ) : 1 != fread( bfi, sizeof( *bfi ), 1, SplitRendBFIReader->bfiFile ) ) { diff --git a/lib_util/split_rend_bfi_file_reader.h b/lib_util/split_rend_bfi_file_reader.h index 0956b6b3ddcecc0b8fd58f0f13a26b15b8e4c5a0..5ff3f4956b23505973680f8ee80c9b453bb9996a 100644 --- a/lib_util/split_rend_bfi_file_reader.h +++ b/lib_util/split_rend_bfi_file_reader.h @@ -44,7 +44,8 @@ ivas_error SplitRendBFIFileReader_open( ivas_error SplitRendBFIFileReading( SplitRendBFIFileReader *SplitRendBFIReader, /* i/o: SplitRendBFIFileReader handle */ - int16_t *bfi ); + int16_t *bfi /* o : bad frame indicator */ +); void SplitRendBFIFileReader_close( SplitRendBFIFileReader **SplitRendBFIReader /* i/o: SplitRendBFIFileReader handle */ diff --git a/lib_util/split_render_file_read_write.c b/lib_util/split_render_file_read_write.c index cc8e3c4a40f87c85a5bb5348ad1466df273fcf2e..59dad090fab53c5d0e75de068e17c0e4c8fa6a46 100644 --- a/lib_util/split_render_file_read_write.c +++ b/lib_util/split_render_file_read_write.c @@ -114,21 +114,25 @@ ivas_error split_rend_reader_open( { return IVAS_ERR_FAILED_FILE_READ; } + /* read transport codec frame size signalling */ if ( fread( codec_frame_size_ms, sizeof( *codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) { return IVAS_ERR_FAILED_FILE_READ; } - /* read isar bitstream frame size signalling */ + + /* read ISAR bitstream frame size signalling */ if ( fread( isar_frame_size_ms, sizeof( *isar_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) { return IVAS_ERR_FAILED_FILE_READ; } + /* read sampling rate signalling */ if ( fread( sampling_rate, sizeof( *sampling_rate ), 1, hSplitRendFileReadWrite->file ) != 1 ) { return IVAS_ERR_FAILED_FILE_READ; } + /* read LC3plus highres signalling */ if ( fread( lc3plus_highres, sizeof( *lc3plus_highres ), 1, hSplitRendFileReadWrite->file ) != 1 ) { @@ -154,7 +158,7 @@ ivas_error split_rend_writer_open( const int32_t delayTimeScale, ISAR_SPLIT_REND_CODEC codec, ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, - int16_t codec_frame_size_ms, + const int16_t codec_frame_size_ms, const int16_t isar_frame_size_ms, const int32_t sampling_rate, const int16_t lc3plus_highres ) @@ -203,21 +207,25 @@ ivas_error split_rend_writer_open( { return IVAS_ERR_FAILED_FILE_WRITE; } + /* Write transport codec frame size signalling */ if ( fwrite( &codec_frame_size_ms, sizeof( codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) { return IVAS_ERR_FAILED_FILE_WRITE; } - /* Write isar bit stream frame size signalling */ + + /* Write ISAR bit stream frame size signalling */ if ( fwrite( &isar_frame_size_ms, sizeof( isar_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) { return IVAS_ERR_FAILED_FILE_WRITE; } + /* Write sampling rate signalling */ if ( fwrite( &sampling_rate, sizeof( sampling_rate ), 1, hSplitRendFileReadWrite->file ) != 1 ) { return IVAS_ERR_FAILED_FILE_WRITE; } + /* Write LC3plus highres signalling */ if ( fwrite( &lc3plus_highres, sizeof( lc3plus_highres ), 1, hSplitRendFileReadWrite->file ) != 1 ) { diff --git a/lib_util/split_render_file_read_write.h b/lib_util/split_render_file_read_write.h index 0ea113e899d9cf0920c7978c52d11ebfbe1c536b..97ff673b36f03926e4e7168378fcdb20b54104e2 100644 --- a/lib_util/split_render_file_read_write.h +++ b/lib_util/split_render_file_read_write.h @@ -37,7 +37,7 @@ typedef struct SplitFileReadWrite SplitFileReadWrite; -/* Allocates and initializes a a split renderer reader instance */ +/* Allocates and initializes a a split renderer reader instance */ ivas_error split_rend_reader_open( SplitFileReadWrite **hhSplitRendFileReadWrite, char *filename, @@ -48,8 +48,7 @@ ivas_error split_rend_reader_open( int32_t *sampling_rate, int16_t *lc3plus_highres ); - -/* Allocates and initializes a a split renderer writer instance */ +/* Allocates and initializes a a split renderer writer instance */ ivas_error split_rend_writer_open( SplitFileReadWrite **hhSplitRendFileReadWrite, char *filename, @@ -57,13 +56,12 @@ ivas_error split_rend_writer_open( const int32_t delayTimeScale, ISAR_SPLIT_REND_CODEC codec, ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, - int16_t codec_frame_size_ms, + const int16_t codec_frame_size_ms, const int16_t isar_frame_size_ms, const int32_t sampling_rate, const int16_t lc3plus_highres ); - -/* Closes the split renderer reader/writer and deallocates memory */ +/* Closes the split renderer reader/writer and deallocates memory */ void split_rend_reader_writer_close( SplitFileReadWrite **hhSplitRendFileReadWrite ); diff --git a/lib_util/tinywavein_c.h b/lib_util/tinywavein_c.h index 179c676a81b274098fabbe5050c2c977572c82ec..1ff6f26bb78438b2fbb835e483f99c1d46128dce 100644 --- a/lib_util/tinywavein_c.h +++ b/lib_util/tinywavein_c.h @@ -54,22 +54,14 @@ #define __TWI_SUCCESS ( 0 ) #define __TWI_ERROR ( -1 ) -#ifdef CODE_IMPROVEMENTS typedef struct tinyWaveInHandle -#else -typedef struct __tinyWaveInHandle -#endif { FILE *theFile; fpos_t dataChunkPos; uint32_t position; uint32_t length; uint32_t bps; -#ifdef CODE_IMPROVEMENTS } tinyWaveInHandle, WAVEFILEIN; -#else -} __tinyWaveInHandle, WAVEFILEIN; -#endif typedef struct { diff --git a/lib_util/tinywaveout_c.h b/lib_util/tinywaveout_c.h index 70373e3cca0850aacd3849376765690d3980927a..190bc5eb50ccf2cd1904dec576fe1af9d423e585 100644 --- a/lib_util/tinywaveout_c.h +++ b/lib_util/tinywaveout_c.h @@ -70,27 +70,15 @@ #endif #endif -#ifdef CODE_IMPROVEMENTS typedef struct tinyWaveOutHeader -#else -typedef struct __tinyWaveOutHeader -#endif { uint32_t riffType; /* 'RIFF' */ uint32_t riffSize; /* file size */ uint32_t waveType; /* 'WAVE' */ -#ifdef CODE_IMPROVEMENTS } tinyWaveOutHeader; -#else -} __tinyWaveOutHeader; -#endif -#ifdef CODE_IMPROVEMENTS typedef struct tinyWaveOutFmtChunk -#else -typedef struct __tinyWaveOutFmtChunk -#endif { uint32_t formatType; uint32_t formatSize; @@ -103,32 +91,15 @@ typedef struct __tinyWaveOutFmtChunk uint16_t bitsPerSample; /* wav fmt ext hdr here */ -#ifdef CODE_IMPROVEMENTS } tinyWaveOutFmtChunk; -#else -} __tinyWaveOutFmtChunk; -#endif -#ifdef CODE_IMPROVEMENTS typedef struct tinyWaveOutDataChunk -#else -typedef struct __tinyWaveOutDataChunk -#endif { uint32_t dataType; uint32_t dataSize; - -#ifdef CODE_IMPROVEMENTS } tinyWaveOutDataChunk; -#else -} __tinyWaveOutDataChunk; -#endif -#ifdef CODE_IMPROVEMENTS typedef struct tinyWaveOutHandle -#else -typedef struct __tinyWaveOutHandle -#endif { FILE *theFile; uint32_t dataSize; @@ -137,11 +108,7 @@ typedef struct __tinyWaveOutHandle uint32_t dataChunkOffset; uint32_t bps; uint32_t clipCount; -#ifdef CODE_IMPROVEMENTS } tinyWaveOutHandle, WAVEFILEOUT; -#else -} __tinyWaveOutHandle, WAVEFILEOUT; -#endif /*--- local protos --------------------------------------------------*/ static __inline uint32_t BigEndian32( char, char, char, char ); @@ -164,15 +131,9 @@ static WAVEFILEOUT *CreateBWF( /* ,const uint32_t writeWaveExt */ ) { WAVEFILEOUT *self; -#ifdef CODE_IMPROVEMENTS tinyWaveOutHeader whdr; tinyWaveOutFmtChunk wfch; tinyWaveOutDataChunk wdch; -#else - __tinyWaveOutHeader whdr; - __tinyWaveOutFmtChunk wfch; - __tinyWaveOutDataChunk wdch; -#endif uint32_t blockAlignment = 0; uint32_t ByteCnt = 0; /* Byte counter for fwrite */ diff --git a/lib_util/tsm_scale_file_reader.h b/lib_util/tsm_scale_file_reader.h index 897e15681b413d8fe18e49851f464076ba2a37d4..6fa83dbba363bfe4dbd7769a8970228179cfe5de 100644 --- a/lib_util/tsm_scale_file_reader.h +++ b/lib_util/tsm_scale_file_reader.h @@ -36,6 +36,7 @@ #include "common_api_types.h" /* clang-format off */ + #ifdef DEBUGGING #ifdef VARIABLE_SPEED_DECODING @@ -63,6 +64,7 @@ const char *TsmScaleFileReader_getFilePath( #endif #endif + /* clang-format on */ #endif /* IVAS_TSM_SCALE_FILE_READER_H */