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

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <math.h>
      34             : #include "options.h"
      35             : #include "lib_rend.h"
      36             : #include "ivas_prot_rend.h"
      37             : #include "ivas_prot.h"
      38             : #include "ivas_cnst.h"
      39             : #include "prot.h"
      40             : #include "wmc_auto.h"
      41             : 
      42             : 
      43             : /*---------------------------------------------------------------------*
      44             :  * Local function prototypes
      45             :  *---------------------------------------------------------------------*/
      46             : 
      47             : static void copy_masa_meta_tile( MASA_DECODER_EXT_OUT_META_HANDLE outMeta, MASA_DECODER_EXT_OUT_META_HANDLE inMeta, const uint8_t sf, const uint8_t band );
      48             : 
      49             : static void full_stream_merge( MASA_DECODER_EXT_OUT_META_HANDLE outMeta, MASA_DECODER_EXT_OUT_META_HANDLE inMeta1, float inEne1[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], MASA_DECODER_EXT_OUT_META_HANDLE inMeta2, float inEne2[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS] );
      50             : 
      51             : static void diffuse_meta_merge_1x1( MASA_DECODER_EXT_OUT_META_HANDLE outMeta, MASA_DECODER_EXT_OUT_META_HANDLE inMeta, float inEne[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], MASA_DECODER_EXT_OUT_META_HANDLE inMetaISM, float inEneISM[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS] );
      52             : 
      53             : 
      54             : /*---------------------------------------------------------------------*
      55             :  * copy_masa_meta_tile()
      56             :  *
      57             :  *
      58             :  *---------------------------------------------------------------------*/
      59             : 
      60       86400 : void copy_masa_meta_tile(
      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 uint8_t sf,                         /* i  : sub-frame index        */
      64             :     const uint8_t band                        /* i  : band index             */
      65             : )
      66             : {
      67       86400 :     outMeta->directionIndex[0][sf][band] = inMeta->directionIndex[0][sf][band];
      68       86400 :     outMeta->directToTotalRatio[0][sf][band] = inMeta->directToTotalRatio[0][sf][band];
      69       86400 :     outMeta->spreadCoherence[0][sf][band] = inMeta->spreadCoherence[0][sf][band];
      70             : 
      71       86400 :     outMeta->surroundCoherence[sf][band] = inMeta->surroundCoherence[sf][band];
      72       86400 :     outMeta->diffuseToTotalRatio[sf][band] = inMeta->diffuseToTotalRatio[sf][band];
      73             : 
      74       86400 :     if ( inMeta->descriptiveMeta.numberOfDirections == 1 )
      75             :     {
      76       32720 :         outMeta->directionIndex[1][sf][band] = inMeta->directionIndex[1][sf][band];
      77       32720 :         outMeta->directToTotalRatio[1][sf][band] = inMeta->directToTotalRatio[1][sf][band];
      78       32720 :         outMeta->spreadCoherence[1][sf][band] = inMeta->spreadCoherence[1][sf][band];
      79             :     }
      80             :     else
      81             :     {
      82             :         /* make sure the output has zeroed data in the second direction */
      83       53680 :         outMeta->directionIndex[1][sf][band] = SPH_IDX_FRONT;
      84       53680 :         outMeta->directToTotalRatio[1][sf][band] = 0u;
      85       53680 :         outMeta->spreadCoherence[1][sf][band] = 0u;
      86             :     }
      87             : 
      88       86400 :     return;
      89             : }
      90             : 
      91             : 
      92             : /*---------------------------------------------------------------------*
      93             :  * copy_masa_descriptive_meta()
      94             :  *
      95             :  *
      96             :  *---------------------------------------------------------------------*/
      97             : 
      98         300 : void copy_masa_descriptive_meta(
      99             :     MASA_DECRIPTIVE_META *outMeta, /* o  : metadata to be written */
     100             :     MASA_DECRIPTIVE_META *inMeta   /* i  : input metadata         */
     101             : )
     102             : {
     103             :     uint8_t char_idx;
     104        2700 :     for ( char_idx = 0; char_idx < 8; char_idx++ )
     105             :     {
     106        2400 :         outMeta->formatDescriptor[char_idx] = inMeta->formatDescriptor[char_idx];
     107             :     }
     108         300 :     outMeta->numberOfDirections = inMeta->numberOfDirections;
     109         300 :     outMeta->numberOfChannels = inMeta->numberOfChannels;
     110         300 :     outMeta->sourceFormat = inMeta->sourceFormat;
     111         300 :     outMeta->transportDefinition = inMeta->transportDefinition;
     112         300 :     outMeta->channelAngle = inMeta->channelAngle;
     113         300 :     outMeta->channelDistance = inMeta->channelDistance;
     114         300 :     outMeta->channelLayout = inMeta->channelLayout;
     115             : 
     116         300 :     return;
     117             : }
     118             : 
     119             : 
     120             : /*---------------------------------------------------------------------*
     121             :  * diffuse_meta_merge_1x1()
     122             :  *
     123             :  *
     124             :  *---------------------------------------------------------------------*/
     125             : 
     126         108 : void diffuse_meta_merge_1x1(
     127             :     MASA_DECODER_EXT_OUT_META_HANDLE outMeta,                         /* o  : Merged metadata output                   */
     128             :     MASA_DECODER_EXT_OUT_META_HANDLE inMeta,                          /* i  : Input metadata 1                         */
     129             :     float inEne[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],   /* i/o: TF-energy of input 1. energy after merge */
     130             :     MASA_DECODER_EXT_OUT_META_HANDLE inMetaISM,                       /* i  : Input metadata 2                         */
     131             :     float inEneISM[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS] /* i  : TF-energy of input 2                     */
     132             : )
     133             : {
     134             :     int8_t sf, band;
     135             : 
     136         540 :     for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
     137             :     {
     138       10800 :         for ( band = 0; band < MASA_FREQUENCY_BANDS; band++ )
     139             :         {
     140             :             float energyTimesRatio, energyTimesRatioISM, total_diff_nrg, dir_nrg_ratio, total_nrg;
     141             :             float dir_ratio_ism;
     142             : 
     143       10368 :             energyTimesRatio = (float) ( inMeta->directToTotalRatio[0][sf][band] ) / UINT8_MAX * inEne[sf][band];
     144             : 
     145       10368 :             total_nrg = inEne[sf][band] + inEneISM[sf][band];
     146             : 
     147             :             /* target is original MASA diffuseness */
     148       10368 :             total_diff_nrg = (float) ( inMeta->diffuseToTotalRatio[sf][band] ) / UINT8_MAX * inEne[sf][band];
     149             :             /* criterion is mean of ISM ratio and new ratio */
     150       10368 :             dir_ratio_ism = (float) ( inMetaISM->directToTotalRatio[0][sf][band] ) / UINT8_MAX;
     151             : 
     152       10368 :             energyTimesRatioISM = ( dir_ratio_ism + ( 1.0f - total_diff_nrg / ( EPSILON + total_nrg ) ) ) / 2.0f * inEneISM[sf][band];
     153             : 
     154       10368 :             if ( energyTimesRatioISM > energyTimesRatio )
     155             :             {
     156             :                 float new_dir_ratio, new_diff_ratio;
     157        2394 :                 outMeta->directionIndex[0][sf][band] = inMetaISM->directionIndex[0][sf][band];
     158        2394 :                 outMeta->directToTotalRatio[0][sf][band] = inMetaISM->directToTotalRatio[0][sf][band];
     159        2394 :                 outMeta->spreadCoherence[0][sf][band] = inMetaISM->spreadCoherence[0][sf][band];
     160             : 
     161        2394 :                 outMeta->surroundCoherence[sf][band] = inMetaISM->surroundCoherence[sf][band];
     162             : 
     163        2394 :                 dir_nrg_ratio = 1.0f - total_diff_nrg / ( EPSILON + total_nrg ); /* new dir ratio */
     164        2394 :                 new_dir_ratio = min( dir_nrg_ratio, dir_ratio_ism );             /* clip with original ISM dir */
     165        2394 :                 outMeta->directToTotalRatio[0][sf][band] = (uint8_t) floorf( new_dir_ratio * UINT8_MAX );
     166        2394 :                 new_diff_ratio = 1.0f - new_dir_ratio;
     167        2394 :                 outMeta->diffuseToTotalRatio[sf][band] = (uint8_t) floorf( new_diff_ratio * UINT8_MAX );
     168             :             }
     169             :             else
     170             :             {
     171             :                 /* use the plain original meta for this tile */
     172        7974 :                 outMeta->directionIndex[0][sf][band] = inMeta->directionIndex[0][sf][band];
     173        7974 :                 outMeta->directToTotalRatio[0][sf][band] = inMeta->directToTotalRatio[0][sf][band];
     174        7974 :                 outMeta->spreadCoherence[0][sf][band] = inMeta->spreadCoherence[0][sf][band];
     175             : 
     176        7974 :                 outMeta->surroundCoherence[sf][band] = inMeta->surroundCoherence[sf][band];
     177        7974 :                 outMeta->diffuseToTotalRatio[sf][band] = inMeta->diffuseToTotalRatio[sf][band];
     178             :             }
     179       10368 :             outMeta->directionIndex[1][sf][band] = SPH_IDX_FRONT;
     180       10368 :             outMeta->directToTotalRatio[1][sf][band] = 0u;
     181       10368 :             outMeta->spreadCoherence[1][sf][band] = 0u;
     182             : 
     183       10368 :             inEne[sf][band] += inEneISM[sf][band]; /* Update energy for subsequent mergings */
     184             :         }
     185             :     }
     186             : 
     187             :     /* Set descriptive meta for mixed format */
     188         108 :     outMeta->descriptiveMeta.sourceFormat = 0u;
     189         108 :     outMeta->descriptiveMeta.transportDefinition = 0u;
     190         108 :     outMeta->descriptiveMeta.channelAngle = 0u;
     191         108 :     outMeta->descriptiveMeta.channelDistance = 0u;
     192         108 :     outMeta->descriptiveMeta.channelLayout = 0u;
     193         108 :     outMeta->descriptiveMeta.numberOfDirections = 0u;
     194             :     /* Number of transports should be set outside. */
     195             : 
     196         108 :     return;
     197             : }
     198             : 
     199             : 
     200             : /*---------------------------------------------------------------------*
     201             :  * full_stream_merge()
     202             :  *
     203             :  *
     204             :  *---------------------------------------------------------------------*/
     205             : 
     206         900 : void full_stream_merge(
     207             :     MASA_DECODER_EXT_OUT_META_HANDLE outMeta,                        /* o  : Merged metadata output                                                        */
     208             :     MASA_DECODER_EXT_OUT_META_HANDLE inMeta1,                        /* i  : Input metadata 1                                                              */
     209             :     float inEne1[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i/o: TF-energy of input 1. after merge, contains the energy of the merged signal   */
     210             :     MASA_DECODER_EXT_OUT_META_HANDLE inMeta2,                        /* i  : Input metadata 2                                                              */
     211             :     float inEne2[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]  /* i  : TF-energy of input 2                                                          */
     212             : )
     213             : {
     214             :     float dir_nrg_1, dir_nrg_2;
     215             :     uint8_t n_dirs_1, n_dirs_2;
     216             :     uint8_t sf, band;
     217             : 
     218             :     /* full stream select based on total direct energy */
     219         900 :     n_dirs_1 = inMeta1->descriptiveMeta.numberOfDirections + 1u; /* to 1-based */
     220         900 :     n_dirs_2 = inMeta2->descriptiveMeta.numberOfDirections + 1u;
     221             : 
     222        4500 :     for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
     223             :     {
     224       90000 :         for ( band = 0; band < MASA_FREQUENCY_BANDS; band++ )
     225             :         {
     226       86400 :             dir_nrg_1 = (float) ( inMeta1->directToTotalRatio[0][sf][band] ) / UINT8_MAX * inEne1[sf][band];
     227       86400 :             dir_nrg_2 = (float) ( inMeta2->directToTotalRatio[0][sf][band] ) / UINT8_MAX * inEne2[sf][band];
     228             : 
     229       86400 :             if ( n_dirs_1 == 2 )
     230             :             {
     231       28800 :                 dir_nrg_1 += (float) ( inMeta1->directToTotalRatio[1][sf][band] ) / UINT8_MAX * inEne1[sf][band];
     232             :             }
     233             : 
     234       86400 :             if ( n_dirs_2 == 2 )
     235             :             {
     236       28800 :                 dir_nrg_2 += (float) ( inMeta2->directToTotalRatio[1][sf][band] ) / UINT8_MAX * inEne2[sf][band];
     237             :             }
     238             : 
     239       86400 :             if ( dir_nrg_1 > dir_nrg_2 )
     240             :             {
     241       53536 :                 copy_masa_meta_tile( outMeta, inMeta1, sf, band );
     242             :             }
     243             :             else
     244             :             {
     245       32864 :                 copy_masa_meta_tile( outMeta, inMeta2, sf, band );
     246             :             }
     247             : 
     248       86400 :             inEne1[sf][band] += inEne2[sf][band]; /* Update energy for subsequent mergings */
     249             :         }
     250             :     }
     251             : 
     252             :     /* Set descriptive meta for mixed format */
     253         900 :     outMeta->descriptiveMeta.sourceFormat = 0u;
     254         900 :     outMeta->descriptiveMeta.transportDefinition = 0u;
     255         900 :     outMeta->descriptiveMeta.channelAngle = 0u;
     256         900 :     outMeta->descriptiveMeta.channelDistance = 0u;
     257         900 :     outMeta->descriptiveMeta.channelLayout = 0u;
     258         900 :     if ( n_dirs_1 == 2 || n_dirs_2 == 2 )
     259             :     {
     260         600 :         outMeta->descriptiveMeta.numberOfDirections = 1u;
     261             :     }
     262             :     else
     263             :     {
     264         300 :         outMeta->descriptiveMeta.numberOfDirections = 0u;
     265             :     }
     266             :     /* Number of transports should be set outside. */
     267             : 
     268         900 :     return;
     269             : }
     270             : 
     271             : 
     272             : /*---------------------------------------------------------------------*
     273             :  * ivas_prerend_merge_masa_metadata()
     274             :  *
     275             :  *
     276             :  *---------------------------------------------------------------------*/
     277             : 
     278        1008 : void ivas_prerend_merge_masa_metadata(
     279             :     MASA_DECODER_EXT_OUT_META_HANDLE outMeta,                        /* o  : Merged metadata output                                                        */
     280             :     MASA_DECODER_EXT_OUT_META_HANDLE inMeta1,                        /* i  : Input metadata 1                                                              */
     281             :     IVAS_REND_AudioConfigType inType1,                               /* i  : Type of input 1                                                               */
     282             :     float inEne1[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /* i/o: TF-energy of input 1. after merge, contains the energy of the merged signal   */
     283             :     MASA_DECODER_EXT_OUT_META_HANDLE inMeta2,                        /* i  : Input metadata 2                                                              */
     284             :     IVAS_REND_AudioConfigType inType2,                               /* i  : Type of input 2                                                               */
     285             :     float inEne2[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]  /* i  : TF-energy of input 2. may be altered                                          */
     286             : )
     287             : {
     288             :     /* mixing ISMs with non-ISM use different merge */
     289        1008 :     if ( inType1 == IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED && inType2 != IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED && ( inMeta1->descriptiveMeta.numberOfDirections == 0u && inMeta2->descriptiveMeta.numberOfDirections == 0u ) )
     290           0 :     {
     291             :         /* meta_1 is ISM and both are 1dir */
     292             :         int8_t sf;
     293             : 
     294           0 :         diffuse_meta_merge_1x1( outMeta, inMeta2, inEne2, inMeta1, inEne1 ); /* post-merge energy is now in inEne2 and needs to be copied to inEne1 */
     295             : 
     296           0 :         for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
     297             :         {
     298           0 :             mvr2r( inEne2[sf], inEne1[sf], MASA_FREQUENCY_BANDS );
     299             :         }
     300             :     }
     301        1008 :     else if ( inType2 == IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED && inType1 != IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED && ( inMeta1->descriptiveMeta.numberOfDirections == 0u && inMeta2->descriptiveMeta.numberOfDirections == 0u ) )
     302             :     {
     303             :         /* meta_2 is ISM and both are 1dir */
     304         108 :         diffuse_meta_merge_1x1( outMeta, inMeta1, inEne1, inMeta2, inEne2 );
     305             :     }
     306             :     else
     307             :     {
     308         900 :         full_stream_merge( outMeta, inMeta1, inEne1, inMeta2, inEne2 );
     309             :     }
     310             : 
     311        1008 :     return;
     312             : }
     313             : 
     314             : 
     315             : /*---------------------------------------------------------------------*
     316             :  * masaPrerendOpen()
     317             :  *
     318             :  *
     319             :  *---------------------------------------------------------------------*/
     320             : 
     321           2 : ivas_error masaPrerendOpen(
     322             :     MASA_PREREND_HANDLE *hMasaPrerendPtr, /* o  : handle to the opened prerenderer */
     323             :     int16_t numTransports,                /* i  : number of transport channels     */
     324             :     int32_t input_Fs                      /* i  : signal sampling rate             */
     325             : )
     326             : {
     327             :     MASA_PREREND_HANDLE hMasaPrerend;
     328             :     int16_t i;
     329             :     ivas_error error;
     330             : 
     331           2 :     error = IVAS_ERR_OK;
     332             : 
     333           2 :     hMasaPrerend = (MASA_PREREND_HANDLE) malloc( sizeof( MASA_PREREND_DATA ) );
     334           2 :     if ( hMasaPrerend == NULL )
     335             :     {
     336           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA prerenderer\n" ) );
     337             :     }
     338             : 
     339           2 :     hMasaPrerend->num_Cldfb_instances = numTransports;
     340           6 :     for ( i = 0; i < hMasaPrerend->num_Cldfb_instances; i++ )
     341             :     {
     342           4 :         if ( ( error = openCldfb( &( hMasaPrerend->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK )
     343             :         {
     344           0 :             return error;
     345             :         }
     346             :     }
     347           2 :     for ( ; i < MASA_MAX_TRANSPORT_CHANNELS; i++ )
     348             :     {
     349           0 :         hMasaPrerend->cldfbAnaEnc[i] = NULL;
     350             :     }
     351             : 
     352           2 :     if ( ( hMasaPrerend->hMasaOut = (MASA_DECODER_EXT_OUT_META_HANDLE) malloc( sizeof( MASA_DECODER_EXT_OUT_META ) ) ) == NULL )
     353             :     {
     354           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA prerenderer\n" ) );
     355             :     }
     356             : 
     357           2 :     if ( ( hMasaPrerend->sph_grid16 = (SPHERICAL_GRID_DATA *) malloc( sizeof( SPHERICAL_GRID_DATA ) ) ) == NULL )
     358             :     {
     359           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA prerenderer\n" ) );
     360             :     }
     361           2 :     generate_gridEq( hMasaPrerend->sph_grid16 );
     362             : 
     363           2 :     if ( error == IVAS_ERR_OK )
     364             :     {
     365           2 :         *hMasaPrerendPtr = hMasaPrerend;
     366             :     }
     367             : 
     368           2 :     return error;
     369             : }
     370             : 
     371             : 
     372             : /*---------------------------------------------------------------------*
     373             :  * masaPrerendClose()
     374             :  *
     375             :  *
     376             :  *---------------------------------------------------------------------*/
     377             : 
     378        1316 : void masaPrerendClose(
     379             :     MASA_PREREND_HANDLE *hMasaPrerendPtr /* i/o: prerenderer handle to be closed */
     380             : )
     381             : {
     382             :     int16_t i;
     383             : 
     384        1316 :     if ( hMasaPrerendPtr == NULL || *hMasaPrerendPtr == NULL )
     385             :     {
     386        1314 :         return;
     387             :     }
     388             : 
     389           6 :     for ( i = 0; i < ( *hMasaPrerendPtr )->num_Cldfb_instances; i++ )
     390             :     {
     391           4 :         deleteCldfb( &( ( *hMasaPrerendPtr )->cldfbAnaEnc[i] ) );
     392             :     }
     393             : 
     394           2 :     free( ( *hMasaPrerendPtr )->hMasaOut );
     395           2 :     ( *hMasaPrerendPtr )->hMasaOut = NULL;
     396           2 :     free( ( *hMasaPrerendPtr )->sph_grid16 );
     397           2 :     ( *hMasaPrerendPtr )->sph_grid16 = NULL;
     398             : 
     399           2 :     free( ( *hMasaPrerendPtr ) );
     400           2 :     ( *hMasaPrerendPtr ) = NULL;
     401             : 
     402           2 :     return;
     403             : }

Generated by: LCOV version 1.14