LCOV - code coverage report
Current view: top level - lib_dec - ivas_ism_renderer.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 189 197 95.9 %
Date: 2025-05-23 08:37:30 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <stdint.h>
      34             : #include "options.h"
      35             : #include "ivas_cnst.h"
      36             : #include "prot.h"
      37             : #include "ivas_prot.h"
      38             : #include "ivas_prot_rend.h"
      39             : #include "ivas_stat_com.h"
      40             : #include "ivas_rom_com.h"
      41             : #include "ivas_rom_dec.h"
      42             : #include <math.h>
      43             : #ifdef DEBUGGING
      44             : #include "debug.h"
      45             : #endif
      46             : #include "wmc_auto.h"
      47             : 
      48             : 
      49             : /*-------------------------------------------------------------------------*
      50             :  * ivas_ism_renderer_open()
      51             :  *
      52             :  * Open struct for object rendering, reserve memory, and init values.
      53             :  *-------------------------------------------------------------------------*/
      54             : 
      55        1281 : ivas_error ivas_ism_renderer_open(
      56             :     Decoder_Struct *st_ivas /* i/o: IVAS decoder structure      */
      57             : )
      58             : {
      59             :     int16_t i;
      60             :     uint16_t interpolator_length;
      61             :     uint16_t init_interpolator_length;
      62             :     ivas_error error;
      63             : 
      64        1281 :     if ( ( st_ivas->hIsmRendererData = (ISM_RENDERER_HANDLE) malloc( sizeof( ISM_RENDERER_DATA ) ) ) == NULL )
      65             :     {
      66           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM renderer\n" ) );
      67             :     }
      68             : 
      69        1281 :     if ( st_ivas->hIntSetup.is_loudspeaker_setup &&
      70         642 :          st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_STEREO &&
      71         549 :          st_ivas->hIntSetup.ls_azimuth != NULL && st_ivas->hIntSetup.ls_elevation != NULL &&
      72         549 :          st_ivas->hEFAPdata == NULL )
      73             :     {
      74         549 :         if ( ( error = efap_init_data( &( st_ivas->hEFAPdata ), st_ivas->hIntSetup.ls_azimuth, st_ivas->hIntSetup.ls_elevation, st_ivas->hIntSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK )
      75             :         {
      76           0 :             return error;
      77             :         }
      78             :     }
      79             : 
      80        6405 :     for ( i = 0; i < MAX_NUM_OBJECTS; i++ )
      81             :     {
      82        5124 :         set_f( st_ivas->hIsmRendererData->prev_gains[i], 0.0f, MAX_OUTPUT_CHANNELS );
      83        5124 :         set_f( st_ivas->hIsmRendererData->gains[i], 0.0f, MAX_OUTPUT_CHANNELS );
      84             :     }
      85             : 
      86        1281 :     if ( st_ivas->hDecoderConfig->Opt_tsm )
      87             :     {
      88         303 :         init_interpolator_length = NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_CLDFB_TIMESLOTS * CLDFB_SLOT_NS );
      89         303 :         interpolator_length = (uint16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC );
      90             :     }
      91             :     else
      92             :     {
      93         978 :         init_interpolator_length = (uint16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC );
      94         978 :         interpolator_length = init_interpolator_length;
      95             :     }
      96             : 
      97        1281 :     if ( ( st_ivas->hIsmRendererData->interpolator = (float *) malloc( sizeof( float ) * init_interpolator_length ) ) == NULL )
      98             :     {
      99           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM renderer interpolator\n" ) );
     100             :     }
     101             : 
     102     1054401 :     for ( i = 0; i < interpolator_length; i++ )
     103             :     {
     104     1053120 :         st_ivas->hIsmRendererData->interpolator[i] = (float) i / ( (float) interpolator_length - 1 );
     105             :     }
     106             : 
     107        1281 :     return IVAS_ERR_OK;
     108             : }
     109             : 
     110             : 
     111             : /*-------------------------------------------------------------------------*
     112             :  * ivas_ism_renderer_close()
     113             :  *
     114             :  * Close struct for object rendering.
     115             :  *-------------------------------------------------------------------------*/
     116             : 
     117        9813 : void ivas_ism_renderer_close(
     118             :     ISM_RENDERER_HANDLE *hIsmRendererData /* i/o: ISM renderer handle */
     119             : )
     120             : {
     121        9813 :     if ( hIsmRendererData == NULL || *hIsmRendererData == NULL )
     122             :     {
     123        6993 :         return;
     124             :     }
     125             : 
     126        2820 :     if ( ( *hIsmRendererData )->interpolator != NULL )
     127             :     {
     128        2820 :         free( ( *hIsmRendererData )->interpolator );
     129        2820 :         ( *hIsmRendererData )->interpolator = NULL;
     130             :     }
     131             : 
     132        2820 :     free( *hIsmRendererData );
     133        2820 :     *hIsmRendererData = NULL;
     134             : 
     135        2820 :     return;
     136             : }
     137             : 
     138             : 
     139             : /*-------------------------------------------------------------------------*
     140             :  * ivas_ism_render_sf()
     141             :  *
     142             :  * Object rendering process
     143             :  *-------------------------------------------------------------------------*/
     144             : 
     145      188283 : void ivas_ism_render_sf(
     146             :     Decoder_Struct *st_ivas,           /* i/o: IVAS decoder structure                      */
     147             :     const RENDERER_TYPE renderer_type, /* i  : active renderer type                        */
     148             :     float *output_f[],                 /* i/o: core-coder transport channels/object output */
     149             :     const int16_t n_samples_to_render  /* i  : output frame length per channel             */
     150             : )
     151             : {
     152             :     int16_t i, j, k, j2;
     153             :     float *g1, g2, *tc;
     154             :     int16_t num_objects, nchan_out_woLFE, lfe_index;
     155             :     int16_t azimuth, elevation;
     156             :     int16_t tc_offset;
     157             :     int16_t interp_offset;
     158             :     float gain, prev_gain;
     159             :     float tc_local[MAX_NUM_OBJECTS][L_FRAME48k];
     160             :     float *p_tc[MAX_NUM_OBJECTS];
     161             :     int16_t ism_md_subframe_update_jbm, slots_to_render, first_sf, last_sf, subframe_idx;
     162             :     int16_t n_samples_rendered_loop;
     163             : 
     164             :     /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */
     165      188283 :     slots_to_render = min( st_ivas->hTcBuffer->num_slots - st_ivas->hTcBuffer->slots_rendered, n_samples_to_render / st_ivas->hTcBuffer->n_samples_granularity );
     166      188283 :     first_sf = st_ivas->hTcBuffer->subframes_rendered;
     167      188283 :     last_sf = first_sf;
     168      188283 :     n_samples_rendered_loop = 0;
     169             : 
     170      506757 :     while ( slots_to_render > 0 )
     171             :     {
     172      318474 :         slots_to_render -= st_ivas->hTcBuffer->subframe_nbslots[last_sf];
     173      318474 :         last_sf++;
     174             :     }
     175             : #ifdef DEBUGGING
     176             :     assert( slots_to_render == 0 );
     177             :     assert( last_sf <= st_ivas->hTcBuffer->nb_subframes );
     178             : #endif
     179      188283 :     num_objects = st_ivas->nchan_ism;
     180             : 
     181      188283 :     nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE;
     182             : 
     183      188283 :     tc_offset = st_ivas->hTcBuffer->n_samples_rendered;
     184      188283 :     interp_offset = st_ivas->hTcBuffer->n_samples_rendered;
     185             : 
     186             :     /* Number of subframes to delay metadata to sync with audio */
     187      188283 :     if ( st_ivas->hDecoderConfig->Opt_delay_comp )
     188             :     {
     189      188283 :         ism_md_subframe_update_jbm = max( 0, st_ivas->hTcBuffer->nb_subframes - 3 );
     190             :     }
     191             :     else
     192             :     {
     193           0 :         ism_md_subframe_update_jbm = st_ivas->hTcBuffer->nb_subframes - 2;
     194             :     }
     195             : 
     196      188283 :     if ( st_ivas->hDecoderConfig->Opt_tsm )
     197             :     {
     198       65928 :         for ( i = 0; i < num_objects; i++ )
     199             :         {
     200       49446 :             p_tc[i] = &st_ivas->hTcBuffer->tc[i][tc_offset];
     201             :         }
     202             :     }
     203             :     else
     204             :     {
     205      637847 :         for ( i = 0; i < num_objects; i++ )
     206             :         {
     207      466046 :             mvr2r( &output_f[i][tc_offset], tc_local[i], n_samples_to_render );
     208      466046 :             p_tc[i] = tc_local[i];
     209             :         }
     210             :     }
     211             : 
     212     1899815 :     for ( i = 0; i < nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; i++ )
     213             :     {
     214     1711532 :         set_f( output_f[i], 0.0f, n_samples_to_render );
     215             :     }
     216             : 
     217      506757 :     for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ )
     218             :     {
     219             :         int16_t n_samples_in_subframe;
     220             : 
     221      318474 :         n_samples_in_subframe = st_ivas->hTcBuffer->n_samples_granularity * st_ivas->hTcBuffer->subframe_nbslots[subframe_idx];
     222             : 
     223      318474 :         if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 )
     224             :         {
     225       35976 :             ivas_jbm_dec_get_adapted_linear_interpolator( n_samples_in_subframe, n_samples_in_subframe, st_ivas->hIsmRendererData->interpolator );
     226       35976 :             interp_offset = 0;
     227             :         }
     228             : 
     229     1189284 :         for ( i = 0; i < num_objects; i++ )
     230             :         {
     231             :             /* Combined rotation: rotate the object positions depending the head and external orientations */
     232      870810 :             if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 )
     233             :             {
     234       35976 :                 if ( subframe_idx >= ism_md_subframe_update_jbm )
     235             :                 {
     236       26982 :                     rotateAziEle( st_ivas->hIsmMetaData[i]->edited_azimuth, st_ivas->hIsmMetaData[i]->edited_elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat[st_ivas->hCombinedOrientationData->subframe_idx], st_ivas->hIntSetup.is_planar_setup );
     237             :                 }
     238             :                 else
     239             :                 {
     240        8994 :                     rotateAziEle( st_ivas->hIsmMetaData[i]->edited_azimuth, st_ivas->hIsmMetaData[i]->edited_elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat[st_ivas->hCombinedOrientationData->subframe_idx], st_ivas->hIntSetup.is_planar_setup );
     241             :                 }
     242             : 
     243       35976 :                 if ( st_ivas->hEFAPdata != NULL )
     244             :                 {
     245       35976 :                     efap_determine_gains( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains[i], azimuth, elevation, EFAP_MODE_EFAP );
     246       35976 :                     v_multc( st_ivas->hIsmRendererData->gains[i], st_ivas->hIsmMetaData[i]->edited_gain, st_ivas->hIsmRendererData->gains[i], nchan_out_woLFE );
     247             :                 }
     248             :             }
     249             : 
     250      870810 :             lfe_index = 0;
     251     8101977 :             for ( j = 0, j2 = 0; j < nchan_out_woLFE; j++, j2++ )
     252             :             {
     253     7231167 :                 if ( ( st_ivas->hIntSetup.num_lfe > 0 ) && ( st_ivas->hIntSetup.index_lfe[lfe_index] == j ) )
     254             :                 {
     255      533361 :                     ( lfe_index < ( st_ivas->hIntSetup.num_lfe - 1 ) ) ? ( lfe_index++, j2++ ) : j2++;
     256             :                 }
     257             : 
     258     7231167 :                 gain = st_ivas->hIsmRendererData->gains[i][j];
     259     7231167 :                 prev_gain = st_ivas->hIsmRendererData->prev_gains[i][j];
     260     7231167 :                 if ( fabsf( gain ) > 0.0f || fabsf( prev_gain ) > 0.0f )
     261             :                 {
     262     3653355 :                     g1 = &st_ivas->hIsmRendererData->interpolator[interp_offset];
     263     3653355 :                     tc = p_tc[i];
     264   796874715 :                     for ( k = 0; k < n_samples_in_subframe; k++ )
     265             :                     {
     266   793221360 :                         g2 = 1.0f - *g1;
     267   793221360 :                         output_f[j2][k + n_samples_rendered_loop] += ( *( g1++ ) * gain + g2 * prev_gain ) * *( tc++ );
     268             :                     }
     269             :                 }
     270             : 
     271             :                 /* update here only in case of head rotation */
     272     7231167 :                 if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 )
     273             :                 {
     274      395736 :                     st_ivas->hIsmRendererData->prev_gains[i][j] = gain;
     275             :                 }
     276             :             }
     277      870810 :             p_tc[i] += n_samples_in_subframe;
     278             :         }
     279             : 
     280             :         /* update combined orientation access index */
     281      318474 :         ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_in_subframe );
     282             : 
     283      318474 :         n_samples_rendered_loop += n_samples_in_subframe;
     284             :         /* update rendered subframe and slots info for all cases apart from a following crend call, the update will
     285             :            then happen in the crend call*/
     286      318474 :         if ( renderer_type != RENDERER_BINAURAL_MIXER_CONV_ROOM )
     287             :         {
     288      188883 :             st_ivas->hTcBuffer->subframes_rendered += 1;
     289      188883 :             st_ivas->hTcBuffer->slots_rendered += st_ivas->hTcBuffer->subframe_nbslots[subframe_idx];
     290             :         }
     291      318474 :         tc_offset += n_samples_in_subframe;
     292      318474 :         interp_offset += n_samples_in_subframe;
     293             :     }
     294             : 
     295      188283 :     return;
     296             : }
     297             : 
     298             : 
     299             : /*-------------------------------------------------------------------------*
     300             :  * ivas_ism_get_stereo_gains()
     301             :  *
     302             :  *
     303             :  *-------------------------------------------------------------------------*/
     304             : 
     305      354400 : void ivas_ism_get_stereo_gains(
     306             :     const float azimuth,   /* i  : object azimuth       */
     307             :     const float elevation, /* i  : object elevation     */
     308             :     float *left_gain,      /* o  : left channel gain    */
     309             :     float *right_gain      /* o  : right channel gain   */
     310             : )
     311             : {
     312             :     float aziRad, eleRad;
     313             :     float y, mappedX, aziRadMapped, A, A2, A3;
     314      354400 :     const float LsAngleRad = 30.0f * PI_OVER_180;
     315             : 
     316             :     /* Convert azi and ele to an azi value of the cone of confusion */
     317      354400 :     aziRad = azimuth * PI_OVER_180;
     318      354400 :     eleRad = elevation * PI_OVER_180;
     319      354400 :     y = ( sinf( aziRad ) * cosf( eleRad ) );
     320      354400 :     mappedX = sqrtf( max( 0.0f, 1.0f - ( y * y ) ) );
     321      354400 :     aziRadMapped = atan2f( y, mappedX );
     322             : 
     323             :     /* Determine the amplitude panning gains */
     324      354400 :     if ( aziRadMapped >= LsAngleRad )
     325             :     { /* Left side */
     326       72152 :         *left_gain = 1.0f;
     327       72152 :         *right_gain = 0.0f;
     328             :     }
     329      282248 :     else if ( aziRadMapped <= -LsAngleRad )
     330             :     { /* Right side */
     331       74684 :         *left_gain = 0.0f;
     332       74684 :         *right_gain = 1.0f;
     333             :     }
     334             :     else /* Tangent panning law */
     335             :     {
     336      207564 :         A = tanf( aziRadMapped ) / tanf( LsAngleRad );
     337      207564 :         A2 = ( A - 1.0f ) / max( 0.001f, A + 1.0f );
     338      207564 :         A3 = 1.0f / ( A2 * A2 + 1.0f );
     339      207564 :         *left_gain = sqrtf( A3 );
     340      207564 :         *right_gain = sqrtf( 1.0f - A3 );
     341             :     }
     342             : 
     343      354400 :     return;
     344             : }
     345             : 
     346             : 
     347             : /*-------------------------------------------------------------------------*
     348             :  * ivas_omasa_separate_object_renderer_open()
     349             :  *
     350             :  * Open structures, reserve memory, and init values.
     351             :  *-------------------------------------------------------------------------*/
     352             : 
     353        1485 : ivas_error ivas_omasa_separate_object_renderer_open(
     354             :     Decoder_Struct *st_ivas /* i/o: IVAS decoder structure      */
     355             : )
     356             : {
     357             :     int16_t interpolator_length;
     358             :     int16_t i;
     359             :     int16_t init_interpolator_length;
     360             : 
     361        1485 :     if ( ( st_ivas->hIsmRendererData = (ISM_RENDERER_HANDLE) malloc( sizeof( ISM_RENDERER_DATA ) ) ) == NULL )
     362             :     {
     363           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM renderer \n" ) );
     364             :     }
     365             : 
     366        7425 :     for ( i = 0; i < MAX_NUM_OBJECTS; i++ )
     367             :     {
     368        5940 :         set_f( st_ivas->hIsmRendererData->prev_gains[i], 0.0f, MAX_OUTPUT_CHANNELS );
     369             :     }
     370             : 
     371        1485 :     init_interpolator_length = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES );
     372        1485 :     interpolator_length = init_interpolator_length;
     373        1485 :     if ( ( st_ivas->hIsmRendererData->interpolator = (float *) malloc( sizeof( float ) * init_interpolator_length ) ) == NULL )
     374             :     {
     375           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM renderer interpolator \n" ) );
     376             :     }
     377             : 
     378      357165 :     for ( i = 0; i < interpolator_length; i++ )
     379             :     {
     380      355680 :         st_ivas->hIsmRendererData->interpolator[i] = (float) i / ( (float) interpolator_length );
     381             :     }
     382        1485 :     st_ivas->hIsmRendererData->interpolator_length = interpolator_length;
     383             : 
     384        1485 :     return IVAS_ERR_OK;
     385             : }
     386             : 
     387             : 
     388             : /*-------------------------------------------------------------------------*
     389             :  * ivas_omasa_separate_object_renderer_close()
     390             :  *
     391             :  * Close structures, free memory.
     392             :  *-------------------------------------------------------------------------*/
     393             : 
     394        6012 : void ivas_omasa_separate_object_renderer_close(
     395             :     Decoder_Struct *st_ivas /* i/o: IVAS decoder structure      */
     396             : )
     397             : {
     398             :     int16_t i;
     399             : 
     400        6012 :     if ( st_ivas->hMasaIsmData != NULL )
     401             :     {
     402        6012 :         if ( st_ivas->hMasaIsmData->delayBuffer != NULL )
     403             :         {
     404        5184 :             for ( i = 0; i < st_ivas->hMasaIsmData->delayBuffer_nchan; i++ )
     405             :             {
     406        3441 :                 if ( st_ivas->hMasaIsmData->delayBuffer[i] != NULL )
     407             :                 {
     408        3441 :                     free( st_ivas->hMasaIsmData->delayBuffer[i] );
     409        3441 :                     st_ivas->hMasaIsmData->delayBuffer[i] = NULL;
     410             :                 }
     411             :             }
     412             : 
     413        1743 :             free( st_ivas->hMasaIsmData->delayBuffer );
     414        1743 :             st_ivas->hMasaIsmData->delayBuffer = NULL;
     415             :         }
     416             :     }
     417             : 
     418        6012 :     ivas_ism_renderer_close( &st_ivas->hIsmRendererData );
     419             : 
     420        6012 :     return;
     421             : }
     422             : 
     423             : 
     424             : /*-------------------------------------------------------------------------*
     425             :  * ivas_omasa_separate_object_render_jbm()
     426             :  *
     427             :  * Rendering separated objects and mixing them to the parametrically rendered signals for JBM
     428             :  *-------------------------------------------------------------------------*/
     429             : 
     430       18845 : void ivas_omasa_separate_object_render_jbm(
     431             :     Decoder_Struct *st_ivas,          /* i/o: IVAS decoder structure                      */
     432             :     const uint16_t nSamplesRendered,  /* i  : number of samples rendered                  */
     433             :     float input_f_in[][L_FRAME48k],   /* i  : separated object signal                     */
     434             :     float *output_f[],                /* o  : rendered time signal                        */
     435             :     const int16_t subframes_rendered, /* i  : number of subframes rendered                */
     436             :     const int16_t slots_rendered      /* i  : number of CLDFB slots rendered              */
     437             : )
     438             : {
     439             :     VBAP_HANDLE hVBAPdata;
     440             :     DIRAC_REND_HANDLE hDirACRend;
     441             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
     442             :     int16_t nchan_out_woLFE, num_lfe;
     443             :     ISM_RENDERER_HANDLE hRendererData;
     444             :     int16_t j, k, j2;
     445             :     int16_t obj;
     446             :     float gains[MAX_OUTPUT_CHANNELS];
     447             :     float g1, g2;
     448             :     int16_t lfe_index;
     449             :     int16_t azimuth, elevation;
     450             :     int16_t num_objects;
     451             :     uint8_t single_separated;
     452             :     float *input_f[MAX_TRANSPORT_CHANNELS];
     453             :     float *output_f_local[MAX_OUTPUT_CHANNELS];
     454             :     int16_t offsetSamples;
     455             :     int16_t n_samples_sf, md_idx;
     456             :     int16_t slots_to_render, first_sf, last_sf, subframe_idx;
     457             : 
     458       18845 :     hVBAPdata = st_ivas->hVBAPdata;
     459       18845 :     hDirACRend = st_ivas->hDirACRend;
     460       18845 :     hSpatParamRendCom = st_ivas->hSpatParamRendCom;
     461       18845 :     nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE;
     462       18845 :     num_lfe = st_ivas->hIntSetup.num_lfe;
     463       18845 :     hRendererData = st_ivas->hIsmRendererData;
     464       18845 :     lfe_index = hDirACRend->hOutSetup.index_lfe[0];
     465             : 
     466       18845 :     if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
     467             :     {
     468       10491 :         single_separated = 1;
     469       10491 :         num_objects = 1;
     470             :     }
     471             :     else
     472             :     {
     473        8354 :         single_separated = 0;
     474        8354 :         num_objects = st_ivas->nchan_ism;
     475             :     }
     476             : 
     477       18845 :     offsetSamples = slots_rendered * hSpatParamRendCom->slot_size;
     478             : 
     479      191755 :     for ( j = 0; j < nchan_out_woLFE + num_lfe; j++ )
     480             :     {
     481      172910 :         output_f_local[j] = output_f[j];
     482             :     }
     483             : 
     484       18845 :     if ( st_ivas->hDecoderConfig->Opt_tsm )
     485             :     {
     486       17629 :         for ( obj = 0; obj < num_objects; obj++ )
     487             :         {
     488       11370 :             input_f[obj] = &st_ivas->hTcBuffer->tc[obj + 2][offsetSamples];
     489             :         }
     490             :     }
     491             :     else
     492             :     {
     493       31990 :         for ( obj = 0; obj < num_objects; obj++ )
     494             :         {
     495       19404 :             input_f[obj] = input_f_in[obj];
     496             :         }
     497             :     }
     498             : 
     499       18845 :     slots_to_render = nSamplesRendered / hSpatParamRendCom->slot_size;
     500       18845 :     first_sf = subframes_rendered;
     501       18845 :     last_sf = first_sf;
     502             : 
     503       49949 :     while ( slots_to_render > 0 )
     504             :     {
     505       31104 :         slots_to_render -= hSpatParamRendCom->subframe_nbslots[last_sf];
     506       31104 :         last_sf++;
     507             :     }
     508             : 
     509       49619 :     for ( obj = 0; obj < num_objects; obj++ )
     510             :     {
     511       30774 :         offsetSamples = 0;
     512             : 
     513       81369 :         for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ )
     514             :         {
     515       50595 :             n_samples_sf = hSpatParamRendCom->subframe_nbslots[subframe_idx] * hSpatParamRendCom->slot_size;
     516       50595 :             if ( n_samples_sf != hRendererData->interpolator_length )
     517             :             {
     518      743036 :                 for ( k = 0; k < n_samples_sf; k++ )
     519             :                 {
     520      738720 :                     hRendererData->interpolator[k] = (float) k / ( (float) n_samples_sf );
     521             :                 }
     522        4316 :                 hRendererData->interpolator_length = n_samples_sf;
     523             :             }
     524             : 
     525       50595 :             md_idx = hSpatParamRendCom->render_to_md_map[subframe_idx];
     526             : 
     527       50595 :             if ( single_separated )
     528             :             {
     529       17325 :                 if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && st_ivas->hMasaIsmData->ism_dir_is_edited[st_ivas->hMasaIsmData->idx_separated_ism] )
     530             :                 {
     531           0 :                     azimuth = st_ivas->hMasaIsmData->azimuth_ism_edited[st_ivas->hMasaIsmData->idx_separated_ism];
     532           0 :                     elevation = st_ivas->hMasaIsmData->elevation_ism_edited[st_ivas->hMasaIsmData->idx_separated_ism];
     533             :                 }
     534             :                 else
     535             :                 {
     536       17325 :                     azimuth = st_ivas->hMasaIsmData->azimuth_separated_ism[md_idx];
     537       17325 :                     elevation = st_ivas->hMasaIsmData->elevation_separated_ism[md_idx];
     538             :                 }
     539             :             }
     540             :             else
     541             :             {
     542       33270 :                 if ( st_ivas->hMasaIsmData->ism_dir_is_edited[obj] )
     543             :                 {
     544        4200 :                     azimuth = st_ivas->hMasaIsmData->azimuth_ism_edited[obj];
     545        4200 :                     elevation = st_ivas->hMasaIsmData->elevation_ism_edited[obj];
     546             :                 }
     547             :                 else
     548             :                 {
     549       29070 :                     azimuth = st_ivas->hMasaIsmData->azimuth_ism[obj][md_idx];
     550       29070 :                     elevation = st_ivas->hMasaIsmData->elevation_ism[obj][md_idx];
     551             :                 }
     552             :             }
     553             : 
     554       50595 :             if ( st_ivas->hOutSetup.is_planar_setup )
     555             :             {
     556             :                 /* If no elevation support in output format, then rendering should be done with zero elevation */
     557        2175 :                 elevation = 0;
     558             :             }
     559             : 
     560       50595 :             if ( hVBAPdata != NULL )
     561             :             {
     562       18477 :                 vbap_determine_gains( hVBAPdata, gains, azimuth, elevation, 1 );
     563             :             }
     564             :             else
     565             :             {
     566       32118 :                 ivas_dirac_dec_get_response( azimuth, elevation, gains, hDirACRend->hOutSetup.ambisonics_order );
     567             :             }
     568             : 
     569      538494 :             for ( j = 0; j < nchan_out_woLFE; j++ )
     570             :             {
     571      487899 :                 if ( hDirACRend->hOutSetup.num_lfe > 0 )
     572             :                 {
     573      156315 :                     j2 = j + ( j >= lfe_index );
     574             :                 }
     575             :                 else
     576             :                 {
     577      331584 :                     j2 = j;
     578             :                 }
     579             : 
     580      487899 :                 if ( fabsf( gains[j] ) > 0.0f || fabsf( hRendererData->prev_gains[obj][j] ) > 0.0f )
     581             :                 {
     582    74929161 :                     for ( k = 0; k < n_samples_sf; k++ )
     583             :                     {
     584    74551980 :                         g1 = hRendererData->interpolator[k];
     585    74551980 :                         g2 = 1.0f - g1;
     586    74551980 :                         output_f_local[j2][k + offsetSamples] += ( g1 * gains[j] + g2 * hRendererData->prev_gains[obj][j] ) * input_f[obj][k + offsetSamples];
     587             :                     }
     588             :                 }
     589      487899 :                 hRendererData->prev_gains[obj][j] = gains[j];
     590             :             }
     591             : 
     592       50595 :             offsetSamples += n_samples_sf;
     593             :         }
     594             :     }
     595             : 
     596       18845 :     return;
     597             : }

Generated by: LCOV version 1.14