Loading lib_com/options.h +1 −0 Original line number Diff line number Diff line Loading @@ -170,6 +170,7 @@ #define RTP_SR_CODEC_FRAME_SIZE_IN_TOC_BYTE /* CR for split rendering codec framesize signalling in Toc Byte*/ #define FIX_SPLIT_RENDERING_ON_DECODER_RESTART /* Re-configure split rendering on decoder restart */ #define RTP_UPDATES_SA4_134 /* Updates to RTP during SA4 134 */ #define COMPACT_ORIENTATION_PI_DATA /* ################### Start BE switches ################################# */ /* only BE switches wrt selection floating point code */ Loading lib_util/ivas_rtp_pi_data.c +115 −1 Original line number Diff line number Diff line Loading @@ -106,6 +106,95 @@ static int16_t ivasPayload_convertToQ9( float value ) return (int16_t) ( value ); } #ifdef COMPACT_ORIENTATION_PI_DATA static uint32_t packQuaternion( IVAS_QUATERNION orientation, uint8_t *buffer ) { uint32_t nBytes = 0; float q[4], q_max; uint16_t max_q_idx, n, k; uint32_t lWord; q[0] = orientation.w; q[1] = orientation.x; q[2] = orientation.y; q[3] = orientation.z; max_q_idx = 0; q_max = (float) fabs( q[0] ); for ( n = 1; n < 4; n++ ) { if ( (float) fabs( q[n] ) > q_max ) { q_max = (float) fabs( q[n] ); max_q_idx = n; } } if ( q[max_q_idx] < 0 ) { for ( n = 0; n < 4; n++ ) { q[n] = -q[n]; } } lWord = max_q_idx << 30; k = 1; for ( n = 0; n < 4; n++ ) { if ( n == max_q_idx ) { continue; } lWord |= ( ( (int16_t) ( ( q[n] + 1 ) * 1023 * 0.5f ) & MASK_10BIT ) << ( 30 - k * 10 ) ); k++; } buffer[nBytes++] = ( lWord >> 24 ) & MASK_8BIT; buffer[nBytes++] = ( lWord >> 16 ) & MASK_8BIT; buffer[nBytes++] = ( lWord >> 8 ) & MASK_8BIT; buffer[nBytes++] = (lWord) &MASK_8BIT; return nBytes; } static ivas_error unpackQuaternion( const uint8_t *buffer, IVAS_QUATERNION *orientation ) { uint32_t i, k, lWord; uint16_t max_q_idx, tmp; float q[4], qs; lWord = ( buffer[0] ) << 24; lWord |= ( buffer[1] ) << 16; lWord |= ( buffer[2] ) << 8; lWord |= buffer[3]; max_q_idx = ( lWord >> 30 ) & MASK_2BIT; k = 1; qs = 0.0f; for ( i = 0; i < 4; i++ ) { if ( i == max_q_idx ) { continue; } tmp = ( lWord >> ( 30 - k * 10 ) ) & MASK_10BIT; q[i] = tmp / 1023.0f * 2.0f - 1; qs += q[i] * q[i]; k++; } q[max_q_idx] = sqrtf( 1 - qs ); orientation->w = q[0]; orientation->x = q[1]; orientation->y = q[2]; orientation->z = q[3]; return IVAS_ERR_OK; } #else /*-----------------------------------------------------------------------* * ivasPayload_convertToQ7() * Loading @@ -119,6 +208,7 @@ static int16_t ivasPayload_convertToQ7( float value ) return (int16_t) ( value ); } #endif #endif static ivas_error packUnsupportedData( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ) { Loading Loading @@ -210,10 +300,14 @@ static ivas_error packOrientation( const IVAS_PIDATA_GENERIC *piData, uint8_t *b buffer[nBytes++] = ( orientation->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ #ifdef RTP_UPDATES_SA4_134 buffer[nBytes++] = 4; #ifdef COMPACT_ORIENTATION_PI_DATA nBytes += packQuaternion( orientation->orientation, &buffer[nBytes] ); #else buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation.w ); buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation.x ); buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation.y ); buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation.z ); #endif #else buffer[nBytes++] = 8; nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( orientation->orientation.w ) ); Loading Loading @@ -262,10 +356,14 @@ static ivas_error packISMOrientation( const IVAS_PIDATA_GENERIC *piData, uint8_t buffer[nBytes++] = (uint8_t) orientation->numObjects * 4; for ( n = 0; n < orientation->numObjects; n++ ) { #ifdef COMPACT_ORIENTATION_PI_DATA nBytes += packQuaternion( orientation->orientation[n], &buffer[nBytes] ); #else buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation[n].w ); buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation[n].x ); buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation[n].y ); buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation[n].z ); #endif } #else buffer[nBytes++] = (uint8_t) orientation->numObjects * 8; Loading Loading @@ -294,10 +392,14 @@ static ivas_error unpackOrientation( const uint8_t *buffer, uint32_t numDataByte } piData->size = sizeof( IVAS_PIDATA_ORIENTATION ); #ifdef COMPACT_ORIENTATION_PI_DATA unpackQuaternion( buffer, &( orientation->orientation ) ); #else orientation->orientation.w = FLOAT_FROM_Q7( (int8_t) buffer[0] ); orientation->orientation.x = FLOAT_FROM_Q7( (int8_t) buffer[1] ); orientation->orientation.y = FLOAT_FROM_Q7( (int8_t) buffer[2] ); orientation->orientation.z = FLOAT_FROM_Q7( (int8_t) buffer[3] ); #endif #else /* Orientation data is 8 bytes */ if ( numDataBytes != 8 ) Loading @@ -306,12 +408,12 @@ static ivas_error unpackOrientation( const uint8_t *buffer, uint32_t numDataByte } piData->size = sizeof( IVAS_PIDATA_ORIENTATION ); orientation->orientation.w = FLOAT_FROM_Q15( readInt16( &buffer[0] ) ); orientation->orientation.x = FLOAT_FROM_Q15( readInt16( &buffer[2] ) ); orientation->orientation.y = FLOAT_FROM_Q15( readInt16( &buffer[4] ) ); orientation->orientation.z = FLOAT_FROM_Q15( readInt16( &buffer[6] ) ); #endif return IVAS_ERR_OK; } Loading @@ -333,10 +435,14 @@ static ivas_error unpackISMOrientation( const uint8_t *buffer, uint32_t numDataB for ( n = 0; n < ism_orientation->numObjects; n++ ) { #ifdef COMPACT_ORIENTATION_PI_DATA unpackQuaternion( &buffer[4 * n], &( ism_orientation->orientation[n] ) ); #else ism_orientation->orientation[n].w = FLOAT_FROM_Q7( (int8_t) buffer[4 * n] ); ism_orientation->orientation[n].x = FLOAT_FROM_Q7( (int8_t) buffer[4 * n + 1] ); ism_orientation->orientation[n].y = FLOAT_FROM_Q7( (int8_t) buffer[4 * n + 2] ); ism_orientation->orientation[n].z = FLOAT_FROM_Q7( (int8_t) buffer[4 * n + 3] ); #endif } #else /* Orientation data is 8 bytes */ Loading Loading @@ -1036,10 +1142,14 @@ static ivas_error packAudioFocusCommon( const IVAS_PIDATA_GENERIC *piData, uint8 #ifdef RTP_UPDATES_SA4_134 if ( packedSize == 5 || packedSize == 4 ) { #ifdef COMPACT_ORIENTATION_PI_DATA nBytes += packQuaternion( audioFocus->direction, &buffer[nBytes] ); #else buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( audioFocus->direction.w ); buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( audioFocus->direction.x ); buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( audioFocus->direction.y ); buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( audioFocus->direction.z ); #endif } if ( packedSize == 5 || packedSize == 1 ) { Loading Loading @@ -1084,10 +1194,14 @@ static ivas_error unpackAudioFocusCommon( const uint8_t *buffer, uint32_t numDat } else { #ifdef COMPACT_ORIENTATION_PI_DATA unpackQuaternion( buffer, &( audioFocus->direction ) ); #else audioFocus->direction.w = FLOAT_FROM_Q7( (int8_t) buffer[0] ); audioFocus->direction.x = FLOAT_FROM_Q7( (int8_t) buffer[1] ); audioFocus->direction.y = FLOAT_FROM_Q7( (int8_t) buffer[2] ); audioFocus->direction.z = FLOAT_FROM_Q7( (int8_t) buffer[3] ); #endif if ( numDataBytes == 5 ) { Loading tests/rtp/ivasrtp.py +26 −8 Original line number Diff line number Diff line Loading @@ -761,11 +761,23 @@ def unpackOrientations(bitstrm: ConstBitStream, piSize: int) -> list[ORIENTATION piSize % 4 ) == 0 and piSize <= 16, "Incorrect PI Data Size for list[ORIENTATION]" orientations = list() q = [(float)]*4 qs = 0 while piSize > 0: w = bitstrm.read(8).int / 128.0 x = bitstrm.read(8).int / 128.0 y = bitstrm.read(8).int / 128.0 z = bitstrm.read(8).int / 128.0 max_q_idx = bitstrm.read(2).uint for i in range(0,4): if i == max_q_idx: continue tmp = bitstrm.read(10).uint q[i] = (tmp / 1023.0) * 2.0 - 1.0 qs = qs + q[i]**2 q[max_q_idx] = (1 - qs)**0.5 w = q[0] x = q[1] y = q[2] z = q[3] orientations.append(ORIENTATION(w, x, y, z)) piSize -= 4 return orientations Loading @@ -777,10 +789,16 @@ def packOrientations(bitstrm: BitStream, data: any): assert ( type(orientation) == ORIENTATION ), "Orientation PI Data expects a data of type list[ORIENTATION]" bitstrm.append(f"intbe:8={q7(orientation.w)}") bitstrm.append(f"intbe:8={q7(orientation.x)}") bitstrm.append(f"intbe:8={q7(orientation.y)}") bitstrm.append(f"intbe:8={q7(orientation.z)}") q = [orientation.w, orientation.x, orientation.y, orientation.z] max_q = max(q, key=abs) max_q_idx = q.index(max_q) if max_q < 0: q = [-x for x in q] bitstrm.append(f"uint:2={max_q_idx}") for i in range(0,4): if i == max_q_idx: continue bitstrm.append(f"uint:10={(int)((q[i]+1)*1023*1/2)}") def unpackPositions(bitstrm: ConstBitStream, piSize: int) -> list[POSITION]: Loading tests/rtp/test_rtp.py +22 −32 Original line number Diff line number Diff line Loading @@ -182,12 +182,17 @@ def generateRequests(startTs: int, endTs: int) -> dict: def generatePiData(startTs: int, endTs: int) -> dict: data = dict() someOrientation = lambda: 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, ) def random_unit_quaternion(): w = 2*random.random() - 1.0 x = 2*random.random() - 1.0 y = 2*random.random() - 1.0 z = 2*random.random() - 1.0 n = (w*w + x*x + y*y + z*z)**0.5 if n == 0.0: return random_unit_quaternion() return ORIENTATION(w/n, x/n, y/n, z/n) someOrientation = lambda: random_unit_quaternion() somePosition = lambda: POSITION( x=random.randint(-32788, 32767) / 100.0, y=random.randint(-32788, 32767) / 100.0, Loading @@ -214,23 +219,8 @@ def generatePiData(startTs: int, endTs: int) -> dict: someDIG = lambda: DIEGETIC_TYPE( isDigetic=[bool(random.getrandbits(1)) for _ in range(random.randint(1, 5))] ) someAuFocusDirLvl = lambda: AUDIO_FOCUS( 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, ), level=AUDIO_FOCUS_LEVEL(random.randint(0, 15)), ) someAuFocusDir = lambda: AUDIO_FOCUS( 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, ) ) someAuFocusDirLvl = lambda: AUDIO_FOCUS(random_unit_quaternion(),level=AUDIO_FOCUS_LEVEL(random.randint(0, 15)),) someAuFocusDir = lambda: AUDIO_FOCUS(random_unit_quaternion()) someAuFocusLvl = lambda: AUDIO_FOCUS(level=AUDIO_FOCUS_LEVEL(random.randint(0, 15))) someAuFocusList = [someAuFocusDirLvl, someAuFocusDir, someAuFocusLvl] someLatency = lambda: PI_LATENCY( Loading Loading @@ -278,7 +268,7 @@ def generatePiData(startTs: int, endTs: int) -> dict: 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=[random.choice([int(random.randint(-24,12)), -128]) for _ in range(num_ism)]) # -128 corresponds to -Inf 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)] someISMOrientations = lambda num_ism : [random_unit_quaternion() 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)] someISMPositionsCompact = lambda num_ism : [POSITION( x=random.randint(-1024, 1023)/100.0, y=random.randint(-1024, 1023)/100.0, z=random.randint(-512, 511)/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)] Loading Loading @@ -330,10 +320,10 @@ def isEqualFrame(refFrame: bytes, dutFrame: bytes): def isEqualOrientation(ref: ORIENTATION, dut: ORIENTATION): assert abs(ref.w - dut.w) < 0.0079, "Scene Orientation PI Data mismatch in w" assert abs(ref.x - dut.x) < 0.0079, "Scene Orientation PI Data mismatch in x" assert abs(ref.y - dut.y) < 0.0079, "Scene Orientation PI Data mismatch in y" assert abs(ref.z - dut.z) < 0.0079, "Scene Orientation PI Data mismatch in z" assert abs(abs(ref.w) - abs(dut.w)) < 0.01, "Scene Orientation PI Data mismatch in w" assert abs(abs(ref.x) - abs(dut.x)) < 0.01, "Scene Orientation PI Data mismatch in x" assert abs(abs(ref.y) - abs(dut.y)) < 0.01, "Scene Orientation PI Data mismatch in y" assert abs(abs(ref.z) - abs(dut.z)) < 0.01, "Scene Orientation PI Data mismatch in z" def isEqualPosition(ref: POSITION, dut: POSITION): Loading Loading @@ -400,16 +390,16 @@ def isEqualAudioFocus(ref: AUDIO_FOCUS, dut: AUDIO_FOCUS): assert dut.direction is not None, "Audio Focus PI Data missing direction" if ref.direction is not None and dut.direction is not None: assert ( abs(ref.direction["w"] - dut.direction.w) < 0.0079 abs(abs(ref.direction["w"]) - abs(dut.direction.w)) < 0.01 ), "Audio Focus PI Data mismatch in direction w" assert ( abs(ref.direction["x"] - dut.direction.x) < 0.0079 abs(abs(ref.direction["x"]) - abs(dut.direction.x)) < 0.01 ), "Audio Focus PI Data mismatch in direction x" assert ( abs(ref.direction["y"] - dut.direction.y) < 0.0079 abs(abs(ref.direction["y"]) - abs(dut.direction.y)) < 0.01 ), "Audio Focus PI Data mismatch in direction y" assert ( abs(ref.direction["z"] - dut.direction.z) < 0.0079 abs(abs(ref.direction["z"]) - abs(dut.direction.z)) < 0.01 ), "Audio Focus PI Data mismatch in direction z" assert ref.level == dut.level, "Audio Focus PI Data mismatch in level" Loading Loading
lib_com/options.h +1 −0 Original line number Diff line number Diff line Loading @@ -170,6 +170,7 @@ #define RTP_SR_CODEC_FRAME_SIZE_IN_TOC_BYTE /* CR for split rendering codec framesize signalling in Toc Byte*/ #define FIX_SPLIT_RENDERING_ON_DECODER_RESTART /* Re-configure split rendering on decoder restart */ #define RTP_UPDATES_SA4_134 /* Updates to RTP during SA4 134 */ #define COMPACT_ORIENTATION_PI_DATA /* ################### Start BE switches ################################# */ /* only BE switches wrt selection floating point code */ Loading
lib_util/ivas_rtp_pi_data.c +115 −1 Original line number Diff line number Diff line Loading @@ -106,6 +106,95 @@ static int16_t ivasPayload_convertToQ9( float value ) return (int16_t) ( value ); } #ifdef COMPACT_ORIENTATION_PI_DATA static uint32_t packQuaternion( IVAS_QUATERNION orientation, uint8_t *buffer ) { uint32_t nBytes = 0; float q[4], q_max; uint16_t max_q_idx, n, k; uint32_t lWord; q[0] = orientation.w; q[1] = orientation.x; q[2] = orientation.y; q[3] = orientation.z; max_q_idx = 0; q_max = (float) fabs( q[0] ); for ( n = 1; n < 4; n++ ) { if ( (float) fabs( q[n] ) > q_max ) { q_max = (float) fabs( q[n] ); max_q_idx = n; } } if ( q[max_q_idx] < 0 ) { for ( n = 0; n < 4; n++ ) { q[n] = -q[n]; } } lWord = max_q_idx << 30; k = 1; for ( n = 0; n < 4; n++ ) { if ( n == max_q_idx ) { continue; } lWord |= ( ( (int16_t) ( ( q[n] + 1 ) * 1023 * 0.5f ) & MASK_10BIT ) << ( 30 - k * 10 ) ); k++; } buffer[nBytes++] = ( lWord >> 24 ) & MASK_8BIT; buffer[nBytes++] = ( lWord >> 16 ) & MASK_8BIT; buffer[nBytes++] = ( lWord >> 8 ) & MASK_8BIT; buffer[nBytes++] = (lWord) &MASK_8BIT; return nBytes; } static ivas_error unpackQuaternion( const uint8_t *buffer, IVAS_QUATERNION *orientation ) { uint32_t i, k, lWord; uint16_t max_q_idx, tmp; float q[4], qs; lWord = ( buffer[0] ) << 24; lWord |= ( buffer[1] ) << 16; lWord |= ( buffer[2] ) << 8; lWord |= buffer[3]; max_q_idx = ( lWord >> 30 ) & MASK_2BIT; k = 1; qs = 0.0f; for ( i = 0; i < 4; i++ ) { if ( i == max_q_idx ) { continue; } tmp = ( lWord >> ( 30 - k * 10 ) ) & MASK_10BIT; q[i] = tmp / 1023.0f * 2.0f - 1; qs += q[i] * q[i]; k++; } q[max_q_idx] = sqrtf( 1 - qs ); orientation->w = q[0]; orientation->x = q[1]; orientation->y = q[2]; orientation->z = q[3]; return IVAS_ERR_OK; } #else /*-----------------------------------------------------------------------* * ivasPayload_convertToQ7() * Loading @@ -119,6 +208,7 @@ static int16_t ivasPayload_convertToQ7( float value ) return (int16_t) ( value ); } #endif #endif static ivas_error packUnsupportedData( const IVAS_PIDATA_GENERIC *piData, uint8_t *buffer, uint32_t maxDataBytes, uint32_t *nBytesWritten ) { Loading Loading @@ -210,10 +300,14 @@ static ivas_error packOrientation( const IVAS_PIDATA_GENERIC *piData, uint8_t *b buffer[nBytes++] = ( orientation->piDataType & MASK_5BIT ); /* PF/PM populated during final packing */ #ifdef RTP_UPDATES_SA4_134 buffer[nBytes++] = 4; #ifdef COMPACT_ORIENTATION_PI_DATA nBytes += packQuaternion( orientation->orientation, &buffer[nBytes] ); #else buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation.w ); buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation.x ); buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation.y ); buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation.z ); #endif #else buffer[nBytes++] = 8; nBytes = writeInt16( buffer, nBytes, ivasPayload_convertToQ15( orientation->orientation.w ) ); Loading Loading @@ -262,10 +356,14 @@ static ivas_error packISMOrientation( const IVAS_PIDATA_GENERIC *piData, uint8_t buffer[nBytes++] = (uint8_t) orientation->numObjects * 4; for ( n = 0; n < orientation->numObjects; n++ ) { #ifdef COMPACT_ORIENTATION_PI_DATA nBytes += packQuaternion( orientation->orientation[n], &buffer[nBytes] ); #else buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation[n].w ); buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation[n].x ); buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation[n].y ); buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( orientation->orientation[n].z ); #endif } #else buffer[nBytes++] = (uint8_t) orientation->numObjects * 8; Loading Loading @@ -294,10 +392,14 @@ static ivas_error unpackOrientation( const uint8_t *buffer, uint32_t numDataByte } piData->size = sizeof( IVAS_PIDATA_ORIENTATION ); #ifdef COMPACT_ORIENTATION_PI_DATA unpackQuaternion( buffer, &( orientation->orientation ) ); #else orientation->orientation.w = FLOAT_FROM_Q7( (int8_t) buffer[0] ); orientation->orientation.x = FLOAT_FROM_Q7( (int8_t) buffer[1] ); orientation->orientation.y = FLOAT_FROM_Q7( (int8_t) buffer[2] ); orientation->orientation.z = FLOAT_FROM_Q7( (int8_t) buffer[3] ); #endif #else /* Orientation data is 8 bytes */ if ( numDataBytes != 8 ) Loading @@ -306,12 +408,12 @@ static ivas_error unpackOrientation( const uint8_t *buffer, uint32_t numDataByte } piData->size = sizeof( IVAS_PIDATA_ORIENTATION ); orientation->orientation.w = FLOAT_FROM_Q15( readInt16( &buffer[0] ) ); orientation->orientation.x = FLOAT_FROM_Q15( readInt16( &buffer[2] ) ); orientation->orientation.y = FLOAT_FROM_Q15( readInt16( &buffer[4] ) ); orientation->orientation.z = FLOAT_FROM_Q15( readInt16( &buffer[6] ) ); #endif return IVAS_ERR_OK; } Loading @@ -333,10 +435,14 @@ static ivas_error unpackISMOrientation( const uint8_t *buffer, uint32_t numDataB for ( n = 0; n < ism_orientation->numObjects; n++ ) { #ifdef COMPACT_ORIENTATION_PI_DATA unpackQuaternion( &buffer[4 * n], &( ism_orientation->orientation[n] ) ); #else ism_orientation->orientation[n].w = FLOAT_FROM_Q7( (int8_t) buffer[4 * n] ); ism_orientation->orientation[n].x = FLOAT_FROM_Q7( (int8_t) buffer[4 * n + 1] ); ism_orientation->orientation[n].y = FLOAT_FROM_Q7( (int8_t) buffer[4 * n + 2] ); ism_orientation->orientation[n].z = FLOAT_FROM_Q7( (int8_t) buffer[4 * n + 3] ); #endif } #else /* Orientation data is 8 bytes */ Loading Loading @@ -1036,10 +1142,14 @@ static ivas_error packAudioFocusCommon( const IVAS_PIDATA_GENERIC *piData, uint8 #ifdef RTP_UPDATES_SA4_134 if ( packedSize == 5 || packedSize == 4 ) { #ifdef COMPACT_ORIENTATION_PI_DATA nBytes += packQuaternion( audioFocus->direction, &buffer[nBytes] ); #else buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( audioFocus->direction.w ); buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( audioFocus->direction.x ); buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( audioFocus->direction.y ); buffer[nBytes++] = (uint8_t) ivasPayload_convertToQ7( audioFocus->direction.z ); #endif } if ( packedSize == 5 || packedSize == 1 ) { Loading Loading @@ -1084,10 +1194,14 @@ static ivas_error unpackAudioFocusCommon( const uint8_t *buffer, uint32_t numDat } else { #ifdef COMPACT_ORIENTATION_PI_DATA unpackQuaternion( buffer, &( audioFocus->direction ) ); #else audioFocus->direction.w = FLOAT_FROM_Q7( (int8_t) buffer[0] ); audioFocus->direction.x = FLOAT_FROM_Q7( (int8_t) buffer[1] ); audioFocus->direction.y = FLOAT_FROM_Q7( (int8_t) buffer[2] ); audioFocus->direction.z = FLOAT_FROM_Q7( (int8_t) buffer[3] ); #endif if ( numDataBytes == 5 ) { Loading
tests/rtp/ivasrtp.py +26 −8 Original line number Diff line number Diff line Loading @@ -761,11 +761,23 @@ def unpackOrientations(bitstrm: ConstBitStream, piSize: int) -> list[ORIENTATION piSize % 4 ) == 0 and piSize <= 16, "Incorrect PI Data Size for list[ORIENTATION]" orientations = list() q = [(float)]*4 qs = 0 while piSize > 0: w = bitstrm.read(8).int / 128.0 x = bitstrm.read(8).int / 128.0 y = bitstrm.read(8).int / 128.0 z = bitstrm.read(8).int / 128.0 max_q_idx = bitstrm.read(2).uint for i in range(0,4): if i == max_q_idx: continue tmp = bitstrm.read(10).uint q[i] = (tmp / 1023.0) * 2.0 - 1.0 qs = qs + q[i]**2 q[max_q_idx] = (1 - qs)**0.5 w = q[0] x = q[1] y = q[2] z = q[3] orientations.append(ORIENTATION(w, x, y, z)) piSize -= 4 return orientations Loading @@ -777,10 +789,16 @@ def packOrientations(bitstrm: BitStream, data: any): assert ( type(orientation) == ORIENTATION ), "Orientation PI Data expects a data of type list[ORIENTATION]" bitstrm.append(f"intbe:8={q7(orientation.w)}") bitstrm.append(f"intbe:8={q7(orientation.x)}") bitstrm.append(f"intbe:8={q7(orientation.y)}") bitstrm.append(f"intbe:8={q7(orientation.z)}") q = [orientation.w, orientation.x, orientation.y, orientation.z] max_q = max(q, key=abs) max_q_idx = q.index(max_q) if max_q < 0: q = [-x for x in q] bitstrm.append(f"uint:2={max_q_idx}") for i in range(0,4): if i == max_q_idx: continue bitstrm.append(f"uint:10={(int)((q[i]+1)*1023*1/2)}") def unpackPositions(bitstrm: ConstBitStream, piSize: int) -> list[POSITION]: Loading
tests/rtp/test_rtp.py +22 −32 Original line number Diff line number Diff line Loading @@ -182,12 +182,17 @@ def generateRequests(startTs: int, endTs: int) -> dict: def generatePiData(startTs: int, endTs: int) -> dict: data = dict() someOrientation = lambda: 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, ) def random_unit_quaternion(): w = 2*random.random() - 1.0 x = 2*random.random() - 1.0 y = 2*random.random() - 1.0 z = 2*random.random() - 1.0 n = (w*w + x*x + y*y + z*z)**0.5 if n == 0.0: return random_unit_quaternion() return ORIENTATION(w/n, x/n, y/n, z/n) someOrientation = lambda: random_unit_quaternion() somePosition = lambda: POSITION( x=random.randint(-32788, 32767) / 100.0, y=random.randint(-32788, 32767) / 100.0, Loading @@ -214,23 +219,8 @@ def generatePiData(startTs: int, endTs: int) -> dict: someDIG = lambda: DIEGETIC_TYPE( isDigetic=[bool(random.getrandbits(1)) for _ in range(random.randint(1, 5))] ) someAuFocusDirLvl = lambda: AUDIO_FOCUS( 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, ), level=AUDIO_FOCUS_LEVEL(random.randint(0, 15)), ) someAuFocusDir = lambda: AUDIO_FOCUS( 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, ) ) someAuFocusDirLvl = lambda: AUDIO_FOCUS(random_unit_quaternion(),level=AUDIO_FOCUS_LEVEL(random.randint(0, 15)),) someAuFocusDir = lambda: AUDIO_FOCUS(random_unit_quaternion()) someAuFocusLvl = lambda: AUDIO_FOCUS(level=AUDIO_FOCUS_LEVEL(random.randint(0, 15))) someAuFocusList = [someAuFocusDirLvl, someAuFocusDir, someAuFocusLvl] someLatency = lambda: PI_LATENCY( Loading Loading @@ -278,7 +268,7 @@ def generatePiData(startTs: int, endTs: int) -> dict: 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=[random.choice([int(random.randint(-24,12)), -128]) for _ in range(num_ism)]) # -128 corresponds to -Inf 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)] someISMOrientations = lambda num_ism : [random_unit_quaternion() 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)] someISMPositionsCompact = lambda num_ism : [POSITION( x=random.randint(-1024, 1023)/100.0, y=random.randint(-1024, 1023)/100.0, z=random.randint(-512, 511)/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)] Loading Loading @@ -330,10 +320,10 @@ def isEqualFrame(refFrame: bytes, dutFrame: bytes): def isEqualOrientation(ref: ORIENTATION, dut: ORIENTATION): assert abs(ref.w - dut.w) < 0.0079, "Scene Orientation PI Data mismatch in w" assert abs(ref.x - dut.x) < 0.0079, "Scene Orientation PI Data mismatch in x" assert abs(ref.y - dut.y) < 0.0079, "Scene Orientation PI Data mismatch in y" assert abs(ref.z - dut.z) < 0.0079, "Scene Orientation PI Data mismatch in z" assert abs(abs(ref.w) - abs(dut.w)) < 0.01, "Scene Orientation PI Data mismatch in w" assert abs(abs(ref.x) - abs(dut.x)) < 0.01, "Scene Orientation PI Data mismatch in x" assert abs(abs(ref.y) - abs(dut.y)) < 0.01, "Scene Orientation PI Data mismatch in y" assert abs(abs(ref.z) - abs(dut.z)) < 0.01, "Scene Orientation PI Data mismatch in z" def isEqualPosition(ref: POSITION, dut: POSITION): Loading Loading @@ -400,16 +390,16 @@ def isEqualAudioFocus(ref: AUDIO_FOCUS, dut: AUDIO_FOCUS): assert dut.direction is not None, "Audio Focus PI Data missing direction" if ref.direction is not None and dut.direction is not None: assert ( abs(ref.direction["w"] - dut.direction.w) < 0.0079 abs(abs(ref.direction["w"]) - abs(dut.direction.w)) < 0.01 ), "Audio Focus PI Data mismatch in direction w" assert ( abs(ref.direction["x"] - dut.direction.x) < 0.0079 abs(abs(ref.direction["x"]) - abs(dut.direction.x)) < 0.01 ), "Audio Focus PI Data mismatch in direction x" assert ( abs(ref.direction["y"] - dut.direction.y) < 0.0079 abs(abs(ref.direction["y"]) - abs(dut.direction.y)) < 0.01 ), "Audio Focus PI Data mismatch in direction y" assert ( abs(ref.direction["z"] - dut.direction.z) < 0.0079 abs(abs(ref.direction["z"]) - abs(dut.direction.z)) < 0.01 ), "Audio Focus PI Data mismatch in direction z" assert ref.level == dut.level, "Audio Focus PI Data mismatch in level" Loading