LCOV - code coverage report
Current view: top level - lib_rend - ivas_objectRenderer_sources_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 357 381 93.7 %
Date: 2025-05-03 01:55:50 Functions: 16 16 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             : static ivas_error TDREND_SRC_REND_Alloc( TDREND_SRC_REND_t **SrcRend_pp );
      52             : static void TDREND_SRC_SPATIAL_Dealloc( TDREND_SRC_SPATIAL_t *SrcSpatial_p );
      53             : 
      54             : /*-------------------------------------------------------------------*
      55             :  * TDREND_MIX_SRC_SetPos()
      56             :  *
      57             :  * Set source position
      58             :  --------------------------------------------------------------------*/
      59             : 
      60      397828 : ivas_error TDREND_MIX_SRC_SetPos_fx(
      61             :     BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle  */
      62             :     const Word16 SrcInd,                               /* i  : Source index        */
      63             :     const Word32 *Vec_p                                /* i  : Position vector Q25 */
      64             : )
      65             : {
      66             :     TDREND_SRC_SPATIAL_t *SrcSpatial_p;
      67             : 
      68      397828 :     IF( GT_16( SrcInd, hBinRendererTd->MaxSrcInd ) )
      69             :     {
      70           0 :         return ( IVAS_ERROR( IVAS_ERR_INVALID_INDEX, "Index exceeds max index!\n" ) );
      71             :     }
      72             :     ELSE
      73             :     {
      74      397828 :         SrcSpatial_p = hBinRendererTd->Sources[SrcInd]->SrcSpatial_p;
      75      397828 :         SrcSpatial_p->Pos_p_fx[0] = L_shr( SrcSpatial_p->Pos_p_fx[0], sub( SrcSpatial_p->q_Pos_p, Q25 ) ); // Q25
      76      397828 :         move32();
      77      397828 :         SrcSpatial_p->Pos_p_fx[1] = L_shr( SrcSpatial_p->Pos_p_fx[1], sub( SrcSpatial_p->q_Pos_p, Q25 ) ); // Q25
      78      397828 :         move32();
      79      397828 :         SrcSpatial_p->Pos_p_fx[2] = L_shr( SrcSpatial_p->Pos_p_fx[2], sub( SrcSpatial_p->q_Pos_p, Q25 ) ); // Q25
      80      397828 :         move32();
      81      397828 :         SrcSpatial_p->q_Pos_p = Q25;
      82      397828 :         move16();
      83      397828 :         test();
      84      397828 :         test();
      85      397828 :         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] ) )
      86             :         {
      87      213574 :             Copy32( Vec_p, SrcSpatial_p->Pos_p_fx, 3 ); // Q25
      88      213574 :             SrcSpatial_p->Updated = TRUE;
      89      213574 :             move16();
      90             :         }
      91             :     }
      92             : 
      93      397828 :     return IVAS_ERR_OK;
      94             : }
      95             : 
      96             : 
      97             : /*-------------------------------------------------------------------*
      98             :  * TDREND_MIX_SRC_SetDir()
      99             :  *
     100             :  * Set source direction
     101             :  --------------------------------------------------------------------*/
     102      397000 : ivas_error TDREND_MIX_SRC_SetDir_fx(
     103             :     BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle         */
     104             :     const Word16 SrcInd,                               /* i  : Source index               */
     105             :     const Word32 *Vec_p,                               /* i  : Direction vector   Vec_p_q */
     106             :     const Word16 Vec_p_q                               /* i  : Direction vector q         */
     107             : )
     108             : {
     109             :     TDREND_SRC_SPATIAL_t *SrcSpatial_p;
     110             :     /* Value verification */
     111      397000 :     test();
     112      397000 :     test();
     113      397000 :     IF( EQ_32( Vec_p[0], 0 ) && EQ_32( Vec_p[1], 0 ) && EQ_32( Vec_p[2], 0 ) )
     114             :     {
     115           0 :         return ( IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Zero direction vector. Command is ignored!\n" ) );
     116             :     }
     117      397000 :     IF( GT_16( SrcInd, hBinRendererTd->MaxSrcInd ) )
     118             :     {
     119           0 :         return ( IVAS_ERROR( IVAS_ERR_INVALID_INDEX, "Index exceeds max index!\n" ) );
     120             :     }
     121             :     ELSE
     122             :     {
     123      397000 :         SrcSpatial_p = hBinRendererTd->Sources[SrcInd]->SrcSpatial_p;
     124      397000 :         TDREND_SPATIAL_VecNormalize_fx( Vec_p, Vec_p_q, SrcSpatial_p->Front_p_fx );
     125      397000 :         SrcSpatial_p->Updated = TRUE;
     126      397000 :         move16();
     127             :     }
     128      397000 :     return IVAS_ERR_OK;
     129             : }
     130             : 
     131             : 
     132             : /*-------------------------------------------------------------------*
     133             :  * TDREND_MIX_SRC_SetDirAtten()
     134             :  *
     135             :  * Set directional attenuation for the mixer.
     136             :  --------------------------------------------------------------------*/
     137      397722 : ivas_error TDREND_MIX_SRC_SetDirAtten_fx(
     138             :     BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle                */
     139             :     const Word16 SrcInd,                               /* i  : Source index                   Q0 */
     140             :     const TDREND_DirAtten_t *DirAtten_p                /* i  : Directional attenuation specifier */
     141             : )
     142             : {
     143             :     TDREND_SRC_SPATIAL_t *SrcSpatial_p;
     144      397722 :     IF( GT_16( SrcInd, hBinRendererTd->MaxSrcInd ) )
     145             :     {
     146           0 :         return ( IVAS_ERROR( IVAS_ERR_INVALID_INDEX, "Index exceeds max index\n" ) );
     147             :     }
     148             :     ELSE
     149             :     {
     150      397722 :         SrcSpatial_p = hBinRendererTd->Sources[SrcInd]->SrcSpatial_p;
     151      397722 :         TDREND_SRC_SPATIAL_SetDirAtten_fx( SrcSpatial_p, DirAtten_p );
     152             :     }
     153             : 
     154      397722 :     return IVAS_ERR_OK;
     155             : }
     156             : 
     157             : 
     158             : /*-------------------------------------------------------------------*
     159             :  * TDREND_MIX_SRC_SetPlayState()
     160             :  *
     161             :  * Set play state for the source.
     162             :  --------------------------------------------------------------------*/
     163             : 
     164         274 : ivas_error TDREND_MIX_SRC_SetPlayState(
     165             :     BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle  */
     166             :     const Word16 SrcInd,                               /* i  : Source index     Q0 */
     167             :     const TDREND_PlayStatus_t PlayStatus               /* i  : Play state          */
     168             : )
     169             : {
     170         274 :     IF( GT_16( SrcInd, hBinRendererTd->MaxSrcInd ) )
     171             :     {
     172           0 :         return ( IVAS_ERROR( IVAS_ERR_INVALID_INDEX, "Index exceeds max index\n" ) );
     173             :     }
     174             :     ELSE
     175             :     {
     176         274 :         hBinRendererTd->Sources[SrcInd]->SrcRend_p->PlayStatus = PlayStatus;
     177         274 :         move32();
     178             :     }
     179         274 :     return IVAS_ERR_OK;
     180             : }
     181             : 
     182             : /*-------------------------------------------------------------------*
     183             :  * TDREND_SRC_REND_Alloc()
     184             :  *
     185             :  * Renderer allocation
     186             :  --------------------------------------------------------------------*/
     187             : 
     188         996 : static ivas_error TDREND_SRC_REND_Alloc(
     189             :     TDREND_SRC_REND_t **SrcRend_pp /* i/o: Source object */
     190             : )
     191             : {
     192             :     TDREND_SRC_REND_t *SrcRend_p;
     193             : 
     194         996 :     *SrcRend_pp = NULL;
     195             : 
     196             :     /* Allocate the TDREND_SRC_REND_t variable */
     197         996 :     IF( ( SrcRend_p = (TDREND_SRC_REND_t *) malloc( sizeof( TDREND_SRC_REND_t ) ) ) == NULL )
     198             :     {
     199           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "SrcRend_p allocation error\n" ) );
     200             :     }
     201             : 
     202         996 :     *SrcRend_pp = SrcRend_p;
     203             : 
     204         996 :     return IVAS_ERR_OK;
     205             : }
     206             : 
     207             : 
     208             : /*-------------------------------------------------------------------*
     209             :  * TDREND_SRC_REND_Init()
     210             :  *
     211             :  * Initialize rendering aspects of source.
     212             :  --------------------------------------------------------------------*/
     213         996 : static void TDREND_SRC_REND_Init_fx(
     214             :     TDREND_SRC_REND_t *SrcRend_p /* i/o: Source object        */
     215             : )
     216             : {
     217             :     Word16 nC;
     218             :     /* Internal state */
     219         996 :     SrcRend_p->InputAvailable = FALSE;
     220         996 :     move16();
     221         996 :     SrcRend_p->PlayStatus = TDREND_PLAYSTATUS_PLAYING;
     222         996 :     move16();
     223             :     /* SrcGain  */
     224        1992 :     FOR( nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ )
     225             :     {
     226         996 :         SrcRend_p->SrcGainMin_p_fx[nC] = 0; /* Q15 */
     227         996 :         move16();
     228         996 :         SrcRend_p->SrcGain_p_fx[nC] = ONE_IN_Q14; // Q14
     229         996 :         move16();
     230         996 :         SrcRend_p->SrcGainMax_p_fx[nC] = 32767; /* Q15 */
     231         996 :         move16();
     232             :     }
     233         996 :     SrcRend_p->SrcGainUpdated = FALSE;
     234         996 :     move16();
     235             :     /* Init directional and distance gains */
     236        1992 :     FOR( nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ )
     237             :     {
     238         996 :         SrcRend_p->DirGain_p_fx[nC] = ONE_IN_Q14; // Q14
     239         996 :         move16();
     240         996 :         SrcRend_p->DistGain_p_fx[nC] = ONE_IN_Q14; // Q14
     241         996 :         move16();
     242             :     }
     243         996 :     return;
     244             : }
     245             : 
     246             : /*-------------------------------------------------------------------*
     247             :  * TDREND_SRC_REND_UpdateFiltersFromSpatialParams()
     248             :  *
     249             :  * Update the HR filter due to spatial change.
     250             :  --------------------------------------------------------------------*/
     251             : 
     252      903144 : void TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx(
     253             :     BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle                        */
     254             :     TDREND_SRC_REND_t *SrcRend_p,                      /* i/o: Source object                             */
     255             :     TDREND_SRC_SPATIAL_t *SrcSpatial_p,                /* i  : Spatial aspects of source                 */
     256             :     Word32 *hrf_left_prev,
     257             :     /* i/o: Left filter                               */ // exp(hrf_left_prev_e)
     258             :     Word16 *hrf_left_prev_e,
     259             :     /* i/o: Left filter exponent                      */ // Q0
     260             :     Word32 *hrf_right_prev,
     261             :     /* i/o: Right filter                              */ // exp(hrf_right_prev_e)
     262             :     Word16 *hrf_right_prev_e,
     263             :     /* i/o: Right filter exponent                     */ // Q0
     264             :     Word32 *hrf_left_delta,
     265             :     /* o  : Left filter interpolation delta           */ // exp(hrf_left_delta_e)
     266             :     Word16 *hrf_left_delta_e,
     267             :     /* o  : Left filter interpolation delta exponent  */ // Q0
     268             :     Word32 *hrf_right_delta,
     269             :     /* o  : Right filter interpolation delta          */ // exp(hrf_right_delta_e)
     270             :     Word16 *hrf_right_delta_e,
     271             :     /* o  : Right filter interpolation delta exponent */ // Q0
     272             :     Word16 *intp_count,
     273             :     /* o  : Interpolation count                       */ // Q0
     274             :     Word16 *filterlength,
     275             :     /* o  : Length of filters                         */ // Q0
     276             :     Word16 *itd,
     277             :     /* o  : ITD value                                 */ // Q0
     278             :     Word16 *Gain,
     279             :     /* o  : Gain value                                */ // Q14
     280             :     TDREND_SRC_t *Src_p,                                 /* i/o: Source pointer                            */
     281             :     const Word16 subframe_update_flag )
     282             : {
     283             :     TDREND_MIX_Listener_t *Listener_p;
     284             :     TDREND_HRFILT_FiltSet_t *HrFiltSet_p;
     285             :     Word32 ListRelPos[3];
     286             :     Word32 ListRelDist;
     287             :     Word32 ListRelPosAbs[3]; /* Relative position, ignoring orientation of listener */
     288             :     Word32 Azim, Elev;
     289             :     Word32 hrf_left[SFX_SPAT_BIN_MAX_FILTER_LENGTH];
     290             :     Word32 hrf_right[SFX_SPAT_BIN_MAX_FILTER_LENGTH];
     291             :     Word16 hrf_left_e, hrf_right_e;
     292             :     Word32 azim_delta;
     293             :     Word32 elev_delta;
     294             :     Word16 ListRelPos_e, ListRelDist_e;
     295             : 
     296             :     /* Evaluate the HR filters from the source and listener positions and orientations */
     297      903144 :     Listener_p = hBinRendererTd->Listener_p;
     298      903144 :     HrFiltSet_p = hBinRendererTd->HrFiltSet_p;
     299             : 
     300      903144 :     *filterlength = s_min( HrFiltSet_p->FiltLength, SFX_SPAT_BIN_MAX_FILTER_LENGTH ); // Q0
     301      903144 :     move16();
     302      903144 :     IF( EQ_16( SrcSpatial_p->PosType, TDREND_POSTYPE_ABSOLUTE ) )
     303             :     {
     304             : 
     305             :         /* Absolute position */
     306      902316 :         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 );
     307      902316 :         ListRelPos_e = 7; // output q of above function is Q25 + Q30 - 31. so exp will be 62 - Q25 - Q30.
     308      902316 :         move16();
     309      902316 :         ListRelDist = TDREND_SPATIAL_VecNorm_fx( ListRelPos, ListRelPos_e, &ListRelDist_e );
     310             : 
     311             :         /* 2. Evaluate the Elevation and Azimuth angles  */
     312      902316 :         test();
     313      902316 :         test();
     314      902316 :         IF( ( ListRelPos[0] == 0 ) && ( ListRelPos[1] == 0 ) && ( ListRelPos[2] == 0 ) )
     315             :         {
     316        1035 :             Elev = 0;
     317        1035 :             move32();
     318        1035 :             Azim = 0;
     319        1035 :             move32();
     320             :         }
     321             :         ELSE
     322             :         {
     323      901281 :             Word32 tmp1 = Mpy_32_32( ListRelPos[0], ListRelPos[0] ); // exp(2*ListRelPos_e)
     324      901281 :             Word32 tmp2 = Mpy_32_32( ListRelPos[1], ListRelPos[1] ); // exp(2*ListRelPos_e)
     325      901281 :             Word32 tmp3 = L_add( tmp1, tmp2 );                       // exp(2*ListRelPos_e)
     326      901281 :             Word16 tmp_e = shl( ListRelPos_e, 1 );
     327      901281 :             Word32 tmp4 = Sqrt32( tmp3, &tmp_e );                                              // exp(tmp_e)
     328      901281 :             Word16 tmp5 = BASOP_util_atan2( ListRelPos[2], tmp4, sub( ListRelPos_e, tmp_e ) ); // Q13
     329      901281 :             Word32 tmp6 = Mpy_32_16_1( _180_OVER_PI_Q25, tmp5 );                               // Q25 + Q13 - Q15 = Q23
     330             :             /* 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 */
     331      901281 :             Word16 tmp7 = BASOP_util_atan2( ListRelPos[1], ListRelPos[0], 0 ); // Q13
     332      901281 :             Word32 tmp8 = L_negate( Mpy_32_16_1( _180_OVER_PI_Q25, tmp7 ) );   // Q25 + Q13 - Q15 = Q23
     333             : 
     334      901281 :             Elev = L_shr( tmp6, 1 ); // Q22
     335      901281 :             Azim = L_shr( tmp8, 1 ); // Q22
     336             :         }
     337             : 
     338      902316 :         GetFilterFromAngle_fx( HrFiltSet_p, Elev, Azim, *filterlength, hrf_left, &hrf_left_e, hrf_right, &hrf_right_e, itd );
     339             : 
     340             :         /* 6. Evaluate the directional and distance gains */
     341             :         /* Directional gain */
     342      902316 :         *SrcRend_p->DirGain_p_fx = ONE_IN_Q14; // Q14
     343      902316 :         move16();
     344      902316 :         IF( SrcSpatial_p->DirAttenEnabled )
     345             :         {
     346      902316 :             *SrcRend_p->DirGain_p_fx = TDREND_SRC_SPATIAL_GetDirGain_fx( &SrcSpatial_p->DirAtten, SrcSpatial_p->Front_p_fx, ListRelPosAbs, 6 );
     347             :         }
     348             : 
     349             :         /* Distance gain */
     350      902316 :         *SrcRend_p->DistGain_p_fx = ONE_IN_Q14; // Q14
     351      902316 :         move16();
     352      902316 :         IF( hBinRendererTd->UseCommonDistAttenModel )
     353             :         {
     354      902316 :             IF( hBinRendererTd->DistAttenEnabled )
     355             :             {
     356      902316 :                 SrcSpatial_p->DistAtten.DistAttenModel = hBinRendererTd->DistAttenModel;
     357      902316 :                 move32();
     358      902316 :                 *SrcRend_p->DistGain_p_fx = TDREND_SRC_SPATIAL_GetDistGain_fx( &SrcSpatial_p->DistAtten, ListRelDist, ListRelDist_e ); // Q14
     359      902316 :                 move32();
     360             :             }
     361             :         }
     362           0 :         ELSE IF( SrcSpatial_p->DistAttenEnabled )
     363             :         {
     364             : 
     365           0 :             *SrcRend_p->DistGain_p_fx = TDREND_SRC_SPATIAL_GetDistGain_fx( &SrcSpatial_p->DistAtten, ListRelDist, ListRelDist_e ); // Q14
     366           0 :             move32();
     367             :         }
     368             : 
     369             : 
     370             :         /* Update total gains */
     371      902316 :         *Gain = extract_h( 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 ) ); // Q14
     372      902316 :         move16();
     373             :         /* Delta for interpolation, in case the angular step exceeds MAX_ANGULAR_STEP */
     374      902316 :         Word32 ele_tmp = Src_p->elev_prev_fx; // Q22
     375      902316 :         move32();
     376      902316 :         IF( GT_32( ele_tmp, DEG_180_IN_Q22 ) )
     377             :         {
     378           0 :             ele_tmp = L_sub( ele_tmp, DEG_360_IN_Q22 ); // Q22
     379             :         }
     380      902316 :         ELSE IF( LT_32( ele_tmp, -DEG_180_IN_Q22 ) )
     381             :         {
     382           0 :             ele_tmp = L_add( ele_tmp, DEG_360_IN_Q22 ); // Q22
     383             :         }
     384      902316 :         elev_delta = L_sub( Elev, ele_tmp ); // Q22
     385             : 
     386      902316 :         Word32 azi_tmp = Src_p->azim_prev_fx; // Q22
     387      902316 :         IF( GT_32( azi_tmp, DEG_180_IN_Q22 ) )
     388             :         {
     389           3 :             azi_tmp = L_sub( azi_tmp, DEG_360_IN_Q22 ); // Q22
     390             :         }
     391      902313 :         ELSE IF( LT_32( azi_tmp, -DEG_180_IN_Q22 ) )
     392             :         {
     393         312 :             azi_tmp = L_add( azi_tmp, DEG_360_IN_Q22 ); // Q22
     394             :         }
     395      902316 :         azim_delta = L_sub( Azim, azi_tmp ); // Q22
     396             : 
     397      902316 :         Src_p->elev_prev_fx = Elev; // Q22
     398      902316 :         move32();
     399      902316 :         Src_p->azim_prev_fx = Azim; // Q22
     400      902316 :         move32();
     401             : 
     402             :         /* map to -180:180 range */
     403      902316 :         IF( GT_32( azim_delta, DEG_180_IN_Q22 ) )
     404             :         {
     405       19969 :             azim_delta = L_sub( azim_delta, DEG_360_IN_Q22 ); // Q22
     406             :         }
     407      882347 :         ELSE IF( LT_32( azim_delta, -DEG_180_IN_Q22 ) )
     408             :         {
     409        2633 :             azim_delta = L_add( azim_delta, DEG_360_IN_Q22 ); // Q22
     410             :         }
     411      902316 :         Word16 tmp1 = extract_l( Mpy_32_32( L_abs( azim_delta ), 100 << Q9 ) ); // Q22 + Q9 - Q31 = Q0
     412      902316 :         Word16 tmp2 = extract_l( Mpy_32_32( L_abs( elev_delta ), 100 << Q9 ) ); // Q22 + Q9 - Q31 = Q0
     413      902316 :         *intp_count = s_min( MAX_INTERPOLATION_STEPS, s_max( tmp1, tmp2 ) );    // Q0
     414      902316 :         move16();
     415             :     }
     416             :     ELSE /* TDREND_POSTYPE_NON_DIEGETIC */
     417             :     {
     418         828 :         *itd = 0; // Q0
     419         828 :         move16();
     420         828 :         *Gain = ONE_IN_Q14; // Q14
     421         828 :         move16();
     422         828 :         set32_fx( hrf_left, 0, *filterlength );
     423         828 :         set32_fx( hrf_right, 0, *filterlength );
     424         828 :         hrf_left[0] = L_shr( L_add( SrcSpatial_p->Pos_p_fx[1], ONE_IN_Q25 ), 1 ); // Q25
     425         828 :         move32();
     426         828 :         hrf_right[0] = L_sub( ONE_IN_Q25, hrf_left[0] ); // Q25
     427         828 :         move32();
     428         828 :         hrf_left_e = 6;
     429         828 :         move16();
     430         828 :         hrf_right_e = 6;
     431         828 :         move16();
     432         828 :         *intp_count = MAX_INTERPOLATION_STEPS; // Q22
     433         828 :         move16();
     434         828 :         Src_p->elev_prev_fx = 0; // Q22
     435         828 :         move16();
     436         828 :         Src_p->azim_prev_fx = DEG_360_IN_Q22; /* Dummy angle -- sets max interpolation if switching to TDREND_POSTYPE_ABSOLUTE */ // Q22
     437         828 :         move16();
     438             :     }
     439             : 
     440      903144 :     test();
     441      903144 :     IF( ( *intp_count > 0 ) && subframe_update_flag )
     442      465483 :     {
     443             :         /* Set deltas for interpolation */
     444             :         Word16 tmp_e;
     445      465483 :         tmp_e = s_max( *hrf_left_prev_e, hrf_left_e );
     446    59382349 :         FOR( Word16 i = 0; i < *filterlength; i++ )
     447             :         {
     448    58916866 :             hrf_left[i] = L_shr( hrf_left[i], sub( tmp_e, hrf_left_e ) ); // exp(tmp_e)
     449    58916866 :             move32();
     450    58916866 :             hrf_left_prev[i] = L_shr( hrf_left_prev[i], sub( tmp_e, *hrf_left_prev_e ) ); // exp(tmp_e)
     451    58916866 :             move32();
     452             :         }
     453      465483 :         *hrf_left_prev_e = tmp_e;
     454      465483 :         move16();
     455      465483 :         hrf_left_e = tmp_e;
     456      465483 :         move16();
     457      465483 :         v_sub_32( hrf_left, hrf_left_prev, hrf_left_delta, *filterlength ); // exp(tmp_e)
     458      465483 :         *hrf_left_delta_e = tmp_e;
     459      465483 :         move16();
     460             : 
     461      465483 :         Word32 fac = L_deposit_h( div_s( 1, *intp_count ) );                 // Q15
     462      465483 :         v_multc_fixed( hrf_left_delta, fac, hrf_left_delta, *filterlength ); // exp(hrf_left_delta_e)
     463             : 
     464      465483 :         tmp_e = s_max( *hrf_right_prev_e, hrf_right_e );
     465    59382349 :         FOR( Word16 i = 0; i < *filterlength; i++ )
     466             :         {
     467    58916866 :             hrf_right[i] = L_shr( hrf_right[i], sub( tmp_e, hrf_right_e ) ); // exp(tmp_e)
     468    58916866 :             move32();
     469    58916866 :             hrf_right_prev[i] = L_shr( hrf_right_prev[i], sub( tmp_e, *hrf_right_prev_e ) ); // exp(tmp_e)
     470    58916866 :             move32();
     471             :         }
     472      465483 :         *hrf_right_prev_e = tmp_e;
     473      465483 :         move16();
     474      465483 :         hrf_right_e = tmp_e;
     475      465483 :         move16();
     476      465483 :         v_sub_32( hrf_right, hrf_right_prev, hrf_right_delta, *filterlength ); // exp(hrf_right_delta_e)
     477      465483 :         *hrf_right_delta_e = tmp_e;
     478      465483 :         move16();
     479             : 
     480      465483 :         v_multc_fixed( hrf_right_delta, fac, hrf_right_delta, *filterlength ); // exp(hrf_right_delta_e)
     481             :     }
     482             :     ELSE
     483             :     {
     484             :         /* No interpolation, just set the new filters and reset deltas */
     485      437661 :         Copy32( hrf_left, hrf_left_prev, *filterlength ); // exp(hrf_left_prev_e)
     486      437661 :         *hrf_left_prev_e = hrf_left_e;
     487      437661 :         move16();
     488      437661 :         Copy32( hrf_right, hrf_right_prev, *filterlength ); // exp(hrf_right_prev_e)
     489      437661 :         *hrf_right_prev_e = hrf_right_e;
     490      437661 :         move16();
     491      437661 :         set32_fx( hrf_left_delta, 0, *filterlength );
     492      437661 :         set32_fx( hrf_right_delta, 0, *filterlength );
     493      437661 :         *hrf_left_delta_e = 0;
     494      437661 :         move16();
     495      437661 :         *hrf_right_delta_e = 0;
     496      437661 :         move16();
     497             :     }
     498             : 
     499      903144 :     return;
     500             : }
     501             : 
     502             : /*-------------------------------------------------------------------*
     503             :  * TDREND_SRC_SPATIAL_Alloc()
     504             :  *
     505             :  * Allocatie spatial properties of a source.
     506             :  --------------------------------------------------------------------*/
     507             : 
     508         996 : static ivas_error TDREND_SRC_SPATIAL_Alloc(
     509             :     TDREND_SRC_SPATIAL_t **SrcSpatial_pp /* i/o: Source spatial parameters */
     510             : )
     511             : {
     512             :     TDREND_SRC_SPATIAL_t *SrcSpatial_p;
     513             : 
     514         996 :     *SrcSpatial_pp = NULL;
     515             : 
     516             :     /* Allocate the TDREND_SRC_t variable */
     517         996 :     IF( ( SrcSpatial_p = (TDREND_SRC_SPATIAL_t *) malloc( sizeof( TDREND_SRC_SPATIAL_t ) ) ) == NULL )
     518             :     {
     519           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "TDREND_SRC_SPATIAL_t allocation error\n" ) );
     520             :     }
     521             : 
     522         996 :     *SrcSpatial_pp = SrcSpatial_p;
     523             : 
     524         996 :     return IVAS_ERR_OK;
     525             : }
     526             : 
     527             : 
     528             : /*-------------------------------------------------------------------*
     529             :  * TDREND_SRC_SPATIAL_Dealloc()
     530             :  *
     531             :  * Deallocate spatial properties of a source.
     532             :  --------------------------------------------------------------------*/
     533             : 
     534         996 : static void TDREND_SRC_SPATIAL_Dealloc(
     535             :     TDREND_SRC_SPATIAL_t *SrcSpatial_p /* i/o: Source spatial parameters */
     536             : )
     537             : {
     538         996 :     IF( SrcSpatial_p == NULL )
     539             :     {
     540           0 :         return;
     541             :     }
     542             :     /* Free the SrcSpatial_p variable */
     543         996 :     free( SrcSpatial_p );
     544         996 :     SrcSpatial_p = NULL;
     545         996 :     return;
     546             : }
     547             : 
     548             : /*-------------------------------------------------------------------*
     549             :  * TDREND_SRC_SPATIAL_Init()
     550             :  *
     551             :  * Initialize spatial properties of a source.
     552             :  --------------------------------------------------------------------*/
     553         996 : static void TDREND_SRC_SPATIAL_Init_fx(
     554             :     TDREND_SRC_SPATIAL_t *SrcSpatial_p, /* i/o: Source spatial parameters       */
     555             :     const TDREND_PosType_t PosType      /* i  : Relative/absolute position type */
     556             : )
     557             : {
     558             :     Word16 nC; // Q0
     559             : 
     560             :     /* Initialize variables */
     561         996 :     SrcSpatial_p->Updated = FALSE;
     562             : 
     563         996 :     move16();
     564             :     /* Source position, velocity and direction vectors */
     565         996 :     SrcSpatial_p->PosType = PosType;
     566         996 :     move32();
     567        1992 :     FOR( nC = 0; nC < SPAT_BIN_MAX_INPUT_CHANNELS; nC++ )
     568             :     {
     569             :         /* Source position */
     570         996 :         TDREND_SPATIAL_VecInit_fx( SrcSpatial_p->Pos_p_fx + nC * 3, 0, 0, 0 ); /*Assuming Q31*/
     571             : 
     572             :         /* Source direction */
     573         996 :         TDREND_SPATIAL_VecInit_fx( SrcSpatial_p->Front_p_fx + nC * 3, 0, 0, ONE_IN_Q30 ); /*Assuming Q30*/
     574             :     }
     575             : 
     576         996 :     SrcSpatial_p->q_Pos_p = Q31;
     577         996 :     move16();
     578             : 
     579             :     /* Source directional attenuation */
     580         996 :     SrcSpatial_p->DirAttenEnabled = FALSE; // Q0
     581         996 :     move16();
     582         996 :     SrcSpatial_p->DirAtten.ConeInnerAngle_fx = DEG_360_IN_Q22; // Q22
     583         996 :     move32();
     584         996 :     SrcSpatial_p->DirAtten.ConeOuterAngle_fx = DEG_360_IN_Q22; // Q22
     585         996 :     move32();
     586         996 :     SrcSpatial_p->DirAtten.ConeOuterGain_fx = ONE_IN_Q30; // Q30
     587         996 :     move16();
     588             : 
     589             :     /* Source distance attenuation */
     590         996 :     SrcSpatial_p->DistAttenEnabled = FALSE; // Q0
     591         996 :     move16();
     592         996 :     SrcSpatial_p->DistAtten.DistAttenModel = TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED; // Q0
     593         996 :     move16();
     594         996 :     SrcSpatial_p->DistAtten.RefDist_fx = ONE_IN_Q30; // Q30
     595         996 :     move32();
     596         996 :     SrcSpatial_p->DistAtten.MaxDist_fx = 2113929216; /* Maximum radius (2^ISM_RADIUS_NBITS-1)*0.25 */ /*15.75 in Q27*/
     597         996 :     move32();
     598         996 :     SrcSpatial_p->DistAtten.RollOffFactor_fx = ONE_IN_Q30; // Q30
     599         996 :     move16();
     600             : 
     601         996 :     return;
     602             : }
     603             : 
     604             : /*-------------------------------------------------------------------*
     605             :  * TDREND_SRC_SPATIAL_SetDirAtten()
     606             :  *
     607             :  * Sets the directional attenuation mode.
     608             :  --------------------------------------------------------------------*/
     609             : 
     610      397722 : static void TDREND_SRC_SPATIAL_SetDirAtten_fx(
     611             :     TDREND_SRC_SPATIAL_t *SrcSpatial_p, /* i/o: Source spatial parameters    */
     612             :     const TDREND_DirAtten_t *DirAtten_p /* i  : Directionality specification */
     613             : )
     614             : {
     615             :     /* Set directional attenuation */
     616      397722 :     SrcSpatial_p->DirAttenEnabled = TRUE;                                     // Q0
     617      397722 :     SrcSpatial_p->DirAtten.ConeInnerAngle_fx = DirAtten_p->ConeInnerAngle_fx; // Q22
     618      397722 :     SrcSpatial_p->DirAtten.ConeOuterAngle_fx = DirAtten_p->ConeOuterAngle_fx; // Q22
     619      397722 :     SrcSpatial_p->DirAtten.ConeOuterGain_fx = DirAtten_p->ConeOuterGain_fx;   // Q30
     620      397722 :     move16();
     621      397722 :     move16();
     622      397722 :     move16();
     623      397722 :     move16();
     624      397722 :     return;
     625             : }
     626             : 
     627             : /*-------------------------------------------------------------------*
     628             :  * TDREND_SRC_SPATIAL_GetDirGain()
     629             :  *
     630             :  * Returns the gain due to object orientation.
     631             :  --------------------------------------------------------------------*/
     632             : 
     633             : /*! r: Gain value */
     634      902316 : static Word16 TDREND_SRC_SPATIAL_GetDirGain_fx(                                      /* o  : Directional Gain Output               Q14 */
     635             :                                                 const TDREND_DirAtten_t *DirAtten_p, /* i  : Directional attenuation specification     */
     636             :                                                 const Word32 *Front_p_fx,            /* i  : Front-pointing vector                 Q30 */
     637             :                                                 const Word32 *RelPos_p_fx,           /* i  : Relative position                         */
     638             :                                                 const Word16 RelPos_p_e              /* i  : Relative position exp          RelPos_p_e */
     639             : )
     640             : {
     641             :     Word16 DirGain_fx; // Q14
     642             :     Word32 Vec_fx[3];
     643             :     Word32 ProjCoef_fx;
     644             :     Word16 ProjCoef_e;
     645             :     Word32 NormRelPos_fx;
     646             :     Word16 NormRelPos_e;
     647             :     Word32 AngleDeg_fx; // Q22
     648             : 
     649      902316 :     DirGain_fx = ONE_IN_Q14;
     650      902316 :     move16();
     651             : 
     652             :     /* Note that the front vector is unit norm, thus */
     653             :     /* Angle = acos ( Proj coeff from projecting -RelPos onto Front / norm(RelPos) ); */
     654     3609264 :     FOR( Word16 i = 0; i < 3; i++ )
     655             :     {
     656     2706948 :         Vec_fx[i] = L_negate( RelPos_p_fx[i] ); // exp(RelPos_p_e)
     657     2706948 :         move32();
     658             :     }
     659      902316 :     ProjCoef_fx = dotp_fixed( Vec_fx, Front_p_fx, 3 ); // exp: RelPos_p_e + 1
     660      902316 :     ProjCoef_e = add( RelPos_p_e, 1 );
     661      902316 :     NormRelPos_fx = TDREND_SPATIAL_VecNorm_fx( RelPos_p_fx, RelPos_p_e, &NormRelPos_e ); // exp(NormRelPos_e)
     662             : 
     663      902316 :     IF( NormRelPos_fx != 0 )
     664             :     {
     665             :         // AngleDeg = _180_OVER_PI * acosf( ProjCoef / NormRelPos );
     666             : 
     667             :         Word16 tmp_e1, tmp_e2, tmp_e3, tmp_e4, acosfx;
     668             :         Word32 tmp1, tmp2, tmp3, tmp4;
     669             : 
     670             :         // acos(x/y) = atan( sqrt(1-(x/y)^2) / (x/y) )
     671      901281 :         tmp1 = L_deposit_h( BASOP_Util_Divide3232_Scale( ProjCoef_fx, NormRelPos_fx, &tmp_e1 ) ); // x/y /* exp(tmp_e1) */
     672      901281 :         tmp_e1 = add( tmp_e1, sub( ProjCoef_e, NormRelPos_e ) );
     673      901281 :         tmp2 = Mpy_32_32( tmp1, tmp1 ); // (x/y)^2 /* exp(tmp_e2 */
     674      901281 :         tmp_e2 = shl( tmp_e1, 1 );
     675      901281 :         tmp3 = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30, 1, L_negate( tmp2 ), tmp_e2, &tmp_e3 ); // 1 - (x/y)^2 /* exp(tmp_e3) */
     676      901281 :         tmp_e4 = tmp_e3;
     677      901281 :         move16();
     678      901281 :         tmp3 = L_abs( tmp3 );                                              // for safety: sometimes it can go negative due to slight precision difference between numerator and denominator.
     679      901281 :         tmp4 = Sqrt32( tmp3, &tmp_e4 );                                    // sqrt(1 - (x/y)^2) /* exp(tmp_e4) */
     680      901281 :         acosfx = BASOP_util_atan2( tmp4, tmp1, sub( tmp_e4, tmp_e1 ) );    // 2Q13
     681      901281 :         AngleDeg_fx = L_shr( Mpy_32_16_1( _180_OVER_PI_Q25, acosfx ), 1 ); // Q22
     682             :     }
     683             :     ELSE
     684             :     {
     685        1035 :         AngleDeg_fx = 0;
     686        1035 :         move32();
     687             :     }
     688             : 
     689      902316 :     IF( LE_32( AngleDeg_fx, L_shr( DirAtten_p->ConeInnerAngle_fx, 1 ) ) )
     690             :     {
     691      865410 :         DirGain_fx = ONE_IN_Q14; // Q14
     692      865410 :         move16();
     693             :     }
     694       36906 :     ELSE IF( LE_32( AngleDeg_fx, L_shr( DirAtten_p->ConeOuterAngle_fx, 1 ) ) )
     695             :     {
     696             :         // DirGain = 1.0f - ( 2.0f * AngleDeg - DirAtten_p->ConeInnerAngle ) / ( DirAtten_p->ConeOuterAngle - DirAtten_p->ConeInnerAngle ) * ( 1.0f - DirAtten_p->ConeOuterGain );
     697             :         Word32 tmp1, tmp2, tmp3;
     698       30560 :         tmp1 = L_sub( ONE_IN_Q30, DirAtten_p->ConeOuterGain_fx );                                     // Q30
     699       30560 :         tmp2 = L_sub( DirAtten_p->ConeOuterAngle_fx, DirAtten_p->ConeInnerAngle_fx );                 // Q22
     700       30560 :         tmp3 = L_sub( L_shl( AngleDeg_fx, 1 ) /* 2.0f * AngleDeg */, DirAtten_p->ConeInnerAngle_fx ); // Q22
     701       30560 :         DirGain_fx = sub( ONE_IN_Q14, div_l( Mpy_32_32( tmp1, tmp3 ), extract_h( tmp2 ) ) );          // Q14
     702             :     }
     703             :     ELSE
     704             :     {
     705        6346 :         DirGain_fx = extract_h( DirAtten_p->ConeOuterGain_fx ); // Q14
     706             :     }
     707             : 
     708      902316 :     return DirGain_fx;
     709             : }
     710             : 
     711             : 
     712             : /*-------------------------------------------------------------------*
     713             :  * TDREND_SRC_SPATIAL_GetDistGain()
     714             :  *
     715             :  * Returns the gain due to distance.
     716             :  --------------------------------------------------------------------*/
     717             : 
     718             : /*! r: Gain value */
     719      902316 : static Word16 TDREND_SRC_SPATIAL_GetDistGain_fx(                                        /* o  : Distance gain                    Q14 */
     720             :                                                  const TDREND_DistAtten_t *DistAtten_p, /* i  : Distance attenuation parameters      */
     721             :                                                  const Word32 Dist_fx,                  /* i  : Distance value                Dist_e */
     722             :                                                  const Word16 Dist_e                    /* i  : Distance value exp                   */
     723             : )
     724             : {
     725             :     Word16 DistGain_fx; // Q14
     726             :     Word32 Dist2_fx;
     727             :     Word16 Dist2_e;
     728             :     Word16 tmp_e;
     729             :     Word16 DistGain_e;
     730             :     Word32 tmp32;
     731             :     Word16 flag;
     732             : 
     733      902316 :     DistGain_fx = ONE_IN_Q14; // Q14
     734      902316 :     move16();
     735      902316 :     DistGain_e = 1;
     736      902316 :     move16();
     737      902316 :     Dist2_fx = Dist_fx;
     738      902316 :     move32();
     739      902316 :     Dist2_e = Dist_e;
     740      902316 :     move16();
     741             : 
     742      902316 :     SWITCH( DistAtten_p->DistAttenModel )
     743             :     {
     744           0 :         case TDREND_DIST_ATTEN_MODEL_INV_DIST:
     745           0 :             tmp32 = BASOP_Util_Add_Mant32Exp( Dist2_fx, Dist2_e, L_negate( DistAtten_p->RefDist_fx ), 1, &tmp_e ); // exp: tmp_e
     746           0 :             tmp32 = Mpy_32_32( tmp32, DistAtten_p->RollOffFactor_fx );                                             // exp: 1 + tmp_e
     747           0 :             tmp32 = BASOP_Util_Add_Mant32Exp( DistAtten_p->RefDist_fx, 1, tmp32, add( 1, tmp_e ), &tmp_e );        // exp: tmp_e
     748           0 :             DistGain_fx = BASOP_Util_Divide3232_Scale( DistAtten_p->RefDist_fx, tmp32, &DistGain_e );              // exp: DistGain_e
     749           0 :             DistGain_e = add( DistGain_e, sub( 1, tmp_e ) );
     750           0 :             BREAK;
     751             : 
     752      902316 :         case TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED:
     753      902316 :             flag = BASOP_Util_Cmp_Mant32Exp( Dist2_fx, Dist2_e, DistAtten_p->RefDist_fx, 1 );
     754      902316 :             IF( flag < 0 )
     755             :             {
     756      498114 :                 Dist2_fx = DistAtten_p->RefDist_fx; // Q30
     757      498114 :                 move32();
     758      498114 :                 Dist2_e = 1;
     759      498114 :                 move16();
     760             :             }
     761      902316 :             flag = BASOP_Util_Cmp_Mant32Exp( Dist2_fx, Dist2_e, DistAtten_p->MaxDist_fx, 4 );
     762      902316 :             IF( flag > 0 )
     763             :             {
     764       10468 :                 Dist2_fx = DistAtten_p->MaxDist_fx; // Q27
     765       10468 :                 move32();
     766       10468 :                 Dist2_e = 4;
     767       10468 :                 move16();
     768             :             }
     769      902316 :             tmp32 = BASOP_Util_Add_Mant32Exp( Dist2_fx, Dist2_e, L_negate( DistAtten_p->RefDist_fx ), 1, &tmp_e ); // exp: tmp_e
     770      902316 :             tmp32 = Mpy_32_32( tmp32, DistAtten_p->RollOffFactor_fx );                                             // exp: 1 + tmp_e
     771      902316 :             tmp32 = BASOP_Util_Add_Mant32Exp( DistAtten_p->RefDist_fx, 1, tmp32, add( 1, tmp_e ), &tmp_e );        // exp: tmp_e
     772      902316 :             DistGain_fx = BASOP_Util_Divide3232_Scale( DistAtten_p->RefDist_fx, tmp32, &DistGain_e );              // exp: DistGain_e
     773      902316 :             DistGain_e = add( DistGain_e, sub( 1, tmp_e ) );
     774             : 
     775      902316 :             BREAK;
     776             :     }
     777             : 
     778      902316 :     DistGain_fx = shr( DistGain_fx, sub( 1, DistGain_e ) ); // Reducing it to Q14
     779             : 
     780      902316 :     return DistGain_fx;
     781             : }
     782             : 
     783             : /*-------------------------------------------------------------------*
     784             :  * TDREND_SRC_Alloc()
     785             :  *
     786             :  * Allocate a source.
     787             :  --------------------------------------------------------------------*/
     788         996 : ivas_error TDREND_SRC_Alloc(
     789             :     TDREND_SRC_t **Src_pp /* i/o: Source          */
     790             : )
     791             : {
     792             :     ivas_error error;
     793             :     TDREND_SRC_t *Src_p;
     794             : 
     795         996 :     error = IVAS_ERR_OK;
     796         996 :     move32();
     797         996 :     *Src_pp = NULL;
     798             : 
     799             :     /* Allocate the TDREND_SRC_t variable */
     800         996 :     IF( ( Src_p = (TDREND_SRC_t *) malloc( sizeof( TDREND_SRC_t ) ) ) == NULL )
     801             :     {
     802           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, " TDREND_SRC_Alloc: Allocation error\n" ) );
     803             :     }
     804             : 
     805         996 :     Src_p->SrcSpatial_p = NULL;
     806             :     /* If source type is dynamic alloc the TDREND_SRC_SPATIAL_t variable */
     807         996 :     IF( NE_32( ( error = TDREND_SRC_SPATIAL_Alloc( &Src_p->SrcSpatial_p ) ), IVAS_ERR_OK ) )
     808             :     {
     809           0 :         return error;
     810             :     }
     811             : 
     812         996 :     IF( NE_32( ( error = TDREND_SRC_REND_Alloc( &Src_p->SrcRend_p ) ), IVAS_ERR_OK ) )
     813             :     {
     814           0 :         return error;
     815             :     }
     816             : 
     817         996 :     *Src_pp = Src_p;
     818             : 
     819         996 :     return error;
     820             : }
     821             : 
     822             : /*-------------------------------------------------------------------*
     823             :  * TDREND_SRC_Dealloc()
     824             :  *
     825             :  * Deallocate a source.
     826             :  --------------------------------------------------------------------*/
     827             : 
     828         996 : void TDREND_SRC_Dealloc(
     829             :     TDREND_SRC_t *Src_p )
     830             : {
     831         996 :     IF( Src_p == NULL )
     832             :     {
     833           0 :         return;
     834             :     }
     835             :     /* Delloc the TDREND_SRC_Spatial_t variable */
     836         996 :     TDREND_SRC_SPATIAL_Dealloc( Src_p->SrcSpatial_p );
     837             :     /* Delloc the TDREND_SRC_REND__t variable */
     838         996 :     free( Src_p->SrcRend_p );
     839         996 :     Src_p->SrcRend_p = NULL;
     840             :     /* Free the Src_p variable */
     841         996 :     free( Src_p );
     842         996 :     Src_p = NULL;
     843         996 :     return;
     844             : }
     845             : /*-------------------------------------------------------------------*
     846             :  * TDREND_SRC_Init()
     847             :  *
     848             :  * Initializes a source.
     849             :  --------------------------------------------------------------------*/
     850         996 : void TDREND_SRC_Init_fx(
     851             :     TDREND_SRC_t *Src_p,           /* i/o: Source to initialize    */
     852             :     const TDREND_PosType_t PosType /* i  : Position type specifier */
     853             : )
     854             : {
     855             :     /* Init the TDREND_SRC_Spatial_t variable */
     856         996 :     IF( Src_p->SrcSpatial_p != NULL )
     857             :     {
     858         996 :         TDREND_SRC_SPATIAL_Init_fx( Src_p->SrcSpatial_p, PosType );
     859             :     }
     860             : 
     861             :     /* Init the TDREND_SRC_REND_t variable */
     862         996 :     TDREND_SRC_REND_Init_fx( Src_p->SrcRend_p );
     863             : 
     864             :     /* Reset memory buffers */
     865         996 :     Src_p->itd = 0; // Q0
     866         996 :     move16();
     867         996 :     Src_p->previtd = 0; // Q0
     868         996 :     move16();
     869         996 :     Src_p->filterlength = 1; /* Init to unit impulse of length 1 */ // Q0
     870         996 :     move16();
     871         996 :     set32_fx( Src_p->mem_itd_fx, 0, ITD_MEM_LEN );
     872         996 :     set32_fx( Src_p->mem_hrf_left_fx, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 );
     873         996 :     set32_fx( Src_p->mem_hrf_right_fx, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH - 1 );
     874             : 
     875         996 :     set32_fx( Src_p->hrf_left_prev_fx, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH );
     876         996 :     set32_fx( Src_p->hrf_right_prev_fx, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH );
     877         996 :     Src_p->hrf_left_prev_fx[0] = ONE_IN_Q30; // Q30
     878         996 :     move32();
     879         996 :     Src_p->hrf_left_prev_e = 1;
     880         996 :     move16();
     881         996 :     Src_p->hrf_right_prev_fx[0] = ONE_IN_Q30; // Q30
     882         996 :     move32();
     883         996 :     Src_p->hrf_right_prev_e = 1;
     884         996 :     move16();
     885         996 :     Src_p->azim_prev_fx = 0; // Q22
     886         996 :     move32();
     887         996 :     Src_p->elev_prev_fx = 0; // Q22
     888         996 :     move32();
     889         996 :     Src_p->Gain_fx = ONE_IN_Q14; // Q14
     890         996 :     move16();
     891         996 :     Src_p->prevGain_fx = ONE_IN_Q14; // Q14
     892         996 :     move16();
     893         996 :     return;
     894             : }

Generated by: LCOV version 1.14