LCOV - code coverage report
Current view: top level - lib_com - frame_ener_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 112 112 100.0 %
Date: 2025-05-03 01:55:50 Functions: 3 3 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 "wmc_auto.h"
      43             : /*----------------------------------------------------------------------------------*
      44             :  * fer_energy()
      45             :  *
      46             :  * Estimation of pitch-synchronous (voiced sounds) or half-frame energy
      47             :  *----------------------------------------------------------------------------------*/
      48             : 
      49       69696 : void fer_energy_fx(
      50             :     const Word16 L_frame, /* i  : frame length                                      */
      51             :     const Word16 clas,    /* i  : frame classification                              */
      52             :     const Word32 *synth,  /* i  : synthesized speech at Fs = 12k8 Hz     Q(q_synth) */
      53             :     const Word16 q_synth, /* i  : synthesized speech at Fs = 12k8 Hz                */
      54             :     const Word16 pitch,   /* i  : pitch period                           Q0         */
      55             :     Word32 *enr,          /* o  : pitch-synchronous or half_frame energy Q0         */
      56             :     const Word16 offset   /* i  : speech pointer offset (0 or L_frame)              */
      57             : )
      58             : {
      59             :     Word16 len, shift, exp;
      60             :     const Word32 *pt_synth;
      61             :     Word16 enr_tmp, i;
      62             :     Word64 W_tmp;
      63             : 
      64       69696 :     test();
      65       69696 :     test();
      66       69696 :     IF( EQ_16( clas, VOICED_CLAS ) || EQ_16( clas, ONSET ) || EQ_16( clas, SIN_ONSET ) ) /* Voiced or Onset current frame */
      67             :     {
      68       33858 :         len = ( pitch ); /* pitch value */
      69       33858 :         move16();
      70             : 
      71       33858 :         pt_synth = synth;
      72       33858 :         IF( offset != 0 )
      73             :         {
      74       33858 :             pt_synth = synth + sub( L_frame, len );
      75             :         }
      76             : 
      77       33858 :         emaximum_32fx( q_synth, pt_synth, len, enr ); /* pitch synchronous E */
      78             :     }
      79             :     ELSE
      80             :     {
      81       35838 :         pt_synth = synth;
      82       35838 :         IF( offset != 0 )
      83             :         {
      84       35838 :             pt_synth = synth + shr( L_frame, 1 );
      85             :         }
      86             : 
      87       35838 :         W_tmp = 0;
      88       35838 :         move64();
      89     7565758 :         FOR( i = 0; i < L_frame / 2; i++ )
      90             :         {
      91     7529920 :             W_tmp = W_add( W_tmp, W_mult0_32_32( pt_synth[i], pt_synth[i] ) ); // Q = q_synth * 2
      92             :         }
      93       35838 :         shift = W_norm( W_tmp );
      94       35838 :         W_tmp = W_shl( W_tmp, shift ); // Q = q_synth * 2 + shift
      95       35838 :         *enr = W_extract_h( W_tmp );   // Q = q_synth * 2 + shift - 32
      96       35838 :         move32();
      97             : 
      98       35838 :         enr_tmp = BASOP_Util_Divide3216_Scale( *enr, shr( L_frame, 1 ) /*Q0*/, &exp );
      99       35838 :         *enr = L_shr( L_deposit_l( enr_tmp ), sub( sub( sub( shift, 32 ), exp ), 1 ) ); /*Q0*/
     100       35838 :         move32();
     101             :     }
     102       69696 :     return;
     103             : }
     104             : 
     105             : /*----------------------------------------------------------------------------------*
     106             :  * frame_ener()
     107             :  *
     108             :  * Estimation of pitch-synchronous (voiced) or mean half-frame (unvoiced) energy
     109             :  *----------------------------------------------------------------------------------*/
     110      236657 : Word16 frame_ener_fx(
     111             :     const Word16 L_frame, /* i  : length of the frame                            */
     112             :     const Word16 clas,    /* i  : frame classification                           */
     113             :     const Word16 *synth,  /* i  : synthesized speech at Fs = 12k8 Hz       Q_new */
     114             :     const Word16 pitch,   /* i  : pitch period                             Q0    */
     115             :     Word32 *enr_q,        /* o  : pitch-synchronous or half_frame energy   Q0    */
     116             :     const Word16 offset,  /* i  : speech pointer offset (0 or L_FRAME)           */
     117             :     const Word16 Q_new,   /* i  : Scaling factor                                 */
     118             :     Word16 shift,         /* i  : Shift need to obtain 12 bits vectors           */
     119             :     const Word16 enc      /* i  : Encoder/decoder                                */
     120             : )
     121             : {
     122             :     Word16 len, exp_enrq, exp_tmp, pos;
     123             :     Word16 i;
     124             :     const Word16 *pt_synth;
     125             :     Word32 Ltmp;
     126             : 
     127      236657 :     exp_enrq = 0;
     128      236657 :     move16();
     129      236657 :     test();
     130      236657 :     test();
     131      236657 :     IF( ( EQ_16( clas, VOICED_CLAS ) ) || ( EQ_16( clas, ONSET ) ) || ( EQ_16( clas, SIN_ONSET ) ) ) /* current frame is voiced */
     132             :     {
     133             :         /* current frame is voiced */
     134       90280 :         len = pitch;
     135       90280 :         move16(); /* pitch value at the end of frame */
     136       90280 :         pt_synth = synth;
     137       90280 :         if ( offset != 0 )
     138             :         {
     139       89322 :             pt_synth = synth + sub( L_frame, len );
     140             :         }
     141       90280 :         emaximum_fx( Q_new, pt_synth, len, enr_q );
     142       90280 :         IF( enc != 0 )
     143             :         {
     144         341 :             exp_enrq = norm_l( *enr_q );
     145         341 :             *enr_q = L_shl( *enr_q, exp_enrq );
     146         341 :             move32();
     147         341 :             exp_enrq = sub( exp_enrq, 2 );
     148             :         }
     149             :     }
     150             :     ELSE
     151             :     {
     152             :         /* current frame is unvoiced */
     153             :         Word16 L_frame2, exp2, enr_q_tmp;
     154             : 
     155      146377 :         L_frame2 = shr( L_frame, 1 );
     156      146377 :         pos = 0;
     157      146377 :         move16();
     158             : 
     159      146377 :         if ( offset != 0 )
     160             :         {
     161      145998 :             pos = sub( L_frame, L_frame2 );
     162             :         }
     163      146377 :         Ltmp = L_mult_sat( synth[pos], synth[pos] ); /*2 * Qnew + 1*/
     164    21123584 :         FOR( i = 1; i < L_frame2; i++ )
     165             :         {
     166    20977207 :             Ltmp = L_mac_sat( Ltmp, synth[pos + i], synth[pos + i] ); /*2 * Qnew + 1*/
     167             :         }
     168      146377 :         test();
     169      146377 :         IF( EQ_32( Ltmp, MAX_32 ) || enc != 0 )
     170             :         {
     171             :             /* scale down when overflow occurs */
     172         588 :             *enr_q = Energy_scale( synth + pos, L_frame2, shift, &exp_enrq );
     173         588 :             move32();
     174             :         }
     175             :         ELSE
     176             :         {
     177      145789 :             shift = 0;
     178      145789 :             move16();
     179             :             /* Normalize acc in Q31 (energy already calculated) */
     180      145789 :             pos = norm_l( Ltmp );
     181      145789 :             Ltmp = L_shl( Ltmp, pos );
     182      145789 :             exp_enrq = sub( 30, pos ); /* exponent = 0..30 */
     183      145789 :             *enr_q = Ltmp;
     184      145789 :             move32();
     185             :         }
     186             : 
     187             :         /* enr2 = 1.0f/L_FRAME2 * dot_product(synth, synth, L_FRAME2) */
     188      146377 :         exp_enrq = sub( exp_enrq, shl( shift, 1 ) );
     189             : 
     190      146377 :         IF( enc != 0 )
     191             :         {
     192         283 :             assert( L_frame == 256 || L_frame == 320 );
     193             : 
     194         283 :             exp_tmp = add( shl( Q_new, 1 ), -2 + 7 ); /*  L_subfr == L_SUBFR */
     195         283 :             exp_enrq = sub( exp_enrq, exp_tmp );
     196         283 :             exp_enrq = sub( 31, exp_enrq );
     197             : 
     198         283 :             IF( EQ_16( L_frame, 320 ) )
     199             :             {
     200         283 :                 *enr_q = Mult_32_16( *enr_q, 26214 ); /*x 0.8 to get /160*/
     201         283 :                 move32();
     202         283 :                 i = norm_l( *enr_q );
     203         283 :                 *enr_q = L_shl( *enr_q, i );
     204         283 :                 move32();
     205         283 :                 exp_enrq = add( i, exp_enrq );
     206             :             }
     207             :         }
     208             :         ELSE
     209             :         {
     210      146094 :             exp_enrq = sub( exp_enrq, add( Q_new, Q_new ) );
     211      146094 :             enr_q_tmp /*Q30 exp2+exp_enrq*/ = BASOP_Util_Divide3216_Scale( *enr_q /*Q31*/, L_frame2 /*Q0*/, &exp2 );
     212      146094 :             *enr_q = L_shr( L_deposit_l( enr_q_tmp ), sub( 30, add( exp2, exp_enrq ) ) ); /*Q0*/
     213      146094 :             move32();
     214      146094 :             *enr_q = L_add( *enr_q, 1 );
     215      146094 :             move32();
     216      146094 :             exp_enrq = 0;
     217      146094 :             move16();
     218             :         }
     219             :     }
     220             : 
     221      236657 :     return exp_enrq;
     222             : }
     223             : 
     224             : /*------------------------------------------------------------------------*
     225             :  * frame_energy()
     226             :  *
     227             :  * Compute pitch-synchronous energy at the frame end
     228             :  *------------------------------------------------------------------------*/
     229      123491 : Word16 frame_energy_fx( /* o  : Frame energy in                               Q8 */
     230             :                         Word16 L_frame,
     231             :                         const Word16 *pitch,    /* i  : pitch values for each subframe                Q6 */
     232             :                         const Word16 *speech,   /* i  : pointer to speech signal for E computation  Q_syn*/
     233             :                         const Word16 lp_speech, /* i  : long term active speech energy average      Q8   */
     234             :                         Word16 *frame_ener,     /* o  : pitch-synchronous energy at frame end       Q8   */
     235             :                         const Word16 Q_syn      /* i  : Synthesis scaling                                */
     236             : )
     237             : {
     238             :     Word32 Ltmp;
     239             :     const Word16 *pt1;
     240             :     Word16 tmp16, exp1, exp2, tmp1, tmp2;
     241             :     Word16 len, enern;
     242             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     243      123491 :     Flag Overflow = 0;
     244      123491 :     move32();
     245             : #endif
     246             : 
     247             : 
     248             :     /* len = (0.5f * (pitch[2]/64.0 + pitch[3]/64.0) + 0.5f) */
     249      123491 :     len = mult_r( add_o( pitch[2], pitch[3], &Overflow ), 256 );
     250             : 
     251      123491 :     if ( LT_16( len, L_SUBFR ) )
     252             :     {
     253       30846 :         len = shl( len, 1 );
     254             :     }
     255      123491 :     pt1 = speech + sub( L_frame, len );
     256             : 
     257             :     /* *frame_ener = 10.0f * log10(dot_product(pt1, pt1, len) / (float)len) */
     258             : 
     259      123491 :     tmp1 = norm_s( len );
     260      123491 :     tmp2 = shl( len, tmp1 );
     261      123491 :     tmp1 = sub( 15, tmp1 );
     262             : 
     263      123491 :     Ltmp = Dot_productSq16HQ( 0, pt1, len, &exp1 );
     264      123491 :     exp1 = sub( exp1, shl( Q_syn, 1 ) );
     265      123491 :     exp1 = sub( exp1, 1 ); /* compensation of leftshift caused by mac operation in dot_productSq16HQ */
     266      123491 :     tmp16 = BASOP_Util_Divide3216_Scale( Ltmp, len, &exp2 );
     267             : 
     268      123491 :     exp1 = add( exp1, exp2 );
     269      123491 :     exp1 = add( exp1, 1 ); /* compensate result of division Q-1 */
     270             : 
     271             : 
     272      123491 :     tmp2 = norm_s( tmp16 );
     273      123491 :     Ltmp = L_shl( L_deposit_h( tmp16 ), tmp2 ); /*Q16, (exp1-tmp2)  =  Q31, exp1-tmp2+15*/
     274             : 
     275      123491 :     Ltmp = BASOP_Util_Log2( Ltmp ); /*Q(31-6) = Q25*/
     276      123491 :     exp1 = sub( 15 + exp1, tmp2 );
     277             : 
     278             :     /*add ld(2^exp1)=exp1 but check format, first*/
     279      123491 :     tmp16 = sub( sub( 15, norm_s( exp1 ) ), 5 );                         /*factor to shift Ltmp and exp1 with (shr) to avoid overflows when adding*/
     280      123491 :     Ltmp = L_shr_o( Ltmp, tmp16, &Overflow );                            /*Q25, tmp16*/
     281      123491 :     exp2 = shr( exp1, tmp16 );                                           /*Q0 , tmp16*/
     282      123491 :     Ltmp = L_add_o( Ltmp, L_shl( L_deposit_l( exp2 ), 25 ), &Overflow ); /*Q25, tmp16, normalized*/
     283             : 
     284             :     /*make 10*log10 out of log2*/
     285      123491 :     Ltmp = Mpy_32_16_1( Ltmp, LG10 );                                       /*Q25,tmp16 * Q13 = Q23, tmp16*/
     286      123491 :     *frame_ener = extract_h( L_shl_o( Ltmp, add( tmp16, 1 ), &Overflow ) ); /*Q8*/
     287      123491 :     move16();
     288      123491 :     enern = sub_o( *frame_ener, lp_speech, &Overflow ); /*Q8*/
     289             : 
     290      123491 :     return enern;
     291             : }

Generated by: LCOV version 1.14