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

Generated by: LCOV version 1.14