From d5677a690a9bc9c01fa970e943cdcced97956424 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Sun, 4 Feb 2024 06:32:34 +0530 Subject: [PATCH] Subfunctions for ivas_td_binaural_open converted to fxd point. [x]Few functions added/cleaned up: TDREND_MIX_Init,TDREND_MIX_SetDistAttenModel,TDREND_SRC_Init, TDREND_SRC_SPATIAL_Init,TDREND_SRC_REND_Init,TDREND_SPATIAL_VecInit, TDREND_MIX_AddSrc_fx,TDREND_MIX_SRC_SetPos,TDREND_MIX_SRC_SetPlayState_fx, TDREND_SRC_SPATIAL_SetDirAtten_fx,TDREND_MIX_SRC_SetDirAtten_fx [x] Few BASOP updates and initializations. --- lib_com/ivas_prot.h | 8 + lib_dec/ivas_ism_dec.c | 82 ++++++++ lib_dec/ivas_objectRenderer_internal.c | 18 ++ lib_rend/ivas_objectRenderer.c | 221 +++++++++++++++++++++ lib_rend/ivas_objectRenderer_mix.c | 203 +++++++++++++++++++- lib_rend/ivas_objectRenderer_sources.c | 253 ++++++++++++++++++++++++- lib_rend/ivas_objectRenderer_vec.c | 36 ++++ lib_rend/ivas_prot_rend.h | 83 ++++++++ lib_rend/ivas_stat_rend.h | 42 ++++ 9 files changed, 934 insertions(+), 12 deletions(-) diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index e368250e1..25a0813a4 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -6051,6 +6051,14 @@ void ivas_omasa_modify_masa_energy_ratios( /*----------------------------------------------------------------------------------* * TD Binaural Object renderer *----------------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_td_binaural_open_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Word16 * SrcInd, /*Temporarily used to store the updated value of SrcInd*/ + Word16 *num_src, + Word16 *directivity_fx +); +#endif // IVAS_FLOAT_FIXED ivas_error ivas_td_binaural_open( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index aa2c4752c..206d43755 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -39,6 +39,7 @@ #include "wmc_auto.h" #ifdef IVAS_FLOAT_FIXED #include "ivas_prot_fx.h" +#include "prot_fx2.h" #endif // IVAS_FLOAT_FIXED /*-------------------------------------------------------------------------* @@ -196,10 +197,91 @@ static ivas_error ivas_ism_bitrate_switching_dec( /* Open the TD Binaural renderer */ if ( st_ivas->hHrtfTD == NULL || st_ivas->hBinRendererTd == NULL ) { +#ifdef IVAS_FLOAT_FIXED +#if 1 /*Cleanup changes: float to fixed */ + Word16 directivity_fx[IVAS_MAX_NUM_OBJECTS * 3]; + Word16 SrcInd[MAX_NUM_TDREND_CHANNELS]; + Word16 num_src; + FOR( Word16 i = 0; i < 4; i++ ) + { + directivity_fx[i * 3] = floatToFixed( st_ivas->hRenderConfig->directivity[i * 3], 6 ); + directivity_fx[i * 3 + 1] = floatToFixed( st_ivas->hRenderConfig->directivity[i * 3 + 1], 6 ); + directivity_fx[i * 3 + 2] = floatToFixed( st_ivas->hRenderConfig->directivity[i * 3 + 2], 15 ); + } +#endif + IF ( ( error = ivas_td_binaural_open_fx( st_ivas , SrcInd,&num_src, directivity_fx) ) != IVAS_ERR_OK ) + { + return error; + } +#if 1 // Cleanup changes for ivas_td_binaural_open: fixed to float + st_ivas->hBinRendererTd->Gain = 1.0f; /*1.0f Q15*/ + fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Pos_fx, st_ivas->hBinRendererTd->Listener_p->Pos, 15, 3 ); + fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Vel_fx, st_ivas->hBinRendererTd->Listener_p->Vel, 15, 3 ); + fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Front_fx, st_ivas->hBinRendererTd->Listener_p->Front, 15, 3 ); + fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Up_fx, st_ivas->hBinRendererTd->Listener_p->Up, 15, 3 ); + fixedToFloat_arr( st_ivas->hBinRendererTd->Listener_p->Right_fx, st_ivas->hBinRendererTd->Listener_p->Right, 15, 3 ); + TDREND_DirAtten_t *DirAtten_p = st_ivas->hBinRendererTd->DirAtten_p; + DirAtten_p->ConeInnerAngle = fixedToFloat( DirAtten_p->ConeInnerAngle_fx, 6 ); + DirAtten_p->ConeOuterAngle = fixedToFloat( DirAtten_p->ConeOuterAngle_fx, 6 ); + DirAtten_p->ConeOuterGain = fixedToFloat( DirAtten_p->ConeOuterGain_fx, 15 ); + Word16 nchan_rend = num_src; + IF( EQ_16( st_ivas->ivas_format, MC_FORMAT ) && NE_16( st_ivas->transport_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) ) + { + nchan_rend--; /* Skip LFE channel -- added to the others */ + } + FOR( Word16 nS = 0; nS < nchan_rend; nS++ ) + { + TDREND_SRC_t *Src_p = st_ivas->hBinRendererTd->Sources[SrcInd[nS]]; + IF( Src_p->SrcSpatial_p != NULL ) + { + Src_p->SrcSpatial_p->DirAtten.ConeInnerAngle = 360.0f; + Src_p->SrcSpatial_p->DirAtten.ConeOuterAngle = 360.0f; + Src_p->SrcSpatial_p->DirAtten.ConeOuterGain = 1.0f; + Src_p->SrcSpatial_p->DistAtten.RefDist = 1.0f; + Src_p->SrcSpatial_p->DistAtten.MaxDist = 15.75f; /* Maximum radius (2^ISM_RADIUS_NBITS-1)*0.25 */ + Src_p->SrcSpatial_p->DistAtten.RollOffFactor = 1.0f; + FOR( Word16 nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ ) + { + fixedToFloat_arr( Src_p->SrcSpatial_p->Pos_p_fx + nC * 3, Src_p->SrcSpatial_p->Pos_p + nC * 3, 15, 3 ); + fixedToFloat_arr( Src_p->SrcSpatial_p->Front_p_fx + nC * 3, Src_p->SrcSpatial_p->Front_p + nC * 3, 15, 3 ); + } + } + FOR( Word16 nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ ) + { + Src_p->SrcRend_p->SrcGainMin_p[nC] = 0.0f; + Src_p->SrcRend_p->SrcGain_p[nC] = 1.0f; + Src_p->SrcRend_p->SrcGainMax_p[nC] = 1.0f; + } + FOR( Word16 nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ ) + { + Src_p->SrcRend_p->DirGain_p[nC] = 1.0f; + Src_p->SrcRend_p->DistGain_p[nC] = 1.0f; + } + set_f( Src_p->mem_itd, 0.0f, ITD_MEM_LEN ); + set_f( Src_p->mem_hrf_left, 0.0f, SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 ); + set_f( Src_p->mem_hrf_right, 0.0f, SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 ); + set_f( Src_p->hrf_left_prev, 0.0f, SFX_SPAT_BIN_MAX_FILTER_LENGTH ); + set_f( Src_p->hrf_right_prev, 0.0f, SFX_SPAT_BIN_MAX_FILTER_LENGTH ); + Src_p->hrf_left_prev[0] = 1; + Src_p->hrf_right_prev[0] = 1; + Src_p->azim_prev = 0.0f; + Src_p->elev_prev = 0.0f; + Src_p->Gain = 1.0f; + Src_p->prevGain = 1.0f; + TDREND_SRC_SPATIAL_t *SrcSpatial_p = st_ivas->hBinRendererTd->Sources[nS]->SrcSpatial_p; + fixedToFloat_arr( SrcSpatial_p->Pos_p_fx, SrcSpatial_p->Pos_p, 15, 3 ); + fixedToFloat_arr( SrcSpatial_p->Front_p_fx, SrcSpatial_p->Front_p, 15, 3 ); + SrcSpatial_p->DirAtten.ConeInnerAngle = fixedToFloat( SrcSpatial_p->DirAtten.ConeInnerAngle_fx, 6 ); + SrcSpatial_p->DirAtten.ConeOuterAngle = fixedToFloat( SrcSpatial_p->DirAtten.ConeOuterAngle_fx, 6 ); + SrcSpatial_p->DirAtten.ConeOuterGain = fixedToFloat( SrcSpatial_p->DirAtten.ConeOuterGain_fx, 15 ); + } +#endif +#else if ( ( error = ivas_td_binaural_open( st_ivas ) ) != IVAS_ERR_OK ) { return error; } +#endif // IVAS_FLOAT_FIXED if ( st_ivas->hIntSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { if ( ( error = ivas_reverb_open( &st_ivas->hReverb, st_ivas->hDecoderConfig->output_config, NULL, st_ivas->hBinRendererTd->HrFiltSet_p->lr_energy_and_iac, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index 5f5f9c75d..b1b31a915 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -51,6 +51,24 @@ * * Open and initialize TD Object binaural renderer *---------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_td_binaural_open_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Word16 * SrcInd, /*Temporarily used to store the updated value of SrcInd*/ + Word16 *num_src, + Word16 *directivity_fx +) +{ + *num_src = st_ivas->nchan_transport; + move16(); + IF ( EQ_16( st_ivas->ism_mode , ISM_MASA_MODE_DISC ) || EQ_16( st_ivas->ism_mode , ISM_SBA_MODE_DISC ) ) + { + *num_src = st_ivas->nchan_ism; + move16(); + } + return ivas_td_binaural_open_unwrap_fx( &st_ivas->hHrtfTD, st_ivas->hDecoderConfig->output_Fs, *num_src, st_ivas->ivas_format, st_ivas->transport_config, directivity_fx, st_ivas->hTransSetup, &st_ivas->hBinRendererTd, &st_ivas->binaural_latency_ns, SrcInd ); +} +#endif // IVAS_FLOAT_FIXED ivas_error ivas_td_binaural_open( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index a981ac2a6..07ee94829 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -43,6 +43,7 @@ #include "prot_fx1.h" #include "prot_fx2.h" #include "debug.h" +#include "ivas_rom_com_fx.h" #define float_to_fix( n, factor ) ( round( n * ( 1 << factor ) ) ) #define fix_to_float( n, factor ) ( (float) n / ( 1 << factor ) ) #endif @@ -55,6 +56,12 @@ static void TDREND_Clear_Update_flags( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRe static void angles_to_vec( const float radius, const float azimuth, const float elevation, float *vec ); +static void angles_to_vec_fx( + const Word16 radius, /* i : radius */ + const Word32 azimuth, /* i : Azimuth angle */ + const Word32 elevation, /* i : Elevation angle */ + Word16 *vec /* o : Pos/Dir vector */ +); /*---------------------------------------------------------------------* * ivas_td_binaural_open_unwrap() @@ -62,6 +69,203 @@ static void angles_to_vec( const float radius, const float azimuth, const float * Call TD open/init function without st_ivas *---------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_td_binaural_open_unwrap_fx( + TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HR filter model (from file or NULL) */ + const Word32 output_Fs, /* i : Output sampling rate */ + const Word16 nchan_transport, /* i : Number of channels */ + const IVAS_FORMAT ivas_format, /* i : IVAS format (ISM/MC) */ + const AUDIO_CONFIG transport_config, /* i : Transport configuration */ + const Word16 *directivity, /* i : Directivity pattern (used for ISM) */ + const IVAS_OUTPUT_SETUP hTransSetup, /* i : Loudspeaker layout */ + BINAURAL_TD_OBJECT_RENDERER_HANDLE *hBinRendererTd, /* o : TD renderer handle */ + Word32 *binaural_latency_ns, /* i : Binauralization delay */ + Word16 *SrcInd +) +{ + BINAURAL_TD_OBJECT_RENDERER_HANDLE pBinRendTd; + TDREND_PosType_t PosType; + Word16 nS; + const Word32 *ls_azimuth_fx, *ls_elevation_fx; + Word16 Pos_fx[3]; + Word16 Dir_fx[3]; + TDREND_DirAtten_t *DirAtten_p; + Word16 nchan_rend; + ivas_error error; + + error = IVAS_ERR_OK; + + IF( ( pBinRendTd = malloc( sizeof( BINAURAL_TD_OBJECT_RENDERER ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD renderer\n" ) ); + } + IF( ( pBinRendTd->TdRend_MixSpatSpec_p = malloc( sizeof( TDREND_MixSpatSpec_t ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD renderer\n" ) ); + } + IF( ( pBinRendTd->DirAtten_p = malloc( sizeof( TDREND_DirAtten_t ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD renderer\n" ) ); + } + IF( ( pBinRendTd->Listener_p = malloc( sizeof( TDREND_MIX_Listener_t ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD renderer\n" ) ); + } + + pBinRendTd->NumOfSrcs = 0; + pBinRendTd->MaxSrcInd = -1; + + move16(); + move16(); + /* Mixer spatial setup */ + pBinRendTd->TdRend_MixSpatSpec_p->UseCommonDistAttenModel = TRUE; + pBinRendTd->TdRend_MixSpatSpec_p->DistAttenModel = 0; /* 0=Turned off, else use TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED */ + move16(); + + IF( ( error = TDREND_MIX_Init_fx( pBinRendTd, hHrtfTD, pBinRendTd->TdRend_MixSpatSpec_p, output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Set the attenuation (or can set MixSpatSpec.DistAttenModel above) */ + IF( ( error = TDREND_MIX_SetDistAttenModel( pBinRendTd, TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Add sources to module and mixer, headphones */ + PosType = TDREND_POSTYPE_ABSOLUTE; /* or TDREND_POSTYPE_RELATIVE_TO_LISTENER */ + + nchan_rend = nchan_transport; + move16(); + IF( EQ_16( ivas_format, MC_FORMAT ) && NE_16( transport_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) ) + { + nchan_rend--; /* Skip LFE channel -- added to the others */ + } + + FOR( nS = 0; nS < nchan_rend; nS++ ) + { + IF( ( error = TDREND_MIX_AddSrc_fx( pBinRendTd, &SrcInd[nS], PosType ) ) != IVAS_ERR_OK ) + { + return error; + } + } + IF( EQ_16( ivas_format, MC_FORMAT ) ) + { + SWITCH( transport_config ) + { + case IVAS_AUDIO_CONFIG_5_1: + ls_azimuth_fx = ls_azimuth_CICP6_fx; + ls_elevation_fx = ls_elevation_CICP6_fx; + BREAK; + case IVAS_AUDIO_CONFIG_7_1: + ls_azimuth_fx = ls_azimuth_CICP12_fx; + ls_elevation_fx = ls_elevation_CICP12_fx; + BREAK; + case IVAS_AUDIO_CONFIG_5_1_2: + ls_azimuth_fx = ls_azimuth_CICP14_fx; + ls_elevation_fx = ls_elevation_CICP14_fx; + BREAK; + case IVAS_AUDIO_CONFIG_5_1_4: + ls_azimuth_fx = ls_azimuth_CICP16_fx; + ls_elevation_fx = ls_elevation_CICP16_fx; + BREAK; + case IVAS_AUDIO_CONFIG_7_1_4: + ls_azimuth_fx = ls_azimuth_CICP19_fx; + ls_elevation_fx = ls_elevation_CICP19_fx; + BREAK; + case IVAS_AUDIO_CONFIG_LS_CUSTOM: + ls_azimuth_fx = hTransSetup.ls_azimuth_fx; + ls_elevation_fx = hTransSetup.ls_elevation_fx; + BREAK; + default: + ls_azimuth_fx = NULL; + ls_elevation_fx = NULL; + } + + DirAtten_p = pBinRendTd->DirAtten_p; + + FOR( nS = 0; nS < nchan_rend; nS++ ) + { + /* Set source positions according to loudspeaker layout */ + angles_to_vec_fx( 32767, ls_azimuth_fx[nS], ls_elevation_fx[nS], Pos_fx ); + + Dir_fx[0] = 32767; + move16(); + Dir_fx[1] = 0; + move16(); + Dir_fx[2] = 0; + move16(); + /* Source directivity info */ + DirAtten_p->ConeInnerAngle_fx = 23040; + move16(); + DirAtten_p->ConeOuterAngle_fx = 23040; + move16(); + DirAtten_p->ConeOuterGain_fx = 32767; + move16(); + + TDREND_SRC_SPATIAL_t *SrcSpatial_p = pBinRendTd->Sources[nS]->SrcSpatial_p; + // floatToFixed_arr( SrcSpatial_p->Pos_p, SrcSpatial_p->Pos_p_fx, 15, 3 ); + IF( ( error = TDREND_MIX_SRC_SetPos_fx( pBinRendTd, nS, Pos_fx ) ) != IVAS_ERR_OK ) + { + return error; + } + IF( ( error = TDREND_MIX_SRC_SetDir_fx( pBinRendTd, nS, Dir_fx ) ) != IVAS_ERR_OK ) + { + return error; + } + IF( ( error = TDREND_MIX_SRC_SetPlayState( pBinRendTd, nS, TDREND_PLAYSTATUS_PLAYING ) ) != IVAS_ERR_OK ) + { + return error; + } + /*TDREND_SRC_SPATIAL_t **/ SrcSpatial_p = pBinRendTd->Sources[nS]->SrcSpatial_p; + IF( ( error = TDREND_MIX_SRC_SetDirAtten_fx( pBinRendTd, nS, DirAtten_p ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + + IF( EQ_16( ivas_format, ISM_FORMAT ) || EQ_16( ivas_format, MASA_ISM_FORMAT ) || EQ_16( ivas_format, SBA_ISM_FORMAT ) ) + { + DirAtten_p = pBinRendTd->DirAtten_p; + + FOR( nS = 0; nS < nchan_rend; nS++ ) + { + IF( NULL == directivity ) + { + DirAtten_p->ConeInnerAngle_fx = 23040; /* Front cone */ + DirAtten_p->ConeOuterAngle_fx = 23040; /* Back cone */ + DirAtten_p->ConeOuterGain_fx = 32767; /* Back attenuation */ + } + ELSE + { + DirAtten_p->ConeInnerAngle_fx = directivity[nS * 3]; + DirAtten_p->ConeOuterAngle_fx = directivity[nS * 3 + 1]; + DirAtten_p->ConeOuterGain_fx = directivity[nS * 3 + 2]; + } + move16(); + move16(); + move16(); + IF( ( error = TDREND_MIX_SRC_SetDirAtten_fx( pBinRendTd, nS, DirAtten_p ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + + *hBinRendererTd = pBinRendTd; + + IF( NE_16( ivas_format, MASA_ISM_FORMAT ) && NE_16( ivas_format, SBA_ISM_FORMAT ) ) + { + // To be removed later + ( *hBinRendererTd )->HrFiltSet_p->latency_s_fx = floatToFixed( ( *hBinRendererTd )->HrFiltSet_p->latency_s, 31 ); + *binaural_latency_ns = Mult_32_32( ( *hBinRendererTd )->HrFiltSet_p->latency_s_fx, 1000000000 ); + } + + return error; +} +#endif // IVAS_FLOAT_FIXED ivas_error ivas_td_binaural_open_unwrap( TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HR filter model (from file or NULL) */ const int32_t output_Fs, /* i : Output sampling rate */ @@ -817,6 +1021,23 @@ ivas_error ivas_td_binaural_renderer_ext( * * Convert azimuth and elevation angles to position/orientation vector *---------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void angles_to_vec_fx( + const Word16 radius, /* i : radius */ + const Word32 azimuth, /* i : Azimuth angle */ + const Word32 elevation, /* i : Elevation angle */ + Word16 *vec /* o : Pos/Dir vector */ +) +{ + Word16 elevation_fx, azimuth_fx; + elevation_fx =(Word16)L_shr( Mult_32_16( elevation, 91 ), 22 ); + azimuth_fx = (Word16)L_shr( Mult_32_16( azimuth, 91 ), 22 ); + vec[0] = mult( radius, mult( getCosWord16R2( imult1616( elevation_fx, 91 ) ), getCosWord16R2( imult1616( azimuth_fx, 91 ) ) ) ); + vec[1] = mult( radius, mult( getCosWord16R2( imult1616( elevation_fx, 91 ) ), getSineWord16R2( imult1616( azimuth_fx, 91 ) ) ) ); + vec[2] = mult( radius, getSineWord16R2( imult1616( elevation_fx, 91 ) ) ); + return; +} +#endif // IVAS_FLOAT_FIXED static void angles_to_vec( const float radius, /* i : radius */ diff --git a/lib_rend/ivas_objectRenderer_mix.c b/lib_rend/ivas_objectRenderer_mix.c index 20c0b152a..5fc52e817 100644 --- a/lib_rend/ivas_objectRenderer_mix.c +++ b/lib_rend/ivas_objectRenderer_mix.c @@ -39,6 +39,9 @@ #include "wmc_auto.h" #include "ivas_rom_rend.h" +#ifdef IVAS_FLOAT_FIXED +#include "prot_fx2.h" +#endif // IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* * Local constants @@ -55,6 +58,7 @@ *-------------------------------------------------------------------------*/ static ivas_error DefaultBSplineModel( TDREND_HRFILT_FiltSet_t *HrFiltSet_p, const Word32 output_Fs ); +static ivas_error DefaultBSplineModel_fx( TDREND_HRFILT_FiltSet_t *HrFiltSet_p, const Word32 output_Fs ); /*-------------------------------------------------------------------* @@ -186,6 +190,61 @@ void TDREND_MIX_Dealloc( * * Initializes the mixer and sets HRTF --------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error TDREND_MIX_Init_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HRTF data (initialized in case of NULL) */ + const TDREND_MixSpatSpec_t *MixSpatSpec_p, /* i : Mixer spatial specification */ + const Word32 output_Fs /* i : Output sampling rate */ +) +{ + ivas_error error; + hBinRendererTd->Gain_fx = 32767;/*1.0f Q15*/ + move16(); + /* Init source list */ + /* Spatial settings */ + IF ( MixSpatSpec_p != NULL ) + { + hBinRendererTd->UseCommonDistAttenModel = MixSpatSpec_p->UseCommonDistAttenModel; + hBinRendererTd->DistAttenModel = MixSpatSpec_p->DistAttenModel; + } + ELSE + { + hBinRendererTd->UseCommonDistAttenModel = TRUE; + hBinRendererTd->DistAttenModel = 0x0000; /* Distance attenuation not activated; */ + } + move16(); + /* Init virtual and rendering listeners for spatial mixers */ + TDREND_SPATIAL_VecInit_fx( hBinRendererTd->Listener_p->Pos_fx, 0, 0, 0 ); + TDREND_SPATIAL_VecInit_fx( hBinRendererTd->Listener_p->Vel_fx, 0, 0, 0 ); + TDREND_SPATIAL_VecInit_fx( hBinRendererTd->Listener_p->Front_fx, 0, 0, -32767 );/*Q15*/ + TDREND_SPATIAL_VecInit_fx( hBinRendererTd->Listener_p->Up_fx, 0, 32767, 0 );/*Q15*/ + TDREND_SPATIAL_VecInit_fx( hBinRendererTd->Listener_p->Right_fx, 32767, 0, 0 );/*Q15*/ + /* Init HR filter set */ + IF ( *hHrtfTD == NULL ) + { + IF ( ( hBinRendererTd->HrFiltSet_p = (TDREND_HRFILT_FiltSet_t *) malloc( sizeof( TDREND_HRFILT_FiltSet_t ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) ); + } + + IF ( ( error = DefaultBSplineModel_fx( hBinRendererTd->HrFiltSet_p, output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + *hHrtfTD = hBinRendererTd->HrFiltSet_p; + } + ELSE + { + hBinRendererTd->HrFiltSet_p = *hHrtfTD; + } + IF ( NE_32(hBinRendererTd->HrFiltSet_p->SampleRate , output_Fs) ) + { + return ( IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "The sampling rate for the HR filter set does not match the output sampling rate.\n" ) ); + } + return IVAS_ERR_OK; +} +#endif // IVAS_FLOAT_FIXED ivas_error TDREND_MIX_Init( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ @@ -253,6 +312,33 @@ ivas_error TDREND_MIX_Init( * Set the distance attenuation model of the mixer --------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error TDREND_MIX_SetDistAttenModel( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const TDREND_DistAttenModel_t DistAttenModel /* i : Distance attenuation model */ +) +{ + /* Value validation */ + IF ( LT_16( DistAttenModel , TDREND_DIST_ATTEN_MODEL_INV_DIST ) || GT_16( DistAttenModel , TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED ) ) + { + return ( IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid distance attenuation model!\n" ) ); + } + ELSE + { + /* Set the common distance attenuation model */ + hBinRendererTd->DistAttenModel = DistAttenModel; + + /* If using common distance attenuation model, set it. */ + IF ( hBinRendererTd->UseCommonDistAttenModel ) + { + hBinRendererTd->DistAttenEnabled = TRUE; + move16(); + hBinRendererTd->DistAttenModel = DistAttenModel; + } + } + return IVAS_ERR_OK; +} +#else ivas_error TDREND_MIX_SetDistAttenModel( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const TDREND_DistAttenModel_t DistAttenModel /* i : Distance attenuation model */ @@ -279,6 +365,7 @@ ivas_error TDREND_MIX_SetDistAttenModel( return IVAS_ERR_OK; } +#endif // IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* @@ -286,6 +373,58 @@ ivas_error TDREND_MIX_SetDistAttenModel( * * Adds the specified input source unit to the specified mixer unit. --------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error TDREND_MIX_AddSrc_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + Word16 *SrcInd, /* o : Source index */ + const TDREND_PosType_t PosType /* i : Position type (absolute/relative) */ +) +{ + TDREND_SRC_t *Src_p; + ivas_error error; + + error = IVAS_ERR_OK; + + /* Get unique source index */ + *SrcInd = add(hBinRendererTd->MaxSrcInd , 1); + hBinRendererTd->MaxSrcInd++; + hBinRendererTd->NumOfSrcs++; + + IF ( GT_16(hBinRendererTd->NumOfSrcs , MAX_NUM_TDREND_CHANNELS) ) + { + return ( IVAS_ERROR( IVAS_ERR_INTERNAL, "Maximum number of sources exceeded!\n" ) ); + } + ELSE + { + IF ( LT_16( PosType , TDREND_POSTYPE_ABSOLUTE ) || GT_16( PosType , TDREND_POSTYPE_NON_DIEGETIC ) ) + { + return ( IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid position type!\n" ) ); + } + ELSE + { + /* Alloc and init a complete source: signal+spatial+rend components */ + IF ( ( error = TDREND_SRC_Alloc( &Src_p ) ) != IVAS_ERR_OK ) + { + return error; + } + + TDREND_SRC_Init_fx( Src_p, PosType ); + + /* Special OpenAL initialization due to a common distance attenuation model */ + IF ( NE_16(hBinRendererTd->DistAttenModel , 0) ) + { + Src_p->SrcSpatial_p->DistAttenEnabled = TRUE; + move16(); + Src_p->SrcSpatial_p->DistAtten.DistAttenModel = hBinRendererTd->DistAttenModel; + } + /* Add source to mixer */ + hBinRendererTd->Sources[*SrcInd] = Src_p; + } + } + + return error; +} +#endif // IVAS_FLOAT_FIXED ivas_error TDREND_MIX_AddSrc( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ @@ -345,7 +484,7 @@ ivas_error TDREND_MIX_AddSrc( --------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED -static ivas_error BSplineModelEvalAlloc( +static ivas_error BSplineModelEvalAlloc_fx( ModelParams_t *model, /* i : Model parameters */ ModelEval_t *modelEval /* i/o: Model evaluation structure */ ) @@ -371,7 +510,7 @@ static ivas_error BSplineModelEvalAlloc( /*---------------------------------------------ends-here*/ return IVAS_ERR_OK; } -#else +#endif static ivas_error BSplineModelEvalAlloc( ModelParams_t *model, /* i : Model parameters */ ModelEval_t *modelEval /* i/o: Model evaluation structure */ @@ -389,7 +528,6 @@ static ivas_error BSplineModelEvalAlloc( return IVAS_ERR_OK; } -#endif // IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* @@ -399,7 +537,7 @@ static ivas_error BSplineModelEvalAlloc( --------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED -static ivas_error DefaultBSplineModel( +static ivas_error DefaultBSplineModel_fx( TDREND_HRFILT_FiltSet_t *HrFiltSet_p, /* o : Loaded HR filter set */ const Word32 output_Fs /* i : Output sampling rate */ ) @@ -448,23 +586,39 @@ static ivas_error DefaultBSplineModel( /* Set ROM flag for correct deallocation */ model->modelROM = TRUE; + move16(); /* int16_t parameters */ model->UseItdModel = 1; + move16(); model->SplineDegree = 4; + move16(); model->elevDim2 = 17; + move16(); model->elevDim3 = 15; + move16(); model->AlphaN = 470; + move16(); model->num_unique_azim_splines = 1; + move16(); model->elevSegSamples = 4; + move16(); model->elevBsLen[0] = 5; + move16(); model->elevBsLen[1] = 9; + move16(); model->elevBsLen[2] = 13; + move16(); model->elevBsLen[3] = 9; + move16(); model->elevBsStart[0] = 0; + move16(); model->elevBsStart[1] = 5; + move16(); model->elevBsStart[2] = 14; + move16(); model->elevBsStart[3] = 27; + move16(); model->azimDim2 = defaultHRIR_rom_azimDim2; model->azimDim3 = defaultHRIR_rom_azimDim3; @@ -524,6 +678,10 @@ static ivas_error DefaultBSplineModel( model->azimKSeq_fx[model->elevDim3 - 1][0] = 0; model->azimKSeq_fx[0][1] = 360; model->azimKSeq_fx[model->elevDim3 - 1][1] = 360; + move32(); + move32(); + move32(); + move32(); FOR ( i = 1; i < model->elevDim3 - 1; i++ ) { @@ -565,9 +723,11 @@ static ivas_error DefaultBSplineModel( model->EL_fx = defaultHRIR_rom_EL48; model->ER_fx = defaultHRIR_rom_ER48; model->K = 128; + move16(); IF( HrFiltSet_p->ModelParams.UseItdModel ) { modelITD->resamp_factor_fx = 32767;/*Q-15*/ + move16(); } BREAK; case 32000: @@ -586,9 +746,11 @@ static ivas_error DefaultBSplineModel( model->EL_fx = defaultHRIR_rom_EL32; model->ER_fx = defaultHRIR_rom_ER32; model->K = 86; + move16(); IF( HrFiltSet_p->ModelParams.UseItdModel ) { modelITD->resamp_factor_fx = RESAMPLE_FACTOR_32_48_FX; + move16(); } BREAK; case 16000: @@ -607,9 +769,11 @@ static ivas_error DefaultBSplineModel( model->EL_fx = defaultHRIR_rom_EL16; model->ER_fx = defaultHRIR_rom_ER16; model->K = 43; + move16(); IF( HrFiltSet_p->ModelParams.UseItdModel ) { modelITD->resamp_factor_fx = RESAMPLE_FACTOR_16_48_FX; + move16(); } BREAK; default: @@ -617,34 +781,57 @@ static ivas_error DefaultBSplineModel( } modelITD->N = 4; + move16(); modelITD->elevDim2 = 20; + move16(); modelITD->elevDim3 = 18; + move16(); modelITD->azimDim2 = 41; + move16(); modelITD->azimDim3 = 41; + move16(); modelITD->elevSegSamples = 3; + move16(); modelITD->elevBsLen[0] = 4; + move16(); modelITD->elevBsLen[1] = 7; + move16(); modelITD->elevBsLen[2] = 10; + move16(); modelITD->elevBsLen[3] = 7; + move16(); modelITD->elevBsStart[0] = 0; + move16(); modelITD->elevBsStart[1] = 4; + move16(); modelITD->elevBsStart[2] = 11; + move16(); modelITD->elevBsStart[3] = 21; + move16(); #if 1/*To be removed later : floating point pointer initialization*/ modelITD->elevKSeq = defaultHRIR_rom_ITD_elevKSeq; #endif modelITD->elevKSeq_fx = defaultHRIR_rom_ITD_elevKSeq_fx; modelITD->azimBsLen[0] = 11; + move16(); modelITD->azimBsLen[1] = 21; + move16(); modelITD->azimBsLen[2] = 31; + move16(); modelITD->azimBsLen[3] = 21; + move16(); modelITD->azimBsStart[0] = 0; + move16(); modelITD->azimBsStart[1] = 11; + move16(); modelITD->azimBsStart[2] = 32; + move16(); modelITD->azimBsStart[3] = 63; + move16(); modelITD->azimSegSamples = 10; + move16(); #if 1/*To be removed later : floating point pointer initialization*/ modelITD->azimKSeq = defaultHRIR_rom_ITD_azimKSeq; modelITD->W = (const float *) defaultHRIR_rom_ITD_W; @@ -660,17 +847,20 @@ static ivas_error DefaultBSplineModel( HrFiltSet_p->latency_s = defaultHRIR_rom_latency_s; #endif HrFiltSet_p->latency_s_fx = defaultHRIR_rom_latency_s_fx; + move32(); HrFiltSet_p->SampleRate = output_Fs; + move32(); HrFiltSet_p->FiltLength = HrFiltSet_p->ModelParams.K; + move16(); - IF ( ( error = BSplineModelEvalAlloc( &HrFiltSet_p->ModelParams, &HrFiltSet_p->ModelEval ) ) != IVAS_ERR_OK ) + IF ( ( error = BSplineModelEvalAlloc_fx( &HrFiltSet_p->ModelParams, &HrFiltSet_p->ModelEval ) ) != IVAS_ERR_OK ) { return error; } return IVAS_ERR_OK; } -#else +#endif static ivas_error DefaultBSplineModel( TDREND_HRFILT_FiltSet_t *HrFiltSet_p, /* o : Loaded HR filter set */ const int32_t output_Fs /* i : Output sampling rate */ @@ -855,4 +1045,3 @@ static ivas_error DefaultBSplineModel( return IVAS_ERR_OK; } -#endif // IVAS_FLOAT_FIXED diff --git a/lib_rend/ivas_objectRenderer_sources.c b/lib_rend/ivas_objectRenderer_sources.c index 5d948cab8..997a5f822 100644 --- a/lib_rend/ivas_objectRenderer_sources.c +++ b/lib_rend/ivas_objectRenderer_sources.c @@ -36,6 +36,9 @@ #include "prot.h" #include "ivas_prot_rend.h" #include "wmc_auto.h" +#ifdef IVAS_FLOAT_FIXED +#include "prot_fx2.h" +#endif // IVAS_FLOAT_FIXED /*---------------------------------------------------------------------* @@ -45,8 +48,10 @@ static void TDREND_SRC_SPATIAL_Dealloc( TDREND_SRC_SPATIAL_t *SrcSpatial_p ); static void TDREND_SRC_SPATIAL_Init( TDREND_SRC_SPATIAL_t *SrcSpatial_p, const TDREND_PosType_t PosType ); +static void TDREND_SRC_SPATIAL_Init_fx( TDREND_SRC_SPATIAL_t *SrcSpatial_p, const TDREND_PosType_t PosType ); static void TDREND_SRC_SPATIAL_SetDirAtten( TDREND_SRC_SPATIAL_t *SrcSpatial_p, const TDREND_DirAtten_t *DirAtten_p ); +static void TDREND_SRC_SPATIAL_SetDirAtten_fx( TDREND_SRC_SPATIAL_t *SrcSpatial_p, const TDREND_DirAtten_t *DirAtten_p ); static float TDREND_SRC_SPATIAL_GetDirGain( const TDREND_DirAtten_t *DirAtten_p, const float *Front_p, const float *RelPos_p ); @@ -55,6 +60,7 @@ static float TDREND_SRC_SPATIAL_GetDistGain( const TDREND_DistAtten_t *DistAtten static ivas_error TDREND_SRC_REND_Alloc( TDREND_SRC_REND_t **SrcRend_pp ); static void TDREND_SRC_REND_Init( TDREND_SRC_REND_t *SrcRend_p ); +static void TDREND_SRC_REND_Init_fx( TDREND_SRC_REND_t *SrcRend_p ); /*-------------------------------------------------------------------* @@ -63,6 +69,34 @@ static void TDREND_SRC_REND_Init( TDREND_SRC_REND_t *SrcRend_p ); * Set source position --------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error TDREND_MIX_SRC_SetPos_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const Word16 SrcInd, /* i : Source index */ + const Word16 *Vec_p /* i : Position vector */ +) +{ + TDREND_SRC_SPATIAL_t *SrcSpatial_p; + + IF ( GT_16(SrcInd , hBinRendererTd->MaxSrcInd) ) + { + return ( IVAS_ERROR( IVAS_ERR_INVALID_INDEX, "Index exceeds max index!\n" ) ); + } + ELSE + { + SrcSpatial_p = hBinRendererTd->Sources[SrcInd]->SrcSpatial_p; + + IF ( NE_16(SrcSpatial_p->Pos_p_fx[0] , Vec_p[0]) || NE_16(SrcSpatial_p->Pos_p_fx[1] , Vec_p[1]) || NE_16(SrcSpatial_p->Pos_p_fx[2] , Vec_p[2]) ) + { + Copy( Vec_p, SrcSpatial_p->Pos_p_fx, 3 ); + SrcSpatial_p->Updated = TRUE; + move16(); + } + } + + return IVAS_ERR_OK; +} +#endif ivas_error TDREND_MIX_SRC_SetPos( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ @@ -95,6 +129,33 @@ ivas_error TDREND_MIX_SRC_SetPos( * * Set source direction --------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error TDREND_MIX_SRC_SetDir_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const Word16 SrcInd, /* i : Source index */ + const Word16 *Vec_p /* i : Direction vector */ +) +{ + TDREND_SRC_SPATIAL_t *SrcSpatial_p; + /* Value verification */ + IF ( EQ_16( Vec_p[0] , 0 ) && EQ_16( Vec_p[1] , 0 ) && EQ_16( Vec_p[2] , 0 ) ) + { + return ( IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Zero direction vector. Command is ignored!\n" ) ); + } + IF ( GT_16(SrcInd , hBinRendererTd->MaxSrcInd) ) + { + return ( IVAS_ERROR( IVAS_ERR_INVALID_INDEX, "Index exceeds max index!\n" ) ); + } + ELSE + { + SrcSpatial_p = hBinRendererTd->Sources[SrcInd]->SrcSpatial_p; + TDREND_SPATIAL_VecNormalize_fx( Vec_p, SrcSpatial_p->Front_p_fx ); + SrcSpatial_p->Updated = TRUE; + move16(); + } + return IVAS_ERR_OK; +} +#endif // IVAS_FLOAT_FIXED ivas_error TDREND_MIX_SRC_SetDir( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ @@ -129,6 +190,27 @@ ivas_error TDREND_MIX_SRC_SetDir( * * Set directional attenuation for the mixer. --------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error TDREND_MIX_SRC_SetDirAtten_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const Word16 SrcInd, /* i : Source index */ + const TDREND_DirAtten_t *DirAtten_p /* i : Directional attenuation specifier */ +) +{ + TDREND_SRC_SPATIAL_t *SrcSpatial_p; + IF ( GT_16(SrcInd , hBinRendererTd->MaxSrcInd) ) + { + return ( IVAS_ERROR( IVAS_ERR_INVALID_INDEX, "Index exceeds max index\n" ) ); + } + ELSE + { + SrcSpatial_p = hBinRendererTd->Sources[SrcInd]->SrcSpatial_p; + TDREND_SRC_SPATIAL_SetDirAtten_fx( SrcSpatial_p, DirAtten_p ); + } + + return IVAS_ERR_OK; +} +#endif // IVAS_FLOAT_FIXED ivas_error TDREND_MIX_SRC_SetDirAtten( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ @@ -157,6 +239,24 @@ ivas_error TDREND_MIX_SRC_SetDirAtten( * Set play state for the source. --------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error TDREND_MIX_SRC_SetPlayState( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const Word16 SrcInd, /* i : Source index */ + const TDREND_PlayStatus_t PlayStatus /* i : Play state */ +) +{ + IF ( GT_16(SrcInd , hBinRendererTd->MaxSrcInd) ) + { + return ( IVAS_ERROR( IVAS_ERR_INVALID_INDEX, "Index exceeds max index\n" ) ); + } + ELSE + { + hBinRendererTd->Sources[SrcInd]->SrcRend_p->PlayStatus = PlayStatus; + } + return IVAS_ERR_OK; +} +#else // IVAS_FLOAT_FIXED ivas_error TDREND_MIX_SRC_SetPlayState( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ @@ -174,6 +274,7 @@ ivas_error TDREND_MIX_SRC_SetPlayState( return IVAS_ERR_OK; } +#endif // IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* * TDREND_SRC_REND_Alloc() @@ -190,7 +291,7 @@ static ivas_error TDREND_SRC_REND_Alloc( *SrcRend_pp = NULL; /* Allocate the TDREND_SRC_REND_t variable */ - if ( ( SrcRend_p = (TDREND_SRC_REND_t *) malloc( sizeof( TDREND_SRC_REND_t ) ) ) == NULL ) + IF ( ( SrcRend_p = (TDREND_SRC_REND_t *) malloc( sizeof( TDREND_SRC_REND_t ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "SrcRend_p allocation error\n" ) ); } @@ -206,6 +307,39 @@ static ivas_error TDREND_SRC_REND_Alloc( * * Initialize rendering aspects of source. --------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void TDREND_SRC_REND_Init_fx( + TDREND_SRC_REND_t *SrcRend_p /* i/o: Source object */ +) +{ + Word16 nC; + /* Internal state */ + SrcRend_p->InputAvailable = FALSE; + move16(); + SrcRend_p->PlayStatus = TDREND_PLAYSTATUS_PLAYING; + /* SrcGain */ + FOR( nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ ) + { + SrcRend_p->SrcGainMin_p_fx[nC] = 0;/*Assuming Q15*/ + move16(); + SrcRend_p->SrcGain_p_fx[nC] = 32767;/*Assuming Q15*/ + move16(); + SrcRend_p->SrcGainMax_p_fx[nC] = 32767;/*Assuming Q15*/ + move16(); + } + SrcRend_p->SrcGainUpdated = FALSE; + move16(); + /* Init directional and distance gains */ + FOR ( nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ ) + { + SrcRend_p->DirGain_p_fx[nC] = 32767;/*Assuming Q15*/ + move16(); + SrcRend_p->DistGain_p_fx[nC] = 32767;/*Assuming Q15*/ + move16(); + } + return; +} +#endif // IVAS_FLOAT_FIXED static void TDREND_SRC_REND_Init( TDREND_SRC_REND_t *SrcRend_p /* i/o: Source object */ @@ -383,7 +517,7 @@ static ivas_error TDREND_SRC_SPATIAL_Alloc( *SrcSpatial_pp = NULL; /* Allocate the TDREND_SRC_t variable */ - if ( ( SrcSpatial_p = (TDREND_SRC_SPATIAL_t *) malloc( sizeof( TDREND_SRC_SPATIAL_t ) ) ) == NULL ) + IF ( ( SrcSpatial_p = (TDREND_SRC_SPATIAL_t *) malloc( sizeof( TDREND_SRC_SPATIAL_t ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "TDREND_SRC_SPATIAL_t allocation error\n" ) ); } @@ -421,6 +555,54 @@ static void TDREND_SRC_SPATIAL_Dealloc( * * Initialize spatial properties of a source. --------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void TDREND_SRC_SPATIAL_Init_fx( + TDREND_SRC_SPATIAL_t *SrcSpatial_p, /* i/o: Source spatial parameters */ + const TDREND_PosType_t PosType /* i : Relative/absolute position type */ +) +{ + Word16 nC; + + /* Initialize variables */ + SrcSpatial_p->Updated = FALSE; + + move16(); + /* Source position, velocity and direction vectors */ + SrcSpatial_p->PosType = PosType; + FOR( nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ ) + { + /* Source position */ + TDREND_SPATIAL_VecInit_fx( SrcSpatial_p->Pos_p_fx + nC * 3, 0, 0, 0 );/*Q15*/ + + /* Source direction */ + TDREND_SPATIAL_VecInit_fx( SrcSpatial_p->Front_p_fx + nC * 3, 0, 0, 32767);/*Q15*/ + } + + + /* Source directional attenuation */ + SrcSpatial_p->DirAttenEnabled = FALSE; + move16(); + SrcSpatial_p->DirAtten.ConeInnerAngle_fx = 23040;/*Q6*/ + move16(); + SrcSpatial_p->DirAtten.ConeOuterAngle_fx = 23040;/*Q6*/ + move16(); + SrcSpatial_p->DirAtten.ConeOuterGain_fx = 16384;/*Q14*/ + move16(); + + /* Source distance attenuation */ + SrcSpatial_p->DistAttenEnabled = FALSE; + move16(); + SrcSpatial_p->DistAtten.DistAttenModel = TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED; + SrcSpatial_p->DistAtten.RefDist_fx = 16384;/*Q14*/ + move16(); + SrcSpatial_p->DistAtten.MaxDist_fx = 32256; /* Maximum radius (2^ISM_RADIUS_NBITS-1)*0.25 *//*Q11*/ + move16(); + SrcSpatial_p->DistAtten.RollOffFactor_fx = 16384;/*Q14*/ + move16(); + + return; +} +#endif static void TDREND_SRC_SPATIAL_Init( TDREND_SRC_SPATIAL_t *SrcSpatial_p, /* i/o: Source spatial parameters */ @@ -466,6 +648,24 @@ static void TDREND_SRC_SPATIAL_Init( * Sets the directional attenuation mode. --------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void TDREND_SRC_SPATIAL_SetDirAtten_fx( + TDREND_SRC_SPATIAL_t *SrcSpatial_p, /* i/o: Source spatial parameters */ + const TDREND_DirAtten_t *DirAtten_p /* i : Directionality specification */ +) +{ + /* Set directional attenuation */ + SrcSpatial_p->DirAttenEnabled = TRUE; + SrcSpatial_p->DirAtten.ConeInnerAngle_fx = DirAtten_p->ConeInnerAngle_fx; + SrcSpatial_p->DirAtten.ConeOuterAngle_fx = DirAtten_p->ConeOuterAngle_fx; + SrcSpatial_p->DirAtten.ConeOuterGain_fx = DirAtten_p->ConeOuterGain_fx; + move16(); + move16(); + move16(); + move16(); + return; +} +#endif static void TDREND_SRC_SPATIAL_SetDirAtten( TDREND_SRC_SPATIAL_t *SrcSpatial_p, /* i/o: Source spatial parameters */ const TDREND_DirAtten_t *DirAtten_p /* i : Directionality specification */ @@ -594,19 +794,19 @@ ivas_error TDREND_SRC_Alloc( *Src_pp = NULL; /* Allocate the TDREND_SRC_t variable */ - if ( ( Src_p = (TDREND_SRC_t *) malloc( sizeof( TDREND_SRC_t ) ) ) == NULL ) + IF ( ( Src_p = (TDREND_SRC_t *) malloc( sizeof( TDREND_SRC_t ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, " TDREND_SRC_Alloc: Allocation error\n" ) ); } Src_p->SrcSpatial_p = NULL; /* If source type is dynamic alloc the TDREND_SRC_SPATIAL_t variable */ - if ( ( error = TDREND_SRC_SPATIAL_Alloc( &Src_p->SrcSpatial_p ) ) != IVAS_ERR_OK ) + IF ( ( error = TDREND_SRC_SPATIAL_Alloc( &Src_p->SrcSpatial_p ) ) != IVAS_ERR_OK ) { return error; } - if ( ( error = TDREND_SRC_REND_Alloc( &Src_p->SrcRend_p ) ) != IVAS_ERR_OK ) + IF ( ( error = TDREND_SRC_REND_Alloc( &Src_p->SrcRend_p ) ) != IVAS_ERR_OK ) { return error; } @@ -651,6 +851,49 @@ void TDREND_SRC_Dealloc( * * Initializes a source. --------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void TDREND_SRC_Init_fx( + TDREND_SRC_t *Src_p, /* i/o: Source to initialize */ + const TDREND_PosType_t PosType /* i : Position type specifier */ +) +{ + /* Init the TDREND_SRC_Spatial_t variable */ + IF ( Src_p->SrcSpatial_p != NULL ) + { + TDREND_SRC_SPATIAL_Init_fx( Src_p->SrcSpatial_p, PosType ); + } + + /* Init the TDREND_SRC_REND_t variable */ + TDREND_SRC_REND_Init_fx( Src_p->SrcRend_p ); + + /* Reset memory buffers */ + Src_p->itd = 0; + move16(); + Src_p->previtd = 0; + move16(); + Src_p->filterlength = 1; /* Init to unit impulse of length 1 */ + move16(); + set16_fx( Src_p->mem_itd_fx, 0, ITD_MEM_LEN ); + set16_fx( Src_p->mem_hrf_left_fx, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 ); + set16_fx( Src_p->mem_hrf_right_fx, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 ); + + set16_fx( Src_p->hrf_left_prev_fx, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH ); + set16_fx( Src_p->hrf_right_prev_fx, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH ); + Src_p->hrf_left_prev_fx[0] = 32767; + move16(); + Src_p->hrf_right_prev_fx[0] = 32767; + move16(); + Src_p->azim_prev_fx = 0; + move16(); + Src_p->elev_prev_fx = 0; + move16(); + Src_p->Gain_fx = 32767; + move16(); + Src_p->prevGain_fx = 32767; + move16(); + return; +} +#endif // IVAS_FLOAT_FIXED void TDREND_SRC_Init( TDREND_SRC_t *Src_p, /* i/o: Source to initialize */ diff --git a/lib_rend/ivas_objectRenderer_vec.c b/lib_rend/ivas_objectRenderer_vec.c index 0abde0389..305a501c9 100644 --- a/lib_rend/ivas_objectRenderer_vec.c +++ b/lib_rend/ivas_objectRenderer_vec.c @@ -44,6 +44,23 @@ * Initialize 3-dim vector *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void TDREND_SPATIAL_VecInit_fx( + Word16 *Pos_p, /* o : Output vector */ + const Word16 PosX, /* i : X value */ + const Word16 PosY, /* i : Y value */ + const Word16 PosZ /* i : Z value */ +) +{ + Pos_p[0] = PosX; + Pos_p[1] = PosY; + Pos_p[2] = PosZ; + move16(); + move16(); + move16(); + return; +} +#endif // IVAS_FLOAT_FIXED void TDREND_SPATIAL_VecInit( float *Pos_p, /* o : Output vector */ const float PosX, /* i : X value */ @@ -79,6 +96,25 @@ float TDREND_SPATIAL_VecNorm( * * Normalize vector to unit norm *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void TDREND_SPATIAL_VecNormalize_fx( + const Word16 *Vec_p, /* i : Input vector */ + Word16 *VecNorm_p /* o : Output vector */ +) +{ + Word32 scaler; + scaler = L_shr(Isqrt( L_add( L_mult0( Vec_p[0], Vec_p[0] ), L_add( L_mult0( Vec_p[1], Vec_p[1] ), L_mult0( Vec_p[2], Vec_p[2] ) ) ) ),1);//15 bit output + IF( scaler > MAX16B ) + { + scaler = MAX16B;/*Handling the overflow*/ + move32(); + } + VecNorm_p[0] = mult((Word16)scaler , Vec_p[0]); + VecNorm_p[1] = mult((Word16)scaler , Vec_p[1]); + VecNorm_p[2] = mult((Word16)scaler , Vec_p[2]); + return; +} +#endif // IVAS_FLOAT_FIXED void TDREND_SPATIAL_VecNormalize( const float *Vec_p, /* i : Input vector */ diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index d9dec4a6a..6094a0919 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -726,6 +726,20 @@ ivas_error ivas_td_binaural_renderer_ext( const int16_t output_frame, /* i : output frame length */ float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */ ); +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_td_binaural_open_unwrap_fx( + TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HR filter model (from file or NULL) */ + const Word32 output_Fs, /* i : Output sampling rate */ + const Word16 nchan_transport, /* i : Number of channels */ + const IVAS_FORMAT ivas_format, /* i : IVAS format (ISM/MC) */ + const AUDIO_CONFIG transport_config, /* i : Transport configuration */ + const Word16 *directivity, /* i : Directivity pattern (used for ISM) */ + const IVAS_OUTPUT_SETUP hTransSetup, /* i : Loudspeaker layout */ + BINAURAL_TD_OBJECT_RENDERER_HANDLE *hBinRendererTd, /* o : TD renderer handle */ + Word32 *binaural_latency_ns, /* i : Binauralization delay */ + Word16 *SrcInd +); +#endif // IVAS_FLOAT_FIXED ivas_error ivas_td_binaural_open_unwrap( TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HR filter model (from file or NULL) */ @@ -805,17 +819,43 @@ ivas_error TDREND_REND_RenderSourceHRFilt( /* ----- Object renderer - sources ----- */ +#ifdef IVAS_FLOAT_FIXED +ivas_error TDREND_MIX_SRC_SetPos_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const Word16 SrcInd, /* i : Source index */ + const Word16 *Vec_p /* i : Position vector */ +); +#endif // IVAS_FLOAT_FIXED ivas_error TDREND_MIX_SRC_SetPos( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ const float *Vec_p /* i : Position vector */ ); +#ifdef IVAS_FLOAT_FIXED +ivas_error TDREND_MIX_SRC_SetDir_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const Word16 SrcInd, /* i : Source index */ + const Word16 *Vec_p /* i : Direction vector */ +); +#endif ivas_error TDREND_MIX_SRC_SetDir( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ const float *Vec_p /* i : Direction vector */ ); +#ifdef IVAS_FLOAT_FIXED +ivas_error TDREND_MIX_SRC_SetDir_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const Word16 SrcInd, /* i : Source index */ + const Word16 *Vec_p /* i : Direction vector */ +); +ivas_error TDREND_MIX_SRC_SetDirAtten_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const Word16 SrcInd, /* i : Source index */ + const TDREND_DirAtten_t *DirAtten_p /* i : Directional attenuation specifier */ +); +#endif // IVAS_FLOAT_FIXED ivas_error TDREND_MIX_SRC_SetDirAtten( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ @@ -823,11 +863,19 @@ ivas_error TDREND_MIX_SRC_SetDirAtten( const TDREND_DirAtten_t *DirAtten_p /* i : Directional attenuation specifier */ ); +#ifdef IVAS_FLOAT_FIXED +ivas_error TDREND_MIX_SRC_SetPlayState( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + const Word16 SrcInd, /* i : Source index */ + const TDREND_PlayStatus_t PlayStatus /* i : Play state */ +); +#else ivas_error TDREND_MIX_SRC_SetPlayState( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ const TDREND_PlayStatus_t PlayStatus /* i : Play state */ ); +#endif // IVAS_FLOAT_FIXED void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ @@ -853,6 +901,12 @@ void TDREND_SRC_Dealloc( TDREND_SRC_t *Src_p /* i/o: Source to deallocate */ ); +#ifdef IVAS_FLOAT_FIXED +void TDREND_SRC_Init_fx( + TDREND_SRC_t *Src_p, /* i/o: Source to initialize */ + const TDREND_PosType_t PosType /* i : Position type specifier */ +); +#endif // IVAS_FLOAT_FIXED void TDREND_SRC_Init( TDREND_SRC_t *Src_p, /* i/o: Source to initialize */ const TDREND_PosType_t PosType /* i : Position type specifier */ @@ -866,11 +920,25 @@ void TDREND_SPATIAL_VecInit( const float PosY, /* i : Y value */ const float PosZ /* i : Z value */ ); +#ifdef IVAS_FLOAT_FIXED +void TDREND_SPATIAL_VecInit_fx( + Word16 *Pos_p, /* o : Output vector */ + const Word16 PosX, /* i : X value */ + const Word16 PosY, /* i : Y value */ + const Word16 PosZ /* i : Z value */ +); +#endif // IVAS_FLOAT_FIXED /*! r: Euclidian norm value */ float TDREND_SPATIAL_VecNorm( const float *Vec_p /* i : Vector for norm calculation */ ); +#ifdef IVAS_FLOAT_FIXED +void TDREND_SPATIAL_VecNormalize_fx( + const Word16 *Vec_p, /* i : Input vector */ + Word16 *VecNorm_p /* o : Output vector */ +); +#endif // IVAS_FLOAT_FIXED void TDREND_SPATIAL_VecNormalize( const float *Vec_p, /* i : Input vector */ @@ -898,6 +966,13 @@ int16_t TDREND_SPATIAL_EvalOrthonormOrient( /* ----- Object renderer - mix ----- */ +#ifdef IVAS_FLOAT_FIXED +ivas_error TDREND_MIX_AddSrc_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + Word16 *SrcInd, /* o : Source index */ + const TDREND_PosType_t PosType /* i : Position type (absolute/relative) */ +); +#endif ivas_error TDREND_MIX_AddSrc( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ int16_t *SrcInd, /* o : Source index */ @@ -924,6 +999,14 @@ void TDREND_MIX_Dealloc( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd /* i/o: TD renderer handle */ ); +#ifdef IVAS_FLOAT_FIXED +ivas_error TDREND_MIX_Init_fx( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HRTF data (initialized in case of NULL) */ + const TDREND_MixSpatSpec_t *MixSpatSpec_p, /* i : Mixer spatial specification */ + const Word32 output_Fs /* i : Output sampling rate */ +); +#endif // IVAS_FLOAT_FIXED ivas_error TDREND_MIX_Init( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HRTF data (initialized in case of NULL) */ diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 5edd1f889..cea26b77a 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -1349,6 +1349,13 @@ typedef struct int16_t VelUpdated; float Vel[3]; +#ifdef IVAS_FLOAT_FIXED + Word16 Pos_fx[3]; + Word16 Front_fx[3]; + Word16 Up_fx[3]; + Word16 Right_fx[3]; + Word16 Vel_fx[3]; +#endif // IVAS_FLOAT_FIXED } TDREND_MIX_Listener_t; /* HR filter */ @@ -1386,6 +1393,11 @@ typedef struct float RefDist; float MaxDist; float RollOffFactor; +#ifdef IVAS_FLOAT_FIXED + Word16 RefDist_fx; + Word16 MaxDist_fx; + Word16 RollOffFactor_fx; +#endif // IVAS_FLOAT_FIXED } TDREND_DistAtten_t; @@ -1395,6 +1407,11 @@ typedef struct float ConeInnerAngle; float ConeOuterAngle; float ConeOuterGain; +#ifdef IVAS_FLOAT_FIXED + Word16 ConeInnerAngle_fx; + Word16 ConeOuterAngle_fx; + Word16 ConeOuterGain_fx; +#endif // IVAS_FLOAT_FIXED } TDREND_DirAtten_t; @@ -1413,6 +1430,13 @@ typedef struct TDREND_SRC_REND_s /* Gains */ int16_t SrcGainUpdated; +#ifdef IVAS_FLOAT_FIXED + Word16 SrcGain_p_fx[SPAT_BIN_MAX_INPUT_CHANNELS]; + Word16 SrcGainMin_p_fx[SPAT_BIN_MAX_INPUT_CHANNELS]; + Word16 SrcGainMax_p_fx[SPAT_BIN_MAX_INPUT_CHANNELS]; + Word16 DirGain_p_fx[SPAT_BIN_MAX_INPUT_CHANNELS]; + Word16 DistGain_p_fx[SPAT_BIN_MAX_INPUT_CHANNELS]; +#endif // IVAS_FLOAT_FIXED float SrcGain_p[SPAT_BIN_MAX_INPUT_CHANNELS]; float SrcGainMin_p[SPAT_BIN_MAX_INPUT_CHANNELS]; float SrcGainMax_p[SPAT_BIN_MAX_INPUT_CHANNELS]; @@ -1428,6 +1452,10 @@ typedef struct TDREND_PosType_t PosType; float Pos_p[3 * SPAT_BIN_MAX_INPUT_CHANNELS]; float Front_p[3 * SPAT_BIN_MAX_INPUT_CHANNELS]; +#ifdef IVAS_FLOAT_FIXED + Word16 Pos_p_fx[3 * SPAT_BIN_MAX_INPUT_CHANNELS]; + Word16 Front_p_fx[3 * SPAT_BIN_MAX_INPUT_CHANNELS]; +#endif // IVAS_FLOAT_FIXED int16_t DirAttenEnabled; TDREND_DirAtten_t DirAtten; int16_t DistAttenEnabled; @@ -1443,6 +1471,17 @@ typedef struct int16_t itd; int16_t previtd; int16_t filterlength; +#ifdef IVAS_FLOAT_FIXED + Word16 mem_itd_fx[ITD_MEM_LEN]; + Word16 mem_hrf_left_fx[SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1]; + Word16 mem_hrf_right_fx[SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1]; + Word16 hrf_left_prev_fx[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; + Word16 hrf_right_prev_fx[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; + Word16 azim_prev_fx; + Word16 elev_prev_fx; + Word16 Gain_fx; + Word16 prevGain_fx; +#endif // IVAS_FLOAT_FIXED float mem_itd[ITD_MEM_LEN]; float hrf_left_prev[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; float hrf_right_prev[SFX_SPAT_BIN_MAX_FILTER_LENGTH]; @@ -1464,6 +1503,9 @@ typedef struct ivas_binaural_td_rendering_struct int16_t MaxSrcInd; TDREND_SRC_t *Sources[MAX_NUM_TDREND_CHANNELS]; +#ifdef IVAS_FLOAT_FIXED + Word16 Gain_fx; /* Mixer gain */ +#endif // IVAS_FLOAT_FIXED float Gain; /* Mixer gain */ TDREND_MIX_Listener_t *Listener_p; /* The virtual listener */ -- GitLab