diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 7816c19e023776840421edc9e49c17d54fedb372..16ebf808c33c58865313a23e02044ad628b4c7f1 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -566,6 +566,7 @@ enum #define FRAMES_PER_SEC 50 #ifdef IVAS_FLOAT_FIXED +#define MAX_PARAM__SPATIAL_SUB_FRAMES_PER_SEC 200 //(FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES) #define ONE_BY_FRAMES_PER_SEC ((Word32)(0x028F5C29)) #define FRAMES_PER_SEC_BY_2 (FRAMES_PER_SEC >> 1) #endif diff --git a/lib_com/float_to_fix_ops.c b/lib_com/float_to_fix_ops.c index 902b03787375747add6abf0e7e0b3e6b4f2bbc76..dc7a3a9f92a99fba734ff5ae1f69311c3fbb9ff3 100644 --- a/lib_com/float_to_fix_ops.c +++ b/lib_com/float_to_fix_ops.c @@ -194,6 +194,13 @@ Word16 Q_factor_L(float x) Q = norm_l(abs((Word32)x)); return Q; } +Word16 Q_factor_L_32( Word32 x ) +{ + Word16 Q = 31; + if ( x >= 1 || x <= -1 ) + Q = norm_l(L_abs( (Word32) x ) ); + return Q; +} Word16 Q_factor_arr(float *x, Word16 l) { Word16 Q = 15; @@ -789,10 +796,6 @@ void stereo_tcx_dec_mode_switch_reconf_To_fixed_2( //st->hFdCngDec->msPeriodog_ST_fx[p] = (Word32) ( st->hFdCngDec->msPeriodog_ST[p] * ( 1u << ( 31 - st->hFdCngDec->msPeriodog_ST_exp ) ) ); } - // st->hFdCngDec->hFdCngCom->cngNoiseLevelExp = 31 - Q4; // Q4 - //for ( int p = 0; p < FFTCLDFBLEN; p++ ) - //{ - // st->hFdCngDec->hFdCngCom->cngNoiseLevel[p] = (Word32) ( st->hFdCngDec->hFdCngCom->cngNoiseLevel_flt[p] * ( 1u << ( 31 - st->hFdCngDec->hFdCngCom->cngNoiseLevelExp ) ) ); //} //st->hFdCngDec->hFdCngCom->sidNoiseEstExp = 31 - Q4; //st->hFdCngDec->partNoiseShape_exp = 31 - Q4; diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index c801a195bd0e97e1bac2e0b33b447978e1b627fd..2253f7694a23e50d6b575747a1f377271da9bf0f 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -6485,9 +6485,15 @@ ivas_error ivas_binRenderer_open( ); #endif +#ifdef IVAS_FLOAT_FIXED +void ivas_binRenderer_close_fx( + BINAURAL_RENDERER_HANDLE *hBinRenderer /* i/o: decoder binaural renderer handle */ +); +#else void ivas_binRenderer_close( BINAURAL_RENDERER_HANDLE *hBinRenderer /* i/o: decoder binaural renderer handle */ ); +#endif void ivas_binaural_hrtf_close( HRTFS_FASTCONV_HANDLE *hHrtfFastConv /* i/o: decoder binaural hrtf handle */ diff --git a/lib_com/prot_fx2.h b/lib_com/prot_fx2.h index 5ce69999b619834edaf8718fa29a504ef5238120..2c8c19d5844f3744e7cb0d13cfe00c8b1a9c3bc0 100644 --- a/lib_com/prot_fx2.h +++ b/lib_com/prot_fx2.h @@ -99,7 +99,8 @@ Word16 Q_factor(float x); Word16 Q_factor_L(float x); Word16 Q_factor_arr(float* x, Word16 l); Word16 Q_factor_arrL(float* x, Word16 l); -//Handles the cases where Q is negative +Word16 Q_factor_L_32( Word32 x ); + //Handles the cases where Q is negative Word32 floatToFixed( float f, Word16 Q); float fixedToFloat( Word32 i, Word16 Q); Word32 floatToFixed_32(float f, Word16 Q); diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index 11edbc665c9958af77fe2ae5008ca747e355bcfb..890c8367d99fa8b0a90cc4b855530f80f2901daf 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -48,10 +48,6 @@ #include "prot_fx2.h" #include "ivas_rom_com_fx.h" #include "debug.h" -#define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) ) -#define float_to_fixQ29( n ) float_to_fix( n, Q29 ) -#define fix_to_float( n, factor ) ( (float) n / ( 1 << factor ) ) -#define fix_W64_to_float( n, factor ) ( (float) n / ( ( (Word64) 1 ) << factor ) ) #endif #ifndef IVAS_FLOAT_FIXED /*------------------------------------------------------------------------- @@ -242,18 +238,7 @@ static ivas_error ivas_binRenderer_convModuleOpen( const HRTFS_FASTCONV_HANDLE hHrtf ) { Word16 bandIdx, chIdx; -#ifndef IVAS_FLOAT_FIXED - BINRENDERER_CONV_MODULE_HANDLE hBinRenConvModule; - - /*-----------------------------------------------------------------* - * prepare library opening - *-----------------------------------------------------------------*/ - IF( ( hBinRenConvModule = (BINRENDERER_CONV_MODULE_HANDLE) malloc( sizeof( BINRENDERER_CONV_MODULE ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } -#else BINRENDERER_CONV_MODULE_HANDLE_FX hBinRenConvModule; /*-----------------------------------------------------------------* @@ -264,7 +249,6 @@ static ivas_error ivas_binRenderer_convModuleOpen( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } -#endif IF( !isLoudspeaker ) { @@ -323,87 +307,6 @@ static ivas_error ivas_binRenderer_convModuleOpen( } /* allocate memory for filter states */ -#ifndef IVAS_FLOAT_FIXED - IF( ( hBinRenConvModule->filterTapsLeftReal = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } - - IF( ( hBinRenConvModule->filterTapsLeftImag = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } - - IF( ( hBinRenConvModule->filterTapsRightReal = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } - - IF( ( hBinRenConvModule->filterTapsRightImag = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } - - FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) - { - IF( ( hBinRenConvModule->filterTapsLeftReal[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } - - IF( ( hBinRenConvModule->filterTapsLeftImag[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } - - IF( ( hBinRenConvModule->filterTapsRightReal[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } - - IF( ( hBinRenConvModule->filterTapsRightImag[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } - } - - - IF( ( hBinRenConvModule->filterStatesLeftReal = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } - - IF( ( hBinRenConvModule->filterStatesLeftImag = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } - - FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) - { - IF( ( hBinRenConvModule->filterStatesLeftReal[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } - - IF( ( hBinRenConvModule->filterStatesLeftImag[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } - - FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) - { - IF( ( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx] = (float *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( float ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } - - IF( ( hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx] = (float *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( float ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); - } - } - } -#else IF( ( hBinRenConvModule->filterTapsLeftReal_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); @@ -498,7 +401,6 @@ static ivas_error ivas_binRenderer_convModuleOpen( } } } -#endif /* set memories */ FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) { @@ -530,65 +432,6 @@ static ivas_error ivas_binRenderer_convModuleOpen( } } -#ifndef IVAS_FLOAT_FIXED - IF( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) - { - /* set the memories to zero */ - set_zero( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx], hBinRenConvModule->numTapsArray[bandIdx] ); - set_zero( hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx], hBinRenConvModule->numTapsArray[bandIdx] ); - IF( isLoudspeaker ) - { - hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx] = hHrtf->leftBRIRReal[bandIdx][tmp]; - hBinRenConvModule->filterTapsLeftImag[bandIdx][chIdx] = hHrtf->leftBRIRImag[bandIdx][tmp]; - hBinRenConvModule->filterTapsRightReal[bandIdx][chIdx] = hHrtf->rightBRIRReal[bandIdx][tmp]; - hBinRenConvModule->filterTapsRightImag[bandIdx][chIdx] = hHrtf->rightBRIRImag[bandIdx][tmp]; - } - } - ELSE - { - /* set the memories to zero */ - set_zero( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx], hBinRenConvModule->numTaps ); - set_zero( hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx], hBinRenConvModule->numTaps ); - IF( isLoudspeaker ) - { - hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx] = hHrtf->leftHRIRReal[bandIdx][tmp]; - hBinRenConvModule->filterTapsLeftImag[bandIdx][chIdx] = hHrtf->leftHRIRImag[bandIdx][tmp]; - hBinRenConvModule->filterTapsRightReal[bandIdx][chIdx] = hHrtf->rightHRIRReal[bandIdx][tmp]; - hBinRenConvModule->filterTapsRightImag[bandIdx][chIdx] = hHrtf->rightHRIRImag[bandIdx][tmp]; - } - ELSE - { - IF( input_config == IVAS_AUDIO_CONFIG_HOA3 ) - { - /* HOA3 filter coefficients */ - hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx] = hHrtf->leftHRIRReal_HOA3[bandIdx][chIdx]; - hBinRenConvModule->filterTapsLeftImag[bandIdx][chIdx] = hHrtf->leftHRIRImag_HOA3[bandIdx][chIdx]; - hBinRenConvModule->filterTapsRightReal[bandIdx][chIdx] = hHrtf->rightHRIRReal_HOA3[bandIdx][chIdx]; - hBinRenConvModule->filterTapsRightImag[bandIdx][chIdx] = hHrtf->rightHRIRImag_HOA3[bandIdx][chIdx]; - } - ELSE IF( input_config == IVAS_AUDIO_CONFIG_HOA2 ) - { - /* HOA2 filter coefficients */ - hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx] = hHrtf->leftHRIRReal_HOA2[bandIdx][chIdx]; - hBinRenConvModule->filterTapsLeftImag[bandIdx][chIdx] = hHrtf->leftHRIRImag_HOA2[bandIdx][chIdx]; - hBinRenConvModule->filterTapsRightReal[bandIdx][chIdx] = hHrtf->rightHRIRReal_HOA2[bandIdx][chIdx]; - hBinRenConvModule->filterTapsRightImag[bandIdx][chIdx] = hHrtf->rightHRIRImag_HOA2[bandIdx][chIdx]; - } - ELSE IF( input_config == IVAS_AUDIO_CONFIG_FOA ) - { - /* FOA filter coefficients */ - hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx] = hHrtf->leftHRIRReal_FOA[bandIdx][chIdx]; - hBinRenConvModule->filterTapsLeftImag[bandIdx][chIdx] = hHrtf->leftHRIRImag_FOA[bandIdx][chIdx]; - hBinRenConvModule->filterTapsRightReal[bandIdx][chIdx] = hHrtf->rightHRIRReal_FOA[bandIdx][chIdx]; - hBinRenConvModule->filterTapsRightImag[bandIdx][chIdx] = hHrtf->rightHRIRImag_FOA[bandIdx][chIdx]; - } - ELSE - { - return IVAS_ERR_INVALID_INPUT_FORMAT; - } - } - } -#else IF( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { /* set the memories to zero */ @@ -648,7 +491,6 @@ static ivas_error ivas_binRenderer_convModuleOpen( } } } -#endif } } @@ -926,62 +768,42 @@ void ivas_init_binaural_hrtf_fx( { Word16 i; - HrtfFastConv->leftHRIRReal_HOA3 = NULL; - HrtfFastConv->leftHRIRImag_HOA3 = NULL; - HrtfFastConv->rightHRIRReal_HOA3 = NULL; - HrtfFastConv->rightHRIRImag_HOA3 = NULL; HrtfFastConv->leftHRIRReal_HOA3_fx = NULL; HrtfFastConv->leftHRIRImag_HOA3_fx = NULL; HrtfFastConv->rightHRIRReal_HOA3_fx = NULL; HrtfFastConv->rightHRIRImag_HOA3_fx = NULL; - HrtfFastConv->FASTCONV_HOA3_latency_s = 0x00; + HrtfFastConv->FASTCONV_HOA3_latency_s_fx = 0x00; - HrtfFastConv->leftHRIRReal = NULL; - HrtfFastConv->leftHRIRImag = NULL; - HrtfFastConv->rightHRIRReal = NULL; - HrtfFastConv->rightHRIRImag = NULL; HrtfFastConv->leftHRIRReal_fx = NULL; HrtfFastConv->leftHRIRImag_fx = NULL; HrtfFastConv->rightHRIRReal_fx = NULL; HrtfFastConv->rightHRIRImag_fx = NULL; - HrtfFastConv->FASTCONV_HRIR_latency_s = 0x00; + HrtfFastConv->FASTCONV_HRIR_latency_s_fx = 0x00; - HrtfFastConv->leftBRIRReal = NULL; - HrtfFastConv->leftBRIRImag = NULL; - HrtfFastConv->rightBRIRReal = NULL; - HrtfFastConv->rightBRIRImag = NULL; HrtfFastConv->leftBRIRReal_fx = NULL; HrtfFastConv->leftBRIRImag_fx = NULL; HrtfFastConv->rightBRIRReal_fx = NULL; HrtfFastConv->rightBRIRImag_fx = NULL; - HrtfFastConv->FASTCONV_BRIR_latency_s = 0x00; + HrtfFastConv->FASTCONV_BRIR_latency_s_fx = 0x00; - HrtfFastConv->leftHRIRReal_HOA2 = NULL; - HrtfFastConv->leftHRIRImag_HOA2 = NULL; - HrtfFastConv->rightHRIRReal_HOA2 = NULL; - HrtfFastConv->rightHRIRImag_HOA2 = NULL; HrtfFastConv->leftHRIRReal_HOA2_fx = NULL; HrtfFastConv->leftHRIRImag_HOA2_fx = NULL; HrtfFastConv->rightHRIRReal_HOA2_fx = NULL; HrtfFastConv->rightHRIRImag_HOA2_fx = NULL; - HrtfFastConv->FASTCONV_HOA2_latency_s = 0x00; + HrtfFastConv->FASTCONV_HOA2_latency_s_fx = 0x00; - HrtfFastConv->leftHRIRReal_FOA = NULL; - HrtfFastConv->leftHRIRImag_FOA = NULL; - HrtfFastConv->rightHRIRReal_FOA = NULL; - HrtfFastConv->rightHRIRImag_FOA = NULL; HrtfFastConv->leftHRIRReal_FOA_fx = NULL; HrtfFastConv->leftHRIRImag_FOA_fx = NULL; HrtfFastConv->rightHRIRReal_FOA_fx = NULL; HrtfFastConv->rightHRIRImag_FOA_fx = NULL; - HrtfFastConv->FASTCONV_FOA_latency_s = 0x00; + HrtfFastConv->FASTCONV_FOA_latency_s_fx = 0x00; HrtfFastConv->allocate_init_flag = 0x00; FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) { - HrtfFastConv->fastconvReverberationTimes[i] = 0x00; - HrtfFastConv->fastconvReverberationEneCorrections[i] = 0x00; + HrtfFastConv->fastconvReverberationTimes_fx[i] = 0x00; + HrtfFastConv->fastconvReverberationEneCorrections_fx[i] = 0x00; } return; @@ -1078,7 +900,7 @@ static ivas_error ivas_alloc_pppMem_fx( return IVAS_ERR_OK; } -#endif +#else static ivas_error ivas_alloc_pppMem( float ****pppMem, const int16_t dim1, @@ -1116,7 +938,7 @@ static ivas_error ivas_alloc_pppMem( return IVAS_ERR_OK; } - +#endif /*-------------------------------------------------------------------------* * ivas_allocate_binaural_hrtf() @@ -1157,29 +979,6 @@ ivas_error ivas_allocate_binaural_hrtf_fx( return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag_HOA3"); } } - IF( ( HrtfFastConv->leftHRIRReal_HOA3 != NULL ) && ( HrtfFastConv->leftHRIRImag_HOA3 != NULL ) && ( HrtfFastConv->rightHRIRReal_HOA3 != NULL ) && ( HrtfFastConv->rightHRIRImag_HOA3 != NULL ) ) - { - return IVAS_ERR_OK; - } - ELSE - { - IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRReal_HOA3, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRReal_HOA3" ); - } - IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRImag_HOA3, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRImag_HOA3" ); - } - IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRReal_HOA3, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRReal_HOA3" ); - } - IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRImag_HOA3, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag_HOA3" ); - } - } } IF( input_config == IVAS_AUDIO_CONFIG_HOA2 || bin_input_config == BINAURAL_INPUT_AUDIO_CONFIG_HOA2 ) @@ -1207,29 +1006,6 @@ ivas_error ivas_allocate_binaural_hrtf_fx( return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag_HOA2"); } } - IF( ( HrtfFastConv->leftHRIRReal_HOA2 != NULL ) && ( HrtfFastConv->leftHRIRImag_HOA2 != NULL ) && ( HrtfFastConv->rightHRIRReal_HOA2 != NULL ) && ( HrtfFastConv->rightHRIRImag_HOA2 != NULL ) ) - { - return IVAS_ERR_OK; - } - ELSE - { - IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRReal_HOA2, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRReal_HOA2" ); - } - IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRImag_HOA2, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRImag_HOA2" ); - } - IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRReal_HOA2, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRReal_HOA2" ); - } - IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRImag_HOA2, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag_HOA2" ); - } - } } IF( input_config == IVAS_AUDIO_CONFIG_FOA || bin_input_config == BINAURAL_INPUT_AUDIO_CONFIG_FOA ) @@ -1257,29 +1033,6 @@ ivas_error ivas_allocate_binaural_hrtf_fx( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag_FOA" ); } } - IF( ( HrtfFastConv->leftHRIRReal_FOA != NULL ) && ( HrtfFastConv->leftHRIRImag_FOA != NULL ) && ( HrtfFastConv->rightHRIRReal_FOA != NULL ) && ( HrtfFastConv->rightHRIRImag_FOA != NULL ) ) - { - return IVAS_ERR_OK; - } - ELSE - { - IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRReal_FOA, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRReal_FOA" ); - } - IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRImag_FOA, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRImag_FOA" ); - } - IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRReal_FOA, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRReal_FOA" ); - } - IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRImag_FOA, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag_FOA" ); - } - } } IF( renderer_type == RENDERER_BINAURAL_FASTCONV || bin_input_config == BINAURAL_INPUT_AUDIO_CONFIG_COMBINED ) @@ -1307,29 +1060,6 @@ ivas_error ivas_allocate_binaural_hrtf_fx( return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag"); } } - IF( ( HrtfFastConv->leftHRIRReal != NULL ) && ( HrtfFastConv->leftHRIRImag != NULL ) && ( HrtfFastConv->rightHRIRReal != NULL ) && ( HrtfFastConv->rightHRIRImag != NULL ) ) - { - return IVAS_ERR_OK; - } - ELSE - { - IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRReal, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRReal" ); - } - IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftHRIRImag, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRImag" ); - } - IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRReal, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRReal" ); - } - IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightHRIRImag, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag" ); - } - } } IF( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || bin_input_config == BINAURAL_INPUT_AUDIO_CONFIG_COMBINED ) @@ -1357,29 +1087,6 @@ ivas_error ivas_allocate_binaural_hrtf_fx( return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightBRIRImag"); } } - IF( ( HrtfFastConv->leftBRIRReal != NULL ) && ( HrtfFastConv->leftBRIRImag != NULL ) && ( HrtfFastConv->rightBRIRReal != NULL ) && ( HrtfFastConv->rightBRIRImag != NULL ) ) - { - return IVAS_ERR_OK; - } - ELSE - { - IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftBRIRReal, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftBRIRReal" ); - } - IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftBRIRImag, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftBRIRImag" ); - } - IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightBRIRReal, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightBRIRReal" ); - } - IF( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightBRIRImag, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightBRIRImag" ); - } - } } return IVAS_ERR_OK; @@ -1567,23 +1274,23 @@ static ivas_error ivas_binaural_hrtf_open_fx( IF( input_config == IVAS_AUDIO_CONFIG_BINAURAL || renderer_type == RENDERER_BINAURAL_FASTCONV ) { - HrtfFastConv->FASTCONV_HRIR_latency_s = FASTCONV_HRIR_latency_s; + HrtfFastConv->FASTCONV_HRIR_latency_s_fx = FASTCONV_HRIR_latency_s_fx; } IF( input_config == IVAS_AUDIO_CONFIG_HOA2 ) { - HrtfFastConv->FASTCONV_HOA2_latency_s = FASTCONV_HOA2_latency_s; + HrtfFastConv->FASTCONV_HOA2_latency_s_fx = FASTCONV_HOA2_latency_s_fx; } IF( input_config == IVAS_AUDIO_CONFIG_HOA3 ) { - HrtfFastConv->FASTCONV_HOA3_latency_s = FASTCONV_HOA3_latency_s; + HrtfFastConv->FASTCONV_HOA3_latency_s_fx = FASTCONV_HOA3_latency_s_fx; } IF( input_config == IVAS_AUDIO_CONFIG_FOA ) { - HrtfFastConv->FASTCONV_FOA_latency_s = FASTCONV_FOA_latency_s; + HrtfFastConv->FASTCONV_FOA_latency_s_fx = FASTCONV_FOA_latency_s_fx; } IF( input_config == IVAS_AUDIO_CONFIG_BINAURAL || renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { - HrtfFastConv->FASTCONV_BRIR_latency_s = FASTCONV_BRIR_latency_s; + HrtfFastConv->FASTCONV_BRIR_latency_s_fx = FASTCONV_BRIR_latency_s_fx; } HrtfFastConv->allocate_init_flag = 1; @@ -1602,11 +1309,6 @@ static ivas_error ivas_binaural_hrtf_open_fx( HrtfFastConv->leftHRIRImag_fx[i][j] = leftHRIRImag_fx[i][j]; HrtfFastConv->rightHRIRReal_fx[i][j] = rightHRIRReal_fx[i][j]; HrtfFastConv->rightHRIRImag_fx[i][j] = rightHRIRImag_fx[i][j]; - - HrtfFastConv->leftHRIRReal[i][j] = leftHRIRReal[i][j]; - HrtfFastConv->leftHRIRImag[i][j] = leftHRIRImag[i][j]; - HrtfFastConv->rightHRIRReal[i][j] = rightHRIRReal[i][j]; - HrtfFastConv->rightHRIRImag[i][j] = rightHRIRImag[i][j]; } } ELSE IF( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) @@ -1617,11 +1319,6 @@ static ivas_error ivas_binaural_hrtf_open_fx( HrtfFastConv->leftBRIRImag_fx[i][j] = leftBRIRImag_fx[i][j]; HrtfFastConv->rightBRIRReal_fx[i][j] = rightBRIRReal_fx[i][j]; HrtfFastConv->rightBRIRImag_fx[i][j] = rightBRIRImag_fx[i][j]; - - HrtfFastConv->leftBRIRReal[i][j] = leftBRIRReal[i][j]; - HrtfFastConv->leftBRIRImag[i][j] = leftBRIRImag[i][j]; - HrtfFastConv->rightBRIRReal[i][j] = rightBRIRReal[i][j]; - HrtfFastConv->rightBRIRImag[i][j] = rightBRIRImag[i][j]; } } IF( input_config == IVAS_AUDIO_CONFIG_HOA3 ) @@ -1632,11 +1329,6 @@ static ivas_error ivas_binaural_hrtf_open_fx( HrtfFastConv->leftHRIRImag_HOA3_fx[i][j] = leftHRIRImag_HOA3_fx[i][j]; HrtfFastConv->rightHRIRReal_HOA3_fx[i][j] = rightHRIRReal_HOA3_fx[i][j]; HrtfFastConv->rightHRIRImag_HOA3_fx[i][j] = rightHRIRImag_HOA3_fx[i][j]; - - HrtfFastConv->leftHRIRReal_HOA3[i][j] = leftHRIRReal_HOA3[i][j]; - HrtfFastConv->leftHRIRImag_HOA3[i][j] = leftHRIRImag_HOA3[i][j]; - HrtfFastConv->rightHRIRReal_HOA3[i][j] = rightHRIRReal_HOA3[i][j]; - HrtfFastConv->rightHRIRImag_HOA3[i][j] = rightHRIRImag_HOA3[i][j]; } } IF( input_config == IVAS_AUDIO_CONFIG_HOA2 ) @@ -1647,11 +1339,6 @@ static ivas_error ivas_binaural_hrtf_open_fx( HrtfFastConv->leftHRIRImag_HOA2_fx[i][j] = leftHRIRImag_HOA2_fx[i][j]; HrtfFastConv->rightHRIRReal_HOA2_fx[i][j] = rightHRIRReal_HOA2_fx[i][j]; HrtfFastConv->rightHRIRImag_HOA2_fx[i][j] = rightHRIRImag_HOA2_fx[i][j]; - - HrtfFastConv->leftHRIRReal_HOA2[i][j] = leftHRIRReal_HOA2[i][j]; - HrtfFastConv->leftHRIRImag_HOA2[i][j] = leftHRIRImag_HOA2[i][j]; - HrtfFastConv->rightHRIRReal_HOA2[i][j] = rightHRIRReal_HOA2[i][j]; - HrtfFastConv->rightHRIRImag_HOA2[i][j] = rightHRIRImag_HOA2[i][j]; } } IF( input_config == IVAS_AUDIO_CONFIG_FOA ) @@ -1662,19 +1349,11 @@ static ivas_error ivas_binaural_hrtf_open_fx( HrtfFastConv->leftHRIRImag_FOA_fx[i][j] = leftHRIRImag_FOA_fx[i][j]; HrtfFastConv->rightHRIRReal_FOA_fx[i][j] = rightHRIRReal_FOA_fx[i][j]; HrtfFastConv->rightHRIRImag_FOA_fx[i][j] = rightHRIRImag_FOA_fx[i][j]; - - HrtfFastConv->leftHRIRReal_FOA[i][j] = leftHRIRReal_FOA[i][j]; - HrtfFastConv->leftHRIRImag_FOA[i][j] = leftHRIRImag_FOA[i][j]; - HrtfFastConv->rightHRIRReal_FOA[i][j] = rightHRIRReal_FOA[i][j]; - HrtfFastConv->rightHRIRImag_FOA[i][j] = rightHRIRImag_FOA[i][j]; } } } mvl2l(fastconvReverberationTimes_fx, HrtfFastConv->fastconvReverberationTimes_fx, CLDFB_NO_CHANNELS_MAX); mvl2l(fastconvReverberationEneCorrections_fx, HrtfFastConv->fastconvReverberationEneCorrections_fx, CLDFB_NO_CHANNELS_MAX); - - mvr2r( fastconvReverberationTimes, HrtfFastConv->fastconvReverberationTimes, CLDFB_NO_CHANNELS_MAX ); - mvr2r( fastconvReverberationEneCorrections, HrtfFastConv->fastconvReverberationEneCorrections, CLDFB_NO_CHANNELS_MAX ); *hHrtfFastConv = HrtfFastConv; } @@ -1990,7 +1669,7 @@ static void ivas_binaural_obtain_DMX_fx( P_out_fx = L_add( P_out_fx, L_add( Mpy_32_32( temp1_fx, temp1_fx ), Mpy_32_32( temp2_fx, temp2_fx ) ) ); //Q31-2*Q_in } // if ( ( factEQ <= 1e-20f ) || ( P_in[bandIdx] <= 1e-20f ) || ( P_out <= 1e-20f ) ) - IF ( LE_32( P_in_fx[bandIdx], 0 ) || LE_32( P_out_fx, 0 ) ) + IF( LE_32( P_in_fx[bandIdx], 0 ) || LE_32( P_out_fx, 0 ) ) { //factEQ = 1.0f; factEQ_fx = 0x40000000; @@ -2009,7 +1688,7 @@ static void ivas_binaural_obtain_DMX_fx( } //factEQ = max( min( factEQ, 2.0f ), 0.5f ); - factEQ_fx = max( min( factEQ_fx, 0x7fffffff ), 0x20000000 ); // Q30 + factEQ_fx = L_max( L_min( factEQ_fx, 0x7fffffff ), 0x20000000 ); // Q30 FOR( k = 0; k < numTimeSlots; k++ ) { //realDMX[chOutIdx][k][bandIdx] *= factEQ; @@ -2161,7 +1840,7 @@ ivas_error ivas_binRenderer_open_fx( } hBinRenderer->hoa_dec_mtx = st_ivas->hoa_dec_mtx; - st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_BRIR_latency_s * 1000000000.f ); + st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_BRIR_latency_s_fx; // (int32_t)(st_ivas->hHrtfFastConv->FASTCONV_BRIR_latency_s * 1000000000.f); } ELSE { @@ -2175,21 +1854,21 @@ ivas_error ivas_binRenderer_open_fx( { IF( hBinRenderer->ivas_format == MC_FORMAT ) { - st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_HRIR_latency_s * 1000000000.f ); + st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_HRIR_latency_s_fx; // (int32_t)(st_ivas->hHrtfFastConv->FASTCONV_HRIR_latency_s * 1000000000.f); } ELSE { IF( hBinRenderer->nInChannels == 16 ) { - st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_HOA3_latency_s * 1000000000.f ); + st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_HOA3_latency_s_fx; //(int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_HOA3_latency_s * 1000000000.f ); } ELSE IF( hBinRenderer->nInChannels == 9 ) { - st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_HOA2_latency_s * 1000000000.f ); + st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_HOA2_latency_s_fx; // (int32_t)(st_ivas->hHrtfFastConv->FASTCONV_HOA2_latency_s * 1000000000.f); } ELSE IF( hBinRenderer->nInChannels == 4 ) { - st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_FOA_latency_s * 1000000000.f ); + st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_FOA_latency_s_fx; // (int32_t)(st_ivas->hHrtfFastConv->FASTCONV_FOA_latency_s * 1000000000.f); } ELSE { @@ -2200,7 +1879,7 @@ ivas_error ivas_binRenderer_open_fx( ELSE { /* same value for MC or HOA both use MC BRIR*/ - st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_BRIR_latency_s * 1000000000.f ); + st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_BRIR_latency_s_fx; // (int32_t)(st_ivas->hHrtfFastConv->FASTCONV_BRIR_latency_s * 1000000000.f); } } @@ -2444,73 +2123,13 @@ ivas_error ivas_binRenderer_open( * * Close convolution module handle of fastconv binaural renderer *------------------------------------------------------------------------*/ - -static void ivas_binRenderer_convModuleClose( +#ifdef IVAS_FLOAT_FIXED +static void ivas_binRenderer_convModuleClose_fx( BINAURAL_RENDERER_HANDLE *hBinRenderer /* i/o: fastconv binaural renderer handle */ ) { Word16 bandIdx, chIdx; -#ifndef IVAS_FLOAT_FIXED - BINRENDERER_CONV_MODULE_HANDLE hBinRenConvModule; - - hBinRenConvModule = ( *hBinRenderer )->hBinRenConvModule; - - IF( hBinRenConvModule == NULL ) - { - return; - } - - FOR( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ ) - { - free( hBinRenConvModule->filterTapsLeftReal[bandIdx] ); - hBinRenConvModule->filterTapsLeftReal[bandIdx] = NULL; - - free( hBinRenConvModule->filterTapsLeftImag[bandIdx] ); - hBinRenConvModule->filterTapsLeftImag[bandIdx] = NULL; - - free( hBinRenConvModule->filterTapsRightReal[bandIdx] ); - hBinRenConvModule->filterTapsRightReal[bandIdx] = NULL; - - free( hBinRenConvModule->filterTapsRightImag[bandIdx] ); - hBinRenConvModule->filterTapsRightImag[bandIdx] = NULL; - } - free( hBinRenConvModule->filterTapsLeftReal ); - hBinRenConvModule->filterTapsLeftReal = NULL; - - free( hBinRenConvModule->filterTapsLeftImag ); - hBinRenConvModule->filterTapsLeftImag = NULL; - - free( hBinRenConvModule->filterTapsRightReal ); - hBinRenConvModule->filterTapsRightReal = NULL; - - free( hBinRenConvModule->filterTapsRightImag ); - hBinRenConvModule->filterTapsRightImag = NULL; - - FOR( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ ) - { - FOR( chIdx = 0; chIdx < ( *hBinRenderer )->nInChannels; chIdx++ ) - { - free( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx] ); - hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx] = NULL; - - free( hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx] ); - hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx] = NULL; - } - - free( hBinRenConvModule->filterStatesLeftReal[bandIdx] ); - hBinRenConvModule->filterStatesLeftReal[bandIdx] = NULL; - - free( hBinRenConvModule->filterStatesLeftImag[bandIdx] ); - hBinRenConvModule->filterStatesLeftImag[bandIdx] = NULL; - } - - free( hBinRenConvModule->filterStatesLeftReal ); - hBinRenConvModule->filterStatesLeftReal = NULL; - - free( hBinRenConvModule->filterStatesLeftImag ); - hBinRenConvModule->filterStatesLeftImag = NULL; -#else BINRENDERER_CONV_MODULE_HANDLE_FX hBinRenConvModule; hBinRenConvModule = ( *hBinRenderer )->hBinRenConvModule; @@ -2579,20 +2198,117 @@ static void ivas_binRenderer_convModuleClose( free( hBinRenConvModule->Q_filterStatesLeft ); hBinRenConvModule->Q_filterStatesLeft = NULL; -#endif + free( ( *hBinRenderer )->hBinRenConvModule ); ( *hBinRenderer )->hBinRenConvModule = NULL; return; } +#else +static void ivas_binRenderer_convModuleClose( + BINAURAL_RENDERER_HANDLE *hBinRenderer /* i/o: fastconv binaural renderer handle */ +) +{ + Word16 bandIdx, chIdx; + + BINRENDERER_CONV_MODULE_HANDLE hBinRenConvModule; + + hBinRenConvModule = ( *hBinRenderer )->hBinRenConvModule; + + IF( hBinRenConvModule == NULL ) + { + return; + } + + FOR( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ ) + { + free( hBinRenConvModule->filterTapsLeftReal[bandIdx] ); + hBinRenConvModule->filterTapsLeftReal[bandIdx] = NULL; + + free( hBinRenConvModule->filterTapsLeftImag[bandIdx] ); + hBinRenConvModule->filterTapsLeftImag[bandIdx] = NULL; + + free( hBinRenConvModule->filterTapsRightReal[bandIdx] ); + hBinRenConvModule->filterTapsRightReal[bandIdx] = NULL; + + free( hBinRenConvModule->filterTapsRightImag[bandIdx] ); + hBinRenConvModule->filterTapsRightImag[bandIdx] = NULL; + } + + free( hBinRenConvModule->filterTapsLeftReal ); + hBinRenConvModule->filterTapsLeftReal = NULL; + + free( hBinRenConvModule->filterTapsLeftImag ); + hBinRenConvModule->filterTapsLeftImag = NULL; + + free( hBinRenConvModule->filterTapsRightReal ); + hBinRenConvModule->filterTapsRightReal = NULL; + + free( hBinRenConvModule->filterTapsRightImag ); + hBinRenConvModule->filterTapsRightImag = NULL; + + FOR( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ ) + { + FOR( chIdx = 0; chIdx < ( *hBinRenderer )->nInChannels; chIdx++ ) + { + free( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx] ); + hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx] = NULL; + + free( hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx] ); + hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx] = NULL; + } + + free( hBinRenConvModule->filterStatesLeftReal[bandIdx] ); + hBinRenConvModule->filterStatesLeftReal[bandIdx] = NULL; + free( hBinRenConvModule->filterStatesLeftImag[bandIdx] ); + hBinRenConvModule->filterStatesLeftImag[bandIdx] = NULL; + } + + free( hBinRenConvModule->filterStatesLeftReal ); + hBinRenConvModule->filterStatesLeftReal = NULL; + + free( hBinRenConvModule->filterStatesLeftImag ); + hBinRenConvModule->filterStatesLeftImag = NULL; + + free( ( *hBinRenderer )->hBinRenConvModule ); + ( *hBinRenderer )->hBinRenConvModule = NULL; + + return; +} +#endif /*------------------------------------------------------------------------- * ivas_binRenderer_close() * * Close fastconv binaural renderer memories *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_binRenderer_close_fx( + BINAURAL_RENDERER_HANDLE *hBinRenderer /* i/o: fastconv binaural renderer handle */ +) +{ + IF( hBinRenderer == NULL || *hBinRenderer == NULL ) + { + return; + } + + IF( ( *hBinRenderer )->hBinRenConvModule != NULL ) + { + ivas_binRenderer_convModuleClose_fx( hBinRenderer ); + } + IF( ( *hBinRenderer )->hReverb != NULL ) + { + ivas_binaural_reverb_close_fx( &( ( *hBinRenderer )->hReverb ) ); + } + + free( *hBinRenderer ); + *hBinRenderer = NULL; + + return; +} +#else void ivas_binRenderer_close( BINAURAL_RENDERER_HANDLE *hBinRenderer /* i/o: fastconv binaural renderer handle */ ) @@ -2609,11 +2325,7 @@ void ivas_binRenderer_close( IF( ( *hBinRenderer )->hReverb != NULL ) { -#ifdef IVAS_FLOAT_FIXED - ivas_binaural_reverb_close_fx( &( ( *hBinRenderer )->hReverb ) ); -#else ivas_binaural_reverb_close( &( ( *hBinRenderer )->hReverb ) ); -#endif } free( *hBinRenderer ); @@ -2621,7 +2333,7 @@ void ivas_binRenderer_close( return; } - +#endif /*------------------------------------------------------------------------- * ivas_free_pppHrtfMem() @@ -2657,7 +2369,7 @@ static void ivas_free_pppHrtfMem_fx( return; } -#endif +#else static void ivas_free_pppHrtfMem( float ****ppppHRIR, const int16_t dim, @@ -2686,7 +2398,7 @@ static void ivas_free_pppHrtfMem( return; } - +#endif /*------------------------------------------------------------------------- * ivas_binaural_hrtf_close() @@ -2732,31 +2444,6 @@ void ivas_binaural_hrtf_close( ivas_free_pppHrtfMem_fx(&(*hHrtfFastConv)->rightHRIRReal_FOA_fx, FOA_CHANNELS, allocate_init_flag); ivas_free_pppHrtfMem_fx(&(*hHrtfFastConv)->rightHRIRImag_FOA_fx, FOA_CHANNELS, allocate_init_flag); - ivas_free_pppHrtfMem( &( *hHrtfFastConv )->leftHRIRReal, HRTF_LS_CHANNELS, allocate_init_flag ); - ivas_free_pppHrtfMem( &( *hHrtfFastConv )->leftHRIRImag, HRTF_LS_CHANNELS, allocate_init_flag ); - ivas_free_pppHrtfMem( &( *hHrtfFastConv )->rightHRIRReal, HRTF_LS_CHANNELS, allocate_init_flag ); - ivas_free_pppHrtfMem( &( *hHrtfFastConv )->rightHRIRImag, HRTF_LS_CHANNELS, allocate_init_flag ); - - ivas_free_pppHrtfMem( &( *hHrtfFastConv )->leftBRIRReal, HRTF_LS_CHANNELS, allocate_init_flag ); - ivas_free_pppHrtfMem( &( *hHrtfFastConv )->leftBRIRImag, HRTF_LS_CHANNELS, allocate_init_flag ); - ivas_free_pppHrtfMem( &( *hHrtfFastConv )->rightBRIRReal, HRTF_LS_CHANNELS, allocate_init_flag ); - ivas_free_pppHrtfMem( &( *hHrtfFastConv )->rightBRIRImag, HRTF_LS_CHANNELS, allocate_init_flag ); - - ivas_free_pppHrtfMem( &( *hHrtfFastConv )->leftHRIRReal_HOA3, HOA3_CHANNELS, allocate_init_flag ); - ivas_free_pppHrtfMem( &( *hHrtfFastConv )->leftHRIRImag_HOA3, HOA3_CHANNELS, allocate_init_flag ); - ivas_free_pppHrtfMem( &( *hHrtfFastConv )->rightHRIRReal_HOA3, HOA3_CHANNELS, allocate_init_flag ); - ivas_free_pppHrtfMem( &( *hHrtfFastConv )->rightHRIRImag_HOA3, HOA3_CHANNELS, allocate_init_flag ); - - ivas_free_pppHrtfMem( &( *hHrtfFastConv )->leftHRIRReal_HOA2, HOA2_CHANNELS, allocate_init_flag ); - ivas_free_pppHrtfMem( &( *hHrtfFastConv )->leftHRIRImag_HOA2, HOA2_CHANNELS, allocate_init_flag ); - ivas_free_pppHrtfMem( &( *hHrtfFastConv )->rightHRIRReal_HOA2, HOA2_CHANNELS, allocate_init_flag ); - ivas_free_pppHrtfMem( &( *hHrtfFastConv )->rightHRIRImag_HOA2, HOA2_CHANNELS, allocate_init_flag ); - - ivas_free_pppHrtfMem( &( *hHrtfFastConv )->leftHRIRReal_FOA, FOA_CHANNELS, allocate_init_flag ); - ivas_free_pppHrtfMem( &( *hHrtfFastConv )->leftHRIRImag_FOA, FOA_CHANNELS, allocate_init_flag ); - ivas_free_pppHrtfMem( &( *hHrtfFastConv )->rightHRIRReal_FOA, FOA_CHANNELS, allocate_init_flag ); - ivas_free_pppHrtfMem( &( *hHrtfFastConv )->rightHRIRImag_FOA, FOA_CHANNELS, allocate_init_flag ); - return; } #else @@ -2905,258 +2592,6 @@ void ivas_binaural_add_LFE_fx( * Fastconv binaural renderer main function *-------------------------------------------------------------------------*/ -void ivas_binRenderer( - BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle*/ - const int16_t numTimeSlots, /* i : number of time slots to render */ - float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ - float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ - float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ - float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] /* i : LS signals */ -) -{ - int16_t chIdx, k; - - push_wmops( "fastconv_binaural_rendering" ); - - /* Compute Convolution */ - /* memory reset for the binaural output */ - for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) - { - for ( k = 0; k < numTimeSlots; k++ ) - { - set_zero( Cldfb_RealBuffer_Binaural[chIdx][k], CLDFB_NO_CHANNELS_MAX ); - set_zero( Cldfb_ImagBuffer_Binaural[chIdx][k], CLDFB_NO_CHANNELS_MAX ); - } - } - - -#ifdef IVAS_FLOAT_FIXED - Word16 exp_real_final = 0, exp_im_final = 0; - Word32 RealBuffer_fx[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - Word32 ImagBuffer_fx[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - Word16 i, j; - Word32 max32_real = 1, max32_im = 1; - - for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) - { - for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) - { - for ( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) - { - max32_real = (Word32) L_max( max32_real, L_abs( (Word32) RealBuffer[i][j][k] ) ); - max32_im = (Word32) L_max( max32_im, L_abs( (Word32) ImagBuffer[i][j][k] ) ); - } - } - } - Word16 exp_real = norm_l( max32_real ); - Word16 exp_im = norm_l( max32_im ); - exp_real = exp_im = min( exp_real, exp_im ); - for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) - { - for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) - { - for ( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) - { - RealBuffer_fx[i][j][k] = (Word32) float_to_fix( RealBuffer[i][j][k], exp_real ); - exp_real_final = exp_real; - ImagBuffer_fx[i][j][k] = (Word32) float_to_fix( ImagBuffer[i][j][k], exp_im ); - exp_im_final = exp_im; - } - } - } -#endif - /* Head rotation in HOA3 or CICPx */ - if ( hCombinedOrientationData != NULL && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] && hBinRenderer->rotInCldfb ) - { - if ( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 ) - { -#ifdef IVAS_FLOAT_FIXED - for ( i = 0; i < 3; i++ ) - { - for ( j = 0; j < 3; j++ ) - { - hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx][i][j] = (Word32) float_to_fix( hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx][i][j], 30 ); - } - } - /* Rotation in SHD (HOA3) */ - if ( hCombinedOrientationData->shd_rot_max_order == -1 ) - { - rotateFrame_shd_cldfb( RealBuffer_fx, ImagBuffer_fx, hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 ); - exp_real_final--; //( exp_real + 14 - 15 ) - exp_im_final--; //( exp_im + 14 - 15 ) - } - else if ( hCombinedOrientationData->shd_rot_max_order > 0 ) - { - rotateFrame_shd_cldfb( RealBuffer_fx, ImagBuffer_fx, hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, hCombinedOrientationData->shd_rot_max_order ); - exp_real_final--; //( exp_real + 14 - 15 ) - exp_im_final--; //( exp_im + 14 - 15 ) - } - - -#else - /* Rotation in SHD (HOA3) */ - if ( hCombinedOrientationData->shd_rot_max_order == -1 ) - { - rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 ); - } - else if ( hCombinedOrientationData->shd_rot_max_order > 0 ) - { - rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, hCombinedOrientationData->shd_rot_max_order ); - } -#endif - } - else - { - /* Rotation in SD (CICPx) */ -#ifndef IVAS_FLOAT_FIXED - rotateFrame_sd_cldfb( hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], RealBuffer, ImagBuffer, hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band ); -#else - rotateFrame_sd_cldfb_fixed( hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx], RealBuffer_fx, ImagBuffer_fx, - hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band ); -#endif - } - } - - /* HOA decoding to CICP19 if needed*/ - if ( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 && hBinRenderer->nInChannels != 16 ) - { -#ifndef IVAS_FLOAT_FIXED - ivas_sba2mc_cldfb( *( hBinRenderer->hInputSetup ), RealBuffer, ImagBuffer, hBinRenderer->nInChannels, hBinRenderer->conv_band, numTimeSlots, hBinRenderer->hoa_dec_mtx ); -#else - ivas_sba2mc_cldfb_fixed( *( hBinRenderer->hInputSetup ), RealBuffer_fx, ImagBuffer_fx, - hBinRenderer->nInChannels, hBinRenderer->conv_band, numTimeSlots, hBinRenderer->hoa_dec_mtx ); -#endif - } -#ifndef IVAS_FLOAT_FIXED - ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer ); -#else - Word64 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - Word64 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - for ( j = 0; j < numTimeSlots; j++ ) - { - set64_fx( Cldfb_RealBuffer_Binaural_fx[i][j], 0, hBinRenderer->conv_band ); - set64_fx( Cldfb_ImagBuffer_Binaural_fx[i][j], 0, hBinRenderer->conv_band ); - } - } - ivas_binRenderer_filterModule_fx( Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx, RealBuffer_fx, ImagBuffer_fx, numTimeSlots, hBinRenderer, exp_real_final ); -#endif - - /* Obtain the binaural dmx and compute the reverb */ - if ( hBinRenderer->hReverb != NULL ) - { -#ifndef IVAS_FLOAT_FIXED - float reverbRe[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - float reverbIm[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - float inRe[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - float inIm[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - - ivas_binaural_obtain_DMX( numTimeSlots, hBinRenderer, RealBuffer, ImagBuffer, inRe, inIm ); - - for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) - { - for ( k = 0; k < numTimeSlots; k++ ) - { - set_zero( reverbRe[chIdx][k], hBinRenderer->max_band ); - set_zero( reverbIm[chIdx][k], hBinRenderer->max_band ); - } - } - - ivas_binaural_reverb_processSubframe( hBinRenderer->hReverb, BINAURAL_CHANNELS, numTimeSlots, inRe, inIm, reverbRe, reverbIm ); - - /* Add the conv module and reverb module output */ - for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) - { - for ( k = 0; k < numTimeSlots; k++ ) - { - /* Combine first and second parts to generate binaural output signal with room effect */ - v_add( Cldfb_RealBuffer_Binaural[chIdx][k], reverbRe[chIdx][k], Cldfb_RealBuffer_Binaural[chIdx][k], hBinRenderer->conv_band ); - v_add( Cldfb_ImagBuffer_Binaural[chIdx][k], reverbIm[chIdx][k], Cldfb_ImagBuffer_Binaural[chIdx][k], hBinRenderer->conv_band ); - } - } -#else - //float reverbRe[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - //float reverbIm[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - Word32 reverbRe_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - Word32 reverbIm_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - Word64 reverbRe_fx_64[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - Word64 reverbIm_fx_64[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - //float inRe[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - //float inIm[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - Word32 inRe_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - Word32 inIm_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; - - ivas_binaural_obtain_DMX_fx( numTimeSlots, hBinRenderer, RealBuffer_fx, ImagBuffer_fx, inRe_fx, inIm_fx ); - // inRe_fx Q = exp_real_final - Q1 - - FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) - { - FOR( k = 0; k < numTimeSlots; k++ ) - { - set32_fx( reverbRe_fx[chIdx][k], 0, hBinRenderer->max_band ); - set32_fx( reverbIm_fx[chIdx][k], 0, hBinRenderer->max_band ); - } - } - - ivas_binaural_reverb_processSubframe_fx( hBinRenderer->hReverb, BINAURAL_CHANNELS, numTimeSlots, inRe_fx, inIm_fx, reverbRe_fx, reverbIm_fx ); - // reverbRe_fx Q = exp_real_final + Q30 // - - FOR(i = 0; i < BINAURAL_CHANNELS; i++) - { - FOR(j = 0; j < numTimeSlots; j++) - { - - FOR(k = 0; k < hBinRenderer->hReverb->numBins; k++) - { - reverbRe_fx_64[i][j][k] = W_shl(reverbRe_fx[i][j][k], Q29); - reverbIm_fx_64[i][j][k] = W_shl(reverbIm_fx[i][j][k], Q29); - } - } - } - - /* Add the conv module and reverb module output */ - FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) - { - FOR( k = 0; k < numTimeSlots; k++ ) - { - /* Combine first and second parts to generate binaural output signal with room effect */ - v_add_w64( Cldfb_RealBuffer_Binaural_fx[chIdx][k], reverbRe_fx_64[chIdx][k], Cldfb_RealBuffer_Binaural_fx[chIdx][k], hBinRenderer->conv_band, 0 ); - v_add_w64( Cldfb_ImagBuffer_Binaural_fx[chIdx][k], reverbIm_fx_64[chIdx][k], Cldfb_ImagBuffer_Binaural_fx[chIdx][k], hBinRenderer->conv_band, 0 ); - } - } -#endif - } -#ifdef IVAS_FLOAT_FIXED - for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) - { - for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) - { - for ( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) - { - RealBuffer[i][j][k] = fix_to_float( RealBuffer_fx[i][j][k], exp_real_final ); - ImagBuffer[i][j][k] = fix_to_float( ImagBuffer_fx[i][j][k], exp_im_final ); - } - } - } - - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - for ( j = 0; j < numTimeSlots; j++ ) - { - for ( k = 0; k < hBinRenderer->conv_band; k++ ) - { - Cldfb_RealBuffer_Binaural[i][j][k] = fix_W64_to_float( Cldfb_RealBuffer_Binaural_fx[i][j][k], ( exp_real_final + Q29 ) ); - Cldfb_ImagBuffer_Binaural[i][j][k] = fix_W64_to_float( Cldfb_ImagBuffer_Binaural_fx[i][j][k], ( exp_im_final + Q29 ) ); - } - } - } -#endif - pop_wmops(); - return; -} - #ifdef IVAS_FLOAT_FIXED void ivas_binRenderer_fx( BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ @@ -3282,5 +2717,97 @@ void ivas_binRenderer_fx( pop_wmops(); return; } +#else +void ivas_binRenderer( + BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle*/ + const int16_t numTimeSlots, /* i : number of time slots to render */ + float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ + float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ + float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ + float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] /* i : LS signals */ +) +{ + int16_t chIdx, k; + + push_wmops( "fastconv_binaural_rendering" ); -#endif \ No newline at end of file + /* Compute Convolution */ + /* memory reset for the binaural output */ + for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) + { + for ( k = 0; k < numTimeSlots; k++ ) + { + set_zero( Cldfb_RealBuffer_Binaural[chIdx][k], CLDFB_NO_CHANNELS_MAX ); + set_zero( Cldfb_ImagBuffer_Binaural[chIdx][k], CLDFB_NO_CHANNELS_MAX ); + } + } + + /* Head rotation in HOA3 or CICPx */ + if ( hCombinedOrientationData != NULL && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] && hBinRenderer->rotInCldfb ) + { + if ( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 ) + { + /* Rotation in SHD (HOA3) */ + if ( hCombinedOrientationData->shd_rot_max_order == -1 ) + { + rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 ); + } + else if ( hCombinedOrientationData->shd_rot_max_order > 0 ) + { + rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, hCombinedOrientationData->shd_rot_max_order ); + } + } + else + { + /* Rotation in SD (CICPx) */ + rotateFrame_sd_cldfb( hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], RealBuffer, ImagBuffer, hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band ); + } + } + + /* HOA decoding to CICP19 if needed*/ + if ( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 && hBinRenderer->nInChannels != 16 ) + { + ivas_sba2mc_cldfb( *( hBinRenderer->hInputSetup ), RealBuffer, ImagBuffer, hBinRenderer->nInChannels, hBinRenderer->conv_band, numTimeSlots, hBinRenderer->hoa_dec_mtx ); + } + + ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer ); + + + /* Obtain the binaural dmx and compute the reverb */ + if ( hBinRenderer->hReverb != NULL ) + { + float reverbRe[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float reverbIm[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float inRe[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float inIm[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + + ivas_binaural_obtain_DMX( numTimeSlots, hBinRenderer, RealBuffer, ImagBuffer, inRe, inIm ); + + for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) + { + for ( k = 0; k < numTimeSlots; k++ ) + { + set_zero( reverbRe[chIdx][k], hBinRenderer->max_band ); + set_zero( reverbIm[chIdx][k], hBinRenderer->max_band ); + } + } + + ivas_binaural_reverb_processSubframe( hBinRenderer->hReverb, BINAURAL_CHANNELS, numTimeSlots, inRe, inIm, reverbRe, reverbIm ); + + /* Add the conv module and reverb module output */ + for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) + { + for ( k = 0; k < numTimeSlots; k++ ) + { + /* Combine first and second parts to generate binaural output signal with room effect */ + v_add( Cldfb_RealBuffer_Binaural[chIdx][k], reverbRe[chIdx][k], Cldfb_RealBuffer_Binaural[chIdx][k], hBinRenderer->conv_band ); + v_add( Cldfb_ImagBuffer_Binaural[chIdx][k], reverbIm[chIdx][k], Cldfb_ImagBuffer_Binaural[chIdx][k], hBinRenderer->conv_band ); + } + } + } + + pop_wmops(); + return; +} +#endif diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 6591023f2e0ec2cd366446c25b326a6c11825be9..0e9a1d5289a8cfd73ba3be3d006fdffad409d5e8 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -1170,6 +1170,16 @@ ivas_error ivas_init_decoder_front( { return error; } +#ifdef IVAS_FLOAT_FIXED + for ( Word16 i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + st_ivas->hExtOrientationData->Quaternions[i].w = fixedToFloat_32( st_ivas->hExtOrientationData->Quaternions[i].w_fx, st_ivas->hExtOrientationData->Quaternions[i].q_fact ); + st_ivas->hExtOrientationData->Quaternions[i].x = fixedToFloat_32( st_ivas->hExtOrientationData->Quaternions[i].x_fx, st_ivas->hExtOrientationData->Quaternions[i].q_fact ); + st_ivas->hExtOrientationData->Quaternions[i].y = fixedToFloat_32( st_ivas->hExtOrientationData->Quaternions[i].y_fx, st_ivas->hExtOrientationData->Quaternions[i].q_fact ); + st_ivas->hExtOrientationData->Quaternions[i].z = fixedToFloat_32( st_ivas->hExtOrientationData->Quaternions[i].z_fx, st_ivas->hExtOrientationData->Quaternions[i].q_fact ); + } + +#endif } /*-------------------------------------------------------------------* @@ -1182,6 +1192,33 @@ ivas_error ivas_init_decoder_front( { return error; } +#ifdef IVAS_FLOAT_FIXED + for ( Word16 i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + st_ivas->hCombinedOrientationData->Quaternions[i].w = fixedToFloat_32( st_ivas->hCombinedOrientationData->Quaternions[i].w_fx, st_ivas->hCombinedOrientationData->Quaternions[i].q_fact ); + st_ivas->hCombinedOrientationData->Quaternions[i].x = fixedToFloat_32( st_ivas->hCombinedOrientationData->Quaternions[i].x_fx, st_ivas->hCombinedOrientationData->Quaternions[i].q_fact ); + st_ivas->hCombinedOrientationData->Quaternions[i].y = fixedToFloat_32( st_ivas->hCombinedOrientationData->Quaternions[i].y_fx, st_ivas->hCombinedOrientationData->Quaternions[i].q_fact ); + st_ivas->hCombinedOrientationData->Quaternions[i].z = fixedToFloat_32( st_ivas->hCombinedOrientationData->Quaternions[i].z_fx, st_ivas->hCombinedOrientationData->Quaternions[i].q_fact ); + + st_ivas->hCombinedOrientationData->listenerPos[i].x = fixedToFloat_32( st_ivas->hCombinedOrientationData->listenerPos[i].x_fx, st_ivas->hCombinedOrientationData->listenerPos[i].q_fact ); + st_ivas->hCombinedOrientationData->listenerPos[i].y = fixedToFloat_32( st_ivas->hCombinedOrientationData->listenerPos[i].y_fx, st_ivas->hCombinedOrientationData->listenerPos[i].q_fact ); + st_ivas->hCombinedOrientationData->listenerPos[i].z = fixedToFloat_32( st_ivas->hCombinedOrientationData->listenerPos[i].z_fx, st_ivas->hCombinedOrientationData->listenerPos[i].q_fact ); + for ( Word16 j = 0; j < 3; j++ ) + { + for ( Word16 k = 0; k < 3; k++ ) + { + st_ivas->hCombinedOrientationData->Rmat[i][j][k] = (float) fixedToFloat_32( st_ivas->hCombinedOrientationData->Rmat_fx[i][j][k], 30 ); + } + } + } + for ( Word16 j = 0; j < 3; j++ ) + { + for ( Word16 k = 0; k < 3; k++ ) + { + st_ivas->hCombinedOrientationData->Rmat_prev[j][k] = (float) fixedToFloat_32( st_ivas->hCombinedOrientationData->Rmat_prev_fx[j][k], 30 ); + } + } +#endif } /*-------------------------------------------------------------------* @@ -4116,8 +4153,11 @@ void ivas_destroy_dec( #endif /* Fastconv binaural renderer handle */ +#ifdef IVAS_FLOAT_FIXED + ivas_binRenderer_close_fx( &st_ivas->hBinRenderer ); +#else ivas_binRenderer_close( &st_ivas->hBinRenderer ); - +#endif /* Parametric binaural renderer handle */ ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 37f986184e331ba806cee4a8a22fe3e5fda712bf..de9b4c93219e0da7a961ee515e3ace26a117a4dd 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -2024,7 +2024,7 @@ static ivas_error ivas_mc_dec_reconfig( /* remove unneeded binaural renderers */ IF ( st_ivas->hBinRenderer != NULL && ( NE_16(st_ivas->renderer_type , RENDERER_BINAURAL_FASTCONV) && NE_16(st_ivas->renderer_type , RENDERER_BINAURAL_FASTCONV_ROOM) ) ) { - ivas_binRenderer_close( &st_ivas->hBinRenderer ); + ivas_binRenderer_close_fx( &st_ivas->hBinRenderer ); } IF ( ( st_ivas->hCrendWrapper != NULL ) && ( st_ivas->hCrendWrapper->hCrend != NULL ) && ( NE_16(st_ivas->renderer_type , RENDERER_BINAURAL_MIXER_CONV) && NE_16(st_ivas->renderer_type , RENDERER_BINAURAL_MIXER_CONV_ROOM) && ( NE_16(st_ivas->renderer_type , RENDERER_BINAURAL_OBJECTS_TD) || NE_16(st_ivas->hIntSetup.output_config , IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB) ) ) ) diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 2d2779d814cc91de914df694dcd701e34c226da1..a169d6683a27af1734735905a973f44748ab19a5 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -1330,7 +1330,7 @@ ivas_error ivas_sba_dec_reconfigure_fx( } else if ( st_ivas->hBinRenderer != NULL && ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV && st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV_ROOM ) ) { - ivas_binRenderer_close( &st_ivas->hBinRenderer ); + ivas_binRenderer_close_fx( &st_ivas->hBinRenderer ); } if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX && st_ivas->hMonoDmxRenderer == NULL ) diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index b549879e01187f92a9c3237bb780a1787e3535cb..23e2d0746695edb0616315a1e3cc108f4a8c7641 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -791,22 +791,23 @@ static void stereo_dft_generate_comfort_noise_fx( IF( hStereoCng->first_SID_after_TD ) { - Word16 q_div, q_sqrt; - scaleAvg = 0; - move16(); - FOR( b = 0; b < hStereoDft->nbands; b++ ) + Word16 q_div, q_sqrt, q_sqrt2; + scaleAvg = 0; move16(); + FOR ( b = 0; b < hStereoDft->nbands; b++ ) { - Word32 tmp_n, tmp_d; + Word32 tmp_n, tmp_d, tmp_32, tmp_32_2; Word16 sqrt_res; IF( LT_16( hStereoCng->cm_fx[b], (Word32) ( 0x7333 ) ) ) { gamma = hStereoCng->cm_fx[b]; move16(); - gamma = BASOP_Util_Divide1616_Scale( gamma, sub( MAX_16, gamma ), &q_div ); - tmp_16 = Sqrt16( gamma, &q_div ); - gamma = Sqrt16( add( gamma, sub( MAX_16, mult( hStereoDft->g_state_fx[b], hStereoDft->g_state_fx[b] ) ) ), &q_sqrt ); - gamma = shl( gamma, sub( q_sqrt, q_div ) ); // Bring both gamma and tmp to same Q i.e., q_div. - gamma = shl( sub( gamma, tmp_16 ), q_div ); // Apply appropriate left shift on the result. + gamma = BASOP_Util_Divide1616_Scale(gamma , sub( MAX_16 , gamma ), &q_div); + q_sqrt2 = q_div+16; + tmp_32_2 = Sqrt32(gamma, &q_sqrt2); + tmp_32 = BASOP_Util_Add_Mant32Exp(gamma, 16+q_div, sub(MAX_16, mult(hStereoDft->g_state_fx[b], hStereoDft->g_state_fx[b])), 16, &q_sqrt); + tmp_32 = Sqrt32( tmp_32, &q_sqrt); + tmp_32 = BASOP_Util_Add_Mant32Exp(tmp_32, q_sqrt, L_negate(tmp_32_2), q_sqrt2, &q_sqrt); + gamma = extract_h(L_shl(tmp_32, q_sqrt)); } ELSE { @@ -843,7 +844,7 @@ static void stereo_dft_generate_comfort_noise_fx( scaleAvg = add( scaleAvg, shr( scaleMS, sub( Q15, q_sqrt ) ) ); } scaleAvg = BASOP_Util_Divide1616_Scale( scaleAvg, hStereoDft->nbands, &q_div ); - hStereoDft->scale_fx = shl( scaleAvg, q_div ); + hStereoDft->scale_fx = shl_sat( scaleAvg, q_div ); } } @@ -1169,11 +1170,11 @@ static void stereo_dft_generate_comfort_noise_fx( /* Real part in FFT bins */ rand_gauss_fx( ptr_r, &st->hTdCngDec->cng_seed, q_dft); //ptr_shb will be in Q30 - rshift at this point. So apply left shift by 1 to compensate Mpy_32_32 right shift.. - ( *ptr_r ) = L_shl(Mpy_32_32(L_shl(*ptr_r, add(1, *ptr_q_shb)), *ptr_shb), rshift_shb); move32(); + ( *ptr_r ) = W_extract_l(W_shl(W_mult0_32_32(*ptr_r, *ptr_shb), sub(add(rshift_shb, add(1, *ptr_q_shb)), 31))); move32(); ptr_r += 2; /* Imaginary part in FFT bins */ rand_gauss_fx( ptr_i, &st->hTdCngDec->cng_seed, q_dft); - ( *ptr_i ) = L_shl(Mpy_32_32(L_shl(*ptr_i, add(1, *ptr_q_shb)), *ptr_shb), rshift_shb); move32(); + ( *ptr_i ) = W_extract_l(W_shl(W_mult0_32_32(*ptr_i, *ptr_shb), sub(add(rshift_shb, add(1, *ptr_q_shb)), 31))); move32(); ptr_i += 2; ptr_shb--; } @@ -1185,9 +1186,9 @@ static void stereo_dft_generate_comfort_noise_fx( ptr_i = ptr_r + 1; FOR( i = 0; i < shr( sub( s_min( output_frame, shl( hFdCngCom->regularStopBand, 4 ) ), hFdCngCom->stopFFTbin ), 1 ); i++ ) { - ( *ptr_r ) = imult3216(L_shl(Mpy_32_16_1(*ptr_r, scale), q_div), shr(output_frame, 1)); + ( *ptr_r ) = W_extract_l(W_shl(W_mult0_32_32(Mpy_32_16_1(*ptr_r, scale), shr(output_frame, 1)), q_div)); move32(); move32(); - ( *ptr_i ) = imult3216(L_shl(Mpy_32_16_1(*ptr_i, scale), q_div), shr(output_frame, 1)); + ( *ptr_i ) = W_extract_l(W_shl(W_mult0_32_32(Mpy_32_16_1(*ptr_i, scale), shr(output_frame, 1)), q_div)); move32(); move32(); ptr_r += 2; ptr_i += 2; diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index e5e73a07e995cc9d2a79443fedd172d842f66e62..f5e7626eb4f5c19a13d450952423c90e6b0abced 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -850,8 +850,20 @@ ivas_error IVAS_DEC_GetSamples( { return error; } - - + for ( Word16 i = 0; i < hIvasDec->st_ivas->hCombinedOrientationData->num_subframes; i++ ) + { + hIvasDec->st_ivas->hCombinedOrientationData->Quaternions[i].w = fixedToFloat_32( hIvasDec->st_ivas->hCombinedOrientationData->Quaternions[i].w_fx, hIvasDec->st_ivas->hCombinedOrientationData->Quaternions[i].q_fact ); + hIvasDec->st_ivas->hCombinedOrientationData->Quaternions[i].x = fixedToFloat_32( hIvasDec->st_ivas->hCombinedOrientationData->Quaternions[i].x_fx, hIvasDec->st_ivas->hCombinedOrientationData->Quaternions[i].q_fact ); + hIvasDec->st_ivas->hCombinedOrientationData->Quaternions[i].y = fixedToFloat_32( hIvasDec->st_ivas->hCombinedOrientationData->Quaternions[i].y_fx, hIvasDec->st_ivas->hCombinedOrientationData->Quaternions[i].q_fact ); + hIvasDec->st_ivas->hCombinedOrientationData->Quaternions[i].z = fixedToFloat_32( hIvasDec->st_ivas->hCombinedOrientationData->Quaternions[i].z_fx, hIvasDec->st_ivas->hCombinedOrientationData->Quaternions[i].q_fact ); + for (Word16 j = 0; j < 3; j++ ) + { + for ( Word16 k = 0; k < 3; k++ ) + { + hIvasDec->st_ivas->hCombinedOrientationData->Rmat[i][j][k] = (float) fixedToFloat_32( hIvasDec->st_ivas->hCombinedOrientationData->Rmat_fx[i][j][k], 30 ); + } + } + } hIvasDec->updateOrientation = false; } diff --git a/lib_rend/ivas_dirac_decorr_dec.c b/lib_rend/ivas_dirac_decorr_dec.c index b1e24ca062f1582ecaf80a1d532790aaf2ab3391..412da0468b13d1730baa3cd264aa097bb2e72963 100644 --- a/lib_rend/ivas_dirac_decorr_dec.c +++ b/lib_rend/ivas_dirac_decorr_dec.c @@ -1667,10 +1667,12 @@ static void get_lattice_coeffs_fx( { Word16 k; - for ( k = 0; k < ap_filter_length[band_index]; k++ ) + FOR ( k = 0; k < ap_filter_length[band_index]; k++ ) { Word16 cur_lattice_coeff = ap_lattice_coeffs_fx[band_index][channel_index * ap_filter_length[band_index] + k]; lattice_coeffs[k] = cur_lattice_coeff; + move16(); + move16(); } return; @@ -1729,7 +1731,7 @@ static void lattice2allpass_fx( Word16 *filter_coeffs_num_real_fx, Word16 *filter_coeffs_den_real_fx) { - int16_t i, p; + Word16 i, p; #ifdef IVAS_FLOAT_FIXED Word16 alpha_real_fx[2][DIRAC_MAX_DECORR_FILTER_LEN + 1]; @@ -1743,7 +1745,7 @@ static void lattice2allpass_fx( float *tmp; #endif - for (i = 0; i < 2; i++) + FOR (i = 0; i < 2; i++) { #ifdef IVAS_FLOAT_FIXED set16_fx(alpha_real_fx[i], 0, DIRAC_MAX_DECORR_FILTER_LEN + 1); @@ -1755,6 +1757,8 @@ static void lattice2allpass_fx( #ifdef IVAS_FLOAT_FIXED alpha_real_p_fx[0] = ONE_IN_Q12; alpha_real_p_old_fx[0] = ONE_IN_Q12; + move16(); + move16(); #else alpha_real_p[0] = 1.0f; alpha_real_p_old[0] = 1.0f; @@ -1764,6 +1768,7 @@ static void lattice2allpass_fx( #ifdef IVAS_FLOAT_FIXED Word16 lattice_alpha = 0; + move16(); FOR (p = 1; p < filter_length; p++) { alpha_real_p_fx[p] = shr(lattice_coeffs_fx[(p - 1)], 3);//Q12 @@ -1800,6 +1805,8 @@ static void lattice2allpass_fx( { filter_coeffs_den_real_fx[i] = alpha_real_p_old_fx[i]; filter_coeffs_num_real_fx[i] = alpha_real_p_old_fx[filter_length - i - 1]; + move16(); + move16(); }//Q12 #else for (i = 0; i < filter_length; i++) diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index ebfc55f9745827dafc4c74164584836e7d64843c..9cad5d1ff966b171ac228a6c8c58b68a6fc86eab 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -6074,33 +6074,36 @@ static void computeTargetPSDs_direct_fx( Word32 aux_buffer_res[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */ /* estimate direct and diffuse power */ - v_mult_fixed( direct_power_factor, reference_power, direct_power, num_freq_bands ); // (Q31, q_reference_power) -> q_reference_power + v_mult_fixed( direct_power_factor, reference_power, direct_power, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ + + Word16 common1_q = s_min( *q_cy_auto_dir_smooth, *q_reference_power ); + Word16 common2_q = s_min( *q_cy_cross_dir_smooth, *q_reference_power ); /* compute target auto and cross PSDs of current frame (smoothed) */ FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { cur_idx = imult1616( ch_idx, num_freq_bands ); - v_mult_fixed( direct_power, &direct_responses_square[cur_idx], aux_buffer_res, num_freq_bands ); // (q_reference_power, Q31) -> q_reference_power - Scale_sig32( aux_buffer_res, num_freq_bands, sub( *q_cy_auto_dir_smooth, *q_reference_power ) ); // q_cy_auto_dir_smooth - v_add_fixed( &cy_auto_dir_smooth[cur_idx], aux_buffer_res, &cy_auto_dir_smooth[cur_idx], num_freq_bands, Q1 ); // (q_cy_auto_dir_smooth - Q1) + v_mult_fixed( direct_power, &direct_responses_square[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ + scale_sig32( aux_buffer_res, num_freq_bands, sub( common1_q, *q_reference_power ) ); /* Q(common1_q) */ + scale_sig32( &cy_auto_dir_smooth[cur_idx], num_freq_bands, sub( common1_q, *q_cy_auto_dir_smooth ) ); /* Q(common1_q) */ + v_add_fixed( &cy_auto_dir_smooth[cur_idx], aux_buffer_res, &cy_auto_dir_smooth[cur_idx], num_freq_bands, Q1 ); /* Q(common1_q) - Q1 */ - v_mult_fixed( direct_power, &direct_responses[cur_idx], aux_buffer_res, num_freq_bands ); // (q_reference_power, Q31) -> q_reference_power - Scale_sig32( aux_buffer_res, num_freq_bands, sub( *q_cy_cross_dir_smooth, *q_reference_power ) ); // q_cy_cross_dir_smooth - v_add_fixed( &cy_cross_dir_smooth[cur_idx], aux_buffer_res, &cy_cross_dir_smooth[cur_idx], num_freq_bands, Q1 ); // (q_cy_cross_dir_smooth - Q1) + v_mult_fixed( direct_power, &direct_responses[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ + scale_sig32( aux_buffer_res, num_freq_bands, sub( common2_q, *q_reference_power ) ); /* Q(common2_q) */ + scale_sig32( &cy_cross_dir_smooth[cur_idx], num_freq_bands, sub( common2_q, *q_cy_cross_dir_smooth ) ); /* Q(common2_q) */ + v_add_fixed( &cy_cross_dir_smooth[cur_idx], aux_buffer_res, &cy_cross_dir_smooth[cur_idx], num_freq_bands, Q1 ); /* Q(common2_q) - Q1 */ } /* Q adjustment */ - *q_cy_auto_dir_smooth = sub( *q_cy_auto_dir_smooth, Q1 ); + *q_cy_auto_dir_smooth = sub( common1_q, Q1 ); move16(); - *q_cy_cross_dir_smooth = sub( *q_cy_cross_dir_smooth, Q1 ); + *q_cy_cross_dir_smooth = sub( common2_q, Q1 ); move16(); return; } #else - - static void computeTargetPSDs_direct( const int16_t num_channels, const int16_t num_freq_bands, @@ -6227,28 +6230,28 @@ static void computeTargetPSDs_diffuse_fx( Word32 aux_buffer_res[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */ /* estimate direct and diffuse power */ - v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_freq_bands ); // (Q31, q_reference_power) -> q_reference_power + v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ + + Word16 common_q = s_min( *q_cy_auto_diff_smooth, *q_reference_power ); /* compute target auto and cross PSDs of current frame (smoothed) */ FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx ) { cur_idx = imult1616( ch_idx, num_freq_bands ); - v_multc_fixed( &diffuse_power[start_band], diffuse_responses_square[ch_idx], aux_buffer_res, num_freq_bands - start_band ); // (q_reference_power, Q31) -> q_reference_power - Scale_sig32( aux_buffer_res, num_freq_bands - start_band, sub( *q_cy_auto_diff_smooth, *q_reference_power ) ); // q_cy_auto_diff_smooth - Scale_sig32( &cy_auto_diff_smooth[cur_idx], start_band, negate( Q1 ) ); // (q_cy_auto_diff_smooth - Q1) - v_add_fixed( &cy_auto_diff_smooth[cur_idx + start_band], aux_buffer_res, &cy_auto_diff_smooth[cur_idx + start_band], num_freq_bands - start_band, Q1 ); // (q_cy_auto_diff_smooth - Q1) + v_multc_fixed( &diffuse_power[start_band], diffuse_responses_square[ch_idx], aux_buffer_res, num_freq_bands - start_band ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */ + scale_sig32( aux_buffer_res, num_freq_bands - start_band, sub( common_q, *q_reference_power ) ); /* Q(common_q) */ + scale_sig32( &cy_auto_diff_smooth[cur_idx + start_band], num_freq_bands - start_band, sub( common_q, *q_cy_auto_diff_smooth ) ); /* Q(common_q) */ + v_add_fixed( &cy_auto_diff_smooth[cur_idx + start_band], aux_buffer_res, &cy_auto_diff_smooth[cur_idx + start_band], num_freq_bands - start_band, Q1 ); /* Q(common_q) - Q1 */ } /* Q adjustment */ - *q_cy_auto_diff_smooth = sub( *q_cy_auto_diff_smooth, Q1 ); + *q_cy_auto_diff_smooth = sub( common_q, Q1 ); move16(); return; } #else - - static void computeTargetPSDs_diffuse( const int16_t num_channels, const int16_t num_freq_bands, diff --git a/lib_rend/ivas_objectRenderer_hrFilt.c b/lib_rend/ivas_objectRenderer_hrFilt.c index b1272616cb242717af14fbc9f809897f81aa72a8..bf59d928eed5bdc959bcf0dfee0407c6d9789adb 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt.c +++ b/lib_rend/ivas_objectRenderer_hrFilt.c @@ -441,7 +441,7 @@ static void GenerateFilter_fx( FOR( i = 0; i < num_az_idx[p]; i++ ) { modelEval->BM_fx[qp + i] = L_shl( Mpy_32_32( modelEval->elevBfVec_fx[p], modelEval->azimBfVec_fx[p][i] ), Q30 - ( Q30 * 2 - 31 ) ); // Q30 - BM_idx[qp + i] = model->azim_start_idx[EvIdx[p]] + AzIdx[p][i]; + BM_idx[qp + i] = add(model->azim_start_idx[EvIdx[p]] , AzIdx[p][i]); } qp = add( qp, num_az_idx[p] ); } @@ -927,7 +927,7 @@ static void getPeriodicBSplineSampVec_fx( FOR( i = 0; i < *num_az_idx; i++ ) { - d = d0 - ( i + nI - 1 ) * SegSamples; /* offset of knot_interval */ + d = sub(d0 , imult1616(( sub(add(i , nI) , 1) ) , SegSamples)); /* offset of knot_interval */ d = sub( d0, imult1616( sub( add( i, nI ), 1 ), SegSamples ) ); BfVec_fx[i] = azimBsShape_fx[abs_s( d ) * subSampFactor]; AzIdx[i] = add( nI, i ) % NumBFs; diff --git a/lib_rend/ivas_objectRenderer_mix.c b/lib_rend/ivas_objectRenderer_mix.c index 5696571f9e87723174876dfd45adfd23cca46302..30dbb9cd40620829b9db4f73ce8a775b39e01276 100644 --- a/lib_rend/ivas_objectRenderer_mix.c +++ b/lib_rend/ivas_objectRenderer_mix.c @@ -213,7 +213,7 @@ void TDREND_MIX_Dealloc_fx( { IF ( EQ_16(hBinRendererTd->HrFiltSet_p->FilterMethod , TDREND_HRFILT_Method_BSplineModel) ) { -#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED +#if 0 /*IVAS_FLOAT_FIXED_TO_BE_REMOVED*/ BSplineModelEvalDealloc( &hBinRendererTd->HrFiltSet_p->ModelParams, &hBinRendererTd->HrFiltSet_p->ModelEval ); #endif BSplineModelEvalDealloc_fx( &hBinRendererTd->HrFiltSet_p->ModelParams, &hBinRendererTd->HrFiltSet_p->ModelEval ); @@ -704,7 +704,7 @@ static ivas_error DefaultBSplineModel_fx( SWITCH( output_Fs ) { case 48000: -#if 1/*To be removed later : floating point pointer initialization*/ +#if 0/*To be removed later : floating point pointer initialization*/ HrFiltSet_p->lr_energy_and_iac[0] = defaultHRIR_left_avg_power_48kHz; HrFiltSet_p->lr_energy_and_iac[1] = defaultHRIR_right_avg_power_48kHz; HrFiltSet_p->lr_energy_and_iac[2] = defaultHRIR_coherence_48kHz; @@ -714,7 +714,7 @@ static ivas_error DefaultBSplineModel_fx( HrFiltSet_p->lr_energy_and_iac_fx[2] = defaultHRIR_coherence_48kHz_fx; BREAK; case 32000: -#if 1/*To be removed later : floating point pointer initialization*/ +#if 0/*To be removed later : floating point pointer initialization*/ HrFiltSet_p->lr_energy_and_iac[0] = defaultHRIR_left_avg_power_32kHz; HrFiltSet_p->lr_energy_and_iac[1] = defaultHRIR_right_avg_power_32kHz; HrFiltSet_p->lr_energy_and_iac[2] = defaultHRIR_coherence_32kHz; @@ -724,7 +724,7 @@ static ivas_error DefaultBSplineModel_fx( HrFiltSet_p->lr_energy_and_iac_fx[2] = defaultHRIR_coherence_32kHz_fx; BREAK; case 16000: -#if 1/*To be removed later : floating point pointer initialization*/ +#if 0/*To be removed later : floating point pointer initialization*/ HrFiltSet_p->lr_energy_and_iac[0] = defaultHRIR_left_avg_power_16kHz; HrFiltSet_p->lr_energy_and_iac[1] = defaultHRIR_right_avg_power_16kHz; HrFiltSet_p->lr_energy_and_iac[2] = defaultHRIR_coherence_16kHz; @@ -779,13 +779,13 @@ static ivas_error DefaultBSplineModel_fx( model->azimShapeSampFactor = defaultHRIR_rom_azimShapeSampFactor; /* float parameters */ -#if 1 /*To be removed later Floating point initializations */ +#if 0 /*To be removed later Floating point initializations */ model->elevKSeq = (const float *) defaultHRIR_rom_elevKSeq; model->elevBsShape = (const float *) defaultHRIR_rom_elevBsShape; #endif // 1 model->elevKSeq_fx = defaultHRIR_rom_elevKSeq_fx; model->elevBsShape_fx = (const Word32 *) defaultHRIR_rom_elevBsShape_fx; -#if 1 /*To be removed later : Floating point memory allocation*/ +#if 0 /*To be removed later : Floating point memory allocation*/ IF ( ( model->azimBsShape = (const float **) malloc( model->num_unique_azim_splines * sizeof( float * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) ); @@ -836,7 +836,7 @@ static ivas_error DefaultBSplineModel_fx( FOR ( i = 1; i < model->elevDim3 - 1; i++ ) { -#if 1 /*To be removed later : Floating point initialization*/ +#if 0 /*To be removed later : Floating point initialization*/ IF ( ( model->azimKSeq[i] = (float *) malloc( model->azimDim2[i] * sizeof( float * ) ) ) == NULL ) /* azimDim2[i] = 91, i=2..15 */ { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) ); @@ -860,7 +860,7 @@ static ivas_error DefaultBSplineModel_fx( SWITCH ( output_Fs ) { case 48000: -#if 1/*To be removed later : floating point pointer initialization*/ +#if 0/*To be removed later : floating point pointer initialization*/ model->AlphaL = (const float *) defaultHRIR_rom_AlphaL48; model->AlphaR = (const float *) defaultHRIR_rom_AlphaR48; model->EL = (const float *) defaultHRIR_rom_EL48; @@ -891,7 +891,7 @@ static ivas_error DefaultBSplineModel_fx( } BREAK; case 32000: -#if 1/*To be removed later : floating point pointer initialization*/ +#if 0/*To be removed later : floating point pointer initialization*/ model->AlphaL = (const float *) defaultHRIR_rom_AlphaL32; model->AlphaR = (const float *) defaultHRIR_rom_AlphaR32; model->EL = (const float *) defaultHRIR_rom_EL32; @@ -922,7 +922,7 @@ static ivas_error DefaultBSplineModel_fx( } BREAK; case 16000: -#if 1/*To be removed later : floating point pointer initialization*/ +#if 0/*To be removed later : floating point pointer initialization*/ model->AlphaL = (const float *) defaultHRIR_rom_AlphaL16; model->AlphaR = (const float *) defaultHRIR_rom_AlphaR16; model->EL = (const float *) defaultHRIR_rom_EL16; @@ -984,7 +984,7 @@ static ivas_error DefaultBSplineModel_fx( move16(); modelITD->elevBsStart[3] = 21; move16(); -#if 1/*To be removed later : floating point pointer initialization*/ +#if 0/*To be removed later : floating point pointer initialization*/ modelITD->elevKSeq = defaultHRIR_rom_ITD_elevKSeq; #endif modelITD->elevKSeq_fx = defaultHRIR_rom_ITD_elevKSeq_fx; @@ -1008,7 +1008,7 @@ static ivas_error DefaultBSplineModel_fx( modelITD->azimSegSamples = 10; move16(); -#if 1/*To be removed later : floating point pointer initialization*/ +#if 0/*To be removed later : floating point pointer initialization*/ modelITD->azimKSeq = defaultHRIR_rom_ITD_azimKSeq; modelITD->W = (const float *) defaultHRIR_rom_ITD_W; modelITD->azimBsShape = (const float *) defaultHRIR_rom_ITD_azimBsShape; diff --git a/lib_rend/ivas_objectRenderer_vec.c b/lib_rend/ivas_objectRenderer_vec.c index 243001e2630f05e9d16285c70b1dda6f5b2daafe..e389ed74b6307376a3e7e22d1323a4a9bde8d79f 100644 --- a/lib_rend/ivas_objectRenderer_vec.c +++ b/lib_rend/ivas_objectRenderer_vec.c @@ -159,7 +159,7 @@ void TDREND_SPATIAL_VecNormalize_fx( exp = add( exp, sub( 31, q ) ); // Since vector is normalised, all values will be <= 1. Hence making all values in Q30 - shift = exp - 1; + shift = sub(exp , 1); VecNorm_p_fx[0] = L_shl( VecNorm_p_fx[0], shift ); move16(); VecNorm_p_fx[1] = L_shl( VecNorm_p_fx[1], shift ); diff --git a/lib_rend/ivas_reverb_delay_line.c b/lib_rend/ivas_reverb_delay_line.c index d8307be755972c60ae8eca3b888a31221f681c36..929597973065f316a08435c36015371b8c4549eb 100644 --- a/lib_rend/ivas_reverb_delay_line.c +++ b/lib_rend/ivas_reverb_delay_line.c @@ -58,20 +58,25 @@ void ivas_rev_delay_line_init( ) { pDelay->MaxDelay = maxdelay; + move16(); - if ( delay <= pDelay->MaxDelay ) + IF ( LE_32(delay , pDelay->MaxDelay) ) { pDelay->Delay = delay; } - else + ELSE { pDelay->Delay = pDelay->MaxDelay; } + move16(); pDelay->pBuffer_fx = memory_buffer; + move32(); set_val_Word32( pDelay->pBuffer_fx, 0, pDelay->MaxDelay ); pDelay->BufferPos = 0; + move16(); pDelay->Gain_fx = ONE_IN_Q14; + move16(); return; } @@ -88,10 +93,12 @@ void ivas_rev_delay_line_feed_sample_fx( ) { pDelay->pBuffer_fx[pDelay->BufferPos++] = input; + move32(); - if ( pDelay->BufferPos >= pDelay->Delay ) + IF ( GE_32(pDelay->BufferPos , pDelay->Delay) ) { pDelay->BufferPos = 0; + move16(); } return; @@ -227,41 +234,48 @@ void ivas_rev_delay_line_feed_sample_blk_fx( UWord16 i, pos; pos = (UWord16) pDelay->BufferPos; + move16(); - if ( pos + blk_size > (UWord16) pDelay->Delay ) /* splitting block in 2 if it exceeds buffer end limit */ + IF ( GT_32(L_add(pos , blk_size) , pDelay->Delay) ) /* splitting block in 2 if it exceeds buffer end limit */ { UWord16 blk_size_1; /* 1st block up to the end of the buffer */ UWord16 blk_size_2; /* 2nd block at the beginning of the buffer */ - blk_size_1 = (UWord16) pDelay->Delay - pos; - blk_size_2 = blk_size - blk_size_1; + blk_size_1 = (UWord16) L_sub(pDelay->Delay , pos); + blk_size_2 = (UWord16) L_sub(blk_size , blk_size_1); pDst = &pDelay->pBuffer_fx[pos]; - for ( i = 0; i < blk_size_1; i++ ) + FOR ( i = 0; i < blk_size_1; i++ ) { pDst[i] = input[i]; + move32(); } pDst = &pDelay->pBuffer_fx[0]; pSrc = &input[blk_size_1]; - for ( i = 0; i < blk_size_2; i++ ) + FOR ( i = 0; i < blk_size_2; i++ ) { pDst[i] = pSrc[i]; + move32(); } pos = blk_size_2; + move16(); } - else /* copy only 1 data block directly if it fits in the buffer */ + ELSE /* copy only 1 data block directly if it fits in the buffer */ { pDst = &pDelay->pBuffer_fx[pos]; - for ( i = 0; i < blk_size; i++ ) + FOR ( i = 0; i < blk_size; i++ ) { pDst[i] = input[i]; + move32(); } - pos += blk_size; + pos = (UWord16)L_add(pos,blk_size); } pDelay->BufferPos = pos; + move16(); - if ( pDelay->BufferPos >= pDelay->Delay ) + IF ( GE_32(pDelay->BufferPos , pDelay->Delay) ) { pDelay->BufferPos = 0; + move16(); } return; @@ -278,15 +292,15 @@ Word32 ivas_rev_delay_line_get_sample_fx( ivas_rev_delay_line_t *pDelay /* i/o: the delay line */ ) { - if ( pDelay->Gain_fx == ONE_IN_Q14 ) + IF ( EQ_16(pDelay->Gain_fx , ONE_IN_Q14) ) { return pDelay->pBuffer_fx[pDelay->BufferPos]; } - else + ELSE { - return (Mpy_32_16_r( pDelay->pBuffer_fx[pDelay->BufferPos], pDelay->Gain_fx) << 1); + return (L_shl(Mpy_32_16_r( pDelay->pBuffer_fx[pDelay->BufferPos], pDelay->Gain_fx) , 1)); } } /*-----------------------------------------------------------------------------------------* @@ -307,58 +321,63 @@ void ivas_rev_delay_line_get_sample_blk_fx( pos = (UWord16) pDelay->BufferPos; gain = pDelay->Gain_fx; + move16(); + move16(); - if ( pos + blk_size > (UWord16) pDelay->Delay ) /* splitting block in 2 if it exceeds buffer end limit */ + IF ( GT_32(L_add(pos , blk_size) , pDelay->Delay) ) /* splitting block in 2 if it exceeds buffer end limit */ { UWord16 blk_size_1; /* 1st block up to the end of the buffer */ UWord16 blk_size_2; /* 2nd block at the beginning of the buffer */ - blk_size_1 = (UWord16) pDelay->Delay - pos; - blk_size_2 = blk_size - blk_size_1; + blk_size_1 = (UWord16)L_sub(pDelay->Delay , pos); + blk_size_2 = (UWord16)L_sub(blk_size , blk_size_1); pSrc = &pDelay->pBuffer_fx[pos]; - if ( gain == ONE_IN_Q14 ) + IF ( EQ_16(gain , ONE_IN_Q14) ) { - for ( i = 0; i < blk_size_1; i++ ) + FOR ( i = 0; i < blk_size_1; i++ ) { output[i] = pSrc[i]; + move32(); } pSrc = &pDelay->pBuffer_fx[0]; pDst = &output[blk_size_1]; - for ( i = 0; i < blk_size_2; i++ ) + FOR ( i = 0; i < blk_size_2; i++ ) { pDst[i] = pSrc[i]; + move32(); } } - else + ELSE { - for ( i = 0; i < blk_size_1; i++ ) + FOR ( i = 0; i < blk_size_1; i++ ) { - output[i] = Mpy_32_16_r( pSrc[i],gain ) << 1; + output[i] = L_shl(Mpy_32_16_r( pSrc[i],gain ) , 1); } pSrc = &pDelay->pBuffer_fx[0]; pDst = &output[blk_size_1]; - for ( i = 0; i < blk_size_2; i++ ) + FOR ( i = 0; i < blk_size_2; i++ ) { - pDst[i] = Mpy_32_16_r(pSrc[i],gain ) << 1; + pDst[i] = L_shl(Mpy_32_16_r(pSrc[i],gain ) , 1); } } } - else /* copy only 1 data block directly if it fits in the buffer */ + ELSE /* copy only 1 data block directly if it fits in the buffer */ { pSrc = &pDelay->pBuffer_fx[pos]; - if ( gain == ONE_IN_Q14 ) + IF ( EQ_16(gain , ONE_IN_Q14) ) { - for ( i = 0; i < blk_size; i++ ) + FOR ( i = 0; i < blk_size; i++ ) { output[i] = pSrc[i]; + move32(); } } - else + ELSE { - for ( i = 0; i < blk_size; i++ ) + FOR ( i = 0; i < blk_size; i++ ) { - output[i] = Mpy_32_16_r( pSrc[i], gain ) << 1; + output[i] = L_shl(Mpy_32_16_r( pSrc[i], gain ) , 1); } } } diff --git a/lib_rend/ivas_rom_binauralRenderer.c b/lib_rend/ivas_rom_binauralRenderer.c index 9bd2b542d4cbe65a60be631e52f0fbd7d56dc5a3..8233d16ef722e725161d321ec690c9259e21be08 100644 --- a/lib_rend/ivas_rom_binauralRenderer.c +++ b/lib_rend/ivas_rom_binauralRenderer.c @@ -53,6 +53,7 @@ +const Word32 FASTCONV_HOA3_latency_s_fx = 20833; const float FASTCONV_HOA3_latency_s = 0.000020833f; const Word32 leftHRIRReal_HOA3_fx[BINAURAL_CONVBANDS][HOA3_CHANNELS][BINAURAL_NTAPS_SBA]= { @@ -7288,6 +7289,7 @@ const float rightHRIRImag_HOA3[BINAURAL_CONVBANDS][HOA3_CHANNELS][BINAURAL_NTAPS +const Word32 FASTCONV_HOA2_latency_s_fx = 20833; const float FASTCONV_HOA2_latency_s = 0.000020833f; const Word32 leftHRIRReal_HOA2_fx[BINAURAL_CONVBANDS][HOA2_CHANNELS][BINAURAL_NTAPS_SBA]= { @@ -11723,6 +11725,7 @@ const float rightHRIRImag_HOA2[BINAURAL_CONVBANDS][HOA2_CHANNELS][BINAURAL_NTAPS +const Word32 FASTCONV_FOA_latency_s_fx = 20833; const float FASTCONV_FOA_latency_s = 0.000020833f; const Word32 leftHRIRReal_FOA_fx[BINAURAL_CONVBANDS][FOA_CHANNELS][BINAURAL_NTAPS_SBA]= { @@ -14157,6 +14160,7 @@ const float rightHRIRImag_FOA[BINAURAL_CONVBANDS][FOA_CHANNELS][BINAURAL_NTAPS_S }; +const Word32 FASTCONV_HRIR_latency_s_fx = 666667; const float FASTCONV_HRIR_latency_s = 0.000666667f; const Word32 leftHRIRReal_fx[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]= { @@ -21731,6 +21735,7 @@ const float hrtfShCoeffsIm[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BINS]= /* Binaural rendering data set based on BRIRs */ /* Tables derived from Mozart IIS BRIRs.*/ +const Word32 FASTCONV_BRIR_latency_s_fx = 937500; const float FASTCONV_BRIR_latency_s = 0.000937500f; const Word32 leftBRIRReal_fx[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS_MAX]= { diff --git a/lib_rend/ivas_rom_binauralRenderer.h b/lib_rend/ivas_rom_binauralRenderer.h index a65192ac82ee960b3bdd1a96f66eaa4a7d8d4e33..b0258ccddeaf112ed2e94feafb04e9398cd1974b 100644 --- a/lib_rend/ivas_rom_binauralRenderer.h +++ b/lib_rend/ivas_rom_binauralRenderer.h @@ -40,6 +40,7 @@ *------------------------------------------------------------------------*/ /* Binaural rendering data set based on HRIRs */ +extern const Word32 FASTCONV_HRIR_latency_s_fx; extern const float FASTCONV_HRIR_latency_s; extern float leftHRIRReal_HOA3[BINAURAL_CONVBANDS][HOA3_CHANNELS][BINAURAL_NTAPS_SBA]; extern float leftHRIRImag_HOA3[BINAURAL_CONVBANDS][HOA3_CHANNELS][BINAURAL_NTAPS_SBA]; @@ -77,6 +78,9 @@ extern Word32 leftHRIRImag_fx[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTA extern Word32 rightHRIRReal_fx[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]; extern Word32 rightHRIRImag_fx[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS]; +extern Word32 FASTCONV_HOA3_latency_s_fx; +extern Word32 FASTCONV_HOA2_latency_s_fx; +extern Word32 FASTCONV_FOA_latency_s_fx; extern float FASTCONV_HOA3_latency_s; extern float FASTCONV_HOA2_latency_s; extern float FASTCONV_FOA_latency_s; @@ -89,6 +93,7 @@ extern Word16 hrtfShCoeffsIm_fx[BINAURAL_CHANNELS][HRTF_SH_CHANNELS][HRTF_NUM_BI /* Binaural rendering data set based on BRIRs */ +extern const Word32 FASTCONV_BRIR_latency_s_fx; extern const float FASTCONV_BRIR_latency_s; extern float leftBRIRReal[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS_MAX]; extern float leftBRIRImag[BINAURAL_CONVBANDS][HRTF_LS_CHANNELS][BINAURAL_NTAPS_MAX]; diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 0073b9b85baa7500bca0da917d517670c04c6253..c9843bafd36ab60da885a85cdc07d74d00af075e 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -101,7 +101,10 @@ static void external_target_interpolation( static bool are_orientations_same( const IVAS_QUATERNION *orientation1, const IVAS_QUATERNION *orientation2 ); +#ifdef IVAS_FLOAT_FIXED +static bool are_orientations_same_fx( const IVAS_QUATERNION *orientation1, const IVAS_QUATERNION *orientation2 ); +#endif /*-----------------------------------------------------------------------* * ivas_headTrack_open() * @@ -211,12 +214,12 @@ void ivas_headTrack_close( HEAD_TRACK_DATA_HANDLE *hHeadTrackData /* i/o: head track handle */ ) { - if ( hHeadTrackData == NULL || *hHeadTrackData == NULL ) + IF ( hHeadTrackData == NULL || *hHeadTrackData == NULL ) { return; } - if ( ( *hHeadTrackData )->OrientationTracker != NULL ) + IF ( ( *hHeadTrackData )->OrientationTracker != NULL ) { free( ( *hHeadTrackData )->OrientationTracker ); ( *hHeadTrackData )->OrientationTracker = NULL; @@ -394,13 +397,13 @@ float deg2rad( Word32 deg2rad_fx( Word32 degrees ) { - while ( degrees >= DEGREE_180 ) + WHILE ( GE_32(degrees , DEGREE_180 )) { - degrees = degrees - DEGREE_360; + degrees = L_sub(degrees , DEGREE_360); } - while ( degrees <= -DEGREE_180 ) + WHILE( LE_32(degrees , -DEGREE_180) ) { - degrees = degrees + DEGREE_360; + degrees = L_add(degrees , DEGREE_360); } return Mpy_32_32( PI_OVER_180_FX, degrees ); @@ -432,18 +435,18 @@ Word32 rad2deg_fx( Word32 radians ) { - while ( radians >= EVS_PI_FX ) + WHILE ( GE_32(radians , EVS_PI_FX) ) { - radians = radians - EVS_PI_FX; + radians = L_sub(radians, EVS_PI_FX); } - while ( radians <= -EVS_PI_FX ) + WHILE(LE_32( radians , -EVS_PI_FX) ) { - radians = radians + EVS_PI_FX; + radians = L_add(radians , EVS_PI_FX); } return ( radians * _180_OVER_PI_FX ); } -#endif +#endif #ifdef IVAS_FLOAT_FIXED /*------------------------------------------------------------------------- * rotateAziEle() @@ -464,24 +467,32 @@ void rotateAziEle_fx( Word32 dv_fx[3], dv_r_fx[3]; Word32 w_fx; Word32 temp; + Word16 temp_16; Word32 y, x, sqrt_fx; Word16 radian, angle; /*Conversion spherical to cartesian coordinates*/ - if ( abs( azi_in ) > 180 ) + IF( GT_16( abs_s( azi_in ), 180 ) ) { - azi_in = ( azi_in > 0 ) ? ( azi_in - 360 ) : ( azi_in + 360 ); + azi_in = GT_16( azi_in, 0 ) ? sub( azi_in, 360 ) : add( azi_in, 360 ); } - temp = ele_in; - w_fx = cosine_table_Q31[abs( temp )]; - temp = azi_in; - dv_fx[0] = Mpy_32_32( w_fx, cosine_table_Q31[abs( temp )] ); - temp = azi_in; - dv_fx[1] = Mpy_32_32( w_fx, sine_table_Q31[temp + 180] ); - temp = ele_in; - dv_fx[2] = sine_table_Q31[temp + 180]; - + temp_16 = ele_in; + move16(); + w_fx = cosine_table_Q31[abs_s( temp_16 )]; + move32(); + temp_16 = azi_in; + move16(); + dv_fx[0] = Mpy_32_32( w_fx, cosine_table_Q31[abs_s( temp_16 )] ); + move32(); + temp_16 = azi_in; + move16(); + dv_fx[1] = Mpy_32_32( w_fx, sine_table_Q31[add( temp_16, 180 )] ); + move32(); + temp_16 = ele_in; + move16(); + dv_fx[2] = sine_table_Q31[add( temp_16, 180 )]; + move32(); /*Rotation mtx multiplication*/ - for ( n = 0; n < 3; n++ ) + FOR( n = 0; n < 3; n++ ) { temp = L_add( Mpy_32_32( dv_fx[0], Rmat_fx[n][0] ), Mpy_32_32( dv_fx[1], Rmat_fx[n][1] ) ); dv_r_fx[n] = L_add( Mpy_32_32( dv_fx[2], Rmat_fx[n][2] ), temp ); // Q30 @@ -489,65 +500,68 @@ void rotateAziEle_fx( /*Conversion cartesian to spherical coordinates*/ y = dv_r_fx[1]; + move32(); x = dv_r_fx[0]; - radian = atan2_fx( abs( y >> 15 ), abs( x >> 15 ) ); + move32(); + radian = atan2_fx( L_abs( L_shr( y, 15 ) ), L_abs( L_shr( x, 15 ) ) ); radian = y > 0 ? radian : -radian; - if ( x < 0 ) + IF( LT_32( x, 0 ) ) { - if ( radian < 0 ) + IF( LT_32( radian, 0 ) ) { - angle = -( 180 + ( Mpy_32_16_1( _180_OVER_PI_Q25, radian ) >> ( 24 ) ) ); + angle = -add( 180, extract_l( L_shr( Mpy_32_16_1( _180_OVER_PI_Q25, radian ), ( 24 ) ) ) ); } - else + ELSE { - angle = 180 - ( Mpy_32_16_1( _180_OVER_PI_Q25, radian ) >> ( 24 ) ); + angle = sub( 180, extract_l( L_shr( Mpy_32_16_1( _180_OVER_PI_Q25, radian ), ( 24 ) ) ) ); } - if ( radian == 0 ) + IF( EQ_16( radian, 0 ) ) { - angle = y >= 0 ? angle : -angle; + angle = GE_32( y, 0 ) ? angle : -angle; } } - else + ELSE { - angle = ( Mpy_32_16_1( _180_OVER_PI_Q25, radian ) >> ( 24 ) ); + angle = extract_l( L_shr( Mpy_32_16_1( _180_OVER_PI_Q25, radian ), 24 ) ); } - *azi = (Word16) ( max( -180, min( 180, angle ) ) ); + *azi = (Word16) ( s_max( -180, min( 180, angle ) ) ); - if ( isPlanar == 0 ) + IF( EQ_16( isPlanar, 0 ) ) { sqrt_fx = L_Frac_sqrtQ31( L_add( Mpy_32_32( dv_r_fx[0], dv_r_fx[0] ), Mpy_32_32( dv_r_fx[1], dv_r_fx[1] ) ) ); y = dv_r_fx[2]; x = sqrt_fx; - radian = atan2_fx( abs( y >> 15 ), abs( x >> 15 ) ); + radian = atan2_fx( L_abs( L_shr( y, 15 ) ), L_abs( L_shr( x, 15 ) ) ); radian = y > 0 ? radian : -radian; - if ( x < 0 ) + IF( LT_32( x, 0 ) ) { - if ( radian < 0 ) + IF( LT_16( radian, 0 ) ) { - angle = -( 180 + ( Mpy_32_16_r( _180_OVER_PI_Q25, radian ) >> ( 24 ) ) ); + angle = -add( 180, extract_l( L_shr( Mpy_32_16_r( _180_OVER_PI_Q25, radian ), ( 24 ) ) ) ); } - else + ELSE { - angle = 180 - ( Mpy_32_16_r( _180_OVER_PI_Q25, radian ) >> ( 24 ) ); + angle = sub( 180, extract_l( L_shr( Mpy_32_16_r( _180_OVER_PI_Q25, radian ), ( 24 ) ) ) ); } - if ( radian == 0 ) + IF( EQ_16( radian, 0 ) ) { angle = y >= 0 ? angle : -angle; } } - else + ELSE { - angle = ( Mpy_32_16_r( _180_OVER_PI_Q25, radian ) >> ( 24 ) ); + angle = extract_l( L_shr( Mpy_32_16_r( _180_OVER_PI_Q25, radian ), ( 24 ) ) ); } - *ele = (Word16) ( max( -90, min( 90, angle ) ) ); + *ele = (Word16) ( s_max( -90, s_min( 90, angle ) ) ); } - else + ELSE { *ele = 0; + move16(); } return; @@ -575,21 +589,28 @@ void rotateAziEle_fixed( Word32 y, x, sqrt_fx; Word32 angle; /*Conversion spherical to cartesian coordinates*/ - if ( abs( azi_in ) > 180 ) + IF( GT_16( abs_s( azi_in ), 180 ) ) { - azi_in = ( azi_in > 0 ) ? ( azi_in - 360 ) : ( azi_in + 360 ); + azi_in = ( azi_in > 0 ) ? sub( azi_in, 360 ) : add( azi_in, 360 ); } temp_16 = ele_in; + move16(); w_fx = cosine_table_Q31[abs( temp_16 )]; + move32(); temp_16 = azi_in; - dv_fx[0] = Mpy_32_32( w_fx, cosine_table_Q31[abs( temp_16 )] ); + move16(); + dv_fx[0] = Mpy_32_32( w_fx, cosine_table_Q31[abs_s( temp_16 )] ); + move32(); temp_16 = azi_in; + move16(); dv_fx[1] = Mpy_32_32( w_fx, sine_table_Q31[temp_16 + 180] ); + move32(); temp_16 = ele_in; + move16(); dv_fx[2] = sine_table_Q31[temp_16 + 180]; - + move32(); /*Rotation mtx multiplication*/ - for ( n = 0; n < 3; n++ ) + FOR( n = 0; n < 3; n++ ) { temp = L_add( Mpy_32_32( dv_fx[0], Rmat_fx[n][0] ), Mpy_32_32( dv_fx[1], Rmat_fx[n][1] ) ); dv_r_fx[n] = L_add( Mpy_32_32( dv_fx[2], Rmat_fx[n][2] ), temp ); // Q30 @@ -597,36 +618,41 @@ void rotateAziEle_fixed( /*Conversion cartesian to spherical coordinates*/ y = dv_r_fx[1]; + move32(); x = dv_r_fx[0]; - radian = BASOP_util_atan2( y, x, 0 ); // Q13 + move32(); + radian = BASOP_util_atan2( y, x, 0 ); // Q13 - angle = ( Mpy_32_16_1( _180_OVER_PI_Q25, radian ) >> 1 ); // Q22 + angle = L_shr( Mpy_32_16_1( _180_OVER_PI_Q25, radian ), 1 ); // Q22 - *azi = (Word32) ( max( L_shl( -180, 22 ), min( L_shl( 180, 22 ), angle ) ) ); // Q22 - if ( abs( *azi ) <= ONE_IN_Q22 ) + *azi = (Word32) ( L_max( L_shl( -180, 22 ), L_min( L_shl( 180, 22 ), angle ) ) ); // Q22 + IF( LE_32( L_abs( *azi ), ONE_IN_Q22 ) ) { *azi = 0; + move32(); } - if ( isPlanar == 0 ) + IF( EQ_16( isPlanar, 0 ) ) { sqrt_fx = L_Frac_sqrtQ31( L_add( Mpy_32_32( dv_r_fx[0], dv_r_fx[0] ), Mpy_32_32( dv_r_fx[1], dv_r_fx[1] ) ) ); y = dv_r_fx[2]; x = sqrt_fx; radian = BASOP_util_atan2( y, x, 0 ); - angle = ( Mpy_32_16_1( _180_OVER_PI_Q25, radian ) >> 1 ); // Q22 + angle = L_shr( Mpy_32_16_1( _180_OVER_PI_Q25, radian ), 1 ); // Q22 - *ele = (Word32) ( max( L_shl( -90, 22 ), min( L_shl( 90, 22 ), angle ) ) ); // Q22 - if ( abs( *ele ) < ONE_IN_Q22 ) + *ele = (Word32) ( L_max( L_shl( -90, 22 ), L_min( L_shl( 90, 22 ), angle ) ) ); // Q22 + IF( LT_32( L_abs( *ele ), ONE_IN_Q22 ) ) { *ele = 0; + move32(); } } - else + ELSE { *ele = 0; + move32(); } return; @@ -724,7 +750,7 @@ void rotateFrame_shd( default: BREAK; } - + move32(); FOR( i = 0; i < subframe_len; i++ ) { cross_fade[i] = UL_Mpy_32_32( i, tmp ); @@ -748,14 +774,16 @@ void rotateFrame_shd( /* loop over l blocks */ m1 = 1; + move16(); m2 = 4; + move16(); FOR( l = 1; l <= shd_rot_max_order; l++ ) { /* compute mtx-vector product for this l */ FOR( n = m1; n < m2; n++ ) { tmpRot[n - m1] = 0; - + move32(); FOR( m = m1; m < m2; m++ ) { /* crossfade with previous rotation gains */ @@ -770,7 +798,9 @@ void rotateFrame_shd( output[n][subframe_idx * subframe_len + i] = (Word32) tmpRot[n - m1]; } m1 = m2; - m2 += 2 * ( l + 1 ) + 1; + move16(); + m2 = add( m2, add( shl( add( l, 1 ), 1 ), 1 ) ); + } /* unoptimized code for reference (full matrix multiplication) @@ -929,6 +959,7 @@ void rotateFrame_sd( Word16 azimuth, elevation; Word32 azimuth_fx, elevation_fx; Word32 tmp = Q31_BY_SUB_FRAME_240; + move32(); Word32 out_temp; Word32 tmp_gains_fx[MAX_CICP_CHANNELS - 1]; Word32 gains_fx[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; @@ -936,9 +967,9 @@ void rotateFrame_sd( Word32 output_tmp_fx[MAX_CICP_CHANNELS][L_FRAME48k]; Word32 cross_fade_fx[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; push_wmops( "rotateFrame_sd" ); - nchan = hTransSetup.nchan_out_woLFE + hTransSetup.num_lfe; + nchan = add(hTransSetup.nchan_out_woLFE , hTransSetup.num_lfe); index_lfe = hTransSetup.index_lfe[0]; - + move16(); SWITCH( subframe_len ) { case L_SUBFRAME_48k: @@ -956,7 +987,7 @@ void rotateFrame_sd( default: BREAK; } - + move32(); FOR( i = 0; i < subframe_len; i++ ) { cross_fade_fx[i] = UL_Mpy_32_32( i, tmp ); @@ -970,37 +1001,39 @@ void rotateFrame_sd( set_val_Word32( gains_fx[ch_in], 0, nchan ); /* set gains to passthrough by default */ gains_prev_fx[ch_in][ch_in] = ONE_IN_Q30; + move32(); gains_fx[ch_in][ch_in] = ONE_IN_Q30; - + move32(); /* skip LFE */ - IF( ch_in == index_lfe ) + IF( EQ_16( ch_in, index_lfe ) ) { - continue; + CONTINUE; } /* input channel index without LFE */ - ch_in_woLFE = ( ch_in >= index_lfe ) ? ch_in - 1 : ch_in; + ch_in_woLFE = ( ch_in >= index_lfe ) ? sub( ch_in, 1 ) : ch_in; /* gains for previous subframe rotation */ rotateAziEle_fx( (Word16) hTransSetup.ls_azimuth[ch_in_woLFE], (Word16) hTransSetup.ls_elevation[ch_in_woLFE], &azimuth, &elevation, hCombinedOrientationData->Rmat_prev_fx, hTransSetup.is_planar_setup ); - + test(); + test(); IF( hEFAPdata != NULL && ( hTransSetup.ls_azimuth[ch_in_woLFE] != azimuth || hTransSetup.ls_elevation[ch_in_woLFE] != elevation ) ) { - azimuth_fx = (Word32) azimuth * ONE_IN_Q22; - elevation_fx = (Word32) elevation * ONE_IN_Q22; + azimuth_fx = L_shl( (Word32) azimuth, Q22 ); + elevation_fx = L_shl( (Word32) elevation, Q22 ); efap_determine_gains_fx( hEFAPdata, tmp_gains_fx, azimuth_fx, elevation_fx, EFAP_MODE_EFAP ); FOR( ch_out = 0; ch_out < nchan; ch_out++ ) { /* skip LFE */ - if ( ch_out == index_lfe ) + IF( EQ_16( ch_out, index_lfe ) ) { - continue; + CONTINUE; } /* output channel index without LFE */ - ch_out_woLFE = ( ch_out >= index_lfe ) ? ch_out - 1 : ch_out; + ch_out_woLFE = ( ch_out >= index_lfe ) ? sub(ch_out , 1) : ch_out; gains_prev_fx[ch_in][ch_out] = tmp_gains_fx[ch_out_woLFE]; // Q30 } } @@ -1011,20 +1044,20 @@ void rotateFrame_sd( IF( hEFAPdata != NULL && ( hTransSetup.ls_azimuth[ch_in_woLFE] != azimuth || hTransSetup.ls_elevation[ch_in_woLFE] != elevation ) ) { - azimuth_fx = (Word32) azimuth * ONE_IN_Q22; - elevation_fx = (Word32) elevation * ONE_IN_Q22; + azimuth_fx = L_shl( (Word32) azimuth, Q22 ); + elevation_fx = L_shl( (Word32) elevation, Q22 ); efap_determine_gains_fx( hEFAPdata, tmp_gains_fx, azimuth_fx, elevation_fx, EFAP_MODE_EFAP ); FOR( ch_out = 0; ch_out < nchan; ch_out++ ) { /* skip LFE */ - if ( ch_out == index_lfe ) + IF( EQ_16( ch_out, index_lfe ) ) { - continue; + CONTINUE; } /* output channel index without LFE */ - ch_out_woLFE = ( ch_out >= index_lfe ) ? ch_out - 1 : ch_out; + ch_out_woLFE = ( ch_out >= index_lfe ) ? sub(ch_out, 1) : ch_out; gains_fx[ch_in][ch_out] = tmp_gains_fx[ch_out_woLFE]; // Q30 } @@ -1036,13 +1069,16 @@ void rotateFrame_sd( { FOR( ch_in = 0; ch_in < nchan; ch_in++ ) { + j = 0; /* crossfade with previous rotation gains */ - for ( i = subframe_idx * subframe_len, j = 0; j < subframe_len; i++, j++ ) + FOR( i = subframe_idx * subframe_len; j < subframe_len; i++ ) { out_temp = output[ch_in][i]; + move32(); Word32 temp = Mpy_32_32( Mpy_32_32( ( cross_fade_fx[j] ), gains_fx[ch_in][ch_out] ), out_temp ); - Word32 temp1 = Mpy_32_32( Mpy_32_32( ( ONE_IN_Q31 - cross_fade_fx[j] ), gains_prev_fx[ch_in][ch_out] ), out_temp ); + Word32 temp1 = Mpy_32_32( Mpy_32_32(L_sub ( ONE_IN_Q31 , cross_fade_fx[j] ), gains_prev_fx[ch_in][ch_out] ), out_temp ); output_tmp_fx[ch_out][i] = L_add( L_shl( L_add( temp, temp1 ), 1 ), output_tmp_fx[ch_out][i] ); + j++; } } } @@ -1224,7 +1260,7 @@ void rotateFrame_shd_cldfb( assert( nInChannels == HEADROT_SHMAT_DIM && "Number of channels must be 16!" ); /* initialize rotation matrices with zeros */ - for ( i = 0; i < HEADROT_SHMAT_DIM; i++ ) + FOR( i = 0; i < HEADROT_SHMAT_DIM; i++ ) { set16_fx( SHrotmat[i], 0, HEADROT_SHMAT_DIM ); } @@ -1236,24 +1272,28 @@ void rotateFrame_shd_cldfb( dbgwrite_txt( SHrotmat, HEADROT_SHMAT_DIM * HEADROT_SHMAT_DIM, "Fixed_SHrotmat.txt", NULL ); #endif /* rotation by mtx multiplication */ - for ( i = 0; i < numTimeSlots; i++ ) + FOR( i = 0; i < numTimeSlots; i++ ) { - for ( iBand = 0; iBand < CLDFB_NO_CHANNELS_MAX; iBand++ ) + FOR( iBand = 0; iBand < CLDFB_NO_CHANNELS_MAX; iBand++ ) { /*As the rotation matrix becomes block diagonal in a SH basis, we can apply each angular-momentum block individually to save complexity. */ /* loop over l blocks */ m1 = 1; + move16(); m2 = 4; - for ( l = 1; l <= shd_rot_max_order; l++ ) + move16(); + FOR( l = 1; l <= shd_rot_max_order; l++ ) { /* compute mtx-vector product for this l */ - for ( n = m1; n < m2; n++ ) + FOR( n = m1; n < m2; n++ ) { realRot[n - m1] = 0; + move32(); imagRot[n - m1] = 0; - for ( m = m1; m < m2; m++ ) + move32(); + FOR( m = m1; m < m2; m++ ) { temp1 = Mpy_32_16_r( Cldfb_RealBuffer[m][i][iBand], SHrotmat[n][m] ); temp2 = Mpy_32_16_r( Cldfb_ImagBuffer[m][i][iBand], SHrotmat[n][m] ); @@ -1262,13 +1302,16 @@ void rotateFrame_shd_cldfb( } } /* write back the result */ - for ( n = m1; n < m2; n++ ) + FOR( n = m1; n < m2; n++ ) { Cldfb_RealBuffer[n][i][iBand] = realRot[n - m1]; + move32(); Cldfb_ImagBuffer[n][i][iBand] = imagRot[n - m1]; + move32(); } m1 = m2; - m2 += 2 * ( l + 1 ) + 1; + move16(); + m2 = add( m2, add( shl( add( l, 1 ), 1 ), 1 ) ); } /* unoptimized code for reference (full matrix multiplication) @@ -1292,12 +1335,12 @@ void rotateFrame_shd_cldfb( } } // To make the Q factor same as tha of the remaining vector values - for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) { - for ( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) + FOR( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) { - Cldfb_RealBuffer[0][j][k] = Cldfb_RealBuffer[0][j][k] / ONE_IN_Q1; - Cldfb_ImagBuffer[0][j][k] = Cldfb_ImagBuffer[0][j][k] / ONE_IN_Q1; + Cldfb_RealBuffer[0][j][k] = L_shr( Cldfb_RealBuffer[0][j][k], 1 ); + Cldfb_ImagBuffer[0][j][k] = L_shr( Cldfb_ImagBuffer[0][j][k], 1 ); } } return; @@ -1516,20 +1559,20 @@ void rotateFrame_sd_cldfb_fixed( Word32 Cldfb_ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: unrotated HOA3 signal buffer in cldfb domain imag part */ const IVAS_OUTPUT_SETUP_HANDLE hOutputSetup, /* i : output format setup number of channels */ const EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ - const int16_t numTimeSlots, /* i : number of time slots to process */ - const int16_t nb_band /* i : number of CLDFB bands to process */ + const Word16 numTimeSlots, /* i : number of time slots to process */ + const Word16 nb_band /* i : number of CLDFB bands to process */ ) { - int16_t iBlock, iBand, m, n; + Word16 iBlock, iBand, m, n; Word32 gains_fx[MAX_CICP_CHANNELS - 1][MAX_CICP_CHANNELS - 1]; - int16_t azimuth, elevation; + Word16 azimuth, elevation; Word32 g1_fx; Word32 realRot_fx[MAX_CICP_CHANNELS - 1][MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX]; Word32 imagRot_fx[MAX_CICP_CHANNELS - 1][MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX]; Word32 *p_realRot_fx, *p_imagRot_fx; Word32 *p_real_fx, *p_imag_fx; - int16_t nInChannels; - int16_t isPlanar; + Word16 nInChannels; + Word16 isPlanar; push_wmops( "rotateFrame_sd_cldfb" ); nInChannels = hOutputSetup->nchan_out_woLFE; @@ -1539,7 +1582,7 @@ void rotateFrame_sd_cldfb_fixed( IF( hOutputSetup->ls_elevation[n] != 0 ) { isPlanar = 0; - break; + BREAK; } } @@ -1557,29 +1600,37 @@ void rotateFrame_sd_cldfb_fixed( { set_l( gains_fx[n], 0, nInChannels ); gains_fx[n][n] = 0x7fffffff; + move32(); } } /* Apply panning gains by mtx multiplication*/ FOR( n = 0; n < nInChannels; n++ ) { - set_l( realRot_fx[n], 0, MAX_PARAM_SPATIAL_SUBFRAMES * nb_band ); - set_l( imagRot_fx[n], 0, MAX_PARAM_SPATIAL_SUBFRAMES * nb_band ); + set_l( realRot_fx[n], 0, shl( nb_band, 2 ) ); + set_l( imagRot_fx[n], 0, shl( nb_band, 2 ) ); FOR( m = 0; m < nInChannels; m++ ) { g1_fx = gains_fx[m][n]; + move32(); p_realRot_fx = realRot_fx[n]; + move32(); p_imagRot_fx = imagRot_fx[n]; + move32(); IF( GT_32( g1_fx, 0 ) ) { FOR( iBlock = 0; iBlock < numTimeSlots; iBlock++ ) { p_real_fx = Cldfb_RealBuffer[m][iBlock]; + move32(); p_imag_fx = Cldfb_ImagBuffer[m][iBlock]; + move32(); FOR( iBand = 0; iBand < nb_band; iBand++ ) { - *( p_realRot_fx ) = *p_realRot_fx + Mpy_32_32( g1_fx, *( p_real_fx++ ) ); - *( p_imagRot_fx ) = *p_imagRot_fx + Mpy_32_32( g1_fx, *( p_imag_fx++ ) ); + *( p_realRot_fx ) =L_add( *p_realRot_fx , Mpy_32_32( g1_fx, *( p_real_fx++ ) )); + move32(); + *( p_imagRot_fx ) =L_add( *p_imagRot_fx , Mpy_32_32( g1_fx, *( p_imag_fx++ ) )); + move32(); p_realRot_fx++; p_imagRot_fx++; } @@ -1591,20 +1642,28 @@ void rotateFrame_sd_cldfb_fixed( FOR( n = 0; n < nInChannels; n++ ) { p_realRot_fx = realRot_fx[n]; + move32(); p_imagRot_fx = imagRot_fx[n]; + move32(); FOR( iBlock = 0; iBlock < numTimeSlots; iBlock++ ) { p_real_fx = Cldfb_RealBuffer[n][iBlock]; + move32(); p_imag_fx = Cldfb_ImagBuffer[n][iBlock]; + move32(); FOR( iBand = 0; iBand < nb_band; iBand++ ) { *( p_real_fx++ ) = *( p_realRot_fx++ ); + move32(); *( p_imag_fx++ ) = *( p_imagRot_fx++ ); + move32(); } FOR( ; iBand < CLDFB_NO_CHANNELS_MAX; iBand++ ) { *( p_real_fx++ ) = 0; + move32(); *( p_imag_fx++ ) = 0; + move32(); } } } @@ -1619,7 +1678,49 @@ void rotateFrame_sd_cldfb_fixed( * * Allocate and initialize external orientation handle *-----------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_external_orientation_open( + EXTERNAL_ORIENTATION_HANDLE *hExtOrientationData, /* o : external orientation handle */ + const Word16 num_subframes /* i : number of subframes */ +) +{ + + Word16 i; + IVAS_QUATERNION identity; +#if 0 // to be removed later + identity.w = 1.0f; + identity.x = identity.y = identity.z = 0.0f; +#endif + identity.w_fx = ONE_IN_Q31; + move32(); + identity.x_fx = 0; + move32(); + identity.y_fx = 0; + move32(); + identity.z_fx = 0; + move32(); + identity.q_fact = 31; + move16(); + /* Allocate handle */ + IF( ( *hExtOrientationData = (EXTERNAL_ORIENTATION_HANDLE) malloc( sizeof( EXTERNAL_ORIENTATION_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for external orientation memory\n" ) ); + } + ( *hExtOrientationData )->num_subframes = num_subframes; + /* Enable head rotation and disable external orientation as default */ + FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + ( *hExtOrientationData )->enableHeadRotation[i] = 1; + ( *hExtOrientationData )->enableExternalOrientation[i] = 0; + ( *hExtOrientationData )->enableRotationInterpolation[i] = 0; + ( *hExtOrientationData )->numFramesToTargetOrientation[i] = 0; + move16(); + ( *hExtOrientationData )->Quaternions[i] = identity; + } + return IVAS_ERR_OK; +} +#else ivas_error ivas_external_orientation_open( EXTERNAL_ORIENTATION_HANDLE *hExtOrientationData, /* o : external orientation handle */ const int16_t num_subframes /* i : number of subframes */ @@ -1650,7 +1751,7 @@ ivas_error ivas_external_orientation_open( return IVAS_ERR_OK; } - +#endif /*-----------------------------------------------------------------------* * ivas_external_orientation_close() * @@ -1695,33 +1796,133 @@ void ivas_external_orientation_close( * * Allocate and initialize combined orientation handle *-----------------------------------------------------------------------*/ - +#ifdef IVAS_FLOAT_FIXED ivas_error ivas_combined_orientation_open( COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData, /* o : combined orientation handle */ - const int32_t fs, /* i : sampling rate */ - const int16_t num_subframes /* i : number of subframes */ + const Word32 fs, /* i : sampling rate */ + const Word16 num_subframes /* i : number of subframes */ ) { - int16_t i; - int16_t j; + Word16 i; + Word16 j; + Word16 tmp_e = 0, tmp; IVAS_QUATERNION identity; IVAS_VECTOR3 origo; - +#if 0 // to be removed later identity.w = 1.0f; identity.x = identity.y = identity.z = 0.0f; origo.x = origo.y = origo.z = 0.0f; -#ifdef IVAS_FLOAT_FIXED +#endif identity.w_fx = ONE_IN_Q31; + move32(); identity.x_fx = 0; + move32(); identity.y_fx = 0; + move32(); identity.z_fx = 0; + move32(); identity.q_fact = 31; - + move16(); origo.x_fx = 0; + move32(); origo.y_fx = 0; + move32(); origo.z_fx = 0; + move32(); origo.q_fact = 31; + move16(); + /* Allocate handle */ + IF( ( *hCombinedOrientationData = (COMBINED_ORIENTATION_HANDLE) malloc( sizeof( COMBINED_ORIENTATION_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for combined orientation memory\n" ) ); + } + + /* Initialization */ + ( *hCombinedOrientationData )->num_subframes = num_subframes; + move16(); + ( *hCombinedOrientationData )->interpolationCoefficient_fx = ONE_IN_Q30; + move32(); + ( *hCombinedOrientationData )->interpolationIncrement_Fx = ONE_IN_Q30; + move32(); + IF( EQ_16( num_subframes, 1 ) ) + { + ( *hCombinedOrientationData )->maximumFramesToTargetOrientation = 2000; + move16(); + } + ELSE + { + ( *hCombinedOrientationData )->maximumFramesToTargetOrientation = 500; + move16(); + } + ( *hCombinedOrientationData )->lrSwitchedNext = 0; + ( *hCombinedOrientationData )->lrSwitchedCurrent = 0; + + ( *hCombinedOrientationData )->lrSwitchInterpVal_fx = 0; + ( *hCombinedOrientationData )->isInterpolationOngoing = FALSE; + ( *hCombinedOrientationData )->Quaternions_ext_interpolation_start = identity; + ( *hCombinedOrientationData )->Quaternions_ext_interpolation_target = identity; + + /* Initialise orientations to identity */ + FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + ( *hCombinedOrientationData )->enableCombinedOrientation[i] = 0; + move16(); + ( *hCombinedOrientationData )->Quaternions[i] = identity; + ( *hCombinedOrientationData )->listenerPos[i] = origo; + + FOR( j = 0; j < 3; j++ ) + { + set32_fx( ( *hCombinedOrientationData )->Rmat_fx[i][j], 0, 3 ); + ( *hCombinedOrientationData )->Rmat_fx[i][j][j] = ONE_IN_Q30; + move32(); + } + } + + FOR( j = 0; j < 3; j++ ) + { + set32_fx( ( *hCombinedOrientationData )->Rmat_prev_fx[j], 0, 3 ); + ( *hCombinedOrientationData )->Rmat_prev_fx[j][j] = ONE_IN_Q30; + move32(); + } + ( *hCombinedOrientationData )->Quaternion_prev_extOrientation = identity; + ( *hCombinedOrientationData )->Quaternion_frozen_ext = identity; + ( *hCombinedOrientationData )->Quaternion_frozen_head = identity; + set_zero_fx( ( *hCombinedOrientationData )->chEneIIR_fx[0], MASA_FREQUENCY_BANDS ); + set_zero_fx( ( *hCombinedOrientationData )->chEneIIR_fx[1], MASA_FREQUENCY_BANDS ); + set_zero_fx( ( *hCombinedOrientationData )->procChEneIIR_fx[0], MASA_FREQUENCY_BANDS ); + set_zero_fx( ( *hCombinedOrientationData )->procChEneIIR_fx[1], MASA_FREQUENCY_BANDS ); + ( *hCombinedOrientationData )->q_chEneIIR = Q31; + move16(); + ( *hCombinedOrientationData )->q_procChEneIIR = Q31; + move16(); + ( *hCombinedOrientationData )->isExtOrientationFrozen = 0; + ( *hCombinedOrientationData )->isHeadRotationFrozen = 0; + + ( *hCombinedOrientationData )->subframe_idx = 0; + move16(); + tmp = BASOP_Util_Divide3232_Scale( fs, MAX_PARAM__SPATIAL_SUB_FRAMES_PER_SEC, &tmp_e ); + ( *hCombinedOrientationData )->subframe_size = shr( tmp, sub( 15, tmp_e ) ); + // ( *hCombinedOrientationData )->subframe_size = (int16_t) ( fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ); + ( *hCombinedOrientationData )->cur_subframe_samples_rendered = 0; + + return IVAS_ERR_OK; +} #endif +#ifndef IVAS_FLOAT_FIXED +ivas_error ivas_combined_orientation_open( + COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData, /* o : combined orientation handle */ + const int32_t fs, /* i : sampling rate */ + const int16_t num_subframes /* i : number of subframes */ +) +{ + int16_t i; + int16_t j; + IVAS_QUATERNION identity; + IVAS_VECTOR3 origo; + + identity.w = 1.0f; + identity.x = identity.y = identity.z = 0.0f; + origo.x = origo.y = origo.z = 0.0f; /* Allocate handle */ if ( ( *hCombinedOrientationData = (COMBINED_ORIENTATION_HANDLE) malloc( sizeof( COMBINED_ORIENTATION_DATA ) ) ) == NULL ) @@ -1744,9 +1945,6 @@ ivas_error ivas_combined_orientation_open( ( *hCombinedOrientationData )->lrSwitchedNext = 0; ( *hCombinedOrientationData )->lrSwitchedCurrent = 0; ( *hCombinedOrientationData )->lrSwitchInterpVal = 0.0f; -#ifdef IVAS_FLOAT_FIXED - (*hCombinedOrientationData)->lrSwitchInterpVal_fx = 0; -#endif ( *hCombinedOrientationData )->isInterpolationOngoing = FALSE; ( *hCombinedOrientationData )->Quaternions_ext_interpolation_start = identity; ( *hCombinedOrientationData )->Quaternions_ext_interpolation_target = identity; @@ -1780,15 +1978,6 @@ ivas_error ivas_combined_orientation_open( set_zero( ( *hCombinedOrientationData )->chEneIIR[1], MASA_FREQUENCY_BANDS ); set_zero( ( *hCombinedOrientationData )->procChEneIIR[0], MASA_FREQUENCY_BANDS ); set_zero( ( *hCombinedOrientationData )->procChEneIIR[1], MASA_FREQUENCY_BANDS ); -#ifdef IVAS_FLOAT_FIXED - set_zero_fx((*hCombinedOrientationData)->chEneIIR_fx[0], MASA_FREQUENCY_BANDS); - set_zero_fx((*hCombinedOrientationData)->chEneIIR_fx[1], MASA_FREQUENCY_BANDS); - set_zero_fx((*hCombinedOrientationData)->procChEneIIR_fx[0], MASA_FREQUENCY_BANDS); - set_zero_fx((*hCombinedOrientationData)->procChEneIIR_fx[1], MASA_FREQUENCY_BANDS); - (*hCombinedOrientationData)->q_chEneIIR = Q31; - (*hCombinedOrientationData)->q_procChEneIIR = Q31; -#endif - ( *hCombinedOrientationData )->isExtOrientationFrozen = 0; ( *hCombinedOrientationData )->isHeadRotationFrozen = 0; @@ -1798,8 +1987,7 @@ ivas_error ivas_combined_orientation_open( return IVAS_ERR_OK; } - - +#endif /*-----------------------------------------------------------------------* * ivas_combined_orientation_close() * @@ -1855,12 +2043,11 @@ ivas_error combine_external_and_head_orientations_dec( IVAS_QUATERNION *pHeadRotQuaternion = NULL; IVAS_VECTOR3 *listenerPos = NULL; - if ( hHeadTrackData != NULL ) + IF( hHeadTrackData != NULL ) { pHeadRotQuaternion = hHeadTrackData->Quaternions; listenerPos = hHeadTrackData->Pos; } - return combine_external_and_head_orientations( pHeadRotQuaternion, listenerPos, hExtOrientationData, hCombinedOrientationData ); } @@ -1880,22 +2067,22 @@ ivas_error combine_external_and_head_orientations_rend( { IVAS_QUATERNION *headRotQuaternions = NULL; IVAS_VECTOR3 *listenerPos = NULL; - int16_t i; + Word16 i; - if ( hHeadTrackData != NULL ) + IF( hHeadTrackData != NULL ) { - if ( hHeadTrackData->headRotEnabled ) + IF( hHeadTrackData->headRotEnabled ) { headRotQuaternions = hHeadTrackData->headPositions; listenerPos = hHeadTrackData->Pos; } } - else if ( hExtOrientationData != NULL ) + ELSE IF( hExtOrientationData != NULL ) { /* Head rotation data not available, use the freezed value or disable */ - for ( i = 0; i < hExtOrientationData->num_subframes; i++ ) + FOR( i = 0; i < hExtOrientationData->num_subframes; i++ ) { - if ( hExtOrientationData->enableHeadRotation[i] != 2 ) + IF( hExtOrientationData->enableHeadRotation[i] != 2 ) { hExtOrientationData->enableHeadRotation[i] = 0; } @@ -1913,7 +2100,7 @@ ivas_error combine_external_and_head_orientations_rend( * Combine the external orientations and the head orientation. * NOTE that the external orientations are inversed. *------------------------------------------------------------------------*/ - +#ifdef IVAS_FLOAT_FIXED ivas_error combine_external_and_head_orientations( IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ IVAS_VECTOR3 *listenerPos, /* i : listener position */ @@ -1921,107 +2108,397 @@ ivas_error combine_external_and_head_orientations( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ ) { - int16_t i; - int16_t j; + Word16 i; + Word16 j; IVAS_QUATERNION identity; IVAS_VECTOR3 origo; - - identity.w = 1.0f; - identity.x = identity.y = identity.z = 0.0f; - origo.x = origo.y = origo.z = 0.0f; + identity.w_fx = ONE_IN_Q31; + move32(); + identity.x_fx = 0; + move32(); + identity.y_fx = 0; + move32(); + identity.z_fx = 0; + move32(); + identity.q_fact = 31; + move16(); + origo.x_fx = 0; + move32(); + origo.y_fx = 0; + move32(); + origo.z_fx = 0; + move32(); + origo.q_fact = 31; + move16(); /* Form combined orientations or return if no data available */ - if ( hCombinedOrientationData == NULL ) + IF( hCombinedOrientationData == NULL ) { - if ( headRotQuaternions != NULL || hExtOrientationData != NULL ) + test(); + IF( headRotQuaternions != NULL || hExtOrientationData != NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - else + ELSE { return IVAS_ERR_OK; } } - else if ( headRotQuaternions == NULL && hExtOrientationData == NULL ) + ELSE IF( headRotQuaternions == NULL && hExtOrientationData == NULL ) { /* Reset the combined orientations and rotations */ hCombinedOrientationData->isInterpolationOngoing = FALSE; - hCombinedOrientationData->interpolationCoefficient = 1.0f; - hCombinedOrientationData->interpolationIncrement = 1.0f; + hCombinedOrientationData->interpolationCoefficient_fx = ONE_IN_Q30; + move32(); + hCombinedOrientationData->interpolationIncrement_Fx = ONE_IN_Q30; + move32(); hCombinedOrientationData->Quaternions_ext_interpolation_start = identity; hCombinedOrientationData->Quaternions_ext_interpolation_target = identity; - for ( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + FOR( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) { hCombinedOrientationData->enableCombinedOrientation[i] = 0; hCombinedOrientationData->Quaternions[i] = identity; hCombinedOrientationData->listenerPos[i] = origo; - for ( j = 0; j < 3; j++ ) + FOR( j = 0; j < 3; j++ ) { - set_zero( hCombinedOrientationData->Rmat[i][j], 3 ); - hCombinedOrientationData->Rmat[i][j][j] = 1.0f; + set_zero_fx( hCombinedOrientationData->Rmat_fx[i][j], 3 ); + hCombinedOrientationData->Rmat_fx[i][j][j] = ONE_IN_Q30; + move32(); } } } - else if ( hExtOrientationData == NULL && headRotQuaternions != NULL ) + ELSE IF( hExtOrientationData == NULL && headRotQuaternions != NULL ) { /* Head rotation only */ - for ( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + FOR( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) { hCombinedOrientationData->Quaternions[i] = headRotQuaternions[i]; } } - if ( hExtOrientationData != NULL ) + IF( hExtOrientationData != NULL ) { /* External orientations */ - for ( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + FOR( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) { /* Check for frozen external orientation */ - if ( hExtOrientationData->enableExternalOrientation[i] == 2 ) + IF( hExtOrientationData->enableExternalOrientation[i] == 2 ) { - if ( hCombinedOrientationData->isExtOrientationFrozen != 1 ) + IF( hCombinedOrientationData->isExtOrientationFrozen != 1 ) { hCombinedOrientationData->Quaternion_frozen_ext = hExtOrientationData->Quaternions[i]; hCombinedOrientationData->isExtOrientationFrozen = 1; } } - else + ELSE { hCombinedOrientationData->Quaternion_frozen_ext = identity; hCombinedOrientationData->isExtOrientationFrozen = 0; } - - if ( hExtOrientationData->enableRotationInterpolation[i] == 1 && hExtOrientationData->enableExternalOrientation[i] > 0 ) + test(); + IF( hExtOrientationData->enableRotationInterpolation[i] == 1 && hExtOrientationData->enableExternalOrientation[i] > 0 ) { - if ( hCombinedOrientationData->isInterpolationOngoing == true && hCombinedOrientationData->interpolationCoefficient <= 1.0f && are_orientations_same( &hCombinedOrientationData->Quaternions_ext_interpolation_target, &hExtOrientationData->Quaternions[i] ) == true ) + test(); + IF( hCombinedOrientationData->isInterpolationOngoing == true && hCombinedOrientationData->interpolationCoefficient_fx <= ONE_IN_Q30 && are_orientations_same_fx( &hCombinedOrientationData->Quaternions_ext_interpolation_target, &hExtOrientationData->Quaternions[i] ) == true ) { /* Continue interpolation */ -#ifdef IVAS_FLOAT_FIXED - hCombinedOrientationData->interpolationCoefficient_fx = float_to_fix(hCombinedOrientationData->interpolationCoefficient, Q30); - hCombinedOrientationData->Quaternions_ext_interpolation_start.w_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_start.w, Q29); - hCombinedOrientationData->Quaternions_ext_interpolation_start.x_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_start.x, Q29); - hCombinedOrientationData->Quaternions_ext_interpolation_start.y_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_start.y, Q29); - hCombinedOrientationData->Quaternions_ext_interpolation_start.z_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_start.z, Q29); + hCombinedOrientationData->Quaternions_ext_interpolation_start.w_fx = L_shr( hCombinedOrientationData->Quaternions_ext_interpolation_start.w_fx, hCombinedOrientationData->Quaternions_ext_interpolation_start.q_fact - Q29 ); + hCombinedOrientationData->Quaternions_ext_interpolation_start.x_fx = L_shr( hCombinedOrientationData->Quaternions_ext_interpolation_start.x_fx, hCombinedOrientationData->Quaternions_ext_interpolation_start.q_fact - Q29 ); + hCombinedOrientationData->Quaternions_ext_interpolation_start.y_fx = L_shr( hCombinedOrientationData->Quaternions_ext_interpolation_start.y_fx, hCombinedOrientationData->Quaternions_ext_interpolation_start.q_fact - Q29 ); + hCombinedOrientationData->Quaternions_ext_interpolation_start.z_fx = L_shr( hCombinedOrientationData->Quaternions_ext_interpolation_start.z_fx, hCombinedOrientationData->Quaternions_ext_interpolation_start.q_fact - Q29 ); + + hCombinedOrientationData->Quaternions_ext_interpolation_target.w_fx = L_shr( hCombinedOrientationData->Quaternions_ext_interpolation_target.w_fx, hCombinedOrientationData->Quaternions_ext_interpolation_target.q_fact - Q29 ); + hCombinedOrientationData->Quaternions_ext_interpolation_target.x_fx = L_shr( hCombinedOrientationData->Quaternions_ext_interpolation_target.x_fx, hCombinedOrientationData->Quaternions_ext_interpolation_target.q_fact - Q29 ); + hCombinedOrientationData->Quaternions_ext_interpolation_target.y_fx = L_shr( hCombinedOrientationData->Quaternions_ext_interpolation_target.y_fx, hCombinedOrientationData->Quaternions_ext_interpolation_target.q_fact - Q29 ); + hCombinedOrientationData->Quaternions_ext_interpolation_target.z_fx = L_shr( hCombinedOrientationData->Quaternions_ext_interpolation_target.z_fx, hCombinedOrientationData->Quaternions_ext_interpolation_target.q_fact - Q29 ); + + hCombinedOrientationData->Quaternions_ext_interpolation_start.q_fact = Q29; + move16(); + hCombinedOrientationData->Quaternions_ext_interpolation_target.q_fact = Q29; + move16(); + QuaternionSlerp_fx( hCombinedOrientationData->Quaternions_ext_interpolation_start, hCombinedOrientationData->Quaternions_ext_interpolation_target, hCombinedOrientationData->interpolationCoefficient_fx, &hCombinedOrientationData->Quaternions[i] ); + hCombinedOrientationData->interpolationCoefficient_fx = L_add( hCombinedOrientationData->interpolationIncrement_Fx, hCombinedOrientationData->interpolationCoefficient_fx ); + } + ELSE + { + /* Stop interpolation or check for new interpolation */ + hCombinedOrientationData->isInterpolationOngoing = FALSE; + hCombinedOrientationData->interpolationCoefficient_fx = ONE_IN_Q30; + move32(); + hCombinedOrientationData->interpolationIncrement_Fx = ONE_IN_Q30; + move32(); + external_target_interpolation( hExtOrientationData, hCombinedOrientationData, i ); + Word16 l_shift = 0; + move16(); + l_shift = s_min( s_min( Q_factor_L_32( hCombinedOrientationData->Quaternions[i].w_fx ), Q_factor_L_32( hCombinedOrientationData->Quaternions[i].x_fx ) ), s_min( Q_factor_L_32( hCombinedOrientationData->Quaternions[i].y_fx ), Q_factor_L_32( hCombinedOrientationData->Quaternions[i].z_fx ) ) ); + hCombinedOrientationData->Quaternions[i].w_fx = L_shl( hCombinedOrientationData->Quaternions[i].w_fx, l_shift ); + hCombinedOrientationData->Quaternions[i].x_fx = L_shl( hCombinedOrientationData->Quaternions[i].x_fx, l_shift ); + hCombinedOrientationData->Quaternions[i].y_fx = L_shl( hCombinedOrientationData->Quaternions[i].y_fx, l_shift ); + hCombinedOrientationData->Quaternions[i].z_fx = L_shl( hCombinedOrientationData->Quaternions[i].z_fx, l_shift ); + hCombinedOrientationData->Quaternions[i].q_fact = add( hCombinedOrientationData->Quaternions[i].q_fact, l_shift ); + } + } + ELSE + { + /* Interpolation disabled, use the current orientation values */ - hCombinedOrientationData->Quaternions_ext_interpolation_target.w_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_target.w, Q29); - hCombinedOrientationData->Quaternions_ext_interpolation_target.x_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_target.x, Q29); - hCombinedOrientationData->Quaternions_ext_interpolation_target.y_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_target.y, Q29); - hCombinedOrientationData->Quaternions_ext_interpolation_target.z_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_target.z, Q29); + /* Use the most recent external orientation */ + IF( hExtOrientationData->enableExternalOrientation[i] == 1 ) + { + hCombinedOrientationData->Quaternions[i] = hExtOrientationData->Quaternions[i]; + } + /* Use the freezed external orientation */ + ELSE IF( hExtOrientationData->enableExternalOrientation[i] == 2 ) + { + hCombinedOrientationData->Quaternions[i] = hCombinedOrientationData->Quaternion_frozen_ext; + } + } + } + } - hCombinedOrientationData->Quaternions_ext_interpolation_start.q_fact = Q29; - hCombinedOrientationData->Quaternions_ext_interpolation_target.q_fact = Q29; + IF( hExtOrientationData != NULL && headRotQuaternions != NULL ) + { + /* Combine head and external orientations */ + FOR( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + /* Check for frozen head rotation */ + IF( hExtOrientationData->enableHeadRotation[i] == 2 ) + { + IF( hCombinedOrientationData->isHeadRotationFrozen != 1 ) + { + hCombinedOrientationData->Quaternion_frozen_head = headRotQuaternions[i]; + hCombinedOrientationData->isHeadRotationFrozen = 1; + } + } + ELSE + { + hCombinedOrientationData->Quaternion_frozen_head = identity; + hCombinedOrientationData->isHeadRotationFrozen = 0; + } + /* Use the most recent head rotation */ + IF( hExtOrientationData->enableHeadRotation[i] == 1 ) + { + IF( hExtOrientationData->enableExternalOrientation[i] > 0 ) + { + QuaternionProduct_fx( hCombinedOrientationData->Quaternions[i], headRotQuaternions[i], &hCombinedOrientationData->Quaternions[i] ); + } + ELSE + { + hCombinedOrientationData->Quaternions[i] = headRotQuaternions[i]; + } + } + /* Use the freezed head rotation */ + ELSE IF( hExtOrientationData->enableHeadRotation[i] == 2 ) + { + IF( hExtOrientationData->enableExternalOrientation[i] > 0 ) + { + QuaternionProduct_fx( hCombinedOrientationData->Quaternions[i], hCombinedOrientationData->Quaternion_frozen_head, &hCombinedOrientationData->Quaternions[i] ); + } + ELSE + { + hCombinedOrientationData->Quaternions[i] = hCombinedOrientationData->Quaternion_frozen_head; + } + } + + /* Reset the combined orientations to identity */ + IF( hExtOrientationData->enableHeadRotation[i] == 0 && hExtOrientationData->enableExternalOrientation[i] == 0 ) + { + hCombinedOrientationData->Quaternions[i] = identity; + } + } + } + + IF( headRotQuaternions != NULL || hExtOrientationData != NULL ) + { + /* Calculate the combined rotation matrix */ + FOR( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + QuatToRotMat_fx( hCombinedOrientationData->Quaternions[i], hCombinedOrientationData->Rmat_fx[i] ); + } + } + + /* Save the current orientations */ + IF( hExtOrientationData != NULL ) + { + IF( hExtOrientationData->enableExternalOrientation[hExtOrientationData->num_subframes - 1] > 0 ) + { + hCombinedOrientationData->Quaternion_prev_extOrientation = hExtOrientationData->Quaternions[hExtOrientationData->num_subframes - 1]; + } + ELSE + { + hCombinedOrientationData->Quaternion_prev_extOrientation = identity; + } + } + IF( headRotQuaternions != NULL ) + { + FOR( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + hCombinedOrientationData->listenerPos[i] = listenerPos[i]; + } + } - QuaternionSlerp_fx(hCombinedOrientationData->Quaternions_ext_interpolation_start, hCombinedOrientationData->Quaternions_ext_interpolation_target, hCombinedOrientationData->interpolationCoefficient_fx, &hCombinedOrientationData->Quaternions[i]); + /* Check if combined orientation is enabled */ + IF( headRotQuaternions != NULL && hExtOrientationData == NULL ) + { + FOR( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + hCombinedOrientationData->enableCombinedOrientation[i] = 1; + } + } + ELSE IF( headRotQuaternions == NULL && hExtOrientationData != NULL ) + { + FOR( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + IF( hExtOrientationData->enableExternalOrientation[i] > 0 ) + { + hCombinedOrientationData->enableCombinedOrientation[i] = 1; + } + ELSE + { + hCombinedOrientationData->enableCombinedOrientation[i] = 0; + } + } + } + ELSE IF( headRotQuaternions != NULL && hExtOrientationData != NULL ) + { + FOR( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + IF( hExtOrientationData->enableExternalOrientation[i] > 0 || ( hExtOrientationData->enableHeadRotation[i] > 0 ) ) + { + hCombinedOrientationData->enableCombinedOrientation[i] = 1; + } + ELSE + { + hCombinedOrientationData->enableCombinedOrientation[i] = 0; + } + } + } + ELSE + { + FOR( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + hCombinedOrientationData->enableCombinedOrientation[i] = 0; + } + } - hCombinedOrientationData->Quaternions[i].w = fixedToFloat_32(hCombinedOrientationData->Quaternions[i].w_fx, hCombinedOrientationData->Quaternions[i].q_fact); - hCombinedOrientationData->Quaternions[i].x = fixedToFloat_32(hCombinedOrientationData->Quaternions[i].x_fx, hCombinedOrientationData->Quaternions[i].q_fact); - hCombinedOrientationData->Quaternions[i].y = fixedToFloat_32(hCombinedOrientationData->Quaternions[i].y_fx, hCombinedOrientationData->Quaternions[i].q_fact); - hCombinedOrientationData->Quaternions[i].z = fixedToFloat_32(hCombinedOrientationData->Quaternions[i].z_fx, hCombinedOrientationData->Quaternions[i].q_fact); + hCombinedOrientationData->subframe_idx = 0; + move16(); + hCombinedOrientationData->cur_subframe_samples_rendered = 0; + move16(); + hCombinedOrientationData->subframe_idx_start = 0; + move16(); + hCombinedOrientationData->cur_subframe_samples_rendered_start = 0; + move16(); + FOR( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + FOR( j = 0; j < 3; j++ ) + { + FOR( Word16 k = 0; k < 3; k++ ) + { + hCombinedOrientationData->Rmat_fx[i][j][k] = L_shl( hCombinedOrientationData->Rmat_fx[i][j][k], sub( 62, shl( hCombinedOrientationData->Quaternions[i].q_fact, 1 ) ) ); // Q30 + } + } + } + Word16 l_shift = 0; + move16(); + FOR( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + l_shift = s_min( s_min( Q_factor_L_32( hCombinedOrientationData->Quaternions[i].w_fx ), Q_factor_L_32( hCombinedOrientationData->Quaternions[i].x_fx ) ), s_min( Q_factor_L_32( hCombinedOrientationData->Quaternions[i].y_fx ), Q_factor_L_32( hCombinedOrientationData->Quaternions[i].z_fx ) ) ); + hCombinedOrientationData->Quaternions[i].w_fx = L_shl( hCombinedOrientationData->Quaternions[i].w_fx, l_shift ); + hCombinedOrientationData->Quaternions[i].x_fx = L_shl( hCombinedOrientationData->Quaternions[i].x_fx, l_shift ); + hCombinedOrientationData->Quaternions[i].y_fx = L_shl( hCombinedOrientationData->Quaternions[i].y_fx, l_shift ); + hCombinedOrientationData->Quaternions[i].z_fx = L_shl( hCombinedOrientationData->Quaternions[i].z_fx, l_shift ); + hCombinedOrientationData->Quaternions[i].q_fact = add( hCombinedOrientationData->Quaternions[i].q_fact, l_shift ); + } + return IVAS_ERR_OK; +} #else - QuaternionSlerp(hCombinedOrientationData->Quaternions_ext_interpolation_start, hCombinedOrientationData->Quaternions_ext_interpolation_target, hCombinedOrientationData->interpolationCoefficient, &hCombinedOrientationData->Quaternions[i]); -#endif +ivas_error combine_external_and_head_orientations( + IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ + IVAS_VECTOR3 *listenerPos, /* i : listener position */ + EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, /* i : external orientation handle */ + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ +) +{ + int16_t i; + int16_t j; + IVAS_QUATERNION identity; + IVAS_VECTOR3 origo; + + identity.w = 1.0f; + identity.x = identity.y = identity.z = 0.0f; + origo.x = origo.y = origo.z = 0.0f; + + /* Form combined orientations or return if no data available */ + if ( hCombinedOrientationData == NULL ) + { + if ( headRotQuaternions != NULL || hExtOrientationData != NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + else + { + return IVAS_ERR_OK; + } + } + else if ( headRotQuaternions == NULL && hExtOrientationData == NULL ) + { + /* Reset the combined orientations and rotations */ + hCombinedOrientationData->isInterpolationOngoing = FALSE; + hCombinedOrientationData->interpolationCoefficient = 1.0f; + hCombinedOrientationData->interpolationIncrement = 1.0f; + hCombinedOrientationData->Quaternions_ext_interpolation_start = identity; + hCombinedOrientationData->Quaternions_ext_interpolation_target = identity; + for ( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + hCombinedOrientationData->enableCombinedOrientation[i] = 0; + hCombinedOrientationData->Quaternions[i] = identity; + hCombinedOrientationData->listenerPos[i] = origo; + + for ( j = 0; j < 3; j++ ) + { + set_zero( hCombinedOrientationData->Rmat[i][j], 3 ); + hCombinedOrientationData->Rmat[i][j][j] = 1.0f; + } + } + } + else if ( hExtOrientationData == NULL && headRotQuaternions != NULL ) + { + /* Head rotation only */ + for ( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + hCombinedOrientationData->Quaternions[i] = headRotQuaternions[i]; + } + } + + if ( hExtOrientationData != NULL ) + { + /* External orientations */ + for ( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + /* Check for frozen external orientation */ + if ( hExtOrientationData->enableExternalOrientation[i] == 2 ) + { + if ( hCombinedOrientationData->isExtOrientationFrozen != 1 ) + { + hCombinedOrientationData->Quaternion_frozen_ext = hExtOrientationData->Quaternions[i]; + hCombinedOrientationData->isExtOrientationFrozen = 1; + } + } + else + { + hCombinedOrientationData->Quaternion_frozen_ext = identity; + hCombinedOrientationData->isExtOrientationFrozen = 0; + } + + if ( hExtOrientationData->enableRotationInterpolation[i] == 1 && hExtOrientationData->enableExternalOrientation[i] > 0 ) + { + if ( hCombinedOrientationData->isInterpolationOngoing == true && hCombinedOrientationData->interpolationCoefficient <= 1.0f && are_orientations_same( &hCombinedOrientationData->Quaternions_ext_interpolation_target, &hExtOrientationData->Quaternions[i] ) == true ) + { + /* Continue interpolation */ + QuaternionSlerp( hCombinedOrientationData->Quaternions_ext_interpolation_start, hCombinedOrientationData->Quaternions_ext_interpolation_target, hCombinedOrientationData->interpolationCoefficient, &hCombinedOrientationData->Quaternions[i] ); hCombinedOrientationData->interpolationCoefficient += hCombinedOrientationData->interpolationIncrement; } else @@ -2180,37 +2657,117 @@ ivas_error combine_external_and_head_orientations( hCombinedOrientationData->cur_subframe_samples_rendered = 0; hCombinedOrientationData->subframe_idx_start = 0; hCombinedOrientationData->cur_subframe_samples_rendered_start = 0; + return IVAS_ERR_OK; +} +#endif + +/*------------------------------------------------------------------------- + * external_target_interpolation() + * + * + *------------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED - for ( Word16 k = 0; k < 4; k++ ) +static void external_target_interpolation( + EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, /* i : external orientation handle */ + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientation handle */ + const Word16 i /* i : subframe index */ +) +{ + /* Sanity check for number of frames */ + hExtOrientationData->numFramesToTargetOrientation[i] = s_min( hExtOrientationData->numFramesToTargetOrientation[i], hCombinedOrientationData->maximumFramesToTargetOrientation ); + hExtOrientationData->numFramesToTargetOrientation[i] = s_max( hExtOrientationData->numFramesToTargetOrientation[i], 0 ); + + /* Interpolate from the current orientation to the target orientation */ + IF( hExtOrientationData->numFramesToTargetOrientation[i] > 0 ) { - for ( i = 0; i < 3; i++ ) + IF( are_orientations_same_fx( &hCombinedOrientationData->Quaternions_ext_interpolation_target, &hExtOrientationData->Quaternions[i] ) == false ) { - for ( j = 0; j < 3; j++ ) + /* Target orientation is different from the previous target, update the values */ + + /* Set the received orientation as the target */ + hCombinedOrientationData->Quaternions_ext_interpolation_target = hExtOrientationData->Quaternions[i]; + + /* Use the most recent external orientation as the starting orientation */ + IF( hExtOrientationData->enableExternalOrientation[i] == 1 ) { - hCombinedOrientationData->Rmat_fx[k][i][j] = (Word32) float_to_fixed( hCombinedOrientationData->Rmat[k][i][j], 30 ); + IF( GT_16( i, 0 ) ) + { + IF( hExtOrientationData->enableExternalOrientation[i - 1] == 0 ) + { + IVAS_QUATERNION identity; + identity.w_fx = ONE_IN_Q31; + move32(); + identity.x_fx = identity.y_fx = identity.z_fx = 0; + move32(); + move32(); + move32(); + identity.q_fact = 31; + move16(); + hCombinedOrientationData->Quaternions_ext_interpolation_start = identity; + } + ELSE IF( hExtOrientationData->enableExternalOrientation[i - 1] == 2 ) + { + hCombinedOrientationData->Quaternions_ext_interpolation_start = hCombinedOrientationData->Quaternion_frozen_ext; + } + ELSE + { + hCombinedOrientationData->Quaternions_ext_interpolation_start = hExtOrientationData->Quaternions[i - 1]; + } + } + ELSE + { + hCombinedOrientationData->Quaternions_ext_interpolation_start = hCombinedOrientationData->Quaternion_prev_extOrientation; + } + } + ELSE IF( hExtOrientationData->enableExternalOrientation[i] == 2 ) + { + hCombinedOrientationData->Quaternions_ext_interpolation_start = hCombinedOrientationData->Quaternion_frozen_ext; } + Word16 tmp_e = 0; + move16(); + Word32 tmp; + /* Calculate the interpolation increment and coefficient */ + // hCombinedOrientationData->interpolationIncrement_Fx = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, L_shl( L_deposit_l(hExtOrientationData->numFramesToTargetOrientation[i]), 2 ), &tmp_e ); // Multiplying with MAX_PARAM_SPATIAL_SUBFRAMES + tmp = BASOP_Util_Divide3232_Scale_cadence( ONE_IN_Q30, L_shl( L_deposit_l( hExtOrientationData->numFramesToTargetOrientation[i] ), 2 ), &tmp_e ); + hCombinedOrientationData->interpolationIncrement_Fx = L_shl( tmp, sub( tmp_e, 31 ) ); // Q30 + hCombinedOrientationData->interpolationCoefficient_fx = hCombinedOrientationData->interpolationIncrement_Fx; + move32(); } - } - for (i = 0; i < hCombinedOrientationData->num_subframes; i++) + /* Interpolate */ + hCombinedOrientationData->isInterpolationOngoing = TRUE; + // hCombinedOrientationData->interpolationCoefficient_fx = float_to_fix( hCombinedOrientationData->interpolationCoefficient, Q30 ); + hCombinedOrientationData->Quaternions_ext_interpolation_start.w_fx = L_shr( hCombinedOrientationData->Quaternions_ext_interpolation_start.w_fx, hCombinedOrientationData->Quaternions_ext_interpolation_start.q_fact - Q29 ); + hCombinedOrientationData->Quaternions_ext_interpolation_start.x_fx = L_shr( hCombinedOrientationData->Quaternions_ext_interpolation_start.x_fx, hCombinedOrientationData->Quaternions_ext_interpolation_start.q_fact - Q29 ); + hCombinedOrientationData->Quaternions_ext_interpolation_start.y_fx = L_shr( hCombinedOrientationData->Quaternions_ext_interpolation_start.y_fx, hCombinedOrientationData->Quaternions_ext_interpolation_start.q_fact - Q29 ); + hCombinedOrientationData->Quaternions_ext_interpolation_start.z_fx = L_shr( hCombinedOrientationData->Quaternions_ext_interpolation_start.z_fx, hCombinedOrientationData->Quaternions_ext_interpolation_start.q_fact - Q29 ); + + hCombinedOrientationData->Quaternions_ext_interpolation_target.w_fx = L_shr( hCombinedOrientationData->Quaternions_ext_interpolation_target.w_fx, hCombinedOrientationData->Quaternions_ext_interpolation_target.q_fact - Q29 ); + hCombinedOrientationData->Quaternions_ext_interpolation_target.x_fx = L_shr( hCombinedOrientationData->Quaternions_ext_interpolation_target.x_fx, hCombinedOrientationData->Quaternions_ext_interpolation_target.q_fact - Q29 ); + hCombinedOrientationData->Quaternions_ext_interpolation_target.y_fx = L_shr( hCombinedOrientationData->Quaternions_ext_interpolation_target.y_fx, hCombinedOrientationData->Quaternions_ext_interpolation_target.q_fact - Q29 ); + hCombinedOrientationData->Quaternions_ext_interpolation_target.z_fx = L_shr( hCombinedOrientationData->Quaternions_ext_interpolation_target.z_fx, hCombinedOrientationData->Quaternions_ext_interpolation_target.q_fact - Q29 ); + + hCombinedOrientationData->Quaternions_ext_interpolation_start.q_fact = Q29; + move16(); + hCombinedOrientationData->Quaternions_ext_interpolation_target.q_fact = Q29; + move16(); + QuaternionSlerp_fx( hCombinedOrientationData->Quaternions_ext_interpolation_start, hCombinedOrientationData->Quaternions_ext_interpolation_target, hCombinedOrientationData->interpolationCoefficient_fx, &hCombinedOrientationData->Quaternions[i] ); + hCombinedOrientationData->interpolationCoefficient_fx = L_add_sat( hCombinedOrientationData->interpolationCoefficient_fx, hCombinedOrientationData->interpolationIncrement_Fx ); + } + ELSE { - hCombinedOrientationData->Quaternions[i].q_fact = s_min(s_min(Q_factor_L(hCombinedOrientationData->Quaternions[i].w), Q_factor_L(hCombinedOrientationData->Quaternions[i].x)), s_min(Q_factor_L(hCombinedOrientationData->Quaternions[i].y), Q_factor_L(hCombinedOrientationData->Quaternions[i].z))); - hCombinedOrientationData->Quaternions[i].w_fx = float_to_fix(hCombinedOrientationData->Quaternions[i].w, hCombinedOrientationData->Quaternions[i].q_fact); - hCombinedOrientationData->Quaternions[i].x_fx = float_to_fix(hCombinedOrientationData->Quaternions[i].x, hCombinedOrientationData->Quaternions[i].q_fact); - hCombinedOrientationData->Quaternions[i].y_fx = float_to_fix(hCombinedOrientationData->Quaternions[i].y, hCombinedOrientationData->Quaternions[i].q_fact); - hCombinedOrientationData->Quaternions[i].z_fx = float_to_fix(hCombinedOrientationData->Quaternions[i].z, hCombinedOrientationData->Quaternions[i].q_fact); + /* Use the target orientation immediately */ + hCombinedOrientationData->isInterpolationOngoing = FALSE; + hCombinedOrientationData->interpolationCoefficient_fx = ONE_IN_Q30; + move32(); + hCombinedOrientationData->interpolationIncrement_Fx = ONE_IN_Q30; + move32(); + hCombinedOrientationData->Quaternions[i] = hExtOrientationData->Quaternions[i]; } -#endif - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------- - * external_target_interpolation() - * - * - *------------------------------------------------------------------------*/ + return; +} +#else static void external_target_interpolation( EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, /* i : external orientation handle */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientation handle */ @@ -2269,31 +2826,7 @@ static void external_target_interpolation( /* Interpolate */ hCombinedOrientationData->isInterpolationOngoing = TRUE; -#ifdef IVAS_FLOAT_FIXED - hCombinedOrientationData->interpolationCoefficient_fx = float_to_fix(hCombinedOrientationData->interpolationCoefficient, Q30); - hCombinedOrientationData->Quaternions_ext_interpolation_start.w_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_start.w, Q29); - hCombinedOrientationData->Quaternions_ext_interpolation_start.x_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_start.x, Q29); - hCombinedOrientationData->Quaternions_ext_interpolation_start.y_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_start.y, Q29); - hCombinedOrientationData->Quaternions_ext_interpolation_start.z_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_start.z, Q29); - - hCombinedOrientationData->Quaternions_ext_interpolation_target.w_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_target.w, Q29); - hCombinedOrientationData->Quaternions_ext_interpolation_target.x_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_target.x, Q29); - hCombinedOrientationData->Quaternions_ext_interpolation_target.y_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_target.y, Q29); - hCombinedOrientationData->Quaternions_ext_interpolation_target.z_fx = float_to_fix(hCombinedOrientationData->Quaternions_ext_interpolation_target.z, Q29); - - hCombinedOrientationData->Quaternions_ext_interpolation_start.q_fact = Q29; - hCombinedOrientationData->Quaternions_ext_interpolation_target.q_fact = Q29; - - QuaternionSlerp_fx(hCombinedOrientationData->Quaternions_ext_interpolation_start, hCombinedOrientationData->Quaternions_ext_interpolation_target, hCombinedOrientationData->interpolationCoefficient_fx, &hCombinedOrientationData->Quaternions[i]); - - hCombinedOrientationData->Quaternions[i].w = fixedToFloat_32(hCombinedOrientationData->Quaternions[i].w_fx, hCombinedOrientationData->Quaternions[i].q_fact); - hCombinedOrientationData->Quaternions[i].x = fixedToFloat_32(hCombinedOrientationData->Quaternions[i].x_fx, hCombinedOrientationData->Quaternions[i].q_fact); - hCombinedOrientationData->Quaternions[i].y = fixedToFloat_32(hCombinedOrientationData->Quaternions[i].y_fx, hCombinedOrientationData->Quaternions[i].q_fact); - hCombinedOrientationData->Quaternions[i].z = fixedToFloat_32(hCombinedOrientationData->Quaternions[i].z_fx, hCombinedOrientationData->Quaternions[i].q_fact); - -#else - QuaternionSlerp(hCombinedOrientationData->Quaternions_ext_interpolation_start, hCombinedOrientationData->Quaternions_ext_interpolation_target, hCombinedOrientationData->interpolationCoefficient, &hCombinedOrientationData->Quaternions[i]); -#endif + QuaternionSlerp( hCombinedOrientationData->Quaternions_ext_interpolation_start, hCombinedOrientationData->Quaternions_ext_interpolation_target, hCombinedOrientationData->interpolationCoefficient, &hCombinedOrientationData->Quaternions[i] ); hCombinedOrientationData->interpolationCoefficient += hCombinedOrientationData->interpolationIncrement; } else @@ -2304,25 +2837,50 @@ static void external_target_interpolation( hCombinedOrientationData->interpolationIncrement = 1.0f; hCombinedOrientationData->Quaternions[i] = hExtOrientationData->Quaternions[i]; } -#ifdef IVAS_FLOAT_FIXED - /* Updating the fixed point values which will be used later */ - hCombinedOrientationData->Quaternions[i].q_fact = s_min(s_min(Q_factor_L(hCombinedOrientationData->Quaternions[i].w), Q_factor_L(hCombinedOrientationData->Quaternions[i].x)), s_min(Q_factor_L(hCombinedOrientationData->Quaternions[i].y), Q_factor_L(hCombinedOrientationData->Quaternions[i].z))); - hCombinedOrientationData->Quaternions[i].w_fx = float_to_fix(hCombinedOrientationData->Quaternions[i].w, hCombinedOrientationData->Quaternions[i].q_fact); - hCombinedOrientationData->Quaternions[i].x_fx = float_to_fix(hCombinedOrientationData->Quaternions[i].x, hCombinedOrientationData->Quaternions[i].q_fact); - hCombinedOrientationData->Quaternions[i].y_fx = float_to_fix(hCombinedOrientationData->Quaternions[i].y, hCombinedOrientationData->Quaternions[i].q_fact); - hCombinedOrientationData->Quaternions[i].z_fx = float_to_fix(hCombinedOrientationData->Quaternions[i].z, hCombinedOrientationData->Quaternions[i].q_fact); -#endif return; } - +#endif /*------------------------------------------------------------------------- * are_orientations_same() * * *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static bool are_orientations_same_fx( + const IVAS_QUATERNION *orientation1, + const IVAS_QUATERNION *orientation2 ) +{ + bool orientationsAreSame = true; + Word32 error_margin_fx = 107374182; // 0.05f in Q31 + move32(); + Word16 error_margin_e = 0; + move16(); + Word16 w_e = 0, x_e = 0, y_e = 0, z_e = 0; + move16(); + move16(); + move16(); + Word32 w_result = 0, x_result = 0, y_result = 0, z_result = 0; + w_result = L_abs( BASOP_Util_Add_Mant32Exp( orientation1->w_fx, sub(31 , orientation1->q_fact), L_negate( orientation2->w_fx ), sub(31 , orientation2->q_fact), &w_e ) ); + x_result = L_abs( BASOP_Util_Add_Mant32Exp( orientation1->x_fx, sub(31 , orientation1->q_fact), L_negate( orientation2->x_fx ), sub(31 , orientation2->q_fact), &x_e ) ); + y_result = L_abs( BASOP_Util_Add_Mant32Exp( orientation1->y_fx, sub(31 , orientation1->q_fact), L_negate( orientation2->y_fx ), sub(31 , orientation2->q_fact), &y_e ) ); + z_result = L_abs( BASOP_Util_Add_Mant32Exp( orientation1->z_fx, sub(31 , orientation1->q_fact), L_negate( orientation2->z_fx ), sub(31 , orientation2->q_fact), &z_e ) ); + Word16 Flag_1 = BASOP_Util_Cmp_Mant32Exp( w_result, w_e, error_margin_fx, error_margin_e ); + Word16 Flag_2 = BASOP_Util_Cmp_Mant32Exp( x_result, x_e, error_margin_fx, error_margin_e ); + Word16 Flag_3 = BASOP_Util_Cmp_Mant32Exp( y_result, y_e, error_margin_fx, error_margin_e ); + Word16 Flag_4 = BASOP_Util_Cmp_Mant32Exp( z_result, z_e, error_margin_fx, error_margin_e ); + IF( EQ_16( Flag_1 , 1 ) || + EQ_16( Flag_2 , 1 ) || + EQ_16( Flag_3 , 1 ) || + EQ_16( Flag_4 , 1 ) ) + { + orientationsAreSame = false; + } + return orientationsAreSame; +} +#endif static bool are_orientations_same( const IVAS_QUATERNION *orientation1, const IVAS_QUATERNION *orientation2 ) @@ -2943,7 +3501,7 @@ void ivas_combined_orientation_update_start_index( { IF( hCombinedOrientationData != NULL ) { - IF( EQ_16(hCombinedOrientationData->num_subframes , 1) ) + IF( EQ_16( hCombinedOrientationData->num_subframes, 1 ) ) { /* only one orientation available anyway or split rendering with low resolution*/ hCombinedOrientationData->subframe_idx = 0; @@ -2952,9 +3510,9 @@ void ivas_combined_orientation_update_start_index( ELSE { hCombinedOrientationData->cur_subframe_samples_rendered_start = add( hCombinedOrientationData->cur_subframe_samples_rendered_start, samples_rendered ); - hCombinedOrientationData->subframe_idx_start = add(hCombinedOrientationData->subframe_idx_start,mult(hCombinedOrientationData->cur_subframe_samples_rendered , div_s(1,hCombinedOrientationData->subframe_size))); - hCombinedOrientationData->cur_subframe_samples_rendered_start = hCombinedOrientationData->cur_subframe_samples_rendered % hCombinedOrientationData->subframe_size;/* No operator to calculate modulo*/ - hCombinedOrientationData->subframe_idx_start = s_min( hCombinedOrientationData->subframe_idx, sub(hCombinedOrientationData->num_subframes , 1) ); + hCombinedOrientationData->subframe_idx_start = add( hCombinedOrientationData->subframe_idx_start, mult( hCombinedOrientationData->cur_subframe_samples_rendered, div_s( 1, hCombinedOrientationData->subframe_size ) ) ); + hCombinedOrientationData->cur_subframe_samples_rendered_start = hCombinedOrientationData->cur_subframe_samples_rendered % hCombinedOrientationData->subframe_size; /* No operator to calculate modulo*/ + hCombinedOrientationData->subframe_idx_start = s_min( hCombinedOrientationData->subframe_idx, sub( hCombinedOrientationData->num_subframes, 1 ) ); } } diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 9215f0068fecaada43395554f46a0dec57691a63..0824de2c3e501d0486a2736ea3e0d3bf18bd9b40 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -931,8 +931,8 @@ typedef struct ivas_binaural_rendering_conv_module_struct_fx Word32 ***filterStatesLeftImag_fx; Word16 ***Q_filterStatesLeft; - int16_t numTapsArray[BINAURAL_CONVBANDS]; - int16_t numTaps; + Word16 numTapsArray[BINAURAL_CONVBANDS]; + Word16 numTaps; } BINRENDERER_CONV_MODULE_FX, *BINRENDERER_CONV_MODULE_HANDLE_FX; #endif @@ -1112,7 +1112,18 @@ typedef struct ivas_binaural_head_track_struct /*----------------------------------------------------------------------------------* * External orientation data structure *----------------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +typedef struct ivas_external_orientation_struct +{ + Word8 enableHeadRotation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable, 2 - freeze to previous rotation */ + Word8 enableExternalOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable, 2 - freeze to previous orientation */ + Word8 enableRotationInterpolation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable */ + Word16 numFramesToTargetOrientation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* Number of frames until target orientation is reached */ + IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; /* External orientation in quaternions */ + Word16 num_subframes; +} EXTERNAL_ORIENTATION_DATA, *EXTERNAL_ORIENTATION_HANDLE; +#else typedef struct ivas_external_orientation_struct { int8_t enableHeadRotation[MAX_PARAM_SPATIAL_SUBFRAMES]; /* 0 - disable, 1 - enable, 2 - freeze to previous rotation */ @@ -1123,7 +1134,7 @@ typedef struct ivas_external_orientation_struct int16_t num_subframes; } EXTERNAL_ORIENTATION_DATA, *EXTERNAL_ORIENTATION_HANDLE; - +#endif /*----------------------------------------------------------------------------------* * Combined orientation data structure for the external orienations and head orientation *----------------------------------------------------------------------------------*/ @@ -1712,6 +1723,7 @@ typedef struct TDREND_HRFILT_FiltSet_struct Word16 *Elev_p_fx; Word16 *LeftFiltSet_p_fx; Word16 *RightFiltSet_p_fx; + Word32 *lr_energy_and_iac_dyn_fx[3]; const Word32 *lr_energy_and_iac_fx[3]; /* left/right energy and interaural coherence for late reverb */ Word32 latency_s_fx;/*Q-31*/ #endif // IVAS_FLOAT_FIXED @@ -1986,6 +1998,10 @@ typedef struct ivas_hrtfs_crend_structure /* Fastconv binaural data structure */ typedef struct ivas_hrtfs_fastconv_struct { +#ifdef IVAS_FLOAT_FIXED + Word32 FASTCONV_HOA3_latency_s_fx; + Word32 FASTCONV_HRIR_latency_s_fx; +#endif float FASTCONV_HOA3_latency_s; float FASTCONV_HRIR_latency_s; @@ -2016,6 +2032,7 @@ typedef struct ivas_hrtfs_fastconv_struct Word32 ***leftBRIRImag_fx; Word32 ***rightBRIRReal_fx; Word32 ***rightBRIRImag_fx; + Word32 FASTCONV_BRIR_latency_s_fx; #endif float ***leftBRIRReal; float ***leftBRIRImag; @@ -2028,6 +2045,7 @@ typedef struct ivas_hrtfs_fastconv_struct Word32 ***leftHRIRImag_HOA2_fx; Word32 ***rightHRIRReal_HOA2_fx; Word32 ***rightHRIRImag_HOA2_fx; + Word32 FASTCONV_HOA2_latency_s_fx; #endif float ***leftHRIRReal_HOA2; float ***leftHRIRImag_HOA2; @@ -2040,6 +2058,7 @@ typedef struct ivas_hrtfs_fastconv_struct Word32 ***leftHRIRImag_FOA_fx; Word32 ***rightHRIRReal_FOA_fx; Word32 ***rightHRIRImag_FOA_fx; + Word32 FASTCONV_FOA_latency_s_fx; #endif float ***leftHRIRReal_FOA; float ***leftHRIRImag_FOA; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index d4bd50556ca94a0e5810df9917438029441c5707..7793b192ca88d3b5065632f9c41898daf54deeb7 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -2202,7 +2202,11 @@ static ivas_error initIsmMasaRendering( if ( inputIsm->tdRendWrapper.hBinRendererTd != NULL ) { +#ifdef IVAS_FLOAT_FIXED + ivas_td_binaural_close_fx( &inputIsm->tdRendWrapper.hBinRendererTd ); +#else ivas_td_binaural_close( &inputIsm->tdRendWrapper.hBinRendererTd ); +#endif // IVAS_FLOAT_FIXED inputIsm->tdRendWrapper.hHrtfTD = NULL; } @@ -2356,7 +2360,11 @@ static void clearInputIsm( if ( inputIsm->tdRendWrapper.hBinRendererTd != NULL ) { +#ifdef IVAS_FLOAT_FIXED + ivas_td_binaural_close_fx( &inputIsm->tdRendWrapper.hBinRendererTd ); +#else ivas_td_binaural_close( &inputIsm->tdRendWrapper.hBinRendererTd ); +#endif inputIsm->tdRendWrapper.hHrtfTD = NULL; } @@ -3705,7 +3713,11 @@ static ivas_error initMcBinauralRendering( /* if TD renderer was open and we need to use CREND, close it */ if ( !reconfigureFlag || ( !useTDRend && inputMc->tdRendWrapper.hBinRendererTd != NULL ) ) { +#ifdef IVAS_FLOAT_FIXED + ivas_td_binaural_close_fx( &inputMc->tdRendWrapper.hBinRendererTd ); +#else ivas_td_binaural_close( &inputMc->tdRendWrapper.hBinRendererTd ); +#endif inputMc->tdRendWrapper.hHrtfTD = NULL; } @@ -3841,7 +3853,11 @@ static ivas_error initMcMasaRendering( if ( inputMc->tdRendWrapper.hBinRendererTd != NULL ) { +#ifdef IVAS_FLOAT_FIXED + ivas_td_binaural_close_fx( &inputMc->tdRendWrapper.hBinRendererTd ); +#else ivas_td_binaural_close( &inputMc->tdRendWrapper.hBinRendererTd ); +#endif inputMc->tdRendWrapper.hHrtfTD = NULL; } @@ -4175,7 +4191,11 @@ static void clearInputMc( if ( inputMc->tdRendWrapper.hBinRendererTd != NULL ) { +#ifdef IVAS_FLOAT_FIXED + ivas_td_binaural_close_fx( &inputMc->tdRendWrapper.hBinRendererTd ); +#else ivas_td_binaural_close( &inputMc->tdRendWrapper.hBinRendererTd ); +#endif inputMc->tdRendWrapper.hHrtfTD = NULL; } @@ -4885,13 +4905,48 @@ ivas_error IVAS_REND_Open( { return error; } +#ifdef IVAS_FLOAT_FIXED + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + hIvasRend->hExternalOrientationData->Quaternions[i].w = fixedToFloat_32( hIvasRend->hExternalOrientationData->Quaternions[i].w_fx, hIvasRend->hExternalOrientationData->Quaternions[i].q_fact ); + hIvasRend->hExternalOrientationData->Quaternions[i].x = fixedToFloat_32( hIvasRend->hExternalOrientationData->Quaternions[i].x_fx, hIvasRend->hExternalOrientationData->Quaternions[i].q_fact ); + hIvasRend->hExternalOrientationData->Quaternions[i].y = fixedToFloat_32( hIvasRend->hExternalOrientationData->Quaternions[i].y_fx, hIvasRend->hExternalOrientationData->Quaternions[i].q_fact ); + hIvasRend->hExternalOrientationData->Quaternions[i].z = fixedToFloat_32( hIvasRend->hExternalOrientationData->Quaternions[i].z_fx, hIvasRend->hExternalOrientationData->Quaternions[i].q_fact ); + } +#endif /* Initilize combined orientation data */ if ( ( error = ivas_combined_orientation_open( &( hIvasRend->hCombinedOrientationData ), outputSampleRate, num_subframes ) ) != IVAS_ERR_OK ) { return error; } - +#ifdef IVAS_FLOAT_FIXED + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + hIvasRend->hCombinedOrientationData->Quaternions[i].w = fixedToFloat_32( hIvasRend->hCombinedOrientationData->Quaternions[i].w_fx, hIvasRend->hCombinedOrientationData->Quaternions[i].q_fact ); + hIvasRend->hCombinedOrientationData->Quaternions[i].x = fixedToFloat_32( hIvasRend->hCombinedOrientationData->Quaternions[i].x_fx, hIvasRend->hCombinedOrientationData->Quaternions[i].q_fact ); + hIvasRend->hCombinedOrientationData->Quaternions[i].y = fixedToFloat_32( hIvasRend->hCombinedOrientationData->Quaternions[i].y_fx, hIvasRend->hCombinedOrientationData->Quaternions[i].q_fact ); + hIvasRend->hCombinedOrientationData->Quaternions[i].z = fixedToFloat_32( hIvasRend->hCombinedOrientationData->Quaternions[i].z_fx, hIvasRend->hCombinedOrientationData->Quaternions[i].q_fact ); + + hIvasRend->hCombinedOrientationData->listenerPos[i].x = fixedToFloat_32( hIvasRend->hCombinedOrientationData->listenerPos[i].x_fx, hIvasRend->hCombinedOrientationData->listenerPos[i].q_fact ); + hIvasRend->hCombinedOrientationData->listenerPos[i].y = fixedToFloat_32( hIvasRend->hCombinedOrientationData->listenerPos[i].y_fx, hIvasRend->hCombinedOrientationData->listenerPos[i].q_fact ); + hIvasRend->hCombinedOrientationData->listenerPos[i].z = fixedToFloat_32( hIvasRend->hCombinedOrientationData->listenerPos[i].z_fx, hIvasRend->hCombinedOrientationData->listenerPos[i].q_fact ); + for ( Word16 j = 0; j < 3; j++ ) + { + for ( Word16 k = 0; k < 3; k++ ) + { + hIvasRend->hCombinedOrientationData->Rmat[i][j][k] = (float) fixedToFloat_32( hIvasRend->hCombinedOrientationData->Rmat_fx[i][j][k], 30 ); + } + } + } + for ( Word16 j = 0; j < 3; j++ ) + { + for ( Word16 k = 0; k < 3; k++ ) + { + hIvasRend->hCombinedOrientationData->Rmat_prev[j][k] = (float) fixedToFloat_32( hIvasRend->hCombinedOrientationData->Rmat_prev_fx[j][k], 30 ); + } + } +#endif /* Initialize EFAP */ if ( ( error = initEfap( &hIvasRend->efapOutWrapper, outConfig, &hIvasRend->customLsOut ) ) != IVAS_ERR_OK ) { @@ -7305,8 +7360,32 @@ ivas_error IVAS_REND_CombineHeadAndExternalOrientation( { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + ivas_error error_type = combine_external_and_head_orientations_rend( &hIvasRend->headRotData, hIvasRend->hExternalOrientationData, hIvasRend->hCombinedOrientationData ); +#ifdef IVAS_FLOAT_FIXED + for ( Word16 i = 0; i < hIvasRend->hCombinedOrientationData->num_subframes; i++ ) + { + hIvasRend->hCombinedOrientationData->Quaternions[i].w = fixedToFloat_32( hIvasRend->hCombinedOrientationData->Quaternions[i].w_fx, hIvasRend->hCombinedOrientationData->Quaternions[i].q_fact ); + hIvasRend->hCombinedOrientationData->Quaternions[i].x = fixedToFloat_32( hIvasRend->hCombinedOrientationData->Quaternions[i].x_fx, hIvasRend->hCombinedOrientationData->Quaternions[i].q_fact ); + hIvasRend->hCombinedOrientationData->Quaternions[i].y = fixedToFloat_32( hIvasRend->hCombinedOrientationData->Quaternions[i].y_fx, hIvasRend->hCombinedOrientationData->Quaternions[i].q_fact ); + hIvasRend->hCombinedOrientationData->Quaternions[i].z = fixedToFloat_32( hIvasRend->hCombinedOrientationData->Quaternions[i].z_fx, hIvasRend->hCombinedOrientationData->Quaternions[i].q_fact ); - return combine_external_and_head_orientations_rend( &hIvasRend->headRotData, hIvasRend->hExternalOrientationData, hIvasRend->hCombinedOrientationData ); + /*for ( j = 0; j < 3; j++ ) + { + for ( Word16 k = 0; k < 3; k++ ) + { + hCombinedOrientationData->Rmat_fx[i][j][k] = L_shl( hCombinedOrientationData->Rmat_fx[i][j][k], 30 - ( 2 * hCombinedOrientationData->Quaternions[i].q_fact - 32 ) ); + } + }*/ + for ( Word16 j = 0; j < 3; j++ ) + { + for ( Word16 k = 0; k < 3; k++ ) + { + hIvasRend->hCombinedOrientationData->Rmat[i][j][k] = (float) fixedToFloat_32( hIvasRend->hCombinedOrientationData->Rmat_fx[i][j][k], 30 ); + } + } + } +#endif + return error_type; } diff --git a/lib_util/hrtf_file_reader.c b/lib_util/hrtf_file_reader.c index 33bebf42f84c2a40133888672661b6b896ade16c..c8b7643c101c6a2f760028ec12f300ed2d278ac4 100644 --- a/lib_util/hrtf_file_reader.c +++ b/lib_util/hrtf_file_reader.c @@ -363,6 +363,9 @@ static ivas_error LoadBSplineBinary( int16_t i, tmp; fread( &HrFiltSet_p->latency_s, sizeof( float ), 1, f_hrtf ); +#ifdef IVAS_FLOAT_FIXED + HrFiltSet_p->latency_s_fx = float_to_fix( HrFiltSet_p->latency_s, Q31 ); +#endif // IVAS_FLOAT_FIXED model = &( HrFiltSet_p->ModelParams ); @@ -568,6 +571,14 @@ static ivas_error LoadBSplineBinary( HrFiltSet_p->lr_energy_and_iac_dyn[i] = (float *) malloc( LR_IAC_LENGTH_NR_FC * sizeof( float ) ); fread( HrFiltSet_p->lr_energy_and_iac_dyn[i], sizeof( const float ), LR_IAC_LENGTH_NR_FC, f_hrtf ); HrFiltSet_p->lr_energy_and_iac[i] = (const float *) HrFiltSet_p->lr_energy_and_iac_dyn[i]; +#ifdef IVAS_FLOAT_FIXED + HrFiltSet_p->lr_energy_and_iac_dyn_fx[i] = (Word32 *) malloc( LR_IAC_LENGTH_NR_FC * sizeof( Word32 ) ); + IF( i == 2 ) + floatToFixed_arr32( HrFiltSet_p->lr_energy_and_iac_dyn[i], HrFiltSet_p->lr_energy_and_iac_dyn_fx[i], Q27, LR_IAC_LENGTH_NR_FC ); /* tables from which lr_energy_and_iac is updated has Q27 for i=2 */ + ELSE + floatToFixed_arr32( HrFiltSet_p->lr_energy_and_iac_dyn[i], HrFiltSet_p->lr_energy_and_iac_dyn_fx[i], Q23, LR_IAC_LENGTH_NR_FC ); /* tables from which lr_energy_and_iac is updated has Q23 for i=0,1 */ + HrFiltSet_p->lr_energy_and_iac_fx[i] = (const Word32 *) HrFiltSet_p->lr_energy_and_iac_dyn_fx[i]; +#endif // IVAS_FLOAT_FIXED } return IVAS_ERR_OK; @@ -895,6 +906,9 @@ ivas_error dealloc_HRTF_binary( for ( i = 0; i < 3; i++ ) { free( hHrtf->lr_energy_and_iac_dyn[i] ); +#ifdef IVAS_FLOAT_FIXED + free( hHrtf->lr_energy_and_iac_dyn_fx[i] ); +#endif // IVAS_FLOAT_FIXED } } @@ -1405,6 +1419,9 @@ static ivas_error create_fastconv_HRTF_from_rawdata( ) { int16_t i, j; + float f_tmp; + float f_tmp_ntaps_sba[BINAURAL_NTAPS]; + float f_tmp_ntaps_max[BINAURAL_NTAPS_MAX]; char *hrtf_data_rptr; ( *hHRTF )->allocate_init_flag = 0; ivas_allocate_binaural_hrtf_fx( *hHRTF, 0, input_cfg, rend_type, ( *hHRTF )->allocate_init_flag ); @@ -1421,8 +1438,9 @@ static ivas_error create_fastconv_HRTF_from_rawdata( /* HRIR */ if ( rend_type == RENDERER_BINAURAL_FASTCONV && input_cfg == BINAURAL_INPUT_AUDIO_CONFIG_COMBINED ) { - ( *hHRTF )->FASTCONV_HRIR_latency_s = *( (float *) ( hrtf_data_rptr ) ); + f_tmp = *( (float *) ( hrtf_data_rptr ) ); hrtf_data_rptr += sizeof( float ); + ( *hHRTF )->FASTCONV_HRIR_latency_s_fx = (Word32) ( f_tmp * 1000000000 ); if ( HRTF_LS_CHANNELS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) { @@ -1440,39 +1458,44 @@ static ivas_error create_fastconv_HRTF_from_rawdata( { for ( j = 0; j < HRTF_LS_CHANNELS; j++ ) { - memcpy( ( *hHRTF )->leftHRIRReal[i][j], hrtf_data_rptr, BINAURAL_NTAPS * sizeof( float ) ); + memcpy( f_tmp_ntaps_sba, hrtf_data_rptr, BINAURAL_NTAPS * sizeof( float ) ); hrtf_data_rptr += BINAURAL_NTAPS * sizeof( float ); + floatToFixed_arrL( f_tmp_ntaps_sba, ( *hHRTF )->leftHRIRReal_fx[i][j], Q29, BINAURAL_NTAPS ); } } for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) { for ( j = 0; j < HRTF_LS_CHANNELS; j++ ) { - memcpy( ( *hHRTF )->leftHRIRImag[i][j], hrtf_data_rptr, BINAURAL_NTAPS * sizeof( float ) ); + memcpy( f_tmp_ntaps_sba, hrtf_data_rptr, BINAURAL_NTAPS * sizeof( float ) ); hrtf_data_rptr += BINAURAL_NTAPS * sizeof( float ); + floatToFixed_arrL( f_tmp_ntaps_sba, ( *hHRTF )->leftHRIRImag_fx[i][j], Q29, BINAURAL_NTAPS ); } } for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) { for ( j = 0; j < HRTF_LS_CHANNELS; j++ ) { - memcpy( ( *hHRTF )->rightHRIRReal[i][j], hrtf_data_rptr, BINAURAL_NTAPS * sizeof( float ) ); + memcpy( f_tmp_ntaps_sba, hrtf_data_rptr, BINAURAL_NTAPS * sizeof( float ) ); hrtf_data_rptr += BINAURAL_NTAPS * sizeof( float ); + floatToFixed_arrL( f_tmp_ntaps_sba, ( *hHRTF )->rightHRIRReal_fx[i][j], Q29, BINAURAL_NTAPS ); } } for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) { for ( j = 0; j < HRTF_LS_CHANNELS; j++ ) { - memcpy( ( *hHRTF )->rightHRIRImag[i][j], hrtf_data_rptr, BINAURAL_NTAPS * sizeof( float ) ); + memcpy( f_tmp_ntaps_sba, hrtf_data_rptr, BINAURAL_NTAPS * sizeof( float ) ); hrtf_data_rptr += BINAURAL_NTAPS * sizeof( float ); + floatToFixed_arrL( f_tmp_ntaps_sba, ( *hHRTF )->rightHRIRImag_fx[i][j], Q29, BINAURAL_NTAPS ); } } } else if ( rend_type == RENDERER_BINAURAL_FASTCONV && input_cfg == BINAURAL_INPUT_AUDIO_CONFIG_HOA3 ) { /* HRIR_HOA3 */ - ( *hHRTF )->FASTCONV_HOA3_latency_s = *( (float *) ( hrtf_data_rptr ) ); + f_tmp = *( (float *) ( hrtf_data_rptr ) ); + ( *hHRTF )->FASTCONV_HOA3_latency_s_fx = (Word32) ( f_tmp * 1000000000 ); hrtf_data_rptr += sizeof( float ); if ( HOA3_CHANNELS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) @@ -1490,39 +1513,44 @@ static ivas_error create_fastconv_HRTF_from_rawdata( { for ( j = 0; j < HOA3_CHANNELS; j++ ) { - memcpy( ( *hHRTF )->leftHRIRReal_HOA3[i][j], hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); + memcpy( f_tmp_ntaps_sba, hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( float ); + floatToFixed_arrL( f_tmp_ntaps_sba, ( *hHRTF )->leftHRIRReal_HOA3_fx[i][j], Q29, BINAURAL_NTAPS_SBA ); } } for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) { for ( j = 0; j < HOA3_CHANNELS; j++ ) { - memcpy( ( *hHRTF )->leftHRIRImag_HOA3[i][j], hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); + memcpy( f_tmp_ntaps_sba, hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( float ); + floatToFixed_arrL( f_tmp_ntaps_sba, ( *hHRTF )->leftHRIRImag_HOA3_fx[i][j], Q29, BINAURAL_NTAPS_SBA ); } } for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) { for ( j = 0; j < HOA3_CHANNELS; j++ ) { - memcpy( ( *hHRTF )->rightHRIRReal_HOA3[i][j], hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); + memcpy( f_tmp_ntaps_sba, hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( float ); + floatToFixed_arrL( f_tmp_ntaps_sba, ( *hHRTF )->rightHRIRReal_HOA3_fx[i][j], Q29, BINAURAL_NTAPS_SBA ); } } for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) { for ( j = 0; j < HOA3_CHANNELS; j++ ) { - memcpy( ( *hHRTF )->rightHRIRImag_HOA3[i][j], hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); + memcpy( f_tmp_ntaps_sba, hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( float ); + floatToFixed_arrL( f_tmp_ntaps_sba, ( *hHRTF )->rightHRIRReal_HOA3_fx[i][j], Q29, BINAURAL_NTAPS_SBA ); } } } else if ( rend_type == RENDERER_BINAURAL_FASTCONV && input_cfg == BINAURAL_INPUT_AUDIO_CONFIG_HOA2 ) { /* HRIR_HOA2 */ - ( *hHRTF )->FASTCONV_HOA2_latency_s = *( (float *) ( hrtf_data_rptr ) ); + f_tmp = *( (float *) ( hrtf_data_rptr ) ); + ( *hHRTF )->FASTCONV_HOA2_latency_s_fx = (Word32) ( f_tmp * 1000000000 ); hrtf_data_rptr += sizeof( float ); if ( HOA2_CHANNELS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) { @@ -1540,39 +1568,44 @@ static ivas_error create_fastconv_HRTF_from_rawdata( { for ( j = 0; j < HOA2_CHANNELS; j++ ) { - memcpy( ( *hHRTF )->leftHRIRReal_HOA2[i][j], hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); + memcpy( f_tmp_ntaps_sba, hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( float ); + floatToFixed_arrL( f_tmp_ntaps_sba, ( *hHRTF )->leftHRIRReal_HOA2_fx[i][j], Q29, BINAURAL_NTAPS_SBA ); } } for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) { for ( j = 0; j < HOA2_CHANNELS; j++ ) { - memcpy( ( *hHRTF )->leftHRIRImag_HOA2[i][j], hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); + memcpy( f_tmp_ntaps_sba, hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( float ); + floatToFixed_arrL( f_tmp_ntaps_sba, ( *hHRTF )->leftHRIRImag_HOA2_fx[i][j], Q29, BINAURAL_NTAPS_SBA ); } } for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) { for ( j = 0; j < HOA2_CHANNELS; j++ ) { - memcpy( ( *hHRTF )->rightHRIRReal_HOA2[i][j], hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); + memcpy( f_tmp_ntaps_sba, hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( float ); + floatToFixed_arrL( f_tmp_ntaps_sba, ( *hHRTF )->rightHRIRReal_HOA2_fx[i][j], Q29, BINAURAL_NTAPS_SBA ); } } for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) { for ( j = 0; j < HOA2_CHANNELS; j++ ) { - memcpy( ( *hHRTF )->rightHRIRImag_HOA2[i][j], hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); + memcpy( f_tmp_ntaps_sba, hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( float ); + floatToFixed_arrL( f_tmp_ntaps_sba, ( *hHRTF )->rightHRIRImag_HOA2_fx[i][j], Q29, BINAURAL_NTAPS_SBA ); } } } else if ( rend_type == RENDERER_BINAURAL_FASTCONV && input_cfg == BINAURAL_INPUT_AUDIO_CONFIG_FOA ) { /* HRIR_FOA */ - ( *hHRTF )->FASTCONV_FOA_latency_s = *( (float *) ( hrtf_data_rptr ) ); + f_tmp = *( (float *) ( hrtf_data_rptr ) ); + ( *hHRTF )->FASTCONV_FOA_latency_s_fx = (Word32) ( f_tmp * 1000000000 ); hrtf_data_rptr += sizeof( float ); if ( FOA_CHANNELS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) { @@ -1590,39 +1623,44 @@ static ivas_error create_fastconv_HRTF_from_rawdata( { for ( j = 0; j < FOA_CHANNELS; j++ ) { - memcpy( ( *hHRTF )->leftHRIRReal_FOA[i][j], hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); + memcpy( f_tmp_ntaps_sba, hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( float ); + floatToFixed_arrL( f_tmp_ntaps_sba, ( *hHRTF )->leftHRIRReal_FOA_fx[i][j], Q29, BINAURAL_NTAPS_SBA ); } } for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) { for ( j = 0; j < FOA_CHANNELS; j++ ) { - memcpy( ( *hHRTF )->leftHRIRImag_FOA[i][j], hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); + memcpy( f_tmp_ntaps_sba, hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( float ); + floatToFixed_arrL( f_tmp_ntaps_sba, ( *hHRTF )->leftHRIRImag_FOA_fx[i][j], Q29, BINAURAL_NTAPS_SBA ); } } for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) { for ( j = 0; j < FOA_CHANNELS; j++ ) { - memcpy( ( *hHRTF )->rightHRIRReal_FOA[i][j], hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); + memcpy( f_tmp_ntaps_sba, hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( float ); + floatToFixed_arrL( f_tmp_ntaps_sba, ( *hHRTF )->rightHRIRReal_FOA_fx[i][j], Q29, BINAURAL_NTAPS_SBA ); } } for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) { for ( j = 0; j < FOA_CHANNELS; j++ ) { - memcpy( ( *hHRTF )->rightHRIRImag_FOA[i][j], hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); + memcpy( f_tmp_ntaps_sba, hrtf_data_rptr, BINAURAL_NTAPS_SBA * sizeof( float ) ); hrtf_data_rptr += BINAURAL_NTAPS_SBA * sizeof( float ); + floatToFixed_arrL( f_tmp_ntaps_sba, ( *hHRTF )->rightHRIRImag_FOA_fx[i][j], Q29, BINAURAL_NTAPS_SBA ); } } } /* BRIR */ else if ( rend_type == RENDERER_BINAURAL_FASTCONV_ROOM && input_cfg == BINAURAL_INPUT_AUDIO_CONFIG_COMBINED ) { - ( *hHRTF )->FASTCONV_BRIR_latency_s = *( (float *) ( hrtf_data_rptr ) ); + f_tmp = *( (float *) ( hrtf_data_rptr ) ); + ( *hHRTF )->FASTCONV_BRIR_latency_s_fx = (Word32) ( f_tmp * 1000000000 ); hrtf_data_rptr += sizeof( float ); if ( HRTF_LS_CHANNELS != *( (uint16_t *) ( hrtf_data_rptr ) ) ) @@ -1641,32 +1679,36 @@ static ivas_error create_fastconv_HRTF_from_rawdata( { for ( j = 0; j < HRTF_LS_CHANNELS; j++ ) { - memcpy( ( *hHRTF )->leftBRIRReal[i][j], hrtf_data_rptr, BINAURAL_NTAPS_MAX * sizeof( float ) ); + memcpy( f_tmp_ntaps_max, hrtf_data_rptr, BINAURAL_NTAPS_MAX * sizeof( float ) ); hrtf_data_rptr += BINAURAL_NTAPS_MAX * sizeof( float ); + floatToFixed_arrL( f_tmp_ntaps_max, ( *hHRTF )->leftBRIRReal_fx[i][j], Q29, BINAURAL_NTAPS_MAX ); } } for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) { for ( j = 0; j < HRTF_LS_CHANNELS; j++ ) { - memcpy( ( *hHRTF )->leftBRIRImag[i][j], hrtf_data_rptr, BINAURAL_NTAPS_MAX * sizeof( float ) ); + memcpy( f_tmp_ntaps_max, hrtf_data_rptr, BINAURAL_NTAPS_MAX * sizeof( float ) ); hrtf_data_rptr += BINAURAL_NTAPS_MAX * sizeof( float ); + floatToFixed_arrL( f_tmp_ntaps_max, ( *hHRTF )->leftBRIRImag_fx[i][j], Q29, BINAURAL_NTAPS_MAX ); } } for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) { for ( j = 0; j < HRTF_LS_CHANNELS; j++ ) { - memcpy( ( *hHRTF )->rightBRIRReal[i][j], hrtf_data_rptr, BINAURAL_NTAPS_MAX * sizeof( float ) ); + memcpy( f_tmp_ntaps_max, hrtf_data_rptr, BINAURAL_NTAPS_MAX * sizeof( float ) ); hrtf_data_rptr += BINAURAL_NTAPS_MAX * sizeof( float ); + floatToFixed_arrL( f_tmp_ntaps_max, ( *hHRTF )->rightBRIRReal_fx[i][j], Q29, BINAURAL_NTAPS_MAX ); } } for ( i = 0; i < BINAURAL_CONVBANDS; i++ ) { for ( j = 0; j < HRTF_LS_CHANNELS; j++ ) { - memcpy( ( *hHRTF )->rightBRIRImag[i][j], hrtf_data_rptr, BINAURAL_NTAPS_MAX * sizeof( float ) ); + memcpy( f_tmp_ntaps_max, hrtf_data_rptr, BINAURAL_NTAPS_MAX * sizeof( float ) ); hrtf_data_rptr += BINAURAL_NTAPS_MAX * sizeof( float ); + floatToFixed_arrL( f_tmp_ntaps_max, ( *hHRTF )->rightBRIRImag_fx[i][j], Q29, BINAURAL_NTAPS_MAX ); } }