LCOV - code coverage report
Current view: top level - lib_dec - ivas_ism_renderer_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 4c82f1d24d39d0296b18d775f18a006f4c7d024b Lines: 253 261 96.9 %
Date: 2025-05-17 01:59:02 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_fx.h"
      37             : #include "ivas_prot_fx.h"
      38             : #include "ivas_prot_rend_fx.h"
      39             : #include "ivas_stat_com.h"
      40             : #include "ivas_rom_com.h"
      41             : #include "rom_com.h"
      42             : #include "ivas_rom_dec.h"
      43             : #include <math.h>
      44             : #include "wmc_auto.h"
      45             : 
      46             : 
      47             : /*-------------------------------------------------------------------------*
      48             :  * ivas_ism_renderer_open()
      49             :  *
      50             :  * Open struct for object rendering, reserve memory, and init values.
      51             :  *-------------------------------------------------------------------------*/
      52             : 
      53             : #define SIN_NEG_30_DEGREES_Q15 ( (Word16) 0xC000 )
      54             : #define SIN_30_DEGREES_Q15     ( (Word16) 0x4000 )
      55             : 
      56         244 : ivas_error ivas_ism_renderer_open_fx(
      57             :     Decoder_Struct *st_ivas /* i/o: IVAS decoder structure      */
      58             : )
      59             : {
      60             :     Word16 i;
      61             :     UWord16 interpolator_length;
      62             :     UWord16 init_interpolator_length;
      63             :     ivas_error error;
      64             : 
      65         244 :     IF( ( st_ivas->hIsmRendererData = (ISM_RENDERER_HANDLE) malloc( sizeof( ISM_RENDERER_DATA ) ) ) == NULL )
      66             :     {
      67           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM renderer\n" ) );
      68             :     }
      69             : 
      70         244 :     test();
      71         244 :     test();
      72         244 :     test();
      73         244 :     IF( st_ivas->hIntSetup.is_loudspeaker_setup && st_ivas->hIntSetup.ls_azimuth_fx != NULL && st_ivas->hIntSetup.ls_elevation_fx != NULL && st_ivas->hEFAPdata == NULL )
      74             :     {
      75         112 :         IF( NE_32( ( error = efap_init_data_fx( &( st_ivas->hEFAPdata ), st_ivas->hIntSetup.ls_azimuth_fx, st_ivas->hIntSetup.ls_elevation_fx, st_ivas->hIntSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ), IVAS_ERR_OK ) )
      76             :         {
      77           0 :             return error;
      78             :         }
      79             :     }
      80             : 
      81        1220 :     FOR( i = 0; i < MAX_NUM_OBJECTS; i++ )
      82             :     {
      83         976 :         set32_fx( st_ivas->hIsmRendererData->prev_gains_fx[i], 0, MAX_OUTPUT_CHANNELS );
      84         976 :         set32_fx( st_ivas->hIsmRendererData->gains_fx[i], 0, MAX_OUTPUT_CHANNELS );
      85             :     }
      86             : 
      87         244 :     IF( st_ivas->hDecoderConfig->Opt_tsm )
      88             :     {
      89             :         Word32 res_dec, res_frac;
      90          84 :         init_interpolator_length = NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_CLDFB_TIMESLOTS * CLDFB_SLOT_NS );
      91          84 :         move16();
      92          84 :         iDiv_and_mod_32( st_ivas->hDecoderConfig->output_Fs, FRAMES_PER_SEC, &res_dec, &res_frac, 0 );
      93          84 :         interpolator_length = (UWord16) ( res_dec );
      94          84 :         move16();
      95             :     }
      96             :     ELSE
      97             :     {
      98             :         Word32 res_dec, res_frac;
      99         160 :         iDiv_and_mod_32( st_ivas->hDecoderConfig->output_Fs, FRAMES_PER_SEC, &res_dec, &res_frac, 0 );
     100         160 :         init_interpolator_length = (UWord16) ( res_dec );
     101         160 :         move16();
     102         160 :         interpolator_length = init_interpolator_length;
     103         160 :         move16();
     104             :     }
     105         244 :     IF( ( st_ivas->hIsmRendererData->interpolator_fx = (Word16 *) malloc( sizeof( Word16 ) * init_interpolator_length ) ) == NULL )
     106             :     {
     107           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM renderer interpolator\n" ) );
     108             :     }
     109             : 
     110         244 :     st_ivas->hIsmRendererData->interpolator_len = init_interpolator_length;
     111         244 :     move16();
     112             : 
     113      198400 :     FOR( i = 0; i < sub( interpolator_length, 1 ); i++ )
     114             :     {
     115      198156 :         st_ivas->hIsmRendererData->interpolator_fx[i] = div_s( i, sub( interpolator_length, 1 ) );
     116      198156 :         move16();
     117             :     }
     118         244 :     st_ivas->hIsmRendererData->interpolator_fx[interpolator_length - 1] = 32767; // (1.0f in Q15 )- 1
     119         244 :     move16();
     120             : 
     121         244 :     return IVAS_ERR_OK;
     122             : }
     123             : 
     124             : 
     125             : /*-------------------------------------------------------------------------*
     126             :  * ivas_ism_renderer_close()
     127             :  *
     128             :  * Close struct for object rendering.
     129             :  *-------------------------------------------------------------------------*/
     130        2795 : void ivas_ism_renderer_close(
     131             :     ISM_RENDERER_HANDLE *hIsmRendererData /* i/o: ISM renderer handle */
     132             : )
     133             : {
     134        2795 :     test();
     135        2795 :     IF( hIsmRendererData == NULL || *hIsmRendererData == NULL )
     136             :     {
     137        2002 :         return;
     138             :     }
     139             : 
     140         793 :     IF( ( *hIsmRendererData )->interpolator_fx != NULL )
     141             :     {
     142         793 :         free( ( *hIsmRendererData )->interpolator_fx );
     143         793 :         ( *hIsmRendererData )->interpolator_fx = NULL;
     144             :     }
     145             : 
     146         793 :     free( *hIsmRendererData );
     147         793 :     *hIsmRendererData = NULL;
     148             : 
     149         793 :     return;
     150             : }
     151             : 
     152             : /*-------------------------------------------------------------------------*
     153             :  * ivas_ism_render_sf()
     154             :  *
     155             :  * Object rendering process
     156             :  *-------------------------------------------------------------------------*/
     157       24028 : void ivas_ism_render_sf_fx(
     158             :     Decoder_Struct *st_ivas,         /* i/o: IVAS decoder structure                      */
     159             :     Word32 *output_fx[],             /* i/o: core-coder transport channels/object output  Q11*/
     160             :     const Word16 n_samples_to_render /* i  : output frame length per channel             */
     161             : )
     162             : {
     163             :     Word16 i, j, k, j2;
     164             :     Word16 *g1_fx, g2_fx;
     165             :     Word32 *tc_fx;
     166             :     Word16 num_objects, nchan_out_woLFE, lfe_index;
     167             :     Word16 azimuth, elevation;
     168             :     Word16 tc_offset;
     169             :     Word16 interp_offset;
     170             :     Word32 gain_fx, prev_gain_fx;
     171             :     Word32 tc_local_fx[MAX_NUM_OBJECTS][L_FRAME48k];
     172             :     Word32 *p_tc_fx[MAX_NUM_OBJECTS];
     173             : 
     174       24028 :     num_objects = st_ivas->nchan_transport;
     175       24028 :     move16();
     176       24028 :     if ( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
     177             :     {
     178        3210 :         num_objects = st_ivas->nchan_ism;
     179        3210 :         move16();
     180             :     }
     181             : 
     182       24028 :     nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE;
     183       24028 :     move16();
     184             : 
     185       24028 :     tc_offset = st_ivas->hTcBuffer->n_samples_rendered;
     186       24028 :     move16();
     187       24028 :     interp_offset = st_ivas->hTcBuffer->n_samples_rendered;
     188       24028 :     move16();
     189             : 
     190       24028 :     IF( st_ivas->hDecoderConfig->Opt_tsm )
     191             :     {
     192        5681 :         FOR( i = 0; i < num_objects; i++ )
     193             :         {
     194        4259 :             p_tc_fx[i] = &st_ivas->hTcBuffer->tc_fx[i][tc_offset]; // Q11
     195             :         }
     196             :     }
     197             :     ELSE
     198             :     {
     199       82620 :         FOR( i = 0; i < num_objects; i++ )
     200             :         {
     201       60014 :             Copy32( &output_fx[i][tc_offset], tc_local_fx[i], n_samples_to_render );
     202       60014 :             p_tc_fx[i] = tc_local_fx[i];
     203             :         }
     204             :     }
     205             : 
     206      247264 :     FOR( i = 0; i < nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; i++ )
     207             :     {
     208      223236 :         set32_fx( output_fx[i], 0, n_samples_to_render );
     209             :     }
     210             : 
     211       24028 :     test();
     212       24028 :     IF( st_ivas->hCombinedOrientationData && EQ_16( st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx], 1 ) )
     213             :     {
     214        3000 :         ivas_jbm_dec_get_adapted_linear_interpolator_fx( n_samples_to_render, n_samples_to_render, st_ivas->hIsmRendererData->interpolator_fx );
     215        3000 :         interp_offset = 0;
     216        3000 :         move16();
     217             :     }
     218             : 
     219       88301 :     FOR( i = 0; i < num_objects; i++ )
     220             :     {
     221             :         /* Combined rotation: rotate the object positions depending the head and external orientations */
     222       64273 :         test();
     223       64273 :         IF( st_ivas->hCombinedOrientationData != NULL && EQ_16( st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx], 1 ) )
     224             :         {
     225        3000 :             rotateAziEle_fx( extract_l( L_shr( st_ivas->hIsmMetaData[i]->azimuth_fx, 22 ) ), extract_l( L_shr( st_ivas->hIsmMetaData[i]->elevation_fx, 22 ) ), &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat_fx[0], st_ivas->hIntSetup.is_planar_setup );
     226             : 
     227        3000 :             IF( st_ivas->hEFAPdata != NULL )
     228             :             {
     229        3000 :                 efap_determine_gains_fx( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains_fx[i], L_shl( azimuth, 22 ), L_shl( elevation, 22 ), EFAP_MODE_EFAP );
     230             :             }
     231             :         }
     232             : 
     233       64273 :         lfe_index = 0;
     234       64273 :         move16();
     235      606806 :         FOR( ( j = 0, j2 = 0 ); j < nchan_out_woLFE; ( j++, j2++ ) )
     236             :         {
     237      542533 :             test();
     238      542533 :             IF( ( st_ivas->hIntSetup.num_lfe > 0 ) && EQ_16( st_ivas->hIntSetup.index_lfe[lfe_index], j ) )
     239             :             {
     240       40443 :                 IF( LT_16( lfe_index, sub( st_ivas->hIntSetup.num_lfe, 1 ) ) )
     241             :                 {
     242           0 :                     lfe_index = add( lfe_index, 1 );
     243           0 :                     j2 = add( j2, 1 );
     244             :                 }
     245             :                 ELSE
     246             :                 {
     247       40443 :                     j2 = add( j2, 1 );
     248             :                 }
     249             :             }
     250             : 
     251      542533 :             gain_fx = st_ivas->hIsmRendererData->gains_fx[i][j];
     252      542533 :             move32();
     253      542533 :             prev_gain_fx = st_ivas->hIsmRendererData->prev_gains_fx[i][j];
     254      542533 :             move32();
     255             : 
     256      542533 :             test();
     257      542533 :             IF( ( L_abs( gain_fx ) > 0 ) || ( L_abs( prev_gain_fx ) > 0 ) )
     258             :             {
     259      265791 :                 g1_fx = &st_ivas->hIsmRendererData->interpolator_fx[interp_offset];
     260      265791 :                 tc_fx = p_tc_fx[i];
     261   219870431 :                 FOR( k = 0; k < n_samples_to_render; k++ )
     262             :                 {
     263   219604640 :                     g2_fx = sub( 32767, *g1_fx );                                                                                                                                           // 32767 = (1.0f in Q15) - 1
     264   219604640 :                     output_fx[j2][k] = L_add( output_fx[j2][k], L_shl( Mpy_32_32( L_add( Mpy_32_16_1( gain_fx, *( g1_fx++ ) ), Mpy_32_16_1( prev_gain_fx, g2_fx ) ), *( tc_fx++ ) ), 1 ) ); // Q11( (30+15+1-16) + 11 -31 +1)
     265   219604640 :                     move16();
     266             :                 }
     267             :             }
     268             : 
     269             :             /* update here only in case of head rotation */
     270      542533 :             test();
     271      542533 :             IF( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 )
     272             :             {
     273       33000 :                 st_ivas->hIsmRendererData->prev_gains_fx[i][j] = gain_fx; // Q30
     274       33000 :                 move32();
     275             :             }
     276             :         }
     277             :     }
     278             : 
     279             :     /* update combined orientation access index */
     280       24028 :     ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_to_render );
     281             : 
     282       24028 :     return;
     283             : }
     284             : 
     285             : 
     286             : /*-------------------------------------------------------------------------*
     287             :  * ivas_ism_get_stereo_gains()
     288             :  *
     289             :  *
     290             :  *-------------------------------------------------------------------------*/
     291             : 
     292      168640 : void ivas_ism_get_stereo_gains_fx(
     293             :     const Word16 aziDeg,  /* i  : object azimuth       Q0*/
     294             :     const Word16 eleDeg,  /* i  : object elevation     Q0*/
     295             :     Word16 *left_gain_fx, /* o  : left channel gain    Q15*/
     296             :     Word16 *right_gain_fx /* o  : right channel gain   Q15*/
     297             : )
     298             : {
     299             :     /* Convert azi and ele to an azi value of the cone of confusion */
     300      168640 :     Word16 azAddEl = add( aziDeg, eleDeg );
     301      168640 :     Word16 azSubEl = sub( aziDeg, eleDeg );
     302             :     Word16 gains[2];
     303             : 
     304      168640 :     const Word16 *ptr_sin_az = ivas_sin_az_fx;
     305             : 
     306      241767 :     WHILE( azAddEl > 180 )
     307             :     {
     308       73127 :         azAddEl = sub( azAddEl, 360 );
     309             :     }
     310      169219 :     WHILE( azAddEl < -180 )
     311             :     {
     312         579 :         azAddEl = add( azAddEl, 360 );
     313             :     }
     314      242264 :     WHILE( azSubEl > 180 )
     315             :     {
     316       73624 :         azSubEl = sub( azSubEl, 360 );
     317             :     }
     318      169703 :     WHILE( azSubEl < -180 )
     319             :     {
     320        1063 :         azSubEl = add( azSubEl, 360 );
     321             :     }
     322      168640 :     Word16 sin_az_cos_el = extract_l( L_shr( L_add( L_deposit_l( ptr_sin_az[azAddEl + 180] ), L_deposit_l( ptr_sin_az[azSubEl + 180] ) ), 1 ) );
     323             : 
     324      168640 :     IF( GE_16( sin_az_cos_el, SIN_30_DEGREES_Q15 ) )
     325             :     {                               /* Left side */
     326       33926 :         gains[0] = (Word16) 0x7fff; // 1.0f in Q15
     327       33926 :         move16();
     328       33926 :         gains[1] = 0;
     329       33926 :         move16();
     330             :     }
     331      134714 :     ELSE IF( LE_16( sin_az_cos_el, SIN_NEG_30_DEGREES_Q15 ) )
     332             :     { /* Right side */
     333       34147 :         gains[0] = 0;
     334       34147 :         move16();
     335       34147 :         gains[1] = (Word16) 0x7fff; // 1.0f in Q15
     336       34147 :         move16();
     337             :     }
     338             :     ELSE /* Tangent panning law */
     339             :     {
     340      100567 :         get_panning_gain_fx( sin_az_cos_el, gains );
     341             :     }
     342             : 
     343      168640 :     *left_gain_fx = gains[0];
     344      168640 :     move16();
     345      168640 :     *right_gain_fx = gains[1];
     346      168640 :     move16();
     347             : 
     348      168640 :     return;
     349             : }
     350             : 
     351             : /*-------------------------------------------------------------------------*
     352             :  * ivas_masa_oism_separate_object_renderer_open()
     353             :  *
     354             :  * Open structures, reserve memory, and init values.
     355             :  *-------------------------------------------------------------------------*/
     356             : 
     357         549 : ivas_error ivas_omasa_separate_object_renderer_open(
     358             :     Decoder_Struct *st_ivas /* i/o: IVAS decoder structure      */
     359             : )
     360             : {
     361             :     Word16 interpolator_length;
     362             :     Word16 i;
     363             :     Word16 init_interpolator_length;
     364             : 
     365         549 :     IF( ( st_ivas->hIsmRendererData = (ISM_RENDERER_HANDLE) malloc( sizeof( ISM_RENDERER_DATA ) ) ) == NULL )
     366             :     {
     367           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM renderer \n" ) );
     368             :     }
     369             : 
     370        2745 :     FOR( i = 0; i < MAX_NUM_OBJECTS; i++ )
     371             :     {
     372        2196 :         set32_fx( st_ivas->hIsmRendererData->prev_gains_fx[i], 0, MAX_OUTPUT_CHANNELS );
     373             :     }
     374             :     Word32 res_dec1, res_frac1;
     375             :     Word32 res_dec2, res_frac2;
     376         549 :     iDiv_and_mod_32( st_ivas->hDecoderConfig->output_Fs, FRAMES_PER_SEC, &res_dec1, &res_frac1, 0 );
     377         549 :     iDiv_and_mod_32( res_dec1, MAX_PARAM_SPATIAL_SUBFRAMES, &res_dec2, &res_frac2, 0 );
     378         549 :     init_interpolator_length = extract_l( res_dec2 );
     379         549 :     interpolator_length = init_interpolator_length;
     380         549 :     move16();
     381             : 
     382         549 :     st_ivas->hIsmRendererData->interpolator_fx = (Word16 *) malloc( sizeof( Word16 ) * init_interpolator_length );
     383         549 :     st_ivas->hIsmRendererData->interpolator_len = init_interpolator_length;
     384         549 :     move16();
     385      128869 :     FOR( i = 0; i < interpolator_length; i++ )
     386             :     {
     387      128320 :         st_ivas->hIsmRendererData->interpolator_fx[i] = div_s( i, interpolator_length );
     388      128320 :         move16();
     389             :     }
     390         549 :     st_ivas->hIsmRendererData->interpolator_len = interpolator_length;
     391         549 :     move16();
     392             : 
     393         549 :     st_ivas->hMasaIsmData->delayBuffer_size = extract_l( ( st_ivas->hDecoderConfig->output_Fs / 50 ) / MAX_PARAM_SPATIAL_SUBFRAMES );
     394         549 :     move16();
     395             : 
     396         549 :     test();
     397         549 :     IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
     398             :     {
     399         321 :         st_ivas->hMasaIsmData->delayBuffer_nchan = 1;
     400         321 :         move16();
     401             :     }
     402             :     ELSE
     403             :     {
     404         228 :         st_ivas->hMasaIsmData->delayBuffer_nchan = st_ivas->nchan_ism;
     405         228 :         move16();
     406             :     }
     407             : 
     408         549 :     IF( ( st_ivas->hMasaIsmData->delayBuffer_fx = (Word32 **) malloc( st_ivas->hMasaIsmData->delayBuffer_nchan * sizeof( Word32 * ) ) ) == NULL )
     409             :     {
     410           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM delay buffer \n" ) );
     411             :     }
     412             : 
     413        1654 :     FOR( i = 0; i < st_ivas->hMasaIsmData->delayBuffer_nchan; i++ )
     414             :     {
     415        1105 :         IF( ( st_ivas->hMasaIsmData->delayBuffer_fx[i] = (Word32 *) malloc( st_ivas->hMasaIsmData->delayBuffer_size * sizeof( Word32 ) ) ) == NULL )
     416             :         {
     417           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM delay buffer \n" ) );
     418             :         }
     419        1105 :         set32_fx( st_ivas->hMasaIsmData->delayBuffer_fx[i], 0, st_ivas->hMasaIsmData->delayBuffer_size );
     420             :     }
     421             : 
     422         549 :     return IVAS_ERR_OK;
     423             : }
     424             : 
     425             : 
     426             : /*-------------------------------------------------------------------------*
     427             :  * ivas_omasa_separate_object_renderer_close()
     428             :  *
     429             :  * Close structures, free memory.
     430             :  *-------------------------------------------------------------------------*/
     431             : 
     432        1808 : void ivas_omasa_separate_object_renderer_close(
     433             :     Decoder_Struct *st_ivas /* i/o: IVAS decoder structure      */
     434             : )
     435             : {
     436             :     Word16 i;
     437             : 
     438        1808 :     IF( st_ivas->hMasaIsmData != NULL )
     439             :     {
     440        1808 :         IF( st_ivas->hMasaIsmData->delayBuffer_fx != NULL )
     441             :         {
     442        1615 :             FOR( i = 0; i < st_ivas->hMasaIsmData->delayBuffer_nchan; i++ )
     443             :             {
     444        1078 :                 IF( st_ivas->hMasaIsmData->delayBuffer_fx[i] != NULL )
     445             :                 {
     446        1078 :                     free( st_ivas->hMasaIsmData->delayBuffer_fx[i] );
     447        1078 :                     st_ivas->hMasaIsmData->delayBuffer_fx[i] = NULL;
     448             :                 }
     449             :             }
     450             : 
     451         537 :             free( st_ivas->hMasaIsmData->delayBuffer_fx );
     452         537 :             st_ivas->hMasaIsmData->delayBuffer_fx = NULL;
     453             :         }
     454             :     }
     455             : 
     456        1808 :     ivas_ism_renderer_close( &st_ivas->hIsmRendererData );
     457             : 
     458        1808 :     return;
     459             : }
     460             : 
     461             : 
     462             : /*-------------------------------------------------------------------------*
     463             :  * ivas_omasa_separate_object_render_jbm()
     464             :  *
     465             :  * Rendering separated objects and mixing them to the parametrically rendered signals for JBM
     466             :  *-------------------------------------------------------------------------*/
     467             : 
     468        2705 : void ivas_omasa_separate_object_render_jbm_fx(
     469             :     Decoder_Struct *st_ivas,          /* i/o: IVAS decoder structure                      */
     470             :     const UWord16 nSamplesRendered,   /* i  : number of samples rendered                  */
     471             :     Word32 input_fx_in[][L_FRAME48k], /* i  : separated object signal                     Q11*/
     472             :     Word32 *output_fx[],              /* o  : rendered time signal                        Q11*/
     473             :     const Word16 subframes_rendered,  /* i  : number of subframes rendered                */
     474             :     const Word16 slots_rendered       /* i  : number of CLDFB slots rendered              */
     475             : )
     476             : {
     477             :     VBAP_HANDLE hVBAPdata;
     478             :     DIRAC_REND_HANDLE hDirACRend;
     479             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
     480             :     Word16 nchan_out_woLFE, num_lfe;
     481             :     ISM_RENDERER_HANDLE hRendererData;
     482             :     Word16 j, k, j2;
     483             :     Word16 obj;
     484             :     Word32 gains_fx[MAX_OUTPUT_CHANNELS];
     485             :     Word16 g1_fx, g2_fx;
     486             :     Word16 lfe_index;
     487             :     Word16 azimuth, elevation;
     488             :     Word16 num_objects;
     489             :     UWord8 single_separated;
     490             :     Word32 *input_fx[MAX_TRANSPORT_CHANNELS];
     491             :     Word32 *output_fx_local[MAX_OUTPUT_CHANNELS];
     492             :     Word16 offsetSamples;
     493             :     Word16 n_samples_sf, md_idx;
     494             :     Word16 slots_to_render, first_sf, last_sf, subframe_idx;
     495             : 
     496        2705 :     hVBAPdata = st_ivas->hVBAPdata;
     497        2705 :     hDirACRend = st_ivas->hDirACRend;
     498        2705 :     hSpatParamRendCom = st_ivas->hSpatParamRendCom;
     499        2705 :     nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE;
     500        2705 :     move16();
     501        2705 :     num_lfe = st_ivas->hIntSetup.num_lfe;
     502        2705 :     move16();
     503        2705 :     hRendererData = st_ivas->hIsmRendererData;
     504        2705 :     lfe_index = hDirACRend->hOutSetup.index_lfe[0];
     505        2705 :     move16();
     506             : 
     507        2705 :     test();
     508        2705 :     IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
     509             :     {
     510        1634 :         single_separated = 1;
     511        1634 :         move16();
     512        1634 :         num_objects = 1;
     513        1634 :         move16();
     514             :     }
     515             :     ELSE
     516             :     {
     517        1071 :         single_separated = 0;
     518        1071 :         move16();
     519        1071 :         num_objects = st_ivas->nchan_ism;
     520        1071 :         move16();
     521             :     }
     522             : 
     523        2705 :     offsetSamples = i_mult( slots_rendered, hSpatParamRendCom->slot_size );
     524             : 
     525       27915 :     FOR( j = 0; j < nchan_out_woLFE + num_lfe; j++ )
     526             :     {
     527       25210 :         output_fx_local[j] = output_fx[j];
     528             :     }
     529             : 
     530        2705 :     IF( st_ivas->hDecoderConfig->Opt_tsm )
     531             :     {
     532        2514 :         FOR( obj = 0; obj < num_objects; obj++ )
     533             :         {
     534        1609 :             input_fx[obj] = &st_ivas->hTcBuffer->tc_fx[obj + 2][offsetSamples];
     535        1609 :             move32();
     536             :         }
     537             :     }
     538             :     ELSE
     539             :     {
     540        4574 :         FOR( obj = 0; obj < num_objects; obj++ )
     541             :         {
     542        2774 :             input_fx[obj] = input_fx_in[obj];
     543        2774 :             move32();
     544             :         }
     545             :     }
     546             : 
     547        2705 :     slots_to_render = idiv1616( nSamplesRendered, hSpatParamRendCom->slot_size );
     548        2705 :     first_sf = subframes_rendered;
     549        2705 :     move16();
     550        2705 :     last_sf = first_sf;
     551        2705 :     move16();
     552             : 
     553       12180 :     WHILE( slots_to_render > 0 )
     554             :     {
     555        9475 :         slots_to_render = sub( slots_to_render, hSpatParamRendCom->subframe_nbslots[last_sf] );
     556        9475 :         last_sf = add( last_sf, 1 );
     557             :     }
     558             : 
     559        7088 :     FOR( obj = 0; obj < num_objects; obj++ )
     560             :     {
     561             :         /* Delay the signal to match CLDFB delay. Delay the whole buffer with the first rendering call of the stretched buffer. */
     562        4383 :         IF( slots_rendered == 0 )
     563             :         {
     564             :             Word16 tcBufferSize;
     565             : 
     566        3766 :             tcBufferSize = i_mult( hSpatParamRendCom->num_slots, hSpatParamRendCom->slot_size );
     567        3766 :             delay_signal32_fx( input_fx[obj], tcBufferSize, st_ivas->hMasaIsmData->delayBuffer_fx[obj], st_ivas->hMasaIsmData->delayBuffer_size );
     568             :         }
     569        4383 :         offsetSamples = 0;
     570        4383 :         move16();
     571             : 
     572       19463 :         FOR( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ )
     573             :         {
     574       15080 :             n_samples_sf = i_mult( hSpatParamRendCom->subframe_nbslots[subframe_idx], hSpatParamRendCom->slot_size );
     575       15080 :             IF( n_samples_sf != hRendererData->interpolator_len )
     576             :             {
     577       16959 :                 FOR( k = 0; k < n_samples_sf; k++ )
     578             :                 {
     579       16860 :                     hRendererData->interpolator_fx[k] = div_s( k, n_samples_sf );
     580       16860 :                     move16();
     581             :                 }
     582          99 :                 hRendererData->interpolator_len = n_samples_sf;
     583          99 :                 move16();
     584             :             }
     585             : 
     586       15080 :             md_idx = hSpatParamRendCom->render_to_md_map[subframe_idx];
     587       15080 :             move16();
     588             : 
     589       15080 :             IF( single_separated )
     590             :             {
     591        5653 :                 azimuth = st_ivas->hMasaIsmData->azimuth_separated_ism[md_idx];
     592        5653 :                 move16();
     593        5653 :                 elevation = st_ivas->hMasaIsmData->elevation_separated_ism[md_idx];
     594        5653 :                 move16();
     595             :             }
     596             :             ELSE
     597             :             {
     598        9427 :                 azimuth = st_ivas->hMasaIsmData->azimuth_ism[obj][md_idx];
     599        9427 :                 move16();
     600        9427 :                 elevation = st_ivas->hMasaIsmData->elevation_ism[obj][md_idx];
     601        9427 :                 move16();
     602             :             }
     603             : 
     604       15080 :             if ( st_ivas->hOutSetup.is_planar_setup )
     605             :             {
     606             :                 /* If no elevation support in output format, then rendering should be done with zero elevation */
     607         673 :                 elevation = 0;
     608         673 :                 move16();
     609             :             }
     610             : 
     611       15080 :             IF( hVBAPdata != NULL )
     612             :             {
     613        6102 :                 vbap_determine_gains_fx( hVBAPdata, gains_fx, azimuth, elevation, 1 );
     614             :             }
     615             :             ELSE
     616             :             {
     617        8978 :                 ivas_dirac_dec_get_response_fx( azimuth, elevation, gains_fx, hDirACRend->hOutSetup.ambisonics_order, Q29 );
     618             :             }
     619             : 
     620      170418 :             FOR( j = 0; j < nchan_out_woLFE; j++ )
     621             :             {
     622      155338 :                 IF( hDirACRend->hOutSetup.num_lfe > 0 )
     623             :                 {
     624       51722 :                     j2 = add( j, extract_l( GE_16( j, lfe_index ) ) );
     625             :                 }
     626             :                 ELSE
     627             :                 {
     628      103616 :                     j2 = j;
     629      103616 :                     move16();
     630             :                 }
     631             : 
     632      155338 :                 test();
     633      155338 :                 IF( ( L_abs( gains_fx[j] ) > 0 ) || ( L_abs( hRendererData->prev_gains_fx[obj][j] ) > 0 ) )
     634             :                 {
     635    23913228 :                     FOR( k = 0; k < n_samples_sf; k++ )
     636             :                     {
     637    23793960 :                         g1_fx = hRendererData->interpolator_fx[k];
     638    23793960 :                         move16();
     639    23793960 :                         g2_fx = sub( 32767, g1_fx ); // 32767 = 1.0f in Q15
     640             : 
     641    23793960 :                         output_fx_local[j2][k + offsetSamples] = L_add( output_fx_local[j2][k + offsetSamples], L_add( L_shl( Mpy_32_32( Mpy_32_16_1( input_fx[obj][k + offsetSamples], g1_fx ), gains_fx[j] ), 2 ), L_shl( Mpy_32_32( Mpy_32_16_1( input_fx[obj][k + offsetSamples], g2_fx ), hRendererData->prev_gains_fx[obj][j] ), 2 ) ) ); // Q11( (30+15+1-16) + 11 -31 +1)
     642    23793960 :                         move32();
     643             :                     }
     644             :                 }
     645      155338 :                 hRendererData->prev_gains_fx[obj][j] = gains_fx[j];
     646      155338 :                 move32();
     647             :             }
     648             : 
     649       15080 :             offsetSamples = add( offsetSamples, n_samples_sf );
     650             :         }
     651             :     }
     652             : 
     653        2705 :     return;
     654             : }

Generated by: LCOV version 1.14