LCOV - code coverage report
Current view: top level - lib_rend - ivas_objectRenderer_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 353 396 89.1 %
Date: 2025-05-03 01:55:50 Functions: 10 10 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 "ivas_stat_rend.h"
      34             : #include <stdint.h>
      35             : #include "options.h"
      36             : #include "prot_fx.h"
      37             : #include "ivas_prot_rend_fx.h"
      38             : #include <math.h>
      39             : #include "ivas_rom_com.h"
      40             : #include "wmc_auto.h"
      41             : #include "ivas_prot_fx.h"
      42             : #include "debug.h"
      43             : #include "ivas_rom_com_fx.h"
      44             : #define float_to_fixed( n, factor ) ( round( n * ( 1 << factor ) ) )
      45             : #define fixed_to_float( n, factor ) ( (float) n / ( 1 << factor ) )
      46             : 
      47             : /*---------------------------------------------------------------------*
      48             :  * Local function prototypes
      49             :  *---------------------------------------------------------------------*/
      50             : 
      51             : 
      52             : static void TDREND_Clear_Update_flags_fx(
      53             :     BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd /* i/o: TD renderer handle */
      54             : );
      55             : 
      56             : 
      57             : static void angles_to_vec_fx(
      58             :     const Word16 radius,    /* i  : radius                              */
      59             :     const Word32 azimuth,   /* i  : Azimuth angle                       */
      60             :     const Word32 elevation, /* i  : Elevation angle                     */
      61             :     Word32 *vec             /* o  : Pos/Dir vector                      */
      62             : );
      63             : 
      64             : /*---------------------------------------------------------------------*
      65             :  * ivas_td_binaural_open_unwrap()
      66             :  *
      67             :  * Call TD open/init function without st_ivas
      68             :  *---------------------------------------------------------------------*/
      69             : 
      70         513 : ivas_error ivas_td_binaural_open_unwrap_fx(
      71             :     TDREND_HRFILT_FiltSet_t **hHrtfTD,                  /* i/o: HR filter model (from file or NULL) */
      72             :     const Word32 output_Fs,                             /* i  : Output sampling rate                */
      73             :     const Word16 nchan_transport,                       /* i  : Number of channels                  */
      74             :     const IVAS_FORMAT ivas_format,                      /* i  : IVAS format (ISM/MC)                */
      75             :     const AUDIO_CONFIG transport_config,                /* i  : Transport configuration             */
      76             :     const Word16 *directivity,                          /* i  : Directivity pattern (used for ISM)  */
      77             :     const IVAS_OUTPUT_SETUP hTransSetup,                /* i  : Loudspeaker layout                  */
      78             :     BINAURAL_TD_OBJECT_RENDERER_HANDLE *hBinRendererTd, /* o  : TD renderer handle                  */
      79             :     Word32 *binaural_latency_ns,                        /* i  : Binauralization delay               */
      80             :     Word16 *SrcInd )
      81             : {
      82             :     BINAURAL_TD_OBJECT_RENDERER_HANDLE pBinRendTd;
      83             :     TDREND_PosType_t PosType;
      84             :     Word16 nS;
      85             :     const Word32 *ls_azimuth_fx, *ls_elevation_fx;
      86             :     Word32 Pos_fx[3]; // Q25
      87             :     Word32 Dir_fx[3]; // Q30
      88             :     TDREND_DirAtten_t *DirAtten_p;
      89             :     Word16 nchan_rend;
      90             :     ivas_error error;
      91             : 
      92         513 :     error = IVAS_ERR_OK;
      93             : 
      94         513 :     IF( ( pBinRendTd = malloc( sizeof( BINAURAL_TD_OBJECT_RENDERER ) ) ) == NULL )
      95             :     {
      96           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD renderer\n" ) );
      97             :     }
      98         513 :     IF( ( pBinRendTd->TdRend_MixSpatSpec_p = malloc( sizeof( TDREND_MixSpatSpec_t ) ) ) == NULL )
      99             :     {
     100           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD renderer\n" ) );
     101             :     }
     102         513 :     IF( ( pBinRendTd->DirAtten_p = malloc( sizeof( TDREND_DirAtten_t ) ) ) == NULL )
     103             :     {
     104           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD renderer\n" ) );
     105             :     }
     106         513 :     IF( ( pBinRendTd->Listener_p = malloc( sizeof( TDREND_MIX_Listener_t ) ) ) == NULL )
     107             :     {
     108           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD renderer\n" ) );
     109             :     }
     110             : 
     111         513 :     pBinRendTd->NumOfSrcs = 0;
     112         513 :     pBinRendTd->MaxSrcInd = -1;
     113             : 
     114         513 :     move16();
     115         513 :     move16();
     116             :     /* Mixer spatial setup */
     117         513 :     pBinRendTd->TdRend_MixSpatSpec_p->UseCommonDistAttenModel = TRUE;
     118         513 :     move16();
     119         513 :     pBinRendTd->TdRend_MixSpatSpec_p->DistAttenModel = 0; /* 0=Turned off, else use TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED */
     120         513 :     move16();
     121             : 
     122         513 :     IF( NE_32( ( error = TDREND_MIX_Init_fx( pBinRendTd, hHrtfTD, pBinRendTd->TdRend_MixSpatSpec_p, output_Fs ) ), IVAS_ERR_OK ) )
     123             :     {
     124           0 :         return error;
     125             :     }
     126             : 
     127             :     /* Set the attenuation (or can set MixSpatSpec.DistAttenModel above) */
     128         513 :     IF( NE_32( ( error = TDREND_MIX_SetDistAttenModel( pBinRendTd, TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED ) ), IVAS_ERR_OK ) )
     129             :     {
     130           0 :         return error;
     131             :     }
     132             : 
     133             :     /* Add sources to module and mixer, headphones */
     134         513 :     PosType = TDREND_POSTYPE_ABSOLUTE; /* or TDREND_POSTYPE_RELATIVE_TO_LISTENER */
     135         513 :     move16();
     136         513 :     nchan_rend = nchan_transport;
     137         513 :     move16();
     138         513 :     test();
     139         513 :     if ( EQ_16( ivas_format, MC_FORMAT ) && NE_16( transport_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
     140             :     {
     141          20 :         nchan_rend = sub( nchan_rend, 1 ); /* Skip LFE channel -- added to the others */
     142             :     }
     143             : 
     144        1509 :     FOR( nS = 0; nS < nchan_rend; nS++ )
     145             :     {
     146         996 :         IF( NE_32( ( error = TDREND_MIX_AddSrc_fx( pBinRendTd, &SrcInd[nS], PosType ) ), IVAS_ERR_OK ) )
     147             :         {
     148           0 :             return error;
     149             :         }
     150             :     }
     151         513 :     IF( EQ_16( ivas_format, MC_FORMAT ) )
     152             :     {
     153          44 :         SWITCH( transport_config )
     154             :         {
     155          11 :             case IVAS_AUDIO_CONFIG_5_1:
     156          11 :                 ls_azimuth_fx = ls_azimuth_CICP6_fx;     // Q22
     157          11 :                 ls_elevation_fx = ls_elevation_CICP6_fx; // Q22
     158          11 :                 BREAK;
     159           9 :             case IVAS_AUDIO_CONFIG_7_1:
     160           9 :                 ls_azimuth_fx = ls_azimuth_CICP12_fx;     // Q22
     161           9 :                 ls_elevation_fx = ls_elevation_CICP12_fx; // Q22
     162           9 :                 BREAK;
     163           0 :             case IVAS_AUDIO_CONFIG_5_1_2:
     164           0 :                 ls_azimuth_fx = ls_azimuth_CICP14_fx;     // Q22
     165           0 :                 ls_elevation_fx = ls_elevation_CICP14_fx; // Q22
     166           0 :                 BREAK;
     167           0 :             case IVAS_AUDIO_CONFIG_5_1_4:
     168           0 :                 ls_azimuth_fx = ls_azimuth_CICP16_fx;     // Q22
     169           0 :                 ls_elevation_fx = ls_elevation_CICP16_fx; // Q22
     170           0 :                 BREAK;
     171           0 :             case IVAS_AUDIO_CONFIG_7_1_4:
     172           0 :                 ls_azimuth_fx = ls_azimuth_CICP19_fx;     // Q22
     173           0 :                 ls_elevation_fx = ls_elevation_CICP19_fx; // Q22
     174           0 :                 BREAK;
     175          24 :             case IVAS_AUDIO_CONFIG_LS_CUSTOM:
     176          24 :                 ls_azimuth_fx = hTransSetup.ls_azimuth_fx;     // Q22
     177          24 :                 ls_elevation_fx = hTransSetup.ls_elevation_fx; // Q22
     178          24 :                 BREAK;
     179           0 :             default:
     180           0 :                 ls_azimuth_fx = NULL;
     181           0 :                 ls_elevation_fx = NULL;
     182             :         }
     183             : 
     184          44 :         DirAtten_p = pBinRendTd->DirAtten_p;
     185             : 
     186         318 :         FOR( nS = 0; nS < nchan_rend; nS++ )
     187             :         {
     188             :             /* Set source positions according to loudspeaker layout */
     189         274 :             angles_to_vec_fx( ONE_IN_Q9, ls_azimuth_fx[nS], ls_elevation_fx[nS], Pos_fx );
     190             : 
     191         274 :             Dir_fx[0] = ONE_IN_Q30;
     192         274 :             move32();
     193         274 :             Dir_fx[1] = 0;
     194         274 :             move32();
     195         274 :             Dir_fx[2] = 0;
     196         274 :             move32();
     197             :             /* Source directivity info */
     198         274 :             DirAtten_p->ConeInnerAngle_fx = DEG_360_IN_Q22;
     199         274 :             move32();
     200         274 :             DirAtten_p->ConeOuterAngle_fx = DEG_360_IN_Q22;
     201         274 :             move32();
     202         274 :             DirAtten_p->ConeOuterGain_fx = ONE_IN_Q30;
     203         274 :             move32();
     204             : 
     205             :             // TDREND_SRC_SPATIAL_t *SrcSpatial_p = pBinRendTd->Sources[nS]->SrcSpatial_p;
     206         274 :             IF( NE_32( ( error = TDREND_MIX_SRC_SetPos_fx( pBinRendTd, nS, Pos_fx ) ), IVAS_ERR_OK ) )
     207             :             {
     208           0 :                 return error;
     209             :             }
     210         274 :             IF( NE_32( ( error = TDREND_MIX_SRC_SetDir_fx( pBinRendTd, nS, Dir_fx, Q30 ) ), IVAS_ERR_OK ) )
     211             :             {
     212           0 :                 return error;
     213             :             }
     214         274 :             IF( NE_32( ( error = TDREND_MIX_SRC_SetPlayState( pBinRendTd, nS, TDREND_PLAYSTATUS_PLAYING ) ), IVAS_ERR_OK ) )
     215             :             {
     216           0 :                 return error;
     217             :             }
     218             :             /*TDREND_SRC_SPATIAL_t **/ // SrcSpatial_p = pBinRendTd->Sources[nS]->SrcSpatial_p;
     219         274 :             IF( NE_32( ( error = TDREND_MIX_SRC_SetDirAtten_fx( pBinRendTd, nS, DirAtten_p ) ), IVAS_ERR_OK ) )
     220             :             {
     221           0 :                 return error;
     222             :             }
     223             :         }
     224             :     }
     225         513 :     test();
     226         513 :     test();
     227         513 :     IF( EQ_16( ivas_format, ISM_FORMAT ) || EQ_16( ivas_format, MASA_ISM_FORMAT ) || EQ_16( ivas_format, SBA_ISM_FORMAT ) )
     228             :     {
     229         469 :         DirAtten_p = pBinRendTd->DirAtten_p;
     230             : 
     231        1191 :         FOR( nS = 0; nS < nchan_rend; nS++ )
     232             :         {
     233         722 :             IF( NULL == directivity )
     234             :             {
     235         285 :                 DirAtten_p->ConeInnerAngle_fx = DEG_360_IN_Q22;
     236         285 :                 DirAtten_p->ConeOuterAngle_fx = DEG_360_IN_Q22;
     237         285 :                 DirAtten_p->ConeOuterGain_fx = ONE_IN_Q30;
     238             :             }
     239             :             ELSE
     240             :             {
     241         437 :                 DirAtten_p->ConeInnerAngle_fx = L_deposit_h( directivity[nS * 3] );                      // 9Q6 -> 9Q22
     242         437 :                 DirAtten_p->ConeOuterAngle_fx = L_deposit_h( directivity[add( nS * 3, 1 )] );            // 9Q6 -> 9Q22
     243         437 :                 DirAtten_p->ConeOuterGain_fx = L_shr( L_deposit_h( directivity[add( nS * 3, 2 )] ), 1 ); // 0Q15 -> 1Q30
     244             :             }
     245         722 :             move32();
     246         722 :             move32();
     247         722 :             move32();
     248         722 :             IF( NE_32( ( error = TDREND_MIX_SRC_SetDirAtten_fx( pBinRendTd, nS, DirAtten_p ) ), IVAS_ERR_OK ) )
     249             :             {
     250           0 :                 return error;
     251             :             }
     252             :         }
     253             :     }
     254             : 
     255         513 :     *hBinRendererTd = pBinRendTd;
     256         513 :     test();
     257         513 :     IF( NE_16( ivas_format, MASA_ISM_FORMAT ) && NE_16( ivas_format, SBA_ISM_FORMAT ) )
     258             :     {
     259         429 :         *binaural_latency_ns = Mult_32_32( ( *hBinRendererTd )->HrFiltSet_p->latency_s_fx, 1000000000 /* 1000000000.f in Q0 */ );
     260         429 :         move32();
     261             :     }
     262             : 
     263         513 :     return error;
     264             : }
     265             : 
     266             : 
     267             : /*---------------------------------------------------------------------*
     268             :  * ivas_td_binaural_close()
     269             :  *
     270             :  * Close TD Object binaural renderer
     271             :  *---------------------------------------------------------------------*/
     272             : 
     273         633 : void ivas_td_binaural_close_fx(
     274             :     BINAURAL_TD_OBJECT_RENDERER_HANDLE *hBinRendererTd /* i/o: TD binaural object renderer handle */
     275             : )
     276             : {
     277         633 :     test();
     278         633 :     IF( hBinRendererTd == NULL || *hBinRendererTd == NULL )
     279             :     {
     280         120 :         return;
     281             :     }
     282             : 
     283         513 :     free( ( *hBinRendererTd )->TdRend_MixSpatSpec_p );
     284         513 :     free( ( *hBinRendererTd )->DirAtten_p );
     285             : 
     286         513 :     TDREND_MIX_Dealloc_fx( *hBinRendererTd );
     287             : 
     288         513 :     free( *hBinRendererTd );
     289         513 :     *hBinRendererTd = NULL;
     290             : 
     291         513 :     return;
     292             : }
     293             : 
     294             : 
     295             : /*---------------------------------------------------------------------*
     296             :  * ivas_td_binaural_renderer_unwrap()
     297             :  *
     298             :  * Call ivas_td_binaural_renderer() without st_ivas.
     299             :  *---------------------------------------------------------------------*/
     300             : 
     301      324504 : ivas_error ivas_td_binaural_renderer_unwrap_fx(
     302             :     const REVERB_HANDLE hReverb,                          /* i  : Reverberator handle                                          */
     303             :     const AUDIO_CONFIG transport_config,                  /* i  : Transport configuration                                      */
     304             :     BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd,    /* i/o: TD binaural object renderer handle                           */
     305             :     const Word16 num_src,                                 /* i  : number of sources to render                                  */
     306             :     const Word16 lfe_idx,                                 /* i  : LFE channel index                                            */
     307             :     const IVAS_FORMAT ivas_format,                        /* i  : IVAS format                                                  */
     308             :     ISM_METADATA_HANDLE *hIsmMetaData,                    /* i  : ISM metadata handle                                          */
     309             :     COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientaton data handle                              */
     310             :     const Word16 ism_md_subframe_update,                  /* i  : Number of subframes to delay ism metadata to sync with audio */
     311             :     Word32 *output_fx[],                                  /* i/o: SCE channels / Binaural synthesis   Q11                      */
     312             :     const Word16 output_frame,                            /* i  : output frame length                                          */
     313             :     const Word16 num_subframes                            /* i  : number of subframes to render                                */
     314             : )
     315             : {
     316             :     Word16 subframe_length;
     317             :     Word16 subframe_idx;
     318             :     ivas_error error;
     319             :     Word16 c_indx, nS;
     320             :     Word16 ch;
     321             :     Word16 *enableCombinedOrientation; /* i  : Combined orientation flag            */
     322             :     IVAS_QUATERNION *Quaternions;      /* i  : Head tracking data per subframe      */
     323             :     IVAS_VECTOR3 *Pos;                 /* i  : Listener position data per subframe  */
     324             : 
     325             : 
     326             :     Word32 reverb_signal_fx[BINAURAL_CHANNELS][L_FRAME48k];
     327             :     Word32 *p_reverb_signal_fx[BINAURAL_CHANNELS];
     328             : 
     329      324504 :     enableCombinedOrientation = NULL;
     330      324504 :     Quaternions = NULL;
     331      324504 :     Pos = NULL;
     332      324504 :     IF( hCombinedOrientationData != NULL )
     333             :     {
     334      324504 :         enableCombinedOrientation = hCombinedOrientationData->enableCombinedOrientation;
     335      324504 :         Quaternions = hCombinedOrientationData->Quaternions;
     336      324504 :         Pos = hCombinedOrientationData->listenerPos;
     337      324504 :         move16();
     338             :     }
     339             : 
     340      973512 :     FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
     341             :     {
     342      649008 :         p_reverb_signal_fx[ch] = reverb_signal_fx[ch];
     343             :     }
     344             : 
     345      324504 :     subframe_length = idiv1616( output_frame, num_subframes );
     346             : 
     347      324504 :     c_indx = 0;
     348      324504 :     move16();
     349      886568 :     FOR( nS = 0; nS < num_src; nS++ )
     350             :     {
     351      562064 :         test();
     352      562064 :         IF( !( EQ_16( ivas_format, MC_FORMAT ) && EQ_16( nS, lfe_idx ) ) ) /* Skip LFE for MC */
     353             :         {
     354      550564 :             hBinRendererTd->Sources[c_indx]->InputFrame_p_fx = output_fx[nS]; /* Q11 */
     355      550564 :             hBinRendererTd->Sources[c_indx]->SrcRend_p->InputAvailable = TRUE;
     356      550564 :             move16();
     357      550564 :             c_indx = add( c_indx, 1 );
     358             :         }
     359             :     }
     360             : 
     361      843714 :     FOR( subframe_idx = 0; subframe_idx < num_subframes; subframe_idx++ )
     362             :     {
     363      519210 :         IF( EQ_16( subframe_idx, ism_md_subframe_update ) )
     364             :         {
     365             :             /* Update object position(s) */
     366      324504 :             IF( NE_32( ( error = TDREND_Update_object_positions_fx( hBinRendererTd, num_src, ivas_format, hIsmMetaData ) ), IVAS_ERR_OK ) )
     367             :             {
     368           0 :                 return error;
     369             :             }
     370             :         }
     371             : 
     372             :         /* Update the listener's location/orientation */
     373             :         Word16 tmp_headRotEnabled;
     374      519210 :         tmp_headRotEnabled = 0;
     375      519210 :         move16();
     376      519210 :         if ( enableCombinedOrientation != NULL )
     377             :         {
     378      519210 :             tmp_headRotEnabled = enableCombinedOrientation[hCombinedOrientationData->subframe_idx];
     379      519210 :             move16();
     380             :         }
     381             : 
     382      519210 :         IF( NE_32( ( error = TDREND_Update_listener_orientation_fx( hBinRendererTd, tmp_headRotEnabled, &Quaternions[hCombinedOrientationData->subframe_idx], &Pos[hCombinedOrientationData->subframe_idx] ) ), IVAS_ERR_OK ) )
     383             :         {
     384           0 :             return error;
     385             :         }
     386             : 
     387      519210 :         IF( hReverb != NULL )
     388             :         {
     389             :             Word16 i;
     390             : 
     391     4236400 :             FOR( i = 0; i < MAX_OUTPUT_CHANNELS; ++i )
     392             :             {
     393     3987200 :                 scale_sig32( output_fx[i], L_FRAME48k, -4 ); // Q11 - 4 = Q7
     394             :             }
     395             : 
     396      249200 :             IF( NE_32( ( error = ivas_reverb_process_fx( hReverb, transport_config, 0, output_fx, p_reverb_signal_fx, subframe_idx ) ), IVAS_ERR_OK ) ) // Q p_reverb_signal_fx = Q output_fx - 2 = 5
     397             :             {
     398           0 :                 return error;
     399             :             }
     400             : 
     401     4236400 :             FOR( i = 0; i < MAX_OUTPUT_CHANNELS; ++i )
     402             :             {
     403     3987200 :                 scale_sig32( output_fx[i], L_FRAME48k, 4 ); // Q7 + 4 = Q11
     404             :             }
     405             : 
     406      747600 :             FOR( i = 0; i < BINAURAL_CHANNELS; ++i )
     407             :             {
     408      498400 :                 scale_sig32( p_reverb_signal_fx[i] + subframe_idx * hReverb->full_block_size, hReverb->full_block_size, 2 + 4 ); // Q5 + 6 = Q11
     409             :             }
     410             :         }
     411             : 
     412             :         /* Render subframe */
     413      519210 :         IF( NE_32( ( error = TDREND_GetMix_fx( hBinRendererTd, output_fx, subframe_length, subframe_idx, ism_md_subframe_update ) ), IVAS_ERR_OK ) )
     414             :         {
     415           0 :             return error;
     416             :         }
     417             : 
     418             : 
     419             :         /* Advance subframe pointer */
     420      519210 :         c_indx = 0;
     421      519210 :         move16();
     422     1418570 :         FOR( nS = 0; nS < num_src; nS++ )
     423             :         {
     424      899360 :             test();
     425      899360 :             IF( !( EQ_16( ivas_format, MC_FORMAT ) && EQ_16( nS, lfe_idx ) ) ) /* Skip LFE for MC */
     426             :             {
     427      880960 :                 hBinRendererTd->Sources[c_indx]->InputFrame_p_fx += subframe_length;
     428      880960 :                 c_indx = add( c_indx, 1 );
     429             :             }
     430             :         }
     431             : 
     432             :         /* update combined orientation access index */
     433      519210 :         ivas_combined_orientation_update_index( hCombinedOrientationData, subframe_length );
     434             :     }
     435             : 
     436      324504 :     IF( hReverb != NULL )
     437             :     {
     438      155750 :         v_add_32( reverb_signal_fx[0], output_fx[0], output_fx[0], output_frame ); // Q11
     439      155750 :         v_add_32( reverb_signal_fx[1], output_fx[1], output_fx[1], output_frame ); // Q11
     440             :     }
     441             : 
     442      324504 :     return IVAS_ERR_OK;
     443             : }
     444             : 
     445             : 
     446             : /*---------------------------------------------------------------------*
     447             :  * TDREND_GetMix()
     448             :  *
     449             :  * Render one 5 ms subframe from the mixer
     450             :  *---------------------------------------------------------------------*/
     451             : 
     452      664495 : ivas_error TDREND_GetMix_fx(
     453             :     BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle                                           */
     454             :     Word32 *output[],                                  /* i/o: ISM object synth / rendered output in 0,1       Q11          */
     455             :     const Word16 subframe_length,                      /* i/o: subframe length                                              */
     456             :     const Word16 subframe_idx,                         /* i  : Subframe index to 5 ms subframe                              */
     457             :     const Word16 ism_md_subframe_update                /* i  : Number of subframes to delay ism metadata to sync with audio */
     458             : )
     459             : {
     460             :     Word16 i;
     461             :     TDREND_SRC_t *Src_p;
     462             :     TDREND_SRC_SPATIAL_t *SrcSpatial_p;
     463             :     TDREND_SRC_REND_t *SrcRend_p;
     464             :     ivas_error error;
     465             :     Word32 output_buf[2][L_SPATIAL_SUBFR_48k]; /* Temp buffer for left/right rendered signal */
     466             :     Word32 hrf_left_delta[SFX_SPAT_BIN_MAX_FILTER_LENGTH];
     467             :     Word32 hrf_right_delta[SFX_SPAT_BIN_MAX_FILTER_LENGTH];
     468             :     Word16 intp_count;
     469             :     Word16 subframe_update_flag;
     470      664495 :     Word16 hrf_left_delta_e = 0, hrf_right_delta_e = 0;
     471      664495 :     move16();
     472      664495 :     move16();
     473             : 
     474      664495 :     subframe_update_flag = (Word16) EQ_16( subframe_idx, ism_md_subframe_update );
     475      664495 :     move16();
     476             : 
     477      664495 :     error = IVAS_ERR_OK;
     478      664495 :     move32();
     479             :     /* Clear the output buffer to accumulate rendered sources */
     480      664495 :     set32_fx( output_buf[0], 0, subframe_length );
     481      664495 :     set32_fx( output_buf[1], 0, subframe_length );
     482             :     /* Clear interpolation buffers and counter */
     483      664495 :     set32_fx( hrf_left_delta, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH );
     484      664495 :     set32_fx( hrf_right_delta, 0, SFX_SPAT_BIN_MAX_FILTER_LENGTH );
     485             : 
     486      664495 :     intp_count = 0;
     487      664495 :     move16();
     488             : 
     489             :     /* Create the mix */
     490             :     /* Loop through the source list and render each source */
     491     1993937 :     FOR( i = 0; i < hBinRendererTd->NumOfSrcs; i++ )
     492             :     {
     493     1329442 :         Src_p = hBinRendererTd->Sources[i];
     494     1329442 :         SrcSpatial_p = Src_p->SrcSpatial_p;
     495     1329442 :         SrcRend_p = Src_p->SrcRend_p;
     496             : 
     497             :         /* Update rendering params if needed */
     498     1329442 :         test();
     499     1329442 :         test();
     500     1329442 :         IF( EQ_16( SrcRend_p->PlayStatus, TDREND_PLAYSTATUS_PLAYING ) && ( hBinRendererTd->Listener_p->PoseUpdated || SrcSpatial_p->Updated ) )
     501             :         {
     502      903144 :             TDREND_SRC_REND_UpdateFiltersFromSpatialParams_fx( hBinRendererTd, SrcRend_p, SrcSpatial_p,
     503      903144 :                                                                Src_p->hrf_left_prev_fx, &Src_p->hrf_left_prev_e, Src_p->hrf_right_prev_fx, &Src_p->hrf_right_prev_e,
     504             :                                                                hrf_left_delta, &hrf_left_delta_e, hrf_right_delta, &hrf_right_delta_e,
     505             :                                                                &intp_count, &Src_p->filterlength, &Src_p->itd,
     506             :                                                                &Src_p->Gain_fx,
     507             :                                                                Src_p, subframe_update_flag );
     508             :         }
     509             : 
     510             :         /* Render source if needed */
     511     1329442 :         test();
     512     1329442 :         IF( EQ_16( SrcRend_p->InputAvailable, TRUE ) && EQ_16( SrcRend_p->PlayStatus, TDREND_PLAYSTATUS_PLAYING ) )
     513             :         {
     514     1329442 :             error = TDREND_REND_RenderSourceHRFilt_fx( Src_p, hrf_left_delta, &hrf_left_delta_e,
     515             :                                                        hrf_right_delta, &hrf_right_delta_e, intp_count, output_buf, subframe_length );
     516             :         }
     517             :     }
     518             : 
     519             : 
     520             :     /* Populate output variable */
     521      664495 :     Copy32( output_buf[0], output[0] + imult1616( subframe_idx, subframe_length ), subframe_length ); /* Left same Q as Src_p->InputFrame_p_fx  Q11 */
     522      664495 :     Copy32( output_buf[1], output[1] + imult1616( subframe_idx, subframe_length ), subframe_length ); /* Right same Q as Src_p->InputFrame_p_fx Q11 */
     523             : 
     524             :     /* Clear the PoseUpdated and Source position update flags */
     525      664495 :     TDREND_Clear_Update_flags_fx( hBinRendererTd );
     526             : 
     527      664495 :     return error;
     528             : }
     529             : 
     530             : 
     531             : /*---------------------------------------------------------------------*
     532             :  * TDREND_Clear_Update_flags()
     533             :  *
     534             :  * Initializes the audio mixer module
     535             :  *---------------------------------------------------------------------*/
     536             : 
     537      664495 : static void TDREND_Clear_Update_flags_fx(
     538             :     BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd /* i/o: TD renderer handle */
     539             : )
     540             : {
     541             :     Word16 i;
     542             : 
     543      664495 :     hBinRendererTd->Listener_p->PoseUpdated = FALSE;
     544      664495 :     move16();
     545             : 
     546     1993937 :     FOR( i = 0; i < hBinRendererTd->NumOfSrcs; i++ )
     547             :     {
     548     1329442 :         hBinRendererTd->Sources[i]->SrcSpatial_p->Updated = FALSE;
     549     1329442 :         move16();
     550             :     }
     551             : 
     552      664495 :     return;
     553             : }
     554             : 
     555             : 
     556             : /*---------------------------------------------------------------------*
     557             :  * TDREND_Update_object_positions_fx()
     558             :  *
     559             :  * Update object position(s)
     560             :  *---------------------------------------------------------------------*/
     561             : 
     562      360835 : ivas_error TDREND_Update_object_positions_fx(
     563             :     BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD Renderer handle               */
     564             :     const Word16 num_src,                              /* i  : number of sources to render      */
     565             :     const IVAS_FORMAT in_format,                       /* i  : Format of input sources          */
     566             :     const ISM_METADATA_HANDLE *hIsmMetaData            /* i  : Input metadata for ISM objects   */
     567             : )
     568             : {
     569             :     TDREND_DirAtten_t *DirAtten_p;
     570             :     Word16 nS;
     571             :     Word32 Pos_fx[3]; // Q25
     572             :     Word32 Dir_fx[3]; // Q30
     573             :     ivas_error error;
     574             : 
     575      360835 :     DirAtten_p = hBinRendererTd->DirAtten_p;
     576             : 
     577             :     /* For each source, write the frame data to the source object*/
     578     1038105 :     FOR( nS = 0; nS < num_src; nS++ )
     579             :     {
     580      677270 :         test();
     581      677270 :         test();
     582      677270 :         IF( EQ_16( in_format, ISM_FORMAT ) || EQ_16( in_format, MASA_ISM_FORMAT ) || EQ_16( in_format, SBA_ISM_FORMAT ) )
     583             :         {
     584             :             /* Update the source positions */
     585             :             /* Source position and direction */
     586      396726 :             angles_to_vec_fx( hIsmMetaData[nS]->radius_fx /*Q9*/, hIsmMetaData[nS]->azimuth_fx, hIsmMetaData[nS]->elevation_fx, Pos_fx );
     587      396726 :             angles_to_vec_fx( ONE_IN_Q14, hIsmMetaData[nS]->yaw_fx, hIsmMetaData[nS]->pitch_fx, Dir_fx );
     588             : 
     589             :             // DirAtten_p->ConeInnerAngle_fx = DEG_360_IN_Q22;
     590             :             // move32();
     591             :             // DirAtten_p->ConeOuterAngle_fx = DEG_360_IN_Q22;
     592             :             // move32();
     593             :             // DirAtten_p->ConeOuterGain_fx = ONE_IN_Q30;
     594             :             // move32();
     595             : 
     596      396726 :             IF( NE_32( ( error = TDREND_MIX_SRC_SetPos_fx( hBinRendererTd, nS, Pos_fx ) ), IVAS_ERR_OK ) )
     597             :             {
     598           0 :                 return error;
     599             :             }
     600             : 
     601      396726 :             IF( NE_32( ( error = TDREND_MIX_SRC_SetDirAtten_fx( hBinRendererTd, nS, DirAtten_p ) ), IVAS_ERR_OK ) )
     602             :             {
     603           0 :                 return error;
     604             :             }
     605             : 
     606      396726 :             IF( hIsmMetaData[nS]->non_diegetic_flag )
     607             :             {
     608         828 :                 Pos_fx[0] = 0;
     609             :                 /* Pos[1] = hIsmMetaData[nS]->azimuth / 90.f; */
     610         828 :                 Pos_fx[1] = L_shl( Mpy_32_32_r( hIsmMetaData[nS]->azimuth_fx, 23860929 /* 1 / 90.f in Q31 */ ), Q3 ); /* Q25 */
     611         828 :                 move32();
     612         828 :                 Pos_fx[2] = 0;
     613         828 :                 move32();
     614             : 
     615         828 :                 IF( NE_32( ( error = TDREND_MIX_SRC_SetPos_fx( hBinRendererTd, nS, Pos_fx ) ), IVAS_ERR_OK ) )
     616             :                 {
     617           0 :                     return error;
     618             :                 }
     619         828 :                 hBinRendererTd->Sources[nS]->SrcSpatial_p->PosType = TDREND_POSTYPE_NON_DIEGETIC;
     620         828 :                 move16();
     621             :             }
     622             :             ELSE
     623             :             {
     624      395898 :                 hBinRendererTd->Sources[nS]->SrcSpatial_p->PosType = TDREND_POSTYPE_ABSOLUTE;
     625      395898 :                 move16();
     626             :             }
     627             : 
     628      396726 :             IF( NE_32( ( error = TDREND_MIX_SRC_SetDir_fx( hBinRendererTd, nS, Dir_fx, Q30 ) ), IVAS_ERR_OK ) )
     629             :             {
     630           0 :                 return error;
     631             :             }
     632             :         }
     633             :     }
     634             : 
     635      360835 :     return IVAS_ERR_OK;
     636             : }
     637             : 
     638             : /*---------------------------------------------------------------------*
     639             :  * TDREND_Update_listener_orientation()
     640             :  *
     641             :  * Update listener orientation (s)
     642             :  *---------------------------------------------------------------------*/
     643             : 
     644      664495 : ivas_error TDREND_Update_listener_orientation_fx(
     645             :     BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD Renderer handle           */
     646             :     const Word16 headRotEnabled,                       /* i  : Headrotation flag            */
     647             :     const IVAS_QUATERNION *headPosition_fx,            /* i  : Listener orientation     Qx  */
     648             :     const IVAS_VECTOR3 *Pos_fx                         /* i  : Listener Position            */
     649             : )
     650             : {
     651             :     Word32 FrontVec_fx[3];
     652             :     Word32 UpVec_fx[3];
     653             :     Word32 Rmat_fx[3][3];
     654             :     Word16 orient_q, headPosition_q;
     655             :     Word32 Pos_p_fx[3];
     656             :     ivas_error error;
     657             : 
     658      664495 :     IF( headRotEnabled )
     659             :     {
     660             :         Word16 Rmat_q;
     661             : 
     662      353645 :         headPosition_q = headPosition_fx->q_fact;
     663      353645 :         move16();
     664             : 
     665             :         /* Obtain head rotation matrix */
     666      353645 :         QuatToRotMat_fx( *headPosition_fx, Rmat_fx ); // Rmat_fx Q: 2*headPosition_q-32
     667      353645 :         Rmat_q = sub( shl( headPosition_q, 1 ), 32 );
     668             : 
     669             :         /* Apply rotation matrix to looking vector [1;0;0] */
     670      353645 :         FrontVec_fx[0] = Rmat_fx[0][0]; // Q Rmat_q
     671      353645 :         move32();
     672      353645 :         FrontVec_fx[1] = Rmat_fx[0][1]; // Q Rmat_q
     673      353645 :         move32();
     674      353645 :         FrontVec_fx[2] = Rmat_fx[0][2]; // Q Rmat_q
     675      353645 :         move32();
     676             : 
     677             :         /* Apply rotation matrix to up vector [0;0;1] */
     678      353645 :         UpVec_fx[0] = Rmat_fx[2][0]; // Q Rmat_q
     679      353645 :         move32();
     680      353645 :         UpVec_fx[1] = Rmat_fx[2][1]; // Q Rmat_q
     681      353645 :         move32();
     682      353645 :         UpVec_fx[2] = Rmat_fx[2][2]; // Q Rmat_q
     683      353645 :         move32();
     684             : 
     685      353645 :         orient_q = Rmat_q;
     686      353645 :         move16();
     687             : 
     688      353645 :         IF( Pos_fx != NULL )
     689             :         {
     690             :             /* Input position   */
     691      353645 :             Pos_p_fx[0] = ( *Pos_fx ).x_fx; // Q Pos_fx->q_fact
     692      353645 :             Pos_p_fx[1] = ( *Pos_fx ).y_fx; // Q Pos_fx->q_fact
     693      353645 :             Pos_p_fx[2] = ( *Pos_fx ).z_fx; // Q Pos_fx->q_fact
     694             :         }
     695             :         ELSE
     696             :         {
     697             :             /* Listener at the origin   */
     698           0 :             Pos_p_fx[0] = 0;
     699           0 :             Pos_p_fx[1] = 0;
     700           0 :             Pos_p_fx[2] = 0;
     701             :         }
     702      353645 :         move32();
     703      353645 :         move32();
     704      353645 :         move32();
     705             :     }
     706             :     ELSE
     707             :     {
     708             :         /* Oriented with looking vector along the x axis */
     709      310850 :         FrontVec_fx[0] = ONE_IN_Q30;
     710      310850 :         move32();
     711      310850 :         FrontVec_fx[1] = 0;
     712      310850 :         move32();
     713      310850 :         FrontVec_fx[2] = 0;
     714      310850 :         move32();
     715             :         /* Oriented with up vector along the z axis      */
     716      310850 :         UpVec_fx[0] = 0;
     717      310850 :         move32();
     718      310850 :         UpVec_fx[1] = 0;
     719      310850 :         move32();
     720      310850 :         UpVec_fx[2] = ONE_IN_Q30;
     721      310850 :         move32();
     722             : 
     723      310850 :         orient_q = Q30;
     724      310850 :         move32();
     725             : 
     726             :         /* Listener at the origin   */
     727      310850 :         Pos_p_fx[0] = 0;
     728      310850 :         move32();
     729      310850 :         Pos_p_fx[1] = 0;
     730      310850 :         move32();
     731      310850 :         Pos_p_fx[2] = 0;
     732      310850 :         move32();
     733             :     }
     734             : 
     735             :     /* Set the listener position and orientation:*/
     736      664495 :     TDREND_MIX_LIST_SetPos_fx( hBinRendererTd, Pos_p_fx );
     737      664495 :     error = TDREND_MIX_LIST_SetOrient_fx( hBinRendererTd, FrontVec_fx, UpVec_fx, orient_q );
     738             : 
     739      664495 :     return error;
     740             : }
     741             : 
     742             : 
     743             : /*---------------------------------------------------------------------*
     744             :  * ivas_td_binaural_open_ext()
     745             :  *
     746             :  *
     747             :  *---------------------------------------------------------------------*/
     748         405 : ivas_error ivas_td_binaural_open_ext_fx(
     749             :     TDREND_WRAPPER *pTDRend,
     750             :     AUDIO_CONFIG inConfig,
     751             :     RENDER_CONFIG_DATA *hRendCfg, /* i  : Renderer configuration */
     752             :     LSSETUP_CUSTOM_STRUCT *customLsInput,
     753             :     const Word32 outFs,
     754             :     Word16 *SrcInd,
     755             :     Word16 *num_src )
     756             : {
     757             :     Word16 nchan_transport;
     758             :     AUDIO_CONFIG transport_config;
     759             :     IVAS_FORMAT ivas_format;
     760             :     IVAS_OUTPUT_SETUP hTransSetup;
     761             :     ivas_error error;
     762             : 
     763         405 :     Word16 *directivity_fx = NULL;
     764             : 
     765         405 :     IF( NE_16( inConfig, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
     766             :     {
     767         381 :         IF( NE_32( ( error = getAudioConfigNumChannels( inConfig, &nchan_transport ) ), IVAS_ERR_OK ) )
     768             :         {
     769           0 :             return error;
     770             :         }
     771             :     }
     772             :     ELSE
     773             :     {
     774          24 :         nchan_transport = customLsInput->num_spk;
     775          24 :         move16();
     776             :     }
     777         405 :     *num_src = nchan_transport;
     778         405 :     move16();
     779             : 
     780         405 :     transport_config = inConfig;
     781         405 :     move16();
     782         405 :     IF( ( getAudioConfigType( inConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) )
     783             :     {
     784          40 :         ivas_format = MC_FORMAT;
     785          40 :         move16();
     786             :     }
     787             :     ELSE
     788             :     {
     789         365 :         ivas_format = ISM_FORMAT;
     790         365 :         move16();
     791             :     }
     792         405 :     hTransSetup.ls_azimuth_fx = NULL;
     793         405 :     hTransSetup.ls_elevation_fx = NULL;
     794             : 
     795         405 :     IF( EQ_16( inConfig, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
     796             :     {
     797          24 :         hTransSetup.ls_azimuth_fx = customLsInput->ls_azimuth_fx;
     798          24 :         hTransSetup.ls_elevation_fx = customLsInput->ls_elevation_fx;
     799             :     }
     800             : 
     801         405 :     if ( NULL != hRendCfg )
     802             :     {
     803         120 :         directivity_fx = hRendCfg->directivity_fx;
     804             :     }
     805             : 
     806         405 :     return ivas_td_binaural_open_unwrap_fx( &pTDRend->hHrtfTD, outFs, *num_src, ivas_format, transport_config, directivity_fx, hTransSetup, &pTDRend->hBinRendererTd, &pTDRend->binaural_latency_ns, SrcInd );
     807             : }
     808             : /*---------------------------------------------------------------------*
     809             :  * ivas_td_binaural_renderer_ext()
     810             :  *
     811             :  * Receives the current frames for the object streams, updates metadata
     812             :  * and renders the current frame.
     813             :  *---------------------------------------------------------------------*/
     814             : 
     815      324504 : ivas_error ivas_td_binaural_renderer_ext_fx(
     816             :     const TDREND_WRAPPER *pTDRend,                               /* i  : TD Renderer wrapper structure           */
     817             :     const AUDIO_CONFIG inConfig,                                 /* i  : Input audio configuration               */
     818             :     const LSSETUP_CUSTOM_STRUCT *customLsInput,                  /* i  : Input custom loudspeaker layout         */
     819             :     const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData, /* i  : Combined head and external orientations */
     820             :     const IVAS_ISM_METADATA *currentPos,                         /* i  : Object position                         */
     821             :     const REVERB_HANDLE hReverb,                                 /* i  : Reverberator handle                     */
     822             :     const Word16 ism_md_subframe_update_ext,                     /* i  : Metadata Delay in subframes to sync with audio delay */
     823             :     const Word32 output_Fs,                                      /* i  : output sampling rate                                    */
     824             :     const Word16 output_frame,                                   /* i  : output frame length                     */
     825             :     Word32 output[][L_FRAME48k],                                 /* i/o: SCE channels / Binaural synthesis   Q11 */
     826             :     Word16 *exp )
     827             : {
     828             :     ISM_METADATA_FRAME hIsmMetaDataFrame;
     829             :     ISM_METADATA_HANDLE hIsmMetaData[1];
     830             :     Word16 lfe_idx, exp_tmp;
     831             :     Word16 num_src;
     832             :     IVAS_FORMAT ivas_format;
     833             :     IVAS_REND_AudioConfigType inConfigType;
     834             :     AUDIO_CONFIG transport_config;
     835             :     ivas_error error;
     836             : 
     837             :     Word32 *p_output_fx[MAX_OUTPUT_CHANNELS];
     838     5516568 :     FOR( Word16 i = 0; i < MAX_OUTPUT_CHANNELS; i++ )
     839             :     {
     840     5192064 :         p_output_fx[i] = output[i];
     841             :     }
     842             : 
     843      324504 :     push_wmops( "ivas_td_binaural_renderer_ext" );
     844             : 
     845      324504 :     inConfigType = getAudioConfigType( inConfig );
     846      324504 :     lfe_idx = LFE_CHANNEL;
     847      324504 :     move16();
     848      324504 :     hIsmMetaData[0] = NULL;
     849             : 
     850             : 
     851      324504 :     IF( EQ_32( inConfigType, IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) )
     852             :     {
     853       24504 :         ivas_format = MC_FORMAT;
     854       24504 :         move16();
     855       24504 :         transport_config = inConfig;
     856       24504 :         move16();
     857             : 
     858       24504 :         IF( NE_32( inConfig, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
     859             :         {
     860       11500 :             IF( NE_32( ( error = getAudioConfigNumChannels( inConfig, &num_src ) ), IVAS_ERR_OK ) )
     861             :             {
     862           0 :                 return error;
     863             :             }
     864             :         }
     865             :         ELSE
     866             :         {
     867       13004 :             IF( customLsInput->num_lfe > 0 )
     868             :             {
     869           0 :                 lfe_idx = customLsInput->lfe_idx[0];
     870           0 :                 move16();
     871             :             }
     872             :             ELSE
     873             :             {
     874       13004 :                 lfe_idx = -1;
     875       13004 :                 move16();
     876             :             }
     877       13004 :             num_src = add( customLsInput->num_spk, customLsInput->num_lfe );
     878             :         }
     879             :     }
     880             :     ELSE
     881             :     {
     882      300000 :         ivas_format = ISM_FORMAT;
     883      300000 :         move16();
     884      300000 :         num_src = 1;
     885      300000 :         move16();
     886      300000 :         transport_config = IVAS_AUDIO_CONFIG_ISM1;
     887      300000 :         move16();
     888      300000 :         hIsmMetaData[0] = &hIsmMetaDataFrame;
     889      300000 :         move16();
     890      300000 :         hIsmMetaData[0]->azimuth_fx = currentPos->azimuth_fx;
     891      300000 :         move32();
     892      300000 :         hIsmMetaData[0]->elevation_fx = currentPos->elevation_fx;
     893      300000 :         move32();
     894      300000 :         hIsmMetaData[0]->yaw_fx = currentPos->yaw_fx;
     895      300000 :         move32();
     896      300000 :         hIsmMetaData[0]->pitch_fx = currentPos->pitch_fx;
     897      300000 :         move32();
     898      300000 :         hIsmMetaData[0]->radius_fx = currentPos->radius_fx;
     899      300000 :         move32();
     900      300000 :         hIsmMetaData[0]->non_diegetic_flag = currentPos->non_diegetic_flag;
     901      300000 :         move16();
     902             :     }
     903             : 
     904      324504 :     Word16 num_subframes = BASOP_Util_Divide3232_Scale( L_mult0( output_frame, FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ), output_Fs, &exp_tmp );
     905      324504 :     IF( sub( 15, exp_tmp ) )
     906             :     {
     907      324504 :         num_subframes = shr( num_subframes, sub( 15, exp_tmp ) );
     908             :     }
     909      843714 :     FOR( Word16 subframe_idx = 0; subframe_idx < num_subframes; subframe_idx++ )
     910             :     {
     911      519210 :         Word16 idx = subframe_idx;
     912      519210 :         move16();
     913      519210 :         Word16 pos_q = Q25;
     914      519210 :         move16();
     915      519210 :         IF( ( *hCombinedOrientationData )->listenerPos != NULL )
     916             :         {
     917      519210 :             ( *hCombinedOrientationData )->listenerPos[idx].x_fx = L_shr( ( *hCombinedOrientationData )->listenerPos[idx].x_fx, sub( ( *hCombinedOrientationData )->listenerPos[idx].q_fact, pos_q ) );
     918      519210 :             move32();
     919      519210 :             ( *hCombinedOrientationData )->listenerPos[idx].y_fx = L_shr( ( *hCombinedOrientationData )->listenerPos[idx].y_fx, sub( ( *hCombinedOrientationData )->listenerPos[idx].q_fact, pos_q ) );
     920      519210 :             move32();
     921      519210 :             ( *hCombinedOrientationData )->listenerPos[idx].z_fx = L_shr( ( *hCombinedOrientationData )->listenerPos[idx].z_fx, sub( ( *hCombinedOrientationData )->listenerPos[idx].q_fact, pos_q ) );
     922      519210 :             move32();
     923      519210 :             ( *hCombinedOrientationData )->listenerPos[idx].q_fact = pos_q;
     924      519210 :             move16();
     925             :         }
     926     2076840 :         FOR( Word16 i = 0; i < 3; i++ )
     927             :         {
     928     1557630 :             pTDRend->hBinRendererTd->Listener_p->Pos_fx[i] = L_shr( pTDRend->hBinRendererTd->Listener_p->Pos_fx[i], sub( pTDRend->hBinRendererTd->Listener_p->Pos_q, pos_q ) );
     929     1557630 :             pTDRend->hBinRendererTd->Listener_p->Pos_q = pos_q;
     930     1557630 :             move32();
     931     1557630 :             move16();
     932             :         }
     933             :     }
     934             : 
     935             : 
     936      324504 :     IF( NE_32( ( error = ivas_td_binaural_renderer_unwrap_fx( hReverb, transport_config, pTDRend->hBinRendererTd, num_src, lfe_idx, ivas_format, hIsmMetaData, *hCombinedOrientationData,
     937             :                                                               ism_md_subframe_update_ext, p_output_fx, output_frame, num_subframes ) ),
     938             :                IVAS_ERR_OK ) )
     939             :     {
     940           0 :         return error;
     941             :     }
     942      324504 :     IF( hReverb != NULL )
     943             :     {
     944      155750 :         *exp = sub( *exp, 2 );
     945      155750 :         move16();
     946             :     }
     947             : 
     948      324504 :     pop_wmops();
     949             : 
     950      324504 :     return IVAS_ERR_OK;
     951             : }
     952             : 
     953             : 
     954             : /*---------------------------------------------------------------------*
     955             :  * angles_to_vec()
     956             :  *
     957             :  * Convert azimuth and elevation angles to position/orientation vector
     958             :  *---------------------------------------------------------------------*/
     959      793726 : static void angles_to_vec_fx(
     960             :     const Word16 radius,    /* i  : radius                               Qx */
     961             :     const Word32 azimuth,   /* i  : Azimuth angle                       Q22 */
     962             :     const Word32 elevation, /* i  : Elevation angle                     Q22 */
     963             :     Word32 *vec             /* o  : Pos/Dir vector                    Qx+16 */
     964             : )
     965             : {
     966             :     Word16 elevation_fx, azimuth_fx;
     967      793726 :     elevation_fx = (Word16) L_shr( Mult_32_16( elevation, 91 ), 7 ); // Q15
     968      793726 :     move16();
     969      793726 :     azimuth_fx = (Word16) L_shr( Mult_32_16( azimuth, 91 ), 7 ); // Q15
     970      793726 :     move16();
     971      793726 :     vec[0] = L_mult( radius, mult( getCosWord16R2( elevation_fx ), getCosWord16R2( azimuth_fx ) ) ); // Qx + 16
     972      793726 :     move32();
     973      793726 :     vec[1] = L_mult( radius, mult( getCosWord16R2( elevation_fx ), getSineWord16R2( azimuth_fx ) ) ); // Qx + 16
     974      793726 :     move32();
     975      793726 :     vec[2] = L_mult( radius, getSineWord16R2( elevation_fx ) ); // Qx + 16
     976      793726 :     move32();
     977      793726 :     return;
     978             : }

Generated by: LCOV version 1.14