diff --git a/lib_com/options.h b/lib_com/options.h index d7daa9187c03ea40bad2c1e563e1bf03edf30ff8..2c70dd14f900bcf3ae42a391332364aa639d8451 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -116,6 +116,7 @@ #define FIX_2250_LARGE_DIFFERENCES_BETWEEN_BASOP_AND_FLOAT /* Dolby: Issue 2250: random vector generation in GenShapedSHBExcitation() */ #define FIX_2254_IMPROV_PRECISION_OR_COMPLEXITY_NON_BE /* VA: Precision improvement without increasing complexity, or complexity reduction that might be not BE on the LSB */ #define FIX_2252_LP_CNG_STARTS_SID /* VA: issues 2251 and 2252: fix LP CNG uninitialized value in bitstream that starts with an SID */ +#define FIX_1466_EXTREND /* FhG: float issue 1466: enable rendering of mono/stereo to other formats in the external renderer */ #define FIX_1381_BWD /* VA: issue 1381: apply no hysteresis in BWD at higher bitrates also in mono MASA and OMASA */ #define FIX_2285_CODE_DECODER_INIT_BW /* VA: basop issue 2285: fix core-decoder initialization bandwidth */ diff --git a/lib_dec/ivas_output_config_fx.c b/lib_dec/ivas_output_config_fx.c index abf80add0da1b9f2af4f621c1d3680a42b573064..2d825d64a5e2c4500d11666bf9715a058eddbe8b 100644 --- a/lib_dec/ivas_output_config_fx.c +++ b/lib_dec/ivas_output_config_fx.c @@ -283,14 +283,22 @@ void ivas_renderer_select( * Non-binaural rendering configurations *-----------------------------------------------------------------*/ +#ifdef FIX_1435_MOVE_STEREO_PANNING + ELSE IF( EQ_32( st_ivas->ivas_format, MONO_FORMAT ) || EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) ) +#else ELSE IF( EQ_32( st_ivas->ivas_format, MONO_FORMAT ) ) +#endif { test(); test(); test(); test(); test(); +#ifdef FIX_1435_MOVE_STEREO_PANNING + IF( EQ_32( st_ivas->ivas_format, MONO_FORMAT ) && EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) ) +#else IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) ) +#endif { *renderer_type = RENDERER_NON_DIEGETIC_DOWNMIX; move16(); @@ -300,7 +308,16 @@ void ivas_renderer_select( *renderer_type = RENDERER_MC; move16(); } +#ifdef FIX_1435_MOVE_STEREO_PANNING + ELSE IF( EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) && + ( EQ_32( output_config, IVAS_AUDIO_CONFIG_FOA ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_HOA2 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_HOA3 ) ) ) + { + *renderer_type = RENDERER_SBA_LINEAR_ENC; + move16(); + } +#endif } +#ifndef FIX_1435_MOVE_STEREO_PANNING ELSE IF( EQ_32( st_ivas->ivas_format, STEREO_FORMAT ) ) { test(); @@ -322,6 +339,7 @@ void ivas_renderer_select( move16(); } } +#endif ELSE IF( EQ_32( st_ivas->ivas_format, ISM_FORMAT ) ) { test(); diff --git a/lib_rend/lib_rend_fx.c b/lib_rend/lib_rend_fx.c index 9b42d17b211d0bd82cd8c0f9bea063ed767db637..9a1dbfe5bd2d83ea1532611739213f52c5bb6f22 100644 --- a/lib_rend/lib_rend_fx.c +++ b/lib_rend/lib_rend_fx.c @@ -1392,6 +1392,22 @@ static bool isIoConfigPairSupported( const AUDIO_CONFIG inConfig, const AUDIO_CONFIG outConfig ) { +#ifdef FIX_1466_EXTREND + /* input config cannot be binaural */ + test(); + test(); + IF( EQ_32( getAudioConfigType( inConfig ), IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) && + NE_32( inConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && NE_32( inConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + return false; + } + + /* output config cannot be object based */ + IF( EQ_32( getAudioConfigType( outConfig ), IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED ) ) + { + return false; + } +#else /* Rendering mono or stereo to binaural is not supported */ test(); test(); @@ -1399,6 +1415,7 @@ static bool isIoConfigPairSupported( { return false; } +#endif /* If not returned so far, config pair is supported */ return true; @@ -2563,15 +2580,53 @@ static ivas_error updateMcPanGainsForAmbiOut( { Word16 ch_in, ch_out, lfeIdx, i; Word16 numNonLfeInChannels, outAmbiOrder; +#ifdef FIX_1466_EXTREND + AUDIO_CONFIG inConfig; +#endif const Word32 *spkAzi_fx, *spkEle_fx; /* Q22 */ ivas_error error; +#ifdef FIX_1466_EXTREND + inConfig = inputMc->base.inConfig; + move32(); + +#endif IF( NE_32( ( error = getAmbisonicsOrder_fx( outConfig, &outAmbiOrder ) ), IVAS_ERR_OK ) ) { return error; } +#ifdef FIX_1466_EXTREND + test(); + IF( EQ_32( inConfig, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( inConfig, IVAS_AUDIO_CONFIG_STEREO ) ) + { + setZeroPanMatrix_fx( inputMc->panGains_fx ); + IF( EQ_32( inConfig, IVAS_AUDIO_CONFIG_MONO ) ) + { + /* W = Mono */ + inputMc->panGains_fx[0][0] = ONE_IN_Q31; + move32(); + } + ELSE + { + /* W = 0.5 * ( L + R ) */ + inputMc->panGains_fx[0][0] = ONE_IN_Q30 /* 0.5f in Q31 */; + inputMc->panGains_fx[0][1] = ONE_IN_Q30 /* 0.5f in Q31 */; + move32(); + move32(); + /* Y = 0.5 * ( L - R ) */ + inputMc->panGains_fx[1][0] = ONE_IN_Q30 /* 0.5f in Q31 */; + inputMc->panGains_fx[1][1] = -ONE_IN_Q30 /* -0.5f in Q31 */; + move32(); + move32(); + } + + return IVAS_ERR_OK; + } + ELSE IF( NE_32( inputMc->base.inConfig, IVAS_AUDIO_CONFIG_LS_CUSTOM ) ) +#else IF( NE_32( inputMc->base.inConfig, IVAS_AUDIO_CONFIG_LS_CUSTOM ) ) +#endif { IF( NE_32( ( error = getNumNonLfeChannelsInSpeakerLayout( inputMc->base.inConfig, &numNonLfeInChannels ) ), IVAS_ERR_OK ) ) { @@ -2682,6 +2737,39 @@ static ivas_error updateMcPanGainsForAmbiOut( return IVAS_ERR_OK; } +#ifdef FIX_1466_EXTREND + +static ivas_error updateMcPanGainsForBinauralOut( + input_mc *inputMc ) +{ + setZeroPanMatrix_fx( inputMc->panGains_fx ); + IF( inputMc->base.inConfig == IVAS_AUDIO_CONFIG_MONO ) + { + IF( EQ_32( inputMc->nonDiegeticPanGain_fx, ONE_IN_Q31 ) ) + { + inputMc->panGains_fx[0][0] = ONE_IN_Q31; + } + ELSE + { + inputMc->panGains_fx[0][0] = L_add( L_shr( inputMc->nonDiegeticPanGain_fx, 1 ), ONE_IN_Q30 /* 0.5f in Q31 */ ); /* Q31 */ + } + move32(); + inputMc->panGains_fx[0][1] = L_sub( ONE_IN_Q31, inputMc->panGains_fx[0][0] ); + move32(); + } + ELSE + { + /* stereo passthrough */ + inputMc->panGains_fx[0][0] = ONE_IN_Q31; + inputMc->panGains_fx[1][1] = ONE_IN_Q31; + move32(); + move32(); + } + + return IVAS_ERR_OK; +} + +#endif static ivas_error updateMcPanGains( input_mc *inputMc, const AUDIO_CONFIG outConfig ) @@ -2703,6 +2791,16 @@ static ivas_error updateMcPanGains( error = updateMcPanGainsForAmbiOut( inputMc, outConfig ); BREAK; case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: +#ifdef FIX_1466_EXTREND + test(); + IF( EQ_32( inputMc->base.inConfig, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( inputMc->base.inConfig, IVAS_AUDIO_CONFIG_STEREO ) ) + { + error = updateMcPanGainsForBinauralOut( inputMc ); + BREAK; + } + + /* not mono or stereo */ +#endif SWITCH( outConfig ) { case IVAS_AUDIO_CONFIG_BINAURAL: @@ -2760,6 +2858,14 @@ static ivas_error initMcBinauralRendering( Word32 outSampleRate; Word8 useTDRend; Word16 i; +#ifdef FIX_1466_EXTREND + + test(); + IF( EQ_32( inputMc->base.inConfig, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( inputMc->base.inConfig, IVAS_AUDIO_CONFIG_STEREO ) ) + { + return IVAS_ERR_OK; + } +#endif /* Allocate TD binaural renderer for custom loudspeaker layouts (regardless of headrotation) or planar MC layouts with headrotation, CREND for the rest */ @@ -7257,6 +7363,29 @@ static ivas_error renderActiveInputsIsm( } return IVAS_ERR_OK; } +#ifdef FIX_1466_EXTREND + +static void renderMonoStereoToBinaural( + const input_mc *mcInput, + IVAS_REND_AudioBuffer outAudio ) +{ + Word16 i; + IVAS_REND_AudioBuffer inAudio; + + push_wmops( "renderMonoStereoToBinaural" ); + inAudio = mcInput->base.inputBuffer; + + FOR( i = 0; i < inAudio.config.numChannels; ++i ) + { + renderBufferChannel_fx( inAudio, i, mcInput->panGains_fx[i], outAudio ); + } + + pop_wmops(); + + return; +} + +#endif static ivas_error renderLfeToBinaural_fx( const input_mc *mcInput, @@ -8011,6 +8140,16 @@ static ivas_error renderInputMc( renderMcToSba( mcInput, outAudio ); BREAK; case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: +#ifdef FIX_1466_EXTREND + test(); + IF( EQ_32( mcInput->base.inConfig, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( mcInput->base.inConfig, IVAS_AUDIO_CONFIG_STEREO ) ) + { + renderMonoStereoToBinaural( mcInput, outAudio ); + BREAK; + } + + /* not mono or stereo */ +#endif SWITCH( outConfig ) { case IVAS_AUDIO_CONFIG_BINAURAL: