LCOV - code coverage report
Current view: top level - lib_rend - ivas_objectRenderer_sources_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 375 398 94.2 %
Date: 2025-08-23 01:22:27 Functions: 18 18 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <stdint.h>
      34             : #include "options.h"
      35             : #include <math.h>
      36             : #include "prot_fx.h"
      37             : #include "ivas_prot_rend_fx.h"
      38             : #include "wmc_auto.h"
      39             : #include "ivas_prot_fx.h"
      40             : 
      41             : 
      42             : /*---------------------------------------------------------------------*
      43             :  * Local function prototypes
      44             :  *---------------------------------------------------------------------*/
      45             : 
      46             : static void TDREND_SRC_REND_Init_fx( TDREND_SRC_REND_t *SrcRend_p );
      47             : static void TDREND_SRC_SPATIAL_Init_fx( TDREND_SRC_SPATIAL_t *SrcSpatial_p, const TDREND_PosType_t PosType );
      48             : static Word16 TDREND_SRC_SPATIAL_GetDirGain_fx( const TDREND_DirAtten_t *DirAtten_p, const Word32 *Front_p_fx, const Word32 *RelPos_p, const Word16 RelPos_p_e );
      49             : static Word16 TDREND_SRC_SPATIAL_GetDistGain_fx( const TDREND_DistAtten_t *DistAtten_p, const Word32 Dist_fx, const Word16 Dist_e );
      50             : static void TDREND_SRC_SPATIAL_SetDirAtten_fx( TDREND_SRC_SPATIAL_t *SrcSpatial_p, const TDREND_DirAtten_t *DirAtten_p );
      51             : #ifdef CONF_DISTATT
      52             : static void TDREND_SRC_SPATIAL_SetDistAtten( TDREND_SRC_SPATIAL_t *SrcSpatial_p, const TDREND_DistAtten_t *DistAtten_p );
      53             : #endif
      54             : static ivas_error TDREND_SRC_REND_Alloc( TDREND_SRC_REND_t **SrcRend_pp );
      55             : static void TDREND_SRC_SPATIAL_Dealloc( TDREND_SRC_SPATIAL_t *SrcSpatial_p );
      56             : 
      57             : /*-------------------------------------------------------------------*
      58             :  * TDREND_MIX_SRC_SetPos()
      59             :  *
      60             :  * Set source position
      61             :  --------------------------------------------------------------------*/
      62             : 
      63      411865 : ivas_error TDREND_MIX_SRC_SetPos_fx(
      64             :     BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle  */
      65             :     const Word16 SrcInd,                               /* i  : Source index        */
      66             :     const Word32 *Vec_p                                /* i  : Position vector Q25 */
      67             : )
      68             : {
      69             :     TDREND_SRC_SPATIAL_t *SrcSpatial_p;
      70             : 
      71      411865 :     IF( GT_16( SrcInd, hBinRendererTd->MaxSrcInd ) )
      72             :     {
      73           0 :         return ( IVAS_ERROR( IVAS_ERR_INVALID_INDEX, "Index exceeds max index!\n" ) );
      74             :     }
      75             :     ELSE
      76             :     {
      77      411865 :         SrcSpatial_p = hBinRendererTd->Sources[SrcInd]->SrcSpatial_p;
      78      411865 :         SrcSpatial_p->Pos_p_fx[0] = L_shr( SrcSpatial_p->Pos_p_fx[0], sub( SrcSpatial_p->q_Pos_p, Q25 ) ); // Q25
      79      411865 :         move32();
      80      411865 :         SrcSpatial_p->Pos_p_fx[1] = L_shr( SrcSpatial_p->Pos_p_fx[1], sub( SrcSpatial_p->q_Pos_p, Q25 ) ); // Q25
      81      411865 :         move32();
      82      411865 :         SrcSpatial_p->Pos_p_fx[2] = L_shr( SrcSpatial_p->Pos_p_fx[2], sub( SrcSpatial_p->q_Pos_p, Q25 ) ); // Q25
      83      411865 :         move32();
      84      411865 :         SrcSpatial_p->q_Pos_p = Q25;
      85      411865 :         move16();
      86      411865 :         test();
      87      411865 :         test();
      88      411865 :         IF( NE_32( SrcSpatial_p->Pos_p_fx[0], Vec_p[0] ) || NE_32( SrcSpatial_p->Pos_p_fx[1], Vec_p[1] ) || NE_32( SrcSpatial_p->Pos_p_fx[2], Vec_p[2] ) )
      89             :         {
      90      227146 :             Copy32( Vec_p, SrcSpatial_p->Pos_p_fx, 3 ); // Q25
      91      227146 :             SrcSpatial_p->Updated = TRUE;
      92      227146 :             move16();
      93             :         }
      94             :     }
      95             : 
      96      411865 :     return IVAS_ERR_OK;
      97             : }
      98             : 
      99             : 
     100             : /*-------------------------------------------------------------------*
     101             :  * TDREND_MIX_SRC_SetDir()
     102             :  *
     103             :  * Set source direction
     104             :  --------------------------------------------------------------------*/
     105      411037 : ivas_error TDREND_MIX_SRC_SetDir_fx(
     106             :     BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle         */
     107             :     const Word16 SrcInd,                               /* i  : Source index               */
     108             :     const Word32 *Vec_p,                               /* i  : Direction vector   Vec_p_q */
     109             :     const Word16 Vec_p_q                               /* i  : Direction vector q         */
     110             : )
     111             : {
     112             :     TDREND_SRC_SPATIAL_t *SrcSpatial_p;
     113             :     /* Value verification */
     114      411037 :     test();
     115      411037 :     test();
     116      411037 :     IF( EQ_32( Vec_p[0], 0 ) && EQ_32( Vec_p[1], 0 ) && EQ_32( Vec_p[2], 0 ) )
     117             :     {
     118           0 :         return ( IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Zero direction vector. Command is ignored!\n" ) );
     119             :     }
     120      411037 :     IF( GT_16( SrcInd, hBinRendererTd->MaxSrcInd ) )
     121             :     {
     122           0 :         return ( IVAS_ERROR( IVAS_ERR_INVALID_INDEX, "Index exceeds max index!\n" ) );
     123             :     }
     124             :     ELSE
     125             :     {
     126      411037 :         SrcSpatial_p = hBinRendererTd->Sources[SrcInd]->SrcSpatial_p;
     127      411037 :         TDREND_SPATIAL_VecNormalize_fx( Vec_p, Vec_p_q, SrcSpatial_p->Front_p_fx );
     128      411037 :         SrcSpatial_p->Updated = TRUE;
     129      411037 :         move16();
     130             :     }
     131      411037 :     return IVAS_ERR_OK;
     132             : }
     133             : 
     134             : 
     135             : /*-------------------------------------------------------------------*
     136             :  * TDREND_MIX_SRC_SetDirAtten()
     137             :  *
     138             :  * Set directional attenuation for the mixer.
     139             :  --------------------------------------------------------------------*/
     140      412401 : ivas_error TDREND_MIX_SRC_SetDirAtten_fx(
     141             :     BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle                */
     142             :     const Word16 SrcInd,                               /* i  : Source index                   Q0 */
     143             :     const TDREND_DirAtten_t *DirAtten_p                /* i  : Directional attenuation specifier */
     144             : )
     145             : {
     146             :     TDREND_SRC_SPATIAL_t *SrcSpatial_p;
     147      412401 :     IF( GT_16( SrcInd, hBinRendererTd->MaxSrcInd ) )
     148             :     {
     149           0 :         return ( IVAS_ERROR( IVAS_ERR_INVALID_INDEX, "Index exceeds max index\n" ) );
     150             :     }
     151             :     ELSE
     152             :     {
     153      412401 :         SrcSpatial_p = hBinRendererTd->Sources[SrcInd]->SrcSpatial_p;
     154      412401 :         TDREND_SRC_SPATIAL_SetDirAtten_fx( SrcSpatial_p, DirAtten_p );
     155             :     }
     156             : 
     157      412401 :     return IVAS_ERR_OK;
     158             : }
     159             : 
     160             : #ifdef CONF_DISTATT
     161             : /*-------------------------------------------------------------------*
     162             :  * TDREND_MIX_SRC_SetDistAtten()
     163             :  *
     164             :  * Set distance attenuation for the mixer.
     165             :  --------------------------------------------------------------------*/
     166             : 
     167        1639 : ivas_error TDREND_MIX_SRC_SetDistAtten(
     168             :     BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle                */
     169             :     const Word16 SrcInd,                               /* i  : Source index                      */
     170             :     const TDREND_DistAtten_t *DistAtten_p              /* i  : Distance attenuation specifier */
     171             : )
     172             : {
     173             :     TDREND_SRC_SPATIAL_t *SrcSpatial_p;
     174        1639 :     IF( GT_16( SrcInd, hBinRendererTd->MaxSrcInd ) )
     175             :     {
     176           0 :         return ( IVAS_ERROR( IVAS_ERR_INVALID_INDEX, "Index exceeds max index\n" ) );
     177             :     }
     178             :     ELSE
     179             :     {
     180        1639 :         SrcSpatial_p = hBinRendererTd->Sources[SrcInd]->SrcSpatial_p;
     181        1639 :         TDREND_SRC_SPATIAL_SetDistAtten( SrcSpatial_p, DistAtten_p );
     182             :     }
     183             : 
     184        1639 :     return IVAS_ERR_OK;
     185             : }
     186             : #endif
     187             : 
     188             : 
     189             : /*-------------------------------------------------------------------*
     190             :  * TDREND_MIX_SRC_SetPlayState()
     191             :  *
     192             :  * Set play state for the source.
     193             :  --------------------------------------------------------------------*/
     194             : 
     195         275 : ivas_error TDREND_MIX_SRC_SetPlayState(
     196             :     BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle  */
     197             :     const Word16 SrcInd,                               /* i  : Source index     Q0 */
     198             :     const TDREND_PlayStatus_t PlayStatus               /* i  : Play state          */
     199             : )
     200             : {
     201         275 :     IF( GT_16( SrcInd, hBinRendererTd->MaxSrcInd ) )
     202             :     {
     203           0 :         return ( IVAS_ERROR( IVAS_ERR_INVALID_INDEX, "Index exceeds max index\n" ) );
     204             :     }
     205             :     ELSE
     206             :     {
     207         275 :         hBinRendererTd->Sources[SrcInd]->SrcRend_p->PlayStatus = PlayStatus;
     208         275 :         move32();
     209             :     }
     210         275 :     return IVAS_ERR_OK;
     211             : }
     212             : 
     213             : /*-------------------------------------------------------------------*
     214             :  * TDREND_SRC_REND_Alloc()
     215             :  *
     216             :  * Renderer allocation
     217             :  --------------------------------------------------------------------*/
     218             : 
     219        1639 : static ivas_error TDREND_SRC_REND_Alloc(
     220             :     TDREND_SRC_REND_t **SrcRend_pp /* i/o: Source object */
     221             : )
     222             : {
     223             :     TDREND_SRC_REND_t *SrcRend_p;
     224             : 
     225        1639 :     *SrcRend_pp = NULL;
     226             : 
     227             :     /* Allocate the TDREND_SRC_REND_t variable */
     228        1639 :     IF( ( SrcRend_p = (TDREND_SRC_REND_t *) malloc( sizeof( TDREND_SRC_REND_t ) ) ) == NULL )
     229             :     {
     230           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "SrcRend_p allocation error\n" ) );
     231             :     }
     232             : 
     233        1639 :     *SrcRend_pp = SrcRend_p;
     234             : 
     235        1639 :     return IVAS_ERR_OK;
     236             : }
     237             : 
     238             : 
     239             : /*-------------------------------------------------------------------*
     240             :  * TDREND_SRC_REND_Init()
     241             :  *
     242             :  * Initialize rendering aspects of source.
     243             :  --------------------------------------------------------------------*/
     244        1639 : static void TDREND_SRC_REND_Init_fx(
     245             :     TDREND_SRC_REND_t *SrcRend_p /* i/o: Source object        */
     246             : )
     247             : {
     248             :     Word16 nC;
     249             :     /* Internal state */
     250        1639 :     SrcRend_p->InputAvailable = FALSE;
     251        1639 :     move16();
     252        1639 :     SrcRend_p->PlayStatus = TDREND_PLAYSTATUS_PLAYING;
     253        1639 :     move16();
     254             :     /* SrcGain  */
     255        3278 :     FOR( nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ )
     256             :     {
     257        1639 :         SrcRend_p->SrcGainMin_p_fx[nC] = 0; /* Q15 */
     258        1639 :         move16();
     259        1639 :         SrcRend_p->SrcGain_p_fx[nC] = ONE_IN_Q14; // Q14
     260        1639 :         move16();
     261        1639 :         SrcRend_p->SrcGainMax_p_fx[nC] = 32767; /* Q15 */
     262        1639 :         move16();
     263             :     }
     264        1639 :     SrcRend_p->SrcGainUpdated = FALSE;
     265        1639 :     move16();
     266             :     /* Init directional and distance gains */
     267        3278 :     FOR( nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ )
     268             :     {
     269        1639 :         SrcRend_p->DirGain_p_fx[nC] = ONE_IN_Q14; // Q14
     270        1639 :         move16();
     271        1639 :         SrcRend_p->DistGain_p_fx[nC] = ONE_IN_Q14; // Q14
     272        1639 :         move16();
     273             :     }
     274        1639 :     return;
     275             : }
     276             : 
     277             : /*-------------------------------------------------------------------*
     278             :  * TDREND_SRC_REND_UpdateFiltersFromSpatialParams()
     279             :  *
     280             :  * Update the HR filter due to spatial change.
     281             :  --------------------------------------------------------------------*/
     282             : 
     283      917831 : void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx(
     284             :     BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle                        */
     285             :     TDREND_SRC_REND_t *SrcRend_p,                      /* i/o: Source object                             */
     286             :     TDREND_SRC_SPATIAL_t *SrcSpatial_p,                /* i  : Spatial aspects of source                 */
     287             :     Word32 *hrf_left_prev,
     288             :     /* i/o: Left filter                               */ // exp(hrf_left_prev_e)
     289             :     Word16 *hrf_left_prev_e,
     290             :     /* i/o: Left filter exponent                      */ // Q0
     291             :     Word32 *hrf_right_prev,
     292             :     /* i/o: Right filter                              */ // exp(hrf_right_prev_e)
     293             :     Word16 *hrf_right_prev_e,
     294             :     /* i/o: Right filter exponent                     */ // Q0
     295             :     Word32 *hrf_left_delta,
     296             :     /* o  : Left filter interpolation delta           */ // exp(hrf_left_delta_e)
     297             :     Word16 *hrf_left_delta_e,
     298             :     /* o  : Left filter interpolation delta exponent  */ // Q0
     299             :     Word32 *hrf_right_delta,
     300             :     /* o  : Right filter interpolation delta          */ // exp(hrf_right_delta_e)
     301             :     Word16 *hrf_right_delta_e,
     302             :     /* o  : Right filter interpolation delta exponent */ // Q0
     303             :     Word16 *intp_count,
     304             :     /* o  : Interpolation count                       */ // Q0
     305             :     Word16 *filterlength,
     306             :     /* o  : Length of filters                         */ // Q0
     307             :     Word16 *itd,
     308             :     /* o  : ITD value                                 */ // Q0
     309             :     Word32 *Gain,
     310             : /* o  : Gain value                                */ // Q30
     311             : #ifdef NONBE_FIX_1196_TD_HEADTRACKING_INTERPOLATION
     312             :     TDREND_SRC_t *Src_p /* i/o: Source pointer                            */
     313             : #else
     314             :     TDREND_SRC_t *Src_p, /* i/o: Source pointer                            */
     315             :     const Word16 subframe_update_flag
     316             : #endif
     317             : )
     318             : {
     319             :     TDREND_MIX_Listener_t *Listener_p;
     320             :     TDREND_HRFILT_FiltSet_t *HrFiltSet_p;
     321             :     Word32 ListRelPos[3];
     322             :     Word32 ListRelDist;
     323             :     Word32 ListRelPosAbs[3]; /* Relative position, ignoring orientation of listener */
     324             :     Word32 Azim, Elev;
     325             :     Word32 hrf_left[SFX_SPAT_BIN_MAX_FILTER_LENGTH];
     326             :     Word32 hrf_right[SFX_SPAT_BIN_MAX_FILTER_LENGTH];
     327             :     Word16 hrf_left_e, hrf_right_e;
     328             :     Word32 azim_delta;
     329             :     Word32 elev_delta;
     330             :     Word16 ListRelPos_e, ListRelDist_e;
     331             : 
     332             :     /* Evaluate the HR filters from the source and listener positions and orientations */
     333      917831 :     Listener_p = hBinRendererTd->Listener_p;
     334      917831 :     HrFiltSet_p = hBinRendererTd->HrFiltSet_p;
     335             : 
     336      917831 :     *filterlength = s_min( HrFiltSet_p->FiltLength, SFX_SPAT_BIN_MAX_FILTER_LENGTH ); // Q0
     337      917831 :     move16();
     338      917831 :     IF( EQ_16( SrcSpatial_p->PosType, TDREND_POSTYPE_ABSOLUTE ) )
     339             :     {
     340             : 
     341             :         /* Absolute position */
     342      917003 :         TDREND_SPATIAL_VecMapToNewCoordSystem_fx( SrcSpatial_p->Pos_p_fx, Listener_p->Pos_fx, Listener_p->Front_fx, Listener_p->Up_fx, Listener_p->Right_fx, ListRelPos, ListRelPosAbs );
     343      917003 :         ListRelPos_e = 7; // output q of above function is Q25 + Q30 - 31. so exp will be 62 - Q25 - Q30.
     344      917003 :         move16();
     345      917003 :         ListRelDist = TDREND_SPATIAL_VecNorm_fx( ListRelPos, ListRelPos_e, &ListRelDist_e );
     346             : 
     347             :         /* 2. Evaluate the Elevation and Azimuth angles  */
     348      917003 :         test();
     349      917003 :         test();
     350      917003 :         IF( ( ListRelPos[0] == 0 ) && ( ListRelPos[1] == 0 ) && ( ListRelPos[2] == 0 ) )
     351             :         {
     352        1371 :             Elev = 0;
     353        1371 :             move32();
     354        1371 :             Azim = 0;
     355        1371 :             move32();
     356             :         }
     357             :         ELSE
     358             :         {
     359      915632 :             Word32 tmp1 = Mpy_32_32( ListRelPos[0], ListRelPos[0] ); // exp(2*ListRelPos_e)
     360      915632 :             Word32 tmp2 = Mpy_32_32( ListRelPos[1], ListRelPos[1] ); // exp(2*ListRelPos_e)
     361      915632 :             Word32 tmp3 = L_add( tmp1, tmp2 );                       // exp(2*ListRelPos_e)
     362      915632 :             Word16 tmp_e = shl( ListRelPos_e, 1 );
     363      915632 :             Word32 tmp4 = Sqrt32( tmp3, &tmp_e );                                              // exp(tmp_e)
     364      915632 :             Word16 tmp5 = BASOP_util_atan2( ListRelPos[2], tmp4, sub( ListRelPos_e, tmp_e ) ); // Q13
     365      915632 :             Word32 tmp6 = Mpy_32_16_1( _180_OVER_PI_Q25, tmp5 );                               // Q25 + Q13 - Q15 = Q23
     366             :             /* Basis set is [front, right, up], which is a left-handed coordinate system. Minus sign here is to change to a positive-left system for azimuth */
     367      915632 :             Word16 tmp7 = BASOP_util_atan2( ListRelPos[1], ListRelPos[0], 0 ); // Q13
     368      915632 :             Word32 tmp8 = L_negate( Mpy_32_16_1( _180_OVER_PI_Q25, tmp7 ) );   // Q25 + Q13 - Q15 = Q23
     369             : 
     370      915632 :             Elev = L_shr( tmp6, 1 ); // Q22
     371      915632 :             Azim = L_shr( tmp8, 1 ); // Q22
     372             :         }
     373             : 
     374      917003 :         GetFilterFromAngle_fx( HrFiltSet_p, Elev, Azim, *filterlength, hrf_left, &hrf_left_e, hrf_right, &hrf_right_e, itd );
     375             : 
     376             :         /* 6. Evaluate the directional and distance gains */
     377             :         /* Directional gain */
     378      917003 :         *SrcRend_p->DirGain_p_fx = ONE_IN_Q14; // Q14
     379      917003 :         move16();
     380      917003 :         IF( SrcSpatial_p->DirAttenEnabled )
     381             :         {
     382      917003 :             *SrcRend_p->DirGain_p_fx = TDREND_SRC_SPATIAL_GetDirGain_fx( &SrcSpatial_p->DirAtten, SrcSpatial_p->Front_p_fx, ListRelPosAbs, 6 );
     383             :         }
     384             : 
     385             :         /* Distance gain */
     386      917003 :         *SrcRend_p->DistGain_p_fx = ONE_IN_Q14; // Q14
     387      917003 :         move16();
     388      917003 :         IF( hBinRendererTd->UseCommonDistAttenModel )
     389             :         {
     390      917003 :             IF( hBinRendererTd->DistAttenEnabled )
     391             :             {
     392      917003 :                 SrcSpatial_p->DistAtten.DistAttenModel = hBinRendererTd->DistAttenModel;
     393      917003 :                 move32();
     394      917003 :                 *SrcRend_p->DistGain_p_fx = TDREND_SRC_SPATIAL_GetDistGain_fx( &SrcSpatial_p->DistAtten, ListRelDist, ListRelDist_e ); // Q14
     395      917003 :                 move32();
     396             :             }
     397             :         }
     398           0 :         ELSE IF( SrcSpatial_p->DistAttenEnabled )
     399             :         {
     400             : 
     401           0 :             *SrcRend_p->DistGain_p_fx = TDREND_SRC_SPATIAL_GetDistGain_fx( &SrcSpatial_p->DistAtten, ListRelDist, ListRelDist_e ); // Q14
     402           0 :             move32();
     403             :         }
     404             : 
     405             : 
     406             :         /* Update total gains */
     407      917003 :         *Gain = L_shl( Mpy_32_32( L_shl( L_mult( *SrcRend_p->SrcGain_p_fx, *SrcRend_p->DirGain_p_fx ), 1 ), L_shl( L_mult( *SrcRend_p->DistGain_p_fx, hBinRendererTd->Gain_fx ), 1 ) ), 1 ); // Q30
     408      917003 :         move32();
     409             :         /* Delta for interpolation, in case the angular step exceeds MAX_ANGULAR_STEP */
     410      917003 :         Word32 ele_tmp = Src_p->elev_prev_fx; // Q22
     411      917003 :         move32();
     412      917003 :         IF( GT_32( ele_tmp, DEG_180_IN_Q22 ) )
     413             :         {
     414           0 :             ele_tmp = L_sub( ele_tmp, DEG_360_IN_Q22 ); // Q22
     415             :         }
     416      917003 :         ELSE IF( LT_32( ele_tmp, -DEG_180_IN_Q22 ) )
     417             :         {
     418           0 :             ele_tmp = L_add( ele_tmp, DEG_360_IN_Q22 ); // Q22
     419             :         }
     420      917003 :         elev_delta = L_sub( Elev, ele_tmp ); // Q22
     421             : 
     422      917003 :         Word32 azi_tmp = Src_p->azim_prev_fx; // Q22
     423      917003 :         IF( GT_32( azi_tmp, DEG_180_IN_Q22 ) )
     424             :         {
     425           3 :             azi_tmp = L_sub( azi_tmp, DEG_360_IN_Q22 ); // Q22
     426             :         }
     427      917000 :         ELSE IF( LT_32( azi_tmp, -DEG_180_IN_Q22 ) )
     428             :         {
     429         312 :             azi_tmp = L_add( azi_tmp, DEG_360_IN_Q22 ); // Q22
     430             :         }
     431      917003 :         azim_delta = L_sub( Azim, azi_tmp ); // Q22
     432             : 
     433      917003 :         Src_p->elev_prev_fx = Elev; // Q22
     434      917003 :         move32();
     435      917003 :         Src_p->azim_prev_fx = Azim; // Q22
     436      917003 :         move32();
     437             : 
     438             :         /* map to -180:180 range */
     439      917003 :         IF( GT_32( azim_delta, DEG_180_IN_Q22 ) )
     440             :         {
     441       21369 :             azim_delta = L_sub( azim_delta, DEG_360_IN_Q22 ); // Q22
     442             :         }
     443      895634 :         ELSE IF( LT_32( azim_delta, -DEG_180_IN_Q22 ) )
     444             :         {
     445        2717 :             azim_delta = L_add( azim_delta, DEG_360_IN_Q22 ); // Q22
     446             :         }
     447      917003 :         Word16 tmp1 = extract_l( Mpy_32_32( L_abs( azim_delta ), 100 << Q9 ) ); // Q22 + Q9 - Q31 = Q0
     448      917003 :         Word16 tmp2 = extract_l( Mpy_32_32( L_abs( elev_delta ), 100 << Q9 ) ); // Q22 + Q9 - Q31 = Q0
     449      917003 :         *intp_count = s_min( MAX_INTERPOLATION_STEPS, s_max( tmp1, tmp2 ) );    // Q0
     450      917003 :         move16();
     451             :     }
     452             :     ELSE /* TDREND_POSTYPE_NON_DIEGETIC */
     453             :     {
     454         828 :         *itd = 0; // Q0
     455         828 :         move16();
     456         828 :         *Gain = ONE_IN_Q30; // Q30
     457         828 :         move32();
     458         828 :         set32_fx( hrf_left, 0, *filterlength );
     459         828 :         set32_fx( hrf_right, 0, *filterlength );
     460         828 :         hrf_left[0] = L_shr( L_add( SrcSpatial_p->Pos_p_fx[1], ONE_IN_Q25 ), 1 ); // Q25
     461         828 :         move32();
     462         828 :         hrf_right[0] = L_sub( ONE_IN_Q25, hrf_left[0] ); // Q25
     463         828 :         move32();
     464         828 :         hrf_left_e = 6;
     465         828 :         move16();
     466         828 :         hrf_right_e = 6;
     467         828 :         move16();
     468         828 :         *intp_count = MAX_INTERPOLATION_STEPS; // Q22
     469         828 :         move16();
     470         828 :         Src_p->elev_prev_fx = 0; // Q22
     471         828 :         move16();
     472         828 :         Src_p->azim_prev_fx = DEG_360_IN_Q22; /* Dummy angle -- sets max interpolation if switching to TDREND_POSTYPE_ABSOLUTE */ // Q22
     473         828 :         move16();
     474             :     }
     475             : 
     476      917831 :     test();
     477             : 
     478             : #ifdef NONBE_FIX_1196_TD_HEADTRACKING_INTERPOLATION
     479      917831 :     IF( ( *intp_count > 0 ) )
     480             : #else
     481             :     IF( ( *intp_count > 0 ) && subframe_update_flag )
     482             : #endif
     483             :     {
     484             :         /* Set deltas for interpolation */
     485             :         Word16 tmp_e;
     486      791494 :         tmp_e = s_max( *hrf_left_prev_e, hrf_left_e );
     487    99952283 :         FOR( Word16 i = 0; i < *filterlength; i++ )
     488             :         {
     489    99160789 :             hrf_left[i] = L_shr( hrf_left[i], sub( tmp_e, hrf_left_e ) ); // exp(tmp_e)
     490    99160789 :             move32();
     491    99160789 :             hrf_left_prev[i] = L_shr( hrf_left_prev[i], sub( tmp_e, *hrf_left_prev_e ) ); // exp(tmp_e)
     492    99160789 :             move32();
     493             :         }
     494      791494 :         *hrf_left_prev_e = tmp_e;
     495      791494 :         move16();
     496      791494 :         hrf_left_e = tmp_e;
     497      791494 :         move16();
     498      791494 :         v_sub_32( hrf_left, hrf_left_prev, hrf_left_delta, *filterlength ); // exp(tmp_e)
     499      791494 :         *hrf_left_delta_e = tmp_e;
     500      791494 :         move16();
     501             : 
     502      791494 :         Word32 fac = L_deposit_h( div_s( 1, *intp_count ) );                 // Q15
     503      791494 :         v_multc_fixed( hrf_left_delta, fac, hrf_left_delta, *filterlength ); // exp(hrf_left_delta_e)
     504             : 
     505      791494 :         tmp_e = s_max( *hrf_right_prev_e, hrf_right_e );
     506    99952283 :         FOR( Word16 i = 0; i < *filterlength; i++ )
     507             :         {
     508    99160789 :             hrf_right[i] = L_shr( hrf_right[i], sub( tmp_e, hrf_right_e ) ); // exp(tmp_e)
     509    99160789 :             move32();
     510    99160789 :             hrf_right_prev[i] = L_shr( hrf_right_prev[i], sub( tmp_e, *hrf_right_prev_e ) ); // exp(tmp_e)
     511    99160789 :             move32();
     512             :         }
     513      791494 :         *hrf_right_prev_e = tmp_e;
     514      791494 :         move16();
     515      791494 :         hrf_right_e = tmp_e;
     516      791494 :         move16();
     517      791494 :         v_sub_32( hrf_right, hrf_right_prev, hrf_right_delta, *filterlength ); // exp(hrf_right_delta_e)
     518      791494 :         *hrf_right_delta_e = tmp_e;
     519      791494 :         move16();
     520             : 
     521      791494 :         v_multc_fixed( hrf_right_delta, fac, hrf_right_delta, *filterlength ); // exp(hrf_right_delta_e)
     522             :     }
     523             :     ELSE
     524             :     {
     525             :         /* No interpolation, just set the new filters and reset deltas */
     526      126337 :         Copy32( hrf_left, hrf_left_prev, *filterlength ); // exp(hrf_left_prev_e)
     527      126337 :         *hrf_left_prev_e = hrf_left_e;
     528      126337 :         move16();
     529      126337 :         Copy32( hrf_right, hrf_right_prev, *filterlength ); // exp(hrf_right_prev_e)
     530      126337 :         *hrf_right_prev_e = hrf_right_e;
     531      126337 :         move16();
     532      126337 :         set32_fx( hrf_left_delta, 0, *filterlength );
     533      126337 :         set32_fx( hrf_right_delta, 0, *filterlength );
     534      126337 :         *hrf_left_delta_e = 0;
     535      126337 :         move16();
     536      126337 :         *hrf_right_delta_e = 0;
     537      126337 :         move16();
     538             :     }
     539             : 
     540      917831 :     return;
     541             : }
     542             : 
     543             : /*-------------------------------------------------------------------*
     544             :  * TDREND_SRC_SPATIAL_Alloc()
     545             :  *
     546             :  * Allocatie spatial properties of a source.
     547             :  --------------------------------------------------------------------*/
     548             : 
     549        1639 : static ivas_error TDREND_SRC_SPATIAL_Alloc(
     550             :     TDREND_SRC_SPATIAL_t **SrcSpatial_pp /* i/o: Source spatial parameters */
     551             : )
     552             : {
     553             :     TDREND_SRC_SPATIAL_t *SrcSpatial_p;
     554             : 
     555        1639 :     *SrcSpatial_pp = NULL;
     556             : 
     557             :     /* Allocate the TDREND_SRC_t variable */
     558        1639 :     IF( ( SrcSpatial_p = (TDREND_SRC_SPATIAL_t *) malloc( sizeof( TDREND_SRC_SPATIAL_t ) ) ) == NULL )
     559             :     {
     560           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "TDREND_SRC_SPATIAL_t allocation error\n" ) );
     561             :     }
     562             : 
     563        1639 :     *SrcSpatial_pp = SrcSpatial_p;
     564             : 
     565        1639 :     return IVAS_ERR_OK;
     566             : }
     567             : 
     568             : 
     569             : /*-------------------------------------------------------------------*
     570             :  * TDREND_SRC_SPATIAL_Dealloc()
     571             :  *
     572             :  * Deallocate spatial properties of a source.
     573             :  --------------------------------------------------------------------*/
     574             : 
     575        1639 : static void TDREND_SRC_SPATIAL_Dealloc(
     576             :     TDREND_SRC_SPATIAL_t *SrcSpatial_p /* i/o: Source spatial parameters */
     577             : )
     578             : {
     579        1639 :     IF( SrcSpatial_p == NULL )
     580             :     {
     581           0 :         return;
     582             :     }
     583             :     /* Free the SrcSpatial_p variable */
     584        1639 :     free( SrcSpatial_p );
     585        1639 :     SrcSpatial_p = NULL;
     586        1639 :     return;
     587             : }
     588             : 
     589             : /*-------------------------------------------------------------------*
     590             :  * TDREND_SRC_SPATIAL_Init()
     591             :  *
     592             :  * Initialize spatial properties of a source.
     593             :  --------------------------------------------------------------------*/
     594        1639 : static void TDREND_SRC_SPATIAL_Init_fx(
     595             :     TDREND_SRC_SPATIAL_t *SrcSpatial_p, /* i/o: Source spatial parameters       */
     596             :     const TDREND_PosType_t PosType      /* i  : Relative/absolute position type */
     597             : )
     598             : {
     599             :     Word16 nC; // Q0
     600             : 
     601             :     /* Initialize variables */
     602        1639 :     SrcSpatial_p->Updated = FALSE;
     603             : 
     604        1639 :     move16();
     605             :     /* Source position, velocity and direction vectors */
     606        1639 :     SrcSpatial_p->PosType = PosType;
     607        1639 :     move32();
     608        3278 :     FOR( nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ )
     609             :     {
     610             :         /* Source position */
     611        1639 :         TDREND_SPATIAL_VecInit_fx( SrcSpatial_p->Pos_p_fx + nC * 3, 0, 0, 0 ); /*Assuming Q31*/
     612             : 
     613             :         /* Source direction */
     614        1639 :         TDREND_SPATIAL_VecInit_fx( SrcSpatial_p->Front_p_fx + nC * 3, 0, 0, ONE_IN_Q30 ); /*Assuming Q30*/
     615             :     }
     616             : 
     617        1639 :     SrcSpatial_p->q_Pos_p = Q31;
     618        1639 :     move16();
     619             : 
     620             :     /* Source directional attenuation */
     621        1639 :     SrcSpatial_p->DirAttenEnabled = FALSE; // Q0
     622        1639 :     move16();
     623        1639 :     SrcSpatial_p->DirAtten.ConeInnerAngle_fx = DEG_360_IN_Q22; // Q22
     624        1639 :     move32();
     625        1639 :     SrcSpatial_p->DirAtten.ConeOuterAngle_fx = DEG_360_IN_Q22; // Q22
     626        1639 :     move32();
     627        1639 :     SrcSpatial_p->DirAtten.ConeOuterGain_fx = ONE_IN_Q30; // Q30
     628        1639 :     move16();
     629             : 
     630             :     /* Source distance attenuation */
     631        1639 :     SrcSpatial_p->DistAttenEnabled = FALSE; // Q0
     632        1639 :     move16();
     633        1639 :     SrcSpatial_p->DistAtten.DistAttenModel = TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED; // Q0
     634        1639 :     move16();
     635        1639 :     SrcSpatial_p->DistAtten.RefDist_fx = ONE_IN_Q30; // Q30
     636        1639 :     move32();
     637        1639 :     SrcSpatial_p->DistAtten.MaxDist_fx = 2113929216; /* Maximum radius (2^ISM_RADIUS_NBITS-1)*0.25 */ /*15.75 in Q27*/
     638        1639 :     move32();
     639        1639 :     SrcSpatial_p->DistAtten.RollOffFactor_fx = ONE_IN_Q30; // Q30
     640        1639 :     move16();
     641             : 
     642        1639 :     return;
     643             : }
     644             : 
     645             : /*-------------------------------------------------------------------*
     646             :  * TDREND_SRC_SPATIAL_SetDirAtten()
     647             :  *
     648             :  * Sets the directional attenuation mode.
     649             :  --------------------------------------------------------------------*/
     650             : 
     651      412401 : static void TDREND_SRC_SPATIAL_SetDirAtten_fx(
     652             :     TDREND_SRC_SPATIAL_t *SrcSpatial_p, /* i/o: Source spatial parameters    */
     653             :     const TDREND_DirAtten_t *DirAtten_p /* i  : Directionality specification */
     654             : )
     655             : {
     656             :     /* Set directional attenuation */
     657      412401 :     SrcSpatial_p->DirAttenEnabled = TRUE;                                     // Q0
     658      412401 :     SrcSpatial_p->DirAtten.ConeInnerAngle_fx = DirAtten_p->ConeInnerAngle_fx; // Q22
     659      412401 :     SrcSpatial_p->DirAtten.ConeOuterAngle_fx = DirAtten_p->ConeOuterAngle_fx; // Q22
     660      412401 :     SrcSpatial_p->DirAtten.ConeOuterGain_fx = DirAtten_p->ConeOuterGain_fx;   // Q30
     661      412401 :     move16();
     662      412401 :     move16();
     663      412401 :     move16();
     664      412401 :     move16();
     665      412401 :     return;
     666             : }
     667             : 
     668             : #ifdef CONF_DISTATT
     669             : /*-------------------------------------------------------------------*
     670             :  * TDREND_SRC_SPATIAL_SetDistAtten()
     671             :  *
     672             :  * Sets the distance attenuation.
     673             :  --------------------------------------------------------------------*/
     674             : 
     675        1639 : static void TDREND_SRC_SPATIAL_SetDistAtten(
     676             :     TDREND_SRC_SPATIAL_t *SrcSpatial_p,
     677             :     const TDREND_DistAtten_t *DistAtten_p )
     678             : {
     679             :     /* Set distance attenuation */
     680        1639 :     SrcSpatial_p->DistAttenEnabled = TRUE;
     681        1639 :     SrcSpatial_p->DistAtten.DistAttenModel = DistAtten_p->DistAttenModel;
     682        1639 :     SrcSpatial_p->DistAtten.MaxDist_fx = DistAtten_p->MaxDist_fx;
     683        1639 :     SrcSpatial_p->DistAtten.RefDist_fx = DistAtten_p->RefDist_fx;
     684        1639 :     SrcSpatial_p->DistAtten.RollOffFactor_fx = DistAtten_p->RollOffFactor_fx;
     685        1639 :     move16();
     686        1639 :     move32();
     687        1639 :     move32();
     688        1639 :     move32();
     689             : 
     690        1639 :     return;
     691             : }
     692             : #endif
     693             : 
     694             : /*-------------------------------------------------------------------*
     695             :  * TDREND_SRC_SPATIAL_GetDirGain()
     696             :  *
     697             :  * Returns the gain due to object orientation.
     698             :  --------------------------------------------------------------------*/
     699             : 
     700             : /*! r: Gain value */
     701      917003 : static Word16 TDREND_SRC_SPATIAL_GetDirGain_fx(                                      /* o  : Directional Gain Output               Q14 */
     702             :                                                 const TDREND_DirAtten_t *DirAtten_p, /* i  : Directional attenuation specification     */
     703             :                                                 const Word32 *Front_p_fx,            /* i  : Front-pointing vector                 Q30 */
     704             :                                                 const Word32 *RelPos_p_fx,           /* i  : Relative position                         */
     705             :                                                 const Word16 RelPos_p_e              /* i  : Relative position exp          RelPos_p_e */
     706             : )
     707             : {
     708             :     Word16 DirGain_fx; // Q14
     709             :     Word32 Vec_fx[3];
     710             :     Word32 ProjCoef_fx;
     711             :     Word16 ProjCoef_e;
     712             :     Word32 NormRelPos_fx;
     713             :     Word16 NormRelPos_e;
     714             :     Word32 AngleDeg_fx; // Q22
     715             : 
     716      917003 :     DirGain_fx = ONE_IN_Q14;
     717      917003 :     move16();
     718             : 
     719             :     /* Note that the front vector is unit norm, thus */
     720             :     /* Angle = acos ( Proj coeff from projecting -RelPos onto Front / norm(RelPos) ); */
     721     3668012 :     FOR( Word16 i = 0; i < 3; i++ )
     722             :     {
     723     2751009 :         Vec_fx[i] = L_negate( RelPos_p_fx[i] ); // exp(RelPos_p_e)
     724     2751009 :         move32();
     725             :     }
     726      917003 :     ProjCoef_fx = dotp_fixed( Vec_fx, Front_p_fx, 3 ); // exp: RelPos_p_e + 1
     727      917003 :     ProjCoef_e = add( RelPos_p_e, 1 );
     728      917003 :     NormRelPos_fx = TDREND_SPATIAL_VecNorm_fx( RelPos_p_fx, RelPos_p_e, &NormRelPos_e ); // exp(NormRelPos_e)
     729             : 
     730      917003 :     IF( NormRelPos_fx != 0 )
     731             :     {
     732             :         // AngleDeg = _180_OVER_PI * acosf( ProjCoef / NormRelPos );
     733             : 
     734             :         Word16 tmp_e1, tmp_e2, tmp_e3, tmp_e4, acosfx;
     735             :         Word32 tmp1, tmp2, tmp3, tmp4;
     736             : 
     737             :         // acos(x/y) = atan( sqrt(1-(x/y)^2) / (x/y) )
     738      915632 :         tmp1 = L_deposit_h( BASOP_Util_Divide3232_Scale( ProjCoef_fx, NormRelPos_fx, &tmp_e1 ) ); // x/y /* exp(tmp_e1) */
     739      915632 :         tmp_e1 = add( tmp_e1, sub( ProjCoef_e, NormRelPos_e ) );
     740      915632 :         tmp2 = Mpy_32_32( tmp1, tmp1 ); // (x/y)^2 /* exp(tmp_e2 */
     741      915632 :         tmp_e2 = shl( tmp_e1, 1 );
     742      915632 :         tmp3 = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30, 1, L_negate( tmp2 ), tmp_e2, &tmp_e3 ); // 1 - (x/y)^2 /* exp(tmp_e3) */
     743      915632 :         tmp_e4 = tmp_e3;
     744      915632 :         move16();
     745      915632 :         tmp3 = L_abs( tmp3 );                                              // for safety: sometimes it can go negative due to slight precision difference between numerator and denominator.
     746      915632 :         tmp4 = Sqrt32( tmp3, &tmp_e4 );                                    // sqrt(1 - (x/y)^2) /* exp(tmp_e4) */
     747      915632 :         acosfx = BASOP_util_atan2( tmp4, tmp1, sub( tmp_e4, tmp_e1 ) );    // 2Q13
     748      915632 :         AngleDeg_fx = L_shr( Mpy_32_16_1( _180_OVER_PI_Q25, acosfx ), 1 ); // Q22
     749             :     }
     750             :     ELSE
     751             :     {
     752        1371 :         AngleDeg_fx = 0;
     753        1371 :         move32();
     754             :     }
     755             : 
     756      917003 :     IF( LE_32( AngleDeg_fx, L_shr( DirAtten_p->ConeInnerAngle_fx, 1 ) ) )
     757             :     {
     758      876150 :         DirGain_fx = ONE_IN_Q14; // Q14
     759      876150 :         move16();
     760             :     }
     761       40853 :     ELSE IF( LE_32( AngleDeg_fx, L_shr( DirAtten_p->ConeOuterAngle_fx, 1 ) ) )
     762             :     {
     763             :         // DirGain = 1.0f - ( 2.0f * AngleDeg - DirAtten_p->ConeInnerAngle ) / ( DirAtten_p->ConeOuterAngle - DirAtten_p->ConeInnerAngle ) * ( 1.0f - DirAtten_p->ConeOuterGain );
     764             :         Word32 tmp1, tmp2, tmp3;
     765       33370 :         tmp1 = L_sub( ONE_IN_Q30, DirAtten_p->ConeOuterGain_fx );                                     // Q30
     766       33370 :         tmp2 = L_sub( DirAtten_p->ConeOuterAngle_fx, DirAtten_p->ConeInnerAngle_fx );                 // Q22
     767       33370 :         tmp3 = L_sub( L_shl( AngleDeg_fx, 1 ) /* 2.0f * AngleDeg */, DirAtten_p->ConeInnerAngle_fx ); // Q22
     768       33370 :         DirGain_fx = sub( ONE_IN_Q14, div_l( Mpy_32_32( tmp1, tmp3 ), extract_h( tmp2 ) ) );          // Q14
     769             :     }
     770             :     ELSE
     771             :     {
     772        7483 :         DirGain_fx = extract_h( DirAtten_p->ConeOuterGain_fx ); // Q14
     773             :     }
     774             : 
     775      917003 :     return DirGain_fx;
     776             : }
     777             : 
     778             : 
     779             : /*-------------------------------------------------------------------*
     780             :  * TDREND_SRC_SPATIAL_GetDistGain()
     781             :  *
     782             :  * Returns the gain due to distance.
     783             :  --------------------------------------------------------------------*/
     784             : 
     785             : /*! r: Gain value */
     786      917003 : static Word16 TDREND_SRC_SPATIAL_GetDistGain_fx(                                        /* o  : Distance gain                    Q14 */
     787             :                                                  const TDREND_DistAtten_t *DistAtten_p, /* i  : Distance attenuation parameters      */
     788             :                                                  const Word32 Dist_fx,                  /* i  : Distance value                Dist_e */
     789             :                                                  const Word16 Dist_e                    /* i  : Distance value exp                   */
     790             : )
     791             : {
     792             :     Word16 DistGain_fx; // Q14
     793             :     Word32 Dist2_fx;
     794             :     Word16 Dist2_e;
     795             :     Word16 tmp_e;
     796             :     Word32 tmp32;
     797             :     Word16 flag;
     798             : #ifdef CONF_DISTATT
     799             :     Word16 Dist_s;
     800             :     Word16 tmp16;
     801             : #else
     802             :     Word16 DistGain_e;
     803             : #endif
     804             : 
     805      917003 :     DistGain_fx = ONE_IN_Q14; // Q14
     806      917003 :     move16();
     807             : #ifndef CONF_DISTATT
     808             :     DistGain_e = 1;
     809             :     move16();
     810             : #endif
     811      917003 :     Dist2_fx = Dist_fx;
     812      917003 :     move32();
     813      917003 :     Dist2_e = Dist_e;
     814      917003 :     move16();
     815             : #ifdef CONF_DISTATT
     816      917003 :     tmp32 = 0;
     817      917003 :     move32();
     818      917003 :     tmp_e = 0;
     819      917003 :     move16();
     820             : #endif
     821             : 
     822      917003 :     SWITCH( DistAtten_p->DistAttenModel )
     823             :     {
     824           0 :         case TDREND_DIST_ATTEN_MODEL_INV_DIST:
     825             : #ifdef CONF_DISTATT
     826             :             /* DistGain = powf( DistAtten_p->RefDist / Dist2, DistAtten_p->RollOffFactor ); */
     827           0 :             tmp16 = BASOP_Util_Divide3232_Scale( DistAtten_p->RefDist_fx, Dist2_fx, &Dist_s ); /* tmp16 is Q(15 - Dist_s + Dist2_e - 1) */
     828           0 :             tmp32 = L_deposit_h( tmp16 );                                                      /* tmp32 is Q(31 - Dist_s + Dist2_e - 1) */
     829             :             /* tmp32 exponent: 31 - (31 - Dist_s + Dist2_e - 1) = Dist_s - Dist2_e + 1, RollOffFactor_fx exponent: 31 - 30 = 1 */
     830           0 :             tmp32 = BASOP_Util_fPow( tmp32, add( sub( Dist_s, Dist2_e ), 1 ), DistAtten_p->RollOffFactor_fx, 1, &tmp_e ); /* Q(31 - tmp_e) */
     831             : #else
     832             :             tmp32 = BASOP_Util_Add_Mant32Exp( Dist2_fx, Dist2_e, L_negate( DistAtten_p->RefDist_fx ), 1, &tmp_e ); // exp: tmp_e
     833             :             tmp32 = Mpy_32_32( tmp32, DistAtten_p->RollOffFactor_fx );                                             // exp: 1 + tmp_e
     834             :             tmp32 = BASOP_Util_Add_Mant32Exp( DistAtten_p->RefDist_fx, 1, tmp32, add( 1, tmp_e ), &tmp_e );        // exp: tmp_e
     835             :             DistGain_fx = BASOP_Util_Divide3232_Scale( DistAtten_p->RefDist_fx, tmp32, &DistGain_e );              // exp: DistGain_e
     836             :             DistGain_e = add( DistGain_e, sub( 1, tmp_e ) );
     837             : #endif
     838           0 :             BREAK;
     839             : 
     840      917003 :         case TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED:
     841      917003 :             flag = BASOP_Util_Cmp_Mant32Exp( Dist2_fx, Dist2_e, DistAtten_p->RefDist_fx, 1 );
     842      917003 :             IF( flag < 0 )
     843             :             {
     844      509035 :                 Dist2_fx = DistAtten_p->RefDist_fx; // Q30
     845      509035 :                 move32();
     846      509035 :                 Dist2_e = 1;
     847      509035 :                 move16();
     848             :             }
     849      917003 :             flag = BASOP_Util_Cmp_Mant32Exp( Dist2_fx, Dist2_e, DistAtten_p->MaxDist_fx, 4 );
     850      917003 :             IF( flag > 0 )
     851             :             {
     852       10473 :                 Dist2_fx = DistAtten_p->MaxDist_fx; // Q27
     853       10473 :                 move32();
     854       10473 :                 Dist2_e = 4;
     855       10473 :                 move16();
     856             :             }
     857             : #ifdef CONF_DISTATT
     858             :             /* DistGain = powf( DistAtten_p->RefDist / Dist2, DistAtten_p->RollOffFactor ); */
     859      917003 :             tmp16 = BASOP_Util_Divide3232_Scale( DistAtten_p->RefDist_fx, Dist2_fx, &Dist_s ); /* tmp16 is Q(15 - Dist_s + Dist2_e - 1) */
     860      917003 :             tmp32 = L_deposit_h( tmp16 );                                                      /* tmp32 is Q(31 - Dist_s + Dist2_e - 1) */
     861             :             /* tmp32 exponent: 31 - (31 - Dist_s + Dist2_e - 1) = Dist_s - Dist2_e + 1, RollOffFactor_fx exponent: 31 - 30 = 1 */
     862      917003 :             tmp32 = BASOP_Util_fPow( tmp32, add( sub( Dist_s, Dist2_e ), 1 ), DistAtten_p->RollOffFactor_fx, 1, &tmp_e ); /* Q(31 - tmp_e) */
     863             : #else
     864             :             tmp32 = BASOP_Util_Add_Mant32Exp( Dist2_fx, Dist2_e, L_negate( DistAtten_p->RefDist_fx ), 1, &tmp_e ); // exp: tmp_e
     865             :             tmp32 = Mpy_32_32( tmp32, DistAtten_p->RollOffFactor_fx );                                             // exp: 1 + tmp_e
     866             :             tmp32 = BASOP_Util_Add_Mant32Exp( DistAtten_p->RefDist_fx, 1, tmp32, add( 1, tmp_e ), &tmp_e );        // exp: tmp_e
     867             :             DistGain_fx = BASOP_Util_Divide3232_Scale( DistAtten_p->RefDist_fx, tmp32, &DistGain_e );              // exp: DistGain_e
     868             :             DistGain_e = add( DistGain_e, sub( 1, tmp_e ) );
     869             : #endif
     870             : 
     871      917003 :             BREAK;
     872             :     }
     873             : 
     874             : #ifdef CONF_DISTATT
     875      917003 :     tmp16 = extract_h( L_shr( tmp32, sub( 1, tmp_e ) ) ); // Reducing it to Q14: Go to Q30 and extract_h. right shift by 31-tmp_e-30 = 1-tmp_e
     876      917003 :     IF( GT_16( tmp16, ONE_IN_Q14 ) )
     877             :     {
     878      512303 :         tmp16 = ONE_IN_Q14;
     879             :     }
     880             : 
     881      917003 :     DistGain_fx = tmp16;
     882             : #else
     883             :     DistGain_fx = shr( DistGain_fx, sub( 1, DistGain_e ) ); // Reducing it to Q14
     884             : #endif
     885             : 
     886      917003 :     return DistGain_fx;
     887             : }
     888             : 
     889             : /*-------------------------------------------------------------------*
     890             :  * TDREND_SRC_Alloc()
     891             :  *
     892             :  * Allocate a source.
     893             :  --------------------------------------------------------------------*/
     894        1639 : ivas_error TDREND_SRC_Alloc(
     895             :     TDREND_SRC_t **Src_pp /* i/o: Source          */
     896             : )
     897             : {
     898             :     ivas_error error;
     899             :     TDREND_SRC_t *Src_p;
     900             : 
     901        1639 :     error = IVAS_ERR_OK;
     902        1639 :     move32();
     903        1639 :     *Src_pp = NULL;
     904             : 
     905             :     /* Allocate the TDREND_SRC_t variable */
     906        1639 :     IF( ( Src_p = (TDREND_SRC_t *) malloc( sizeof( TDREND_SRC_t ) ) ) == NULL )
     907             :     {
     908           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, " TDREND_SRC_Alloc: Allocation error\n" ) );
     909             :     }
     910             : 
     911        1639 :     Src_p->SrcSpatial_p = NULL;
     912             :     /* If source type is dynamic alloc the TDREND_SRC_SPATIAL_t variable */
     913        1639 :     IF( NE_32( ( error = TDREND_SRC_SPATIAL_Alloc( &Src_p->SrcSpatial_p ) ), IVAS_ERR_OK ) )
     914             :     {
     915           0 :         return error;
     916             :     }
     917             : 
     918        1639 :     IF( NE_32( ( error = TDREND_SRC_REND_Alloc( &Src_p->SrcRend_p ) ), IVAS_ERR_OK ) )
     919             :     {
     920           0 :         return error;
     921             :     }
     922             : 
     923        1639 :     *Src_pp = Src_p;
     924             : 
     925        1639 :     return error;
     926             : }
     927             : 
     928             : /*-------------------------------------------------------------------*
     929             :  * TDREND_SRC_Dealloc()
     930             :  *
     931             :  * Deallocate a source.
     932             :  --------------------------------------------------------------------*/
     933             : 
     934        1639 : void TDREND_SRC_Dealloc(
     935             :     TDREND_SRC_t *Src_p )
     936             : {
     937        1639 :     IF( Src_p == NULL )
     938             :     {
     939           0 :         return;
     940             :     }
     941             :     /* Delloc the TDREND_SRC_Spatial_t variable */
     942        1639 :     TDREND_SRC_SPATIAL_Dealloc( Src_p->SrcSpatial_p );
     943             :     /* Delloc the TDREND_SRC_REND__t variable */
     944        1639 :     free( Src_p->SrcRend_p );
     945        1639 :     Src_p->SrcRend_p = NULL;
     946             :     /* Free the Src_p variable */
     947        1639 :     free( Src_p );
     948        1639 :     Src_p = NULL;
     949        1639 :     return;
     950             : }
     951             : /*-------------------------------------------------------------------*
     952             :  * TDREND_SRC_Init()
     953             :  *
     954             :  * Initializes a source.
     955             :  --------------------------------------------------------------------*/
     956        1639 : void TDREND_SRC_Init_fx(
     957             :     TDREND_SRC_t *Src_p,           /* i/o: Source to initialize    */
     958             :     const TDREND_PosType_t PosType /* i  : Position type specifier */
     959             : )
     960             : {
     961             :     /* Init the TDREND_SRC_Spatial_t variable */
     962        1639 :     IF( Src_p->SrcSpatial_p != NULL )
     963             :     {
     964        1639 :         TDREND_SRC_SPATIAL_Init_fx( Src_p->SrcSpatial_p, PosType );
     965             :     }
     966             : 
     967             :     /* Init the TDREND_SRC_REND_t variable */
     968        1639 :     TDREND_SRC_REND_Init_fx( Src_p->SrcRend_p );
     969             : 
     970             :     /* Reset memory buffers */
     971        1639 :     Src_p->itd = 0; // Q0
     972        1639 :     move16();
     973        1639 :     Src_p->previtd = 0; // Q0
     974        1639 :     move16();
     975        1639 :     Src_p->filterlength = 1; /* Init to unit impulse of length 1 */ // Q0
     976        1639 :     move16();
     977        1639 :     set32_fx( Src_p->mem_itd_fx, 0, ITD_MEM_LEN );
     978        1639 :     set32_fx( Src_p->mem_hrf_left_fx, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 );
     979        1639 :     set32_fx( Src_p->mem_hrf_right_fx, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 );
     980             : 
     981        1639 :     set32_fx( Src_p->hrf_left_prev_fx, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH );
     982        1639 :     set32_fx( Src_p->hrf_right_prev_fx, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH );
     983        1639 :     Src_p->hrf_left_prev_fx[0] = ONE_IN_Q30; // Q30
     984        1639 :     move32();
     985        1639 :     Src_p->hrf_left_prev_e = 1;
     986        1639 :     move16();
     987        1639 :     Src_p->hrf_right_prev_fx[0] = ONE_IN_Q30; // Q30
     988        1639 :     move32();
     989        1639 :     Src_p->hrf_right_prev_e = 1;
     990        1639 :     move16();
     991        1639 :     Src_p->azim_prev_fx = 0; // Q22
     992        1639 :     move32();
     993        1639 :     Src_p->elev_prev_fx = 0; // Q22
     994        1639 :     move32();
     995        1639 :     Src_p->Gain_fx = ONE_IN_Q30; // Q30
     996        1639 :     move32();
     997        1639 :     Src_p->prevGain_fx = ONE_IN_Q30; // Q30
     998        1639 :     move32();
     999        1639 :     return;
    1000             : }

Generated by: LCOV version 1.14