LCOV - code coverage report
Current view: top level - lib_com - enhancer.c (source / functions) Hit Total Coverage
Test: Coverage on main @ 6baab0c613aa6c7100498ed7b93676aa8198a493 Lines: 71 73 97.3 %
Date: 2025-05-29 08:28:55 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             :  * Local function prototypes
      50             :  *---------------------------------------------------------------------*/
      51             : 
      52             : static void agc2( const float *sig_in, float *sig_out, const int16_t l_trm );
      53             : 
      54             : /*---------------------------------------------------------------------*
      55             :  * enhancer()
      56             :  *
      57             :  * Enhancement of the excitation signal before synthesis
      58             :  *---------------------------------------------------------------------*/
      59             : 
      60    10879511 : void enhancer(
      61             :     const int16_t codec_mode,   /* i  : flag indicating Codec Mode              */
      62             :     const int32_t core_brate,   /* i  : core bitrate                            */
      63             :     const int16_t cbk_index,    /* i  :                                         */
      64             :     const int16_t Opt_AMR_WB,   /* i  : flag indicating AMR-WB IO mode          */
      65             :     const int16_t coder_type,   /* i  : coding type                             */
      66             :     const int16_t L_frame,      /* i  : frame size                              */
      67             :     const float voice_fac,      /* i  : subframe voicing estimation             */
      68             :     const float stab_fac,       /* i  : LP filter stablility measure            */
      69             :     const float norm_gain_code, /* i  : normalized innovative cb. gain          */
      70             :     const float gain_inov,      /* i  : gain of the unscaled innovation         */
      71             :     float *gc_threshold,        /* i/o: code threshold                          */
      72             :     float *code,                /* i/o: innovation                              */
      73             :     float *pt_exc2,             /* i/o: adapt. excitation/total exc.            */
      74             :     const float gain_pit,       /* i  : Quantized pitch gain                    */
      75             :     float *dispMem              /* i/o: Phase dispersion algorithm memory       */
      76             : )
      77             : {
      78             :     float tmp, gain_code, new_norm_gain_code, fac;
      79             :     int16_t i;
      80             :     float pit_sharp;
      81             :     float excp[L_SUBFR];
      82             : 
      83    10879511 :     pit_sharp = gain_pit;
      84             : 
      85             :     /*-----------------------------------------------------------------*
      86             :      * Phase dispersion
      87             :      *
      88             :      * Enhance noise at low bitrates
      89             :      *-----------------------------------------------------------------*/
      90             : 
      91    10879511 :     i = 2; /* no dispersion   */
      92    10879511 :     if ( Opt_AMR_WB )
      93             :     {
      94       23740 :         if ( core_brate <= ACELP_6k60 )
      95             :         {
      96        2248 :             i = 0; /* high dispersion  */
      97             :         }
      98       21492 :         else if ( core_brate <= ACELP_8k85 )
      99             :         {
     100        1816 :             i = 1; /* low dispersion  */
     101             :         }
     102             :     }
     103    10855771 :     else if ( codec_mode == MODE1 && coder_type != UNVOICED )
     104             :     {
     105    10556727 :         if ( core_brate <= ACELP_7k20 )
     106             :         {
     107       62376 :             i = 0; /* high dispersion  */
     108             :         }
     109    10494351 :         else if ( ( coder_type == GENERIC || coder_type == TRANSITION || coder_type == AUDIO || coder_type == INACTIVE ) && core_brate <= ACELP_9k60 )
     110             :         {
     111     1203848 :             i = 1; /* low dispersion  */
     112             :         }
     113             :     }
     114      299044 :     else if ( codec_mode == MODE2 )
     115             :     {
     116      164416 :         if ( ( ( coder_type != VOICED ) && cbk_index <= 2 ) || ( ( coder_type == UNVOICED ) && L_frame == L_FRAME && cbk_index <= 10 ) || ( ( coder_type == UNVOICED ) && L_frame == L_FRAME16k && cbk_index <= 14 ) )
     117             :         {
     118        4712 :             i = 0; /* high dispersion  */
     119             :         }
     120      159704 :         else if ( ( coder_type != VOICED ) && ( cbk_index <= 7 ) )
     121             :         {
     122       20264 :             i = 1; /* low dispersion  */
     123             :         }
     124             :     }
     125      134628 :     else if ( codec_mode == MODE1 && coder_type == UNVOICED && cbk_index /*uc_two_stage_flag*/ )
     126             :     {
     127      133644 :         i = 0; /* high dispersion  */
     128             :     }
     129             : 
     130    10879511 :     phase_dispersion( norm_gain_code, gain_pit, code, i, dispMem );
     131             : 
     132             :     /*------------------------------------------------------------
     133             :      * Noise enhancer
     134             :      *
     135             :      * Enhance excitation on noise (modify code gain). If signal is noisy and LPC filter is stable,
     136             :      * move code gain 1.5 dB towards its threshold. This decreases by 3 dB noise energy variation.
     137             :      *-----------------------------------------------------------*/
     138             : 
     139    10879511 :     if ( norm_gain_code < *gc_threshold )
     140             :     {
     141     5459832 :         new_norm_gain_code = (float) ( norm_gain_code * 1.19f );
     142     5459832 :         if ( new_norm_gain_code > *gc_threshold )
     143             :         {
     144     2119221 :             new_norm_gain_code = *gc_threshold;
     145             :         }
     146             :     }
     147             :     else
     148             :     {
     149     5419679 :         new_norm_gain_code = (float) ( norm_gain_code / 1.19f );
     150     5419679 :         if ( new_norm_gain_code < *gc_threshold )
     151             :         {
     152     2056138 :             new_norm_gain_code = *gc_threshold;
     153             :         }
     154             :     }
     155    10879511 :     *gc_threshold = new_norm_gain_code;
     156             : 
     157             :     /* calculate new code gain */
     158    10879511 :     fac = stab_fac * ( 0.5f * ( 1.0f - voice_fac ) ); /* 1 = unvoiced, 0 = voiced */
     159    10879511 :     gain_code = fac * new_norm_gain_code + ( 1.0f - fac ) * norm_gain_code;
     160    10879511 :     gain_code *= gain_inov;
     161             : 
     162   707168215 :     for ( i = 0; i < L_SUBFR; i++ )
     163             :     {
     164   696288704 :         code[i] *= gain_code;
     165             :     }
     166             : 
     167             :     /*------------------------------------------------------------*
     168             :      * Pitch enhancer
     169             :      *
     170             :      * Enhance excitation on voiced (HP filtering of code). On voiced signal, filter code by a smooth HP
     171             :      * filter to decrease the energy of code at low frequency
     172             :      *------------------------------------------------------------*/
     173             : 
     174    10879511 :     if ( !Opt_AMR_WB && codec_mode == MODE1 && coder_type == UNVOICED )
     175             :     {
     176      134628 :         mvr2r( code, pt_exc2, L_SUBFR );
     177             :     }
     178             :     else
     179             :     {
     180    10744883 :         if ( Opt_AMR_WB && ( core_brate == ACELP_8k85 || core_brate == ACELP_6k60 ) )
     181             :         {
     182        4064 :             pit_sharp = gain_pit;
     183        4064 :             if ( pit_sharp > 1.0 )
     184             :             {
     185        1138 :                 pit_sharp = 1.0;
     186             :             }
     187             : 
     188        4064 :             if ( pit_sharp > 0.5 )
     189             :             {
     190      218530 :                 for ( i = 0; i < L_SUBFR; i++ )
     191             :                 {
     192      215168 :                     excp[i] = pt_exc2[i] * pit_sharp * 0.25f;
     193             :                 }
     194             :             }
     195             :         }
     196             : 
     197             :         /*-----------------------------------------------------------------
     198             :          * Do a simple noncasual "sharpening": effectively an FIR
     199             :          * filter with coefs [-tmp 1.0 -tmp] where tmp = 0 ... 0.25
     200             :          * This is applied to code and added to exc2
     201             :          *-----------------------------------------------------------------*/
     202    10744883 :         if ( L_frame == L_FRAME16k )
     203             :         {
     204     6024740 :             tmp = (float) ( 0.150f * ( 1.0f + voice_fac ) ); /* 0.30=voiced, 0=unvoiced */
     205             :         }
     206             :         else
     207             :         {
     208     4720143 :             tmp = (float) ( 0.125f * ( 1.0f + voice_fac ) ); /* 0.25=voiced, 0=unvoiced */
     209             :         }
     210    10744883 :         pt_exc2[0] += code[0] - ( tmp * code[1] );
     211   676927629 :         for ( i = 1; i < L_SUBFR - 1; i++ )
     212             :         {
     213   666182746 :             pt_exc2[i] += code[i] - ( tmp * code[i - 1] ) - ( tmp * code[i + 1] );
     214             :         }
     215    10744883 :         pt_exc2[L_SUBFR - 1] += code[L_SUBFR - 1] - ( tmp * code[L_SUBFR - 2] );
     216             : 
     217    10744883 :         if ( Opt_AMR_WB && ( core_brate == ACELP_8k85 || core_brate == ACELP_6k60 ) )
     218             :         {
     219        4064 :             if ( pit_sharp > 0.5f )
     220             :             {
     221      218530 :                 for ( i = 0; i < L_SUBFR; i++ )
     222             :                 {
     223      215168 :                     excp[i] += pt_exc2[i];
     224             :                 }
     225             : 
     226        3362 :                 agc2( pt_exc2, excp, L_SUBFR );
     227        3362 :                 mvr2r( excp, pt_exc2, L_SUBFR );
     228             :             }
     229             :         }
     230             :     }
     231             : 
     232    10879511 :     return;
     233             : }
     234             : 
     235             : /*-----------------------------------------------------------------------*
     236             :  * agc2()
     237             :  *
     238             :  * Adaptive gain control
     239             :  *-----------------------------------------------------------------------*/
     240             : 
     241        3362 : static void agc2(
     242             :     const float *sig_in, /* i  : postfilter input signal  */
     243             :     float *sig_out,      /* i/o: postfilter output signal */
     244             :     const int16_t l_trm  /* i  : subframe size            */
     245             : )
     246             : {
     247             :     int16_t i;
     248             :     float gain_in, gain_out;
     249             :     float g0, gain;
     250             : 
     251             : 
     252        3362 :     gain_out = 0.0f;
     253      218530 :     for ( i = 0; i < l_trm; i++ )
     254             :     {
     255      215168 :         gain_out += sig_out[i] * sig_out[i];
     256             :     }
     257             : 
     258        3362 :     if ( gain_out == 0.0f )
     259             :     {
     260           0 :         return;
     261             :     }
     262             : 
     263        3362 :     gain_in = 0.0f;
     264      218530 :     for ( i = 0; i < l_trm; i++ )
     265             :     {
     266      215168 :         gain_in += sig_in[i] * sig_in[i];
     267             :     }
     268        3362 :     if ( gain_in == 0.0f )
     269             :     {
     270           0 :         g0 = 0.0f;
     271             :     }
     272             :     else
     273             :     {
     274        3362 :         g0 = (float) sqrt( gain_in / gain_out );
     275             :     }
     276             : 
     277        3362 :     gain = g0;
     278      218530 :     for ( i = 0; i < l_trm; i++ )
     279             :     {
     280      215168 :         sig_out[i] *= gain;
     281             :     }
     282             : 
     283        3362 :     return;
     284             : }

Generated by: LCOV version 1.14