LCOV - code coverage report
Current view: top level - lib_com - env_stab.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 60 60 100.0 %
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             : #include "stl.h"
      48             : #ifdef DEBUGGING
      49             : #include "assert.h"
      50             : #endif
      51             : 
      52             : /*--------------------------------------------------------------------------*
      53             :  * Local constants
      54             :  *--------------------------------------------------------------------------*/
      55             : 
      56             : #define ENV_STAB_SMO_HO 10 /* number of hangover frames when switching from music to speech state */
      57             : 
      58             : 
      59             : /*--------------------------------------------------------------------------*/
      60             : /*  Function  env_stability()                                               */
      61             : /*  ~~~~~~~~~~~~~~~~~~~~~~~~~                                               */
      62             : /*                                                                          */
      63             : /*  Envelope stability measure                                              */
      64             : /*--------------------------------------------------------------------------*/
      65             : 
      66       20838 : float env_stability(
      67             :     const int16_t *ynrm,              /* i  : Norm vector for current frame          */
      68             :     const int16_t nb_sfm,             /* i  : Number of sub-bands                    */
      69             :     int16_t *mem_norm,                /* i/o: Norm vector memory from past frame     */
      70             :     int16_t *mem_env_delta,           /* i/o: Envelope stability memory for smoothing*/
      71             :     const int16_t core_switching_flag /* i  : Core switching flag        */
      72             : )
      73             : {
      74             :     Word16 env_delta;
      75             :     Word16 env_stab;
      76             :     Word16 tmp, tmp_stab;
      77             :     Word16 i;
      78             : 
      79             :     Word16 exp, exp2;
      80             :     Word32 L_tmp, L_env_delta;
      81             :     Word16 inv_nb_sfm;
      82             :     float env_stab_f;
      83             : #ifdef BASOP_NOGLOB
      84             :     Flag Overflow;
      85             : #endif /* BASOP_NOGLOB */
      86             : 
      87       20838 :     if ( core_switching_flag )
      88             :     {
      89       16065 :         for ( i = 0; i < nb_sfm; i++ )
      90             :         {
      91       15477 :             mem_norm[i] = ynrm[i];
      92             :         }
      93             : #ifdef BASOP_NOGLOB
      94         588 :         Overflow = 0;
      95         588 :         env_delta = shl_o( *mem_env_delta, 1, &Overflow );
      96             : #else
      97             :         env_delta = shl( *mem_env_delta, 1 );
      98             : #endif
      99             :     }
     100             :     else
     101             :     {
     102             :         /* Calculate envelope stability parameter */
     103       20250 :         L_env_delta = L_deposit_l( 0 );
     104      550788 :         for ( i = 0; i < nb_sfm; i++ )
     105             :         {
     106      530538 :             tmp = sub( mem_norm[i], ynrm[i] );
     107      530538 :             L_env_delta = L_mac0( L_env_delta, tmp, tmp );
     108      530538 :             mem_norm[i] = ynrm[i];
     109             :         }
     110             : 
     111             : #ifdef DEBUGGING
     112             :         assert( nb_sfm == 27 || nb_sfm == 26 );
     113             : #endif
     114       20250 :         inv_nb_sfm = 19418; /* Q19 */
     115       20250 :         if ( nb_sfm == 26 )
     116             :         {
     117       16212 :             inv_nb_sfm = 20165; /* Q19 */
     118             :         }
     119       20250 :         exp = norm_l( L_env_delta );
     120       20250 :         L_env_delta = Mult_32_16( L_shl( L_env_delta, exp ), inv_nb_sfm ); /* 0+exp+19-15 */
     121             : 
     122       20250 :         L_tmp = Sqrt_l( L_env_delta, &exp2 ); /* exp+4+31+exp2 */
     123             : 
     124       20250 :         exp = add( 35, add( exp, exp2 ) );
     125       20250 :         if ( sub( s_and( exp, 1 ), 1 ) == 0 )
     126             :         {
     127        9906 :             L_tmp = Mult_32_16( L_tmp, 23170 ); /* 1/sqrt(2) in Q15 */
     128             :         }
     129       20250 :         exp = shr( exp, 1 );
     130             : 
     131             : #ifndef BASOP_NOGLOB
     132             :         env_delta = round_fx( L_shl( L_tmp, sub( 26, exp ) ) ); /* Q10 */
     133             :         L_tmp = L_mult0( 26214, env_delta );                    /* 26214 is 0.1 in Q18. Q28 */
     134             :         L_tmp = L_mac( L_tmp, 29491, *mem_env_delta );          /* 29491 is 0.9 in Q15. Q28 */
     135             :         *mem_env_delta = round_fx( L_tmp );                     /* Q12 */
     136             : #else                                                           /* BASOP_NOGLOB */
     137       20250 :         env_delta = round_fx_o( L_shl_o( L_tmp, sub( 26, exp ), &Overflow ), &Overflow ); /* Q10 */
     138       20250 :         L_tmp = L_mult0( 26214, env_delta );                                              /* 26214 is 0.1 in Q18. Q28 */
     139       20250 :         L_tmp = L_mac_o( L_tmp, 29491, *mem_env_delta, &Overflow );                       /* 29491 is 0.9 in Q15. Q28 */
     140       20250 :         *mem_env_delta = round_fx_o( L_tmp, &Overflow );                                  /* Q12 */
     141             : #endif                                                          /* BASOP_NOGLOB */
     142       20250 :         Overflow = 0;
     143             : #ifndef BASOP_NOGLOB
     144             :         env_delta = round_fx( L_shl( L_tmp, 1 ) ); /* Q13 */
     145             : #else                                              /* BASOP_NOGLOB */
     146       20250 :         env_delta = round_fx_o( L_shl_o( L_tmp, 1, &Overflow ), &Overflow );              /* Q13 */
     147             : #endif                                             /* BASOP_NOGLOB */
     148             :     }
     149       20838 :     if ( Overflow != 0 ) /* Saturated due to the above up-shifting operation. */
     150             :     {
     151         102 :         env_stab = stab_trans_fx[L_STAB_TBL - 1];             /* The highest quantized index. */
     152         102 :         env_stab_f = ( (float) env_stab ) / PCM16_TO_FLT_FAC; /* Convert env_stab(Q15) to float */
     153         102 :         return env_stab_f;
     154             :     }
     155             : 
     156             :     /* If tmp_stab > (D_STAB_TBL*L_STAB_TBL + M_STAB_TBL), i.e., 0.103138*10+2.51757=3.603137,
     157             :      * the quantized index is equal to 9. Hence, we only need to worry about any tmpStab < 4.
     158             :      * In this case, Q13 is good enough.
     159             :      */
     160       20736 :     tmp_stab = sub( env_delta, M_STAB_TBL_FX ); /* in Q13 */
     161       20736 :     tmp_stab = abs_s( tmp_stab );
     162             : 
     163             :     /* Table lookup for smooth transitions
     164             :      * First, find the quantization level, i, of tmpStab. */
     165             : #if L_STAB_TBL > 10
     166             : #error env_stability_fx: Use more efficient usquant()
     167             : #endif
     168       20736 :     tmp_stab = sub( tmp_stab, HALF_D_STAB_TBL_FX ); /* in Q13 */
     169      150189 :     for ( i = 0; i < L_STAB_TBL - 1; i++ )
     170             :     {
     171      141873 :         if ( tmp_stab < 0 )
     172             :         {
     173       12420 :             break;
     174             :         }
     175             :         else
     176             :         {
     177      129453 :             tmp_stab = sub( tmp_stab, D_STAB_TBL_FX ); /* in Q13 */
     178             :         }
     179             :     }
     180             : 
     181       20736 :     env_stab = stab_trans_fx[i];
     182       20736 :     if ( sub( env_delta, M_STAB_TBL_FX ) < 0 )
     183             :     {
     184       18366 :         env_stab = sub( 0x7FFF, stab_trans_fx[i] );
     185             :     }
     186             : 
     187       20736 :     env_stab_f = ( (float) env_stab ) / PCM16_TO_FLT_FAC; /* Convert env_stab(Q15) to float */
     188             : 
     189       20736 :     return env_stab_f;
     190             : }
     191             : 
     192             : /*--------------------------------------------------------------------------*
     193             :  * env_stab_smo_fx()
     194             :  *
     195             :  *
     196             :  *--------------------------------------------------------------------------*/
     197             : 
     198             : /*! r: New speech/music state */
     199       24705 : float env_stab_smo(
     200             :     float env_stab,          /* i  : env_stab value                         */
     201             :     float *env_stab_state_p, /* i/o: env_stab state probabilities           */
     202             :     int16_t *ho_cnt          /* i/o: hangover counter for speech state      */
     203             : )
     204             : {
     205             :     int16_t state, prev_state;
     206             :     float maxval, pp[NUM_ENV_STAB_PLC_STATES], pa[NUM_ENV_STAB_PLC_STATES];
     207             :     /* get previous state */
     208       24705 :     prev_state = maximum( env_stab_state_p, NUM_ENV_STAB_PLC_STATES, &maxval );
     209             : 
     210             :     /* assume two states: speech(0), music(1) */
     211             :     /* set a posteriori likelihoods for the two states according to env_stab */
     212       24705 :     env_stab = ( env_stab - stab_trans[L_STAB_TBL - 1] ) / ( 1 - 2 * stab_trans[L_STAB_TBL - 1] );
     213       24705 :     pp[0] = 1.0f - env_stab;
     214       24705 :     pp[1] = env_stab;
     215             : 
     216             :     /* calculate a priori likelihoods */
     217       24705 :     pa[0] = dotp( env_stab_tp[0], env_stab_state_p, NUM_ENV_STAB_PLC_STATES );
     218       24705 :     pa[1] = dotp( env_stab_tp[1], env_stab_state_p, NUM_ENV_STAB_PLC_STATES );
     219             : 
     220             :     /* multiply elementwise with a posteriori likelihoods */
     221       24705 :     v_mult( pa, pp, env_stab_state_p, NUM_ENV_STAB_PLC_STATES );
     222             : 
     223             :     /* renormalize state probabilities */
     224       24705 :     v_multc( env_stab_state_p, 1.0f / sum_f( env_stab_state_p, NUM_ENV_STAB_PLC_STATES ), env_stab_state_p, NUM_ENV_STAB_PLC_STATES );
     225             : 
     226             :     /* find maximum index as return value */
     227       24705 :     state = maximum( env_stab_state_p, NUM_ENV_STAB_PLC_STATES, &maxval );
     228             : 
     229             :     /* apply some hangover for speech */
     230       24705 :     if ( state == 0 && prev_state == 1 )
     231             :     {
     232         435 :         *ho_cnt = ENV_STAB_SMO_HO;
     233             :     }
     234       24705 :     if ( *ho_cnt > 0 )
     235             :     {
     236        3804 :         pp[0] = 1;
     237        3804 :         pp[1] = 0;
     238        3804 :         ( *ho_cnt )--;
     239             :     }
     240             : 
     241       24705 :     return state;
     242             : }

Generated by: LCOV version 1.14