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

Generated by: LCOV version 1.14