LCOV - code coverage report
Current view: top level - lib_dec - ivas_objectRenderer_internal_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 109 174 62.6 %
Date: 2025-08-23 01:22:27 Functions: 2 3 66.7 %

          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 "prot_fx.h"
      36             : #include "ivas_prot_rend_fx.h"
      37             : #include <math.h>
      38             : #include "ivas_rom_com.h"
      39             : #include "wmc_auto.h"
      40             : #include "ivas_prot_fx.h"
      41             : #include "debug.h"
      42             : 
      43             : 
      44             : /*---------------------------------------------------------------------*
      45             :  * ivas_td_binaural_open()
      46             :  *
      47             :  * Open and initialize TD Object binaural renderer
      48             :  *---------------------------------------------------------------------*/
      49             : 
      50         202 : ivas_error ivas_td_binaural_open_fx(
      51             :     Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure  */
      52             :     Word16 *SrcInd,          /*Temporarily used to store the updated value of SrcInd*/
      53             :     Word16 *num_src )
      54             : {
      55         202 :     *num_src = st_ivas->nchan_transport;
      56         202 :     move16();
      57             : 
      58         202 :     test();
      59         202 :     if ( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
      60             :     {
      61         170 :         *num_src = st_ivas->nchan_ism;
      62         170 :         move16();
      63             :     }
      64             : 
      65             : #ifdef CONF_DISTATT
      66         202 :     return ivas_td_binaural_open_unwrap_fx( &st_ivas->hHrtfTD, st_ivas->hDecoderConfig->output_Fs, *num_src, st_ivas->ivas_format, st_ivas->transport_config, st_ivas->hRenderConfig->directivity_fx, st_ivas->hRenderConfig->distAtt_fx, st_ivas->hTransSetup, &st_ivas->hBinRendererTd, &st_ivas->binaural_latency_ns, SrcInd );
      67             : #else
      68             :     return ivas_td_binaural_open_unwrap_fx( &st_ivas->hHrtfTD, st_ivas->hDecoderConfig->output_Fs, *num_src, st_ivas->ivas_format, st_ivas->transport_config, st_ivas->hRenderConfig->directivity_fx, st_ivas->hTransSetup, &st_ivas->hBinRendererTd, &st_ivas->binaural_latency_ns, SrcInd );
      69             : #endif
      70             : }
      71             : 
      72             : 
      73             : /*---------------------------------------------------------------------*
      74             :  * ivas_td_binaural_renderer_sf()
      75             :  *
      76             :  * Receives the current frames for the object streams, updates metadata
      77             :  * and renders the current frame.
      78             :  *---------------------------------------------------------------------*/
      79             : 
      80       41987 : ivas_error ivas_td_binaural_renderer_sf_fx(
      81             :     Decoder_Struct *st_ivas,           /* i/o: IVAS decoder structure              */
      82             :     Word32 *output_fx[],               /* i/o: SCE channels / Binaural synthesis   Q11*/
      83             :     const Word16 n_samples_granularity /* i  : granularity of the renderer/buffer  */
      84             : )
      85             : {
      86             :     Word16 first_sf, last_sf, subframe_idx;
      87             :     Word32 *output_fx_local[BINAURAL_CHANNELS];
      88             :     Word32 reverb_signal_fx[BINAURAL_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES];
      89             :     Word32 *p_reverb_signal_fx[BINAURAL_CHANNELS];
      90             :     Word32 *tc_local_fx[MAX_TRANSPORT_CHANNELS];
      91             :     Word16 ch, slot_size, slots_to_render, output_frame, tmp;
      92             :     ivas_error error;
      93             : 
      94             :     Word16 ism_md_subframe_update_jbm;
      95             :     Word16 c_indx, nS, i;
      96             :     Word16 nchan_ism_internal, nchan_ism, ch_offset;
      97             : 
      98             :     IVAS_QUATERNION *tmp_Quaternion_fx;
      99             :     IVAS_VECTOR3 *tmp_vector_fx;
     100             :     Word16 enableCombinedOrientation;
     101             : 
     102             :     /* Set the number of ISMs */
     103             : #ifdef NONBE_1220_OMASA_JBM_BRATE_SW_FLUSH
     104       41987 :     test();
     105       41987 :     test();
     106       41987 :     IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) || ( EQ_32( st_ivas->ivas_format, MASA_FORMAT ) && GT_16( st_ivas->nchan_ism, 0 ) ) )
     107             : #else
     108             :     IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
     109             : #endif
     110             :     {
     111         122 :         nchan_ism_internal = st_ivas->nchan_ism;
     112         122 :         move16();
     113         122 :         nchan_ism = st_ivas->nchan_ism;
     114         122 :         move16();
     115         122 :         ch_offset = 2;
     116         122 :         move16();
     117             :     }
     118       41865 :     ELSE IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
     119             :     {
     120        9250 :         nchan_ism_internal = st_ivas->nchan_ism;
     121        9250 :         move16();
     122        9250 :         nchan_ism = st_ivas->nchan_ism;
     123        9250 :         move16();
     124        9250 :         ch_offset = 0;
     125        9250 :         move16();
     126             :     }
     127             :     ELSE
     128             :     {
     129       32615 :         nchan_ism_internal = st_ivas->hTcBuffer->nchan_transport_internal;
     130       32615 :         move16();
     131       32615 :         nchan_ism = st_ivas->nchan_transport;
     132       32615 :         move16();
     133       32615 :         ch_offset = 0;
     134       32615 :         move16();
     135             :     }
     136             : 
     137             :     /* Number of subframes to delay metadata to sync with audio */
     138       41987 :     IF( st_ivas->hDecoderConfig->Opt_delay_comp )
     139             :     {
     140       41987 :         ism_md_subframe_update_jbm = s_max( 0, sub( st_ivas->hTcBuffer->nb_subframes, 3 ) );
     141             :     }
     142             :     ELSE
     143             :     {
     144           0 :         ism_md_subframe_update_jbm = sub( st_ivas->hTcBuffer->nb_subframes, 2 );
     145             :     }
     146             : 
     147       41987 :     IF( EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
     148             :     {
     149         122 :         ism_md_subframe_update_jbm = s_max( 0, sub( st_ivas->hTcBuffer->nb_subframes, 2 ) );
     150             :     }
     151             : 
     152      125961 :     FOR( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
     153             :     {
     154       83974 :         p_reverb_signal_fx[ch] = reverb_signal_fx[ch];
     155             :     }
     156      172705 :     FOR( ch = 0; ch < nchan_ism_internal; ch++ )
     157             :     {
     158      130718 :         tc_local_fx[ch] = st_ivas->hTcBuffer->tc_fx[ch + ch_offset] + st_ivas->hTcBuffer->n_samples_rendered;
     159             :     }
     160             : 
     161      125961 :     FOR( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ )
     162             :     {
     163       83974 :         output_fx_local[ch] = output_fx[ch]; // Q11
     164             :     }
     165             : 
     166       41987 :     slot_size = st_ivas->hTcBuffer->n_samples_granularity;
     167       41987 :     move16();
     168             : 
     169             :     /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */
     170       41987 :     tmp = 0;
     171       41987 :     move16();
     172       41987 :     IF( n_samples_granularity != 0 )
     173             :     {
     174       41987 :         tmp = idiv1616( n_samples_granularity, slot_size );
     175             :     }
     176       41987 :     slots_to_render = s_min( sub( st_ivas->hTcBuffer->num_slots, st_ivas->hTcBuffer->slots_rendered ), tmp );
     177       41987 :     first_sf = st_ivas->hTcBuffer->subframes_rendered;
     178       41987 :     move16();
     179       41987 :     last_sf = first_sf;
     180       41987 :     move16();
     181       41987 :     st_ivas->hTcBuffer->slots_rendered = add( st_ivas->hTcBuffer->slots_rendered, slots_to_render );
     182       41987 :     move16();
     183             : 
     184      208682 :     WHILE( slots_to_render > 0 )
     185             :     {
     186      166695 :         slots_to_render = sub( slots_to_render, st_ivas->hTcBuffer->subframe_nbslots[last_sf] );
     187      166695 :         last_sf = add( last_sf, 1 );
     188             :     }
     189             : 
     190      208682 :     FOR( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ )
     191             :     {
     192      166695 :         output_frame = i_mult( st_ivas->hTcBuffer->subframe_nbslots[subframe_idx], st_ivas->hTcBuffer->n_samples_granularity );
     193             : 
     194             :         /* Update object position(s) */
     195      166695 :         c_indx = 0;
     196      166695 :         move16();
     197             : 
     198      686427 :         FOR( nS = 0; nS < nchan_ism; nS++ )
     199             :         {
     200      519732 :             test();
     201      519732 :             IF( !( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && EQ_16( nS, LFE_CHANNEL ) ) ) /* Skip LFE for MC */
     202             :             {
     203      507239 :                 st_ivas->hBinRendererTd->Sources[c_indx]->InputFrame_p_fx = tc_local_fx[nS]; /* Q11 */
     204      507239 :                 st_ivas->hBinRendererTd->Sources[c_indx]->SrcRend_p->InputAvailable = TRUE;
     205      507239 :                 move16();
     206      507239 :                 c_indx = add( c_indx, 1 );
     207             :             }
     208             :         }
     209             : 
     210      166695 :         IF( EQ_16( subframe_idx, ism_md_subframe_update_jbm ) )
     211             :         {
     212       41582 :             IF( ( error = TDREND_Update_object_positions_fx( st_ivas->hBinRendererTd, nchan_ism, st_ivas->ivas_format, st_ivas->hIsmMetaData ) ) != IVAS_ERR_OK )
     213             :             {
     214           0 :                 return error;
     215             :             }
     216             :         }
     217             : 
     218             :         /* Update the listener's location/orientation */
     219      166695 :         IF( st_ivas->hCombinedOrientationData != NULL )
     220             :         {
     221       85693 :             tmp_Quaternion_fx = &st_ivas->hCombinedOrientationData->Quaternions[st_ivas->hCombinedOrientationData->subframe_idx];
     222       85693 :             tmp_vector_fx = &st_ivas->hCombinedOrientationData->listenerPos[st_ivas->hCombinedOrientationData->subframe_idx];
     223       85693 :             enableCombinedOrientation = st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx];
     224       85693 :             move16();
     225             : 
     226             :             /* Shifting x_fx, y_fx, z_fx to the same Q-factor as Listener_p->Pos_q (usually Q25) */
     227       85693 :             Word16 pos_q = st_ivas->hBinRendererTd->Listener_p->Pos_q;
     228       85693 :             move16();
     229       85693 :             tmp_vector_fx->x_fx = L_shr( tmp_vector_fx->x_fx, sub( tmp_vector_fx->q_fact, pos_q ) );
     230       85693 :             tmp_vector_fx->y_fx = L_shr( tmp_vector_fx->y_fx, sub( tmp_vector_fx->q_fact, pos_q ) );
     231       85693 :             tmp_vector_fx->z_fx = L_shr( tmp_vector_fx->z_fx, sub( tmp_vector_fx->q_fact, pos_q ) );
     232       85693 :             tmp_vector_fx->q_fact = pos_q;
     233       85693 :             move16();
     234             :         }
     235             :         ELSE
     236             :         {
     237       81002 :             tmp_Quaternion_fx = NULL;
     238       81002 :             tmp_vector_fx = NULL;
     239       81002 :             enableCombinedOrientation = 0;
     240       81002 :             move16();
     241             :         }
     242             : 
     243      166695 :         IF( NE_32( ( error = TDREND_Update_listener_orientation_fx( st_ivas->hBinRendererTd, enableCombinedOrientation, tmp_Quaternion_fx, tmp_vector_fx ) ), IVAS_ERR_OK ) )
     244             :         {
     245           0 :             return error;
     246             :         }
     247             : 
     248      166695 :         test();
     249      166695 :         IF( st_ivas->hRenderConfig != NULL && EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
     250             :         {
     251      122347 :             FOR( i = 0; i < nchan_ism_internal; ++i )
     252             :             {
     253       98604 :                 scale_sig32( tc_local_fx[i], st_ivas->hReverb->full_block_size, -4 ); // Q11 - 4 = Q7
     254             :             }
     255             : 
     256       23743 :             IF( NE_32( ( error = ivas_reverb_process_fx( st_ivas->hReverb, st_ivas->transport_config, 0, tc_local_fx, p_reverb_signal_fx, 0 ) ), IVAS_ERR_OK ) ) // Q(p_reverb_signal_fx) = 11
     257             :             {
     258           0 :                 return error;
     259             :             }
     260             : 
     261      122347 :             FOR( i = 0; i < nchan_ism_internal; ++i )
     262             :             {
     263       98604 :                 scale_sig32( tc_local_fx[i], st_ivas->hReverb->full_block_size, 4 ); // Q7 + 4 = Q11
     264             :             }
     265             : 
     266       71229 :             FOR( i = 0; i < BINAURAL_CHANNELS; ++i )
     267             :             {
     268       47486 :                 scale_sig32( p_reverb_signal_fx[i], st_ivas->hReverb->full_block_size, 2 + 4 ); // Q5 + 6 = Q11
     269             :             }
     270             :         }
     271             : 
     272             :         /* Render subframe */
     273             :         /* ism_md_subframe_update_jbm != subframe_idx: trigger update only for ism_md_subframe_update_jbm == subframe_idx,
     274             :            where then the two TDREND_GetMix()-arguments subframe_idx and ism_md_subframe_update are equal, and we want to enforce the update inside TDREND_GetMix to use subframe_idx == 0 */
     275             : #ifdef NONBE_FIX_1196_TD_HEADTRACKING_INTERPOLATION
     276      166695 :         IF( NE_32( ( error = TDREND_GetMix_fx( st_ivas->hBinRendererTd, output_fx_local, output_frame, 0 ) ), IVAS_ERR_OK ) )
     277             : #else
     278             :         IF( NE_32( ( error = TDREND_GetMix_fx( st_ivas->hBinRendererTd, output_fx_local, output_frame, 0, ism_md_subframe_update_jbm != subframe_idx ) ), IVAS_ERR_OK ) )
     279             : #endif
     280             :         {
     281           0 :             return error;
     282             :         }
     283             : 
     284      166695 :         test();
     285      166695 :         IF( st_ivas->hRenderConfig != NULL && EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
     286             :         {
     287             :             /* add reverb to rendered signals */
     288       23743 :             v_add_32( reverb_signal_fx[0], output_fx_local[0], output_fx_local[0], output_frame ); // Q11
     289       23743 :             v_add_32( reverb_signal_fx[1], output_fx_local[1], output_fx_local[1], output_frame );
     290             :         }
     291             : 
     292      686427 :         FOR( ch = 0; ch < nchan_ism_internal; ch++ )
     293             :         {
     294      519732 :             tc_local_fx[ch] += output_frame;
     295             :         }
     296             : 
     297      500085 :         FOR( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ )
     298             :         {
     299      333390 :             output_fx_local[ch] += output_frame;
     300             :         }
     301             : 
     302             :         /* update combined orientation access index */
     303      166695 :         ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, output_frame );
     304             :     }
     305             : 
     306       41987 :     st_ivas->hTcBuffer->subframes_rendered = last_sf;
     307       41987 :     move16();
     308             : 
     309       41987 :     return IVAS_ERR_OK;
     310             : }
     311             : 
     312             : /*---------------------------------------------------------------------*
     313             :  * ivas_td_binaural_renderer_sf_splitBinaural()
     314             :  *
     315             :  * Render to multiple binaural pairs based on relative head positions for split rendering.
     316             :  *---------------------------------------------------------------------*/
     317             : 
     318           0 : ivas_error ivas_td_binaural_renderer_sf_splitBinaural(
     319             :     Decoder_Struct *st_ivas,      /* i/o: IVAS decoder structure                    */
     320             :     Word32 *output[],             /* i/o: SCE channels / Binaural synthesis         */
     321             :     const Word16 nSamplesRendered /* i  : number of samples to render               */
     322             : )
     323             : {
     324             :     Word16 i;
     325             :     Word16 pos_idx;
     326             :     IVAS_QUATERNION originalHeadRot[MAX_PARAM_SPATIAL_SUBFRAMES];
     327             :     MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData;
     328             :     BINAURAL_TD_OBJECT_RENDERER_HANDLE origTdRendHandle;
     329             :     ivas_error error;
     330             :     Word16 original_subframes_rendered;
     331             :     Word16 original_slots_rendered;
     332             :     Word32 *p_bin_output[BINAURAL_CHANNELS];
     333             :     Word32 output_local[MAX_OUTPUT_CHANNELS][L_FRAME48k];
     334             :     Word16 q_fact_orig[MAX_PARAM_SPATIAL_SUBFRAMES];
     335             : 
     336             :     Word16 SrcInd[MAX_NUM_TDREND_CHANNELS];
     337             : 
     338           0 :     pMultiBinPoseData = &st_ivas->hSplitBinRend->splitrend.multiBinPoseData;
     339           0 :     move32();
     340             : 
     341             :     /* If not yet allocated, open additional instances of TD renderer */
     342           0 :     FOR( i = 0; i < pMultiBinPoseData->num_poses - 1; ++i )
     343             :     {
     344           0 :         IF( st_ivas->hTdRendHandles[i] != NULL )
     345             :         {
     346           0 :             continue;
     347             :         }
     348             : #ifdef CONF_DISTATT
     349           0 :         IF( ( error = ivas_td_binaural_open_unwrap_fx( &st_ivas->hHrtfTD,
     350             :                                                        st_ivas->hDecoderConfig->output_Fs,
     351             :                                                        st_ivas->nchan_transport,
     352             :                                                        st_ivas->ivas_format,
     353             :                                                        st_ivas->transport_config,
     354             :                                                        st_ivas->hRenderConfig->directivity_fx,
     355             :                                                        st_ivas->hRenderConfig->distAtt_fx,
     356             :                                                        st_ivas->hTransSetup,
     357             :                                                        &st_ivas->hTdRendHandles[i],
     358             :                                                        &st_ivas->binaural_latency_ns,
     359             :                                                        SrcInd ) ) != IVAS_ERR_OK )
     360             : #else
     361             :         IF( ( error = ivas_td_binaural_open_unwrap_fx( &st_ivas->hHrtfTD,
     362             :                                                        st_ivas->hDecoderConfig->output_Fs,
     363             :                                                        st_ivas->nchan_transport,
     364             :                                                        st_ivas->ivas_format,
     365             :                                                        st_ivas->transport_config,
     366             :                                                        st_ivas->hRenderConfig->directivity_fx,
     367             :                                                        st_ivas->hTransSetup,
     368             :                                                        &st_ivas->hTdRendHandles[i],
     369             :                                                        &st_ivas->binaural_latency_ns,
     370             :                                                        SrcInd ) ) != IVAS_ERR_OK )
     371             : #endif
     372             :         {
     373           0 :             return error;
     374             :         }
     375             :     }
     376             : 
     377             :     /* Save current head positions */
     378           0 :     FOR( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i )
     379             :     {
     380           0 :         originalHeadRot[i] = st_ivas->hCombinedOrientationData->Quaternions[i];
     381           0 :         q_fact_orig[i] = originalHeadRot[i].q_fact;
     382             :     }
     383             : 
     384           0 :     original_subframes_rendered = st_ivas->hTcBuffer->subframes_rendered;
     385           0 :     move16();
     386           0 :     original_slots_rendered = st_ivas->hTcBuffer->slots_rendered;
     387           0 :     move16();
     388           0 :     origTdRendHandle = st_ivas->hBinRendererTd;
     389           0 :     move32();
     390             : 
     391           0 :     FOR( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i )
     392             :     {
     393           0 :         modify_Quat_q_fx( &originalHeadRot[i], &originalHeadRot[i], Q22 );
     394             :     }
     395             : 
     396           0 :     FOR( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ )
     397             :     {
     398             :         /* Update head positions */
     399           0 :         IF( NE_16( pos_idx, 0 ) )
     400             :         {
     401           0 :             COMBINED_ORIENTATION_HANDLE pCombinedOrientationData = st_ivas->hCombinedOrientationData;
     402           0 :             FOR( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i )
     403             :             {
     404           0 :                 pCombinedOrientationData->Quaternions[i].w_fx = L_negate( 12582912 ); // Q22
     405             :                 /*euler*/
     406           0 :                 Quat2EulerDegree_fx( originalHeadRot[i],
     407           0 :                                      &pCombinedOrientationData->Quaternions[i].z_fx,
     408           0 :                                      &pCombinedOrientationData->Quaternions[i].y_fx,
     409           0 :                                      &pCombinedOrientationData->Quaternions[i].x_fx );
     410           0 :                 pCombinedOrientationData->Quaternions[i].x_fx = L_add( pCombinedOrientationData->Quaternions[i].x_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] );
     411           0 :                 pCombinedOrientationData->Quaternions[i].y_fx = L_add( pCombinedOrientationData->Quaternions[i].y_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] );
     412           0 :                 pCombinedOrientationData->Quaternions[i].z_fx = L_add( pCombinedOrientationData->Quaternions[i].z_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] );
     413             : 
     414           0 :                 Euler2Quat_fx( deg2rad_fx( pCombinedOrientationData->Quaternions[i].x_fx ),
     415             :                                deg2rad_fx( pCombinedOrientationData->Quaternions[i].y_fx ),
     416           0 :                                deg2rad_fx( pCombinedOrientationData->Quaternions[i].z_fx ), &pCombinedOrientationData->Quaternions[i] );
     417             : 
     418           0 :                 modify_Quat_q_fx( &pCombinedOrientationData->Quaternions[i], &pCombinedOrientationData->Quaternions[i], q_fact_orig[i] );
     419             :             }
     420             :         }
     421             : 
     422             :         /* set output channels */
     423           0 :         FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
     424             :         {
     425           0 :             p_bin_output[i] = output_local[add( i_mult( pos_idx, BINAURAL_CHANNELS ), i )];
     426           0 :             move32();
     427             :         }
     428           0 :         st_ivas->hTcBuffer->subframes_rendered = original_subframes_rendered;
     429           0 :         move16();
     430           0 :         st_ivas->hTcBuffer->slots_rendered = original_slots_rendered;
     431           0 :         move16();
     432             : 
     433             :         /* update combined orientation access index */
     434           0 :         ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData );
     435             : 
     436             :         /* Render */
     437           0 :         IF( NE_16( pos_idx, 0 ) )
     438             :         {
     439           0 :             st_ivas->hBinRendererTd = st_ivas->hTdRendHandles[sub( pos_idx, 1 )];
     440           0 :             move32();
     441             :         }
     442             : 
     443           0 :         IF( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_bin_output, nSamplesRendered ) ) != IVAS_ERR_OK )
     444             :         {
     445           0 :             return error;
     446             :         }
     447             : 
     448           0 :         IF( EQ_16( st_ivas->ivas_format, MC_FORMAT ) )
     449             :         {
     450             :             Word32 *p_tc[MAX_TRANSPORT_CHANNELS];
     451           0 :             FOR( i = 0; i < st_ivas->nchan_transport; i++ )
     452             :             {
     453           0 :                 p_tc[i] = st_ivas->hTcBuffer->tc_fx[i] + st_ivas->hTcBuffer->n_samples_rendered;
     454             :             }
     455           0 :             ivas_binaural_add_LFE_fx( st_ivas, nSamplesRendered, p_tc, p_bin_output );
     456             :         }
     457             :     }
     458             : 
     459           0 :     FOR( i = 0; i < i_mult( pMultiBinPoseData->num_poses, BINAURAL_CHANNELS ); i++ )
     460             :     {
     461           0 :         Copy32( output_local[i], output[i], nSamplesRendered );
     462             :     }
     463             : 
     464             :     /* Restore original head rotation */
     465           0 :     FOR( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i )
     466             :     {
     467           0 :         modify_Quat_q_fx( &originalHeadRot[i], &originalHeadRot[i], q_fact_orig[i] );
     468           0 :         st_ivas->hCombinedOrientationData->Quaternions[i] = originalHeadRot[i];
     469           0 :         move32();
     470             :     }
     471             : 
     472             :     /* restore original td renderer handle */
     473           0 :     st_ivas->hBinRendererTd = origTdRendHandle;
     474           0 :     move32();
     475             : 
     476           0 :     return IVAS_ERR_OK;
     477             : }

Generated by: LCOV version 1.14