LCOV - code coverage report
Current view: top level - lib_com - scale_mem_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 132 139 95.0 %
Date: 2025-05-03 01:55:50 Functions: 4 5 80.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.452 Aug 12, 2021. Version 16.3.0
      35             :   ====================================================================================*/
      36             : 
      37             : #include "options.h" /* Common prototypes           */
      38             : #include "prot_fx.h" /* Common prototypes           */
      39             : #include "ivas_cnst.h"
      40             : #include "stl.h"
      41             : 
      42             : /*-------------------------------------------------------------------*
      43             :  * Rescale_exc:
      44             :  *
      45             :  * Find absolute maximum of excitation
      46             :  * Fin scaling factor to apply the excitation and its related memory
      47             :  * Scale excitation and total excitation (exc2)
      48             :  *-------------------------------------------------------------------*/
      49      593777 : Word16 Rescale_exc(
      50             :     Word16 dct_post_old_exc_fx[], /* i/o: Music post processing memory Q_exc*/
      51             :     Word16 exc[],                 /* i/o: excitation to rescale           Q_exc */
      52             :     Word16 bwe_exc[],             /*  output Q = Q_exc */
      53             :     Word16 *last_exc_dct_in,      /*  output Q = Q_exc */
      54             :     Word16 lg,                    /* i  : frame size                            */
      55             :     Word16 lg32,
      56             :     Word32 L_gain_code, /* i  : decoded codebook gain           Q16   */
      57             :     Word16 *sQ_exc,     /* i/o: Excitation scaling factor             */
      58             :     Word16 *sQsubfr,    /* i/o: Past excitation scaling factors       */
      59             :     Word16 exc2[],      /* o  : local excitation vector            output Q = Q_exc   */
      60             :     Word16 i_subfr,     /* i  : subframe number                       */
      61             :     const Word16 coder_type )
      62             : {
      63             :     Word16 i, tmp, max, new_Q;
      64             : 
      65             :     /*-------------------------------------------
      66             :      * find maximum of absolute excitation
      67             :      *-------------------------------------------*/
      68      593777 :     max = s_max( abs_s( exc[0] ), 1 );
      69    44950592 :     FOR( i = 1; i < lg; i++ )
      70             :     {
      71    44356815 :         tmp = abs_s( exc[i] );
      72    44356815 :         max = s_max( max, tmp );
      73             :     }
      74             : 
      75             :     /*----------------------------------------------
      76             :      * find scaling (tmp) to set max = [2048..4096[
      77             :      *----------------------------------------------*/
      78      593777 :     tmp = sub( add( norm_s( max ), *sQ_exc ), 3 );
      79      593777 :     tmp = s_min( tmp, 12 );
      80             : 
      81             :     /*----------------------------------------------
      82             :      * find scaling (new_Q) to keep gain_code < 2048
      83             :      *----------------------------------------------*/
      84             : 
      85      593777 :     new_Q = add( tmp, 1 );
      86      593777 :     tmp = sub( norm_l( L_or( L_gain_code, 1 ) ), 3 ); /* to get to 0x08000000L (L_or with 1 to avoid norm_l(0)) */
      87      593777 :     tmp = s_min( tmp, new_Q );
      88      593777 :     tmp = s_max( tmp, 0 );
      89      593777 :     tmp = sub( tmp, 1 );
      90             : 
      91             :     /*#define REMOVE_EXCITATION_PER_FRAME_SCALING */
      92             : 
      93             :     /*----------------------------------------------
      94             :      * new_Q = smallest Q since 4 subframes (20ms)
      95             :      *----------------------------------------------*/
      96      593777 :     IF( EQ_16( coder_type, TRANSITION ) )
      97             :     {
      98       57187 :         tmp = s_min( tmp, 7 );
      99             :     }
     100      536590 :     ELSE IF( EQ_16( coder_type, INACTIVE ) )
     101             :     {
     102       30984 :         tmp = s_min( tmp, 13 );
     103             :     }
     104      505606 :     ELSE IF( GT_16( lg, L_SUBFR ) ) /* --> can only happen in AUDIO mode */
     105             :     {
     106       14329 :         tmp = s_min( tmp, 4 );                        /* Limitation of the scaling gain because the frequency domain will add much more energy to the excitation*/
     107       14329 :         if ( GE_32( L_abs( L_gain_code ), 3276800 ) ) /*(1-gain_pit)*past gain code*4 > 50 */
     108             :         {
     109        6688 :             tmp = s_min( tmp, 2 ); /* Limitation of the scaling gain because the frequency domain might add much more energy to the excitation*/
     110             :         }
     111             :     }
     112             : 
     113      593777 :     new_Q = s_min( tmp, sQsubfr[0] );
     114      593777 :     IF( EQ_16( lg, L_SUBFR ) )
     115             :     {
     116     2788095 :         FOR( i = L_Q_MEM - 1; i >= 1; i-- )
     117             :         {
     118     2230476 :             new_Q = s_min( new_Q, sQsubfr[i] );
     119     2230476 :             sQsubfr[i] = sQsubfr[i - 1];
     120     2230476 :             move16();
     121             :         }
     122             :     }
     123             :     ELSE
     124             :     {
     125       36158 :         IF( EQ_16( lg, 2 * L_SUBFR ) )
     126             :         {
     127        5178 :             new_Q = s_min( new_Q, sQsubfr[L_Q_MEM - 1] );
     128       20712 :             FOR( i = L_Q_MEM - 1; i >= 2; i-- )
     129             :             {
     130       15534 :                 sQsubfr[i] = sQsubfr[1];
     131       15534 :                 move16();
     132             :             }
     133        5178 :             sQsubfr[1] = tmp;
     134        5178 :             move16();
     135        5178 :             sQsubfr[0] = tmp;
     136        5178 :             move16();
     137             :         }
     138             :         ELSE
     139             :         {
     140       30980 :             set16_fx( sQsubfr, tmp, L_Q_MEM );
     141             :         }
     142             :     }
     143      593777 :     sQsubfr[0] = tmp;
     144      593777 :     move16();
     145             : 
     146             :     /*----------------------------------------------
     147             :      * rescale excitation and associated memories
     148             :      *----------------------------------------------*/
     149             : 
     150      593777 :     tmp = sub( new_Q, *sQ_exc );
     151             : 
     152      593777 :     IF( tmp != 0 )
     153             :     {
     154             : 
     155       87181 :         Scale_sig( exc - L_EXC_MEM_DEC, add( L_EXC_MEM_DEC, lg ), tmp );
     156       87181 :         IF( last_exc_dct_in != NULL )
     157             :         {
     158       86752 :             Scale_sig( last_exc_dct_in, L_FRAME, tmp );
     159             :         }
     160       87181 :         IF( bwe_exc != NULL )
     161             :         {
     162       87136 :             Scale_sig( bwe_exc - PIT16k_MAX * 2, add( PIT16k_MAX * 2, lg32 ), tmp );
     163             :         }
     164       87181 :         IF( exc2 != NULL )
     165             :         {
     166       74962 :             Scale_sig( exc2, i_subfr, tmp );
     167             :         }
     168       87181 :         IF( dct_post_old_exc_fx != NULL )
     169             :         {
     170       85070 :             Scale_sig( dct_post_old_exc_fx, DCT_L_POST - OFFSET2, tmp );
     171             :         }
     172             :     }
     173             : 
     174             :     /* scaling factor of excitation (-1..12) */
     175      593777 :     *sQ_exc = new_Q;
     176      593777 :     move16();
     177             : 
     178      593777 :     return tmp;
     179             : }
     180             : 
     181             : /*-------------------------------------------------------------------*
     182             :  * Rescale_mem:
     183             :  *
     184             :  * this function should be called after excitation update (4 subfr) and before frame synthesis
     185             :  * Rescale excitation related memories
     186             :  *-------------------------------------------------------------------*/
     187      165494 : void Rescale_mem(
     188             :     const Word16 Q_exc,            /* i   : current excitation scaling (>=0)          */
     189             :     Word16 *prev_Q_syn,            /* i/o  : scaling factor of previous frame          */
     190             :     Word16 *Q_syn,                 /* i/o  : scaling factor of frame                   */
     191             :     Word16 *mem_syn2,              /* i/o  : modified synthesis memory              Qexp_scale  */
     192             :     Word16 *mem_syn_clas_estim_fx, /* i/o  : old 12k8 core memory for classification Qexp_scale*/
     193             :     const Word16 MaxScaling,       /* i: Minimal difference between excitation scaling and synthesis scaling */
     194             :     Word16 *mem_deemph,            /* i/o: speech deemph filter memory                Qexp_scale */
     195             :     Word16 *pst_old_syn,           /* i/o:  psfiler                                    Qexp_scale*/
     196             :     Word16 *pst_mem_deemp_err,     /* i/o:  psfiler                                   Qexp_scale  */
     197             :     Word16 *mem_agc,               /*Qexp_scale*/
     198             :     PFSTAT_HANDLE hPFstat,         /* i/o:  All memories related to NB post filter      */
     199             :     const Word16 Vad_flag,
     200             :     const Word16 Cna_flag,
     201             :     const Word16 *tmp_buffer /* tmp_buffer in Q-1 */
     202             : )
     203             : {
     204             :     Word16 exp_scale, new_Q, tmp, i;
     205             : 
     206             :     /*-------------------------------------------------------------------*
     207             :      * find scaling of synthesis (based on min of current frame and last frame)
     208             :      * scaling factor of synthesis (-1..6)
     209             :      *-------------------------------------------------------------------*/
     210      165494 :     new_Q = sub( Q_exc, MaxScaling );
     211      165494 :     tmp = 1;
     212      165494 :     move16();
     213      165494 :     IF( tmp_buffer != NULL )
     214             :     {
     215             :         /* use the temporary synthesis in Q-1 to estimate the scaling */
     216    36767705 :         FOR( i = 0; i < L_FRAME; i++ )
     217             :         {
     218    36624640 :             tmp = s_max( abs_s( tmp_buffer[i] ), tmp );
     219             :         }
     220             :         /* we add Q_syn which represents the actual scaling of the memories prev_Q_syn represents the last potential scaling */
     221      143065 :         tmp = sub( add( norm_s( tmp ), -1 ), 3 ); /* -2 ... 12 */
     222             :     }
     223       22429 :     ELSE IF( hPFstat != NULL )
     224             :     {
     225      257975 :         FOR( i = 0; i < M; i++ )
     226             :         {
     227      242800 :             tmp = s_max( abs_s( mem_syn2[i] ), tmp );
     228      242800 :             tmp = s_max( abs_s( pst_old_syn[i] ), tmp );
     229      242800 :             tmp = s_max( abs_s( mem_syn_clas_estim_fx[i] ), tmp );
     230             :         }
     231      743575 :         FOR( ; i < L_SUBFR; i++ )
     232             :         {
     233      728400 :             tmp = s_max( abs_s( pst_old_syn[i] ), tmp );
     234      728400 :             tmp = s_max( abs_s( mem_syn_clas_estim_fx[i] ), tmp );
     235             :         }
     236     2959125 :         FOR( ; i < L_SYN_MEM_CLAS_ESTIM; i++ )
     237             :         {
     238     2943950 :             tmp = s_max( abs_s( mem_syn_clas_estim_fx[i] ), tmp );
     239     2943950 :             tmp = s_max( abs_s( pst_old_syn[i] ), tmp );
     240             :         }
     241      500775 :         FOR( ; i < NBPSF_PIT_MAX; i++ )
     242             :         {
     243      485600 :             tmp = s_max( abs_s( pst_old_syn[i] ), tmp );
     244             :         }
     245             :         /* we add Q_syn which represents the actual scaling of the memories prev_Q_syn represents the last potential scaling */
     246       15175 :         tmp = sub( add( norm_s( tmp ), *Q_syn ), 2 ); /* -2 ... 12 */
     247             :     }
     248             : 
     249             : 
     250      165494 :     IF( Vad_flag != 0 )
     251             :     {
     252      145966 :         new_Q = s_min( sub( Q_exc, 2 ), tmp );
     253             :     }
     254       19528 :     ELSE IF( Cna_flag != 0 )
     255             :     {
     256           5 :         new_Q = s_min( Q_exc, sub( tmp, 2 ) );
     257             :     }
     258             :     ELSE
     259             :     {
     260       19523 :         new_Q = s_min( Q_exc, tmp );
     261             :     }
     262      165494 :     new_Q = s_min( new_Q, 12 ); /*  */
     263      165494 :     new_Q = s_max( new_Q, -1 ); /*  */
     264             : 
     265             :     /*#define REMOVE_SYNTHESIS_PER_FRAME_SCALING */
     266      165494 :     tmp = s_min( new_Q, *prev_Q_syn );
     267      165494 :     *prev_Q_syn = new_Q;
     268      165494 :     move16();
     269             : 
     270      165494 :     exp_scale = sub( tmp, *Q_syn );
     271      165494 :     *Q_syn = tmp;
     272      165494 :     move16();
     273             : 
     274             :     /* rescale synthesis memory (mem_syn2) */
     275      165494 :     Scale_sig( mem_syn2, M, exp_scale );
     276      165494 :     Scale_sig( mem_syn_clas_estim_fx, L_SYN_MEM_CLAS_ESTIM, exp_scale );
     277             :     /*Scale_sig(core_old_syn, L_SYN_MEM, exp_scale);*/
     278      165494 :     Scale_sig( mem_deemph, 1, exp_scale );
     279      165494 :     IF( hPFstat != NULL )
     280             :     {
     281      158240 :         Scale_sig( pst_old_syn, NBPSF_PIT_MAX, exp_scale );
     282      158240 :         Scale_sig( pst_mem_deemp_err, 1, exp_scale );
     283      158240 :         Scale_sig( hPFstat->mem_pf_in, L_SUBFR, exp_scale );    /* NB post_filter mem */
     284      158240 :         Scale_sig( hPFstat->mem_res2, DECMEM_RES2, exp_scale ); /* NB post_filter mem */
     285      158240 :         Scale_sig( hPFstat->mem_stp, L_SUBFR, exp_scale );      /* NB post_filter mem */
     286             :     }
     287      165494 :     Scale_sig( mem_agc, 1, exp_scale ); /* NB post_filter mem */
     288      165494 :     return;
     289             : }
     290             : 
     291             : // note_ : also present in tools_fx.c which one to take is an issue?
     292             : /*-------------------------------------------------------------------*
     293             :  * Scale_sig32
     294             :  * Note: In order to save complexity, call function only, if exp0 != 0
     295             :  * Up/down scale a 32 bits vector
     296             :  *-------------------------------------------------------------------*/
     297   752973745 : void scale_sig32(
     298             :     Word32 x[],       /* i/o: signal to scale                 Qx        */
     299             :     const Word16 lg,  /* i  : size of x[]                     Q0        */
     300             :     const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx   exp  */
     301             : )
     302             : {
     303             :     Word16 i;
     304             : 
     305 44374321658 :     FOR( i = 0; i < lg; i++ )
     306             :     {
     307             :         /* saturation can occur here */
     308 43621347913 :         x[i] = L_shl( x[i], exp0 );
     309 43621347913 :         move32();
     310             : #ifdef OPT_STEREO_32KBPS_V1
     311 43621347913 :         if ( 0 == exp0 )
     312             :         {
     313   137197172 :             i = lg;
     314             :         }
     315             : #endif /* OPT_STEREO_32KBPS_V1 */
     316             :     }
     317   752973745 : }
     318             : 
     319           0 : void scale_sig32_r(
     320             :     Word32 x[],       /* i/o: signal to scale                 Qx        */
     321             :     const Word16 lg,  /* i  : size of x[]                     Q0        */
     322             :     const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx   exp  */
     323             : )
     324             : {
     325             :     Word16 i;
     326             : 
     327           0 :     FOR( i = 0; i < lg; i++ )
     328             :     {
     329             :         /* saturation can occur here */
     330           0 :         x[i] = L_shl_r( x[i], exp0 );
     331           0 :         move32();
     332             : #ifdef OPT_STEREO_32KBPS_V1
     333           0 :         if ( 0 == exp0 )
     334             :         {
     335           0 :             i = lg;
     336             :         }
     337             : #endif /* OPT_STEREO_32KBPS_V1 */
     338             :     }
     339           0 : }
     340             : 
     341             : /*-------------------------------------------------------------------*
     342             :  * Rescale_mem:
     343             :  *
     344             :  * this function should be called after excitation update (4 subfr) and before frame synthesis
     345             :  * Rescale excitation related memories
     346             :  *-------------------------------------------------------------------*/
     347        3050 : Word16 rescale_mem(
     348             :     const Word16 *Q_exc, /* i    : current excitation scaling (>=0)          */
     349             :     Word16 *prev_Q_syn,  /* i/o  : scaling factor of previous frame          */
     350             :     Word16 *Q_syn,       /* i/o  : scaling factor of frame                   */
     351             :     Word16 *mem_syn2,    /* i/o  : modified synthesis memory       Q_syn    */
     352             :     Word16 *syn,         /* i/o  : synthesis  to rescale           Q_syn     */
     353             :     Word16 mem_len,      /* i    : lenght of modified synthesis memory       */
     354             :     Word16 i_subfr       /* i  : subframe number                       */
     355             : )
     356             : {
     357             :     Word16 exp_scale, new_Q, tmp;
     358             :     Word16 i, max16, max_scale;
     359             : 
     360        3050 :     max16 = 0;
     361        3050 :     move16();
     362       51850 :     FOR( i = 0; i < mem_len; i++ )
     363             :     {
     364       48800 :         max16 = s_max( max16, abs_s( mem_syn2[i] ) );
     365             :     }
     366        3050 :     IF( syn != NULL )
     367             :     {
     368      393450 :         FOR( i = 0; i < i_subfr; i++ )
     369             :         {
     370      390400 :             max16 = s_max( max16, abs_s( syn[i] ) );
     371             :         }
     372             :     }
     373        3050 :     max_scale = 15;
     374        3050 :     move16();
     375        3050 :     IF( max16 > 0 )
     376             :     {
     377        3043 :         max_scale = add( norm_s( max16 ), -3 );
     378             :     }
     379             : 
     380             :     /*-------------------------------------------------------------------*
     381             :      * find scaling of synthesis (based on min of current frame and last frame)
     382             :      * scaling factor of synthesis (-1..6)
     383             :      *-------------------------------------------------------------------*/
     384        3050 :     new_Q = sub( *Q_exc, 3 );
     385        3050 :     new_Q = s_max( new_Q, -1 );
     386             : 
     387        3050 :     tmp = add( max_scale, *Q_syn );
     388        3050 :     if ( GT_16( s_min( new_Q, *prev_Q_syn ), tmp ) )
     389             :     {
     390          85 :         new_Q = s_max( tmp, -1 );
     391             :     }
     392             : 
     393        3050 :     tmp = s_min( new_Q, *prev_Q_syn );
     394        3050 :     *prev_Q_syn = new_Q;
     395        3050 :     move16();
     396             : 
     397        3050 :     exp_scale = sub( tmp, *Q_syn );
     398        3050 :     *Q_syn = tmp;
     399        3050 :     move16();
     400             :     /* rescale synthesis memory (mem_syn2) */
     401        3050 :     Scale_sig( mem_syn2, mem_len, exp_scale );
     402        3050 :     IF( syn != NULL )
     403             :     {
     404        3050 :         Scale_sig( syn, i_subfr, exp_scale );
     405             :     }
     406             : 
     407        3050 :     return exp_scale;
     408             : }

Generated by: LCOV version 1.14