LCOV - code coverage report
Current view: top level - lib_com - wtda.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 134 140 95.7 %
Date: 2025-05-23 08:37:30 Functions: 6 6 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             : /*====================================================================================
      34             :     EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
      35             :   ====================================================================================*/
      36             : 
      37             : #include <stdint.h>
      38             : #include "options.h"
      39             : #ifdef DEBUGGING
      40             : #include "debug.h"
      41             : #endif
      42             : #include "cnst.h"
      43             : #include "prot.h"
      44             : #include "rom_com.h"
      45             : #include <assert.h>
      46             : #include "wmc_auto.h"
      47             : #ifdef DEBUG_PLOT
      48             : #include "deb_out.h"
      49             : #endif
      50             : 
      51             : /*--------------------------------------------------------------------------*
      52             :  *  mvr2r_inv()
      53             :  *
      54             :  *
      55             :  *--------------------------------------------------------------------------*/
      56             : 
      57      163197 : static void mvr2r_inv(
      58             :     const float *in,       /* i  : input vector           */
      59             :     float *out,            /* o  : output vector          */
      60             :     const int16_t L,       /* i  : length                 */
      61             :     const int16_t decimate /* i  : decimation flag [-1,1] */
      62             : )
      63             : {
      64             :     int16_t i;
      65             : 
      66      163197 :     in = in + (int16_t) ( ( decimate - 1 ) / 2 );
      67      163197 :     out = out + L - 1;
      68             : 
      69    15144125 :     for ( i = 0; i < L; i++ )
      70             :     {
      71    14980928 :         *out = *in;
      72    14980928 :         in += decimate;
      73    14980928 :         out--;
      74             :     }
      75             : 
      76      163197 :     return;
      77             : }
      78             : 
      79             : /*--------------------------------------------------------------------------*
      80             :  *  mvr2r_dec()
      81             :  *
      82             :  *
      83             :  *--------------------------------------------------------------------------*/
      84             : 
      85      149817 : static void mvr2r_dec(
      86             :     const float *in, /* i  : input vector           */
      87             :     float *out,      /* o  : output vector          */
      88             :     int16_t L,       /* i  : length                 */
      89             :     int16_t decimate /* i  : decimation flag [-1,1] */
      90             : )
      91             : {
      92             :     int16_t i;
      93      149817 :     in = in + (int16_t) ( ( decimate - 1 ) / 2 );
      94    14449817 :     for ( i = 0; i < L; i++ )
      95             :     {
      96    14300000 :         *out = *in;
      97    14300000 :         in += decimate;
      98    14300000 :         out++;
      99             :     }
     100             : 
     101      149817 :     return;
     102             : }
     103             : 
     104             : /*--------------------------------------------------------------------------*
     105             :  *  copy_win()
     106             :  *
     107             :  *
     108             :  *--------------------------------------------------------------------------*/
     109             : 
     110      313014 : static void copy_win(
     111             :     float *out_win,           /* o  : output window buffer          */
     112             :     const int16_t nb_zero,    /* i  : length of zero padding        */
     113             :     const float *in_win,      /* i  : input window                  */
     114             :     const int16_t win_lenght, /* i  : length                        */
     115             :     const int16_t nb_one,     /* i  : length of flat section (ones) */
     116             :     const int16_t decimate    /* i  : input window                  */
     117             : )
     118             : {
     119      313014 :     if ( decimate < 0 )
     120             :     {
     121      163197 :         set_f( out_win, 1, nb_one );
     122      163197 :         mvr2r_inv( in_win, out_win + nb_one, win_lenght, -decimate );
     123      163197 :         set_f( out_win + win_lenght + nb_one, 0, nb_zero );
     124             :     }
     125             :     else
     126             :     {
     127      149817 :         set_f( out_win, 0, nb_zero );
     128      149817 :         mvr2r_dec( in_win, out_win + nb_zero, win_lenght, decimate );
     129      149817 :         set_f( out_win + nb_zero + win_lenght, 1, nb_one );
     130             :     }
     131             : 
     132      313014 :     return;
     133             : }
     134             : 
     135             : /*--------------------------------------------------------------------------*
     136             :  *  tcx_get_windows_mode1()
     137             :  *
     138             :  *
     139             :  *--------------------------------------------------------------------------*/
     140             : 
     141     6973048 : void tcx_get_windows_mode1(
     142             :     const int16_t left_mode,  /* i  : overlap mode of left window half          */
     143             :     const int16_t right_mode, /* i  : overlap mode of right window half         */
     144             :     float *left_win,          /* o  : left overlap window                       */
     145             :     float *right_win,         /* o  : right overlap window                      */
     146             :     float *left_win_int,      /* o  : left overlap window                       */
     147             :     float *right_win_int,     /* o  : right overlap window                      */
     148             :     const int16_t L           /* i  : length                                    */
     149             : )
     150             : {
     151             :     /* Left part */
     152     6973048 :     if ( left_mode == MIN_OVERLAP || left_mode == TRANSITION_OVERLAP )
     153             :     {
     154       23176 :         if ( L == 256 || L == 512 )
     155             :         {
     156        3119 :             copy_win( left_win, R1_25 - 4 * R2_25 / 7, small_overlap_25, R2_25 / 7, 3 * R2_25 / 7, 1 );
     157             :         }
     158             :         else
     159             :         {
     160       20057 :             copy_win( left_win, R1_48 - 4 * R2_48 / 7, small_overlap_48, R2_48 / 7, 3 * R2_48 / 7, 1 );
     161       20057 :             copy_win( left_win_int, R1_16 - 4 * R2_16 / 7, small_overlap_int, R2_16 / 7, 3 * R2_16 / 7, 1 );
     162             :         }
     163             :     }
     164     6949872 :     else if ( left_mode == HALF_OVERLAP )
     165             :     {
     166       57343 :         if ( L == 256 || L == 512 )
     167             :         {
     168        8102 :             copy_win( left_win, R1_25 - 5 * R2_25 / 7, half_overlap_25, 3 * R2_25 / 7, 2 * R2_25 / 7, 1 );
     169             :         }
     170             :         else
     171             :         {
     172       49241 :             copy_win( left_win, R1_48 - 5 * R2_48 / 7, half_overlap_48, 3 * R2_48 / 7, 2 * R2_48 / 7, 1 );
     173       49241 :             copy_win( left_win_int, R1_16 - 5 * R2_16 / 7, half_overlap_int, 3 * R2_16 / 7, 2 * R2_16 / 7, 1 );
     174             :         }
     175             :     }
     176     6892529 :     else if ( left_mode == ALDO_WINDOW )
     177             :     {
     178             :         /* ALDO */
     179     6892529 :         if ( L == 256 || L == 512 )
     180             :         {
     181      951601 :             mvr2r( window_256kHz, left_win, R1_25 );
     182             :         }
     183             :         else
     184             :         {
     185     5940928 :             mvr2r( window_48kHz, left_win, R1_48 );
     186     5940928 :             mvr2r( window_8_16_32kHz, left_win_int, R1_16 );
     187             :         }
     188             :     }
     189             :     else
     190             :     {
     191           0 :         assert( !"Window not supported" );
     192             :     }
     193             : 
     194             :     /* Right part */
     195     6973048 :     if ( right_mode == MIN_OVERLAP || right_mode == TRANSITION_OVERLAP )
     196             :     {
     197             : 
     198       29647 :         if ( L == 256 || L == 512 )
     199             :         {
     200        4722 :             copy_win( right_win, 3 * R2_25 / 7, small_overlap_25, R2_25 / 7, 3 * R2_25 / 7, -1 );
     201             :         }
     202             :         else
     203             :         {
     204       24925 :             copy_win( right_win, 3 * R2_48 / 7, small_overlap_48, R2_48 / 7, 3 * R2_48 / 7, -1 );
     205       24925 :             copy_win( right_win_int, 3 * R2_16 / 7, small_overlap_int, R2_16 / 7, 3 * R2_16 / 7, -1 );
     206             :         }
     207             :     }
     208     6943401 :     else if ( right_mode == HALF_OVERLAP )
     209             :     {
     210             : 
     211       58462 :         if ( L == 256 || L == 512 )
     212             :         {
     213        8299 :             copy_win( right_win, 2 * R2_25 / 7, half_overlap_25, 3 * R2_25 / 7, 2 * R2_25 / 7, -1 );
     214             :         }
     215             :         else
     216             :         {
     217       50163 :             copy_win( right_win, 2 * R2_48 / 7, half_overlap_48, 3 * R2_48 / 7, 2 * R2_48 / 7, -1 );
     218       50163 :             copy_win( right_win_int, 2 * R2_16 / 7, half_overlap_int, 3 * R2_16 / 7, 2 * R2_16 / 7, -1 );
     219             :         }
     220             :     }
     221     6884939 :     else if ( right_mode == ALDO_WINDOW )
     222             :     {
     223     6884939 :         if ( L == 256 || L == 512 )
     224             :         {
     225      949801 :             mvr2r( window_256kHz + R1_25, right_win, R2_25 );
     226             :         }
     227             :         else
     228             :         {
     229     5935138 :             mvr2r( window_48kHz + R1_48, right_win, R2_48 );
     230     5935138 :             mvr2r( window_8_16_32kHz + R1_16, right_win_int, R2_16 );
     231             :         }
     232             :     }
     233             :     else
     234             :     {
     235           0 :         assert( !"Window not supported" );
     236             :     }
     237             : 
     238     6973048 :     return;
     239             : }
     240             : 
     241             : 
     242             : /*--------------------------------------------------------------------------*
     243             :  *  wtda()
     244             :  *
     245             :  *  Windowing and time-domain aliasing
     246             :  *--------------------------------------------------------------------------*/
     247             : 
     248      955152 : void wtda(
     249             :     const float *new_audio,   /* i  : input audio                         */
     250             :     float *wtda_audio,        /* o  : windowed audio                      */
     251             :     float *old_wtda,          /* i/o: windowed audio from previous frame  */
     252             :     const int16_t left_mode,  /* i  : window overlap of previous frame (0: full, 2: none, or 3: half) */
     253             :     const int16_t right_mode, /* i  : window overlap of current frame (0: full, 2: none, or 3: half) */
     254             :     const int16_t L           /* i  : length                              */
     255             : )
     256             : {
     257             :     int16_t i, decimate, decay;
     258             :     int16_t n, windecay48, windecay16;
     259             :     const float *allsig_l, *allsig_r;
     260             :     float win_right[R2_48];
     261             :     float win_int_left[R1_16];
     262             :     float win_left[R1_48];
     263             :     float win_int_right[R2_16];
     264             : 
     265      955152 :     tcx_get_windows_mode1( left_mode, right_mode, win_left, win_right, win_int_left, win_int_right, L );
     266             : 
     267      955152 :     decimate = 1; /* L_FRAME 48k */
     268      955152 :     decay = 0;
     269      955152 :     windecay48 = (int16_t) ( 2 * ( (float) L_FRAME48k * N_ZERO_MDCT_NS / FRAME_SIZE_NS ) ) + R1_48;
     270             : 
     271      955152 :     if ( L == L_FRAME32k || L == L_FRAME16k )
     272             :     {
     273      241184 :         decimate = 3;
     274      241184 :         decay = 1;
     275             :     }
     276      713968 :     else if ( L == L_FRAME8k )
     277             :     {
     278           0 :         decimate = 6;
     279           0 :         decay = 2;
     280             :     }
     281             : 
     282      955152 :     n = (int16_t) ( (float) L * N_ZERO_MDCT_NS / FRAME_SIZE_NS );
     283             : 
     284      955152 :     windecay16 = (int16_t) ( 2 * ( (float) L_FRAME16k * N_ZERO_MDCT_NS / FRAME_SIZE_NS ) ) + R1_16;
     285             : 
     286             :     /* algorithmic delay reduction */
     287      955152 :     i = 0;
     288             : 
     289      955152 :     if ( old_wtda == NULL )
     290             :     {
     291      865546 :         allsig_r = new_audio + n;
     292      865546 :         allsig_l = new_audio + n - L;
     293             : #ifdef DEBUG_PLOT
     294             :         sendDebout( "tcx_mdct", 2 * L, 1, "mdct_sig", MTV_FLOAT, allsig_l );
     295             : #endif
     296             :     }
     297             :     else
     298             :     {
     299       89606 :         allsig_r = new_audio + n;
     300       89606 :         allsig_l = old_wtda + n;
     301             :     }
     302             : 
     303      955152 :     if ( L == L_FRAME32k )
     304             :     {
     305    13118315 :         for ( i = 0; i < L / 2 - n; i += 2 )
     306             :         {
     307    12933550 :             wtda_audio[i] = -allsig_r[L / 2 - i - 1] * win_int_right[3 * L_FRAME16k / 2 - i / 2 - 1 - windecay16] - allsig_r[L / 2 + i] * win_int_right[3 * L_FRAME16k / 2 + i / 2 - windecay16];
     308    12933550 :             wtda_audio[i + 1] = -allsig_r[L / 2 - ( i + 1 ) - 1] * win_right[( 3 * L_FRAME16k / 2 - i / 2 - 1 ) * decimate + decay - windecay48] - allsig_r[L / 2 + i + 1] * win_right[( 3 * L_FRAME16k / 2 + 1 + i / 2 ) * decimate - decay - 1 - windecay48];
     309             :         }
     310             : 
     311    16813615 :         for ( i = L / 2 - n; i < L / 2; i += 2 )
     312             :         {
     313    16628850 :             wtda_audio[i] = -allsig_r[L / 2 - i - 1];
     314    16628850 :             wtda_audio[i + 1] = -allsig_r[L / 2 - ( i + 1 ) - 1];
     315             :         }
     316    16813615 :         for ( i = 0; i < n; i += 2 )
     317             :         {
     318    16628850 :             wtda_audio[i + L / 2] = allsig_l[i] * win_left[( i / 2 ) * decimate + decay] - new_audio[n - i - 1];
     319    16628850 :             wtda_audio[i + L / 2 + 1] = allsig_l[i + 1] * win_int_left[i / 2] - new_audio[n - ( i + 1 ) - 1];
     320             :         }
     321             : 
     322    13118315 :         for ( i = n; i < L / 2; i += 2 )
     323             :         {
     324    12933550 :             wtda_audio[i + L / 2] = allsig_l[i] * win_left[( i / 2 ) * decimate + decay] - allsig_l[L - i - 1] * win_left[( L / 2 - i / 2 ) * decimate - 1 - decay];
     325    12933550 :             wtda_audio[i + L / 2 + 1] = allsig_l[i + 1] * win_int_left[i / 2] - allsig_l[L - ( i + 1 ) - 1] * win_int_left[L / 2 - i / 2 - 1];
     326             :         }
     327             :     }
     328             :     else
     329             :     {
     330   154652997 :         for ( i = 0; i < L / 2 - n; i++ )
     331             :         {
     332   153882610 :             wtda_audio[i] = -allsig_r[L / 2 - i - 1] * win_right[3 * L / 2 * decimate - ( i + 1 ) * decimate + decay - windecay48] - allsig_r[L / 2 + i] * win_right[3 * L / 2 * decimate - 1 + ( i + 1 ) * decimate - decay - windecay48];
     333             :         }
     334             : 
     335   198619457 :         for ( i = L / 2 - n; i < L / 2; i++ )
     336             :         {
     337   197849070 :             wtda_audio[i] = -allsig_r[L / 2 - i - 1];
     338             :         }
     339             : 
     340   198619457 :         for ( i = 0; i < n; i++ )
     341             :         {
     342   197849070 :             wtda_audio[i + L / 2] = allsig_l[i] * win_left[i * decimate + decay] - new_audio[n - i - 1];
     343             :         }
     344             : 
     345   154652997 :         for ( i = n; i < L / 2; i++ )
     346             :         {
     347   153882610 :             wtda_audio[i + L / 2] = allsig_l[i] * win_left[i * decimate + decay] - allsig_l[L - i - 1] * win_left[L * decimate - i * decimate - 1 - decay];
     348             :         }
     349             :     }
     350             : 
     351      955152 :     if ( old_wtda != NULL )
     352             :     {
     353       89606 :         mvr2r( new_audio, old_wtda, L );
     354             :     }
     355             : 
     356      955152 :     return;
     357             : }
     358             : 
     359      631362 : void wtda_ext(
     360             :     const float *new_audio,    /* i  : input audio                         */
     361             :     float *wtda_audio,         /* o  : windowed audio                      */
     362             :     const int16_t left_mode,   /* i  : window overlap of previous frame (0: full, 2: none, or 3: half) */
     363             :     const int16_t right_mode,  /* i  : window overlap of current frame (0: full, 2: none, or 3: half) */
     364             :     const int16_t L,           /* i  : length                              */
     365             :     const uint16_t kernel_type /* i  : transform kernel type (0 - 3)       */
     366             : )
     367             : {
     368      631362 :     const float sign_left = ( kernel_type >= 2 ? -1.f : 1.f );
     369      631362 :     const float sign_right = ( kernel_type & 1 ? 1.f : -1.f );
     370             :     int16_t i, decimate, decay;
     371             :     int16_t n, windecay48, windecay16;
     372             :     const float *allsig_l, *allsig_r;
     373             :     float win_right[R2_48];
     374             :     float win_int_left[R1_16];
     375             :     float win_left[R1_48];
     376             :     float win_int_right[R2_16];
     377             : 
     378      631362 :     tcx_get_windows_mode1( left_mode, right_mode, win_left, win_right, win_int_left, win_int_right, L );
     379             : 
     380      631362 :     decimate = 1; /* L_FRAME 48k */
     381      631362 :     decay = 0;
     382      631362 :     windecay48 = (int16_t) ( 2 * ( (float) L_FRAME48k * N_ZERO_MDCT_NS / FRAME_SIZE_NS ) ) + R1_48;
     383             : 
     384      631362 :     if ( L == L_FRAME32k || L == L_FRAME16k )
     385             :     {
     386      195837 :         decimate = 3;
     387      195837 :         decay = 1;
     388             :     }
     389      435525 :     else if ( L == L_FRAME8k )
     390             :     {
     391           0 :         decimate = 6;
     392           0 :         decay = 2;
     393             :     }
     394             : 
     395      631362 :     n = (int16_t) ( (float) L * N_ZERO_MDCT_NS / FRAME_SIZE_NS );
     396             : 
     397      631362 :     windecay16 = (int16_t) ( 2 * ( (float) L_FRAME16k * N_ZERO_MDCT_NS / FRAME_SIZE_NS ) ) + R1_16;
     398             : 
     399      631362 :     allsig_r = new_audio + n;
     400      631362 :     allsig_l = new_audio + n - L;
     401             : 
     402      631362 :     if ( L == L_FRAME32k )
     403             :     {
     404    11026939 :         for ( i = 0; i < L / 2 - n; i += 2 )
     405             :         {
     406    10871630 :             wtda_audio[i] = -allsig_r[L / 2 - i - 1] * win_int_right[3 * L_FRAME16k / 2 - i / 2 - 1 - windecay16] + sign_right * allsig_r[L / 2 + i] * win_int_right[3 * L_FRAME16k / 2 + i / 2 - windecay16];
     407    10871630 :             wtda_audio[i + 1] = -allsig_r[L / 2 - ( i + 1 ) - 1] * win_right[( 3 * L_FRAME16k / 2 - i / 2 - 1 ) * decimate + decay - windecay48] + sign_right * allsig_r[L / 2 + i + 1] * win_right[( 3 * L_FRAME16k / 2 + 1 + i / 2 ) * decimate - decay - 1 - windecay48];
     408             :         }
     409             : 
     410    14133119 :         for ( i = L / 2 - n; i < L / 2; i += 2 )
     411             :         {
     412    13977810 :             wtda_audio[i] = -allsig_r[L / 2 - i - 1];
     413    13977810 :             wtda_audio[i + 1] = -allsig_r[L / 2 - ( i + 1 ) - 1];
     414             :         }
     415    14133119 :         for ( i = 0; i < n; i += 2 )
     416             :         {
     417    13977810 :             wtda_audio[i + L / 2] = sign_left * allsig_l[i] * win_left[( i / 2 ) * decimate + decay] - new_audio[n - i - 1];
     418    13977810 :             wtda_audio[i + L / 2 + 1] = sign_left * allsig_l[i + 1] * win_int_left[i / 2] - new_audio[n - ( i + 1 ) - 1];
     419             :         }
     420             : 
     421    11026939 :         for ( i = n; i < L / 2; i += 2 )
     422             :         {
     423    10871630 :             wtda_audio[i + L / 2] = sign_left * allsig_l[i] * win_left[( i / 2 ) * decimate + decay] - allsig_l[L - i - 1] * win_left[( L / 2 - i / 2 ) * decimate - 1 - decay];
     424    10871630 :             wtda_audio[i + L / 2 + 1] = sign_left * allsig_l[i + 1] * win_int_left[i / 2] - allsig_l[L - ( i + 1 ) - 1] * win_int_left[L / 2 - i / 2 - 1];
     425             :         }
     426             :     }
     427             :     else
     428             :     {
     429    94773263 :         for ( i = 0; i < L / 2 - n; i++ )
     430             :         {
     431    94297210 :             wtda_audio[i] = -allsig_r[L / 2 - i - 1] * win_right[3 * L / 2 * decimate - ( i + 1 ) * decimate + decay - windecay48] + sign_right * allsig_r[L / 2 + i] * win_right[3 * L / 2 * decimate - 1 + ( i + 1 ) * decimate - decay - windecay48];
     432             :         }
     433             : 
     434   121715323 :         for ( i = L / 2 - n; i < L / 2; i++ )
     435             :         {
     436   121239270 :             wtda_audio[i] = -allsig_r[L / 2 - i - 1];
     437             :         }
     438             : 
     439   121715323 :         for ( i = 0; i < n; i++ )
     440             :         {
     441   121239270 :             wtda_audio[i + L / 2] = sign_left * allsig_l[i] * win_left[i * decimate + decay] - new_audio[n - i - 1];
     442             :         }
     443             : 
     444    94773263 :         for ( i = n; i < L / 2; i++ )
     445             :         {
     446    94297210 :             wtda_audio[i + L / 2] = sign_left * allsig_l[i] * win_left[i * decimate + decay] - allsig_l[L - i - 1] * win_left[L * decimate - i * decimate - 1 - decay];
     447             :         }
     448             :     }
     449             : 
     450      631362 :     return;
     451             : }

Generated by: LCOV version 1.14