LCOV - code coverage report
Current view: top level - lib_enc - FEC_enc.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 66 68 97.1 %
Date: 2025-05-23 08:37:30 Functions: 2 2 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 <math.h>
      43             : #include "cnst.h"
      44             : #include "prot.h"
      45             : #include "rom_com.h"
      46             : #include "wmc_auto.h"
      47             : 
      48             : /*-------------------------------------------------------------------*
      49             :  * FEC_encode()
      50             :  *
      51             :  * Encoder supplementary information for FEC
      52             :  *-------------------------------------------------------------------*/
      53             : 
      54      157798 : void FEC_encode(
      55             :     BSTR_ENC_HANDLE hBstr,        /* i/o: encoder bitstream handle                        */
      56             :     const ACELP_config acelp_cfg, /* i/o: configuration of the ACELP                      */
      57             :     const float *synth,           /* i  : pointer to synthesized speech for E computation */
      58             :     const int16_t coder_type,     /* i  : type of coder                                   */
      59             :     int16_t clas,                 /* i  : signal clas for current frame                   */
      60             :     const float *fpit,            /* i  : close loop fractional pitch buffer              */
      61             :     const float *res,             /* i  : LP residual signal frame                        */
      62             :     int16_t *last_pulse_pos,      /* i/o: Position of the last pulse                      */
      63             :     const int16_t L_frame,        /* i  : Frame length                                    */
      64             :     const int32_t total_brate     /* i  : total codec bitrate                             */
      65             : )
      66             : {
      67             :     int16_t tmpS, index;
      68      157798 :     int16_t maxi, sign = 0, tmp_FER_pitch;
      69             :     float enr_q;
      70             : 
      71      157798 :     tmpS = 0;
      72      157798 :     enr_q = 1.0f;
      73             : 
      74      157798 :     if ( coder_type > UNVOICED && coder_type < AUDIO && acelp_cfg.FEC_mode > 0 )
      75             :     {
      76             :         /*-----------------------------------------------------------------*
      77             :          * encode signal class (not needed for VC since it is clearly voiced) (2 bits)
      78             :          *-----------------------------------------------------------------*/
      79             : 
      80      111939 :         if ( coder_type != VOICED )
      81             :         {
      82             :             /* encode signal clas with 2 bits */
      83      106972 :             if ( clas == UNVOICED_CLAS )
      84             :             {
      85       45693 :                 index = 0;
      86             :             }
      87       61279 :             else if ( clas == VOICED_TRANSITION || clas == UNVOICED_TRANSITION )
      88             :             {
      89        7291 :                 index = 1;
      90             :             }
      91       53988 :             else if ( clas == VOICED_CLAS )
      92             :             {
      93       46492 :                 index = 2;
      94             :             }
      95             :             else
      96             :             {
      97        7496 :                 index = 3;
      98             :             }
      99             : 
     100      106972 :             push_indice( hBstr, IND_FEC_CLAS, index, FEC_BITS_CLS );
     101             :         }
     102             : 
     103             :         /*-----------------------------------------------------------------*
     104             :          * Encode frame energy (5 bits)
     105             :          *-----------------------------------------------------------------*/
     106             : 
     107      111939 :         if ( acelp_cfg.FEC_mode > 1 ) /* GENERIC and VOICED frames */
     108             :         {
     109             :             /* frame energy (maximum energy per pitch period for voiced frames or mean energy per sample over 2nd halframe for unvoiced frames) */
     110       63532 :             fer_energy( L_frame, clas, synth, fpit[( L_frame >> 6 ) - 1], &enr_q, L_frame );
     111             : 
     112             :             /* linearly quantize the energy in the range 0 : FEC_ENR_STEP : 96 dB */
     113       63532 :             tmpS = (int16_t) ( 10.0 * log10( enr_q + 0.001f ) / FEC_ENR_STEP );
     114             : 
     115       63532 :             if ( tmpS > FEC_ENR_QLIMIT )
     116             :             {
     117           0 :                 tmpS = FEC_ENR_QLIMIT;
     118             :             }
     119             : 
     120       63532 :             if ( tmpS < 0 )
     121             :             {
     122          17 :                 tmpS = 0;
     123             :             }
     124             : 
     125       63532 :             push_indice( hBstr, IND_FEC_ENR, tmpS, FEC_BITS_ENR );
     126             :         }
     127             : 
     128             :         /*-----------------------------------------------------------------*
     129             :          * Encode last glottal pulse position (8 bits)
     130             :          *-----------------------------------------------------------------*/
     131             : 
     132      111939 :         if ( acelp_cfg.FEC_mode > 2 ) /* GENERIC frames */
     133             :         {
     134             :             /* retrieve the last glottal pulse position of the previous frame */
     135             :             /* use the current pitch information to scale or not the quantization */
     136       10699 :             tmp_FER_pitch = (int16_t) ( fpit[0] ); /* take the 1st subframe pitch, since it is easier to retrieve it on decoder side */
     137             : 
     138       10699 :             sign = 0;
     139       10699 :             maxi = *last_pulse_pos;
     140       10699 :             if ( maxi < 0 )
     141             :             {
     142        1788 :                 sign = 1;
     143        1788 :                 maxi = -maxi;
     144             :             }
     145             : 
     146       10699 :             if ( tmp_FER_pitch >= 128 )
     147             :             {
     148        3390 :                 maxi /= 2;
     149             :             }
     150             : 
     151       10699 :             if ( maxi > 127 )
     152             :             {
     153             :                 /* better not use the glottal pulse position at all instead of using a wrong pulse */
     154             :                 /* can happen only with pitch > 254 and max pit = 289 and should happen very rarely */
     155          21 :                 maxi = 0;
     156             :             }
     157             : 
     158       10699 :             if ( sign == 1 )
     159             :             {
     160        1788 :                 maxi += 128; /* use 8 bits (MSB represents the sign of the pulse) */
     161             :             }
     162             : 
     163       10699 :             push_indice( hBstr, IND_FEC_POS, maxi, FEC_BITS_POS );
     164             :         }
     165             : 
     166             :         /* find the glottal pulse position of the current frame (could be sent as extra FEC info in the next frame) */
     167      111939 :         maxi = 0;
     168      111939 :         if ( clas >= VOICED_CLAS && total_brate >= ACELP_24k40 )
     169             :         {
     170       14458 :             maxi = findpulse( L_frame, res, (int16_t) ( fpit[( L_frame >> 6 ) - 1] ), 0, &sign );
     171       14458 :             if ( sign == 1 )
     172             :             {
     173        5673 :                 maxi = -maxi;
     174             :             }
     175             :         }
     176             : 
     177      111939 :         *last_pulse_pos = maxi;
     178             :     }
     179             :     else
     180             :     {
     181       45859 :         *last_pulse_pos = 0;
     182             :     }
     183             : 
     184      157798 :     return;
     185             : }
     186             : 
     187             : 
     188             : /*-------------------------------------------------------------------*
     189             :  * FEC_lsf_estim_enc()
     190             :  *
     191             :  * Simulates LSF estimation in case of FEC in the encoder ( only one frame erasure is considered )
     192             :  * The estimated LSF vector is then used to check LSF stability and may invoke safety-net usage in the next frame
     193             :  *-------------------------------------------------------------------*/
     194             : 
     195      269763 : void FEC_lsf_estim_enc(
     196             :     Encoder_State *st, /* i  : Encoder static memory       */
     197             :     float *lsf         /* o  : estimated LSF vector        */
     198             : )
     199             : {
     200             :     int16_t i;
     201             :     float alpha, lsf_mean[M];
     202             : 
     203      269763 :     if ( st->L_frame == L_FRAME )
     204             :     {
     205      120580 :         mvr2r( UVWB_Ave, lsf_mean, M );
     206             :     }
     207             :     else
     208             :     {
     209      149183 :         mvr2r( GEWB2_Ave, lsf_mean, M );
     210             :     }
     211             : 
     212             :     /*----------------------------------------------------------------------*
     213             :      * Initialize the alpha factor
     214             :      *----------------------------------------------------------------------*/
     215             : 
     216      269763 :     if ( st->last_coder_type == UNVOICED )
     217             :     {
     218             :         /* clearly unvoiced */
     219       28702 :         alpha = ALPHA_UU;
     220             :     }
     221      241061 :     else if ( st->last_coder_type == AUDIO || st->clas == INACTIVE_CLAS )
     222             :     {
     223       11361 :         alpha = 0.995f;
     224             :     }
     225      229700 :     else if ( st->clas == UNVOICED_CLAS )
     226             :     {
     227             :         /* if stable, do not flatten the spectrum in the first erased frame  */
     228      111149 :         alpha = st->stab_fac * ( 1.0f - 2.0f * ALPHA_U ) + 2.0f * ALPHA_U;
     229             :     }
     230      118551 :     else if ( st->clas == UNVOICED_TRANSITION )
     231             :     {
     232        2759 :         alpha = ALPHA_UT;
     233             :     }
     234      115792 :     else if ( st->clas == VOICED_CLAS || st->clas == ONSET )
     235             :     {
     236             :         /* clearly voiced -  mild convergence to the CNG spectrum for the first three erased frames */
     237      101608 :         alpha = ALPHA_V;
     238             :     }
     239       14184 :     else if ( st->clas == SIN_ONSET )
     240             :     {
     241           0 :         alpha = ALPHA_S;
     242             :     }
     243             :     else
     244             :     {
     245             :         /* long erasures and onsets - rapid convergence to the CNG spectrum */
     246       14184 :         alpha = ALPHA_VT;
     247             :     }
     248             : 
     249             :     /*----------------------------------------------------------------------*
     250             :      * Extrapolate LSF vector
     251             :      *----------------------------------------------------------------------*/
     252             : 
     253             :     /* extrapolate the old LSF vector */
     254     4585971 :     for ( i = 0; i < M; i++ )
     255             :     {
     256             :         /* calculate mean LSF vector */
     257     4316208 :         lsf_mean[i] = BETA_FEC * lsf_mean[i] + ( 1 - BETA_FEC ) * st->lsf_adaptive_mean[i];
     258             : 
     259             :         /* move old LSF vector towards the mean LSF vector */
     260     4316208 :         lsf[i] = alpha * st->lsf_old[i] + ( 1.0f - alpha ) * lsf_mean[i];
     261             :     }
     262             : 
     263             :     /* check LSF stability through LSF ordering */
     264      269763 :     if ( st->L_frame == L_FRAME )
     265             :     {
     266      120580 :         reorder_lsf( lsf, MODE1_LSF_GAP, M, INT_FS_12k8 );
     267             :     }
     268             :     else /* L_frame == L_FRAME16k */
     269             :     {
     270      149183 :         reorder_lsf( lsf, MODE1_LSF_GAP, M, INT_FS_16k );
     271             :     }
     272             : 
     273      269763 :     return;
     274             : }

Generated by: LCOV version 1.14