LCOV - code coverage report
Current view: top level - lib_dec - tcq_core_dec.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 80 166 48.2 %
Date: 2025-05-23 08:37:30 Functions: 1 1 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 "rom_com.h"
      44             : #include "prot.h"
      45             : #include "basop_util.h"
      46             : #include "basop_proto_func.h"
      47             : #include "wmc_auto.h"
      48             : 
      49             : /*---------------------------------------------------------------------*
      50             :  * tcq_core_LR_enc()
      51             :  *
      52             :  * Main Generic Audio Decoder Routine for LR-MDCT
      53             :  *---------------------------------------------------------------------*/
      54             : 
      55         102 : void tcq_core_LR_dec(
      56             :     Decoder_State *st,
      57             :     int32_t *inp_vector,
      58             :     const int16_t bit_budget,
      59             :     const int16_t BANDS,
      60             :     const int16_t *band_start,
      61             :     const int16_t *band_width,
      62             :     Word32 *Rk_fx,
      63             :     int16_t *npulses,
      64             :     int16_t *k_sort,
      65             :     const int16_t *p2a_flags,
      66             :     const int16_t p2a_bands,
      67             :     const int16_t *last_bitalloc,
      68             :     const int16_t input_frame,
      69             :     const int16_t adjustFlag,
      70             :     const int16_t *is_transient )
      71             : {
      72             :     int16_t i, j, k;
      73             :     float Rk_sort[NB_SFM];
      74         102 :     int16_t flag_wbnb = 0;
      75             :     int16_t USQ_TCQ[NB_SFM]; /* TCQ is selected by default*/
      76             :     int16_t nb_bytes, pulsesnum, nz;
      77             :     int32_t positions[L_FRAME32k];
      78             :     int16_t k_num[2];
      79             :     ARCODEC ardec, *pardec;
      80             :     TCQ_BITSTREAM bs, *pbs;
      81             : 
      82         102 :     int16_t nzbands = 0;
      83         102 :     int16_t lsbtcq_bits = TCQ_AMP;
      84         102 :     int16_t tcq_arbits = 2;
      85             : 
      86             :     /* LSB TCQ variables*/
      87             :     int16_t dpath[280];
      88         102 :     int16_t bcount = 0;
      89             :     float mbuffer[560];
      90             : 
      91         102 :     Word32 leftbits = 0;
      92         102 :     Word32 sepbits = 0;
      93         102 :     Word32 divider = 0;
      94             : 
      95             :     /*Word32 Rk_fx[NB_SFM];*/  /* Q16 */
      96             :     Word32 Rk_sort_fx[NB_SFM]; /* Q16 */
      97         102 :     Word32 bsub_fx = 0;
      98             : 
      99         102 :     Word16 nzb = 0;
     100             :     Word32 delta_fx;
     101             :     Word32 surplus_fx;
     102             :     Word32 bit_surplus_fx[2];
     103             : 
     104             :     /* initialization */
     105         102 :     set_s( dpath, 0, 280 );
     106         102 :     set_f( mbuffer, 0.f, 560 );
     107         102 :     set_f( Rk_sort, 0.f, NB_SFM );
     108         102 :     set_s( USQ_TCQ, 0, NB_SFM );
     109         102 :     set_l( positions, 0, L_FRAME32k );
     110             : 
     111         102 :     if ( input_frame <= L_FRAME16k && adjustFlag == 0 && *is_transient == 0 )
     112             :     {
     113           0 :         flag_wbnb = 1;
     114           0 :         lsbtcq_bits = 0;
     115           0 :         tcq_arbits = 0;
     116             :     }
     117             : 
     118         102 :     pardec = &ardec;
     119         102 :     pbs = &bs;
     120         102 :     pbs->curPos = 7;
     121         102 :     pbs->numbits = 0;
     122         102 :     pbs->numByte = 0;
     123             : 
     124             :     /* Bits distribution analysis*/
     125        2436 :     for ( i = 0; i < BANDS; i++ )
     126             :     {
     127        2334 :         if ( L_sub( ar_div( Rk_fx[i], band_width[i] ), 49152 ) >= 0 )
     128             :         {
     129             :             /* USQ used for high importance bands*/
     130         873 :             USQ_TCQ[i] = 1;
     131             :         }
     132             :         else
     133             :         {
     134             :             /* TCQ used for usual bands*/
     135        1461 :             USQ_TCQ[i] = 0;
     136             :         }
     137        2334 :         if ( Rk_fx[i] > 0.0f )
     138             :         {
     139        1647 :             nzbands++;
     140             :         }
     141             :     }
     142             : 
     143        2436 :     for ( j = 0; j < BANDS; j++ )
     144             :     {
     145        2334 :         if ( Rk_fx[j] > 0.0f )
     146             :         {
     147        1647 :             nzb++;
     148             :         }
     149             :     }
     150             : 
     151             : #define WMC_TOOL_SKIP
     152         102 :     bsub_fx = L_shl( L_add( tcq_arbits, lsbtcq_bits ), 16 );
     153         102 :     IF( bsub_fx > 0 )
     154             :     {
     155         102 :         bsub_fx = L_add( bsub_fx, 2048 );
     156             :     }
     157        2436 :     for ( j = BANDS - 1; j >= 0; j-- )
     158             :     {
     159        2334 :         if ( Rk_fx[j] > 0 )
     160             :         {
     161        1647 :             Rk_fx[j] = L_sub( Rk_fx[j], ar_div( bsub_fx, nzb ) );
     162        1647 :             if ( Rk_fx[j] < 0 )
     163             :             {
     164           0 :                 bsub_fx = L_sub( bsub_fx, L_add( ar_div( bsub_fx, nzb ), Rk_fx[j] ) );
     165           0 :                 Rk_fx[j] = 0;
     166             :             }
     167             :             else
     168             :             {
     169        1647 :                 bsub_fx = L_sub( bsub_fx, ar_div( bsub_fx, nzb ) );
     170             :             }
     171        1647 :             nzb = sub( nzb, 1 );
     172             :         }
     173             :     }
     174             : 
     175         102 :     srt_vec_ind_fx( Rk_fx, Rk_sort_fx, k_sort, BANDS );
     176             : #undef WMC_TOOL_SKIP
     177             : 
     178             :     /*read the bits*/
     179         102 :     nb_bytes = bit_budget >> 3;
     180         102 :     k = bit_budget - ( nb_bytes << 3 );
     181        1818 :     for ( i = 0; i < nb_bytes; i++ )
     182             :     {
     183        1716 :         pbs->buf[i] = (uint8_t) get_next_indice( st, 8 );
     184             :     }
     185             : 
     186         102 :     if ( k > 0 )
     187             :     {
     188          87 :         pbs->buf[nb_bytes] = (uint8_t) get_next_indice( st, k );
     189          87 :         pbs->buf[nb_bytes] <<= ( 8 - k );
     190          87 :         i++;
     191          87 :         nb_bytes++;
     192             :     }
     193             :     /* set two more bytes, which are used to flush the arithmetic coder, to 0
     194             :        -> this avoids reading of uninitialized memory */
     195         102 :     nb_bytes = min( nb_bytes + 2, MAX_SIZEBUF_PBITSTREAM );
     196         306 :     for ( ; i < nb_bytes; i++ )
     197             :     {
     198         204 :         pbs->buf[i] = 0;
     199             :     }
     200             : 
     201         102 :     pbs->maxBytes = nb_bytes;
     202             : 
     203         102 :     ar_decoder_start( pardec, pbs );
     204             : 
     205         102 :     delta_fx = 0;
     206         102 :     surplus_fx = 0;
     207             : 
     208         102 :     if ( input_frame <= L_FRAME16k && adjustFlag == 0 && *is_transient == 0 )
     209             :     {
     210           0 :         surplus_fx = -131072;
     211             : 
     212           0 :         bit_allocation_second_fx( Rk_fx, Rk_sort_fx, BANDS, band_width, k_sort, k_num, p2a_flags, p2a_bands, last_bitalloc, input_frame );
     213             : 
     214           0 :         nzbands = 0;
     215           0 :         for ( j = 0; j < BANDS; j++ )
     216             :         {
     217           0 :             if ( sub( j, k_num[0] ) == 0 || sub( j, k_num[1] ) == 0 )
     218             :             {
     219           0 :                 sepbits = L_add( sepbits, Rk_fx[k_sort[j]] );
     220             :             }
     221             :             else
     222             :             {
     223           0 :                 leftbits = L_add( leftbits, Rk_fx[k_sort[j]] );
     224           0 :                 if ( Rk_fx[k_sort[j]] > 0 )
     225             :                 {
     226           0 :                     nzbands = add( nzbands, 1 );
     227             :                 }
     228             :             }
     229             :         }
     230             : 
     231           0 :         for ( k = 0; k < BANDS; k++ )
     232             :         {
     233           0 :             if ( k != k_num[0] && k != k_num[1] )
     234             :             {
     235           0 :                 if ( Rk_fx[k_sort[k]] > 0 && USQ_TCQ[k_sort[k]] == 0 )
     236             :                 {
     237             :                     /* When number of bits per band is less than
     238             :                        arithmetic bits overhead, this band is not encoded.
     239             :                        It may happens when the actual number of bits per
     240             :                        band is near same to estimated number of bits, for
     241             :                        most bands (very unprobable but possible) */
     242           0 :                     if ( L_add( Rk_fx[k_sort[k]], delta_fx ) < 0 )
     243             :                     {
     244           0 :                         pulsesnum = 0;
     245           0 :                         for ( i = 0; i < band_width[k_sort[k]]; i++ )
     246             :                         {
     247           0 :                             inp_vector[band_start[k_sort[k]] + i] = 0;
     248             :                         }
     249           0 :                         if ( surplus_fx != 0 )
     250             :                         {
     251             : #define WMC_TOOL_SKIP
     252           0 :                             surplus_fx = L_add( Rk_fx[k_sort[k]], surplus_fx );
     253           0 :                             surplus_fx = L_add( delta_fx, surplus_fx );
     254             : #undef WMC_TOOL_SKIP
     255             :                         }
     256             :                     }
     257             :                     else
     258             :                     {
     259             :                         /*get number of pulses */
     260           0 :                         pulsesnum = GetScale_fx( band_width[k_sort[k]], L_add( Rk_fx[k_sort[k]], delta_fx ), &surplus_fx );
     261             : 
     262           0 :                         leftbits = L_sub( leftbits, L_add( Rk_fx[k_sort[k]], delta_fx ) );
     263             : 
     264           0 :                         decode_position_ari_fx( pardec, band_width[k_sort[k]], pulsesnum, &nz, &positions[band_start[k_sort[k]]] );
     265           0 :                         decode_mangitude_tcq_fx( pardec, band_width[k_sort[k]], pulsesnum, nz, &positions[band_start[k_sort[k]]], &inp_vector[band_start[k_sort[k]]], &surplus_fx );
     266           0 :                         decode_signs_fx( pardec, band_width[k_sort[k]], &inp_vector[band_start[k_sort[k]]] );
     267             :                     }
     268           0 :                     nzbands--;
     269             :                 }
     270           0 :                 else if ( Rk_fx[k_sort[k]] > 0 && USQ_TCQ[k_sort[k]] == 1 )
     271             :                 {
     272             :                     /* When number of bits per band is less than
     273             :                        arithmetic bits overhead, this band is not encoded.
     274             :                        It may happens when the actual number of bits per
     275             :                        band is near same to estimated number of bits, for
     276             :                        most bands (very unprobable but possible) */
     277           0 :                     if ( L_add( Rk_fx[k_sort[k]], delta_fx ) < 0 )
     278             :                     {
     279           0 :                         pulsesnum = 0;
     280           0 :                         for ( i = 0; i < band_width[k_sort[k]]; i++ )
     281             :                         {
     282           0 :                             inp_vector[band_start[k_sort[k]] + i] = 0;
     283             :                         }
     284           0 :                         if ( surplus_fx != 0 )
     285             :                         {
     286             : #define WMC_TOOL_SKIP
     287           0 :                             surplus_fx = L_add( Rk_fx[k_sort[k]], surplus_fx );
     288           0 :                             surplus_fx = L_add( delta_fx, surplus_fx );
     289             : #undef WMC_TOOL_SKIP
     290             :                         }
     291             :                     }
     292             :                     else
     293             :                     {
     294             : 
     295           0 :                         pulsesnum = GetScale_fx( band_width[k_sort[k]], L_add( Rk_fx[k_sort[k]], delta_fx ), &surplus_fx );
     296             : 
     297           0 :                         leftbits = L_sub( leftbits, L_add( Rk_fx[k_sort[k]], delta_fx ) );
     298             : 
     299           0 :                         decode_position_ari_fx( pardec, band_width[k_sort[k]], pulsesnum, &nz, &positions[band_start[k_sort[k]]] );
     300           0 :                         decode_magnitude_usq_fx( pardec, band_width[k_sort[k]], pulsesnum, nz, &positions[band_start[k_sort[k]]], &inp_vector[band_start[k_sort[k]]] );
     301           0 :                         decode_signs_fx( pardec, band_width[k_sort[k]], &inp_vector[band_start[k_sort[k]]] );
     302             :                     }
     303           0 :                     nzbands--;
     304             :                 }
     305             :                 else
     306             :                 {
     307           0 :                     pulsesnum = 0;
     308           0 :                     for ( i = 0; i < band_width[k_sort[k]]; i++ )
     309             :                     {
     310           0 :                         inp_vector[band_start[k_sort[k]] + i] = 0;
     311             :                     }
     312             :                 }
     313             : 
     314           0 :                 npulses[k_sort[k]] = pulsesnum;
     315             : 
     316           0 :                 if ( Rk_fx[k_sort[k]] > 0 && surplus_fx < 0 )
     317             :                 {
     318             : #define WMC_TOOL_SKIP
     319           0 :                     IF( nzbands <= 1 )
     320             :                     {
     321           0 :                         divider = 0;
     322             :                     }
     323             :                     ELSE
     324             :                     {
     325           0 :                         divider = 2;
     326             :                     }
     327             : 
     328           0 :                     IF( L_add( L_add( surplus_fx, sepbits ), ar_div( leftbits, divider ) ) < 0 )
     329             :                     {
     330             :                         /* Overflow possible => start to distribute negative surplus */
     331           0 :                         delta_fx = ar_div( surplus_fx + sepbits, nzbands );
     332             :                     }
     333             :                     else
     334             :                     {
     335           0 :                         delta_fx = 0;
     336             :                     }
     337           0 :                     surplus_fx = L_sub( surplus_fx, delta_fx );
     338             : #undef WMC_TOOL_SKIP
     339             :                 }
     340             :                 else
     341             :                 {
     342           0 :                     delta_fx = 0;
     343             :                 }
     344             :             }
     345             :         }
     346             : 
     347             : #define WMC_TOOL_SKIP
     348           0 :         if ( ( L_sub( surplus_fx, 524288 ) > 0 && sub( input_frame, L_FRAME8k ) == 0 ) || ( L_sub( surplus_fx, 786432 ) > 0 && sub( input_frame, L_FRAME16k ) == 0 ) )
     349             :         {
     350           0 :             bit_surplus_fx[0] = Mult_32_16( surplus_fx, 24576 ); /* Q16 */
     351           0 :             bit_surplus_fx[1] = Mult_32_16( surplus_fx, 8192 );  /* Q16 */
     352             :         }
     353             : #undef WMC_TOOL_SKIP
     354             :         else
     355             :         {
     356           0 :             bit_surplus_fx[0] = surplus_fx;
     357           0 :             bit_surplus_fx[1] = 0;
     358             :         }
     359             : 
     360           0 :         for ( k = 0; k < BANDS; k++ )
     361             :         {
     362           0 :             for ( j = 0; j < 2; j++ )
     363             :             {
     364           0 :                 if ( k == k_num[j] )
     365             :                 {
     366             : #define WMC_TOOL_SKIP
     367           0 :                     Rk_fx[k_sort[k]] = L_add( Rk_fx[k_sort[k]], bit_surplus_fx[j] );
     368             : #undef WMC_TOOL_SKIP
     369           0 :                     if ( Rk_fx[k_sort[k]] > 0 && USQ_TCQ[k_sort[k]] == 0 )
     370             :                     {
     371             :                         /* get number of pulses */
     372           0 :                         pulsesnum = GetScale_fx( band_width[k_sort[k]], Rk_fx[k_sort[k]], &surplus_fx );
     373             : 
     374           0 :                         decode_position_ari_fx( pardec, band_width[k_sort[k]], pulsesnum, &nz, &positions[band_start[k_sort[k]]] );
     375             :                         /* decode tcq magniitude and update the surplus bits. */
     376           0 :                         decode_mangitude_tcq_fx( pardec, band_width[k_sort[k]], pulsesnum, nz, &positions[band_start[k_sort[k]]], &inp_vector[band_start[k_sort[k]]], &surplus_fx );
     377           0 :                         decode_signs_fx( pardec, band_width[k_sort[k]], &inp_vector[band_start[k_sort[k]]] );
     378             :                     }
     379           0 :                     else if ( Rk_fx[k_sort[k]] > 0 && USQ_TCQ[k_sort[k]] == 1 )
     380             :                     {
     381           0 :                         pulsesnum = GetScale_fx( band_width[k_sort[k]], Rk_fx[k_sort[k]], &surplus_fx );
     382             : 
     383           0 :                         decode_position_ari_fx( pardec, band_width[k_sort[k]], pulsesnum, &nz, &positions[band_start[k_sort[k]]] );
     384             :                         /* decode usq magnitude and don't need to update surplus bits */
     385           0 :                         decode_magnitude_usq_fx( pardec, band_width[k_sort[k]], pulsesnum, nz, &positions[band_start[k_sort[k]]], &inp_vector[band_start[k_sort[k]]] );
     386           0 :                         decode_signs_fx( pardec, band_width[k_sort[k]], &inp_vector[band_start[k_sort[k]]] );
     387             :                     }
     388             :                     else
     389             :                     {
     390           0 :                         pulsesnum = 0;
     391           0 :                         for ( i = 0; i < band_width[k_sort[k]]; i++ )
     392             :                         {
     393           0 :                             inp_vector[band_start[k_sort[k]] + i] = 0;
     394             :                         }
     395             :                     }
     396           0 :                     npulses[k_sort[k]] = pulsesnum;
     397             :                 }
     398             :             }
     399             :         }
     400             :     }
     401             :     else
     402             :     {
     403        2436 :         for ( k = 0; k < BANDS; k++ )
     404             :         {
     405        2334 :             if ( Rk_fx[k_sort[k]] > 0 )
     406             :             {
     407        1647 :                 pulsesnum = GetScale_fx( band_width[k_sort[k]], Rk_fx[k_sort[k]] + delta_fx, &surplus_fx );
     408             : 
     409        1647 :                 decode_position_ari_fx( pardec, band_width[k_sort[k]], pulsesnum, &nz, &positions[band_start[k_sort[k]]] );
     410             : 
     411             :                 /*decode usq magnitude and don't need to update surplus bits*/
     412        1647 :                 decode_magnitude_usq_fx( pardec, band_width[k_sort[k]], pulsesnum, nz, &positions[band_start[k_sort[k]]], &inp_vector[band_start[k_sort[k]]] );
     413        1647 :                 decode_signs_fx( pardec, band_width[k_sort[k]], &inp_vector[band_start[k_sort[k]]] );
     414             : 
     415             : #define WMC_TOOL_SKIP
     416        1647 :                 nzbands = sub( nzbands, 1 );
     417             : #undef WMC_TOOL_SKIP
     418             :             }
     419             :             else
     420             :             {
     421         687 :                 pulsesnum = 0;
     422       36567 :                 for ( i = 0; i < band_width[k_sort[k]]; i++ )
     423             :                 {
     424       35880 :                     inp_vector[band_start[k_sort[k]] + i] = 0;
     425             :                 }
     426             :             }
     427             : 
     428        2334 :             npulses[k_sort[k]] = pulsesnum;
     429             : 
     430             :             /* surplus distribution */
     431        2334 :             if ( surplus_fx > 0 && nzbands > 0 )
     432             :             {
     433        1545 :                 delta_fx = ar_div( surplus_fx, nzbands );
     434        1545 :                 surplus_fx = L_sub( surplus_fx, delta_fx );
     435             :             }
     436             :         }
     437             :     }
     438             :     /* Load TCQ path from bitstream */
     439         102 :     LoadTCQdata( pardec, dpath, lsbtcq_bits );
     440             : 
     441         102 :     TCQLSBdec( dpath, mbuffer, 2 * lsbtcq_bits );
     442             : 
     443         102 :     ar_decoder_done( pardec );
     444             : 
     445             :     /* Restore TCQ */
     446         102 :     if ( !flag_wbnb )
     447             :     {
     448        2436 :         for ( k = 0; k < BANDS; k++ )
     449             :         {
     450        2334 :             if ( Rk_fx[k_sort[k]] > 0 )
     451             :             {
     452        1647 :                 RestoreTCQdec( &inp_vector[band_start[k_sort[k]]], band_width[k_sort[k]], &bcount, mbuffer );
     453             :             }
     454             :         }
     455             :     }
     456             :     else
     457             :     {
     458           0 :         for ( k = 0; k < BANDS; k++ )
     459             :         {
     460           0 :             if ( Rk_fx[k_sort[k]] > 0 && k != k_num[0] && k != k_num[1] )
     461             :             {
     462           0 :                 RestoreTCQdec( &inp_vector[band_start[k_sort[k]]], band_width[k_sort[k]], &bcount, mbuffer );
     463             :             }
     464             :         }
     465           0 :         for ( k = 0; k < BANDS; k++ )
     466             :         {
     467           0 :             if ( Rk_fx[k_sort[k]] > 0 && ( k == k_num[0] || k == k_num[1] ) )
     468             :             {
     469           0 :                 RestoreTCQdec( &inp_vector[band_start[k_sort[k]]], band_width[k_sort[k]], &bcount, mbuffer );
     470             :             }
     471             :         }
     472             :     }
     473             : 
     474             : 
     475         102 :     return;
     476             : }

Generated by: LCOV version 1.14