From 9f18ceba632a1df956faaa54472ffdecf3e1dfdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20Toftg=C3=A5rd?= Date: Thu, 30 Oct 2025 10:59:19 +0100 Subject: [PATCH 01/15] Add reading and packing/unpacking of ISM PI data, under define ISM_PI_DATA. --- apps/decoder.c | 28 ++ lib_com/options.h | 1 + lib_util/ivas_rtp_internal.h | 9 + lib_util/ivas_rtp_pi_data.c | 616 ++++++++++++++++++++++++++++++++++- lib_util/ivas_rtp_pi_data.h | 1 - tests/rtp/ivasrtp.py | 184 ++++++++++- tests/rtp/test_rtp.py | 15 + 7 files changed, 826 insertions(+), 28 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index da0fdd2fbd..4bd2c802f5 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -226,6 +226,9 @@ static const char *PiDataNames[IVAS_PI_MAX_ID] = { static void IVAS_RTP_LogPiData( FILE *f_piDataOut, PIDATA_TS *piData, uint32_t nPiDataPresent ) { uint32_t timestamp = ~0u; +#ifdef ISM_PI_DATA + uint16_t n; +#endif if ( f_piDataOut == NULL || piData == NULL || nPiDataPresent == 0 ) { return; @@ -387,6 +390,30 @@ static void IVAS_RTP_LogPiData( FILE *f_piDataOut, PIDATA_TS *piData, uint32_t n fprintf( f_piDataOut, "{}" ); } break; +#ifdef ISM_PI_DATA + case IVAS_PI_ISM_ORIENTATION: + { + fprintf( f_piDataOut, "[\n" ); + for ( n = 0; n < cur->data.ismOrientation.size / 8; n++ ) + { + fprintf( f_piDataOut, "\t\t\t{\n\t\t\t\t\"w\": %f,\n\t\t\t\t\"x\": %f,\n\t\t\t\t\"y\": %f,\n\t\t\t\t\"z\": %f \n\t\t\t},\n", + cur->data.ismOrientation.orientation[n].w, cur->data.ismOrientation.orientation[n].x, cur->data.ismOrientation.orientation[n].y, cur->data.ismOrientation.orientation[n].z ); + } + fprintf( f_piDataOut, "\t\t]" ); + } + break; + case IVAS_PI_ISM_NUM: + case IVAS_PI_ISM_ID: + case IVAS_PI_ISM_GAIN: + + 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: +#else case IVAS_PI_ISM_NUM: case IVAS_PI_ISM_ID: case IVAS_PI_ISM_GAIN: @@ -398,6 +425,7 @@ static void IVAS_RTP_LogPiData( FILE *f_piDataOut, PIDATA_TS *piData, uint32_t n case IVAS_PI_R_ISM_ID: case IVAS_PI_R_ISM_GAIN: case IVAS_PI_R_ISM_DIRECTION: +#endif #endif /* RTP_S4_251135_CR26253_0016_REV1 */ case IVAS_PI_NO_DATA: { diff --git a/lib_com/options.h b/lib_com/options.h index b1f5965027..988fe14dcf 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -160,6 +160,7 @@ #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 ISM_PI_DATA /* Add reading and packing/unpacking of ISM PI data */ /* ################### Start BE switches ################################# */ /* only BE switches wrt selection floating point code */ diff --git a/lib_util/ivas_rtp_internal.h b/lib_util/ivas_rtp_internal.h index f3569ca031..59ba5b04b1 100644 --- a/lib_util/ivas_rtp_internal.h +++ b/lib_util/ivas_rtp_internal.h @@ -72,6 +72,15 @@ extern const float mapRT60[1u << NBITS_RT60]; extern const float mapRoomDims[1u << NBITS_DIM]; extern const float mapAbsorbtion[1u << NBITS_ABS]; +#ifdef ISM_PI_DATA +extern const int16_t ismGains[98]; +extern const float refDistances[64]; +extern const float maxDistances[65]; +extern const float rollOffFactors[41]; +extern const int16_t innerOuterAngles[25]; +extern const float outerAttenuations[32]; +#endif + enum IVAS_RTP_HEADER_BITS { diff --git a/lib_util/ivas_rtp_pi_data.c b/lib_util/ivas_rtp_pi_data.c index c939c4539c..3f2fa18463 100644 --- a/lib_util/ivas_rtp_pi_data.c +++ b/lib_util/ivas_rtp_pi_data.c @@ -156,6 +156,43 @@ static ivas_error packOrientation( const IVAS_PIDATA_GENERIC *piData, uint8_t *b return IVAS_ERR_OK; } +#ifdef ISM_PI_DATA +static ivas_error packISMOrientation( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ) +{ + uint32_t nBytes = 0; + const IVAS_PIDATA_ISM_ORIENTATION *orientation = (const IVAS_PIDATA_ISM_ORIENTATION *) piData; + uint16_t n; + *nBytesWritten = 0; + + if ( piData->size != sizeof( IVAS_PIDATA_ISM_ORIENTATION ) ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect size in Orientation PI data" ); + } + + if ( piData->piDataType != IVAS_PI_ISM_ORIENTATION ) + { + 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 * IVAS_PI_MAX_OBJECTS + 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++] = (uint8_t) piData->size; + for ( n = 0; n < piData->size / 8; n++ ) + { + nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( orientation->orientation[n].w ) ); + nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( orientation->orientation[n].x ) ); + nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( orientation->orientation[n].y ) ); + nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( orientation->orientation[n].z ) ); + } + *nBytesWritten = nBytes; + return IVAS_ERR_OK; +} +#endif + static ivas_error unpackOrientation( const uint8_t *buffer, uint32_t numDataBytes, IVAS_PIDATA_GENERIC *piData ) { IVAS_PIDATA_ORIENTATION *orientation = (IVAS_PIDATA_ORIENTATION *) piData; @@ -175,6 +212,31 @@ static ivas_error unpackOrientation( const uint8_t *buffer, uint32_t numDataByte return IVAS_ERR_OK; } +#ifdef ISM_PI_DATA +static ivas_error unpackISMOrientation( const uint8_t *buffer, uint32_t numDataBytes, IVAS_PIDATA_GENERIC *piData ) +{ + IVAS_PIDATA_ISM_ORIENTATION *orientation = (IVAS_PIDATA_ISM_ORIENTATION *) piData; + + /* Orientation data is 8 bytes */ + uint16_t n; + if ( numDataBytes % 8 != 0 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "Incorrect size to unpack Orientation PI data" ); + } + + piData->size = numDataBytes; + for ( n = 0; n < numDataBytes / 8; n++ ) + { + orientation->orientation[n].w = FLOAT_FROM_Q15( readInt16( &buffer[8 * n] ) ); + orientation->orientation[n].x = FLOAT_FROM_Q15( readInt16( &buffer[8 * n + 2] ) ); + orientation->orientation[n].y = FLOAT_FROM_Q15( readInt16( &buffer[8 * n + 4] ) ); + orientation->orientation[n].z = FLOAT_FROM_Q15( readInt16( &buffer[8 * n + 6] ) ); + } + + return IVAS_ERR_OK; +} +#endif + static uint32_t getIndexTable( const float *table, uint32_t tableLength, float value ) { uint32_t idx = 0; @@ -195,6 +257,25 @@ static uint32_t getIndexTable( const float *table, uint32_t tableLength, float v #define GET_IDX( table, nBits, value ) getIndexTable( table, ( 1u << ( nBits ) ), ( value ) ) +static uint32_t getIndexTable_s( const int16_t *table, uint32_t tableLength, int16_t 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; +} + + static ivas_error packAcousticEnvironment( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ) { uint32_t nBytes = 0; @@ -480,6 +561,65 @@ static ivas_error unpackListenerPosition( const uint8_t *buffer, uint32_t numDat return IVAS_ERR_OK; } +#ifdef ISM_PI_DATA +static ivas_error packISMPosition( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ) +{ + uint32_t nBytes = 0, n; + const IVAS_PIDATA_ISM_POSITION *listener = (const IVAS_PIDATA_ISM_POSITION *) piData; + + *nBytesWritten = 0; + + if ( piData->size != sizeof( IVAS_PIDATA_ISM_POSITION ) ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect size in ISM POSITION PI data" ); + } + + if ( piData->piDataType != IVAS_PI_ISM_POSITION ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect PI ID in ISM POSITION PI data" ); + } + + /* Position data is 6 bytes, header is 2 bytes */ + if ( maxDataBytes < 6 * IVAS_PI_MAX_OBJECTS + 2 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack ISM POSITION PI data" ); + } + + buffer[nBytes++] = ( listener->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ + buffer[nBytes++] = (uint8_t) piData->size; + for ( n = 0; n < piData->size / 6; n++ ) + { + nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( listener->position[n].x / MAX_PI_POSITION_METERS ) ); + nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( listener->position[n].y / MAX_PI_POSITION_METERS ) ); + nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( listener->position[n].z / MAX_PI_POSITION_METERS ) ); + } + *nBytesWritten = nBytes; + return IVAS_ERR_OK; +} + +static ivas_error unpackISMPosition( const uint8_t *buffer, uint32_t numDataBytes, IVAS_PIDATA_GENERIC *piData ) +{ + uint16_t n; + IVAS_PIDATA_ISM_POSITION *listener = (IVAS_PIDATA_ISM_POSITION *) piData; + + /* Position data is 6 bytes */ + if ( numDataBytes % 6 != 0 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "Incorrect size to unpack LISTENER POSITION PI data" ); + } + + listener->size = sizeof( IVAS_PIDATA_ISM_POSITION ); + listener->piDataType = IVAS_PI_ISM_POSITION; + for ( n = 0; n < numDataBytes / 6; n++ ) + { + listener->position[n].x = FLOAT_FROM_Q15( readInt16( &buffer[6 * n] ) ) * MAX_PI_POSITION_METERS; + listener->position[n].y = FLOAT_FROM_Q15( readInt16( &buffer[6 * n + 2] ) ) * MAX_PI_POSITION_METERS; + listener->position[n].z = FLOAT_FROM_Q15( readInt16( &buffer[6 * n + 4] ) ) * MAX_PI_POSITION_METERS; + } + return IVAS_ERR_OK; +} +#endif + static ivas_error packDiegetic( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ) { uint32_t nBytes = 0, n; @@ -590,7 +730,7 @@ static ivas_error packAudioFocusCommon( const IVAS_PIDATA_GENERIC *piData, uint8 nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( audioFocus->direction.y ) ); nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( audioFocus->direction.z ) ); } - if ( packedSize == 9 || packedSize == 1) + if ( packedSize == 9 || packedSize == 1 ) { buffer[nBytes++] = ( (uint8_t) audioFocus->flvl & MASK_4BIT ) << 4; } @@ -632,6 +772,328 @@ static ivas_error unpackAudioFocusCommon( const uint8_t *buffer, uint32_t numDat return IVAS_ERR_OK; } +#ifdef ISM_PI_DATA +static ivas_error packISMNum( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ) +{ + uint32_t nBytes = 0; + const IVAS_PIDATA_ISM_NUM *ism_num = (const IVAS_PIDATA_ISM_NUM *) piData; + + *nBytesWritten = 0; + + if ( piData->size != sizeof( IVAS_PIDATA_ISM_NUM ) ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect size in ISM_NUM PI data" ); + } + + if ( piData->piDataType != IVAS_PI_ISM_NUM ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect PI ID in ISM_NUM PI data" ); + } + + /* ISM_NUM 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 ISM_NUM PI data" ); + } + + buffer[nBytes++] = ( ism_num->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ + buffer[nBytes++] = 1; + buffer[nBytes++] = ( ism_num->numObjects - 1 ) & MASK_2BIT << 6; + *nBytesWritten = nBytes; + return IVAS_ERR_OK; +} + +static ivas_error unpackISMNum( const uint8_t *buffer, uint32_t numDataBytes, IVAS_PIDATA_GENERIC *piData ) +{ + IVAS_PIDATA_ISM_NUM *ism_num = (IVAS_PIDATA_ISM_NUM *) piData; + uint8_t byte; + + /* ISM_NUM data is 1 bytes */ + if ( numDataBytes != 1 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "Incorrect size to unpack ISM_NUM PI data" ); + } + + ism_num->size = sizeof( IVAS_PIDATA_ISM_NUM ); + ism_num->piDataType = IVAS_PI_ISM_NUM; + + byte = buffer[0]; + ism_num->numObjects = ( ( byte >> 6 ) & MASK_2BIT ) + 1; + + return IVAS_ERR_OK; +} +static ivas_error packISMID( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ) +{ + uint32_t nBytes = 0, n; + const IVAS_PIDATA_ISM_ID *ism_id = (const IVAS_PIDATA_ISM_ID *) piData; + + *nBytesWritten = 0; + + if ( piData->size > sizeof( IVAS_PIDATA_ISM_ID ) ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect size in ISM_ID PI data" ); + } + + if ( piData->piDataType != IVAS_PI_ISM_ID ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect PI ID in ISM_ID PI data" ); + } + + /* ISM_ID data is 1 byte per object, header is 2 bytes */ + if ( maxDataBytes < 1 * IVAS_PI_MAX_OBJECTS + 2 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack ISM_NUM PI data" ); + } + + buffer[nBytes++] = ( ism_id->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ + buffer[nBytes++] = (uint8_t) piData->size; + /* Pack ID for each object */ + for ( n = 0; n < piData->size; n++ ) + { + buffer[nBytes++] = ( ism_id->id[n] & MASK_8BIT ); + } + *nBytesWritten = nBytes; + return IVAS_ERR_OK; +} + +static ivas_error unpackISMID( const uint8_t *buffer, uint32_t numDataBytes, IVAS_PIDATA_GENERIC *piData ) +{ + uint32_t n; + IVAS_PIDATA_ISM_ID *ism_id = (IVAS_PIDATA_ISM_ID *) piData; + + /* ISM_ID data is 1 byte per object */ + if ( numDataBytes > IVAS_PI_MAX_OBJECTS ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "Incorrect size to unpack ISM_ID PI data" ); + } + + ism_id->size = sizeof( IVAS_PIDATA_ISM_ID ); + ism_id->piDataType = IVAS_PI_ISM_ID; + + /* Unpack ID for each object (1 byte each) */ + for ( n = 0; n < numDataBytes; n++ ) + { + ism_id->id[n] = buffer[n]; + } + + return IVAS_ERR_OK; +} + +static ivas_error packISMGain( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ) +{ + uint32_t nBytes = 0, n, idx; + int16_t gain; + const IVAS_PIDATA_ISM_GAIN *ism_gain = (const IVAS_PIDATA_ISM_GAIN *) piData; + + *nBytesWritten = 0; + + if ( piData->size > sizeof( IVAS_PIDATA_ISM_GAIN ) ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect size in ISM_GAIN PI data" ); + } + + if ( piData->piDataType != IVAS_PI_ISM_GAIN ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect PI ID in ISM_GAIN PI data" ); + } + + /* ISM_GAIN data is 1 byte per object, header is 2 bytes */ + if ( maxDataBytes < 1 * IVAS_PI_MAX_OBJECTS + 2 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack ISM_GAIN PI data" ); + } + + buffer[nBytes++] = ( ism_gain->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ + buffer[nBytes++] = (uint8_t) piData->size; + /* Pack ID for each object */ + for ( n = 0; n < piData->size; n++ ) + { + gain = (int16_t) ism_gain->dB[n]; + if ( gain >= 0 ) + { + idx = getIndexTable_s( ismGains, 4, gain ); + if ( idx > 0 ) + { + idx += 97; + } + } + else + { + idx = getIndexTable_s( ismGains, 98, -gain ); + } + buffer[nBytes++] = ( idx & MASK_7BIT ) << 1; + } + *nBytesWritten = nBytes; + return IVAS_ERR_OK; +} + +static ivas_error unpackISMGain( const uint8_t *buffer, uint32_t numDataBytes, IVAS_PIDATA_GENERIC *piData ) +{ + uint32_t n, idx; + IVAS_PIDATA_ISM_GAIN *ism_gain = (IVAS_PIDATA_ISM_GAIN *) piData; + + /* ISM_GAIN data is 1 byte per object */ + if ( numDataBytes > IVAS_PI_MAX_OBJECTS ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "Incorrect size to unpack ISM_GAIN PI data" ); + } + + ism_gain->size = sizeof( IVAS_PIDATA_ISM_GAIN ); + ism_gain->piDataType = IVAS_PI_ISM_GAIN; + + /* Unpack ID for each object (1 byte each) */ + for ( n = 0; n < numDataBytes; n++ ) + { + idx = ( buffer[n] ) >> 1; + if ( idx < 98 ) + { + ism_gain->dB[n] = (int8_t) -ismGains[idx]; + } + else + { + ism_gain->dB[n] = (int8_t) ismGains[idx]; + } + } + return IVAS_ERR_OK; +} + +static ivas_error packISMDistanceAttenuation( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ) +{ + uint32_t nBytes = 0, n; + const IVAS_PIDATA_ISM_ATTENUATION *ism_att = (const IVAS_PIDATA_ISM_ATTENUATION *) piData; + uint32_t lWord; + + *nBytesWritten = 0; + + if ( piData->size > sizeof( IVAS_PIDATA_ISM_ATTENUATION ) ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect size in ISM_DISTANCE_ATTENUATION PI data" ); + } + + if ( piData->piDataType != IVAS_PI_ISM_DISTANCE_ATTENUATION ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect PI ID in ISM_DISTANCE_ATTENUATION PI data" ); + } + + /* ISM_DISTANCE_ATTENUATION data is 3 bytes per object, header is 2 bytes */ + if ( maxDataBytes > 3 * IVAS_PI_MAX_OBJECTS + 2 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack ISM_DISTANCE_ATTENUATION PI data" ); + } + + buffer[nBytes++] = ( ism_att->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ + buffer[nBytes++] = (uint8_t) piData->size; + /* Pack ID for each object */ + for ( n = 0; n < piData->size; n++ ) + { + lWord = (uint32_t) ( getIndexTable( refDistances, 64, ism_att->distAtten[n].ref_dist ) << 18 ); + lWord |= (uint32_t) ( getIndexTable( maxDistances, 65, ism_att->distAtten[n].max_dist ) << 12 ); + lWord |= (uint32_t) ( getIndexTable( rollOffFactors, 41, ism_att->distAtten[n].roll ) << 6 ); + + buffer[nBytes++] = ( lWord >> 16 ) & MASK_8BIT; + buffer[nBytes++] = ( lWord >> 8 ) & MASK_8BIT; + buffer[nBytes++] = lWord & MASK_8BIT; + } + *nBytesWritten = nBytes; + return IVAS_ERR_OK; +} + +static ivas_error unpackISMDistanceAttenuation( const uint8_t *buffer, uint32_t numDataBytes, IVAS_PIDATA_GENERIC *piData ) +{ + uint32_t n, lWord; + IVAS_PIDATA_ISM_ATTENUATION *ism_att = (IVAS_PIDATA_ISM_ATTENUATION *) piData; + + /* ISM_DISTANCE_ATTENUATION data is 3 bytes per object */ + if ( numDataBytes % 3 != 0 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "Incorrect size to unpack ISM_DISTANCE_ATTENUATION PI data" ); + } + + ism_att->size = sizeof( IVAS_PIDATA_ISM_ATTENUATION ); + ism_att->piDataType = IVAS_PI_ISM_DISTANCE_ATTENUATION; + + /* Unpack attenuation for each object (3 bytes each) */ + for ( n = 0; n < numDataBytes / 3; n++ ) + { + lWord = ( buffer[3 * n] ) << 16; + lWord = ( buffer[3 * n + 1] ) << 8; + lWord = buffer[3 * n + 2]; + + ism_att->distAtten[n].ref_dist = refDistances[( lWord >> 18 ) & MASK_6BIT]; + ism_att->distAtten[n].max_dist = maxDistances[( lWord >> 12 ) & MASK_6BIT]; + ism_att->distAtten[n].roll = rollOffFactors[( lWord >> 6 ) & MASK_6BIT]; + } + return IVAS_ERR_OK; +} +static ivas_error packISMDirectivity( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ) +{ + uint32_t nBytes = 0, n; + const IVAS_PIDATA_ISM_DIRECTIVITY *ism_directivity = (const IVAS_PIDATA_ISM_DIRECTIVITY *) piData; + uint16_t word; + + *nBytesWritten = 0; + + if ( piData->size > sizeof( IVAS_PIDATA_ISM_DIRECTIVITY ) ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect size in ISM_DIRECTIVITY PI data" ); + } + + if ( piData->piDataType != IVAS_PI_ISM_DIRECTIVITY ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect PI ID in ISM_DIRECTIVITY PI data" ); + } + + /* ISM_DIRECTIVITY data is 2 bytes per object, header is 2 bytes */ + if ( maxDataBytes > 2 * IVAS_PI_MAX_OBJECTS + 2 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack ISM_DIRECTIVITY PI data" ); + } + + buffer[nBytes++] = ( ism_directivity->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ + buffer[nBytes++] = (uint8_t) piData->size; + /* Pack ID for each object */ + for ( n = 0; n < piData->size; n++ ) + { + word = (uint16_t) ( getIndexTable_s( innerOuterAngles, 25, ism_directivity->directivity[n].innerConeAngle ) << 11 ); + word |= (uint16_t) ( getIndexTable_s( innerOuterAngles, 25, ism_directivity->directivity[n].outerConeAngle ) << 6 ); + word |= (uint16_t) ( getIndexTable( outerAttenuations, 32, ism_directivity->directivity[n].outerAttenuationdB ) << 1 ); + + buffer[nBytes++] = ( word >> 8 ) & MASK_8BIT; + buffer[nBytes++] = word & MASK_8BIT; + } + *nBytesWritten = nBytes; + return IVAS_ERR_OK; +} + +static ivas_error unpackISMDirectivity( const uint8_t *buffer, uint32_t numDataBytes, IVAS_PIDATA_GENERIC *piData ) +{ + uint32_t n; + uint16_t word; + IVAS_PIDATA_ISM_DIRECTIVITY *ism_directivity = (IVAS_PIDATA_ISM_DIRECTIVITY *) piData; + + /* ISM_DIRECTIVITY data is 2 bytes per object */ + if ( numDataBytes % 2 != 0 ) + { + return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "Incorrect size to unpack ISM_DIRECTIVITY PI data" ); + } + + ism_directivity->size = sizeof( IVAS_PIDATA_ISM_DIRECTIVITY ); + ism_directivity->piDataType = IVAS_PI_ISM_DIRECTIVITY; + + /* Unpack attenuation for each object (3 bytes each) */ + for ( n = 0; n < numDataBytes / 2; n++ ) + { + word = ( buffer[3 * n] ) << 16; + word = ( buffer[3 * n + 1] ) << 8; + word = buffer[3 * n + 2]; + + ism_directivity->directivity[n].innerConeAngle = innerOuterAngles[( word >> 11 ) & MASK_5BIT]; + ism_directivity->directivity[n].outerConeAngle = innerOuterAngles[( word >> 6 ) & MASK_5BIT]; + ism_directivity->directivity[n].outerAttenuationdB = outerAttenuations[( word >> 1 ) & MASK_5BIT]; + } + return IVAS_ERR_OK; +} +#endif #endif /* RTP_S4_251135_CR26253_0016_REV1 */ @@ -645,14 +1107,24 @@ static const PACK_PI_FN packPiDataFuntions[IVAS_PI_MAX_ID] = { 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 */ +#endif /* RTP_S4_251135_CR26253_0016_REV1 */ +#ifdef ISM_PI_DATA + packISMNum, /* ISM_NUM */ + packISMID, /* ISM_ID */ + packISMGain, /* ISM_GAIN */ + packISMOrientation, /* ISM_ORIENTATION */ + packISMPosition, /* ISM_POSITION */ + packISMDistanceAttenuation, /* ISM_DISTANCE_ATTENUATION */ + packISMDirectivity, /* ISM_DIRECTIVITY */ +#else + packUnsupportedData, /* ISM_NUM */ + packUnsupportedData, /* ISM_ID */ + packUnsupportedData, /* ISM_GAIN */ + packUnsupportedData, /* ISM_ORIENTATION */ + packUnsupportedData, /* ISM_POSITION */ + packUnsupportedData, /* ISM_DISTANCE_ATTENUATION */ + packUnsupportedData, /* ISM_DIRECTIVITY */ +#endif #ifdef RTP_S4_251135_CR26253_0016_REV1 packDiegetic, /* DIEGETIC_TYPE */ #else @@ -660,9 +1132,9 @@ static const PACK_PI_FN packPiDataFuntions[IVAS_PI_MAX_ID] = { #endif packUnsupportedData, /* RESERVED13 */ #ifdef RTP_S4_251135_CR26253_0016_REV1 - packAudioFocusCommon,/* AUDIO_FOCUS_INDICATION */ + packAudioFocusCommon, /* AUDIO_FOCUS_INDICATION */ #else - packUnsupportedData, /* AUDIO_FOCUS_INDICATION */ + packUnsupportedData, /* AUDIO_FOCUS_INDICATION */ #endif packUnsupportedData, /* RESERVED15 */ #ifdef RTP_S4_251135_CR26253_0016_REV1 @@ -705,6 +1177,15 @@ static const UNPACK_PI_FN unpackPiDataFuntions[IVAS_PI_MAX_ID] = { #else unpackUnsupportedData, /* AUDIO_DESCRIPTION */ #endif +#ifdef ISM_PI_DATA + unpackISMNum, /* ISM_NUM */ + unpackISMID, /* ISM_ID */ + unpackISMGain, /* ISM_GAIN */ + unpackISMOrientation, /* ISM_ORIENTATION */ + unpackISMPosition, /* ISM_POSITION */ + unpackISMDistanceAttenuation, /* ISM_DISTANCE_ATTENUATION */ + unpackISMDirectivity, /* ISM_DIRECTIVITY */ +#else unpackUnsupportedData, /* ISM_NUM */ unpackUnsupportedData, /* ISM_ID */ unpackUnsupportedData, /* ISM_GAIN */ @@ -712,6 +1193,7 @@ static const UNPACK_PI_FN unpackPiDataFuntions[IVAS_PI_MAX_ID] = { unpackUnsupportedData, /* ISM_POSITION */ unpackUnsupportedData, /* ISM_DISTANCE_ATTENUATION */ unpackUnsupportedData, /* ISM_DIRECTIVITY */ +#endif #ifdef RTP_S4_251135_CR26253_0016_REV1 unpackDiegetic, /* DIEGETIC_TYPE */ #else @@ -719,7 +1201,7 @@ static const UNPACK_PI_FN unpackPiDataFuntions[IVAS_PI_MAX_ID] = { #endif unpackUnsupportedData, /* RESERVED13 */ #ifdef RTP_S4_251135_CR26253_0016_REV1 - unpackAudioFocusCommon,/* AUDIO_FOCUS_INDICATION */ + unpackAudioFocusCommon, /* AUDIO_FOCUS_INDICATION */ #else unpackUnsupportedData, /* AUDIO_FOCUS_INDICATION */ #endif @@ -848,5 +1330,115 @@ const float mapAbsorbtion[1u << NBITS_ABS] = { 0.0800f, 0.1656f, 0.3430f, 0.7101f }; +#ifdef ISM_PI_DATA +/* gains with negative values flipped to positive for the search */ +const int16_t ismGains[98] = { + 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 32767 +}; +// const float ismGains[98] = { +// 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, +// 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, +// 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, 20.0f, +// 21.0f, 22.0f, 23.0f, 24.0f, 25.0f, 26.0f, 27.0f, +// 28.0f, 29.0f, 30.0f, 31.0f, 32.0f, 33.0f, 34.0f, +// 35.0f, 36.0f, 37.0f, 38.0f, 39.0f, 40.0f, 41.0f, +// 42.0f, 43.0f, 44.0f, 45.0f, 46.0f, 47.0f, 48.0f, +// 49.0f, 50.0f, 51.0f, 52.0f, 53.0f, 54.0f, 55.0f, +// 56.0f, 57.0f, 58.0f, 59.0f, 60.0f, 61.0f, 62.0f, +// 63.0f, 64.0f, 65.0f, 66.0f, 67.0f, 68.0f, 69.0f, +// 70.0f, 71.0f, 72.0f, 73.0f, 74.0f, 75.0f, 76.0f, +// 77.0f, 78.0f, 79.0f, 80.0f, 81.0f, 82.0f, 83.0f, +// 84.0f, 85.0f, 86.0f, 87.0f, 88.0f, 89.0f, 90.0f, +// 91.0f, 92.0f, 93.0f, 94.0f, 95.0f, 96.0f, 32768.0f +// }; + +const float refDistances[64] = { + 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, + 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, + 1.7f, 1.8f, 1.9f, 2.0f, 2.1f, 2.2f, 2.3f, 2.4f, + 2.5f, 2.6f, 2.7f, 2.8f, 2.9f, 3.0f, 3.1f, 3.2f, + 3.3f, 3.4f, 3.5f, 3.6f, 3.7f, 3.8f, 3.9f, 4.0f, + 4.1f, 4.2f, 4.3f, 4.4f, 4.5f, 4.6f, 4.7f, 4.8f, + 4.9f, 5.0f, 5.1f, 5.2f, 5.3f, 5.4f, 5.5f, 5.6f, + 5.7f, 5.8f, 5.9f, 6.0f, 6.1f, 6.2f, 6.3f, 6.4f +}; + +// const int16_t maxDistances[65] = { +// 0, 1, 2, 3, 4, 5, +// 6, 7, 8, 9, 10, 11, +// 12, 13, 14, 15, 16, 17, +// 18, 19, 20, 21, 22, 23, +// 24, 25, 26, 27, 28, 29, +// 30, 31, 32, 33, 34, 35, +// 36, 37, 38, 39, 40, 41, +// 42, 43, 44, 45, 46, 47, +// 48, 49, 50, 51, 52, 53, +// 54, 55, 56, 57, 58, 59, +// 60, 61, 62, 63, 64 +// }; +const float maxDistances[65] = { + 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, + 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, + 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, + 18.0f, 19.0f, 20.0f, 21.0f, 22.0f, 23.0f, + 24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f, + 30.0f, 31.0f, 32.0f, 33.0f, 34.0f, 35.0f, + 36.0f, 37.0f, 38.0f, 39.0f, 40.0f, 41.0f, + 42.0f, 43.0f, 44.0f, 45.0f, 46.0f, 47.0f, + 48.0f, 49.0f, 50.0f, 51.0f, 52.0f, 53.0f, + 54.0f, 55.0f, 56.0f, 57.0f, 58.0f, 59.0f, + 60.0f, 61.0f, 62.0f, 63.0f, 64.0f +}; + +const float rollOffFactors[41] = { + 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, + 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, + 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, + 1.8f, 1.9f, 2.0f, 2.1f, 2.2f, 2.3f, + 2.4f, 2.5f, 2.6f, 2.7f, 2.8f, 2.9f, + 3.0f, 3.1f, 3.2f, 3.3f, 3.4f, 3.5f, + 3.6f, 3.7f, 3.8f, 3.9f, 4.0f +}; +const int16_t innerOuterAngles[25] = { + 0, 15, 30, 45, 60, + 75, 90, 105, 120, 135, + 150, 165, 180, 195, 210, + 225, 240, 255, 270, 285, + 300, 315, 330, 345, 360 +}; +// const float innerOuterAngles[25] = { +// 0.0f, 15.0f, 30.0f, 45.0f, 60.0f, +// 75.0f, 90.0f, 105.0f, 120.0f, 135.0f, +// 150.0f, 165.0f, 180.0f, 195.0f, 210.0f, +// 225.0f, 240.0f, 255.0f, 270.0f, 285.0f, +// 300.0f, 315.0f, 330.0f, 345.0f, 360.0f +// }; +// const int16_t outerAttenuations[32] = { +// -32768, -90, -87, -84, -81, -78, -75, -72, +// -69, -66, -63, -60, -57, -54, -51, -48, +// -45, -42, -39, -36, -33, -30, -27, -24, +// -21, -18, -15, -12, -9, -6, -3, 0 +//}; + +const float outerAttenuations[32] = { + -32768.0f, -90.0f, -87.0f, -84.0f, -81.0f, -78.0f, -75.0f, -72.0f, + -69.0f, -66.0f, -63.0f, -60.0f, -57.0f, -54.0f, -51.0f, -48.0f, + -45.0f, -42.0f, -39.0f, -36.0f, -33.0f, -30.0f, -27.0f, -24.0f, + -21.0f, -18.0f, -15.0f, -12.0f, -9.0f, -6.0f, -3.0f, 0.0f +}; +#endif #endif /* IVAS_RTPDUMP */ diff --git a/lib_util/ivas_rtp_pi_data.h b/lib_util/ivas_rtp_pi_data.h index aad50dd6b6..1ea89aaf39 100644 --- a/lib_util/ivas_rtp_pi_data.h +++ b/lib_util/ivas_rtp_pi_data.h @@ -334,7 +334,6 @@ extern "C" 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 diff --git a/tests/rtp/ivasrtp.py b/tests/rtp/ivasrtp.py index 1eec45fdce..a7599a59be 100644 --- a/tests/rtp/ivasrtp.py +++ b/tests/rtp/ivasrtp.py @@ -43,6 +43,7 @@ import base64 import argparse from pathlib import Path from typing import cast, Optional +import numpy as np NO_REQ="NO_REQ" @@ -330,9 +331,6 @@ class POSITION: y: float = 0.0 z: float = 0.0 -class ISM_POSITIONS: - positions: list[POSITION] - @dataclass class AUDIO_DESCRIPTION: isSpeech: bool = False @@ -360,6 +358,46 @@ class ACOUSTIC_ENVIRONMENT: dim: tuple[float, float, float] = () abscoeff: tuple[float, float, float, float, float, float] = () +@dataclass +class ISM_NUM: + num: int = 1 + +@dataclass +class ISM_ID: + ids: list[int] + +@dataclass +class ISM_GAIN: + gains: list[int] + +@dataclass +class ISM_ORIENTATION: + orientations: list[ORIENTATION] + +@dataclass +class ISM_POSITION: + positions: list[POSITION] + +@dataclass +class DISTANCE_ATTENUATION: + ref_dist: float = 1.0 + max_dist: int = 10 + roll_off: float = 1.0 + +@dataclass +class ISM_DISTANCE_ATTENUATION: + distance_attenuations: list[DISTANCE_ATTENUATION] + +@dataclass +class DIRECTIVITY: + inner_ang: int = 360 + outer_ang: int = 0 + outer_att: int = 0 + +@dataclass +class ISM_DIRECTIVITY: + directivities: list[DIRECTIVITY] + @dataclass class AUDIO_FOCUS: direction: Optional[ORIENTATION] = None @@ -371,7 +409,7 @@ class PIDATA: type: str = "NO_PI_DATA" data: any = None -MAX_PACKED_PI_SIZE = 32 +MAX_PACKED_PI_SIZE = 64 ivasBitrates = [13200, 16400, 24400, 32000, 48000, 64000, 80000, 96000, 128000, 160000, 192000, 256000, 384000, 512000, -1, 5200] evsBitrates = [5900, 7200, 8000, 9600, 13200, 16400, 24400, 32000, 48000, 64000, 96000, 128000, 2400, -1, -1, -1] amrwbBitrates = [6600, 8850, 12650, 14250, 15850, 18250, 19850, 23050, 23850, 1750, -1, -1, -1, -1, -1, -1] @@ -384,6 +422,12 @@ dsrValue = [ -20.0, -21.0, -22.0, -23.0, -24.0, -25.0, -26.0, -27.0, -28.0, -29. -74.0, -75.0, -76.0, -77.0, -78.0, -79.0, -80.0, -81.0, -82.0, -83.0 ] roomDimensionValue = [0.5, 0.707, 1.0, 1.4141, 2.0, 2.8282, 4.0, 5.6568, 8.0, 11.314, 16.0, 22.627, 32.0, 45.255, 64.0, 90.51] absorptionCoeffValues = [0.0800, 0.1656, 0.3430, 0.7101] +ismGains = list(range(0, -97, -1)) + [-float("inf")] + list(range(1, 4)) +refDistances = [round(x * 0.1, 1) for x in range(1, 65)] +maxDistances = list(range(1,65)) +rolloffFactors = [round(x * 0.1, 1) for x in range(0, 41)] +innerOuterAngles = list(range(0,361,15)) +outerAttenuations = [-float("inf")] + list(range(-90,1,3)) codedFormats = list(FORMATS) codedSubFormats = list(SUBFORMATS) PiTypeNames = list(PIDATAS) @@ -616,9 +660,119 @@ def packAudioFocus(bitstrm: BitStream, data: any): if auFocus.direction is not None: packOrientations(bitstrm, [auFocus.direction]) if auFocus.level is not None: - bitstrm.append(f'uint:4={auFocus.level}') + level = int(auFocus.level) + bitstrm.append(f'uint:4={level}') bitstrm.append(f'uint:4=0') +def unpackISMNum(bitstrm: ConstBitStream, piSize: int) -> ISM_NUM: + assert piSize == 1, "Incorrect PI Data Size for ISM_NUM" + numISM = bitstrm.read(2).uint + 1 + bitstrm.bytealign() + return ISM_NUM(num=numISM) + +def packISMNum(bitstrm: BitStream, data: any): + assert type(data) == ISM_NUM, "Data of type ISM_NUM is expected" + ism_num = cast(ISM_NUM, data) + assert ism_num.num <= 4, "Maximum 4 objects" + bitstrm.append(f'uint:2={ism_num.num-1}') + bitstrm.append(f'uint:6=0') + +def unpackISMID(bitstrm: ConstBitStream, piSize: int) -> ISM_ID: + assert piSize == 1 or piSize == 2 or piSize == 3 or piSize == 4, "Incorrect PI Data Size for ISM_ID" + IsmID = list() + for _ in range(piSize): + IsmID.append(bitstrm.read(8).uint+1) + return ISM_ID(ids=IsmID) + +def packISMID(bitstrm: BitStream, data: any): + assert type(data) == ISM_ID, "Data of type ISM_ID is expected" + ism_id = cast(ISM_ID, data) + assert len(ism_id.ids) <= 4, "Maximum 4 objects" + for id in ism_id.ids: + bitstrm.append(f'uint:8={id}') + +def unpackISMGain(bitstrm: ConstBitStream, piSize: int) -> ISM_GAIN: + assert piSize == 1 or piSize == 2 or piSize == 3 or piSize == 4, "Incorrect PI Data Size for ISM_GAIN" + IsmGain = list() + for _ in range(piSize): + IsmGain.append(bitstrm.read(7).uint) + bitstrm.bytealign() + return ISM_GAIN(gains=IsmGain) + +def packISMGain(bitstrm: BitStream, data: any): + assert type(data) == ISM_GAIN, "Data of type ISM_GAIN is expected" + ism_gain = cast(ISM_GAIN, data) + assert len(ism_gain.gains) <= 4, "Maximum 4 objects" + for gain in ism_gain.gains: + gain_idx = getListIndex(ismGains, gain) + bitstrm.append(f'uint:7={gain_idx}') + bitstrm.append(f'uint:1=0') + +def unpackISMDistanceAttenuation(bitstrm: ConstBitStream, piSize: int) -> ISM_DISTANCE_ATTENUATION: + ref_dist = None + max_dist = None + roll_off = None + assert piSize == 1*3 or piSize == 2*3 or piSize == 3*3 or piSize == 4*3, "Incorrect PI Data Size for ISM_DISTANCE_ATTENUATION" + ism_distance_attenutation = list() + for _ in range(piSize): + ref_dist = bitstrm.read(6).uint + max_dist = bitstrm.read(6).uint + roll_off = bitstrm.read(6).uint + ism_distance_attenutation.append(DISTANCE_ATTENUATION(ref_dist=ref_dist, max_dist=max_dist, roll_off=roll_off)) + bitstrm.bytealign() + return ISM_DISTANCE_ATTENUATION(distance_attenuations=ism_distance_attenutation) + +def packISMDistanceAttenuation(bitstrm: BitStream, data: any): + assert type(data) == list, "Data of type list is expected" + + for att in cast(list, data): + assert type(att) == DISTANCE_ATTENUATION, "Data of type list[DISTANCE_ATTENUATION] is expected" + ref_dist_idx = getListIndex(refDistances, att.ref_dist) + max_dist_idx = getListIndex(maxDistances, att.max_dist) + roll_off_idx = getListIndex(rolloffFactors, att.roll_off) + bitstrm.append(f'uint:6={ref_dist_idx}') + bitstrm.append(f'uint:6={max_dist_idx}') + bitstrm.append(f'uint:6={roll_off_idx}') + bitstrm.append(f'uint:6=0') + + +def unpackPositions(bitstrm: ConstBitStream, piSize: int) -> list[POSITION]: + assert piSize <= 24 and (piSize % 6) == 0, "Incorrect PI Data Size for Positions" + positions = list() + while piSize > 0: + x = bitstrm.read(16).int / 100.0 + y = bitstrm.read(16).int / 100.0 + z = bitstrm.read(16).int / 100.0 + positions.append(POSITION(x, y, z)) + piSize -= 6 + return positions + +def unpackISMDirectivity(bitstrm: ConstBitStream, piSize: int) -> list[DISTANCE_ATTENUATION]: + inner_ang = None + outer_ang = None + outer_att = None + assert piSize == 1*2 or piSize == 2*2 or piSize == 3*2 or piSize == 4*2, "Incorrect PI Data Size for ISM_DISTANCE_ATTENUATION" + directivities = list() + for _ in range(piSize): + inner_ang = bitstrm.read(5).uint + outer_ang = bitstrm.read(5).uint + outer_att = bitstrm.read(5).uint + directivities.append(DIRECTIVITY(inner_ang=inner_ang, outer_ang=outer_ang, outer_att=outer_att)) + bitstrm.bytealign() + return directivities + +def packISMDirectivity(bitstrm: BitStream, data: any): + assert type(data) == list, "Data of type ISM_DIRECTIVITY is expected" + + for dir in cast(list, data): + assert type(dir) == DIRECTIVITY, "Orientation PI Data expects a data of type list[DIRECTIVITY]" + inner_ang_idx = getListIndex(innerOuterAngles, dir.inner_ang) + outer_ang_idx = getListIndex(innerOuterAngles, dir.outer_ang) + outer_att_idx = getListIndex(outerAttenuations, dir.outer_att) + bitstrm.append(f'uint:5={inner_ang_idx}') + bitstrm.append(f'uint:5={outer_ang_idx}') + bitstrm.append(f'uint:5={outer_att_idx}') + bitstrm.append(f'uint:1=0') PIDataUnpacker = [ unpackOrientation, # SCENE_ORIENTATION, @@ -626,13 +780,13 @@ PIDataUnpacker = [ unpackOrientation, # DEVICE_ORIENTATION_UNCOMPENSATED unpackAcousticEnv, # ACOUSTIC_ENVIRONMENT unpackAudioDescription, # AUDIO_DESCRIPTION - unpackUnsupported, # ISM_NUM - unpackUnsupported, # ISM_ID - unpackUnsupported, # ISM_GAIN + unpackISMNum, # ISM_NUM + unpackISMID, # ISM_ID + unpackISMGain, # ISM_GAIN unpackOrientations,# ISM_ORIENTATION unpackPositions, # ISM_POSITION - unpackUnsupported, # ISM_DISTANCE_ATTENUATION - unpackUnsupported, # ISM_DIRECTIVITY + unpackISMDistanceAttenuation, # ISM_DISTANCE_ATTENUATION + unpackISMDirectivity, # ISM_DIRECTIVITY unpackDiegetic, # DIEGETIC_TYPE unpackUnsupported, # RESERVED13 unpackAudioFocus, # AUDIO_FOCUS_INDICATION @@ -661,13 +815,13 @@ PIDataPacker = [ packOrientation, # DEVICE_ORIENTATION_UNCOMPENSATED packAcousticEnv, # ACOUSTIC_ENVIRONMENT packAudioDescription, # AUDIO_DESCRIPTION - packUnsupported, # ISM_NUM - packUnsupported, # ISM_ID - packUnsupported, # ISM_GAIN + packISMNum, # ISM_NUM + packISMID, # ISM_ID + packISMGain, # ISM_GAIN packOrientations,# ISM_ORIENTATION packPositions, # ISM_POSITION - packUnsupported, # ISM_DISTANCE_ATTENUATION - packUnsupported, # ISM_DIRECTIVITY + packISMDistanceAttenuation, # ISM_DISTANCE_ATTENUATION + packISMDirectivity, # ISM_DIRECTIVITY packDiegetic, # DIEGETIC_TYPE packUnsupported, # RESERVED13 packAudioFocus, # AUDIO_FOCUS_INDICATION diff --git a/tests/rtp/test_rtp.py b/tests/rtp/test_rtp.py index 4e394ee478..b770fd0fd6 100644 --- a/tests/rtp/test_rtp.py +++ b/tests/rtp/test_rtp.py @@ -169,6 +169,14 @@ def generatePiData(startTs: int, endTs: int) -> dict: someAuFocusLvl = lambda : AUDIO_FOCUS(level=AUDIO_FOCUS_LEVEL(random.randint(0, 15))) someAuFocusList = [someAuFocusDirLvl, someAuFocusDir, someAuFocusLvl] + someNumISM = lambda : ISM_NUM(num=random.randint(1, 4)) + someISMIds = lambda num_ism : ISM_ID(ids=[int(random.getrandbits(8)) for _ in range(num_ism)]) + someISMGains = lambda num_ism : ISM_GAIN(gains=[int(random.randint(-96,3)) for _ in range(num_ism)]) + someISMOrientations = lambda num_ism : [ORIENTATION(w=2*random.random()-1.0, x=2*random.random()-1.0, y=2*random.random()-1.0, z=2*random.random()-1.0) for _ in range(num_ism)] + someISMPositions = lambda num_ism : [POSITION( x=random.randint(-32788, 32767)/100.0, y=random.randint(-32788, 32767)/100.0, z=random.randint(-32788, 32767)/100.0) for _ in range(num_ism)] + someISMDistanceAttenuations = lambda num_ism : [DISTANCE_ATTENUATION(ref_dist=random.randint(1,64)/10.0, max_dist=random.randint(1,64), roll_off=random.randint(0,40)/10.0) for _ in range(num_ism)] + someISMDirectivities = lambda num_ism : [DIRECTIVITY(inner_ang=random.randint(0,24)*15, outer_ang=random.randint(0,24)*15, outer_att=random.randint(-30,0)*3) for _ in range(num_ism)] + for ts in range(startTs, endTs, 320): pidata = dict() pidata["SCENE_ORIENTATION"] = someOrientation() @@ -182,6 +190,13 @@ def generatePiData(startTs: int, endTs: int) -> dict: pidata["AUDIO_DESCRIPTION"] = [someDesc() for n in range(random.randint(1, 5))] pidata["DIEGETIC_TYPE"] = someDIG() pidata["ACOUSTIC_ENVIRONMENT"] = ACOUSTIC_ENVIRONMENT(aeid=random.randint(0, 127)) + pidata["ISM_NUM"] = someNumISM() + pidata["ISM_ID"] = someISMIds(pidata["ISM_NUM"].num) + pidata["ISM_GAIN"] = someISMGains(pidata["ISM_NUM"].num) + pidata["ISM_ORIENTATION"] = someISMOrientations(pidata["ISM_NUM"].num) + pidata["ISM_POSITION"] = someISMPositions(pidata["ISM_NUM"].num) + pidata["ISM_DISTANCE_ATTENUATION"] = someISMDistanceAttenuations(pidata["ISM_NUM"].num) + pidata["ISM_DIRECTIVITY"] = someISMDirectivities(pidata["ISM_NUM"].num) data[str(ts)] = pidata return data -- GitLab From bf093618cc135544b3da7a06a54ab3fb6572079a Mon Sep 17 00:00:00 2001 From: Lauros Pajunen Date: Thu, 30 Oct 2025 15:18:48 +0200 Subject: [PATCH 02/15] Fix ISM orientation PI json writing --- apps/decoder.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 4bd2c802f5..40c4ef78ec 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -396,10 +396,14 @@ static void IVAS_RTP_LogPiData( FILE *f_piDataOut, PIDATA_TS *piData, uint32_t n fprintf( f_piDataOut, "[\n" ); for ( n = 0; n < cur->data.ismOrientation.size / 8; n++ ) { - fprintf( f_piDataOut, "\t\t\t{\n\t\t\t\t\"w\": %f,\n\t\t\t\t\"x\": %f,\n\t\t\t\t\"y\": %f,\n\t\t\t\t\"z\": %f \n\t\t\t},\n", + if ( n != 0 ) + { + fprintf( f_piDataOut, ",\n" ); + } + fprintf( f_piDataOut, "\t\t\t{\n\t\t\t\t\"w\": %f,\n\t\t\t\t\"x\": %f,\n\t\t\t\t\"y\": %f,\n\t\t\t\t\"z\": %f \n\t\t\t}", cur->data.ismOrientation.orientation[n].w, cur->data.ismOrientation.orientation[n].x, cur->data.ismOrientation.orientation[n].y, cur->data.ismOrientation.orientation[n].z ); } - fprintf( f_piDataOut, "\t\t]" ); + fprintf( f_piDataOut, "\n\t\t]" ); } break; case IVAS_PI_ISM_NUM: -- GitLab From 8b4d4af714ecb6053d381592b7e048daa83f8ada Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20Toftg=C3=A5rd?= Date: Wed, 5 Nov 2025 20:59:09 +0100 Subject: [PATCH 03/15] - Remove ISM PI data tables in ivas_rtp_pi_data.c - Initialize non-unpacked PI data to default values - Add output to JSON - Add JSON to generated PI data comparisons - Bug fixes --- apps/decoder.c | 80 +++++++++- lib_util/ivas_rtp_pi_data.c | 309 +++++++++++++++--------------------- lib_util/ivas_rtp_pi_data.h | 18 +++ tests/rtp/test_rtp.py | 44 ++++- 4 files changed, 267 insertions(+), 184 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 40c4ef78ec..57c0a748c1 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -234,7 +234,7 @@ static void IVAS_RTP_LogPiData( FILE *f_piDataOut, PIDATA_TS *piData, uint32_t n return; } - if ( ftell( f_piDataOut ) > 2 ) + if ( ftell( f_piDataOut ) > 3 ) { fprintf( f_piDataOut, ",\n" ); } @@ -394,7 +394,7 @@ static void IVAS_RTP_LogPiData( FILE *f_piDataOut, PIDATA_TS *piData, uint32_t n case IVAS_PI_ISM_ORIENTATION: { fprintf( f_piDataOut, "[\n" ); - for ( n = 0; n < cur->data.ismOrientation.size / 8; n++ ) + for ( n = 0; n < cur->data.ismOrientation.numObjects; n++ ) { if ( n != 0 ) { @@ -407,12 +407,86 @@ static void IVAS_RTP_LogPiData( FILE *f_piDataOut, PIDATA_TS *piData, uint32_t n } break; case IVAS_PI_ISM_NUM: + { + fprintf( f_piDataOut, "{\n" ); + fprintf( f_piDataOut, "\t\t\t\"num\": %d", cur->data.ismNum.numObjects ); + fprintf( f_piDataOut, "\n\t\t}" ); + } + break; case IVAS_PI_ISM_ID: + { + fprintf( f_piDataOut, "{\n" ); + fprintf( f_piDataOut, "\t\t\t\"ids\": [\n" ); + for ( n = 0; n < cur->data.ismId.numObjects; n++ ) + { + if ( n != 0 ) + { + fprintf( f_piDataOut, ",\n" ); + } + fprintf( f_piDataOut, "\t\t\t\t%d", cur->data.ismId.id[n] ); + } + fprintf( f_piDataOut, "\n\t\t\t]" ); + fprintf( f_piDataOut, "\n\t\t}" ); + } + break; case IVAS_PI_ISM_GAIN: - + { + fprintf( f_piDataOut, "{\n" ); + fprintf( f_piDataOut, "\t\t\t\"gains\": [\n" ); + for ( n = 0; n < cur->data.ismGain.numObjects; n++ ) + { + if ( n != 0 ) + { + fprintf( f_piDataOut, ",\n" ); + } + fprintf( f_piDataOut, "\t\t\t\t%d", cur->data.ismGain.dB[n] ); + } + fprintf( f_piDataOut, "\n\t\t\t]" ); + fprintf( f_piDataOut, "\n\t\t}" ); + } + break; case IVAS_PI_ISM_POSITION: + { + fprintf( f_piDataOut, "[\n" ); + for ( n = 0; n < cur->data.ismPosition.numObjects; n++ ) + { + if ( n != 0 ) + { + fprintf( f_piDataOut, ",\n" ); + } + fprintf( f_piDataOut, "\t\t\t{\n\t\t\t\t\"x\": %f,\n\t\t\t\t\"y\": %f,\n\t\t\t\t\"z\": %f \n\t\t\t}", cur->data.ismPosition.position[n].x, cur->data.ismPosition.position[n].y, cur->data.ismPosition.position[n].z ); + } + fprintf( f_piDataOut, "\n\t\t]" ); + } + break; case IVAS_PI_ISM_DISTANCE_ATTENUATION: + { + fprintf( f_piDataOut, "[\n" ); + for ( n = 0; n < cur->data.ismAttenuation.numObjects; n++ ) + { + if ( n != 0 ) + { + fprintf( f_piDataOut, ",\n" ); + } + fprintf( f_piDataOut, "\t\t\t{\n\t\t\t\t\"ref_dist\": %f,\n\t\t\t\t\"max_dist\": %f,\n\t\t\t\t\"roll_off\": %f \n\t\t\t}", cur->data.ismAttenuation.distAtten[n].ref_dist, cur->data.ismAttenuation.distAtten[n].max_dist, cur->data.ismAttenuation.distAtten[n].roll ); + } + fprintf( f_piDataOut, "\n\t\t]" ); + } + break; case IVAS_PI_ISM_DIRECTIVITY: + { + fprintf( f_piDataOut, "[\n" ); + for ( n = 0; n < cur->data.ismDirectivity.numObjects; n++ ) + { + if ( n != 0 ) + { + fprintf( f_piDataOut, ",\n" ); + } + fprintf( f_piDataOut, "\t\t\t{\n\t\t\t\t\"inner_ang\": %d,\n\t\t\t\t\"outer_ang\": %d,\n\t\t\t\t\"outer_att\": %f \n\t\t\t}", cur->data.ismDirectivity.directivity[n].innerConeAngle, cur->data.ismDirectivity.directivity[n].outerConeAngle, cur->data.ismDirectivity.directivity[n].outerAttenuationdB ); + } + fprintf( f_piDataOut, "\n\t\t]" ); + } + break; case IVAS_PI_PI_LATENCY: case IVAS_PI_R_ISM_ID: case IVAS_PI_R_ISM_GAIN: diff --git a/lib_util/ivas_rtp_pi_data.c b/lib_util/ivas_rtp_pi_data.c index 3f2fa18463..acd35d7a95 100644 --- a/lib_util/ivas_rtp_pi_data.c +++ b/lib_util/ivas_rtp_pi_data.c @@ -34,6 +34,9 @@ #include "ivas_rtp_pi_data.h" #include "ivas_error_utils.h" #include "ivas_rtp_internal.h" +#ifdef ISM_PI_DATA +#include +#endif #ifdef IVAS_RTPDUMP @@ -180,8 +183,8 @@ static ivas_error packISMOrientation( const IVAS_PIDATA_GENERIC *piData, uint8_t } buffer[nBytes++] = ( orientation->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ - buffer[nBytes++] = (uint8_t) piData->size; - for ( n = 0; n < piData->size / 8; n++ ) + buffer[nBytes++] = (uint8_t) orientation->numObjects * 8; + for ( n = 0; n < orientation->numObjects; n++ ) { nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( orientation->orientation[n].w ) ); nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( orientation->orientation[n].x ) ); @@ -215,7 +218,7 @@ static ivas_error unpackOrientation( const uint8_t *buffer, uint32_t numDataByte #ifdef ISM_PI_DATA static ivas_error unpackISMOrientation( const uint8_t *buffer, uint32_t numDataBytes, IVAS_PIDATA_GENERIC *piData ) { - IVAS_PIDATA_ISM_ORIENTATION *orientation = (IVAS_PIDATA_ISM_ORIENTATION *) piData; + IVAS_PIDATA_ISM_ORIENTATION *ism_orientation = (IVAS_PIDATA_ISM_ORIENTATION *) piData; /* Orientation data is 8 bytes */ uint16_t n; @@ -224,13 +227,22 @@ static ivas_error unpackISMOrientation( const uint8_t *buffer, uint32_t numDataB return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "Incorrect size to unpack Orientation PI data" ); } - piData->size = numDataBytes; - for ( n = 0; n < numDataBytes / 8; n++ ) + ism_orientation->size = sizeof( IVAS_PIDATA_ISM_ORIENTATION ); + ism_orientation->numObjects = (uint16_t) numDataBytes / 8; + + for ( n = 0; n < ism_orientation->numObjects; n++ ) { - orientation->orientation[n].w = FLOAT_FROM_Q15( readInt16( &buffer[8 * n] ) ); - orientation->orientation[n].x = FLOAT_FROM_Q15( readInt16( &buffer[8 * n + 2] ) ); - orientation->orientation[n].y = FLOAT_FROM_Q15( readInt16( &buffer[8 * n + 4] ) ); - orientation->orientation[n].z = FLOAT_FROM_Q15( readInt16( &buffer[8 * n + 6] ) ); + ism_orientation->orientation[n].w = FLOAT_FROM_Q15( readInt16( &buffer[8 * n] ) ); + ism_orientation->orientation[n].x = FLOAT_FROM_Q15( readInt16( &buffer[8 * n + 2] ) ); + ism_orientation->orientation[n].y = FLOAT_FROM_Q15( readInt16( &buffer[8 * n + 4] ) ); + ism_orientation->orientation[n].z = FLOAT_FROM_Q15( readInt16( &buffer[8 * n + 6] ) ); + } + for ( ; n < IVAS_PI_MAX_OBJECTS; n++ ) + { + ism_orientation->orientation[n].w = 0.0f; + ism_orientation->orientation[n].x = 0.0f; + ism_orientation->orientation[n].y = 0.0f; + ism_orientation->orientation[n].z = 0.0f; } return IVAS_ERR_OK; @@ -600,7 +612,7 @@ static ivas_error packISMPosition( const IVAS_PIDATA_GENERIC *piData, uint8_t *b static ivas_error unpackISMPosition( const uint8_t *buffer, uint32_t numDataBytes, IVAS_PIDATA_GENERIC *piData ) { uint16_t n; - IVAS_PIDATA_ISM_POSITION *listener = (IVAS_PIDATA_ISM_POSITION *) piData; + IVAS_PIDATA_ISM_POSITION *ism_position = (IVAS_PIDATA_ISM_POSITION *) piData; /* Position data is 6 bytes */ if ( numDataBytes % 6 != 0 ) @@ -608,13 +620,15 @@ static ivas_error unpackISMPosition( const uint8_t *buffer, uint32_t numDataByte return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "Incorrect size to unpack LISTENER POSITION PI data" ); } - listener->size = sizeof( IVAS_PIDATA_ISM_POSITION ); - listener->piDataType = IVAS_PI_ISM_POSITION; - for ( n = 0; n < numDataBytes / 6; n++ ) + ism_position->size = sizeof( IVAS_PIDATA_ISM_POSITION ); + ism_position->piDataType = IVAS_PI_ISM_POSITION; + ism_position->numObjects = (uint16_t) numDataBytes / 6; + + for ( n = 0; n < ism_position->numObjects; n++ ) { - listener->position[n].x = FLOAT_FROM_Q15( readInt16( &buffer[6 * n] ) ) * MAX_PI_POSITION_METERS; - listener->position[n].y = FLOAT_FROM_Q15( readInt16( &buffer[6 * n + 2] ) ) * MAX_PI_POSITION_METERS; - listener->position[n].z = FLOAT_FROM_Q15( readInt16( &buffer[6 * n + 4] ) ) * MAX_PI_POSITION_METERS; + ism_position->position[n].x = FLOAT_FROM_Q15( readInt16( &buffer[6 * n] ) ) * MAX_PI_POSITION_METERS; + ism_position->position[n].y = FLOAT_FROM_Q15( readInt16( &buffer[6 * n + 2] ) ) * MAX_PI_POSITION_METERS; + ism_position->position[n].z = FLOAT_FROM_Q15( readInt16( &buffer[6 * n + 4] ) ) * MAX_PI_POSITION_METERS; } return IVAS_ERR_OK; } @@ -790,15 +804,15 @@ static ivas_error packISMNum( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect PI ID in ISM_NUM PI data" ); } - /* ISM_NUM data is 1 bytes, header is 2 bytes */ - if ( maxDataBytes < 1 + 2 ) + /* ISM_NUM data is 1 bytes */ + if ( maxDataBytes < 1 ) { return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack ISM_NUM PI data" ); } buffer[nBytes++] = ( ism_num->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ buffer[nBytes++] = 1; - buffer[nBytes++] = ( ism_num->numObjects - 1 ) & MASK_2BIT << 6; + buffer[nBytes++] = ( ( ism_num->numObjects - 1 ) & MASK_2BIT ) << 6; *nBytesWritten = nBytes; return IVAS_ERR_OK; } @@ -839,8 +853,8 @@ static ivas_error packISMID( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect PI ID in ISM_ID PI data" ); } - /* ISM_ID data is 1 byte per object, header is 2 bytes */ - if ( maxDataBytes < 1 * IVAS_PI_MAX_OBJECTS + 2 ) + /* ISM_ID data is 1 byte per object */ + if ( maxDataBytes < 1 * IVAS_PI_MAX_OBJECTS ) { return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack ISM_NUM PI data" ); } @@ -848,7 +862,7 @@ static ivas_error packISMID( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, buffer[nBytes++] = ( ism_id->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ buffer[nBytes++] = (uint8_t) piData->size; /* Pack ID for each object */ - for ( n = 0; n < piData->size; n++ ) + for ( n = 0; n < ism_id->numObjects; n++ ) { buffer[nBytes++] = ( ism_id->id[n] & MASK_8BIT ); } @@ -869,12 +883,17 @@ static ivas_error unpackISMID( const uint8_t *buffer, uint32_t numDataBytes, IVA ism_id->size = sizeof( IVAS_PIDATA_ISM_ID ); ism_id->piDataType = IVAS_PI_ISM_ID; + ism_id->numObjects = (uint16_t) numDataBytes; /* Unpack ID for each object (1 byte each) */ - for ( n = 0; n < numDataBytes; n++ ) + for ( n = 0; n < ism_id->numObjects; n++ ) { ism_id->id[n] = buffer[n]; } + for ( ; n < IVAS_PI_MAX_OBJECTS; n++ ) + { + ism_id->id[n] = 0; /* Initializing to 0, although there might be another object with this ID */ + } return IVAS_ERR_OK; } @@ -897,8 +916,8 @@ static ivas_error packISMGain( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffe return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect PI ID in ISM_GAIN PI data" ); } - /* ISM_GAIN data is 1 byte per object, header is 2 bytes */ - if ( maxDataBytes < 1 * IVAS_PI_MAX_OBJECTS + 2 ) + /* ISM_GAIN data is 1 byte per object */ + if ( maxDataBytes < 1 * IVAS_PI_MAX_OBJECTS ) { return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack ISM_GAIN PI data" ); } @@ -906,21 +925,15 @@ static ivas_error packISMGain( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffe buffer[nBytes++] = ( ism_gain->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ buffer[nBytes++] = (uint8_t) piData->size; /* Pack ID for each object */ - for ( n = 0; n < piData->size; n++ ) + for ( n = 0; n < ism_gain->numObjects; n++ ) { gain = (int16_t) ism_gain->dB[n]; - if ( gain >= 0 ) + idx = min( -gain, 97 ); + if ( gain > 0 ) { - idx = getIndexTable_s( ismGains, 4, gain ); - if ( idx > 0 ) - { - idx += 97; - } - } - else - { - idx = getIndexTable_s( ismGains, 98, -gain ); + idx += 97; } + buffer[nBytes++] = ( idx & MASK_7BIT ) << 1; } *nBytesWritten = nBytes; @@ -940,20 +953,36 @@ static ivas_error unpackISMGain( const uint8_t *buffer, uint32_t numDataBytes, I ism_gain->size = sizeof( IVAS_PIDATA_ISM_GAIN ); ism_gain->piDataType = IVAS_PI_ISM_GAIN; + ism_gain->numObjects = (uint16_t) numDataBytes; /* Unpack ID for each object (1 byte each) */ - for ( n = 0; n < numDataBytes; n++ ) + for ( n = 0; n < ism_gain->numObjects; n++ ) { idx = ( buffer[n] ) >> 1; - if ( idx < 98 ) + /* negative gains*/ + if ( idx < 97 ) { - ism_gain->dB[n] = (int8_t) -ismGains[idx]; + ism_gain->dB[n] = -(int8_t) ( idx ); + } + /* Set to min for muting, to be interpreted as -Inf */ + else if ( idx == 97 ) + { + ism_gain->dB[n] = -128; + } + /* postive gains */ + else if ( idx < 101 ) + { + ism_gain->dB[n] = (int8_t) idx - 97; } else { - ism_gain->dB[n] = (int8_t) ismGains[idx]; + return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "Incorrect index for ISM_GAIN PI data" ); } } + for ( ; n < IVAS_PI_MAX_OBJECTS; n++ ) + { + ism_gain->dB[n] = 0; /* Set to default */ + } return IVAS_ERR_OK; } @@ -975,8 +1004,8 @@ static ivas_error packISMDistanceAttenuation( const IVAS_PIDATA_GENERIC *piData, return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect PI ID in ISM_DISTANCE_ATTENUATION PI data" ); } - /* ISM_DISTANCE_ATTENUATION data is 3 bytes per object, header is 2 bytes */ - if ( maxDataBytes > 3 * IVAS_PI_MAX_OBJECTS + 2 ) + /* ISM_DISTANCE_ATTENUATION data is 3 bytes per object */ + if ( maxDataBytes > 3 * IVAS_PI_MAX_OBJECTS ) { return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack ISM_DISTANCE_ATTENUATION PI data" ); } @@ -984,11 +1013,15 @@ static ivas_error packISMDistanceAttenuation( const IVAS_PIDATA_GENERIC *piData, buffer[nBytes++] = ( ism_att->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ buffer[nBytes++] = (uint8_t) piData->size; /* Pack ID for each object */ - for ( n = 0; n < piData->size; n++ ) + for ( n = 0; n < ism_att->numObjects; n++ ) { - lWord = (uint32_t) ( getIndexTable( refDistances, 64, ism_att->distAtten[n].ref_dist ) << 18 ); - lWord |= (uint32_t) ( getIndexTable( maxDistances, 65, ism_att->distAtten[n].max_dist ) << 12 ); - lWord |= (uint32_t) ( getIndexTable( rollOffFactors, 41, ism_att->distAtten[n].roll ) << 6 ); + if ( ism_att->distAtten[n].ref_dist < 0 || ism_att->distAtten[n].max_dist < 0 || ism_att->distAtten[n].roll < 0 ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect DISTANCE ATTENUATION data" ); + } + lWord = (uint32_t) ( min( (uint16_t) ( ism_att->distAtten[n].ref_dist * 10.0f + 0.5f ) - 1, 63 ) << 18 ); + lWord |= (uint32_t) ( min( (uint16_t) ( ism_att->distAtten[n].max_dist + 0.5f ) - 1, 63 ) << 12 ); + lWord |= (uint32_t) ( min( (uint16_t) ( ism_att->distAtten[n].roll * 10.0f + 0.5f ), 40 ) << 6 ); buffer[nBytes++] = ( lWord >> 16 ) & MASK_8BIT; buffer[nBytes++] = ( lWord >> 8 ) & MASK_8BIT; @@ -1011,17 +1044,24 @@ static ivas_error unpackISMDistanceAttenuation( const uint8_t *buffer, uint32_t ism_att->size = sizeof( IVAS_PIDATA_ISM_ATTENUATION ); ism_att->piDataType = IVAS_PI_ISM_DISTANCE_ATTENUATION; + ism_att->numObjects = (uint16_t) numDataBytes / 3; /* Unpack attenuation for each object (3 bytes each) */ - for ( n = 0; n < numDataBytes / 3; n++ ) + for ( n = 0; n < ism_att->numObjects; n++ ) { lWord = ( buffer[3 * n] ) << 16; - lWord = ( buffer[3 * n + 1] ) << 8; - lWord = buffer[3 * n + 2]; + lWord |= ( buffer[3 * n + 1] ) << 8; + lWord |= buffer[3 * n + 2]; - ism_att->distAtten[n].ref_dist = refDistances[( lWord >> 18 ) & MASK_6BIT]; - ism_att->distAtten[n].max_dist = maxDistances[( lWord >> 12 ) & MASK_6BIT]; - ism_att->distAtten[n].roll = rollOffFactors[( lWord >> 6 ) & MASK_6BIT]; + ism_att->distAtten[n].ref_dist = ( ( ( lWord >> 18 ) & MASK_6BIT ) + 1 ) / 10.0f; + ism_att->distAtten[n].max_dist = (float) ( ( lWord >> 12 ) & MASK_6BIT ) + 1 ; + ism_att->distAtten[n].roll = ( ( lWord >> 6 ) & MASK_6BIT ) / 10.0f; + } + for ( ; n < IVAS_PI_MAX_OBJECTS; n++ ) + { + ism_att->distAtten[n].ref_dist = 1.0f; /* Set to default */ + ism_att->distAtten[n].max_dist = 16.0f; /* Set to default */ + ism_att->distAtten[n].roll = 1.0f; /* Set to default */ } return IVAS_ERR_OK; } @@ -1029,7 +1069,7 @@ static ivas_error packISMDirectivity( const IVAS_PIDATA_GENERIC *piData, uint8_t { uint32_t nBytes = 0, n; const IVAS_PIDATA_ISM_DIRECTIVITY *ism_directivity = (const IVAS_PIDATA_ISM_DIRECTIVITY *) piData; - uint16_t word; + uint16_t word, idx; *nBytesWritten = 0; @@ -1044,19 +1084,26 @@ static ivas_error packISMDirectivity( const IVAS_PIDATA_GENERIC *piData, uint8_t } /* ISM_DIRECTIVITY data is 2 bytes per object, header is 2 bytes */ - if ( maxDataBytes > 2 * IVAS_PI_MAX_OBJECTS + 2 ) + if ( maxDataBytes > 2 * IVAS_PI_MAX_OBJECTS ) { return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack ISM_DIRECTIVITY PI data" ); } buffer[nBytes++] = ( ism_directivity->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ buffer[nBytes++] = (uint8_t) piData->size; - /* Pack ID for each object */ - for ( n = 0; n < piData->size; n++ ) + /* Pack directivity for each object */ + for ( n = 0; n < ism_directivity->numObjects; n++ ) { - word = (uint16_t) ( getIndexTable_s( innerOuterAngles, 25, ism_directivity->directivity[n].innerConeAngle ) << 11 ); - word |= (uint16_t) ( getIndexTable_s( innerOuterAngles, 25, ism_directivity->directivity[n].outerConeAngle ) << 6 ); - word |= (uint16_t) ( getIndexTable( outerAttenuations, 32, ism_directivity->directivity[n].outerAttenuationdB ) << 1 ); + word = (uint16_t) ( min( ism_directivity->directivity[n].innerConeAngle / 15, 24 ) << 11 ); + word |= (uint16_t) ( min( ism_directivity->directivity[n].outerConeAngle / 15, 24 ) << 6 ); + + idx = 0; + /* For outer attenuation < -90 dB, idx = 0, which corresponds to -Inf (muting) */ + if ( ism_directivity->directivity[n].outerAttenuationdB >= -90.0f ) + { + idx = 32 - (uint16_t) ( -ism_directivity->directivity[n].outerAttenuationdB / 3.0f + 0.5f ); + } + word |= (uint16_t) ( min( idx, 31 ) << 1 ); buffer[nBytes++] = ( word >> 8 ) & MASK_8BIT; buffer[nBytes++] = word & MASK_8BIT; @@ -1068,7 +1115,7 @@ static ivas_error packISMDirectivity( const IVAS_PIDATA_GENERIC *piData, uint8_t static ivas_error unpackISMDirectivity( const uint8_t *buffer, uint32_t numDataBytes, IVAS_PIDATA_GENERIC *piData ) { uint32_t n; - uint16_t word; + uint16_t word, idx; IVAS_PIDATA_ISM_DIRECTIVITY *ism_directivity = (IVAS_PIDATA_ISM_DIRECTIVITY *) piData; /* ISM_DIRECTIVITY data is 2 bytes per object */ @@ -1079,17 +1126,32 @@ static ivas_error unpackISMDirectivity( const uint8_t *buffer, uint32_t numDataB ism_directivity->size = sizeof( IVAS_PIDATA_ISM_DIRECTIVITY ); ism_directivity->piDataType = IVAS_PI_ISM_DIRECTIVITY; + ism_directivity->numObjects = (uint16_t) numDataBytes / 2; - /* Unpack attenuation for each object (3 bytes each) */ - for ( n = 0; n < numDataBytes / 2; n++ ) + /* Unpack directivity for each object (2 bytes each) */ + for ( n = 0; n < ism_directivity->numObjects; n++ ) { - word = ( buffer[3 * n] ) << 16; - word = ( buffer[3 * n + 1] ) << 8; - word = buffer[3 * n + 2]; + word = ( buffer[2 * n] ) << 8; + word |= ( buffer[2 * n + 1] ); - ism_directivity->directivity[n].innerConeAngle = innerOuterAngles[( word >> 11 ) & MASK_5BIT]; - ism_directivity->directivity[n].outerConeAngle = innerOuterAngles[( word >> 6 ) & MASK_5BIT]; - ism_directivity->directivity[n].outerAttenuationdB = outerAttenuations[( word >> 1 ) & MASK_5BIT]; + ism_directivity->directivity[n].innerConeAngle = ( ( word >> 11 ) & MASK_5BIT ) * 15; + ism_directivity->directivity[n].outerConeAngle = ( ( word >> 6 ) & MASK_5BIT ) * 15; + idx = ( word >> 1 ) & MASK_5BIT; + + if (idx == 0) + { + ism_directivity->directivity[n].outerAttenuationdB = SHRT_MIN; /* corresponds to muting */ + } + else + { + ism_directivity->directivity[n].outerAttenuationdB = -3.0f * ( 31 - ( ( word >> 1 ) & MASK_5BIT ) ); + } + } + for ( ; n < IVAS_PI_MAX_OBJECTS; n++ ) + { + ism_directivity->directivity[n].innerConeAngle = 360; /* Set to default */ + ism_directivity->directivity[n].outerConeAngle = 360; /* Set to default */ + ism_directivity->directivity[n].outerAttenuationdB = 0; /* Set to default */ } return IVAS_ERR_OK; } @@ -1330,115 +1392,4 @@ const float mapAbsorbtion[1u << NBITS_ABS] = { 0.0800f, 0.1656f, 0.3430f, 0.7101f }; -#ifdef ISM_PI_DATA -/* gains with negative values flipped to positive for the search */ -const int16_t ismGains[98] = { - 0, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 32767 -}; -// const float ismGains[98] = { -// 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, -// 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, -// 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, 20.0f, -// 21.0f, 22.0f, 23.0f, 24.0f, 25.0f, 26.0f, 27.0f, -// 28.0f, 29.0f, 30.0f, 31.0f, 32.0f, 33.0f, 34.0f, -// 35.0f, 36.0f, 37.0f, 38.0f, 39.0f, 40.0f, 41.0f, -// 42.0f, 43.0f, 44.0f, 45.0f, 46.0f, 47.0f, 48.0f, -// 49.0f, 50.0f, 51.0f, 52.0f, 53.0f, 54.0f, 55.0f, -// 56.0f, 57.0f, 58.0f, 59.0f, 60.0f, 61.0f, 62.0f, -// 63.0f, 64.0f, 65.0f, 66.0f, 67.0f, 68.0f, 69.0f, -// 70.0f, 71.0f, 72.0f, 73.0f, 74.0f, 75.0f, 76.0f, -// 77.0f, 78.0f, 79.0f, 80.0f, 81.0f, 82.0f, 83.0f, -// 84.0f, 85.0f, 86.0f, 87.0f, 88.0f, 89.0f, 90.0f, -// 91.0f, 92.0f, 93.0f, 94.0f, 95.0f, 96.0f, 32768.0f -// }; - -const float refDistances[64] = { - 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, - 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, - 1.7f, 1.8f, 1.9f, 2.0f, 2.1f, 2.2f, 2.3f, 2.4f, - 2.5f, 2.6f, 2.7f, 2.8f, 2.9f, 3.0f, 3.1f, 3.2f, - 3.3f, 3.4f, 3.5f, 3.6f, 3.7f, 3.8f, 3.9f, 4.0f, - 4.1f, 4.2f, 4.3f, 4.4f, 4.5f, 4.6f, 4.7f, 4.8f, - 4.9f, 5.0f, 5.1f, 5.2f, 5.3f, 5.4f, 5.5f, 5.6f, - 5.7f, 5.8f, 5.9f, 6.0f, 6.1f, 6.2f, 6.3f, 6.4f -}; - -// const int16_t maxDistances[65] = { -// 0, 1, 2, 3, 4, 5, -// 6, 7, 8, 9, 10, 11, -// 12, 13, 14, 15, 16, 17, -// 18, 19, 20, 21, 22, 23, -// 24, 25, 26, 27, 28, 29, -// 30, 31, 32, 33, 34, 35, -// 36, 37, 38, 39, 40, 41, -// 42, 43, 44, 45, 46, 47, -// 48, 49, 50, 51, 52, 53, -// 54, 55, 56, 57, 58, 59, -// 60, 61, 62, 63, 64 -// }; -const float maxDistances[65] = { - 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, - 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, - 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, - 18.0f, 19.0f, 20.0f, 21.0f, 22.0f, 23.0f, - 24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f, - 30.0f, 31.0f, 32.0f, 33.0f, 34.0f, 35.0f, - 36.0f, 37.0f, 38.0f, 39.0f, 40.0f, 41.0f, - 42.0f, 43.0f, 44.0f, 45.0f, 46.0f, 47.0f, - 48.0f, 49.0f, 50.0f, 51.0f, 52.0f, 53.0f, - 54.0f, 55.0f, 56.0f, 57.0f, 58.0f, 59.0f, - 60.0f, 61.0f, 62.0f, 63.0f, 64.0f -}; - -const float rollOffFactors[41] = { - 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, - 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, - 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, - 1.8f, 1.9f, 2.0f, 2.1f, 2.2f, 2.3f, - 2.4f, 2.5f, 2.6f, 2.7f, 2.8f, 2.9f, - 3.0f, 3.1f, 3.2f, 3.3f, 3.4f, 3.5f, - 3.6f, 3.7f, 3.8f, 3.9f, 4.0f -}; - -const int16_t innerOuterAngles[25] = { - 0, 15, 30, 45, 60, - 75, 90, 105, 120, 135, - 150, 165, 180, 195, 210, - 225, 240, 255, 270, 285, - 300, 315, 330, 345, 360 -}; -// const float innerOuterAngles[25] = { -// 0.0f, 15.0f, 30.0f, 45.0f, 60.0f, -// 75.0f, 90.0f, 105.0f, 120.0f, 135.0f, -// 150.0f, 165.0f, 180.0f, 195.0f, 210.0f, -// 225.0f, 240.0f, 255.0f, 270.0f, 285.0f, -// 300.0f, 315.0f, 330.0f, 345.0f, 360.0f -// }; -// const int16_t outerAttenuations[32] = { -// -32768, -90, -87, -84, -81, -78, -75, -72, -// -69, -66, -63, -60, -57, -54, -51, -48, -// -45, -42, -39, -36, -33, -30, -27, -24, -// -21, -18, -15, -12, -9, -6, -3, 0 -//}; - -const float outerAttenuations[32] = { - -32768.0f, -90.0f, -87.0f, -84.0f, -81.0f, -78.0f, -75.0f, -72.0f, - -69.0f, -66.0f, -63.0f, -60.0f, -57.0f, -54.0f, -51.0f, -48.0f, - -45.0f, -42.0f, -39.0f, -36.0f, -33.0f, -30.0f, -27.0f, -24.0f, - -21.0f, -18.0f, -15.0f, -12.0f, -9.0f, -6.0f, -3.0f, 0.0f -}; -#endif #endif /* IVAS_RTPDUMP */ diff --git a/lib_util/ivas_rtp_pi_data.h b/lib_util/ivas_rtp_pi_data.h index 1ea89aaf39..cfa942a148 100644 --- a/lib_util/ivas_rtp_pi_data.h +++ b/lib_util/ivas_rtp_pi_data.h @@ -213,6 +213,9 @@ extern "C" { size_t size; /* sizeof(IVAS_PIDATA_ISM_ID) */ uint32_t piDataType; /* IVAS_PI_ISM_ID */ +#ifdef ISM_PI_DATA + uint16_t numObjects; /* number of objects */ +#endif uint8_t id[IVAS_PI_MAX_OBJECTS]; /* 8-bit ISM id of object */ } IVAS_PIDATA_ISM_ID; @@ -221,6 +224,9 @@ extern "C" { size_t size; /* sizeof(IVAS_PIDATA_ISM_GAIN) */ uint32_t piDataType; /* IVAS_PI_ISM_GAIN */ +#ifdef ISM_PI_DATA + uint16_t numObjects; /* number of objects */ +#endif int8_t dB[IVAS_PI_MAX_OBJECTS]; /* ISM gain in dB per object [-96, +3] */ } IVAS_PIDATA_ISM_GAIN; @@ -229,6 +235,9 @@ extern "C" { size_t size; /* sizeof(IVAS_PIDATA_ISM_ORIENTATION) */ uint32_t piDataType; /* IVAS_PI_ISM_ORIENTATION */ +#ifdef ISM_PI_DATA + uint16_t numObjects; /* number of objects */ +#endif IVAS_QUATERNION orientation[IVAS_PI_MAX_OBJECTS]; /* Orientation of audio objects in ISM(s) */ } IVAS_PIDATA_ISM_ORIENTATION; @@ -237,6 +246,9 @@ extern "C" { size_t size; /* sizeof(IVAS_PIDATA_ISM_POSITION) */ uint32_t piDataType; /* IVAS_PI_ISM_POSITION */ +#ifdef ISM_PI_DATA + uint16_t numObjects; /* number of objects */ +#endif IVAS_COORDINATE position[IVAS_PI_MAX_OBJECTS]; /* Position of audio objects in ISM(s) */ } IVAS_PIDATA_ISM_POSITION; @@ -256,6 +268,9 @@ extern "C" { size_t size; /* sizeof(IVAS_PIDATA_ISM_ATTENUATION) */ uint32_t piDataType; /* IVAS_PI_ISM_DISTANCE_ATTENUATION */ +#ifdef ISM_PI_DATA + uint16_t numObjects; /* number of objects */ +#endif IVAS_DIST_ATTEN distAtten[IVAS_PI_MAX_OBJECTS]; /* Distance attenuation of audio objects */ } IVAS_PIDATA_ISM_ATTENUATION; @@ -275,6 +290,9 @@ extern "C" { size_t size; /* sizeof(IVAS_PIDATA_ISM_DIRECTIVITY) */ uint32_t piDataType; /* IVAS_PI_ISM_DIRECTIVITY */ +#ifdef ISM_PI_DATA + uint16_t numObjects; /* number of objects */ +#endif IVAS_ISM_DIRECTIVITY directivity[IVAS_PI_MAX_OBJECTS]; /* Directivity of audio objects */ } IVAS_PIDATA_ISM_DIRECTIVITY; diff --git a/tests/rtp/test_rtp.py b/tests/rtp/test_rtp.py index b770fd0fd6..48511ef59b 100644 --- a/tests/rtp/test_rtp.py +++ b/tests/rtp/test_rtp.py @@ -254,6 +254,27 @@ def isEqualAudioFocus(ref: AUDIO_FOCUS, dut: AUDIO_FOCUS): assert abs(ref.direction['z'] - dut.direction.z) < 0.0001, "Audio Focus PI Data mismatch in direction z" assert ref.level == dut.level, "Audio Focus PI Data mismatch in level" +def isEqualISMNum(ref: ISM_NUM, dut: ISM_NUM): + assert ref.num == dut.num, "ISM NUM PI Data mismatch" + +def isEqualISMID(ref: ISM_ID, dut: ISM_ID): + for r, d in zip(ref.ids, dut.ids): + assert r == d, f"ISM ID PI Data mismatch {r} != {d}" + +def isEqualISMGain(ref: ISM_GAIN, dut: ISM_GAIN): + for r, d in zip(ref.gains, dut.gains): + assert r == d, f"ISM GAIN PI Data mismatch {r} != {d}" + +def isEqualISMDistanceAttenuation(ref: DISTANCE_ATTENUATION, dut: DISTANCE_ATTENUATION): + assert abs(ref.ref_dist - dut.ref_dist) < 0.0001, "DISTANCE ATTENUATION PI Data mismatch in ref_dist" + assert abs(ref.max_dist - dut.max_dist) < 0.0001, "DISTANCE ATTENUATION PI Data mismatch in max_dist" + assert abs(ref.roll_off - dut.roll_off) < 0.0001, "DISTANCE ATTENUATION PI Data mismatch in roll_off" + +def isEqualISMDirectivity(ref: DIRECTIVITY, dut: DIRECTIVITY): + assert ref.inner_ang == dut.inner_ang, "DIRECTIVITYPI Data mismatch in inner_ang" + assert ref.outer_ang == dut.outer_ang, "DIRECTIVITY PI Data mismatch in outer_ang" + assert abs(ref.outer_att - dut.outer_att) < 0.0001, "DIRECTIVITY PI Data mismatch in outer_att" + class CSVREADER: def __init__(self, csvFile: Path): self.rIdx = 0 @@ -480,8 +501,27 @@ def run_rtp_bitstream_tests ( elif type(generatedPIData[ts][pitype]) == AUDIO_FOCUS: isEqualAudioFocus(AUDIO_FOCUS(**decoded), data) elif type(generatedPIData[ts][pitype]) == list: - for r, d in zip(generatedPIData[ts][pitype], decodedPiData[ts][pitype]): - isEqualAD(AUDIO_DESCRIPTION(**d), r) + if pitype == "AUDIO_DESCRIPTION": + for r, d in zip(generatedPIData[ts][pitype], decodedPiData[ts][pitype]): + isEqualAD(AUDIO_DESCRIPTION(**d), r) + elif pitype == "ISM_ORIENTATION": + for r, d in zip(generatedPIData[ts][pitype], decodedPiData[ts][pitype]): + isEqualOrientation(ORIENTATION(**d), r) + elif pitype == "ISM_POSITION": + for r, d in zip(generatedPIData[ts][pitype], decodedPiData[ts][pitype]): + isEqualPosition(POSITION(**d), r) + elif pitype == "ISM_DISTANCE_ATTENUATION": + for r, d in zip(generatedPIData[ts][pitype], decodedPiData[ts][pitype]): + isEqualISMDistanceAttenuation(DISTANCE_ATTENUATION(**d), r) + elif pitype == "ISM_DIRECTIVITY": + for r, d in zip(generatedPIData[ts][pitype], decodedPiData[ts][pitype]): + isEqualISMDirectivity(DIRECTIVITY(**d), r) + elif type(generatedPIData[ts][pitype]) == ISM_NUM: + isEqualISMNum(ISM_NUM(**decoded), data) + elif type(generatedPIData[ts][pitype]) == ISM_ID: + isEqualISMID(ISM_ID(**decoded), data) + elif type(generatedPIData[ts][pitype]) == ISM_GAIN: + isEqualISMGain(ISM_GAIN(**decoded), data) else: assert False, "Unsupported PI data found" -- GitLab From 21c4e2b3c1d234e8369e6c136b86f6b7322b8bc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20Toftg=C3=A5rd?= Date: Wed, 5 Nov 2025 21:28:32 +0100 Subject: [PATCH 04/15] Apply formatting --- lib_dec/lib_dec.c | 6 +++--- lib_rend/ivas_rotation.c | 2 +- lib_util/ivas_rtp_pi_data.c | 14 +++++++------- lib_util/ivas_rtp_pi_data.h | 36 ++++++++++++++++++------------------ 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index c3b7e69a82..1fc21f76a5 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -3836,14 +3836,14 @@ void IVAS_DEC_resetExternalOrientations( *---------------------------------------------------------------------*/ void IVAS_DEC_setDiegeticInputPI( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const bool *diegeticPIValues /* i : diegetic values for the input stream */ + 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++ ) + for ( i = 0; i < ( 1 + IVAS_MAX_NUM_OBJECTS ); i++ ) { hIvasDec->st_ivas->hCombinedOrientationData->isDiegeticInputPI[i] = diegeticPIValues[i]; } diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 8b62d7a111..6c6acb2653 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -864,7 +864,7 @@ ivas_error ivas_combined_orientation_open( ( *hCombinedOrientationData )->cur_subframe_samples_rendered = 0; #ifdef RTP_S4_251135_CR26253_0016_REV1 - for ( i = 0; i < (1 + IVAS_MAX_NUM_OBJECTS); i++ ) + for ( i = 0; i < ( 1 + IVAS_MAX_NUM_OBJECTS ); i++ ) { ( *hCombinedOrientationData )->isDiegeticInputPI[i] = true; } diff --git a/lib_util/ivas_rtp_pi_data.c b/lib_util/ivas_rtp_pi_data.c index acd35d7a95..2150abff30 100644 --- a/lib_util/ivas_rtp_pi_data.c +++ b/lib_util/ivas_rtp_pi_data.c @@ -1054,14 +1054,14 @@ static ivas_error unpackISMDistanceAttenuation( const uint8_t *buffer, uint32_t lWord |= buffer[3 * n + 2]; ism_att->distAtten[n].ref_dist = ( ( ( lWord >> 18 ) & MASK_6BIT ) + 1 ) / 10.0f; - ism_att->distAtten[n].max_dist = (float) ( ( lWord >> 12 ) & MASK_6BIT ) + 1 ; + ism_att->distAtten[n].max_dist = (float) ( ( lWord >> 12 ) & MASK_6BIT ) + 1; ism_att->distAtten[n].roll = ( ( lWord >> 6 ) & MASK_6BIT ) / 10.0f; } for ( ; n < IVAS_PI_MAX_OBJECTS; n++ ) { - ism_att->distAtten[n].ref_dist = 1.0f; /* Set to default */ + ism_att->distAtten[n].ref_dist = 1.0f; /* Set to default */ ism_att->distAtten[n].max_dist = 16.0f; /* Set to default */ - ism_att->distAtten[n].roll = 1.0f; /* Set to default */ + ism_att->distAtten[n].roll = 1.0f; /* Set to default */ } return IVAS_ERR_OK; } @@ -1137,8 +1137,8 @@ static ivas_error unpackISMDirectivity( const uint8_t *buffer, uint32_t numDataB ism_directivity->directivity[n].innerConeAngle = ( ( word >> 11 ) & MASK_5BIT ) * 15; ism_directivity->directivity[n].outerConeAngle = ( ( word >> 6 ) & MASK_5BIT ) * 15; idx = ( word >> 1 ) & MASK_5BIT; - - if (idx == 0) + + if ( idx == 0 ) { ism_directivity->directivity[n].outerAttenuationdB = SHRT_MIN; /* corresponds to muting */ } @@ -1149,8 +1149,8 @@ static ivas_error unpackISMDirectivity( const uint8_t *buffer, uint32_t numDataB } for ( ; n < IVAS_PI_MAX_OBJECTS; n++ ) { - ism_directivity->directivity[n].innerConeAngle = 360; /* Set to default */ - ism_directivity->directivity[n].outerConeAngle = 360; /* Set to default */ + ism_directivity->directivity[n].innerConeAngle = 360; /* Set to default */ + ism_directivity->directivity[n].outerConeAngle = 360; /* Set to default */ ism_directivity->directivity[n].outerAttenuationdB = 0; /* Set to default */ } return IVAS_ERR_OK; diff --git a/lib_util/ivas_rtp_pi_data.h b/lib_util/ivas_rtp_pi_data.h index cfa942a148..3270de8197 100644 --- a/lib_util/ivas_rtp_pi_data.h +++ b/lib_util/ivas_rtp_pi_data.h @@ -211,8 +211,8 @@ extern "C" /* ISM ID */ typedef struct { - size_t size; /* sizeof(IVAS_PIDATA_ISM_ID) */ - uint32_t piDataType; /* IVAS_PI_ISM_ID */ + size_t size; /* sizeof(IVAS_PIDATA_ISM_ID) */ + uint32_t piDataType; /* IVAS_PI_ISM_ID */ #ifdef ISM_PI_DATA uint16_t numObjects; /* number of objects */ #endif @@ -222,8 +222,8 @@ extern "C" /* ISM gain */ typedef struct { - size_t size; /* sizeof(IVAS_PIDATA_ISM_GAIN) */ - uint32_t piDataType; /* IVAS_PI_ISM_GAIN */ + size_t size; /* sizeof(IVAS_PIDATA_ISM_GAIN) */ + uint32_t piDataType; /* IVAS_PI_ISM_GAIN */ #ifdef ISM_PI_DATA uint16_t numObjects; /* number of objects */ #endif @@ -233,8 +233,8 @@ extern "C" /* ISM orientation */ typedef struct { - size_t size; /* sizeof(IVAS_PIDATA_ISM_ORIENTATION) */ - uint32_t piDataType; /* IVAS_PI_ISM_ORIENTATION */ + size_t size; /* sizeof(IVAS_PIDATA_ISM_ORIENTATION) */ + uint32_t piDataType; /* IVAS_PI_ISM_ORIENTATION */ #ifdef ISM_PI_DATA uint16_t numObjects; /* number of objects */ #endif @@ -244,8 +244,8 @@ extern "C" /* ISM position */ typedef struct { - size_t size; /* sizeof(IVAS_PIDATA_ISM_POSITION) */ - uint32_t piDataType; /* IVAS_PI_ISM_POSITION */ + size_t size; /* sizeof(IVAS_PIDATA_ISM_POSITION) */ + uint32_t piDataType; /* IVAS_PI_ISM_POSITION */ #ifdef ISM_PI_DATA uint16_t numObjects; /* number of objects */ #endif @@ -266,8 +266,8 @@ extern "C" typedef struct { - size_t size; /* sizeof(IVAS_PIDATA_ISM_ATTENUATION) */ - uint32_t piDataType; /* IVAS_PI_ISM_DISTANCE_ATTENUATION */ + size_t size; /* sizeof(IVAS_PIDATA_ISM_ATTENUATION) */ + uint32_t piDataType; /* IVAS_PI_ISM_DISTANCE_ATTENUATION */ #ifdef ISM_PI_DATA uint16_t numObjects; /* number of objects */ #endif @@ -288,8 +288,8 @@ extern "C" typedef struct { - size_t size; /* sizeof(IVAS_PIDATA_ISM_DIRECTIVITY) */ - uint32_t piDataType; /* IVAS_PI_ISM_DIRECTIVITY */ + size_t size; /* sizeof(IVAS_PIDATA_ISM_DIRECTIVITY) */ + uint32_t piDataType; /* IVAS_PI_ISM_DIRECTIVITY */ #ifdef ISM_PI_DATA uint16_t numObjects; /* number of objects */ #endif @@ -336,12 +336,12 @@ extern "C" 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 */ + 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 */ -- GitLab From c9efdec2a6aaeca6d98f0d2ff89136a79e6a12b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20Toftg=C3=A5rd?= Date: Wed, 5 Nov 2025 23:06:40 +0100 Subject: [PATCH 05/15] missing fixes --- lib_com/options.h | 1 + lib_util/ivas_rtp_file.c | 106 ++++++++++++++++++++++++++++++++++++ lib_util/ivas_rtp_pi_data.c | 26 ++++----- lib_util/ivas_rtp_pi_data.h | 12 ++-- tests/rtp/ivasrtp.py | 2 +- 5 files changed, 127 insertions(+), 20 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 1f4d9a7aa7..6d7fec9389 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -163,6 +163,7 @@ #define IVAS_RTPDUMP /* RTPDUMP writing and reading for IVAS payloads */ #define FIXED_RTP_SEQUENCE_NUM /* Remove random sequence number initialization */ #define ISM_PI_DATA /* Add reading and packing/unpacking of ISM PI data */ +#define PI_DATA_FIX /* Fix for PI Data JSON file */ /* ################### Start BE switches ################################# */ /* only BE switches wrt selection floating point code */ diff --git a/lib_util/ivas_rtp_file.c b/lib_util/ivas_rtp_file.c index f7d6d5d867..d3ba0a63b1 100644 --- a/lib_util/ivas_rtp_file.c +++ b/lib_util/ivas_rtp_file.c @@ -152,13 +152,20 @@ void IVAS_RTP_LogPiData( uint32_t nPiDataPresent /* i : Number of valid elements in the piData array */ ) { +#ifdef ISM_PI_DATA + uint16_t n; +#endif uint32_t timestamp = ~0u; if ( f_piDataOut == NULL || piData == NULL || nPiDataPresent == 0 ) { return; } +#ifdef PI_DATA_FIX + if ( ftell( f_piDataOut ) > 3 ) +#else if ( ftell( f_piDataOut ) > 2 ) +#endif { fprintf( f_piDataOut, ",\n" ); } @@ -324,6 +331,104 @@ void IVAS_RTP_LogPiData( fprintf( f_piDataOut, "{}" ); } break; +#ifdef ISM_PI_DATA + case IVAS_PI_ISM_ORIENTATION: + { + fprintf( f_piDataOut, "[\n" ); + for ( n = 0; n < cur->data.ismOrientation.numObjects; n++ ) + { + if ( n != 0 ) + { + fprintf( f_piDataOut, ",\n" ); + } + fprintf( f_piDataOut, "\t\t\t{\n\t\t\t\t\"w\": %f,\n\t\t\t\t\"x\": %f,\n\t\t\t\t\"y\": %f,\n\t\t\t\t\"z\": %f \n\t\t\t}", + cur->data.ismOrientation.orientation[n].w, cur->data.ismOrientation.orientation[n].x, cur->data.ismOrientation.orientation[n].y, cur->data.ismOrientation.orientation[n].z ); + } + fprintf( f_piDataOut, "\n\t\t]" ); + } + break; + case IVAS_PI_ISM_NUM: + { + fprintf( f_piDataOut, "{\n" ); + fprintf( f_piDataOut, "\t\t\t\"num\": %d", cur->data.ismNum.numObjects ); + fprintf( f_piDataOut, "\n\t\t}" ); + } + break; + case IVAS_PI_ISM_ID: + { + fprintf( f_piDataOut, "{\n" ); + fprintf( f_piDataOut, "\t\t\t\"ids\": [\n" ); + for ( n = 0; n < cur->data.ismId.numObjects; n++ ) + { + if ( n != 0 ) + { + fprintf( f_piDataOut, ",\n" ); + } + fprintf( f_piDataOut, "\t\t\t\t%d", cur->data.ismId.id[n] ); + } + fprintf( f_piDataOut, "\n\t\t\t]" ); + fprintf( f_piDataOut, "\n\t\t}" ); + } + break; + case IVAS_PI_ISM_GAIN: + { + fprintf( f_piDataOut, "{\n" ); + fprintf( f_piDataOut, "\t\t\t\"gains\": [\n" ); + for ( n = 0; n < cur->data.ismGain.numObjects; n++ ) + { + if ( n != 0 ) + { + fprintf( f_piDataOut, ",\n" ); + } + fprintf( f_piDataOut, "\t\t\t\t%d", cur->data.ismGain.dB[n] ); + } + fprintf( f_piDataOut, "\n\t\t\t]" ); + fprintf( f_piDataOut, "\n\t\t}" ); + } + break; + case IVAS_PI_ISM_POSITION: + { + fprintf( f_piDataOut, "[\n" ); + for ( n = 0; n < cur->data.ismPosition.numObjects; n++ ) + { + if ( n != 0 ) + { + fprintf( f_piDataOut, ",\n" ); + } + fprintf( f_piDataOut, "\t\t\t{\n\t\t\t\t\"x\": %f,\n\t\t\t\t\"y\": %f,\n\t\t\t\t\"z\": %f \n\t\t\t}", cur->data.ismPosition.position[n].x, cur->data.ismPosition.position[n].y, cur->data.ismPosition.position[n].z ); + } + fprintf( f_piDataOut, "\n\t\t]" ); + } + break; + case IVAS_PI_ISM_DISTANCE_ATTENUATION: + { + fprintf( f_piDataOut, "[\n" ); + for ( n = 0; n < cur->data.ismAttenuation.numObjects; n++ ) + { + if ( n != 0 ) + { + fprintf( f_piDataOut, ",\n" ); + } + fprintf( f_piDataOut, "\t\t\t{\n\t\t\t\t\"ref_dist\": %f,\n\t\t\t\t\"max_dist\": %f,\n\t\t\t\t\"roll_off\": %f \n\t\t\t}", cur->data.ismAttenuation.distAtten[n].ref_dist, cur->data.ismAttenuation.distAtten[n].max_dist, cur->data.ismAttenuation.distAtten[n].roll ); + } + fprintf( f_piDataOut, "\n\t\t]" ); + } + break; + case IVAS_PI_ISM_DIRECTIVITY: + { + fprintf( f_piDataOut, "[\n" ); + for ( n = 0; n < cur->data.ismDirectivity.numObjects; n++ ) + { + if ( n != 0 ) + { + fprintf( f_piDataOut, ",\n" ); + } + fprintf( f_piDataOut, "\t\t\t{\n\t\t\t\t\"inner_ang\": %d,\n\t\t\t\t\"outer_ang\": %d,\n\t\t\t\t\"outer_att\": %f \n\t\t\t}", cur->data.ismDirectivity.directivity[n].innerConeAngle, cur->data.ismDirectivity.directivity[n].outerConeAngle, cur->data.ismDirectivity.directivity[n].outerAttenuationdB ); + } + fprintf( f_piDataOut, "\n\t\t]" ); + } + break; +#else case IVAS_PI_ISM_NUM: case IVAS_PI_ISM_ID: case IVAS_PI_ISM_GAIN: @@ -331,6 +436,7 @@ void IVAS_RTP_LogPiData( case IVAS_PI_ISM_POSITION: case IVAS_PI_ISM_DISTANCE_ATTENUATION: case IVAS_PI_ISM_DIRECTIVITY: +#endif case IVAS_PI_PI_LATENCY: case IVAS_PI_R_ISM_ID: case IVAS_PI_R_ISM_GAIN: diff --git a/lib_util/ivas_rtp_pi_data.c b/lib_util/ivas_rtp_pi_data.c index 6cc01a2aeb..a78cd94143 100644 --- a/lib_util/ivas_rtp_pi_data.c +++ b/lib_util/ivas_rtp_pi_data.c @@ -175,7 +175,7 @@ static ivas_error packISMOrientation( const IVAS_PIDATA_GENERIC *piData, uint8_t 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 * IVAS_PI_MAX_OBJECTS + 2 ) + if ( maxDataBytes < 8 * IVAS_MAX_NUM_OBJECTS + 2 ) { return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack Orientation PI data" ); } @@ -235,7 +235,7 @@ static ivas_error unpackISMOrientation( const uint8_t *buffer, uint32_t numDataB ism_orientation->orientation[n].y = FLOAT_FROM_Q15( readInt16( &buffer[8 * n + 4] ) ); ism_orientation->orientation[n].z = FLOAT_FROM_Q15( readInt16( &buffer[8 * n + 6] ) ); } - for ( ; n < IVAS_PI_MAX_OBJECTS; n++ ) + for ( ; n < IVAS_MAX_NUM_OBJECTS; n++ ) { ism_orientation->orientation[n].w = 0.0f; ism_orientation->orientation[n].x = 0.0f; @@ -589,7 +589,7 @@ static ivas_error packISMPosition( const IVAS_PIDATA_GENERIC *piData, uint8_t *b } /* Position data is 6 bytes, header is 2 bytes */ - if ( maxDataBytes < 6 * IVAS_PI_MAX_OBJECTS + 2 ) + if ( maxDataBytes < 6 * IVAS_MAX_NUM_OBJECTS + 2 ) { return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack ISM POSITION PI data" ); } @@ -851,7 +851,7 @@ static ivas_error packISMID( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, } /* ISM_ID data is 1 byte per object */ - if ( maxDataBytes < 1 * IVAS_PI_MAX_OBJECTS ) + if ( maxDataBytes < 1 * IVAS_MAX_NUM_OBJECTS ) { return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack ISM_NUM PI data" ); } @@ -873,7 +873,7 @@ static ivas_error unpackISMID( const uint8_t *buffer, uint32_t numDataBytes, IVA IVAS_PIDATA_ISM_ID *ism_id = (IVAS_PIDATA_ISM_ID *) piData; /* ISM_ID data is 1 byte per object */ - if ( numDataBytes > IVAS_PI_MAX_OBJECTS ) + if ( numDataBytes > IVAS_MAX_NUM_OBJECTS ) { return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "Incorrect size to unpack ISM_ID PI data" ); } @@ -887,7 +887,7 @@ static ivas_error unpackISMID( const uint8_t *buffer, uint32_t numDataBytes, IVA { ism_id->id[n] = buffer[n]; } - for ( ; n < IVAS_PI_MAX_OBJECTS; n++ ) + for ( ; n < IVAS_MAX_NUM_OBJECTS; n++ ) { ism_id->id[n] = 0; /* Initializing to 0, although there might be another object with this ID */ } @@ -914,7 +914,7 @@ static ivas_error packISMGain( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffe } /* ISM_GAIN data is 1 byte per object */ - if ( maxDataBytes < 1 * IVAS_PI_MAX_OBJECTS ) + if ( maxDataBytes < 1 * IVAS_MAX_NUM_OBJECTS ) { return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack ISM_GAIN PI data" ); } @@ -943,7 +943,7 @@ static ivas_error unpackISMGain( const uint8_t *buffer, uint32_t numDataBytes, I IVAS_PIDATA_ISM_GAIN *ism_gain = (IVAS_PIDATA_ISM_GAIN *) piData; /* ISM_GAIN data is 1 byte per object */ - if ( numDataBytes > IVAS_PI_MAX_OBJECTS ) + if ( numDataBytes > IVAS_MAX_NUM_OBJECTS ) { return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "Incorrect size to unpack ISM_GAIN PI data" ); } @@ -976,7 +976,7 @@ static ivas_error unpackISMGain( const uint8_t *buffer, uint32_t numDataBytes, I return IVAS_ERROR( IVAS_ERR_RTP_UNPACK_PI_DATA, "Incorrect index for ISM_GAIN PI data" ); } } - for ( ; n < IVAS_PI_MAX_OBJECTS; n++ ) + for ( ; n < IVAS_MAX_NUM_OBJECTS; n++ ) { ism_gain->dB[n] = 0; /* Set to default */ } @@ -1002,7 +1002,7 @@ static ivas_error packISMDistanceAttenuation( const IVAS_PIDATA_GENERIC *piData, } /* ISM_DISTANCE_ATTENUATION data is 3 bytes per object */ - if ( maxDataBytes > 3 * IVAS_PI_MAX_OBJECTS ) + if ( maxDataBytes > 3 * IVAS_MAX_NUM_OBJECTS ) { return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack ISM_DISTANCE_ATTENUATION PI data" ); } @@ -1054,7 +1054,7 @@ static ivas_error unpackISMDistanceAttenuation( const uint8_t *buffer, uint32_t ism_att->distAtten[n].max_dist = (float) ( ( lWord >> 12 ) & MASK_6BIT ) + 1; ism_att->distAtten[n].roll = ( ( lWord >> 6 ) & MASK_6BIT ) / 10.0f; } - for ( ; n < IVAS_PI_MAX_OBJECTS; n++ ) + for ( ; n < IVAS_MAX_NUM_OBJECTS; n++ ) { ism_att->distAtten[n].ref_dist = 1.0f; /* Set to default */ ism_att->distAtten[n].max_dist = 16.0f; /* Set to default */ @@ -1081,7 +1081,7 @@ static ivas_error packISMDirectivity( const IVAS_PIDATA_GENERIC *piData, uint8_t } /* ISM_DIRECTIVITY data is 2 bytes per object, header is 2 bytes */ - if ( maxDataBytes > 2 * IVAS_PI_MAX_OBJECTS ) + if ( maxDataBytes > 2 * IVAS_MAX_NUM_OBJECTS ) { return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack ISM_DIRECTIVITY PI data" ); } @@ -1144,7 +1144,7 @@ static ivas_error unpackISMDirectivity( const uint8_t *buffer, uint32_t numDataB ism_directivity->directivity[n].outerAttenuationdB = -3.0f * ( 31 - ( ( word >> 1 ) & MASK_5BIT ) ); } } - for ( ; n < IVAS_PI_MAX_OBJECTS; n++ ) + for ( ; n < IVAS_MAX_NUM_OBJECTS; n++ ) { ism_directivity->directivity[n].innerConeAngle = 360; /* Set to default */ ism_directivity->directivity[n].outerConeAngle = 360; /* Set to default */ diff --git a/lib_util/ivas_rtp_pi_data.h b/lib_util/ivas_rtp_pi_data.h index 1dc58f33ed..49dcb9caea 100644 --- a/lib_util/ivas_rtp_pi_data.h +++ b/lib_util/ivas_rtp_pi_data.h @@ -210,7 +210,7 @@ typedef struct #ifdef ISM_PI_DATA uint16_t numObjects; /* number of objects */ #endif - uint8_t id[IVAS_PI_MAX_OBJECTS]; /* 8-bit ISM id of object */ + uint8_t id[IVAS_MAX_NUM_OBJECTS]; /* 8-bit ISM id of object */ } IVAS_PIDATA_ISM_ID; /* ISM gain */ @@ -221,7 +221,7 @@ typedef struct #ifdef ISM_PI_DATA uint16_t numObjects; /* number of objects */ #endif - int8_t dB[IVAS_PI_MAX_OBJECTS]; /* ISM gain in dB per object [-96, +3] */ + int8_t dB[IVAS_MAX_NUM_OBJECTS]; /* ISM gain in dB per object [-96, +3] */ } IVAS_PIDATA_ISM_GAIN; /* ISM orientation */ @@ -232,7 +232,7 @@ typedef struct #ifdef ISM_PI_DATA uint16_t numObjects; /* number of objects */ #endif - IVAS_QUATERNION orientation[IVAS_PI_MAX_OBJECTS]; /* Orientation of audio objects in ISM(s) */ + IVAS_QUATERNION orientation[IVAS_MAX_NUM_OBJECTS]; /* Orientation of audio objects in ISM(s) */ } IVAS_PIDATA_ISM_ORIENTATION; /* ISM position */ @@ -243,7 +243,7 @@ typedef struct #ifdef ISM_PI_DATA uint16_t numObjects; /* number of objects */ #endif - IVAS_COORDINATE position[IVAS_PI_MAX_OBJECTS]; /* Position of audio objects in ISM(s) */ + 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 @@ -265,7 +265,7 @@ typedef struct #ifdef ISM_PI_DATA uint16_t numObjects; /* number of objects */ #endif - IVAS_DIST_ATTEN distAtten[IVAS_PI_MAX_OBJECTS]; /* Distance attenuation of audio objects */ + IVAS_DIST_ATTEN distAtten[IVAS_MAX_NUM_OBJECTS]; /* Distance attenuation of audio objects */ } IVAS_PIDATA_ISM_ATTENUATION; /* ISM Directivity comprising of following per ISM :- @@ -287,7 +287,7 @@ typedef struct #ifdef ISM_PI_DATA uint16_t numObjects; /* number of objects */ #endif - IVAS_ISM_DIRECTIVITY directivity[IVAS_PI_MAX_OBJECTS]; /* Directivity of audio objects */ + 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 diff --git a/tests/rtp/ivasrtp.py b/tests/rtp/ivasrtp.py index bc2156af1a..20d840647a 100644 --- a/tests/rtp/ivasrtp.py +++ b/tests/rtp/ivasrtp.py @@ -443,7 +443,7 @@ class PIDATA: data: any = None -MAX_PACKED_PI_SIZE = 32 +MAX_PACKED_PI_SIZE = 48 ivasBitrates = [ 13200, 16400, -- GitLab From d782f717ec55c4a4df84419e710ca5bc2d12a375 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20Toftg=C3=A5rd?= Date: Wed, 5 Nov 2025 23:25:57 +0100 Subject: [PATCH 06/15] formatting --- lib_util/ivas_rtp_pi_data.h | 116 ++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/lib_util/ivas_rtp_pi_data.h b/lib_util/ivas_rtp_pi_data.h index 49dcb9caea..773fdf6a91 100644 --- a/lib_util/ivas_rtp_pi_data.h +++ b/lib_util/ivas_rtp_pi_data.h @@ -202,49 +202,49 @@ typedef struct 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 */ +/* ISM ID */ +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_ISM_ID) */ + uint32_t piDataType; /* IVAS_PI_ISM_ID */ #ifdef ISM_PI_DATA - uint16_t numObjects; /* number of objects */ + uint16_t numObjects; /* number of objects */ #endif - 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 */ + 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 */ #ifdef ISM_PI_DATA - uint16_t numObjects; /* number of objects */ + uint16_t numObjects; /* number of objects */ #endif - 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 */ + 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 */ #ifdef ISM_PI_DATA - uint16_t numObjects; /* number of objects */ + uint16_t numObjects; /* number of objects */ #endif - 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_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 */ #ifdef ISM_PI_DATA - uint16_t numObjects; /* number of objects */ + uint16_t numObjects; /* number of objects */ #endif - IVAS_COORDINATE position[IVAS_MAX_NUM_OBJECTS]; /* Position of audio objects in ISM(s) */ - } IVAS_PIDATA_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 @@ -258,15 +258,15 @@ typedef struct 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 */ +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_ISM_ATTENUATION) */ + uint32_t piDataType; /* IVAS_PI_ISM_DISTANCE_ATTENUATION */ #ifdef ISM_PI_DATA - uint16_t numObjects; /* number of objects */ + uint16_t numObjects; /* number of objects */ #endif - IVAS_DIST_ATTEN distAtten[IVAS_MAX_NUM_OBJECTS]; /* Distance attenuation of audio objects */ - } IVAS_PIDATA_ISM_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 @@ -280,15 +280,15 @@ typedef struct 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 */ +typedef struct +{ + size_t size; /* sizeof(IVAS_PIDATA_ISM_DIRECTIVITY) */ + uint32_t piDataType; /* IVAS_PI_ISM_DIRECTIVITY */ #ifdef ISM_PI_DATA - uint16_t numObjects; /* number of objects */ + uint16_t numObjects; /* number of objects */ #endif - IVAS_ISM_DIRECTIVITY directivity[IVAS_MAX_NUM_OBJECTS]; /* Directivity of audio objects */ - } IVAS_PIDATA_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 * @@ -328,15 +328,15 @@ typedef enum 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; +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 -- GitLab From 86f9ea10bc998ea7633fd638130994ffcbb6ba97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20Toftg=C3=A5rd?= Date: Wed, 5 Nov 2025 23:50:12 +0100 Subject: [PATCH 07/15] Fixing missing min() for linux builds and removed missing constant, remove unused function. --- lib_util/ivas_rtp_pi_data.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/lib_util/ivas_rtp_pi_data.c b/lib_util/ivas_rtp_pi_data.c index a78cd94143..ef13208d4c 100644 --- a/lib_util/ivas_rtp_pi_data.c +++ b/lib_util/ivas_rtp_pi_data.c @@ -34,6 +34,15 @@ #include "ivas_rtp_internal.h" #ifdef ISM_PI_DATA #include + +#ifndef min +#define min( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) ) +#endif + +#ifndef max +#define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) +#endif + #endif #ifdef IVAS_RTPDUMP @@ -267,25 +276,6 @@ static uint32_t getIndexTable( const float *table, uint32_t tableLength, float v #define GET_IDX( table, nBits, value ) getIndexTable( table, ( 1u << ( nBits ) ), ( value ) ) -static uint32_t getIndexTable_s( const int16_t *table, uint32_t tableLength, int16_t 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; -} - - static ivas_error packAcousticEnvironment( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ) { uint32_t nBytes = 0; @@ -1137,7 +1127,7 @@ static ivas_error unpackISMDirectivity( const uint8_t *buffer, uint32_t numDataB if ( idx == 0 ) { - ism_directivity->directivity[n].outerAttenuationdB = SHRT_MIN; /* corresponds to muting */ + ism_directivity->directivity[n].outerAttenuationdB = -32768.0f; /* corresponds to muting */ } else { -- GitLab From 16f978e81898f794e6642c18be35a5b36e6a90fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20Toftg=C3=A5rd?= Date: Thu, 6 Nov 2025 00:11:37 +0100 Subject: [PATCH 08/15] Add 2 bytes for header in maxDataBytes comparison --- lib_util/ivas_rtp_pi_data.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib_util/ivas_rtp_pi_data.c b/lib_util/ivas_rtp_pi_data.c index ef13208d4c..332542d14d 100644 --- a/lib_util/ivas_rtp_pi_data.c +++ b/lib_util/ivas_rtp_pi_data.c @@ -791,8 +791,8 @@ static ivas_error packISMNum( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect PI ID in ISM_NUM PI data" ); } - /* ISM_NUM data is 1 bytes */ - if ( maxDataBytes < 1 ) + /* ISM_NUM 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 ISM_NUM PI data" ); } @@ -840,8 +840,8 @@ static ivas_error packISMID( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect PI ID in ISM_ID PI data" ); } - /* ISM_ID data is 1 byte per object */ - if ( maxDataBytes < 1 * IVAS_MAX_NUM_OBJECTS ) + /* ISM_ID data is 1 byte per object, header is 2 bytes */ + if ( maxDataBytes < 1 * IVAS_MAX_NUM_OBJECTS + 2 ) { return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack ISM_NUM PI data" ); } @@ -903,8 +903,8 @@ static ivas_error packISMGain( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffe return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect PI ID in ISM_GAIN PI data" ); } - /* ISM_GAIN data is 1 byte per object */ - if ( maxDataBytes < 1 * IVAS_MAX_NUM_OBJECTS ) + /* ISM_GAIN data is 1 byte per object, header is 2 bytes */ + if ( maxDataBytes < 1 * IVAS_MAX_NUM_OBJECTS + 2 ) { return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack ISM_GAIN PI data" ); } @@ -991,8 +991,8 @@ static ivas_error packISMDistanceAttenuation( const IVAS_PIDATA_GENERIC *piData, return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Incorrect PI ID in ISM_DISTANCE_ATTENUATION PI data" ); } - /* ISM_DISTANCE_ATTENUATION data is 3 bytes per object */ - if ( maxDataBytes > 3 * IVAS_MAX_NUM_OBJECTS ) + /* ISM_DISTANCE_ATTENUATION data is 3 bytes per object, header is 2 bytes */ + if ( maxDataBytes > 3 * IVAS_MAX_NUM_OBJECTS + 2 ) { return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack ISM_DISTANCE_ATTENUATION PI data" ); } @@ -1071,7 +1071,7 @@ static ivas_error packISMDirectivity( const IVAS_PIDATA_GENERIC *piData, uint8_t } /* ISM_DIRECTIVITY data is 2 bytes per object, header is 2 bytes */ - if ( maxDataBytes > 2 * IVAS_MAX_NUM_OBJECTS ) + if ( maxDataBytes > 2 * IVAS_MAX_NUM_OBJECTS + 2 ) { return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack ISM_DIRECTIVITY PI data" ); } -- GitLab From 6377f1b3cce593fb2750d7de6a75415e55eb47a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20Toftg=C3=A5rd?= Date: Thu, 6 Nov 2025 13:45:57 +0100 Subject: [PATCH 09/15] Add pack and unpack for DYNAMIC_AUDIO_SUPPRESSION_INDICATION back. --- tests/rtp/ivasrtp.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/rtp/ivasrtp.py b/tests/rtp/ivasrtp.py index 20d840647a..5db48c6c49 100644 --- a/tests/rtp/ivasrtp.py +++ b/tests/rtp/ivasrtp.py @@ -1094,7 +1094,7 @@ PIDataUnpacker = [ unpackISMDistanceAttenuation, # ISM_DISTANCE_ATTENUATION unpackISMDirectivity, # ISM_DIRECTIVITY unpackDiegetic, # DIEGETIC_TYPE - unpackUnsupported, # RESERVED13 + unpackDAS, # DYNAMIC_AUDIO_SUPPRESSION_INDICATION unpackAudioFocus, # AUDIO_FOCUS_INDICATION unpackUnsupported, # RESERVED15 unpackOrientation, # PLAYBACK_DEVICE_ORIENTATION @@ -1129,7 +1129,7 @@ PIDataPacker = [ packISMDistanceAttenuation, # ISM_DISTANCE_ATTENUATION packISMDirectivity, # ISM_DIRECTIVITY packDiegetic, # DIEGETIC_TYPE - packUnsupported, # RESERVED13 + packDAS, # DYNAMIC_AUDIO_SUPPRESSION_INDICATION packAudioFocus, # AUDIO_FOCUS_INDICATION packUnsupported, # RESERVED15 packOrientation, # PLAYBACK_DEVICE_ORIENTATION -- GitLab From fa149d0c74f729dcf1bb13f479c2347f82097a7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20Toftg=C3=A5rd?= Date: Thu, 6 Nov 2025 13:54:17 +0100 Subject: [PATCH 10/15] Unify formatting --- tests/rtp/ivasrtp.py | 48 ++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/rtp/ivasrtp.py b/tests/rtp/ivasrtp.py index 5db48c6c49..301da07760 100644 --- a/tests/rtp/ivasrtp.py +++ b/tests/rtp/ivasrtp.py @@ -1081,19 +1081,19 @@ def packISMDirectivity(bitstrm: BitStream, data: any): bitstrm.append(f'uint:1=0') PIDataUnpacker = [ - unpackOrientation, # SCENE_ORIENTATION, - unpackOrientation, # DEVICE_ORIENTATION_COMPENSATED, - unpackOrientation, # DEVICE_ORIENTATION_UNCOMPENSATED - unpackAcousticEnv, # ACOUSTIC_ENVIRONMENT - unpackAudioDescription, # AUDIO_DESCRIPTION - unpackISMNum, # ISM_NUM - unpackISMID, # ISM_ID - unpackISMGain, # ISM_GAIN - unpackOrientations,# ISM_ORIENTATION - unpackPositions, # ISM_POSITION + unpackOrientation, # SCENE_ORIENTATION, + unpackOrientation, # DEVICE_ORIENTATION_COMPENSATED, + unpackOrientation, # DEVICE_ORIENTATION_UNCOMPENSATED + unpackAcousticEnv, # ACOUSTIC_ENVIRONMENT + unpackAudioDescription, # AUDIO_DESCRIPTION + unpackISMNum, # ISM_NUM + unpackISMID, # ISM_ID + unpackISMGain, # ISM_GAIN + unpackOrientations, # ISM_ORIENTATION + unpackPositions, # ISM_POSITION unpackISMDistanceAttenuation, # ISM_DISTANCE_ATTENUATION unpackISMDirectivity, # ISM_DIRECTIVITY - unpackDiegetic, # DIEGETIC_TYPE + unpackDiegetic, # DIEGETIC_TYPE unpackDAS, # DYNAMIC_AUDIO_SUPPRESSION_INDICATION unpackAudioFocus, # AUDIO_FOCUS_INDICATION unpackUnsupported, # RESERVED15 @@ -1116,19 +1116,19 @@ PIDataUnpacker = [ ] PIDataPacker = [ - packOrientation, # SCENE_ORIENTATION, - packOrientation, # DEVICE_ORIENTATION_COMPENSATED, - packOrientation, # DEVICE_ORIENTATION_UNCOMPENSATED - packAcousticEnv, # ACOUSTIC_ENVIRONMENT - packAudioDescription, # AUDIO_DESCRIPTION - packISMNum, # ISM_NUM - packISMID, # ISM_ID - packISMGain, # ISM_GAIN - packOrientations,# ISM_ORIENTATION - packPositions, # ISM_POSITION - packISMDistanceAttenuation, # ISM_DISTANCE_ATTENUATION - packISMDirectivity, # ISM_DIRECTIVITY - packDiegetic, # DIEGETIC_TYPE + packOrientation, # SCENE_ORIENTATION, + packOrientation, # DEVICE_ORIENTATION_COMPENSATED, + packOrientation, # DEVICE_ORIENTATION_UNCOMPENSATED + packAcousticEnv, # ACOUSTIC_ENVIRONMENT + packAudioDescription, # AUDIO_DESCRIPTION + packISMNum, # ISM_NUM + packISMID, # ISM_ID + packISMGain, # ISM_GAIN + packOrientations, # ISM_ORIENTATION + packPositions, # ISM_POSITION + packISMDistanceAttenuation, # ISM_DISTANCE_ATTENUATION + packISMDirectivity, # ISM_DIRECTIVITY + packDiegetic, # DIEGETIC_TYPE packDAS, # DYNAMIC_AUDIO_SUPPRESSION_INDICATION packAudioFocus, # AUDIO_FOCUS_INDICATION packUnsupported, # RESERVED15 -- GitLab From a84b4cf25e4df7381681d5e027f9654abaaf2ff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20Toftg=C3=A5rd?= Date: Thu, 6 Nov 2025 14:08:03 +0100 Subject: [PATCH 11/15] Correct PI size writing for ISM packing. --- lib_util/ivas_rtp_pi_data.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib_util/ivas_rtp_pi_data.c b/lib_util/ivas_rtp_pi_data.c index 332542d14d..ad8a507355 100644 --- a/lib_util/ivas_rtp_pi_data.c +++ b/lib_util/ivas_rtp_pi_data.c @@ -564,7 +564,7 @@ static ivas_error unpackListenerPosition( const uint8_t *buffer, uint32_t numDat static ivas_error packISMPosition( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ) { uint32_t nBytes = 0, n; - const IVAS_PIDATA_ISM_POSITION *listener = (const IVAS_PIDATA_ISM_POSITION *) piData; + const IVAS_PIDATA_ISM_POSITION *ism_position = (const IVAS_PIDATA_ISM_POSITION *) piData; *nBytesWritten = 0; @@ -584,13 +584,13 @@ static ivas_error packISMPosition( const IVAS_PIDATA_GENERIC *piData, uint8_t *b return IVAS_ERROR( IVAS_ERR_RTP_INSUFFICIENT_OUTPUT_SIZE, "Insufficient space to pack ISM POSITION PI data" ); } - buffer[nBytes++] = ( listener->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ - buffer[nBytes++] = (uint8_t) piData->size; + buffer[nBytes++] = ( ism_position->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ + buffer[nBytes++] = (uint8_t) ism_position->numObjects * 6; for ( n = 0; n < piData->size / 6; n++ ) { - nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( listener->position[n].x / MAX_PI_POSITION_METERS ) ); - nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( listener->position[n].y / MAX_PI_POSITION_METERS ) ); - nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( listener->position[n].z / MAX_PI_POSITION_METERS ) ); + nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( ism_position->position[n].x / MAX_PI_POSITION_METERS ) ); + nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( ism_position->position[n].y / MAX_PI_POSITION_METERS ) ); + nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( ism_position->position[n].z / MAX_PI_POSITION_METERS ) ); } *nBytesWritten = nBytes; return IVAS_ERR_OK; @@ -847,7 +847,7 @@ static ivas_error packISMID( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, } buffer[nBytes++] = ( ism_id->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ - buffer[nBytes++] = (uint8_t) piData->size; + buffer[nBytes++] = (uint8_t) ism_id->numObjects; /* Pack ID for each object */ for ( n = 0; n < ism_id->numObjects; n++ ) { @@ -910,7 +910,7 @@ static ivas_error packISMGain( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffe } buffer[nBytes++] = ( ism_gain->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ - buffer[nBytes++] = (uint8_t) piData->size; + buffer[nBytes++] = (uint8_t) ism_gain->numObjects; /* Pack ID for each object */ for ( n = 0; n < ism_gain->numObjects; n++ ) { @@ -998,7 +998,7 @@ static ivas_error packISMDistanceAttenuation( const IVAS_PIDATA_GENERIC *piData, } buffer[nBytes++] = ( ism_att->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ - buffer[nBytes++] = (uint8_t) piData->size; + buffer[nBytes++] = (uint8_t) ism_att->numObjects * 3; /* Pack ID for each object */ for ( n = 0; n < ism_att->numObjects; n++ ) { @@ -1077,7 +1077,7 @@ static ivas_error packISMDirectivity( const IVAS_PIDATA_GENERIC *piData, uint8_t } buffer[nBytes++] = ( ism_directivity->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ - buffer[nBytes++] = (uint8_t) piData->size; + buffer[nBytes++] = (uint8_t) ism_directivity->numObjects * 2; /* Pack directivity for each object */ for ( n = 0; n < ism_directivity->numObjects; n++ ) { -- GitLab From 59d12f7a46994c0834bdad19c7836d2205ccdb7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20Toftg=C3=A5rd?= Date: Fri, 7 Nov 2025 00:23:22 +0100 Subject: [PATCH 12/15] Remove unused declarations --- lib_util/ivas_rtp_internal.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/lib_util/ivas_rtp_internal.h b/lib_util/ivas_rtp_internal.h index 08d01a4ebc..dc3dd9c129 100644 --- a/lib_util/ivas_rtp_internal.h +++ b/lib_util/ivas_rtp_internal.h @@ -72,15 +72,6 @@ extern const float mapRT60[1u << NBITS_RT60]; extern const float mapRoomDims[1u << NBITS_DIM]; extern const float mapAbsorbtion[1u << NBITS_ABS]; -#ifdef ISM_PI_DATA -extern const int16_t ismGains[98]; -extern const float refDistances[64]; -extern const float maxDistances[65]; -extern const float rollOffFactors[41]; -extern const int16_t innerOuterAngles[25]; -extern const float outerAttenuations[32]; -#endif - enum IVAS_RTP_HEADER_BITS { -- GitLab From 0584c4761f185b01a1a269276e68f06dcac33ebc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20Toftg=C3=A5rd?= Date: Fri, 7 Nov 2025 09:56:07 +0100 Subject: [PATCH 13/15] Fix loop for ism_position packing. Remove duplicate of unpackPositions. --- lib_util/ivas_rtp_pi_data.c | 2 +- tests/rtp/ivasrtp.py | 12 ------------ 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/lib_util/ivas_rtp_pi_data.c b/lib_util/ivas_rtp_pi_data.c index ad8a507355..0e7ceeb747 100644 --- a/lib_util/ivas_rtp_pi_data.c +++ b/lib_util/ivas_rtp_pi_data.c @@ -586,7 +586,7 @@ static ivas_error packISMPosition( const IVAS_PIDATA_GENERIC *piData, uint8_t *b buffer[nBytes++] = ( ism_position->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ buffer[nBytes++] = (uint8_t) ism_position->numObjects * 6; - for ( n = 0; n < piData->size / 6; n++ ) + for ( n = 0; n < ism_position->numObjects; n++ ) { nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( ism_position->position[n].x / MAX_PI_POSITION_METERS ) ); nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( ism_position->position[n].y / MAX_PI_POSITION_METERS ) ); diff --git a/tests/rtp/ivasrtp.py b/tests/rtp/ivasrtp.py index 301da07760..4b3c0dabec 100644 --- a/tests/rtp/ivasrtp.py +++ b/tests/rtp/ivasrtp.py @@ -1041,18 +1041,6 @@ def packISMDistanceAttenuation(bitstrm: BitStream, data: any): bitstrm.append(f'uint:6={roll_off_idx}') bitstrm.append(f'uint:6=0') - -def unpackPositions(bitstrm: ConstBitStream, piSize: int) -> list[POSITION]: - assert piSize <= 24 and (piSize % 6) == 0, "Incorrect PI Data Size for Positions" - positions = list() - while piSize > 0: - x = bitstrm.read(16).int / 100.0 - y = bitstrm.read(16).int / 100.0 - z = bitstrm.read(16).int / 100.0 - positions.append(POSITION(x, y, z)) - piSize -= 6 - return positions - def unpackISMDirectivity(bitstrm: ConstBitStream, piSize: int) -> list[DISTANCE_ATTENUATION]: inner_ang = None outer_ang = None -- GitLab From 9a848bd39de2d2f981547c45a648241ed020e831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20Toftg=C3=A5rd?= Date: Mon, 10 Nov 2025 11:27:16 +0100 Subject: [PATCH 14/15] Remove unused define PI_DATA_FIX --- lib_com/options.h | 1 - 1 file changed, 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 8a4870e0f7..cb8899ca78 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -164,7 +164,6 @@ #define IVAS_RTPDUMP_ACOUSTIC_ENVIRONMENT /* RTPDUMP acoustic environment */ #define FIXED_RTP_SEQUENCE_NUM /* Remove random sequence number initialization */ #define ISM_PI_DATA /* Add reading and packing/unpacking of ISM PI data */ -#define PI_DATA_FIX /* Fix for PI Data JSON file */ /* ################### Start BE switches ################################# */ /* only BE switches wrt selection floating point code */ -- GitLab From ece7a159c35ba8d24d49d3c3fa1f0b9c1dae715d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20Toftg=C3=A5rd?= Date: Mon, 10 Nov 2025 11:44:39 +0100 Subject: [PATCH 15/15] Remove numpy --- tests/rtp/ivasrtp.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/rtp/ivasrtp.py b/tests/rtp/ivasrtp.py index 4b3c0dabec..b336fec5d1 100644 --- a/tests/rtp/ivasrtp.py +++ b/tests/rtp/ivasrtp.py @@ -43,7 +43,6 @@ import base64 import argparse from pathlib import Path from typing import cast, Optional -import numpy as np NO_REQ = "NO_REQ" -- GitLab