Loading lib_com/options.h +5 −0 Original line number Diff line number Diff line Loading @@ -184,6 +184,11 @@ #define FIX_FMSW_DEC_2 /* float issue 1575: fix crash for format switching when bitsream starts with EVS */ #define FIX_FLOAT_1578_OMASA_REND_SPIKES /* Nokia: Float issue 1578: Fix spikes and collapsed perception in OMASA/MASA rendering to FOA/HOA */ #define FIX_FLOAT_1584_RTP_ISM_RENDERING /* Eri: Float issue 1584: Add missing rendering configuration based on ISM PI data */ #ifdef FIX_FLOAT_1584_RTP_ISM_RENDERING #define FIX_FLOAT_1584_RTP_SYNC_PI /* Eri: Float issue 1584: Sync existing PI data with audio data */ #endif /* ##################### End NON-BE switches ########################### */ /* ################## End MAINTENANCE switches ######################### */ Loading lib_dec/lib_dec.c +409 −1 Original line number Diff line number Diff line Loading @@ -97,6 +97,17 @@ struct IVAS_DEC bool needNewFrame; bool hasBeenFedFrame; bool updateOrientation; #ifdef FIX_FLOAT_1584_RTP_ISM_RENDERING bool receivedISMGainPI; bool receivedISMOrientationPI; bool receivedISMPositionPI; bool receivedISMDistanceAttenuationPI; bool receivedISMDirectivityPI; IVAS_PIDATA_TS piBuf[MAX_JBM_SLOTS]; int16_t piBufSize; int16_t piBufNext; uint32_t audioTs; #endif uint16_t nSamplesAvailableNext; int16_t nTransportChannelsOld; int16_t amrwb_rfc4867_flag; /* MIME from rfc4867 is used */ Loading Loading @@ -136,6 +147,14 @@ static int16_t get_render_frame_size_ms( const IVAS_RENDER_NUM_SUBFR render_num_ static int16_t get_render_frame_size_samples( const DECODER_CONFIG_HANDLE hDecoderConfig ); static int16_t ivas_dec_split_rend_cldfb_in( const RENDERER_TYPE renderer_type ); static void update_voip_rendered20ms( IVAS_DEC_HANDLE hIvasDec, const int16_t nSamplesRendered ); #ifdef FIX_FLOAT_1584_RTP_ISM_RENDERING static ivas_error applyPiData( IVAS_DEC_HANDLE hIvasDec, const uint32_t audioTs ); static void feedISMGainPI( IVAS_DEC_HANDLE hIvasDec, const IVAS_PIDATA_ISM_GAIN *gain ); static void feedISMOrientationPI( IVAS_DEC_HANDLE hIvasDec, const IVAS_PIDATA_ISM_ORIENTATION *ori ); static void feedISMPositionPI( IVAS_DEC_HANDLE hIvasDec, const IVAS_PIDATA_ISM_POSITION *pos ); static void feedISMDistanceAttenuationPI( IVAS_DEC_HANDLE hIvasDec, const IVAS_PIDATA_ISM_ATTENUATION *att ); static void feedISMDirectivityPI( IVAS_DEC_HANDLE hIvasDec, const IVAS_PIDATA_ISM_DIRECTIVITY *dir ); #endif #ifdef FIX_FMSW_DEC Loading Loading @@ -257,6 +276,16 @@ ivas_error IVAS_DEC_Open( hIvasDec->hasDecodedFirstGoodFrame = false; hIvasDec->isInitialized = false; hIvasDec->updateOrientation = false; #ifdef FIX_FLOAT_1584_RTP_ISM_RENDERING hIvasDec->receivedISMGainPI = false; hIvasDec->receivedISMOrientationPI = false; hIvasDec->receivedISMPositionPI = false; hIvasDec->receivedISMDistanceAttenuationPI = false; hIvasDec->receivedISMDirectivityPI = false; hIvasDec->piBufSize = 0; hIvasDec->piBufNext = 0; hIvasDec->audioTs = 0; #endif hIvasDec->flushbuffer = NULL; hIvasDec->pcmType = IVAS_DEC_PCM_INVALID; hIvasDec->nSamplesFlushed = 0; Loading Loading @@ -1290,6 +1319,11 @@ ivas_error IVAS_DEC_GetSamplesDecoder( uint8_t nTransportChannels; int16_t nResidualSamples, nSamplesTcsScaled; bool isInitialized_voip; #ifdef FIX_FLOAT_1584_RTP_ISM_RENDERING int16_t obj; ISM_METADATA_HANDLE *hIsmMetaData; PARAM_ISM_DEC_HANDLE hParamIsmDec; #endif if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { Loading Loading @@ -1402,6 +1436,14 @@ ivas_error IVAS_DEC_GetSamplesDecoder( hIvasDec->hasBeenPreparedRendering = false; #ifdef FIX_FLOAT_1584_RTP_ISM_RENDERING /* Apply PI data */ if ( ( error = applyPiData( hIvasDec, hIvasDec->audioTs ) ) != IVAS_ERR_OK ) { return error; } #endif /*-----------------------------------------------------------------* * Set editable metadata *-----------------------------------------------------------------*/ Loading @@ -1412,6 +1454,27 @@ ivas_error IVAS_DEC_GetSamplesDecoder( { if ( st_ivas->ism_mode == ISM_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { #ifdef FIX_FLOAT_1584_RTP_ISM_RENDERING hIsmMetaData = st_ivas->hIsmMetaData; for ( obj = 0; obj < st_ivas->nchan_ism; obj++ ) { if ( !hIvasDec->receivedISMPositionPI ) { hIsmMetaData[obj]->edited_azimuth = hIsmMetaData[obj]->azimuth; hIsmMetaData[obj]->edited_elevation = hIsmMetaData[obj]->elevation; hIsmMetaData[obj]->edited_radius = hIsmMetaData[obj]->radius; } if ( !hIvasDec->receivedISMOrientationPI ) { hIsmMetaData[obj]->edited_yaw = hIsmMetaData[obj]->yaw; hIsmMetaData[obj]->edited_pitch = hIsmMetaData[obj]->pitch; } if ( !hIvasDec->receivedISMGainPI ) { hIsmMetaData[obj]->edited_gain = 1.0f; } } #else int16_t obj; ISM_METADATA_HANDLE *hIsmMetaData = st_ivas->hIsmMetaData; for ( obj = 0; obj < st_ivas->nchan_ism; obj++ ) Loading @@ -1423,7 +1486,7 @@ ivas_error IVAS_DEC_GetSamplesDecoder( hIsmMetaData[obj]->edited_radius = hIsmMetaData[obj]->radius; hIsmMetaData[obj]->edited_gain = 1.0f; } #endif if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { st_ivas->hSbaIsmData->gain_bed = 1.0f; Loading @@ -1436,8 +1499,12 @@ ivas_error IVAS_DEC_GetSamplesDecoder( { if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { #ifdef FIX_FLOAT_1584_RTP_ISM_RENDERING hParamIsmDec = st_ivas->hParamIsmDec; #else int16_t obj = 0; PARAM_ISM_DEC_HANDLE hParamIsmDec = st_ivas->hParamIsmDec; #endif for ( obj = 0; obj < st_ivas->nchan_ism; obj++ ) { hParamIsmDec->edited_azimuth_values[obj] = hParamIsmDec->azimuth_values[obj]; Loading Loading @@ -4107,6 +4174,9 @@ static ivas_error ivas_dec_voip_get_samples_common( } *bitstreamReadDone = true; #ifdef FIX_FLOAT_1584_RTP_ISM_RENDERING hIvasDec->audioTs = dataUnit->timeStamp * 16; #endif } else if ( hIvasDec->hasDecodedFirstGoodFrame ) { Loading Loading @@ -5821,6 +5891,291 @@ static void setDiegeticInputPI( } #ifdef FIX_FLOAT_1584_RTP_ISM_RENDERING static void feedISMGainPI( IVAS_DEC_HANDLE hIvasDec, const IVAS_PIDATA_ISM_GAIN *gain ) { int16_t obj, pi_idx; int8_t dB; ISM_METADATA_HANDLE *hIsmMetaData = hIvasDec->st_ivas->hIsmMetaData; for ( obj = 0; obj < hIvasDec->st_ivas->nchan_ism; obj++ ) { pi_idx = min( obj, gain->numObjects - 1 ); dB = gain->dB[pi_idx]; if ( dB == -128 ) { hIsmMetaData[obj]->edited_gain = 0.0f; } else { hIsmMetaData[obj]->edited_gain = powf( 10.0f, dB / 20.0f ); } } hIvasDec->receivedISMGainPI = true; } static void feedISMOrientationPI( IVAS_DEC_HANDLE hIvasDec, const IVAS_PIDATA_ISM_ORIENTATION *ori ) { int16_t obj, pi_idx; float yaw, pitch, roll; ISM_METADATA_HANDLE *hIsmMetaData = hIvasDec->st_ivas->hIsmMetaData; for ( obj = 0; obj < hIvasDec->st_ivas->nchan_ism; obj++ ) { pi_idx = min( obj, ori->numObjects - 1 ); Quat2EulerDegree( ori->orientation[pi_idx], &yaw, &pitch, &roll ); hIsmMetaData[obj]->edited_yaw = yaw; hIsmMetaData[obj]->edited_pitch = pitch; } hIvasDec->receivedISMOrientationPI = true; } static void feedISMPositionPI( IVAS_DEC_HANDLE hIvasDec, const IVAS_PIDATA_ISM_POSITION *pos ) { int16_t obj, pi_idx; float x, y, z, xy; ISM_METADATA_HANDLE *hIsmMetaData = hIvasDec->st_ivas->hIsmMetaData; for ( obj = 0; obj < hIvasDec->st_ivas->nchan_ism; obj++ ) { pi_idx = min( obj, pos->numObjects - 1 ); x = pos->position[pi_idx].x; y = pos->position[pi_idx].y; z = pos->position[pi_idx].z; xy = x * x + y * y; hIsmMetaData[obj]->edited_radius = sqrtf( xy + z * z ); hIsmMetaData[obj]->edited_azimuth = atan2f( y, x ) * _180_OVER_PI; hIsmMetaData[obj]->edited_elevation = atan2f( z, sqrtf( xy ) ) * _180_OVER_PI; } hIvasDec->receivedISMPositionPI = true; } static void feedISMDistanceAttenuationPI( IVAS_DEC_HANDLE hIvasDec, const IVAS_PIDATA_ISM_ATTENUATION *att ) { int16_t obj, pi_idx; TDREND_DistAtten_t new_att; if ( hIvasDec->st_ivas->hBinRendererTd == NULL ) { return; } for ( obj = 0; obj < hIvasDec->st_ivas->nchan_ism; obj++ ) { pi_idx = min( obj, att->numObjects - 1 ); new_att.DistAttenModel = TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED; new_att.RefDist = att->distAtten[pi_idx].ref_dist; new_att.MaxDist = att->distAtten[pi_idx].max_dist; new_att.RollOffFactor = att->distAtten[pi_idx].roll; TDREND_MIX_SRC_SetDistAtten( hIvasDec->st_ivas->hBinRendererTd, obj, &new_att ); } hIvasDec->receivedISMDistanceAttenuationPI = true; } static void feedISMDirectivityPI( IVAS_DEC_HANDLE hIvasDec, const IVAS_PIDATA_ISM_DIRECTIVITY *dir ) { int16_t obj, pi_idx; TDREND_DirAtten_t new_dir; if ( hIvasDec->st_ivas->hBinRendererTd == NULL ) { return; } for ( obj = 0; obj < hIvasDec->st_ivas->nchan_ism; obj++ ) { pi_idx = min( obj, dir->numObjects - 1 ); new_dir.ConeInnerAngle = dir->directivity[pi_idx].innerConeAngle; new_dir.ConeOuterAngle = dir->directivity[pi_idx].outerConeAngle; new_dir.ConeOuterGain = powf( 10.0f, dir->directivity[pi_idx].outerAttenuationdB / 20.0f ); TDREND_MIX_SRC_SetDirAtten( hIvasDec->st_ivas->hBinRendererTd, obj, &new_dir ); } hIvasDec->receivedISMDirectivityPI = true; } static ivas_error applyPiData( IVAS_DEC_HANDLE hIvasDec, const uint32_t audioTs ) { int16_t i, k, buf_start, buf_size, idx, has_pi[IVAS_PI_MAX_ID]; IVAS_PIDATA_TS *pi_buf, latest_pi[IVAS_PI_MAX_ID]; uint32_t type; #ifdef FIX_FLOAT_1584_RTP_SYNC_PI ivas_error error; #endif if ( hIvasDec->piBufSize == 0 ) { return IVAS_ERR_OK; } buf_size = hIvasDec->piBufSize; buf_start = ( hIvasDec->piBufNext - buf_size + MAX_JBM_SLOTS ) % MAX_JBM_SLOTS; for ( i = 0; i < IVAS_PI_MAX_ID; i++ ) { has_pi[i] = 0; } /* Find latest PI data in buffer */ for ( i = 0; i < buf_size; i++ ) { idx = ( buf_start + i ) % MAX_JBM_SLOTS; pi_buf = &hIvasDec->piBuf[idx]; /* Find latest among preceeding PI data in buffer */ if ( pi_buf->timestamp <= audioTs ) { type = pi_buf->data.noPiData.piDataType; /* Treat IVAS_PI_ISM_POSITION_COMPACT as IVAS_PI_ISM_POSITION */ if ( type == IVAS_PI_ISM_POSITION_COMPACT ) { type = IVAS_PI_ISM_POSITION; } if ( type < IVAS_PI_MAX_ID && ( !has_pi[type] || pi_buf->timestamp >= latest_pi[type].timestamp ) ) { latest_pi[type] = *pi_buf; has_pi[type] = 1; } } } /* Keep only newer PI data in buffer */ k = 0; for ( i = 0; i < buf_size; i++ ) { idx = ( buf_start + i ) % MAX_JBM_SLOTS; if ( hIvasDec->piBuf[idx].timestamp > audioTs ) { hIvasDec->piBuf[k] = hIvasDec->piBuf[idx]; k++; } } hIvasDec->piBufSize = k; hIvasDec->piBufNext = k; #ifdef FIX_FLOAT_1584_RTP_SYNC_PI if ( has_pi[IVAS_PI_SCENE_ORIENTATION] ) { #ifdef DEBUGGING IVAS_QUATERNION *quat = &latest_pi[IVAS_PI_SCENE_ORIENTATION].data.scene.orientation; fprintf( stdout, "PI_SCENE_ORIENTATION : %f, %f, %f, %f\n", quat->w, quat->x, quat->y, quat->z ); #endif error = feedSinglePIorientation( hIvasDec, &latest_pi[IVAS_PI_SCENE_ORIENTATION].data.scene.orientation ); if ( error != IVAS_ERR_OK ) { return error; } } if ( has_pi[IVAS_PI_DEVICE_ORIENTATION_COMPENSATED] ) { #ifdef DEBUGGING IVAS_QUATERNION *quat = &latest_pi[IVAS_PI_DEVICE_ORIENTATION_COMPENSATED].data.deviceCompensated.orientation; fprintf( stdout, "PI_DEVICE_ORIENTATION : %f, %f, %f, %f\n", quat->w, quat->x, quat->y, quat->z ); #endif error = feedSinglePIorientation( hIvasDec, &latest_pi[IVAS_PI_DEVICE_ORIENTATION_COMPENSATED].data.deviceCompensated.orientation ); if ( error != IVAS_ERR_OK ) { return error; } } if ( has_pi[IVAS_PI_ACOUSTIC_ENVIRONMENT] ) { #ifdef DEBUGGING fprintf( stdout, "PI_ACOUSTIC_ENVIRONMENT : AEID : %d\n", latest_pi[IVAS_PI_ACOUSTIC_ENVIRONMENT].data.acousticEnv.aeid ); #endif error = feedAcousticEnvPI( hIvasDec, latest_pi[IVAS_PI_ACOUSTIC_ENVIRONMENT].data.acousticEnv ); if ( error != IVAS_ERR_OK ) { return error; } } if ( has_pi[IVAS_PI_DIEGETIC_TYPE] ) { #ifdef DEBUGGING fprintf( stdout, "PI_DIEGETIC_TYPE : %d, %d, %d, %d, %d\n", latest_pi[IVAS_PI_DIEGETIC_TYPE].data.digeticIndicator.isDiegetic[0], latest_pi[IVAS_PI_DIEGETIC_TYPE].data.digeticIndicator.isDiegetic[1], latest_pi[IVAS_PI_DIEGETIC_TYPE].data.digeticIndicator.isDiegetic[2], latest_pi[IVAS_PI_DIEGETIC_TYPE].data.digeticIndicator.isDiegetic[3], latest_pi[IVAS_PI_DIEGETIC_TYPE].data.digeticIndicator.isDiegetic[4] ); #endif setDiegeticInputPI( hIvasDec->st_ivas, latest_pi[IVAS_PI_DIEGETIC_TYPE].data.digeticIndicator.isDiegetic ); } #endif if ( has_pi[IVAS_PI_ISM_GAIN] ) { #ifdef DEBUGGING IVAS_PIDATA_ISM_GAIN *g = &latest_pi[IVAS_PI_ISM_GAIN].data.ismGain; int16_t n; fprintf( stdout, "PI_ISM_GAIN :" ); for ( n = 0; n < g->numObjects; n++ ) { fprintf( stdout, " %d dB", g->dB[n] ); } fprintf( stdout, "\n" ); #endif feedISMGainPI( hIvasDec, &latest_pi[IVAS_PI_ISM_GAIN].data.ismGain ); } if ( has_pi[IVAS_PI_ISM_ORIENTATION] ) { #ifdef DEBUGGING IVAS_PIDATA_ISM_ORIENTATION *ori = &latest_pi[IVAS_PI_ISM_ORIENTATION].data.ismOrientation; int16_t n; fprintf( stdout, "PI_ISM_ORIENTATION :" ); for ( n = 0; n < ori->numObjects; n++ ) { fprintf( stdout, " (w=%f, x=%f, y=%f, z=%f)", ori->orientation[n].w, ori->orientation[n].x, ori->orientation[n].y, ori->orientation[n].z ); } fprintf( stdout, "\n" ); #endif feedISMOrientationPI( hIvasDec, &latest_pi[IVAS_PI_ISM_ORIENTATION].data.ismOrientation ); } if ( has_pi[IVAS_PI_ISM_POSITION] ) { #ifdef DEBUGGING IVAS_PIDATA_ISM_POSITION *pos = &latest_pi[IVAS_PI_ISM_POSITION].data.ismPosition; int16_t n; fprintf( stdout, "PI_ISM_POSITION :" ); for ( n = 0; n < pos->numObjects; n++ ) { fprintf( stdout, " (x=%f, y=%f, z=%f)", pos->position[n].x, pos->position[n].y, pos->position[n].z ); } fprintf( stdout, "\n" ); #endif feedISMPositionPI( hIvasDec, &latest_pi[IVAS_PI_ISM_POSITION].data.ismPosition ); } if ( has_pi[IVAS_PI_ISM_DISTANCE_ATTENUATION] ) { #ifdef DEBUGGING IVAS_PIDATA_ISM_ATTENUATION *att = &latest_pi[IVAS_PI_ISM_DISTANCE_ATTENUATION].data.ismAttenuation; int16_t n; fprintf( stdout, "PI_ISM_DISTANCE_ATTENUATION :" ); for ( n = 0; n < att->numObjects; n++ ) { fprintf( stdout, " (ref=%f, max=%f, roll=%f)", att->distAtten[n].ref_dist, att->distAtten[n].max_dist, att->distAtten[n].roll ); } fprintf( stdout, "\n" ); #endif feedISMDistanceAttenuationPI( hIvasDec, &latest_pi[IVAS_PI_ISM_DISTANCE_ATTENUATION].data.ismAttenuation ); } if ( has_pi[IVAS_PI_ISM_DIRECTIVITY] ) { #ifdef DEBUGGING IVAS_PIDATA_ISM_DIRECTIVITY *dir = &latest_pi[IVAS_PI_ISM_DIRECTIVITY].data.ismDirectivity; int16_t n; fprintf( stdout, "PI_ISM_DIRECTIVITY :" ); for ( n = 0; n < dir->numObjects; n++ ) { fprintf( stdout, " (inner=%d, outer=%d, att=%f dB)", dir->directivity[n].innerConeAngle, dir->directivity[n].outerConeAngle, dir->directivity[n].outerAttenuationdB ); } fprintf( stdout, "\n" ); #endif feedISMDirectivityPI( hIvasDec, &latest_pi[IVAS_PI_ISM_DIRECTIVITY].data.ismDirectivity ); } return IVAS_ERR_OK; } #endif /*---------------------------------------------------------------------* * IVAS_DEC_FeedPiDataToDecoder( ) * Loading @@ -5834,14 +6189,48 @@ ivas_error IVAS_DEC_FeedPiDataToDecoder( ) { uint32_t i; #ifndef FIX_FLOAT_1584_RTP_SYNC_PI Decoder_Struct *st_ivas; ivas_error error = IVAS_ERR_OK; #endif if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } #ifdef FIX_FLOAT_1584_RTP_SYNC_PI /* Buffer PI data for consumption together with corresponding audio frame from JBM */ for ( i = 0; i < numPiData; i++ ) { uint32_t piDataType = piData->data.noPiData.piDataType; switch ( piDataType ) { case IVAS_PI_SCENE_ORIENTATION: case IVAS_PI_DEVICE_ORIENTATION_COMPENSATED: case IVAS_PI_ACOUSTIC_ENVIRONMENT: case IVAS_PI_ISM_GAIN: case IVAS_PI_ISM_ORIENTATION: case IVAS_PI_ISM_POSITION: case IVAS_PI_ISM_POSITION_COMPACT: case IVAS_PI_ISM_DISTANCE_ATTENUATION: case IVAS_PI_ISM_DIRECTIVITY: case IVAS_PI_DIEGETIC_TYPE: hIvasDec->piBuf[hIvasDec->piBufNext] = *piData; hIvasDec->piBufNext = ( hIvasDec->piBufNext + 1 ) % MAX_JBM_SLOTS; if ( hIvasDec->piBufSize < MAX_JBM_SLOTS ) { hIvasDec->piBufSize++; } break; default: break; } piData++; } #else st_ivas = hIvasDec->st_ivas; for ( i = 0; i < numPiData; i++ ) Loading Loading @@ -5893,6 +6282,24 @@ ivas_error IVAS_DEC_FeedPiDataToDecoder( } break; #ifdef FIX_FLOAT_1584_RTP_ISM_RENDERING case IVAS_PI_ISM_GAIN: case IVAS_PI_ISM_ORIENTATION: case IVAS_PI_ISM_POSITION: case IVAS_PI_ISM_POSITION_COMPACT: case IVAS_PI_ISM_DISTANCE_ATTENUATION: case IVAS_PI_ISM_DIRECTIVITY: { hIvasDec->piBuf[hIvasDec->piBufNext] = *piData; hIvasDec->piBufNext = ( hIvasDec->piBufNext + 1 ) % MAX_JBM_SLOTS; if ( hIvasDec->piBufSize < MAX_JBM_SLOTS ) { hIvasDec->piBufSize++; } } break; #endif default: { /* NOT HANDLED PI DATA - DO NOTHING */ Loading @@ -5907,6 +6314,7 @@ ivas_error IVAS_DEC_FeedPiDataToDecoder( piData++; } #endif return IVAS_ERR_OK; } Loading
lib_com/options.h +5 −0 Original line number Diff line number Diff line Loading @@ -184,6 +184,11 @@ #define FIX_FMSW_DEC_2 /* float issue 1575: fix crash for format switching when bitsream starts with EVS */ #define FIX_FLOAT_1578_OMASA_REND_SPIKES /* Nokia: Float issue 1578: Fix spikes and collapsed perception in OMASA/MASA rendering to FOA/HOA */ #define FIX_FLOAT_1584_RTP_ISM_RENDERING /* Eri: Float issue 1584: Add missing rendering configuration based on ISM PI data */ #ifdef FIX_FLOAT_1584_RTP_ISM_RENDERING #define FIX_FLOAT_1584_RTP_SYNC_PI /* Eri: Float issue 1584: Sync existing PI data with audio data */ #endif /* ##################### End NON-BE switches ########################### */ /* ################## End MAINTENANCE switches ######################### */ Loading
lib_dec/lib_dec.c +409 −1 Original line number Diff line number Diff line Loading @@ -97,6 +97,17 @@ struct IVAS_DEC bool needNewFrame; bool hasBeenFedFrame; bool updateOrientation; #ifdef FIX_FLOAT_1584_RTP_ISM_RENDERING bool receivedISMGainPI; bool receivedISMOrientationPI; bool receivedISMPositionPI; bool receivedISMDistanceAttenuationPI; bool receivedISMDirectivityPI; IVAS_PIDATA_TS piBuf[MAX_JBM_SLOTS]; int16_t piBufSize; int16_t piBufNext; uint32_t audioTs; #endif uint16_t nSamplesAvailableNext; int16_t nTransportChannelsOld; int16_t amrwb_rfc4867_flag; /* MIME from rfc4867 is used */ Loading Loading @@ -136,6 +147,14 @@ static int16_t get_render_frame_size_ms( const IVAS_RENDER_NUM_SUBFR render_num_ static int16_t get_render_frame_size_samples( const DECODER_CONFIG_HANDLE hDecoderConfig ); static int16_t ivas_dec_split_rend_cldfb_in( const RENDERER_TYPE renderer_type ); static void update_voip_rendered20ms( IVAS_DEC_HANDLE hIvasDec, const int16_t nSamplesRendered ); #ifdef FIX_FLOAT_1584_RTP_ISM_RENDERING static ivas_error applyPiData( IVAS_DEC_HANDLE hIvasDec, const uint32_t audioTs ); static void feedISMGainPI( IVAS_DEC_HANDLE hIvasDec, const IVAS_PIDATA_ISM_GAIN *gain ); static void feedISMOrientationPI( IVAS_DEC_HANDLE hIvasDec, const IVAS_PIDATA_ISM_ORIENTATION *ori ); static void feedISMPositionPI( IVAS_DEC_HANDLE hIvasDec, const IVAS_PIDATA_ISM_POSITION *pos ); static void feedISMDistanceAttenuationPI( IVAS_DEC_HANDLE hIvasDec, const IVAS_PIDATA_ISM_ATTENUATION *att ); static void feedISMDirectivityPI( IVAS_DEC_HANDLE hIvasDec, const IVAS_PIDATA_ISM_DIRECTIVITY *dir ); #endif #ifdef FIX_FMSW_DEC Loading Loading @@ -257,6 +276,16 @@ ivas_error IVAS_DEC_Open( hIvasDec->hasDecodedFirstGoodFrame = false; hIvasDec->isInitialized = false; hIvasDec->updateOrientation = false; #ifdef FIX_FLOAT_1584_RTP_ISM_RENDERING hIvasDec->receivedISMGainPI = false; hIvasDec->receivedISMOrientationPI = false; hIvasDec->receivedISMPositionPI = false; hIvasDec->receivedISMDistanceAttenuationPI = false; hIvasDec->receivedISMDirectivityPI = false; hIvasDec->piBufSize = 0; hIvasDec->piBufNext = 0; hIvasDec->audioTs = 0; #endif hIvasDec->flushbuffer = NULL; hIvasDec->pcmType = IVAS_DEC_PCM_INVALID; hIvasDec->nSamplesFlushed = 0; Loading Loading @@ -1290,6 +1319,11 @@ ivas_error IVAS_DEC_GetSamplesDecoder( uint8_t nTransportChannels; int16_t nResidualSamples, nSamplesTcsScaled; bool isInitialized_voip; #ifdef FIX_FLOAT_1584_RTP_ISM_RENDERING int16_t obj; ISM_METADATA_HANDLE *hIsmMetaData; PARAM_ISM_DEC_HANDLE hParamIsmDec; #endif if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { Loading Loading @@ -1402,6 +1436,14 @@ ivas_error IVAS_DEC_GetSamplesDecoder( hIvasDec->hasBeenPreparedRendering = false; #ifdef FIX_FLOAT_1584_RTP_ISM_RENDERING /* Apply PI data */ if ( ( error = applyPiData( hIvasDec, hIvasDec->audioTs ) ) != IVAS_ERR_OK ) { return error; } #endif /*-----------------------------------------------------------------* * Set editable metadata *-----------------------------------------------------------------*/ Loading @@ -1412,6 +1454,27 @@ ivas_error IVAS_DEC_GetSamplesDecoder( { if ( st_ivas->ism_mode == ISM_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { #ifdef FIX_FLOAT_1584_RTP_ISM_RENDERING hIsmMetaData = st_ivas->hIsmMetaData; for ( obj = 0; obj < st_ivas->nchan_ism; obj++ ) { if ( !hIvasDec->receivedISMPositionPI ) { hIsmMetaData[obj]->edited_azimuth = hIsmMetaData[obj]->azimuth; hIsmMetaData[obj]->edited_elevation = hIsmMetaData[obj]->elevation; hIsmMetaData[obj]->edited_radius = hIsmMetaData[obj]->radius; } if ( !hIvasDec->receivedISMOrientationPI ) { hIsmMetaData[obj]->edited_yaw = hIsmMetaData[obj]->yaw; hIsmMetaData[obj]->edited_pitch = hIsmMetaData[obj]->pitch; } if ( !hIvasDec->receivedISMGainPI ) { hIsmMetaData[obj]->edited_gain = 1.0f; } } #else int16_t obj; ISM_METADATA_HANDLE *hIsmMetaData = st_ivas->hIsmMetaData; for ( obj = 0; obj < st_ivas->nchan_ism; obj++ ) Loading @@ -1423,7 +1486,7 @@ ivas_error IVAS_DEC_GetSamplesDecoder( hIsmMetaData[obj]->edited_radius = hIsmMetaData[obj]->radius; hIsmMetaData[obj]->edited_gain = 1.0f; } #endif if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { st_ivas->hSbaIsmData->gain_bed = 1.0f; Loading @@ -1436,8 +1499,12 @@ ivas_error IVAS_DEC_GetSamplesDecoder( { if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { #ifdef FIX_FLOAT_1584_RTP_ISM_RENDERING hParamIsmDec = st_ivas->hParamIsmDec; #else int16_t obj = 0; PARAM_ISM_DEC_HANDLE hParamIsmDec = st_ivas->hParamIsmDec; #endif for ( obj = 0; obj < st_ivas->nchan_ism; obj++ ) { hParamIsmDec->edited_azimuth_values[obj] = hParamIsmDec->azimuth_values[obj]; Loading Loading @@ -4107,6 +4174,9 @@ static ivas_error ivas_dec_voip_get_samples_common( } *bitstreamReadDone = true; #ifdef FIX_FLOAT_1584_RTP_ISM_RENDERING hIvasDec->audioTs = dataUnit->timeStamp * 16; #endif } else if ( hIvasDec->hasDecodedFirstGoodFrame ) { Loading Loading @@ -5821,6 +5891,291 @@ static void setDiegeticInputPI( } #ifdef FIX_FLOAT_1584_RTP_ISM_RENDERING static void feedISMGainPI( IVAS_DEC_HANDLE hIvasDec, const IVAS_PIDATA_ISM_GAIN *gain ) { int16_t obj, pi_idx; int8_t dB; ISM_METADATA_HANDLE *hIsmMetaData = hIvasDec->st_ivas->hIsmMetaData; for ( obj = 0; obj < hIvasDec->st_ivas->nchan_ism; obj++ ) { pi_idx = min( obj, gain->numObjects - 1 ); dB = gain->dB[pi_idx]; if ( dB == -128 ) { hIsmMetaData[obj]->edited_gain = 0.0f; } else { hIsmMetaData[obj]->edited_gain = powf( 10.0f, dB / 20.0f ); } } hIvasDec->receivedISMGainPI = true; } static void feedISMOrientationPI( IVAS_DEC_HANDLE hIvasDec, const IVAS_PIDATA_ISM_ORIENTATION *ori ) { int16_t obj, pi_idx; float yaw, pitch, roll; ISM_METADATA_HANDLE *hIsmMetaData = hIvasDec->st_ivas->hIsmMetaData; for ( obj = 0; obj < hIvasDec->st_ivas->nchan_ism; obj++ ) { pi_idx = min( obj, ori->numObjects - 1 ); Quat2EulerDegree( ori->orientation[pi_idx], &yaw, &pitch, &roll ); hIsmMetaData[obj]->edited_yaw = yaw; hIsmMetaData[obj]->edited_pitch = pitch; } hIvasDec->receivedISMOrientationPI = true; } static void feedISMPositionPI( IVAS_DEC_HANDLE hIvasDec, const IVAS_PIDATA_ISM_POSITION *pos ) { int16_t obj, pi_idx; float x, y, z, xy; ISM_METADATA_HANDLE *hIsmMetaData = hIvasDec->st_ivas->hIsmMetaData; for ( obj = 0; obj < hIvasDec->st_ivas->nchan_ism; obj++ ) { pi_idx = min( obj, pos->numObjects - 1 ); x = pos->position[pi_idx].x; y = pos->position[pi_idx].y; z = pos->position[pi_idx].z; xy = x * x + y * y; hIsmMetaData[obj]->edited_radius = sqrtf( xy + z * z ); hIsmMetaData[obj]->edited_azimuth = atan2f( y, x ) * _180_OVER_PI; hIsmMetaData[obj]->edited_elevation = atan2f( z, sqrtf( xy ) ) * _180_OVER_PI; } hIvasDec->receivedISMPositionPI = true; } static void feedISMDistanceAttenuationPI( IVAS_DEC_HANDLE hIvasDec, const IVAS_PIDATA_ISM_ATTENUATION *att ) { int16_t obj, pi_idx; TDREND_DistAtten_t new_att; if ( hIvasDec->st_ivas->hBinRendererTd == NULL ) { return; } for ( obj = 0; obj < hIvasDec->st_ivas->nchan_ism; obj++ ) { pi_idx = min( obj, att->numObjects - 1 ); new_att.DistAttenModel = TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED; new_att.RefDist = att->distAtten[pi_idx].ref_dist; new_att.MaxDist = att->distAtten[pi_idx].max_dist; new_att.RollOffFactor = att->distAtten[pi_idx].roll; TDREND_MIX_SRC_SetDistAtten( hIvasDec->st_ivas->hBinRendererTd, obj, &new_att ); } hIvasDec->receivedISMDistanceAttenuationPI = true; } static void feedISMDirectivityPI( IVAS_DEC_HANDLE hIvasDec, const IVAS_PIDATA_ISM_DIRECTIVITY *dir ) { int16_t obj, pi_idx; TDREND_DirAtten_t new_dir; if ( hIvasDec->st_ivas->hBinRendererTd == NULL ) { return; } for ( obj = 0; obj < hIvasDec->st_ivas->nchan_ism; obj++ ) { pi_idx = min( obj, dir->numObjects - 1 ); new_dir.ConeInnerAngle = dir->directivity[pi_idx].innerConeAngle; new_dir.ConeOuterAngle = dir->directivity[pi_idx].outerConeAngle; new_dir.ConeOuterGain = powf( 10.0f, dir->directivity[pi_idx].outerAttenuationdB / 20.0f ); TDREND_MIX_SRC_SetDirAtten( hIvasDec->st_ivas->hBinRendererTd, obj, &new_dir ); } hIvasDec->receivedISMDirectivityPI = true; } static ivas_error applyPiData( IVAS_DEC_HANDLE hIvasDec, const uint32_t audioTs ) { int16_t i, k, buf_start, buf_size, idx, has_pi[IVAS_PI_MAX_ID]; IVAS_PIDATA_TS *pi_buf, latest_pi[IVAS_PI_MAX_ID]; uint32_t type; #ifdef FIX_FLOAT_1584_RTP_SYNC_PI ivas_error error; #endif if ( hIvasDec->piBufSize == 0 ) { return IVAS_ERR_OK; } buf_size = hIvasDec->piBufSize; buf_start = ( hIvasDec->piBufNext - buf_size + MAX_JBM_SLOTS ) % MAX_JBM_SLOTS; for ( i = 0; i < IVAS_PI_MAX_ID; i++ ) { has_pi[i] = 0; } /* Find latest PI data in buffer */ for ( i = 0; i < buf_size; i++ ) { idx = ( buf_start + i ) % MAX_JBM_SLOTS; pi_buf = &hIvasDec->piBuf[idx]; /* Find latest among preceeding PI data in buffer */ if ( pi_buf->timestamp <= audioTs ) { type = pi_buf->data.noPiData.piDataType; /* Treat IVAS_PI_ISM_POSITION_COMPACT as IVAS_PI_ISM_POSITION */ if ( type == IVAS_PI_ISM_POSITION_COMPACT ) { type = IVAS_PI_ISM_POSITION; } if ( type < IVAS_PI_MAX_ID && ( !has_pi[type] || pi_buf->timestamp >= latest_pi[type].timestamp ) ) { latest_pi[type] = *pi_buf; has_pi[type] = 1; } } } /* Keep only newer PI data in buffer */ k = 0; for ( i = 0; i < buf_size; i++ ) { idx = ( buf_start + i ) % MAX_JBM_SLOTS; if ( hIvasDec->piBuf[idx].timestamp > audioTs ) { hIvasDec->piBuf[k] = hIvasDec->piBuf[idx]; k++; } } hIvasDec->piBufSize = k; hIvasDec->piBufNext = k; #ifdef FIX_FLOAT_1584_RTP_SYNC_PI if ( has_pi[IVAS_PI_SCENE_ORIENTATION] ) { #ifdef DEBUGGING IVAS_QUATERNION *quat = &latest_pi[IVAS_PI_SCENE_ORIENTATION].data.scene.orientation; fprintf( stdout, "PI_SCENE_ORIENTATION : %f, %f, %f, %f\n", quat->w, quat->x, quat->y, quat->z ); #endif error = feedSinglePIorientation( hIvasDec, &latest_pi[IVAS_PI_SCENE_ORIENTATION].data.scene.orientation ); if ( error != IVAS_ERR_OK ) { return error; } } if ( has_pi[IVAS_PI_DEVICE_ORIENTATION_COMPENSATED] ) { #ifdef DEBUGGING IVAS_QUATERNION *quat = &latest_pi[IVAS_PI_DEVICE_ORIENTATION_COMPENSATED].data.deviceCompensated.orientation; fprintf( stdout, "PI_DEVICE_ORIENTATION : %f, %f, %f, %f\n", quat->w, quat->x, quat->y, quat->z ); #endif error = feedSinglePIorientation( hIvasDec, &latest_pi[IVAS_PI_DEVICE_ORIENTATION_COMPENSATED].data.deviceCompensated.orientation ); if ( error != IVAS_ERR_OK ) { return error; } } if ( has_pi[IVAS_PI_ACOUSTIC_ENVIRONMENT] ) { #ifdef DEBUGGING fprintf( stdout, "PI_ACOUSTIC_ENVIRONMENT : AEID : %d\n", latest_pi[IVAS_PI_ACOUSTIC_ENVIRONMENT].data.acousticEnv.aeid ); #endif error = feedAcousticEnvPI( hIvasDec, latest_pi[IVAS_PI_ACOUSTIC_ENVIRONMENT].data.acousticEnv ); if ( error != IVAS_ERR_OK ) { return error; } } if ( has_pi[IVAS_PI_DIEGETIC_TYPE] ) { #ifdef DEBUGGING fprintf( stdout, "PI_DIEGETIC_TYPE : %d, %d, %d, %d, %d\n", latest_pi[IVAS_PI_DIEGETIC_TYPE].data.digeticIndicator.isDiegetic[0], latest_pi[IVAS_PI_DIEGETIC_TYPE].data.digeticIndicator.isDiegetic[1], latest_pi[IVAS_PI_DIEGETIC_TYPE].data.digeticIndicator.isDiegetic[2], latest_pi[IVAS_PI_DIEGETIC_TYPE].data.digeticIndicator.isDiegetic[3], latest_pi[IVAS_PI_DIEGETIC_TYPE].data.digeticIndicator.isDiegetic[4] ); #endif setDiegeticInputPI( hIvasDec->st_ivas, latest_pi[IVAS_PI_DIEGETIC_TYPE].data.digeticIndicator.isDiegetic ); } #endif if ( has_pi[IVAS_PI_ISM_GAIN] ) { #ifdef DEBUGGING IVAS_PIDATA_ISM_GAIN *g = &latest_pi[IVAS_PI_ISM_GAIN].data.ismGain; int16_t n; fprintf( stdout, "PI_ISM_GAIN :" ); for ( n = 0; n < g->numObjects; n++ ) { fprintf( stdout, " %d dB", g->dB[n] ); } fprintf( stdout, "\n" ); #endif feedISMGainPI( hIvasDec, &latest_pi[IVAS_PI_ISM_GAIN].data.ismGain ); } if ( has_pi[IVAS_PI_ISM_ORIENTATION] ) { #ifdef DEBUGGING IVAS_PIDATA_ISM_ORIENTATION *ori = &latest_pi[IVAS_PI_ISM_ORIENTATION].data.ismOrientation; int16_t n; fprintf( stdout, "PI_ISM_ORIENTATION :" ); for ( n = 0; n < ori->numObjects; n++ ) { fprintf( stdout, " (w=%f, x=%f, y=%f, z=%f)", ori->orientation[n].w, ori->orientation[n].x, ori->orientation[n].y, ori->orientation[n].z ); } fprintf( stdout, "\n" ); #endif feedISMOrientationPI( hIvasDec, &latest_pi[IVAS_PI_ISM_ORIENTATION].data.ismOrientation ); } if ( has_pi[IVAS_PI_ISM_POSITION] ) { #ifdef DEBUGGING IVAS_PIDATA_ISM_POSITION *pos = &latest_pi[IVAS_PI_ISM_POSITION].data.ismPosition; int16_t n; fprintf( stdout, "PI_ISM_POSITION :" ); for ( n = 0; n < pos->numObjects; n++ ) { fprintf( stdout, " (x=%f, y=%f, z=%f)", pos->position[n].x, pos->position[n].y, pos->position[n].z ); } fprintf( stdout, "\n" ); #endif feedISMPositionPI( hIvasDec, &latest_pi[IVAS_PI_ISM_POSITION].data.ismPosition ); } if ( has_pi[IVAS_PI_ISM_DISTANCE_ATTENUATION] ) { #ifdef DEBUGGING IVAS_PIDATA_ISM_ATTENUATION *att = &latest_pi[IVAS_PI_ISM_DISTANCE_ATTENUATION].data.ismAttenuation; int16_t n; fprintf( stdout, "PI_ISM_DISTANCE_ATTENUATION :" ); for ( n = 0; n < att->numObjects; n++ ) { fprintf( stdout, " (ref=%f, max=%f, roll=%f)", att->distAtten[n].ref_dist, att->distAtten[n].max_dist, att->distAtten[n].roll ); } fprintf( stdout, "\n" ); #endif feedISMDistanceAttenuationPI( hIvasDec, &latest_pi[IVAS_PI_ISM_DISTANCE_ATTENUATION].data.ismAttenuation ); } if ( has_pi[IVAS_PI_ISM_DIRECTIVITY] ) { #ifdef DEBUGGING IVAS_PIDATA_ISM_DIRECTIVITY *dir = &latest_pi[IVAS_PI_ISM_DIRECTIVITY].data.ismDirectivity; int16_t n; fprintf( stdout, "PI_ISM_DIRECTIVITY :" ); for ( n = 0; n < dir->numObjects; n++ ) { fprintf( stdout, " (inner=%d, outer=%d, att=%f dB)", dir->directivity[n].innerConeAngle, dir->directivity[n].outerConeAngle, dir->directivity[n].outerAttenuationdB ); } fprintf( stdout, "\n" ); #endif feedISMDirectivityPI( hIvasDec, &latest_pi[IVAS_PI_ISM_DIRECTIVITY].data.ismDirectivity ); } return IVAS_ERR_OK; } #endif /*---------------------------------------------------------------------* * IVAS_DEC_FeedPiDataToDecoder( ) * Loading @@ -5834,14 +6189,48 @@ ivas_error IVAS_DEC_FeedPiDataToDecoder( ) { uint32_t i; #ifndef FIX_FLOAT_1584_RTP_SYNC_PI Decoder_Struct *st_ivas; ivas_error error = IVAS_ERR_OK; #endif if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } #ifdef FIX_FLOAT_1584_RTP_SYNC_PI /* Buffer PI data for consumption together with corresponding audio frame from JBM */ for ( i = 0; i < numPiData; i++ ) { uint32_t piDataType = piData->data.noPiData.piDataType; switch ( piDataType ) { case IVAS_PI_SCENE_ORIENTATION: case IVAS_PI_DEVICE_ORIENTATION_COMPENSATED: case IVAS_PI_ACOUSTIC_ENVIRONMENT: case IVAS_PI_ISM_GAIN: case IVAS_PI_ISM_ORIENTATION: case IVAS_PI_ISM_POSITION: case IVAS_PI_ISM_POSITION_COMPACT: case IVAS_PI_ISM_DISTANCE_ATTENUATION: case IVAS_PI_ISM_DIRECTIVITY: case IVAS_PI_DIEGETIC_TYPE: hIvasDec->piBuf[hIvasDec->piBufNext] = *piData; hIvasDec->piBufNext = ( hIvasDec->piBufNext + 1 ) % MAX_JBM_SLOTS; if ( hIvasDec->piBufSize < MAX_JBM_SLOTS ) { hIvasDec->piBufSize++; } break; default: break; } piData++; } #else st_ivas = hIvasDec->st_ivas; for ( i = 0; i < numPiData; i++ ) Loading Loading @@ -5893,6 +6282,24 @@ ivas_error IVAS_DEC_FeedPiDataToDecoder( } break; #ifdef FIX_FLOAT_1584_RTP_ISM_RENDERING case IVAS_PI_ISM_GAIN: case IVAS_PI_ISM_ORIENTATION: case IVAS_PI_ISM_POSITION: case IVAS_PI_ISM_POSITION_COMPACT: case IVAS_PI_ISM_DISTANCE_ATTENUATION: case IVAS_PI_ISM_DIRECTIVITY: { hIvasDec->piBuf[hIvasDec->piBufNext] = *piData; hIvasDec->piBufNext = ( hIvasDec->piBufNext + 1 ) % MAX_JBM_SLOTS; if ( hIvasDec->piBufSize < MAX_JBM_SLOTS ) { hIvasDec->piBufSize++; } } break; #endif default: { /* NOT HANDLED PI DATA - DO NOTHING */ Loading @@ -5907,6 +6314,7 @@ ivas_error IVAS_DEC_FeedPiDataToDecoder( piData++; } #endif return IVAS_ERR_OK; }