Loading lib_com/ivas_prot.h +9 −0 Original line number Diff line number Diff line Loading @@ -4673,6 +4673,15 @@ void ivas_ism_render( const int16_t output_frame /* i : output frame length per channel */ ); #ifdef FIX_REND_ISM_STEREO_PANNING void ivas_ism_get_stereo_gains( const float azimuth, /* i : object azimuth */ const float elevation, /* i : object elevation */ float *left_gain, /* o : left channel gain */ float *right_gain /* o : right channel gain */ ); #endif void ivas_mc2sba( IVAS_OUTPUT_SETUP hIntSetup, /* i : Format of decoder output */ float buffer_td[][L_FRAME48k], /* i/o: MC signals (on input) and the HOA3 (on output) */ Loading lib_com/options.h +1 −0 Original line number Diff line number Diff line Loading @@ -181,6 +181,7 @@ #define FIX_REND_ISM_XFADE /* Issue 193: Crossfade inconsistencies in ISM between decoder and external renderer */ #define FIX_REND_ISM_POS_ROUNDING /* Issue 193: (TEMPORARY! Pending fix for #215) Align rounding of ISM position data in external renderer */ #define FIX_REND_ISM_STEREO_PANNING /* Issue 193: Use tangent panning for ISM to stereo in external renderer */ /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ Loading lib_dec/ivas_ism_renderer.c +48 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,12 @@ void ivas_ism_render( { if ( st_ivas->intern_config == AUDIO_CONFIG_STEREO ) { #ifdef FIX_REND_ISM_STEREO_PANNING ivas_ism_get_stereo_gains( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &gains[i][0], &gains[i][1] ); #else float aziRad, eleRad; float y, mappedX, aziRadMapped, A, A2, A3; const float LsAngleRad = 30.0f * PI_OVER_180; Loading Loading @@ -174,6 +180,7 @@ void ivas_ism_render( gains[i][0] = sqrtf( A3 ); gains[i][1] = sqrtf( 1.0f - A3 ); } #endif } else { Loading Loading @@ -232,3 +239,44 @@ void ivas_ism_render( } return; } #ifdef FIX_REND_ISM_STEREO_PANNING void ivas_ism_get_stereo_gains( const float azimuth, /* i : object azimuth */ const float elevation, /* i : object elevation */ float *left_gain, /* o : left channel gain */ float *right_gain /* o : right channel gain */ ) { float aziRad, eleRad; float y, mappedX, aziRadMapped, A, A2, A3; const float LsAngleRad = 30.0f * PI_OVER_180; /* Convert azi and ele to an azi value of the cone of confusion */ aziRad = azimuth * PI_OVER_180; eleRad = elevation * PI_OVER_180; y = ( sinf( aziRad ) * cosf( eleRad ) ); mappedX = sqrtf( max( 0.0f, 1.0f - ( y * y ) ) ); aziRadMapped = atan2f( y, mappedX ); /* Determine the amplitude panning gains */ if ( aziRadMapped >= LsAngleRad ) { /* Left side */ *left_gain = 1.0f; *right_gain = 0.0f; } else if ( aziRadMapped <= -LsAngleRad ) { /* Right side */ *left_gain = 0.0f; *right_gain = 1.0f; } else /* Tangent panning law */ { A = tanf( aziRadMapped ) / tanf( LsAngleRad ); A2 = ( A - 1.0f ) / max( 0.001f, A + 1.0f ); A3 = 1.0f / ( A2 * A2 + 1.0f ); *left_gain = sqrtf( A3 ); *right_gain = sqrtf( 1.0f - A3 ); } } #endif lib_rend/lib_rend.c +35 −17 Original line number Diff line number Diff line Loading @@ -3791,6 +3791,24 @@ static ivas_error renderIsmToMc( wmops_sub_start( "renderIsmToMc" ); /* TODO(sgi): Possible optimization: less processing needed if position didn't change */ #ifdef FIX_REND_ISM_STEREO_PANNING if ( *ismInput->base.ctx.pOutConfig == IVAS_REND_AUDIO_CONFIG_STEREO ) { set_zero( currentPanGains, 16 ); ivas_ism_get_stereo_gains( ismInput->currentPos.azimuth, ismInput->currentPos.elevation, ¤tPanGains[0], ¤tPanGains[1] ); set_zero( previousPanGains, 16 ); ivas_ism_get_stereo_gains( ismInput->previousPos.azimuth, ismInput->previousPos.elevation, &previousPanGains[0], &previousPanGains[1] ); } else #endif { #ifdef FIX_REND_ISM_POS_ROUNDING // TODO tmu review when #215 is resolved if ( ( error = getEfapGains( *ismInput->base.ctx.pEfapOutWrapper, Loading @@ -3815,7 +3833,7 @@ static ivas_error renderIsmToMc( { return error; } } /* Assume num channels in audio buffer to be 1. * This should have been validated in IVAS_REND_FeedInputAudio() */ renderBufferChannelLerp( ismInput->base.inputBuffer, 0, currentPanGains, previousPanGains, outAudio ); Loading tests/renderer/constants.py +6 −6 Original line number Diff line number Diff line Loading @@ -376,11 +376,12 @@ pass_snr = { "test_ism_binaural_static[ISM2-BINAURAL_ROOM]": 21, "test_ism_binaural_static[ISM3-BINAURAL_ROOM]": 21, "test_ism_binaural_static[ISM4-BINAURAL_ROOM]": 21, # Failure Reason: Casting of positions in renderer to int16_t vs. float in python # Failure Reason: Tangent law panning missing in python scripts "test_ism[ISM1-STEREO]": 50, "test_ism[ISM2-STEREO]": 54, "test_ism[ISM4-STEREO]": 55, "test_ism[ISM3-STEREO]": 51, # Failure Reason: Casting of positions in renderer to int16_t vs. float in python "test_ism[ISM1-5_1]": 43, "test_ism[ISM1-5_1_2]": 43, "test_ism[ISM1-5_1_4]": 43, Loading Loading @@ -482,11 +483,6 @@ pass_snr = { "test_ism_binaural_static_vs_decoder[ISM3-BINAURAL]": 72, "test_ism_binaural_static_vs_decoder[ISM4-BINAURAL]": 71, # TODO harmonize panning to stereo # Failure reason ISM to stereo panning is done via EFAP in the renderer and tangent law in decoder, harmonize "test_ism_vs_decoder[ISM1-STEREO]": 8, "test_ism_vs_decoder[ISM2-STEREO]": 17, "test_ism_vs_decoder[ISM3-STEREO]": 14, "test_ism_vs_decoder[ISM4-STEREO]": 14, # Failure reason: Decoder sets elevation for non-planar output layouts to 0 "test_ism_vs_decoder[ISM1-5_1]": 27, "test_ism_vs_decoder[ISM1-7_1]": 27, Loading @@ -505,24 +501,28 @@ pass_snr = { "test_ism_vs_decoder[ISM1-FOA]": 27, "test_ism_vs_decoder[ISM1-HOA2]": 27, "test_ism_vs_decoder[ISM1-HOA3]": 27, "test_ism_vs_decoder[ISM1-STEREO]": 27, "test_ism_vs_decoder[ISM2-5_1_2]": 32, "test_ism_vs_decoder[ISM2-5_1_4]": 32, "test_ism_vs_decoder[ISM2-7_1_4]": 32, "test_ism_vs_decoder[ISM2-FOA]": 32, "test_ism_vs_decoder[ISM2-HOA2]": 32, "test_ism_vs_decoder[ISM2-HOA3]": 32, "test_ism_vs_decoder[ISM2-STEREO]": 32, "test_ism_vs_decoder[ISM3-5_1_2]": 33, "test_ism_vs_decoder[ISM3-5_1_4]": 33, "test_ism_vs_decoder[ISM3-7_1_4]": 33, "test_ism_vs_decoder[ISM3-FOA]": 33, "test_ism_vs_decoder[ISM3-HOA2]": 33, "test_ism_vs_decoder[ISM3-HOA3]": 33, "test_ism_vs_decoder[ISM3-STEREO]": 33, "test_ism_vs_decoder[ISM4-5_1_2]": 31, "test_ism_vs_decoder[ISM4-5_1_4]": 31, "test_ism_vs_decoder[ISM4-7_1_4]": 31, "test_ism_vs_decoder[ISM4-FOA]": 31, "test_ism_vs_decoder[ISM4-HOA2]": 32, "test_ism_vs_decoder[ISM4-HOA3]": 31, "test_ism_vs_decoder[ISM4-STEREO]": 32, # TODO needs investigation "test_multichannel_binaural_headrotation_vs_decoder[5_1-BINAURAL-full_circle_in_15s]": 74, "test_multichannel_binaural_headrotation_vs_decoder[5_1-BINAURAL-rotate_yaw_pitch_roll1]": 74, Loading Loading
lib_com/ivas_prot.h +9 −0 Original line number Diff line number Diff line Loading @@ -4673,6 +4673,15 @@ void ivas_ism_render( const int16_t output_frame /* i : output frame length per channel */ ); #ifdef FIX_REND_ISM_STEREO_PANNING void ivas_ism_get_stereo_gains( const float azimuth, /* i : object azimuth */ const float elevation, /* i : object elevation */ float *left_gain, /* o : left channel gain */ float *right_gain /* o : right channel gain */ ); #endif void ivas_mc2sba( IVAS_OUTPUT_SETUP hIntSetup, /* i : Format of decoder output */ float buffer_td[][L_FRAME48k], /* i/o: MC signals (on input) and the HOA3 (on output) */ Loading
lib_com/options.h +1 −0 Original line number Diff line number Diff line Loading @@ -181,6 +181,7 @@ #define FIX_REND_ISM_XFADE /* Issue 193: Crossfade inconsistencies in ISM between decoder and external renderer */ #define FIX_REND_ISM_POS_ROUNDING /* Issue 193: (TEMPORARY! Pending fix for #215) Align rounding of ISM position data in external renderer */ #define FIX_REND_ISM_STEREO_PANNING /* Issue 193: Use tangent panning for ISM to stereo in external renderer */ /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ Loading
lib_dec/ivas_ism_renderer.c +48 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,12 @@ void ivas_ism_render( { if ( st_ivas->intern_config == AUDIO_CONFIG_STEREO ) { #ifdef FIX_REND_ISM_STEREO_PANNING ivas_ism_get_stereo_gains( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &gains[i][0], &gains[i][1] ); #else float aziRad, eleRad; float y, mappedX, aziRadMapped, A, A2, A3; const float LsAngleRad = 30.0f * PI_OVER_180; Loading Loading @@ -174,6 +180,7 @@ void ivas_ism_render( gains[i][0] = sqrtf( A3 ); gains[i][1] = sqrtf( 1.0f - A3 ); } #endif } else { Loading Loading @@ -232,3 +239,44 @@ void ivas_ism_render( } return; } #ifdef FIX_REND_ISM_STEREO_PANNING void ivas_ism_get_stereo_gains( const float azimuth, /* i : object azimuth */ const float elevation, /* i : object elevation */ float *left_gain, /* o : left channel gain */ float *right_gain /* o : right channel gain */ ) { float aziRad, eleRad; float y, mappedX, aziRadMapped, A, A2, A3; const float LsAngleRad = 30.0f * PI_OVER_180; /* Convert azi and ele to an azi value of the cone of confusion */ aziRad = azimuth * PI_OVER_180; eleRad = elevation * PI_OVER_180; y = ( sinf( aziRad ) * cosf( eleRad ) ); mappedX = sqrtf( max( 0.0f, 1.0f - ( y * y ) ) ); aziRadMapped = atan2f( y, mappedX ); /* Determine the amplitude panning gains */ if ( aziRadMapped >= LsAngleRad ) { /* Left side */ *left_gain = 1.0f; *right_gain = 0.0f; } else if ( aziRadMapped <= -LsAngleRad ) { /* Right side */ *left_gain = 0.0f; *right_gain = 1.0f; } else /* Tangent panning law */ { A = tanf( aziRadMapped ) / tanf( LsAngleRad ); A2 = ( A - 1.0f ) / max( 0.001f, A + 1.0f ); A3 = 1.0f / ( A2 * A2 + 1.0f ); *left_gain = sqrtf( A3 ); *right_gain = sqrtf( 1.0f - A3 ); } } #endif
lib_rend/lib_rend.c +35 −17 Original line number Diff line number Diff line Loading @@ -3791,6 +3791,24 @@ static ivas_error renderIsmToMc( wmops_sub_start( "renderIsmToMc" ); /* TODO(sgi): Possible optimization: less processing needed if position didn't change */ #ifdef FIX_REND_ISM_STEREO_PANNING if ( *ismInput->base.ctx.pOutConfig == IVAS_REND_AUDIO_CONFIG_STEREO ) { set_zero( currentPanGains, 16 ); ivas_ism_get_stereo_gains( ismInput->currentPos.azimuth, ismInput->currentPos.elevation, ¤tPanGains[0], ¤tPanGains[1] ); set_zero( previousPanGains, 16 ); ivas_ism_get_stereo_gains( ismInput->previousPos.azimuth, ismInput->previousPos.elevation, &previousPanGains[0], &previousPanGains[1] ); } else #endif { #ifdef FIX_REND_ISM_POS_ROUNDING // TODO tmu review when #215 is resolved if ( ( error = getEfapGains( *ismInput->base.ctx.pEfapOutWrapper, Loading @@ -3815,7 +3833,7 @@ static ivas_error renderIsmToMc( { return error; } } /* Assume num channels in audio buffer to be 1. * This should have been validated in IVAS_REND_FeedInputAudio() */ renderBufferChannelLerp( ismInput->base.inputBuffer, 0, currentPanGains, previousPanGains, outAudio ); Loading
tests/renderer/constants.py +6 −6 Original line number Diff line number Diff line Loading @@ -376,11 +376,12 @@ pass_snr = { "test_ism_binaural_static[ISM2-BINAURAL_ROOM]": 21, "test_ism_binaural_static[ISM3-BINAURAL_ROOM]": 21, "test_ism_binaural_static[ISM4-BINAURAL_ROOM]": 21, # Failure Reason: Casting of positions in renderer to int16_t vs. float in python # Failure Reason: Tangent law panning missing in python scripts "test_ism[ISM1-STEREO]": 50, "test_ism[ISM2-STEREO]": 54, "test_ism[ISM4-STEREO]": 55, "test_ism[ISM3-STEREO]": 51, # Failure Reason: Casting of positions in renderer to int16_t vs. float in python "test_ism[ISM1-5_1]": 43, "test_ism[ISM1-5_1_2]": 43, "test_ism[ISM1-5_1_4]": 43, Loading Loading @@ -482,11 +483,6 @@ pass_snr = { "test_ism_binaural_static_vs_decoder[ISM3-BINAURAL]": 72, "test_ism_binaural_static_vs_decoder[ISM4-BINAURAL]": 71, # TODO harmonize panning to stereo # Failure reason ISM to stereo panning is done via EFAP in the renderer and tangent law in decoder, harmonize "test_ism_vs_decoder[ISM1-STEREO]": 8, "test_ism_vs_decoder[ISM2-STEREO]": 17, "test_ism_vs_decoder[ISM3-STEREO]": 14, "test_ism_vs_decoder[ISM4-STEREO]": 14, # Failure reason: Decoder sets elevation for non-planar output layouts to 0 "test_ism_vs_decoder[ISM1-5_1]": 27, "test_ism_vs_decoder[ISM1-7_1]": 27, Loading @@ -505,24 +501,28 @@ pass_snr = { "test_ism_vs_decoder[ISM1-FOA]": 27, "test_ism_vs_decoder[ISM1-HOA2]": 27, "test_ism_vs_decoder[ISM1-HOA3]": 27, "test_ism_vs_decoder[ISM1-STEREO]": 27, "test_ism_vs_decoder[ISM2-5_1_2]": 32, "test_ism_vs_decoder[ISM2-5_1_4]": 32, "test_ism_vs_decoder[ISM2-7_1_4]": 32, "test_ism_vs_decoder[ISM2-FOA]": 32, "test_ism_vs_decoder[ISM2-HOA2]": 32, "test_ism_vs_decoder[ISM2-HOA3]": 32, "test_ism_vs_decoder[ISM2-STEREO]": 32, "test_ism_vs_decoder[ISM3-5_1_2]": 33, "test_ism_vs_decoder[ISM3-5_1_4]": 33, "test_ism_vs_decoder[ISM3-7_1_4]": 33, "test_ism_vs_decoder[ISM3-FOA]": 33, "test_ism_vs_decoder[ISM3-HOA2]": 33, "test_ism_vs_decoder[ISM3-HOA3]": 33, "test_ism_vs_decoder[ISM3-STEREO]": 33, "test_ism_vs_decoder[ISM4-5_1_2]": 31, "test_ism_vs_decoder[ISM4-5_1_4]": 31, "test_ism_vs_decoder[ISM4-7_1_4]": 31, "test_ism_vs_decoder[ISM4-FOA]": 31, "test_ism_vs_decoder[ISM4-HOA2]": 32, "test_ism_vs_decoder[ISM4-HOA3]": 31, "test_ism_vs_decoder[ISM4-STEREO]": 32, # TODO needs investigation "test_multichannel_binaural_headrotation_vs_decoder[5_1-BINAURAL-full_circle_in_15s]": 74, "test_multichannel_binaural_headrotation_vs_decoder[5_1-BINAURAL-rotate_yaw_pitch_roll1]": 74, Loading