LCOV - code coverage report
Current view: top level - lib_rend - ivas_masa_merge_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 138 248 55.6 %
Date: 2025-05-03 01:55:50 Functions: 6 7 85.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 <math.h>
      34             : #include "options.h"
      35             : #include "lib_rend.h"
      36             : #include "ivas_prot_rend_fx.h"
      37             : #include "ivas_cnst.h"
      38             : #include "prot_fx.h"
      39             : #include "wmc_auto.h"
      40             : #include "ivas_prot_fx.h"
      41             : 
      42             : 
      43             : /*---------------------------------------------------------------------*
      44             :  * Local function prototypes
      45             :  *---------------------------------------------------------------------*/
      46             : 
      47             : static void copy_masa_meta_tile_fx( MASA_DECODER_EXT_OUT_META_HANDLE outMeta, MASA_DECODER_EXT_OUT_META_HANDLE inMeta, const UWord8 sf, const UWord8 band );
      48             : 
      49             : static void full_stream_merge_fx( MASA_DECODER_EXT_OUT_META_HANDLE outMeta, MASA_DECODER_EXT_OUT_META_HANDLE inMeta1, Word32 inEne1[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], Word16 *inEne1_e, MASA_DECODER_EXT_OUT_META_HANDLE inMeta2, Word32 inEne2[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], Word16 *inEne2_e );
      50             : 
      51             : static void diffuse_meta_merge_1x1_fx( MASA_DECODER_EXT_OUT_META_HANDLE outMeta, MASA_DECODER_EXT_OUT_META_HANDLE inMeta, Word32 inEne_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], Word16 *inEne_e, MASA_DECODER_EXT_OUT_META_HANDLE inMetaISM, Word32 inEneISM_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], Word16 *inEneISM_e );
      52             : 
      53             : 
      54             : /*---------------------------------------------------------------------*
      55             :  * copy_masa_meta_tile()
      56             :  *
      57             :  *
      58             :  *---------------------------------------------------------------------*/
      59             : 
      60       43200 : void copy_masa_meta_tile_fx(
      61             :     MASA_DECODER_EXT_OUT_META_HANDLE outMeta, /* o  : metadata to be written */
      62             :     MASA_DECODER_EXT_OUT_META_HANDLE inMeta,  /* i  : input metadata         */
      63             :     const UWord8 sf,                          /* i  : sub-frame index        */
      64             :     const UWord8 band                         /* i  : band index             */
      65             : )
      66             : {
      67       43200 :     outMeta->directionIndex[0][sf][band] = inMeta->directionIndex[0][sf][band];
      68       43200 :     move16();
      69       43200 :     outMeta->directToTotalRatio[0][sf][band] = inMeta->directToTotalRatio[0][sf][band];
      70       43200 :     move16();
      71       43200 :     outMeta->spreadCoherence[0][sf][band] = inMeta->spreadCoherence[0][sf][band];
      72       43200 :     move16();
      73             : 
      74       43200 :     outMeta->surroundCoherence[sf][band] = inMeta->surroundCoherence[sf][band];
      75       43200 :     move16();
      76       43200 :     outMeta->diffuseToTotalRatio[sf][band] = inMeta->diffuseToTotalRatio[sf][band];
      77       43200 :     move16();
      78             : 
      79       43200 :     IF( EQ_16( inMeta->descriptiveMeta.numberOfDirections, 1 ) )
      80             :     {
      81       24390 :         outMeta->directionIndex[1][sf][band] = inMeta->directionIndex[1][sf][band];
      82       24390 :         move16();
      83       24390 :         outMeta->directToTotalRatio[1][sf][band] = inMeta->directToTotalRatio[1][sf][band];
      84       24390 :         move16();
      85       24390 :         outMeta->spreadCoherence[1][sf][band] = inMeta->spreadCoherence[1][sf][band];
      86       24390 :         move16();
      87             :     }
      88             :     ELSE
      89             :     {
      90             :         /* make sure the output has zeroed data in the second direction */
      91       18810 :         outMeta->directionIndex[1][sf][band] = SPH_IDX_FRONT;
      92       18810 :         move16();
      93       18810 :         outMeta->directToTotalRatio[1][sf][band] = 0u;
      94       18810 :         move16();
      95       18810 :         outMeta->spreadCoherence[1][sf][band] = 0u;
      96       18810 :         move16();
      97             :     }
      98             : 
      99       43200 :     return;
     100             : }
     101             : 
     102             : /*---------------------------------------------------------------------*
     103             :  * copy_masa_descriptive_meta()
     104             :  *
     105             :  *
     106             :  *---------------------------------------------------------------------*/
     107             : 
     108         150 : void copy_masa_descriptive_meta_fx(
     109             :     MASA_DECRIPTIVE_META *outMeta, /* o  : metadata to be written */
     110             :     MASA_DECRIPTIVE_META *inMeta   /* i  : input metadata         */
     111             : )
     112             : {
     113             :     UWord8 char_idx;
     114        1350 :     FOR( char_idx = 0; char_idx < 8; char_idx++ )
     115             :     {
     116        1200 :         outMeta->formatDescriptor[char_idx] = inMeta->formatDescriptor[char_idx];
     117        1200 :         move16();
     118             :     }
     119         150 :     outMeta->numberOfDirections = inMeta->numberOfDirections;
     120         150 :     move16();
     121         150 :     outMeta->numberOfChannels = inMeta->numberOfChannels;
     122         150 :     move16();
     123         150 :     outMeta->sourceFormat = inMeta->sourceFormat;
     124         150 :     move16();
     125         150 :     outMeta->transportDefinition = inMeta->transportDefinition;
     126         150 :     move16();
     127         150 :     outMeta->channelAngle = inMeta->channelAngle;
     128         150 :     move16();
     129         150 :     outMeta->channelDistance = inMeta->channelDistance;
     130         150 :     move16();
     131         150 :     outMeta->channelLayout = inMeta->channelLayout;
     132         150 :     move16();
     133             : 
     134         150 :     return;
     135             : }
     136             : 
     137             : /*---------------------------------------------------------------------*
     138             :  * diffuse_meta_merge_1x1()
     139             :  *
     140             :  *
     141             :  *---------------------------------------------------------------------*/
     142             : 
     143           0 : void diffuse_meta_merge_1x1_fx(
     144             :     MASA_DECODER_EXT_OUT_META_HANDLE outMeta,                              /* o  : Merged metadata output        */
     145             :     MASA_DECODER_EXT_OUT_META_HANDLE inMeta,                               /* i  : Input metadata 1              */
     146             :     Word32 inEne_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],    /* i  : TF-energy of input 1          */
     147             :     Word16 *inEne_e,                                                       /* i  : TF-energy of input 1 Exponent */
     148             :     MASA_DECODER_EXT_OUT_META_HANDLE inMetaISM,                            /* i  : Input metadata 2              */
     149             :     Word32 inEneISM_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i  : TF-energy of input 2          */
     150             :     Word16 *inEneISM_e                                                     /* i  : TF-energy of input 2 Exponent */
     151             : )
     152             : {
     153             :     Word8 sf, band;
     154             :     Word16 max_e, in1_e[MASA_FREQUENCY_BANDS], i;
     155           0 :     FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
     156             :     {
     157           0 :         FOR( band = 0; band < MASA_FREQUENCY_BANDS; band++ )
     158             :         {
     159           0 :             Word32 energyTimesRatio_fx, energyTimesRatioISM_fx, total_diff_nrg_fx, dir_nrg_ratio_fx, total_nrg_fx = 0;
     160             :             Word32 dir_ratio_ism_fx, L_tmp1, L_tmp2;
     161           0 :             Word16 scale, energyTimesRatio_e, tmp, total_nrg_e = 0, total_diff_nrg_e, dir_ratio_ism_e, energyTimesRatioISM_e, dir_nrg_ratio_e;
     162           0 :             move32();
     163           0 :             move16();
     164             : 
     165           0 :             tmp = BASOP_Util_Divide1616_Scale( inMeta->directToTotalRatio[0][sf][band], UINT8_MAX, &scale );
     166           0 :             energyTimesRatio_fx = Mpy_32_16_r( inEne_fx[sf][band], tmp ); /* Q( 31 - ( nEne_e[sf] + scale ) ) */
     167           0 :             energyTimesRatio_e = add( inEne_e[sf], scale );
     168             : 
     169           0 :             IF( GT_16( inEne_e[sf], inEneISM_e[sf] ) )
     170             :             {
     171           0 :                 total_nrg_fx = L_add( L_shr( inEne_fx[sf][band], 1 ), L_shr( inEneISM_fx[sf][band], add( sub( inEne_e[sf], inEneISM_e[sf] ), 1 ) ) ); /* Q(30 - inEne_e[sf]) */
     172           0 :                 total_nrg_e = add( inEne_e[sf], 1 );
     173             :             }
     174             :             ELSE
     175             :             {
     176           0 :                 total_nrg_fx = L_add( L_shr( inEneISM_fx[sf][band], 1 ), L_shr( inEne_fx[sf][band], add( sub( inEneISM_e[sf], inEne_e[sf] ), 1 ) ) ); /* Q(30 - inEneISM_e[sf]) */
     177           0 :                 total_nrg_e = add( inEneISM_e[sf], 1 );
     178             :             }
     179             :             /* target is original MASA diffuseness */
     180           0 :             tmp = BASOP_Util_Divide1616_Scale( inMeta->diffuseToTotalRatio[sf][band], UINT8_MAX, &scale );
     181           0 :             total_diff_nrg_fx = Mpy_32_16_r( inEne_fx[sf][band], tmp ); /* Q( 31 - ( nEne_e[sf] + scale ) ) */
     182           0 :             total_diff_nrg_e = add( inEne_e[sf], scale );
     183             : 
     184             :             /* criterion is mean of ISM ratio and new ratio */
     185           0 :             dir_ratio_ism_fx = L_deposit_h( BASOP_Util_Divide1616_Scale( inMetaISM->directToTotalRatio[0][sf][band], UINT8_MAX, &dir_ratio_ism_e ) );
     186           0 :             tmp = BASOP_Util_Divide3232_Scale( total_diff_nrg_fx, L_add( total_nrg_fx, EPSILON_FX ), &scale );
     187           0 :             L_tmp1 = L_deposit_h( tmp ); /* Q( 31 - ( scale + total_nrg_e - total_diff_nrg_e ) ) */
     188           0 :             scale = add( scale, sub( total_diff_nrg_e, total_nrg_e ) );
     189           0 :             L_tmp2 = L_sub( L_shl( 1, scale ), L_tmp1 );
     190             : 
     191           0 :             L_tmp1 = BASOP_Util_Add_Mant32Exp( dir_ratio_ism_fx, dir_ratio_ism_e, L_tmp2, scale, &tmp );
     192           0 :             L_tmp1 = L_shr( L_tmp1, 1 );
     193           0 :             energyTimesRatioISM_fx = Mpy_32_32( L_tmp1, inEneISM_fx[sf][band] ); /* Q( 31 - ( tmp + inEneISM_e[sf] ) ) */
     194           0 :             energyTimesRatioISM_e = add( tmp, inEneISM_e[sf] );
     195             : 
     196           0 :             IF( ( BASOP_Util_Cmp_Mant32Exp( energyTimesRatioISM_fx, energyTimesRatioISM_e, energyTimesRatio_fx, energyTimesRatio_e ) > 0 ) )
     197             :             {
     198             :                 Word32 new_dir_ratio_fx, new_diff_ratio_fx;
     199             :                 Word16 new_dir_ratio_e;
     200           0 :                 outMeta->directionIndex[0][sf][band] = inMetaISM->directionIndex[0][sf][band];
     201           0 :                 move16();
     202           0 :                 outMeta->directToTotalRatio[0][sf][band] = inMetaISM->directToTotalRatio[0][sf][band];
     203           0 :                 move16();
     204           0 :                 outMeta->spreadCoherence[0][sf][band] = inMetaISM->spreadCoherence[0][sf][band];
     205           0 :                 move16();
     206             : 
     207           0 :                 outMeta->surroundCoherence[sf][band] = inMetaISM->surroundCoherence[sf][band];
     208           0 :                 move16();
     209             : 
     210           0 :                 tmp = BASOP_Util_Divide3232_Scale( total_diff_nrg_fx, L_add( EPSILON_FX, total_nrg_fx ), &scale );
     211           0 :                 scale = add( scale, sub( total_diff_nrg_e, total_nrg_e ) );
     212           0 :                 dir_nrg_ratio_fx = L_sub( L_shl( 1, scale ), L_deposit_h( tmp ) );
     213           0 :                 dir_nrg_ratio_e = scale;
     214           0 :                 move16();
     215             : 
     216           0 :                 new_dir_ratio_fx = dir_nrg_ratio_fx;
     217           0 :                 move32();
     218           0 :                 new_dir_ratio_e = dir_nrg_ratio_e;
     219           0 :                 move16();
     220           0 :                 tmp = BASOP_Util_Cmp_Mant32Exp( dir_nrg_ratio_fx, dir_nrg_ratio_e, dir_ratio_ism_fx, dir_ratio_ism_e );
     221           0 :                 IF( tmp <= 0 )
     222             :                 {
     223           0 :                     new_dir_ratio_fx = dir_nrg_ratio_fx;
     224           0 :                     move32();
     225           0 :                     new_dir_ratio_e = dir_nrg_ratio_e;
     226           0 :                     move16();
     227             :                 }
     228             : 
     229           0 :                 outMeta->directToTotalRatio[0][sf][band] = (UWord8) imult1616( extract_l( L_shr( new_dir_ratio_fx, sub( 31, new_dir_ratio_e ) ) ), UINT8_MAX );
     230           0 :                 move16();
     231           0 :                 IF( GT_16( sub( 31, new_dir_ratio_e ), Q30 ) )
     232             :                 {
     233           0 :                     new_dir_ratio_fx = L_shr( new_dir_ratio_fx, sub( sub( 31, new_dir_ratio_e ), Q30 ) ); /* Q30 */
     234           0 :                     new_dir_ratio_e = 1;
     235           0 :                     move16();
     236           0 :                     new_diff_ratio_fx = L_sub( ONE_IN_Q30, new_dir_ratio_fx ); /* Q30 */
     237             :                 }
     238             :                 ELSE
     239             :                 {
     240           0 :                     new_diff_ratio_fx = L_sub( L_shl( 1, sub( 31, new_dir_ratio_e ) ), new_dir_ratio_fx ); /* Q(31 - new_dir_ratiio_e) */
     241             :                 }
     242           0 :                 outMeta->diffuseToTotalRatio[sf][band] = (UWord8) imult1616( extract_l( L_shr( new_diff_ratio_fx, new_dir_ratio_e ) ), UINT8_MAX );
     243           0 :                 move16();
     244             :             }
     245             :             ELSE
     246             :             {
     247             :                 /* use the plain original meta for this tile */
     248           0 :                 outMeta->directionIndex[0][sf][band] = inMeta->directionIndex[0][sf][band];
     249           0 :                 move16();
     250           0 :                 outMeta->directToTotalRatio[0][sf][band] = inMeta->directToTotalRatio[0][sf][band];
     251           0 :                 move16();
     252           0 :                 outMeta->spreadCoherence[0][sf][band] = inMeta->spreadCoherence[0][sf][band];
     253           0 :                 move16();
     254             : 
     255           0 :                 outMeta->surroundCoherence[sf][band] = inMeta->surroundCoherence[sf][band];
     256           0 :                 move16();
     257           0 :                 outMeta->diffuseToTotalRatio[sf][band] = inMeta->diffuseToTotalRatio[sf][band];
     258           0 :                 move16();
     259             :             }
     260           0 :             outMeta->directionIndex[1][sf][band] = SPH_IDX_FRONT;
     261           0 :             move16();
     262           0 :             outMeta->directToTotalRatio[1][sf][band] = 0u;
     263           0 :             move16();
     264           0 :             outMeta->spreadCoherence[1][sf][band] = 0u;
     265           0 :             move16();
     266             : 
     267           0 :             inEne_fx[sf][band] = BASOP_Util_Add_Mant32Exp( inEne_fx[sf][band], inEne_e[sf], inEneISM_fx[sf][band], inEneISM_e[sf], &in1_e[band] ); /* Update energy for subsequent mergings */
     268           0 :             move16();
     269             :         }
     270             : 
     271           0 :         max_e = in1_e[0];
     272           0 :         move16();
     273           0 :         FOR( i = 1; i < MASA_FREQUENCY_BANDS; i++ )
     274             :         {
     275           0 :             if ( LT_16( max_e, in1_e[i] ) )
     276             :             {
     277           0 :                 max_e = in1_e[i];
     278           0 :                 move16();
     279             :             }
     280             :         }
     281             : 
     282           0 :         FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ )
     283             :         {
     284           0 :             inEne_fx[sf][i] = L_shr( inEne_fx[sf][i], sub( max_e, in1_e[i] ) ); /* Q(31 - max_e) */
     285           0 :             move32();
     286             :         }
     287             : 
     288           0 :         inEne_e[sf] = max_e;
     289           0 :         move16();
     290             :     }
     291             : 
     292             :     /* Set descriptive meta for mixed format */
     293           0 :     outMeta->descriptiveMeta.sourceFormat = 0u;
     294           0 :     move16();
     295           0 :     outMeta->descriptiveMeta.transportDefinition = 0u;
     296           0 :     move16();
     297           0 :     outMeta->descriptiveMeta.channelAngle = 0u;
     298           0 :     move16();
     299           0 :     outMeta->descriptiveMeta.channelDistance = 0u;
     300           0 :     move16();
     301           0 :     outMeta->descriptiveMeta.channelLayout = 0u;
     302           0 :     move16();
     303           0 :     outMeta->descriptiveMeta.numberOfDirections = 0u;
     304           0 :     move16();
     305             :     /* Number of transports should be set outside. */
     306             : 
     307           0 :     return;
     308             : }
     309             : 
     310             : 
     311             : /*---------------------------------------------------------------------*
     312             :  * full_stream_merge()
     313             :  *
     314             :  *
     315             :  *---------------------------------------------------------------------*/
     316             : 
     317         450 : void full_stream_merge_fx(
     318             :     MASA_DECODER_EXT_OUT_META_HANDLE outMeta,                            /* o  : Merged metadata output                                                      */
     319             :     MASA_DECODER_EXT_OUT_META_HANDLE inMeta1,                            /* i  : Input metadata 1                                                            */
     320             :     Word32 inEne1_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i/o: TF-energy of input 1. after merge, contains the energy of the merged signal */
     321             :     Word16 *inEne1_e,                                                    /* i/o: TF-energy of input 1 Exponent                                               */
     322             :     MASA_DECODER_EXT_OUT_META_HANDLE inMeta2,                            /* i  : Input metadata 2                                                            */
     323             :     Word32 inEne2_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i  : TF-energy of input 2                                                        */
     324             :     Word16 *inEne2_e                                                     /* i  : TF-energy of input 2 Exponent                                               */
     325             : )
     326             : {
     327             :     UWord8 n_dirs_1, n_dirs_2;
     328             :     UWord8 sf, band;
     329             :     Word16 scale, tmp, dir_nrg_1_e, dir_nrg_2_e, max_e, i;
     330             :     Word16 in1_e[MASA_FREQUENCY_BANDS];
     331             :     Word32 dir_nrg_1_fx, dir_nrg_2_fx, L_tmp;
     332             : 
     333             :     /* full stream select based on total direct energy */
     334         450 :     n_dirs_1 = (UWord8) add( inMeta1->descriptiveMeta.numberOfDirections, 1u ); /* to 1-based */
     335         450 :     n_dirs_2 = (UWord8) add( inMeta2->descriptiveMeta.numberOfDirections, 1u );
     336             : 
     337        2250 :     FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
     338             :     {
     339       45000 :         FOR( band = 0; band < MASA_FREQUENCY_BANDS; band++ )
     340             :         {
     341       43200 :             tmp = BASOP_Util_Divide1616_Scale( inMeta1->directToTotalRatio[0][sf][band], UINT8_MAX, &scale );
     342       43200 :             dir_nrg_1_fx = Mpy_32_32( L_deposit_h( tmp ), inEne1_fx[sf][band] ); /* Q( 31 - ( scale + inEne1_e[sf] ) ) */
     343       43200 :             dir_nrg_1_e = add( scale, inEne1_e[sf] );
     344             : 
     345       43200 :             tmp = BASOP_Util_Divide1616_Scale( inMeta1->directToTotalRatio[0][sf][band], UINT8_MAX, &scale );
     346       43200 :             dir_nrg_2_fx = Mpy_32_32( L_deposit_h( tmp ), inEne2_fx[sf][band] ); /* Q( 31 - ( scale + inEne2_e[sf] ) ) */
     347       43200 :             dir_nrg_2_e = add( scale, inEne2_e[sf] );
     348             : 
     349       43200 :             IF( EQ_16( n_dirs_1, 2 ) )
     350             :             {
     351       14400 :                 tmp = BASOP_Util_Divide1616_Scale( inMeta1->directToTotalRatio[1][sf][band], UINT8_MAX, &scale );
     352       14400 :                 L_tmp = Mpy_32_32( L_deposit_h( tmp ), inEne1_fx[sf][band] ); /* Q( 31 - ( scale + inEne1_e[sf] ) ) */
     353       14400 :                 scale = add( scale, inEne1_e[sf] );
     354       14400 :                 dir_nrg_1_fx = BASOP_Util_Add_Mant32Exp( L_tmp, scale, dir_nrg_1_fx, dir_nrg_1_e, &dir_nrg_1_e );
     355             :             }
     356             : 
     357       43200 :             IF( EQ_16( n_dirs_2, 2 ) )
     358             :             {
     359       14400 :                 tmp = BASOP_Util_Divide1616_Scale( inMeta2->directToTotalRatio[1][sf][band], UINT8_MAX, &scale );
     360       14400 :                 L_tmp = Mpy_32_32( L_deposit_h( tmp ), inEne2_fx[sf][band] ); /* Q( 31 - ( scale + inEne2_e[sf] ) ) */
     361       14400 :                 scale = add( scale, inEne2_e[sf] );
     362       14400 :                 dir_nrg_2_fx = BASOP_Util_Add_Mant32Exp( L_tmp, scale, dir_nrg_2_fx, dir_nrg_2_e, &dir_nrg_2_e );
     363             :             }
     364             : 
     365       43200 :             IF( BASOP_Util_Cmp_Mant32Exp( dir_nrg_1_fx, dir_nrg_1_e, dir_nrg_2_fx, dir_nrg_2_e ) > 0 )
     366             :             {
     367       15654 :                 copy_masa_meta_tile_fx( outMeta, inMeta1, sf, band );
     368             :             }
     369             :             ELSE
     370             :             {
     371       27546 :                 copy_masa_meta_tile_fx( outMeta, inMeta2, sf, band );
     372             :             }
     373             : 
     374       43200 :             inEne1_fx[sf][band] = BASOP_Util_Add_Mant32Exp( inEne1_fx[sf][band], inEne1_e[sf], inEne2_fx[sf][band], inEne2_e[sf], &in1_e[band] );
     375       43200 :             move32();
     376             :         }
     377             : 
     378        1800 :         max_e = in1_e[0];
     379        1800 :         move16();
     380       43200 :         FOR( i = 1; i < MASA_FREQUENCY_BANDS; i++ )
     381             :         {
     382       41400 :             if ( LT_16( max_e, in1_e[i] ) )
     383             :             {
     384         268 :                 max_e = in1_e[i];
     385         268 :                 move16();
     386             :             }
     387             :         }
     388             : 
     389       45000 :         FOR( i = 0; i < MASA_FREQUENCY_BANDS; i++ )
     390             :         {
     391       43200 :             inEne1_fx[sf][i] = L_shr( inEne1_fx[sf][i], sub( max_e, in1_e[i] ) ); /* Q( 31 - max_e ) */
     392       43200 :             move32();
     393             :         }
     394             : 
     395        1800 :         inEne1_e[sf] = max_e;
     396        1800 :         move16();
     397             :     }
     398             : 
     399             :     /* Set descriptive meta for mixed format */
     400         450 :     outMeta->descriptiveMeta.sourceFormat = 0u;
     401         450 :     move16();
     402         450 :     outMeta->descriptiveMeta.transportDefinition = 0u;
     403         450 :     move16();
     404         450 :     outMeta->descriptiveMeta.channelAngle = 0u;
     405         450 :     move16();
     406         450 :     outMeta->descriptiveMeta.channelDistance = 0u;
     407         450 :     move16();
     408         450 :     outMeta->descriptiveMeta.channelLayout = 0u;
     409         450 :     move16();
     410         450 :     test();
     411         450 :     IF( EQ_16( n_dirs_1, 2 ) || EQ_16( n_dirs_2, 2 ) )
     412             :     {
     413         300 :         outMeta->descriptiveMeta.numberOfDirections = 1u;
     414         300 :         move16();
     415             :     }
     416             :     ELSE
     417             :     {
     418         150 :         outMeta->descriptiveMeta.numberOfDirections = 0u;
     419         150 :         move16();
     420             :     }
     421             : 
     422             :     /* Number of transports should be set outside. */
     423             : 
     424         450 :     return;
     425             : }
     426             : 
     427             : 
     428             : /*---------------------------------------------------------------------*
     429             :  * ivas_prerend_merge_masa_metadata()
     430             :  *
     431             :  *
     432             :  *---------------------------------------------------------------------*/
     433             : 
     434         450 : void ivas_prerend_merge_masa_metadata_fx(
     435             :     MASA_DECODER_EXT_OUT_META_HANDLE outMeta,                            /* o  : Merged metadata output                                                      */
     436             :     MASA_DECODER_EXT_OUT_META_HANDLE inMeta1,                            /* i  : Input metadata 1                                                            */
     437             :     IVAS_REND_AudioConfigType inType1,                                   /* i  : Type of input 1                                                             */
     438             :     Word32 inEne1_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i/o: TF-energy of input 1. after merge, contains the energy of the merged signal */
     439             :     Word16 *inEne1_e,                                                    /* i/o: TF-energy of input 1 Exponent                                               */
     440             :     MASA_DECODER_EXT_OUT_META_HANDLE inMeta2,                            /* i  : Input metadata 2                                                            */
     441             :     IVAS_REND_AudioConfigType inType2,                                   /* i  : Type of input 2                                                             */
     442             :     Word32 inEne2_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i  : TF-energy of input 2                                                        */
     443             :     Word16 *inEne2_e                                                     /* i  : TF-energy of input 2 Exponent                                               */
     444             : )
     445             : {
     446             :     /* mixing ISMs with non-ISM use different merge */
     447         450 :     test();
     448         450 :     test();
     449         450 :     test();
     450         450 :     test();
     451         450 :     test();
     452         450 :     test();
     453         450 :     IF( EQ_32( inType1, IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED ) && NE_32( inType2, IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED ) && ( inMeta1->descriptiveMeta.numberOfDirections == 0u && inMeta2->descriptiveMeta.numberOfDirections == 0u ) )
     454             :     {
     455             :         /* meta_1 is ISM and both are 1dir */
     456           0 :         diffuse_meta_merge_1x1_fx( outMeta, inMeta2, inEne2_fx, inEne2_e, inMeta1, inEne1_fx, inEne1_e );
     457             :     }
     458         450 :     ELSE IF( EQ_32( inType2, IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED ) && NE_32( inType1, IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED ) && ( inMeta1->descriptiveMeta.numberOfDirections == 0u && inMeta2->descriptiveMeta.numberOfDirections == 0u ) )
     459             :     {
     460             :         /* meta_2 is ISM and both are 1dir */
     461           0 :         diffuse_meta_merge_1x1_fx( outMeta, inMeta1, inEne1_fx, inEne1_e, inMeta2, inEne2_fx, inEne2_e );
     462             :     }
     463             :     ELSE
     464             :     {
     465             : 
     466         450 :         full_stream_merge_fx( outMeta, inMeta1, inEne1_fx, inEne1_e, inMeta2, inEne2_fx, inEne2_e );
     467             :     }
     468             : 
     469         450 :     return;
     470             : }
     471             : 
     472             : 
     473             : /*---------------------------------------------------------------------*
     474             :  * masaPrerendOpen()
     475             :  *
     476             :  *
     477             :  *---------------------------------------------------------------------*/
     478             : 
     479           1 : ivas_error masaPrerendOpen_fx(
     480             :     MASA_PREREND_HANDLE *hMasaPrerendPtr, /* o  : handle to the opened prerenderer */
     481             :     Word16 numTransports,                 /* i  : number of transport channels     */
     482             :     Word32 input_Fs                       /* i  : signal sampling rate             */
     483             : )
     484             : {
     485             :     MASA_PREREND_HANDLE hMasaPrerend;
     486             :     Word16 i;
     487             :     ivas_error error;
     488             : 
     489           1 :     error = IVAS_ERR_OK;
     490           1 :     move32();
     491             : 
     492           1 :     hMasaPrerend = (MASA_PREREND_HANDLE) malloc( sizeof( MASA_PREREND_DATA ) );
     493           1 :     IF( hMasaPrerend == NULL )
     494             :     {
     495           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA prerenderer\n" ) );
     496             :     }
     497             : 
     498           1 :     hMasaPrerend->num_Cldfb_instances = numTransports;
     499           1 :     move16();
     500           3 :     FOR( i = 0; i < hMasaPrerend->num_Cldfb_instances; i++ )
     501             :     {
     502           2 :         IF( ( error = openCldfb_ivas_fx( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ) != IVAS_ERR_OK )
     503             :         {
     504           0 :             return error;
     505             :         }
     506             :     }
     507           1 :     FOR( ; i < MASA_MAX_TRANSPORT_CHANNELS; i++ )
     508             :     {
     509           0 :         hMasaPrerend->cldfbAnaEnc[i] = NULL;
     510             :     }
     511             : 
     512           1 :     IF( ( hMasaPrerend->hMasaOut = (MASA_DECODER_EXT_OUT_META_HANDLE) malloc( sizeof( MASA_DECODER_EXT_OUT_META ) ) ) == NULL )
     513             :     {
     514           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA prerenderer\n" ) );
     515             :     }
     516             : 
     517           1 :     IF( ( hMasaPrerend->sph_grid16 = (SPHERICAL_GRID_DATA *) malloc( sizeof( SPHERICAL_GRID_DATA ) ) ) == NULL )
     518             :     {
     519           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA prerenderer\n" ) );
     520             :     }
     521           1 :     generate_gridEq_fx( hMasaPrerend->sph_grid16 );
     522             : 
     523           1 :     IF( error == IVAS_ERR_OK )
     524             :     {
     525           1 :         *hMasaPrerendPtr = hMasaPrerend;
     526             :     }
     527             : 
     528           1 :     return error;
     529             : }
     530             : 
     531             : /*---------------------------------------------------------------------*
     532             :  * masaPrerendClose()
     533             :  *
     534             :  *
     535             :  *---------------------------------------------------------------------*/
     536             : 
     537         658 : void masaPrerendClose_fx(
     538             :     MASA_PREREND_HANDLE *hMasaPrerendPtr /* i/o: prerenderer handle to be closed */
     539             : )
     540             : {
     541             :     Word16 i;
     542             : 
     543         658 :     test();
     544         658 :     IF( hMasaPrerendPtr == NULL || *hMasaPrerendPtr == NULL )
     545             :     {
     546         657 :         return;
     547             :     }
     548             : 
     549           3 :     FOR( i = 0; i < ( *hMasaPrerendPtr )->num_Cldfb_instances; i++ )
     550             :     {
     551           2 :         deleteCldfb_ivas_fx( &( ( *hMasaPrerendPtr )->cldfbAnaEnc[i] ) );
     552             :     }
     553             : 
     554           1 :     free( ( *hMasaPrerendPtr )->hMasaOut );
     555           1 :     ( *hMasaPrerendPtr )->hMasaOut = NULL;
     556           1 :     free( ( *hMasaPrerendPtr )->sph_grid16 );
     557           1 :     ( *hMasaPrerendPtr )->sph_grid16 = NULL;
     558             : 
     559           1 :     free( ( *hMasaPrerendPtr ) );
     560           1 :     ( *hMasaPrerendPtr ) = NULL;
     561             : 
     562           1 :     return;
     563             : }

Generated by: LCOV version 1.14