LCOV - code coverage report
Current view: top level - lib_com - env_stab_trans.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 60 66 90.9 %
Date: 2025-05-03 01:55:50 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             : #include <math.h>
      40             : #include "cnst.h"
      41             : #include "prot_fx.h"
      42             : #include "rom_com.h"
      43             : #include "wmc_auto.h"
      44             : /*--------------------------------------------------------------------------*
      45             :  * env_stab_transient_detect()
      46             :  *
      47             :  * Transient detector for envelope stability measure
      48             :  *--------------------------------------------------------------------------*/
      49             : 
      50        1482 : void env_stab_transient_detect_fx(
      51             :     const Word16 is_transient, /* i:   Transient flag                                                                                           */
      52             :     const Word16 length,       /* i  : Length of spectrum (32 or 48 kHz)                                                        */
      53             :     const Word16 norm[],       /* i  : quantization indices for norms                                                           */
      54             :     Word16 *no_att_hangover,   /* i/o: Frame counter for attenuation hangover                    (Q0)           */
      55             :     Word32 *L_energy_lt,       /* i/o: Long-term energy measure for transient detection  (Q13)     */
      56             :     const Word16 HQ_mode,      /* i  : HQ coding mode                                                                                           */
      57             :     const Word16 bin_th,       /* i  : HVQ cross-over frequency bin                                                             */
      58             :     const Word32 *L_coeff,     /* i  : Coded spectral coefficients                                      */
      59             :     const Word16 Qcoeff        /* i  : Q of coded spectral coefficients                                 */
      60             : )
      61             : {
      62             :     Word16 i, blk, norm_ind, sqrt_exp, bin_th_1, temp, sh;
      63             :     Word32 L_e_frame, L_temp, L_d_max;
      64             :     Word32 L_energy_lt_local;
      65             :     Word32 L_E_sub[4];
      66             :     Word32 L_delta_e_sub;
      67             : 
      68        1482 :     L_energy_lt_local = *L_energy_lt;
      69        1482 :     move32();
      70             : 
      71        1482 :     L_d_max = L_deposit_l( 0 );
      72        1482 :     L_e_frame = L_deposit_l( 0 );
      73        1482 :     temp = 32;
      74        1482 :     move16();
      75             : 
      76        1482 :     IF( EQ_16( HQ_mode, HQ_HVQ ) )
      77             :     {
      78       40626 :         FOR( i = 0; i < bin_th; i++ ) /* find adaptive shift */
      79             :         {
      80       40448 :             temp = s_min( temp, norm_l( L_coeff[i] ) );
      81             :         }
      82         178 :         sh = sub( temp, 2 );          /* scale such that 2 msbs are not used, the resulting adaptive Qcoeff will be: Qcoeff+sh-16 */
      83       40626 :         FOR( i = 0; i < bin_th; i++ ) /* Maximum number of loop runs 320 */
      84             :         {
      85       40448 :             temp = extract_h( L_shl( L_coeff[i], sh ) );
      86       40448 :             L_e_frame = L_mac( L_e_frame, temp, temp ); /* Q(2*(Qcoeff+sh-16)+1)=Q(2*(Qcoeff+sh)-31 */
      87             :         }
      88             : 
      89         178 :         bin_th_1 = INV_HVQ_THRES_BIN_24k;
      90         178 :         move16();
      91         178 :         if ( EQ_16( bin_th, HVQ_THRES_BIN_32k ) )
      92             :         {
      93           6 :             bin_th_1 = INV_HVQ_THRES_BIN_32k;
      94           6 :             move16();
      95             :         }
      96         178 :         L_temp = Mult_32_16( L_e_frame, bin_th_1 ); /* Q(2*(Qcoeff-16+sh)+1+21-15) -> Q(2*(Qcoeff+sh)-25)  */
      97         178 :         L_e_frame = Sqrt_l( L_temp, &sqrt_exp );
      98         178 :         L_e_frame = L_shr( L_e_frame, add( sub( add( sh, Qcoeff ), 10 ), shr( sqrt_exp, 1 ) ) ); /* Adjust by (Qcoeff+sh-10) to fixed Q13: Qcoeff+sh+(-25+31)/2 - (Qcoeff+sh-10) -> Q13 */
      99             : 
     100         178 :         IF( GT_32( L_e_frame, ENERGY_TH_FX ) )
     101             :         {
     102         178 :             L_energy_lt_local = Mult_32_16( *L_energy_lt, ENERGY_LT_BETA_FX );
     103         178 :             L_temp = Mult_32_16( L_e_frame, ENERGY_LT_BETA_1_FX );
     104         178 :             *L_energy_lt = L_add( L_energy_lt_local, L_temp );
     105         178 :             move32();
     106             :         }
     107             : 
     108         178 :         IF( *no_att_hangover > 0 )
     109             :         {
     110           0 :             ( *no_att_hangover ) = sub( ( *no_att_hangover ), 1 );
     111           0 :             move16();
     112             :         }
     113             :     }
     114             :     ELSE
     115             :     {
     116        1304 :         L_e_frame = L_deposit_l( 0 );
     117             : 
     118        1304 :         test();
     119        1304 :         IF( is_transient && EQ_16( length, L_FRAME32k ) )
     120             :         {
     121             :             /* Measure subframe energies */
     122         665 :             FOR( blk = 0; blk < NUM_SUBFRAMES; blk++ )
     123             :             {
     124         532 :                 L_E_sub[blk] = L_deposit_l( 0 ); /* Q9 */
     125         532 :                 move32();
     126             : 
     127        5320 :                 FOR( i = 0; i < BANDS_PER_SUBFRAMES; i++ ) /* 9 times -> < 2^4 */
     128             :                 {
     129        4788 :                     norm_ind = subf_norm_groups[blk][i];
     130        4788 :                     move16();
     131        4788 :                     L_E_sub[blk] = L_add( L_E_sub[blk], L_shr( dicn_fx[norm[norm_ind]], 4 ) );
     132        4788 :                     move32();
     133             :                     ; /* Q10  */
     134             :                 }
     135             : 
     136         532 :                 L_E_sub[blk] = Mult_32_16( L_E_sub[blk], INV_BANDS_PER_SUBFRAMES );
     137         532 :                 move32(); /* Q(10+17-15) -> Q12 */
     138             : 
     139         532 :                 L_e_frame = L_add( L_e_frame, L_E_sub[blk] ); /* Q12 */
     140             :             }
     141             : 
     142             :             /* Test for transient */
     143             :             /*            if (e_frame > ENERGY_TH * NUM_SUBFRAMES) */
     144         133 :             IF( GT_32( L_e_frame, ENERGY_TH_NUM_SUBFRAMES ) )
     145             :             {
     146         176 :                 FOR( blk = 0; blk < NUM_SUBFRAMES - 1; blk++ )
     147             :                 {
     148         132 :                     L_delta_e_sub = L_sub( L_E_sub[blk + 1], L_E_sub[blk] ); /* Q12 */
     149         132 :                     if ( GT_32( L_delta_e_sub, L_d_max ) )
     150             :                     {
     151          48 :                         L_d_max = L_delta_e_sub; /* L_d_max is NOT normalized with *energy_lt */
     152          48 :                         move32();
     153             :                     }
     154             :                 }
     155             :             }
     156             :         }
     157             :         ELSE
     158             :         {
     159             :             /* Update long-term energy measure */
     160        1171 :             L_e_frame = L_deposit_l( 0 );         /* Q9 */
     161       32788 :             FOR( i = 0; i < SFM_N_ENV_STAB; i++ ) /* 27 times -> < 2^5 */
     162             :             {
     163       31617 :                 L_e_frame = L_add( L_e_frame, L_shr( dicn_fx[norm[i]], 5 ) );
     164             :                 /* Q9  */
     165             :             }
     166             : 
     167        1171 :             L_e_frame = Mult_32_16( L_e_frame, INV_SFM_N_ENV_STAB ); /* Q(9+19-15) -> Q13 */
     168             : 
     169        1171 :             IF( GT_32( L_e_frame, ENERGY_TH_FX ) )
     170             :             {
     171         649 :                 L_energy_lt_local = Mult_32_16( *L_energy_lt, ENERGY_LT_BETA_FX );
     172         649 :                 L_temp = Mult_32_16( L_e_frame, ENERGY_LT_BETA_1_FX );
     173         649 :                 *L_energy_lt = L_add( L_energy_lt_local, L_temp );
     174         649 :                 move32();
     175             :             }
     176             :         }
     177             : 
     178             :         /* Add hang-over for conservative application of stability dependent attenuation */
     179             :         /*                              -> Note: L_d_max not normalized with *energy_lt */
     180             :         /*                                 Hence, we compare L_d_max/DELTA_TH with *energy_lt */
     181        1304 :         IF( GT_32( Mult_32_16( L_d_max, INV_DELTA_TH ), L_energy_lt_local ) ) /* Q13 = Q(12 + 16 -15) */
     182             :         {
     183           0 :             *no_att_hangover = ATT_LIM_HANGOVER;
     184           0 :             move16();
     185             :         }
     186        1304 :         ELSE IF( *no_att_hangover > 0 )
     187             :         {
     188           0 :             *no_att_hangover = sub( *no_att_hangover, 1 );
     189           0 :             move16();
     190             :         }
     191             :     }
     192             : 
     193        1482 :     return;
     194             : }

Generated by: LCOV version 1.14