diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index ad74f9136cad5e6544a2cdf92084b31297cd02d9..3af0a01d92fc16b549e5f71b6994e9768f20a1e9 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -231,6 +231,18 @@ typedef enum _ivas_binaural_renderer_type IVAS_BIN_RENDERER_TYPE_DEFAULT, } IVAS_BIN_RENDERER_TYPE; +#ifdef FIX_1419_SPATIAL_UMX + +typedef struct _IVAS_MS_UMX_CONF_DATA +{ + int16_t spatialEnabled; /* internal flag for spatial rendering */ + int16_t stereoLR; /* internal flag to use ±90 for BRIRs */ + float radius; + float azi[2]; + float ele[2]; + +} IVAS_MS_UMX_CONF_DATA, *IVAS_MS_UMX_CONF_HANDLE; +#endif /*----------------------------------------------------------------------------------* * Split rendering API constants, structures, and enums @@ -342,6 +354,9 @@ typedef struct _IVAS_RENDER_CONFIG { IVAS_ROOM_ACOUSTICS_CONFIG_DATA roomAcoustics; ISAR_SPLIT_REND_CONFIG_DATA split_rend_config; +#ifdef FIX_1419_SPATIAL_UMX + IVAS_MS_UMX_CONF_DATA mono_stereo_upmix_config; +#endif float directivity[IVAS_MAX_NUM_OBJECTS * 3]; float distAtt[3]; diff --git a/lib_com/options.h b/lib_com/options.h index 11f9b1f26ebdea14a0c6f62e9f9c7e2f110b1c31..0387b8dae8cfc5a70be012c39af93d7a200852c1 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -161,6 +161,8 @@ /*#define FIX_I4_OL_PITCH*/ /* fix open-loop pitch used for EVS core switching */ #define TMP_1342_WORKAROUND_DEC_FLUSH_BROKEN_IN_SR /* FhG: Temporary workaround for incorrect implementation of decoder flush with split rendering */ +#define FIX_1419_SPATIAL_UMX /* FhG: issue 1419: enable spatial upmix for mono/stereo; configurable via renderer config */ +#define FIX_1466_EXTREND /* FhG: issue 1466: enable rendering of mono/stereo to other formats in the external renderer */ #define NONBE_1122_KEEP_EVS_MODE_UNCHANGED /* FhG: Disables fix for issue 1122 in EVS mode to keep BE tests green. This switch should be removed once the 1122 fix is added to EVS via a CR. */ diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index a3d954ef2f3d770751f34017e087449b914f5d1f..167dd531b46e62905d40fed5110b84a7aaab48bf 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1445,12 +1445,30 @@ ivas_error ivas_init_decoder( st_ivas->hOutSetup.output_config = st_ivas->intern_config; st_ivas->hOutSetup.nchan_out_woLFE = audioCfg2channels( st_ivas->intern_config ); } +#ifdef FIX_1419_SPATIAL_UMX + + if ( st_ivas->ivas_format == MONO_FORMAT || st_ivas->ivas_format == STEREO_FORMAT ) + { + st_ivas->transport_config = ( st_ivas->ivas_format == MONO_FORMAT ) ? IVAS_AUDIO_CONFIG_MONO : IVAS_AUDIO_CONFIG_STEREO; + } +#endif /* Only initialize transport setup if it is used */ if ( st_ivas->transport_config != IVAS_AUDIO_CONFIG_INVALID ) { ivas_output_init( &( st_ivas->hTransSetup ), st_ivas->transport_config ); } +#ifdef FIX_1419_SPATIAL_UMX + + /* Override transport config values from render config */ + if ( ( st_ivas->ivas_format == MONO_FORMAT || st_ivas->ivas_format == STEREO_FORMAT ) && + st_ivas->hRenderConfig != NULL && + st_ivas->hRenderConfig->mono_stereo_upmix_config.spatialEnabled ) + { + st_ivas->hTransSetup.ls_azimuth = st_ivas->hRenderConfig->mono_stereo_upmix_config.azi; + st_ivas->hTransSetup.ls_elevation = st_ivas->hRenderConfig->mono_stereo_upmix_config.ele; + } +#endif if ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) { @@ -2310,7 +2328,13 @@ ivas_error ivas_init_decoder( } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { +#ifdef FIX_1419_SPATIAL_UMX + if ( ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation || st_ivas->hCombinedOrientationData ) && + ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM && + ( st_ivas->ivas_format == MONO_FORMAT || st_ivas->ivas_format == STEREO_FORMAT || st_ivas->ivas_format == MC_FORMAT ) ) ) +#else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM && st_ivas->ivas_format == MC_FORMAT && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation || st_ivas->hCombinedOrientationData ) ) +#endif { if ( ( error = efap_init_data( &( st_ivas->hEFAPdata ), st_ivas->hIntSetup.ls_azimuth, st_ivas->hIntSetup.ls_elevation, st_ivas->hIntSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) { @@ -3318,11 +3342,14 @@ static ivas_error doSanityChecks_IVAS( { return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified!" ); } + +#ifndef FIX_1419_SPATIAL_UMX if ( ( st_ivas->ivas_format == MONO_FORMAT || st_ivas->ivas_format == STEREO_FORMAT ) && ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) { return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified!" ); } +#endif if ( ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) && output_Fs != 48000 ) { diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 4f0acd6364146159ca3e5610cdc56ffe963bf89d..67a204fe4665322fbddde9b95040606b452def9f 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -958,6 +958,56 @@ ivas_error ivas_jbm_dec_render( ivas_stereo2sba( p_output, p_output, *nSamplesRendered ); #endif } +#ifdef FIX_1419_SPATIAL_UMX + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) + { + /* Rendering for BINAURAL, BINAURAL_ROOM_REVERB and split rendering */ + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) + { + /* Rendering for BINAURAL_ROOM_IR */ + if ( st_ivas->hDecoderConfig->Opt_Headrotation && st_ivas->ivas_format == MONO_FORMAT ) + { + /* Since rotation is performed on 7.1+4, we treat mono as 7.1+4 with other channels zero + * so move the mono content in index 0 to index 2 (center channel) */ + float *tmp; + tmp = p_output[2]; + p_output[2] = p_output[0]; + p_output[0] = tmp; + } + + if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, + st_ivas->intern_config, + st_ivas->hOutSetup.output_config, + st_ivas->hDecoderConfig, + st_ivas->hCombinedOrientationData, + &st_ivas->hIntSetup, + st_ivas->hEFAPdata, + st_ivas->hTcBuffer, + p_output, + p_output, + *nSamplesRendered, + output_Fs, + 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif /* FIX_1419_SPATIAL_UMX */ } else if ( st_ivas->ivas_format == ISM_FORMAT ) { diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index ff47b1b9a77fa56f539ca737a201d2fff16f22b5..5c7808874e4b4f879fb0a9ee38dc9afd2d59bed2 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -66,8 +66,22 @@ ivas_error ivas_td_binaural_open( return IVAS_ERROR( IVAS_ERR_INTERNAL, "HRTF binary file present but not used in TD renderer" ); } +#ifdef FIX_1419_SPATIAL_UMX + return ivas_td_binaural_open_unwrap( &st_ivas->hHrtfTD, + st_ivas->hDecoderConfig->output_Fs, + num_src, + st_ivas->ivas_format, + st_ivas->transport_config, + st_ivas->hRenderConfig->directivity, + st_ivas->hRenderConfig->distAtt, + ( st_ivas->hRenderConfig != NULL ) ? &st_ivas->hRenderConfig->mono_stereo_upmix_config.radius : NULL, + st_ivas->hTransSetup, + &st_ivas->hBinRendererTd, + &st_ivas->binaural_latency_ns ); +#else return ivas_td_binaural_open_unwrap( &st_ivas->hHrtfTD, st_ivas->hDecoderConfig->output_Fs, num_src, st_ivas->ivas_format, st_ivas->transport_config, st_ivas->hRenderConfig->directivity, st_ivas->hRenderConfig->distAtt, st_ivas->hTransSetup, &st_ivas->hBinRendererTd, &st_ivas->binaural_latency_ns ); +#endif } @@ -312,6 +326,9 @@ ivas_error ivas_td_binaural_renderer_sf_splitBinaural( st_ivas->transport_config, st_ivas->hRenderConfig->directivity, st_ivas->hRenderConfig->distAtt, +#ifdef FIX_1419_SPATIAL_UMX + ( st_ivas->hRenderConfig != NULL ) ? &st_ivas->hRenderConfig->mono_stereo_upmix_config.radius : NULL, +#endif st_ivas->hTransSetup, &st_ivas->hTdRendHandles[i], &st_ivas->binaural_latency_ns ) ) != IVAS_ERR_OK ) diff --git a/lib_dec/ivas_output_config.c b/lib_dec/ivas_output_config.c index 14a56f8adf32dcb400dea893f7e5a930888d936c..8e2f46090f8d2fb03b77e9e2aeba070b696f3fa3 100644 --- a/lib_dec/ivas_output_config.c +++ b/lib_dec/ivas_output_config.c @@ -81,10 +81,51 @@ void ivas_renderer_select( if ( st_ivas->ivas_format == MONO_FORMAT ) { *renderer_type = RENDERER_NON_DIEGETIC_DOWNMIX; +#ifdef FIX_1419_SPATIAL_UMX + + if ( st_ivas->hRenderConfig->mono_stereo_upmix_config.spatialEnabled ) + { + /* spatial rendering configuration */ + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) + { + *internal_config = IVAS_AUDIO_CONFIG_MONO; + if ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) + { + *internal_config = IVAS_AUDIO_CONFIG_7_1_4; + } + + *renderer_type = RENDERER_BINAURAL_MIXER_CONV_ROOM; + } + else /* HRIR based formats and split rendering */ + { + *renderer_type = RENDERER_BINAURAL_OBJECTS_TD; + } + } +#endif } else if ( st_ivas->ivas_format == STEREO_FORMAT ) { *renderer_type = RENDERER_DISABLE; +#ifdef FIX_1419_SPATIAL_UMX + + if ( st_ivas->hRenderConfig->mono_stereo_upmix_config.spatialEnabled ) + { + /* spatial rendering configuration */ + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) + { + *internal_config = IVAS_AUDIO_CONFIG_STEREO; + if ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) + { + *internal_config = IVAS_AUDIO_CONFIG_7_1_4; + } + *renderer_type = RENDERER_BINAURAL_MIXER_CONV_ROOM; + } + else /* HRIR based formats and split rendering */ + { + *renderer_type = RENDERER_BINAURAL_OBJECTS_TD; + } + } +#endif } else if ( st_ivas->ivas_format == ISM_FORMAT ) { diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 102c73becc1115acb22c2158fed651ed52999443..3dcfca2c1c19b292c2c07d9b65bb1878908b493c 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -271,14 +271,21 @@ static ivas_error isar_set_split_rend_setup( ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ ) { - splitRendBits->bits_read = 0; - splitRendBits->bits_written = 0; - splitRendBits->buf_len = ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES; - splitRendBits->codec = ISAR_SPLIT_REND_CODEC_DEFAULT; - splitRendBits->pose_correction = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; - splitRendBits->codec_frame_size_ms = 0; - splitRendBits->isar_frame_size_ms = 0; - splitRendBits->lc3plus_highres = 0; +#ifdef FIX_1419_SPATIAL_UMX + if ( splitRendBits != NULL ) + { +#endif + splitRendBits->bits_read = 0; + splitRendBits->bits_written = 0; + splitRendBits->buf_len = ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES; + splitRendBits->codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + splitRendBits->pose_correction = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + splitRendBits->codec_frame_size_ms = 0; + splitRendBits->isar_frame_size_ms = 0; + splitRendBits->lc3plus_highres = 0; +#ifdef FIX_1419_SPATIAL_UMX + } +#endif ISAR_PRE_REND_GetMultiBinPoseData( hSplitBinConfig, &hSplitBinRend->splitrend.multiBinPoseData, ( hCombinedOrientationData != NULL ) ? hCombinedOrientationData->sr_pose_pred_axis : DEFAULT_AXIS ); @@ -474,8 +481,10 @@ ivas_error IVAS_DEC_Configure( outputConfig == IVAS_AUDIO_CONFIG_ISM2 || outputConfig == IVAS_AUDIO_CONFIG_ISM3 || outputConfig == IVAS_AUDIO_CONFIG_ISM4 || +#ifndef FIX_1419_SPATIAL_UMX outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || +#endif outputConfig == IVAS_AUDIO_CONFIG_MASA1 || outputConfig == IVAS_AUDIO_CONFIG_MASA2 ) ) { @@ -874,6 +883,21 @@ ivas_error IVAS_DEC_FeedFrame_Serial( hIvasDec->st_ivas->hDecoderConfig->ivas_total_brate = ACELP_8k00; hIvasDec->st_ivas->transport_config = IVAS_AUDIO_CONFIG_MONO; +#ifdef FIX_1419_SPATIAL_UMX + if ( hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || + hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + /* necessary to set up correct amount of memory for rendering; remaining setup happens in ivas_dec_setup_all() */ + /* Setup IVAS split rendering */ + if ( ( error = isar_set_split_rend_setup( hIvasDec->st_ivas->hSplitBinRend, + &hIvasDec->st_ivas->hRenderConfig->split_rend_config, + hIvasDec->st_ivas->hCombinedOrientationData, + NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif if ( ( error = ivas_init_decoder( hIvasDec->st_ivas ) ) != IVAS_ERR_OK ) { return error; @@ -1773,6 +1797,10 @@ ivas_error IVAS_DEC_PrepareRenderer( IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ ) { +#ifdef FIX_1419_SPATIAL_UMX + ivas_error error; + +#endif if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; @@ -1782,6 +1810,18 @@ ivas_error IVAS_DEC_PrepareRenderer( { ivas_dec_prepare_renderer( hIvasDec->st_ivas ); } +#ifdef FIX_1419_SPATIAL_UMX + + if ( hIvasDec->st_ivas->hRenderConfig != NULL ) + { + if ( ( error = ms_upmix_validate_config( &hIvasDec->st_ivas->hRenderConfig->mono_stereo_upmix_config, + hIvasDec->st_ivas->ivas_format, + hIvasDec->st_ivas->hDecoderConfig->output_config ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif hIvasDec->hasBeenPreparedRendering = true; @@ -2207,7 +2247,12 @@ static ivas_error ivas_dec_setup_all( { ivas_error error; +#ifdef FIX_1419_SPATIAL_UMX + /* split rendering related functions in else are required also for mono SR */ + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS && splitRendBits == NULL ) +#else if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) +#endif { #ifdef FIX_1435_MOVE_STEREO_PANNING *nTransportChannels = 1; @@ -2245,7 +2290,11 @@ static ivas_error ivas_dec_setup_all( * - reconfigure the decoder when the number of TC or IVAS total bitrate change *----------------------------------------------------------------*/ +#ifdef FIX_1419_SPATIAL_UMX + if ( st_ivas->bfi == 0 && hIvasDec->mode != IVAS_DEC_MODE_EVS ) +#else if ( st_ivas->bfi == 0 ) +#endif { if ( ( error = ivas_dec_setup( st_ivas ) ) != IVAS_ERR_OK ) { @@ -2261,7 +2310,13 @@ static ivas_error ivas_dec_setup_all( * - reconfigure the ISAR handle in case of bitrate switching (renderer might change) *-----------------------------------------------------------------*/ +#ifdef FIX_1419_SPATIAL_UMX + if ( ( ( hIvasDec->mode == IVAS_DEC_MODE_EVS && st_ivas->hSCE[0]->hCoreCoder[0]->ini_frame == 0 ) || + ( hIvasDec->mode == IVAS_DEC_MODE_IVAS && st_ivas->ini_frame == 0 ) ) && + splitRendBits != NULL ) +#else if ( st_ivas->ini_frame == 0 && splitRendBits != NULL ) +#endif { if ( ( error = ivas_dec_init_split_rend( st_ivas ) ) != IVAS_ERR_OK ) { @@ -3166,6 +3221,14 @@ ivas_error IVAS_DEC_GetAcousticEnvironment( st_ivas = hIvasDec->st_ivas; +#ifdef FIX_1419_SPATIAL_UMX + + /* case when config file contains no acoustic environment, the defaults are already set from ROM */ + if ( aeID == IVAS_DEFAULT_AEID && st_ivas->acousticEnvironmentsCount == 0 ) + { + return IVAS_ERR_OK; + } +#endif /* In case of default AE ID, select the first one available */ if ( aeID == IVAS_DEFAULT_AEID && st_ivas->acousticEnvironmentsCount > 0 ) { @@ -3240,6 +3303,11 @@ static ivas_error copyRendererConfigStruct( mvr2r( hRCin->roomAcoustics.pAcoustic_dsr, hRCout->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); mvr2r( hRCin->directivity, hRCout->directivity, 3 * MAX_NUM_OBJECTS ); mvr2r( hRCin->distAtt, hRCout->distAtt, 3 ); +#ifdef FIX_1419_SPATIAL_UMX + + /* Mono/Stereo upmix configuration */ + hRCout->mono_stereo_upmix_config = hRCin->mono_stereo_upmix_config; +#endif hRCout->split_rend_config = hRCin->split_rend_config; @@ -3383,6 +3451,28 @@ ivas_error IVAS_DEC_FeedRenderConfig( mvr2r( renderConfig.directivity, hRenderConfig->directivity, 3 * MAX_NUM_OBJECTS ); mvr2r( renderConfig.distAtt, hRenderConfig->distAtt, 3 ); +#ifdef FIX_1419_SPATIAL_UMX + + /* Mono/Stereo upmix configuration */ + if ( renderConfig.mono_stereo_upmix_config.spatialEnabled ) + { + /* copy data */ + hRenderConfig->mono_stereo_upmix_config.spatialEnabled = renderConfig.mono_stereo_upmix_config.spatialEnabled; + hRenderConfig->mono_stereo_upmix_config.radius = renderConfig.mono_stereo_upmix_config.radius; + hRenderConfig->mono_stereo_upmix_config.stereoLR = renderConfig.mono_stereo_upmix_config.stereoLR; + + mvr2r( renderConfig.mono_stereo_upmix_config.azi, hRenderConfig->mono_stereo_upmix_config.azi, 2 ); + mvr2r( renderConfig.mono_stereo_upmix_config.ele, hRenderConfig->mono_stereo_upmix_config.ele, 2 ); + + /* validate configuration early - repeated in IVAS_DEC_PrepareRenderer when input format is available */ + if ( ( error = ms_upmix_validate_config( &hRenderConfig->mono_stereo_upmix_config, + st_ivas->ivas_format, + st_ivas->hDecoderConfig->output_config ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif hRenderConfig->split_rend_config = renderConfig.split_rend_config; @@ -4096,7 +4186,13 @@ static ivas_error ivas_dec_voip_get_samples_common( } } +#ifdef FIX_1419_SPATIAL_UMX + if ( splitRendBits != NULL && + ( ( hIvasDec->mode == IVAS_DEC_MODE_EVS && hIvasDec->needNewFrame ) || + ( hIvasDec->mode == IVAS_DEC_MODE_IVAS && hIvasDec->hasDecodedFirstGoodFrame ) ) ) +#else if ( hIvasDec->hasDecodedFirstGoodFrame && splitRendBits != NULL ) +#endif { /* Analyse head poses over entire frame, generate ISAR metadata and maybe encode if split coded */ if ( ( error = isar_generate_metadata_and_bitstream( st_ivas, p_head_pose_buf, *nSamplesRendered, splitRendBits ) ) != IVAS_ERR_OK ) diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index 91346675023091f478cd4a637e93d0347e1d052e..2306d49a6b6d8ce35cd9eb5976716a2079cc52ab 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -167,6 +167,9 @@ static ivas_error ivas_rend_initCrend( const AUDIO_CONFIG outConfig, HRTFS_CREND_HANDLE hHrtfCrend, const int16_t ext_rend_flag, +#ifdef FIX_1419_SPATIAL_UMX + const int16_t bin_upmix_stereolr_flag, +#endif const int32_t output_Fs ) { int16_t i, j, tmp, tmp2; @@ -228,8 +231,15 @@ static ivas_error ivas_rend_initCrend( { if ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) { - hHrtf->max_num_ir -= 1; /* subtract LFE */ - hHrtf->gain_lfe = GAIN_LFE; +#ifdef FIX_1419_SPATIAL_UMX + if ( inConfig != IVAS_AUDIO_CONFIG_MONO && inConfig != IVAS_AUDIO_CONFIG_STEREO ) + { +#endif + hHrtf->max_num_ir -= 1; /* subtract LFE */ + hHrtf->gain_lfe = GAIN_LFE; +#ifdef FIX_1419_SPATIAL_UMX + } +#endif if ( output_Fs == 48000 ) { @@ -338,7 +348,20 @@ static ivas_error ivas_rend_initCrend( for ( i = 0; i < hHrtf->max_num_ir; i++ ) { +#ifdef FIX_1419_SPATIAL_UMX + if ( inConfig == IVAS_AUDIO_CONFIG_MONO ) + { + tmp = channelIndex_CICP1[i]; + } + else if ( inConfig == IVAS_AUDIO_CONFIG_STEREO ) + { + /* flag to select ±90 loudspeakers instead of ±30 */ + tmp = ( bin_upmix_stereolr_flag ) ? channelIndex_LR[i] : channelIndex_CICP2[i]; + } + else if ( inConfig == IVAS_AUDIO_CONFIG_5_1 ) +#else if ( inConfig == IVAS_AUDIO_CONFIG_5_1 ) +#endif { tmp = channelIndex_CICP6[i]; } @@ -360,7 +383,11 @@ static ivas_error ivas_rend_initCrend( } else { +#ifdef FIX_1419_SPATIAL_UMX + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Invalid channel configuration for Crend!\n\n" ); +#else return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Channel configuration not specified!\n\n" ); +#endif } if ( output_Fs == 48000 ) @@ -703,8 +730,15 @@ static ivas_error ivas_rend_initCrend( { if ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) { - hHrtf->max_num_ir -= 1; /* subtract LFE */ - hHrtf->gain_lfe = GAIN_LFE; +#ifdef FIX_1419_SPATIAL_UMX + if ( inConfig != IVAS_AUDIO_CONFIG_MONO && inConfig != IVAS_AUDIO_CONFIG_STEREO ) + { +#endif + hHrtf->max_num_ir -= 1; /* subtract LFE */ + hHrtf->gain_lfe = GAIN_LFE; +#ifdef FIX_1419_SPATIAL_UMX + } +#endif } if ( ext_rend_flag == 1 ) @@ -747,7 +781,20 @@ static ivas_error ivas_rend_initCrend( for ( i = 0; i < hHrtf->max_num_ir; i++ ) { +#ifdef FIX_1419_SPATIAL_UMX + if ( inConfig == IVAS_AUDIO_CONFIG_MONO ) + { + tmp = channelIndex_CICP1[i]; + } + else if ( inConfig == IVAS_AUDIO_CONFIG_STEREO ) + { + /* flag to select ±90 loudspeakers instead of ±30 */ + tmp = ( bin_upmix_stereolr_flag ) ? channelIndex_LR[i] : channelIndex_CICP2[i]; + } + else if ( inConfig == IVAS_AUDIO_CONFIG_5_1 ) +#else if ( inConfig == IVAS_AUDIO_CONFIG_5_1 ) +#endif { tmp = channelIndex_CICP6[i]; } @@ -1172,7 +1219,17 @@ ivas_error ivas_rend_openCrend( if ( ( *pCrend )->hHrtfCrend == NULL ) { +#ifdef FIX_1419_SPATIAL_UMX + if ( ( error = ivas_rend_initCrend( *pCrend, + inConfig, + outConfig, + hHrtfCrend, + ext_rend_flag, + ( hRendCfg != NULL ) ? hRendCfg->mono_stereo_upmix_config.stereoLR : 0, + output_Fs ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_initCrend( *pCrend, inConfig, outConfig, hHrtfCrend, ext_rend_flag, output_Fs ) ) != IVAS_ERR_OK ) +#endif { return error; } diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index a4e15c79dea1ae54e130d550b50e21d8c296049a..bd48335925ec408d0e73f2a82d56d47818fba7ce 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -60,13 +60,16 @@ static void angles_to_vec( const float radius, const float azimuth, const float *---------------------------------------------------------------------*/ ivas_error ivas_td_binaural_open_unwrap( - TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HR filter model (from file or NULL) */ - const int32_t output_Fs, /* i : Output sampling rate */ - const int16_t nchan_transport, /* i : Number of channels */ - const IVAS_FORMAT ivas_format, /* i : IVAS format (ISM/MC) */ - const AUDIO_CONFIG transport_config, /* i : Transport configuration */ - const float *directivity, /* i : Directivity pattern (used for ISM) */ - const float *distAtt, /* i : Distance attenuation (used for ISM) */ + TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HR filter model (from file or NULL) */ + const int32_t output_Fs, /* i : Output sampling rate */ + const int16_t nchan_transport, /* i : Number of channels */ + const IVAS_FORMAT ivas_format, /* i : IVAS format (ISM/MC) */ + const AUDIO_CONFIG transport_config, /* i : Transport configuration */ + const float *directivity, /* i : Directivity pattern (used for ISM) */ + const float *distAtt, /* i : Distance attenuation (used for ISM) */ +#ifdef FIX_1419_SPATIAL_UMX + const float *radius_ms_umx, /* i : Radius (used for mono/stereo upmix) */ +#endif const IVAS_OUTPUT_SETUP hTransSetup, /* i : Loudspeaker layout */ BINAURAL_TD_OBJECT_RENDERER_HANDLE *hBinRendererTd, /* o : TD renderer handle */ int32_t *binaural_latency_ns /* i : Binauralization delay */ @@ -77,6 +80,9 @@ ivas_error ivas_td_binaural_open_unwrap( int16_t nS; int16_t SrcInd[MAX_NUM_TDREND_CHANNELS]; const float *ls_azimuth, *ls_elevation; +#ifdef FIX_1419_SPATIAL_UMX + float radius; +#endif float Pos[3]; float Dir[3]; TDREND_DirAtten_t *DirAtten_p; @@ -138,10 +144,22 @@ ivas_error ivas_td_binaural_open_unwrap( } } +#ifdef FIX_1419_SPATIAL_UMX + if ( ivas_format == MONO_FORMAT || ivas_format == STEREO_FORMAT || ivas_format == MC_FORMAT ) +#else if ( ivas_format == MC_FORMAT ) +#endif { switch ( transport_config ) { +#ifdef FIX_1419_SPATIAL_UMX + case IVAS_AUDIO_CONFIG_MONO: + case IVAS_AUDIO_CONFIG_STEREO: + /* appropriate values are set in ivas_init_decoder() */ + ls_azimuth = hTransSetup.ls_azimuth; + ls_elevation = hTransSetup.ls_elevation; + break; +#endif case IVAS_AUDIO_CONFIG_5_1: ls_azimuth = ls_azimuth_CICP6; ls_elevation = ls_elevation_CICP6; @@ -175,8 +193,21 @@ ivas_error ivas_td_binaural_open_unwrap( for ( nS = 0; nS < nchan_rend; nS++ ) { +#ifdef FIX_1419_SPATIAL_UMX + /* set radius from render configuration file for mono/stereo upmix; otherwise 1.f */ + radius = 1.f; + if ( ( transport_config == IVAS_AUDIO_CONFIG_MONO || transport_config == IVAS_AUDIO_CONFIG_STEREO ) && + radius_ms_umx != NULL ) + { + radius = *radius_ms_umx; + } + + /* Set source positions according to loudspeaker layout */ + angles_to_vec( radius, ls_azimuth[nS], ls_elevation[nS], Pos ); +#else /* Set source positions according to loudspeaker layout */ angles_to_vec( 1.0f, ls_azimuth[nS], ls_elevation[nS], Pos ); +#endif Dir[0] = 1.0f; Dir[1] = 0.0f; Dir[2] = 0.0f; @@ -710,7 +741,21 @@ ivas_error ivas_td_binaural_open_ext( distAtt = hRendCfg->distAtt; } +#ifdef FIX_1419_SPATIAL_UMX + return ivas_td_binaural_open_unwrap( pTDRend->hHrtfTD, + outFs, + nchan_transport, + ivas_format, + transport_config, + directivity, + distAtt, + ( hRendCfg != NULL ) ? &hRendCfg->mono_stereo_upmix_config.radius : NULL, + hTransSetup, + &pTDRend->hBinRendererTd, + &pTDRend->binaural_latency_ns ); +#else return ivas_td_binaural_open_unwrap( pTDRend->hHrtfTD, outFs, nchan_transport, ivas_format, transport_config, directivity, distAtt, hTransSetup, &pTDRend->hBinRendererTd, &pTDRend->binaural_latency_ns ); +#endif } diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index 01e1d77231ff06fc84f35a4ca20448a53e8b2729..62403aa8ddb49ff96d636536b8b613383856039f 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -36,7 +36,13 @@ #include "prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" +#ifdef FIX_1419_SPATIAL_UMX +#include "ivas_rom_rend.h" +#endif #include "ivas_prot.h" +#ifdef FIX_1419_SPATIAL_UMX +#include +#endif #include #ifdef DEBUGGING #include "debug.h" @@ -166,9 +172,17 @@ void ivas_output_init( { case IVAS_AUDIO_CONFIG_MONO: hOutSetup->is_loudspeaker_setup = 1; +#ifdef FIX_1419_SPATIAL_UMX + hOutSetup->is_planar_setup = 1; + hOutSetup->ls_azimuth = ls_azimuth_CICP1; + hOutSetup->ls_elevation = ls_elevation_CICP1; +#endif break; case IVAS_AUDIO_CONFIG_STEREO: hOutSetup->is_loudspeaker_setup = 1; +#ifdef FIX_1419_SPATIAL_UMX + hOutSetup->is_planar_setup = 1; +#endif hOutSetup->ls_azimuth = ls_azimuth_CICP2; hOutSetup->ls_elevation = ls_elevation_CICP2; break; @@ -276,10 +290,24 @@ int16_t ivas_get_nchan_buffers_dec( if ( st_ivas->ivas_format == MONO_FORMAT ) { nchan_out_buff = st_ivas->hDecoderConfig->nchan_out; +#ifdef FIX_1419_SPATIAL_UMX + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && + ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) ) + { + nchan_out_buff = max( nchan_out_buff, st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); + } +#endif } else if ( st_ivas->ivas_format == STEREO_FORMAT ) { nchan_out_buff = max( st_ivas->hDecoderConfig->nchan_out, CPE_CHANNELS ); +#ifdef FIX_1419_SPATIAL_UMX + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && + ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) ) + { + nchan_out_buff = max( nchan_out_buff, st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); + } +#endif } else if ( st_ivas->ivas_format == ISM_FORMAT ) { @@ -435,6 +463,120 @@ ivas_error ivas_output_buff_dec( return IVAS_ERR_OK; } +#ifdef FIX_1419_SPATIAL_UMX + +/*---------------------------------------------------------------------* + * ms_upmix_validate_config() + * + * + *---------------------------------------------------------------------*/ + +ivas_error ms_upmix_validate_config( + IVAS_MS_UMX_CONF_HANDLE pMsUpmixConfig, /* i/o: Mono/Stereo upmix configuration */ + const IVAS_FORMAT ivasFormat, /* i : IVAS Decoder input configuration */ + const IVAS_AUDIO_CONFIG outConfig /* i : IVAS Decoder output configuration */ +) +{ + int16_t i; + float azi_abs[2]; + float ele_abs[2]; + + if ( pMsUpmixConfig == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + /* skip validation if non spatial; values aren't used */ + if ( !pMsUpmixConfig->spatialEnabled ) + { + if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_RENDER_CONFIG, "Configuring mono/stereo upmix for split rendering requires a spatial upmix" ); + } + + return IVAS_ERR_OK; + } + + /* validate radius */ + if ( pMsUpmixConfig->radius < 0.f || pMsUpmixConfig->radius > 15.75f ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_RENDER_CONFIG, "Radius must be between 0 and 15.75" ); + } + + /* zero radius corresponds to non-spatial */ + if ( pMsUpmixConfig->radius == 0.f ) + { + pMsUpmixConfig->spatialEnabled = FALSE; + return IVAS_ERR_OK; + } + + /* obtain absolute values */ + for ( i = 0; i < 2; i++ ) + { + azi_abs[i] = fabsf( pMsUpmixConfig->azi[i] ); + ele_abs[i] = fabsf( pMsUpmixConfig->ele[i] ); + } + + /* validate speaker positions */ + if ( ivasFormat == MONO_FORMAT ) + { + if ( azi_abs[0] != 0 ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_RENDER_CONFIG, "Mono cannot be panned" ); + } + if ( ele_abs[0] != 0 ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_RENDER_CONFIG, "Mono cannot be panned" ); + } + } + else if ( ivasFormat == STEREO_FORMAT ) + { + if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) + { + /* validate provided positions match BRIR */ + if ( ( azi_abs[0] != 30 && azi_abs[0] != 90 ) || + ( azi_abs[1] != 30 && azi_abs[1] != 90 ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_RENDER_CONFIG, "BINAURAL_ROOM_IR only supports ±30 and ±90 degree azimuth" ); + } + if ( ele_abs[0] != 0 || ele_abs[1] != 0 ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_RENDER_CONFIG, "BINAURAL_ROOM_IR does not allow nonzero elevation" ); + } + + /* flag to select ±90 azi loudspeakers */ + if ( azi_abs[0] == 90 && azi_abs[1] == 90 ) + { + pMsUpmixConfig->stereoLR = TRUE; + } + } + else /* HRIR based formats and split rendering */ + { + /* enforce symmetry */ + if ( pMsUpmixConfig->azi[0] != -pMsUpmixConfig->azi[1] ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_RENDER_CONFIG, "Panning stereo pair with asymmetric azimuth is not allowed" ); + } + if ( pMsUpmixConfig->ele[0] != pMsUpmixConfig->ele[1] ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_RENDER_CONFIG, "Panning stereo pair with differring elevation is not allowed" ); + } + + /* restrict values */ + if ( ( azi_abs[0] > 90 ) || ( azi_abs[1] > 90 ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_RENDER_CONFIG, "Panning stereo pair beyond |90| degrees azimuth is not allowed" ); + } + if ( ( ele_abs[0] > 45 ) || ( ele_abs[1] > 45 ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_RENDER_CONFIG, "Panning stereo pair beyond |45| degrees of elevation is not allowed" ); + } + } + } + + return IVAS_ERR_OK; +} +#endif /*---------------------------------------------------------------------* * is_split_rendering_enabled() diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 2cd33f685ecbdde277565dce3af1f181f33eb05c..933042f0b27e63731b2d6cfed97a8288185b5e98 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -651,6 +651,9 @@ ivas_error ivas_td_binaural_open_unwrap( const AUDIO_CONFIG transport_config, /* i : Transport configuration */ const float *directivity, /* i : Directivity pattern (used for ISM) */ const float *distAtt, /* i : Distance attenuation (used for ISM) */ +#ifdef FIX_1419_SPATIAL_UMX + const float *radius_ms_umx, /* i : Radius (used for mono/stereo upmix) */ +#endif const IVAS_OUTPUT_SETUP hTransSetup, /* i : Loudspeaker layout */ BINAURAL_TD_OBJECT_RENDERER_HANDLE *hBinRendererTd, /* o : TD renderer handle */ int32_t *binaural_latency_ns /* i : Binauralization delay */ @@ -1348,7 +1351,15 @@ ivas_error ivas_render_config_change_defaults( IVAS_DefaultReverbSize reverbDefault /* i : Reverb default size */ ); +#ifdef FIX_1419_SPATIAL_UMX + +ivas_error ms_upmix_validate_config( + IVAS_MS_UMX_CONF_HANDLE pMsUpmixConfig, /* i/o: Mono/Stereo upmix configuration */ + const IVAS_FORMAT ivasFormat, /* i : IVAS Decoder input configuration */ + const IVAS_AUDIO_CONFIG outConfig /* i : IVAS Decoder output configuration */ +); +#endif /*----------------------------------------------------------------------------------* * Quaternion operations *----------------------------------------------------------------------------------*/ diff --git a/lib_rend/ivas_render_config.c b/lib_rend/ivas_render_config.c index f4348b2cf062ddd000da7340661d5d496e6a00f5..08ebc2afad17973ff8047c745f39f4c86ddcd3ce 100644 --- a/lib_rend/ivas_render_config.c +++ b/lib_rend/ivas_render_config.c @@ -139,6 +139,15 @@ ivas_error ivas_render_config_init_from_rom( ( *hRenderConfig )->distAtt[0] = 15.75f; /* Default max dist */ ( *hRenderConfig )->distAtt[1] = 1.0f; /* Default ref dist */ ( *hRenderConfig )->distAtt[2] = 1.0f; /* Default rolloff factor */ +#ifdef FIX_1419_SPATIAL_UMX + + /* Mono/Stereo upmix configuration */ + ( *hRenderConfig )->mono_stereo_upmix_config.spatialEnabled = FALSE; + ( *hRenderConfig )->mono_stereo_upmix_config.stereoLR = FALSE; + ( *hRenderConfig )->mono_stereo_upmix_config.radius = 0.f; + set_zero( &( *hRenderConfig )->mono_stereo_upmix_config.azi[0], 2 ); + set_zero( &( *hRenderConfig )->mono_stereo_upmix_config.ele[0], 2 ); +#endif /* ISAR-related parameters */ ( *hRenderConfig )->split_rend_config.splitRendBitRate = ISAR_MAX_SPLIT_REND_BITRATE; diff --git a/lib_rend/ivas_rom_rend.c b/lib_rend/ivas_rom_rend.c index 4240efa808dcdf0c8ff509d1ae4bbf3a8ab46fc6..b050cf05e1ce10eaed23987b85e3e87cb4ba0179 100644 --- a/lib_rend/ivas_rom_rend.c +++ b/lib_rend/ivas_rom_rend.c @@ -205,6 +205,11 @@ const int16_t sba_map_tc_512[11] = * 13 = 135, 35 * 14 = -135, 35 */ +#ifdef FIX_1419_SPATIAL_UMX +const int16_t channelIndex_CICP1[1] = { 2 }; +const int16_t channelIndex_CICP2[2] = { 0, 1 }; +const int16_t channelIndex_LR[2] = { 7, 8 }; +#endif const int16_t channelIndex_CICP6[5] = { 0, 1, 2, 5, 6 }; const int16_t channelIndex_CICP12[7] = { 0, 1, 2, 5, 6, 3, 4 }; const int16_t channelIndex_CICP14[7] = { 0, 1, 2, 5, 6, 9, 10 }; diff --git a/lib_rend/ivas_rom_rend.h b/lib_rend/ivas_rom_rend.h index ecda759ccbfab1806fac1ed9d3de37ca42c70704..ddec365a0cd724fee98792915dc42c37d4a87e49 100644 --- a/lib_rend/ivas_rom_rend.h +++ b/lib_rend/ivas_rom_rend.h @@ -67,6 +67,11 @@ extern const int16_t sba_map_tc_512[11]; * FASTCONV and PARAMETRIC binaural renderer ROM tables *----------------------------------------------------------------------------------*/ +#ifdef FIX_1419_SPATIAL_UMX +extern const int16_t channelIndex_CICP1[1]; +extern const int16_t channelIndex_CICP2[2]; +extern const int16_t channelIndex_LR[2]; +#endif extern const int16_t channelIndex_CICP6[5]; extern const int16_t channelIndex_CICP12[7]; extern const int16_t channelIndex_CICP14[7]; diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 7777a147c23dddaab5b3c8d08446e66a33aee2db..a029f7bab3851b39de875036c9ae8ab839f7df29 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -361,7 +361,11 @@ void rotateFrame_sd( ) { int16_t i, j; +#ifdef FIX_1419_SPATIAL_UMX + int16_t nchan, num_lfe, index_lfe; +#else int16_t nchan, index_lfe; +#endif int16_t ch_in, ch_in_woLFE, ch_out, ch_out_woLFE; int16_t azimuth, elevation; @@ -374,6 +378,9 @@ void rotateFrame_sd( push_wmops( "rotateFrame_sd" ); nchan = hTransSetup.nchan_out_woLFE + hTransSetup.num_lfe; +#ifdef FIX_1419_SPATIAL_UMX + num_lfe = hTransSetup.num_lfe; +#endif index_lfe = hTransSetup.index_lfe[0]; tmp = 1.0f / ( subframe_len - 1 ); @@ -400,7 +407,11 @@ void rotateFrame_sd( } /* input channel index without LFE */ +#ifdef FIX_1419_SPATIAL_UMX + ch_in_woLFE = ( ( num_lfe > 0 ) && ( ch_in >= index_lfe ) ) ? ch_in - 1 : ch_in; +#else ch_in_woLFE = ( ch_in >= index_lfe ) ? ch_in - 1 : ch_in; +#endif /* gains for previous subframe rotation */ rotateAziEle( hTransSetup.ls_azimuth[ch_in_woLFE], hTransSetup.ls_elevation[ch_in_woLFE], &azimuth, &elevation, hCombinedOrientationData->Rmat_prev[0], hTransSetup.is_planar_setup ); @@ -417,7 +428,12 @@ void rotateFrame_sd( } /* output channel index without LFE */ +#ifdef FIX_1419_SPATIAL_UMX + ch_out_woLFE = ( ( num_lfe > 0 ) && ( ch_out >= index_lfe ) ) ? ch_out - 1 : ch_out; +#else ch_out_woLFE = ( ch_out >= index_lfe ) ? ch_out - 1 : ch_out; +#endif + gains_prev[ch_in][ch_out] = tmp_gains[ch_out_woLFE]; } @@ -439,7 +455,11 @@ void rotateFrame_sd( } /* output channel index without LFE */ +#ifdef FIX_1419_SPATIAL_UMX + ch_out_woLFE = ( ( num_lfe > 0 ) && ( ch_out >= index_lfe ) ) ? ch_out - 1 : ch_out; +#else ch_out_woLFE = ( ch_out >= index_lfe ) ? ch_out - 1 : ch_out; +#endif gains[ch_in][ch_out] = tmp_gains[ch_out_woLFE]; } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 9462886b3f5cb2f9ef8b63108d43f4eb17cdf841..5d23fde9fd4c5f3f5bbf48b8d286d7fe46da2ed1 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -1262,11 +1262,16 @@ static bool isIoConfigPairSupported( const AUDIO_CONFIG inConfig, const AUDIO_CONFIG outConfig ) { +#ifdef FIX_1466_EXTREND + (void) inConfig; // TODO tmp + (void) outConfig; // TODO tmp +#else /* Rendering mono or stereo to binaural is not supported */ if ( ( inConfig == IVAS_AUDIO_CONFIG_MONO || inConfig == IVAS_AUDIO_CONFIG_STEREO ) && getAudioConfigType( outConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) { return false; } +#endif /* If not returned so far, config pair is supported */ return true; @@ -2208,15 +2213,47 @@ static ivas_error updateMcPanGainsForAmbiOut( { int16_t ch_in, ch_out, lfeIdx; int16_t numNonLfeInChannels, outAmbiOrder; +#ifdef FIX_1466_EXTREND + AUDIO_CONFIG inConfig; +#endif const float *spkAzi, *spkEle; ivas_error error; +#ifdef FIX_1466_EXTREND + inConfig = inputMc->base.inConfig; + +#endif if ( ( error = getAmbisonicsOrder( outConfig, &outAmbiOrder ) ) != IVAS_ERR_OK ) { return error; } +#ifdef FIX_1466_EXTREND + if ( inConfig == IVAS_AUDIO_CONFIG_MONO || + inConfig == IVAS_AUDIO_CONFIG_STEREO ) + { + setZeroPanMatrix( inputMc->panGains ); + if ( inConfig == IVAS_AUDIO_CONFIG_MONO ) + { + /* W = Mono */ + inputMc->panGains[0][0] = 1.f; + } + else + { + /* W = 0.5 * ( L + R ) */ + inputMc->panGains[0][0] = 0.5f; + inputMc->panGains[0][1] = 0.5f; + /* Y = 0.5 * ( L - R ) */ + inputMc->panGains[1][0] = 0.5f; + inputMc->panGains[1][1] = -0.5f; + } + + return IVAS_ERR_OK; + } + else if ( inConfig != IVAS_AUDIO_CONFIG_LS_CUSTOM ) +#else if ( inputMc->base.inConfig != IVAS_AUDIO_CONFIG_LS_CUSTOM ) +#endif { if ( ( error = getNumNonLfeChannelsInSpeakerLayout( inputMc->base.inConfig, &numNonLfeInChannels ) ) != IVAS_ERR_OK ) { @@ -2272,6 +2309,29 @@ static ivas_error updateMcPanGainsForAmbiOut( return IVAS_ERR_OK; } +#ifdef FIX_1466_EXTREND +static ivas_error updateMcPanGainsForBinauralOut( + input_mc *inputMc, + const AUDIO_CONFIG outConfig ) +{ + setZeroPanMatrix( inputMc->panGains ); + if ( inputMc->base.inConfig == IVAS_AUDIO_CONFIG_MONO ) + { + (void)inputMc->nonDiegeticPanGain;//TODO + /* same as non-diegetic panning to C */ + inputMc->panGains[0][0] = 0.5f; + inputMc->panGains[0][1] = 0.5f; + } + else + { + /* stereo passthrough */ + inputMc->panGains[0][0] = 1.f; + inputMc->panGains[1][1] = 1.f; + } + + return IVAS_ERR_OK; +} +#endif static ivas_error updateMcPanGains( input_mc *inputMc, @@ -2293,6 +2353,15 @@ static ivas_error updateMcPanGains( error = updateMcPanGainsForAmbiOut( inputMc, outConfig ); break; case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: +#ifdef FIX_1466_EXTREND + if ( inputMc->base.inConfig == IVAS_AUDIO_CONFIG_MONO || inputMc->base.inConfig == IVAS_AUDIO_CONFIG_STEREO ) + { + error = updateMcPanGainsForBinauralOut( inputMc, outConfig ); + break; + } + + /* not mono or stereo */ +#endif switch ( outConfig ) { case IVAS_AUDIO_CONFIG_BINAURAL: @@ -6246,6 +6315,28 @@ static ivas_error renderActiveInputsIsm( return IVAS_ERR_OK; } +#ifdef FIX_1466_EXTREND +static void renderMonoStereoToBinaural( + const input_mc *mcInput, + const AUDIO_CONFIG outConfig, + IVAS_REND_AudioBuffer outAudio ) +{ + int16_t i; + IVAS_REND_AudioBuffer inAudio; + + push_wmops( "renderMonoStereoToBinaural" ); + inAudio = mcInput->base.inputBuffer; + + for ( i = 0; i < inAudio.config.numChannels; ++i ) + { + renderBufferChannel( inAudio, i, mcInput->panGains[i], outAudio ); + } + + pop_wmops(); + + return; +} +#endif static ivas_error renderLfeToBinaural( const input_mc *mcInput, @@ -6846,6 +6937,15 @@ static ivas_error renderInputMc( renderMcToSba( mcInput, outAudio ); break; case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: +#ifdef FIX_1466_EXTREND + if ( mcInput->base.inConfig == IVAS_AUDIO_CONFIG_MONO || mcInput->base.inConfig == IVAS_AUDIO_CONFIG_STEREO ) + { + renderMonoStereoToBinaural( mcInput, outConfig, outAudio ); + break; + } + + /* not mono or stereo */ +#endif switch ( outConfig ) { case IVAS_AUDIO_CONFIG_BINAURAL: diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index b9bb2e5a609ade0167533ec651f1744a8badf162..d15b91479ced96acaab2dc2a40fc64282c246dc1 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -2571,6 +2571,46 @@ ivas_error RenderConfigReader_read( free( pValue ); acIdx++; } +#ifdef FIX_1419_SPATIAL_UMX + else if ( strcmp( chapter, "MSUPMIX" ) == 0 && strlen( pParams ) != 0 ) + { + params_idx = 0; + pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); + while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) + { + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); + if ( strcmp( item, "AZIMUTH" ) == 0 ) + { + if ( read_txt_vector( pValue, 2, &hRenderConfig->mono_stereo_upmix_config.azi[0] ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + /* set flag to signal that spatial rendering is enabled */ + hRenderConfig->mono_stereo_upmix_config.spatialEnabled = 1; + } + else if ( strcmp( item, "ELEVATION" ) == 0 ) + { + if ( read_txt_vector( pValue, 2, &hRenderConfig->mono_stereo_upmix_config.ele[0] ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + /* set flag to signal that spatial rendering is enabled */ + hRenderConfig->mono_stereo_upmix_config.spatialEnabled = 1; + } + else if ( strcmp( item, "RADIUS" ) == 0 ) + { + if ( !sscanf( pValue, "%f", &hRenderConfig->mono_stereo_upmix_config.radius ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + /* set flag to signal that spatial rendering is enabled */ + hRenderConfig->mono_stereo_upmix_config.spatialEnabled = 1; + } + } + } +#endif else if ( strcmp( chapter, "SPLITREND" ) == 0 && strlen( pParams ) != 0 ) { params_idx = 0; @@ -3021,6 +3061,14 @@ ivas_error RenderConfigReader_getAcousticEnvironment( { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } +#ifdef FIX_1419_SPATIAL_UMX + + /* case when config file contains no acoustic environment, the defaults are already set from ROM */ + if ( id == IVAS_DEFAULT_AEID && pRenderConfigReader->nAE == 0 ) + { + return IVAS_ERR_OK; + } +#endif /* case when -aeid is not specified, select first ID from config file */ if ( id == IVAS_DEFAULT_AEID && pRenderConfigReader->nAE > 0 ) diff --git a/tests/renderer/test_renderer.py b/tests/renderer/test_renderer.py index d12cb47b19cbc1d02ef4439bb94cf6fa76233d92..48892f1fd2025b7dc440df88b4b0d72765b6c0e7 100644 --- a/tests/renderer/test_renderer.py +++ b/tests/renderer/test_renderer.py @@ -208,9 +208,6 @@ def test_dynamic_acoustic_environment( aeid, split_comparison, ): - if in_fmt in ["MONO", "STEREO"]: - pytest.skip("MONO or STEREO to Binaural rendering unsupported") - rend_config_path = TEST_VECTOR_DIR.joinpath("rend_config_combined.cfg") rend_config_path.with_stem("rend_config") @@ -263,9 +260,6 @@ def test_dynamic_acoustic_environment_file( get_odg_bin, split_comparison, ): - if in_fmt in ["MONO", "STEREO"]: - pytest.skip("MONO or STEREO to Binaural rendering unsupported") - rend_config_path = TEST_VECTOR_DIR.joinpath("rend_config_combined.cfg") rend_config_path.with_stem("rend_config") @@ -350,9 +344,6 @@ def test_multichannel_binaural_static( get_odg_bin, split_comparison, ): - if in_fmt in ["MONO", "STEREO"]: - pytest.skip("MONO or STEREO to Binaural rendering unsupported") - run_renderer( record_property, props_to_record, @@ -392,9 +383,6 @@ def test_multichannel_binaural_headrotation( get_odg_bin, split_comparison, ): - if in_fmt in ["MONO", "STEREO"]: - pytest.skip("MONO or STEREO to Binaural rendering unsupported") - run_renderer( record_property, props_to_record, @@ -1569,9 +1557,6 @@ def test_multichannel_binaural_headrotation_refvec_rotating( if test_info.config.option.create_ref or test_info.config.option.create_cut: pytest.skip("OTR tests only run for smoke test") - if in_fmt in ["MONO", "STEREO"]: - pytest.skip("MONO or STEREO to Binaural rendering unsupported") - compare_renderer_args( record_property, props_to_record,