LCOV - code coverage report
Current view: top level - lib_enc - multi_harm_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 317 329 96.4 %
Date: 2025-09-14 03:13:15 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : #include <stdint.h>
       5             : #include "options.h" /* Compilation switches                   */
       6             : #include "cnst.h"    /* Common constants                       */
       7             : //#include "prot_fx.h"       /* Function prototypes                    */
       8             : #include "prot_fx.h"     /* Function prototypes                    */
       9             : #include "prot_fx_enc.h" /* Function prototypes                    */
      10             : #include "basop_util.h"
      11             : 
      12             : #define THR_CORR_FX      ( 56 << 15 ) /* 56 in Q15 starting threshold of multi-harm. correlation */
      13             : #define THR_CORR_MAX_FX  30720        /* 60 in Q9 upper threshold of multi-harm. correlation */
      14             : #define THR_CORR_MIN_FX  25088        /* 49 in Q9 lower threshold of multi-harm. correlation */
      15             : #define THR_CORR_STEP_FX 102          /* 0.2 in Q9 step for the threshold of multi-harm. correlation */
      16             : 
      17             : /*---------------------------------------------------------------------*
      18             :  * multi_harm()
      19             :  *
      20             :  * Perform multi-harmonic analysis, information used for UV and VAD decision
      21             :  *---------------------------------------------------------------------*/
      22             : 
      23       20890 : Word16 multi_harm_fx(                           /* o  : frame multi-harmonicity (1-harmonic, 0-not)             */
      24             :                       const Word16 Bin_E[],     /* i  : log-energy spectrum of the current frame      Q7        */
      25             :                       Word16 old_S[],           /* i/o: prev. log-energy spectrum w. subtracted floor Q7        */
      26             :                       Word16 cor_map_LT[],      /* i/o: LT correlation map                            Q15       */
      27             :                       Word16 *multi_harm_limit, /* i/o: multi harminic threshold                      Q9        */
      28             :                       const Word32 total_brate, /* i  : total bitrate                                                     Q0    */
      29             :                       const Word16 bwidth,      /* i  : input signal bandwidth                        Q0    */
      30             :                       Word16 *cor_strong_limit, /* i/o: HF correlation indicator                                          Q0    */
      31             :                       Word16 *st_mean_avr_dyn,  /* i/o: long term average dynamic                                         Q7    */
      32             :                       Word16 *st_last_sw_dyn,   /* i/o: last dynamic                                                      Q7    */
      33             :                       Word16 *cor_map_sum,      /* i  : sum of correlation map                        Q8        */
      34             :                       Word16 *sp_floor,         /* o: noise floor estimate                            Q7    */
      35             :                       Word16 S_map[]            /* o  : short-term correlation map                    Q7    */
      36             : )
      37             : {
      38             :     Word16 i, j, k, L, stemp, N_mins, ind_mins[L_FFT / 4], *pt_mins, harm;
      39             :     Word16 S[L_FFT / 2], flor, step, sign_fx, tmp16, tmp2, ExpInd, tmpdB, ExpdB, Expx2, Expy2;
      40             :     Word16 corx2, cory2, corxy, cor, cor_map[L_FFT / 2], *pt1, *pt2, cor_strong;
      41             :     Word32 L_acc;
      42             :     Word32 Lcorx2, Lcory2, Lcorxy, Lcor_map_LT_sum;
      43             :     Word16 mean_dyn;
      44             : #ifndef ISSUE_1867_replace_overflow_libenc
      45             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      46             :     Flag Overflow = 0;
      47             :     move32();
      48             : #endif
      49             : #endif
      50             : 
      51             :     /*------------------------------------------------------------------*
      52             :      * initialization
      53             :      *------------------------------------------------------------------*/
      54             : 
      55             :     /* length of the useful part of the spectrum (up to 6.4kHz) */
      56       20890 :     L = L_FFT / 2;
      57       20890 :     move16();
      58       20890 :     if ( ( bwidth == NB ) )
      59             :     {
      60             :         /* length of the useful part of the spectrum (up to 3.6kHz) */
      61           0 :         L = 76;
      62           0 :         move16();
      63             :     }
      64             : 
      65       20890 :     Copy( Bin_E, S, L );
      66             : 
      67             :     /*------------------------------------------------------------------*
      68             :      * searching of spectral maxima and minima
      69             :      *------------------------------------------------------------------*/
      70             : 
      71       20890 :     pt_mins = ind_mins;
      72             : 
      73             :     /* index of the first minimum */
      74       20890 :     if ( LT_16( Bin_E[0], Bin_E[1] ) )
      75             :     {
      76       10230 :         *pt_mins++ = 0;
      77       10230 :         move16();
      78             :     }
      79             : 
      80     2653030 :     FOR( i = 1; i < L - 1; i++ )
      81             :     {
      82             :         /* minimum found */
      83     2632140 :         test();
      84     2632140 :         if ( LT_16( Bin_E[i], Bin_E[i - 1] ) && LT_16( Bin_E[i], Bin_E[i + 1] ) )
      85             :         {
      86      717213 :             *pt_mins++ = i;
      87      717213 :             move16();
      88             :         }
      89             :     }
      90             : 
      91             :     /* index of the last minimum */
      92       20890 :     IF( LT_16( Bin_E[L - 1], Bin_E[L - 2] ) )
      93             :     {
      94           0 :         *pt_mins++ = sub( L, 1 );
      95           0 :         move16();
      96             :     }
      97             : 
      98             :     /* total number of minimas found */
      99       20890 :     N_mins = (Word16) ( pt_mins - ind_mins - 1 );
     100       20890 :     move16();
     101             : 
     102             :     /*------------------------------------------------------------------*
     103             :      * calculation of the spectral floor
     104             :      * subtraction of the spectral floor
     105             :      *------------------------------------------------------------------*/
     106             : 
     107       20890 :     set16_fx( S, 0, L );
     108             : 
     109       20890 :     IF( N_mins > 0 )
     110             :     {
     111       20698 :         L_acc = L_deposit_l( 0 );
     112      727442 :         FOR( i = 0; i < N_mins; ++i )
     113             :         {
     114      706744 :             L_acc = L_mac0( L_acc, Bin_E[ind_mins[i]], 1 );
     115             :         }
     116       20698 :         *sp_floor = extract_l( Mult_32_16( L_acc, div_s( 1, N_mins ) ) );
     117       20698 :         move16();
     118             : 
     119       20698 :         set16_fx( S, 0, ind_mins[0] );
     120       20698 :         set16_fx( &S[ind_mins[N_mins]], 0, sub( shr( L_FFT, 1 ), ind_mins[N_mins] ) );
     121             : 
     122       20698 :         pt_mins = ind_mins;
     123       20698 :         flor = 0;
     124       20698 :         move16();
     125       20698 :         step = 0;
     126       20698 :         move16();
     127             : 
     128     2557174 :         FOR( i = ind_mins[0]; i < ind_mins[N_mins]; i++ )
     129             :         {
     130             :             /* we are at the end of the next minimum */
     131     2536476 :             IF( EQ_16( i, *pt_mins ) )
     132             :             {
     133      706744 :                 pt_mins++;
     134      706744 :                 flor = Bin_E[i];
     135      706744 :                 move16(); /*Q7*/
     136             :                 /* calculate the new step */
     137             :                 /*step = (Bin_E[*pt_mins] - Bin_E[i]) / (*pt_mins-i);*/
     138      706744 :                 tmp16 = sub( *pt_mins, i );
     139      706744 :                 tmpdB = sub( Bin_E[*pt_mins], Bin_E[i] );
     140      706744 :                 sign_fx = shr( tmpdB, 15 ); /* 0 if positive else -1 */
     141      706744 :                 ExpdB = sub( norm_s( tmpdB ), 1 );
     142      706744 :                 tmpdB = abs_s( shl( tmpdB, ExpdB ) );
     143      706744 :                 ExpInd = norm_s( tmp16 );
     144      706744 :                 tmp16 = shl( tmp16, ExpInd );
     145      706744 :                 tmp16 = div_s( tmpdB, tmp16 );
     146      706744 :                 tmp16 = sub( s_xor( tmp16, sign_fx ), sign_fx );
     147      706744 :                 step = shr( tmp16, add( sub( ExpdB, ExpInd ), 15 ) ); /* Q7 */
     148             :             }
     149             : 
     150             :             /* subtract the floor */
     151     2536476 :             S[i] = s_max( sub_sat( Bin_E[i], flor ), 0 );
     152     2536476 :             move16();
     153             : 
     154             :             /* update the floor */
     155     2536476 :             flor = add( flor, step ); /*Q7*/
     156             :         }
     157             :     }
     158             : 
     159             :     /* Calculate the maximum dynamic per band */
     160             :     /* since we are processing 40 bins we will use 1/40 in Q15 to find the mean */
     161             :     /* mean_dyn = mean(&S[L-40], 40);*/
     162       20890 :     L_acc = L_deposit_l( 0 );
     163      856490 :     FOR( i = L - 40; i < L; i++ )
     164             :     {
     165      835600 :         L_acc = L_mac( L_acc, S[i], 819 /* 1 / 40 in Q15 */ );
     166             :     }
     167       20890 :     mean_dyn = round_fx( L_acc ); /*Q7*/
     168             : 
     169             :     /*mean_dyn = 0.6f * *st_mean_avr_dyn + 0.4f * mean_dyn;*/
     170       20890 :     L_acc = L_mult( 13107 /*0.4f*/, mean_dyn );               /*Q23*/
     171       20890 :     L_acc = L_mac( L_acc, 19661 /*0.6f*/, *st_mean_avr_dyn ); /*Q23*/
     172       20890 :     mean_dyn = round_fx( L_acc );                             /*Q7*/
     173             : 
     174       20890 :     test();
     175       20890 :     IF( LT_16( mean_dyn, 1229 ) /*9.6f.Q7*/ && *cor_strong_limit != 0 )
     176             :     {
     177        1701 :         *cor_strong_limit = 0;
     178        1701 :         move16();
     179        1701 :         *st_last_sw_dyn = mean_dyn;
     180        1701 :         move16();
     181             :     }
     182       19189 :     ELSE IF( GT_16( sub( mean_dyn, *st_last_sw_dyn ), 576 ) /*4.5f.Q7*/ )
     183             :     {
     184         168 :         *cor_strong_limit = 1;
     185         168 :         move16();
     186             :     }
     187       20890 :     test();
     188       20890 :     if ( LT_32( total_brate, ACELP_9k60 ) || GT_32( total_brate, ACELP_16k40 ) )
     189             :     {
     190       16800 :         *cor_strong_limit = 1;
     191       16800 :         move16();
     192             :     }
     193             : 
     194       20890 :     *st_mean_avr_dyn = mean_dyn;
     195       20890 :     move16();
     196             : 
     197             :     /*------------------------------------------------------------------*
     198             :      * calculation of the correlation map
     199             :      *------------------------------------------------------------------*/
     200             : 
     201       20890 :     set16_fx( cor_map, 0, L );
     202       20890 :     IF( N_mins > 0 )
     203             :     {
     204       20698 :         Lcorx2 = L_deposit_l( 0 );
     205       20698 :         Lcorxy = L_deposit_l( 0 );
     206       20698 :         stemp = ind_mins[0];
     207       20698 :         move16();
     208       20698 :         Lcory2 = L_mult( old_S[stemp], old_S[stemp] );
     209       20698 :         k = 1;
     210       20698 :         move16();
     211             : 
     212     2557174 :         FOR( i = add( stemp, 1 ); i <= ind_mins[N_mins]; i++ )
     213             :         {
     214     2536476 :             IF( EQ_16( i, ind_mins[k] ) )
     215             :             {
     216             :                 /* include the last peak point (new minimum) to the corr. sum */
     217             : #ifdef ISSUE_1867_replace_overflow_libenc
     218      706744 :                 Lcory2 = L_mac_sat( Lcory2, old_S[i], old_S[i] );
     219             : #else
     220             :                 Lcory2 = L_mac_o( Lcory2, old_S[i], old_S[i], &Overflow );
     221             : #endif
     222             : 
     223             :                 /* calculation of the norm. peak correlation */
     224      706744 :                 test();
     225      706744 :                 IF( Lcorx2 != 0 && Lcory2 != 0 )
     226             :                 {
     227             :                     /* corxy * corxy*/
     228      701725 :                     tmp16 = sub( norm_l( Lcorxy ), 1 );
     229      701725 :                     corxy = extract_h( L_shl( Lcorxy, tmp16 ) );
     230      701725 :                     corxy = mult_r( corxy, corxy );
     231             :                     /* (corx2 * cory2) */
     232      701725 :                     Expx2 = norm_l( Lcorx2 );
     233      701725 :                     Expy2 = norm_l( Lcory2 );
     234      701725 :                     corx2 = extract_h( L_shl( Lcorx2, Expx2 ) );
     235      701725 :                     cory2 = extract_h( L_shl( Lcory2, Expy2 ) );
     236      701725 :                     corx2 = mult_r( corx2, cory2 );
     237      701725 :                     Expx2 = add( Expy2, Expx2 );
     238             :                     /* Validate num < den */
     239      701725 :                     cor = sub( corx2, corxy );
     240      701725 :                     cor = shr( cor, 15 );
     241             :                     /* Add 1 to tmp16 & shr by 2 if corxy > corx2 */
     242      701725 :                     tmp16 = sub( tmp16, cor );
     243      701725 :                     corxy = shl( corxy, cor );
     244      701725 :                     corxy = shl( corxy, cor );
     245             :                     /* cor = corxy * corxy / (corx2 * cory2) */
     246      701725 :                     corxy = div_s( corxy, corx2 );
     247      701725 :                     cor = shr_sat( corxy, sub( shl( tmp16, 1 ), Expx2 ) ); /* Q15 */
     248             :                 }
     249             :                 ELSE
     250             :                 {
     251        5019 :                     cor = 0;
     252        5019 :                     move16();
     253             :                 }
     254             : 
     255             :                 /* save the norm. peak correlation in the correlation map */
     256     3243220 :                 FOR( j = ind_mins[k - 1]; j < ind_mins[k]; j++ )
     257             :                 {
     258     2536476 :                     old_S[j] = S[j];
     259     2536476 :                     move16();
     260     2536476 :                     S[j] = shr( cor, 8 );
     261     2536476 :                     move16();
     262     2536476 :                     cor_map[j] = cor;
     263     2536476 :                     move16();
     264             :                 }
     265             : 
     266      706744 :                 Lcorx2 = L_deposit_l( 0 );
     267      706744 :                 Lcory2 = L_deposit_l( 0 );
     268      706744 :                 Lcorxy = L_deposit_l( 0 );
     269             : 
     270      706744 :                 k++;
     271             :             }
     272             : #ifdef ISSUE_1867_replace_overflow_libenc
     273     2536476 :             Lcorx2 = L_mac_sat( Lcorx2, S[i], S[i] );
     274     2536476 :             Lcory2 = L_mac_sat( Lcory2, old_S[i], old_S[i] );
     275     2536476 :             Lcorxy = L_mac_sat( Lcorxy, S[i], old_S[i] );
     276             : #else
     277             :             Lcorx2 = L_mac_o( Lcorx2, S[i], S[i], &Overflow );
     278             :             Lcory2 = L_mac_o( Lcory2, old_S[i], old_S[i], &Overflow );
     279             :             Lcorxy = L_mac_o( Lcorxy, S[i], old_S[i], &Overflow );
     280             : #endif
     281             :         }
     282             : 
     283       20698 :         Copy( S, old_S, ind_mins[0] );
     284       20698 :         Copy( &S[ind_mins[N_mins]], &old_S[ind_mins[N_mins]], sub( L, ind_mins[N_mins] ) );
     285             :     }
     286             :     ELSE
     287             :     {
     288         192 :         *sp_floor = Bin_E[0];
     289         192 :         move16();
     290             :     }
     291       20890 :     *sp_floor = mult( *sp_floor, 14231 /* 1.0f / logf( 10.0f ) in Q15 */ );
     292       20890 :     move16(); /* Convert to log10() */
     293             : 
     294             :     /*------------------------------------------------------------------*
     295             :      * updating of the long-term correlation map
     296             :      * summation of the long-term correlation map
     297             :      *------------------------------------------------------------------*/
     298             : 
     299       20890 :     Lcor_map_LT_sum = L_deposit_l( 0 );
     300       20890 :     tmp2 = 0;
     301       20890 :     move16();
     302             : 
     303       20890 :     cor_strong = 0;
     304       20890 :     move16();
     305       20890 :     pt1 = cor_map_LT; // Q15
     306       20890 :     move16();
     307       20890 :     pt2 = cor_map;
     308       20890 :     move16();
     309     2694810 :     FOR( i = 0; i < L; i++ )
     310             :     {
     311             :         /* tmp2 += S[i]; */
     312     2673920 :         tmp2 = add( tmp2, shl( S[i], 1 ) ); /* tmp2 in Q8; max value is 128) */
     313             : 
     314             :         /* *pt1 = M_ALPHA_FX * *pt1 + (1-M_ALPHA_FX) * *pt2++ */
     315     2673920 :         *pt1 = mac_r( L_mult( ONE_MINUS_M_ALPHA, *pt2 ), M_ALPHA_FX, *pt1 );
     316     2673920 :         move16();
     317             : 
     318             :         /* cor_map_LT_sum += *pt1 */
     319     2673920 :         Lcor_map_LT_sum = L_add( Lcor_map_LT_sum, *pt1 ); /* cor_map_LT_sum in Q15; max value is 128) */
     320             : 
     321     2673920 :         if ( GT_16( *pt1, 31130 ) /*0.95f.Q15*/ )
     322             :         {
     323        3718 :             cor_strong = 1;
     324        3718 :             move16();
     325             :         }
     326             : 
     327     2673920 :         pt1++;
     328     2673920 :         pt2++;
     329             :     }
     330             : 
     331       20890 :     IF( ( bwidth == NB ) )
     332             :     {
     333             :         /* cor_map_LT_sum *= 1.53f; */
     334             :         /* tmp2 *= 1.53f; */
     335           0 :         Lcor_map_LT_sum = L_shl( Mult_32_16( Lcor_map_LT_sum, 25068 /* 1.53f in Q14 */ ), 1 );
     336           0 :         tmp2 = round_fx( L_mac( L_mult( tmp2, 32767 ), tmp2, 17367 /* 0.53 in Q15 */ ) );
     337             :     }
     338       20890 :     *cor_map_sum = tmp2;
     339       20890 :     move16();
     340             : 
     341             :     /* final decision about multi-harmonicity */
     342       20890 :     harm = 0;
     343       20890 :     move16();
     344       20890 :     test();
     345       20890 :     if ( ( L_msu0( Lcor_map_LT_sum, *multi_harm_limit, 64 ) > 0 ) || ( cor_strong != 0 ) )
     346             :     {
     347        5439 :         harm = 1;
     348        5439 :         move16();
     349             :     }
     350             : 
     351             :     /*------------------------------------------------------------------*
     352             :      * updating of the decision threshold
     353             :      *------------------------------------------------------------------*/
     354             : 
     355       20890 :     stemp = add( *multi_harm_limit, THR_CORR_STEP_FX );
     356       20890 :     if ( GT_32( Lcor_map_LT_sum, THR_CORR_FX ) ) /* Q15 */
     357             :     {
     358             :         /* *multi_harm_limit -= THR_CORR_STEP_FX */
     359        6045 :         stemp = sub( *multi_harm_limit, THR_CORR_STEP_FX );
     360             :     }
     361             : 
     362       20890 :     stemp = s_min( stemp, THR_CORR_MAX_FX );
     363       20890 :     *multi_harm_limit = s_max( stemp, THR_CORR_MIN_FX );
     364       20890 :     move16();
     365             : 
     366       20890 :     IF( N_mins <= 0 )
     367             :     {
     368         192 :         set16_fx( old_S, 0, L );
     369             :     }
     370       20890 :     IF( S_map != NULL )
     371             :     {
     372       17790 :         Copy( S, S_map, L );
     373             :     }
     374       20890 :     return harm;
     375             : }
     376             : 
     377     1132964 : Word16 multi_harm_ivas_fx(                           /* o  : frame multi-harmonicity (1-harmonic, 0-not)                */
     378             :                            const Word16 Bin_E[],     /* i  : log-energy spectrum of the current frame      Q7   */
     379             :                            Word16 old_S[],           /* i/o: prev. log-energy spectrum w. subtracted floor Q7   */
     380             :                            Word16 cor_map_LT[],      /* i/o: LT correlation map                            Q15  */
     381             :                            Word16 *multi_harm_limit, /* i/o: multi harminic threshold                      Q9   */
     382             :                            const Word32 total_brate, /* i  : total bitrate                                                Q0    */
     383             :                            const Word16 bwidth,      /* i  : input signal bandwidth                        Q0    */
     384             :                            Word16 *cor_strong_limit, /* i/o: HF correlation indicator                                     Q0    */
     385             :                            Word16 *st_mean_avr_dyn,  /* i/o: long term average dynamic                                    Q7    */
     386             :                            Word16 *st_last_sw_dyn,   /* i/o: last dynamic                                                 Q7    */
     387             :                            Word16 *cor_map_sum,      /* i  : sum of correlation map                        Q8   */
     388             :                            Word16 *sp_floor,         /* o: noise floor estimate                            Q7    */
     389             :                            Word16 S_map[]            /* o  : short-term correlation map                    Q7    */
     390             : )
     391             : {
     392             :     Word16 i, j, k, L, stemp, N_mins, ind_mins[L_FFT / 4], *pt_mins, harm;
     393             :     Word16 S[L_FFT / 2], flor, step, tmp16, tmp2, Expx2, Expy2;
     394             :     Word32 tmp2_32;
     395             :     Word16 corx2, cory2, corxy, cor, cor_map[L_FFT / 2], *pt1, *pt2, cor_strong;
     396             :     Word32 L_acc;
     397             :     Word32 Lcorx2, Lcory2, Lcorxy, Lcor_map_LT_sum;
     398             :     Word16 mean_dyn;
     399             : #ifndef ISSUE_1867_replace_overflow_libenc
     400             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     401             :     Flag Overflow = 0;
     402             :     move32();
     403             : #endif
     404             : #endif
     405             : 
     406             :     /*------------------------------------------------------------------*
     407             :      * initialization
     408             :      *------------------------------------------------------------------*/
     409             : 
     410             :     /* length of the useful part of the spectrum (up to 6.4kHz) */
     411     1132964 :     L = L_FFT / 2;
     412     1132964 :     move16();
     413     1132964 :     if ( ( bwidth == NB ) )
     414             :     {
     415             :         /* length of the useful part of the spectrum (up to 3.6kHz) */
     416           0 :         L = 76;
     417           0 :         move16();
     418             :     }
     419             : 
     420     1132964 :     Copy( Bin_E, S, L );
     421             : 
     422             :     /*------------------------------------------------------------------*
     423             :      * searching of spectral maxima and minima
     424             :      *------------------------------------------------------------------*/
     425             : 
     426     1132964 :     pt_mins = ind_mins;
     427             : 
     428             :     /* index of the first minimum */
     429     1132964 :     if ( LT_16( Bin_E[0], Bin_E[1] ) )
     430             :     {
     431      549035 :         *pt_mins++ = 0;
     432      549035 :         move16();
     433             :     }
     434             : 
     435   143886428 :     FOR( i = 1; i < L - 1; i++ )
     436             :     {
     437             :         /* minimum found */
     438   142753464 :         test();
     439   142753464 :         if ( LT_16( Bin_E[i], Bin_E[i - 1] ) && LT_16( Bin_E[i], Bin_E[i + 1] ) )
     440             :         {
     441    36416411 :             *pt_mins++ = i;
     442    36416411 :             move16();
     443             :         }
     444             :     }
     445             : 
     446             :     /* index of the last minimum */
     447     1132964 :     IF( LT_16( Bin_E[L - 1], Bin_E[L - 2] ) )
     448             :     {
     449           0 :         *pt_mins++ = sub( L, 1 );
     450           0 :         move16();
     451             :     }
     452             : 
     453             :     /* total number of minimas found */
     454     1132964 :     N_mins = (Word16) ( pt_mins - ind_mins - 1 );
     455     1132964 :     move16();
     456             : 
     457             :     /*------------------------------------------------------------------*
     458             :      * calculation of the spectral floor
     459             :      * subtraction of the spectral floor
     460             :      *------------------------------------------------------------------*/
     461             : 
     462     1132964 :     set16_fx( S, 0, L );
     463             : 
     464     1132964 :     IF( N_mins > 0 )
     465             :     {
     466     1068282 :         L_acc = L_deposit_l( 0 );
     467    36965441 :         FOR( i = 0; i < N_mins; ++i )
     468             :         {
     469    35897159 :             L_acc = L_mac0( L_acc, Bin_E[ind_mins[i]], 1 );
     470             :         }
     471     1068282 :         *sp_floor = extract_l( Mult_32_16( L_acc, div_s( 1, N_mins ) ) );
     472     1068282 :         move16();
     473             : 
     474     1068282 :         set16_fx( S, 0, ind_mins[0] );
     475     1068282 :         set16_fx( &S[ind_mins[N_mins]], 0, sub( shr( L_FFT, 1 ), ind_mins[N_mins] ) );
     476             : 
     477     1068282 :         pt_mins = ind_mins;
     478     1068282 :         flor = 0;
     479     1068282 :         move16();
     480     1068282 :         step = 0;
     481     1068282 :         move16();
     482             : 
     483   131948842 :         FOR( i = ind_mins[0]; i < ind_mins[N_mins]; i++ )
     484             :         {
     485             :             /* we are at the end of the next minimum */
     486   130880560 :             IF( EQ_16( i, *pt_mins ) )
     487             :             {
     488    35897159 :                 pt_mins++;
     489    35897159 :                 flor = Bin_E[i];
     490    35897159 :                 move16(); /*Q7*/
     491             : 
     492             :                 /* calculate the new step */
     493             :                 /*step = (Bin_E[*pt_mins] - Bin_E[i]) / (*pt_mins-i);*/
     494             : 
     495    35897159 :                 tmp16 = div_s( 1, sub( *pt_mins, i ) );                            // Q15
     496    35897159 :                 step = msu_r( L_mult( Bin_E[*pt_mins], tmp16 ), Bin_E[i], tmp16 ); // Q7 (15+7+1-16)
     497             :             }
     498             : 
     499             :             /* subtract the floor */
     500   130880560 :             S[i] = s_max( sub_sat( Bin_E[i], flor ), 0 );
     501   130880560 :             move16();
     502             : 
     503             :             /* update the floor */
     504   130880560 :             flor = add( flor, step ); /*Q7*/
     505             :         }
     506             :     }
     507             : 
     508             :     /* Calculate the maximum dynamic per band */
     509             :     /* since we are processing 40 bins we will use 1/40 in Q15 to find the mean */
     510             :     /* mean_dyn = mean(&S[L-40], 40);*/
     511     1132964 :     L_acc = L_deposit_l( 0 );
     512    46451524 :     FOR( i = L - 40; i < L; i++ )
     513             :     {
     514    45318560 :         L_acc = L_mac( L_acc, S[i], 819 /* 1 / 40 in Q15 */ );
     515             :     }
     516     1132964 :     mean_dyn = round_fx( L_acc ); /*Q7*/
     517             : 
     518             :     /*mean_dyn = 0.6f * *st_mean_avr_dyn + 0.4f * mean_dyn;*/
     519     1132964 :     L_acc = L_mult( 13107 /*0.4f*/, mean_dyn );               /*Q23*/
     520     1132964 :     L_acc = L_mac( L_acc, 19661 /*0.6f*/, *st_mean_avr_dyn ); /*Q23*/
     521     1132964 :     mean_dyn = round_fx( L_acc );                             /*Q7*/
     522             : 
     523     1132964 :     test();
     524     1132964 :     IF( LT_16( mean_dyn, 1229 ) /*9.6f*/ && *cor_strong_limit != 0 )
     525             :     {
     526      244591 :         *cor_strong_limit = 0;
     527      244591 :         move16();
     528      244591 :         *st_last_sw_dyn = mean_dyn;
     529      244591 :         move16();
     530             :     }
     531      888373 :     ELSE IF( GT_16( sub( mean_dyn, *st_last_sw_dyn ), 576 ) /*4.5f*/ )
     532             :     {
     533       37652 :         *cor_strong_limit = 1;
     534       37652 :         move16();
     535             :     }
     536     1132964 :     test();
     537     1132964 :     if ( LT_32( total_brate, ACELP_9k60 ) || GT_32( total_brate, ACELP_16k40 ) )
     538             :     {
     539     1016174 :         *cor_strong_limit = 1;
     540     1016174 :         move16();
     541             :     }
     542             : 
     543     1132964 :     *st_mean_avr_dyn = mean_dyn;
     544     1132964 :     move16();
     545             : 
     546             :     /*------------------------------------------------------------------*
     547             :      * calculation of the correlation map
     548             :      *------------------------------------------------------------------*/
     549             : 
     550     1132964 :     set16_fx( cor_map, 0, L );
     551     1132964 :     IF( N_mins > 0 )
     552             :     {
     553     1068282 :         Lcorx2 = L_deposit_l( 0 );
     554     1068282 :         Lcorxy = L_deposit_l( 0 );
     555     1068282 :         stemp = ind_mins[0];
     556     1068282 :         move16();
     557     1068282 :         Lcory2 = L_mult( old_S[stemp], old_S[stemp] );
     558     1068282 :         k = 1;
     559     1068282 :         move16();
     560             : 
     561   131948842 :         FOR( i = add( stemp, 1 ); i <= ind_mins[N_mins]; i++ )
     562             :         {
     563   130880560 :             IF( EQ_16( i, ind_mins[k] ) )
     564             :             {
     565             :                 /* include the last peak point (new minimum) to the corr. sum */
     566             : #ifdef ISSUE_1867_replace_overflow_libenc
     567    35897159 :                 Lcory2 = L_mac_sat( Lcory2, old_S[i], old_S[i] );
     568             : #else
     569             :                 Lcory2 = L_mac_o( Lcory2, old_S[i], old_S[i], &Overflow );
     570             : #endif
     571             : 
     572             :                 /* calculation of the norm. peak correlation */
     573    35897159 :                 test();
     574    35897159 :                 IF( Lcorx2 != 0 && Lcory2 != 0 )
     575             :                 {
     576             :                     /* corxy * corxy*/
     577    35688220 :                     tmp16 = sub( norm_l( Lcorxy ), 1 );
     578    35688220 :                     corxy = extract_h( L_shl( Lcorxy, tmp16 ) );
     579    35688220 :                     corxy = mult_r( corxy, corxy );
     580             :                     /* (corx2 * cory2) */
     581    35688220 :                     Expx2 = norm_l( Lcorx2 );
     582    35688220 :                     Expy2 = norm_l( Lcory2 );
     583    35688220 :                     corx2 = extract_h( L_shl( Lcorx2, Expx2 ) );
     584    35688220 :                     cory2 = extract_h( L_shl( Lcory2, Expy2 ) );
     585    35688220 :                     corx2 = mult_r( corx2, cory2 );
     586    35688220 :                     Expx2 = add( Expy2, Expx2 );
     587             :                     /* Validate num < den */
     588    35688220 :                     cor = sub( corx2, corxy );
     589    35688220 :                     cor = shr( cor, 15 );
     590             :                     /* Add 1 to tmp16 & shr by 2 if corxy > corx2 */
     591    35688220 :                     tmp16 = sub( tmp16, cor );
     592    35688220 :                     corxy = shl( corxy, cor );
     593    35688220 :                     corxy = shl( corxy, cor );
     594             :                     /* cor = corxy * corxy / (corx2 * cory2) */
     595    35688220 :                     corxy = div_s( corxy, corx2 );
     596    35688220 :                     cor = shr_sat( corxy, sub( shl( tmp16, 1 ), Expx2 ) ); /* Q15 */
     597             :                 }
     598             :                 ELSE
     599             :                 {
     600      208939 :                     cor = 0;
     601      208939 :                     move16();
     602             :                 }
     603             : 
     604             :                 /* save the norm. peak correlation in the correlation map */
     605   166777719 :                 FOR( j = ind_mins[k - 1]; j < ind_mins[k]; j++ )
     606             :                 {
     607   130880560 :                     old_S[j] = S[j];
     608   130880560 :                     move16();
     609   130880560 :                     S[j] = shr( cor, 8 );
     610   130880560 :                     move16();
     611   130880560 :                     cor_map[j] = cor;
     612   130880560 :                     move16();
     613             :                 }
     614             : 
     615    35897159 :                 Lcorx2 = L_deposit_l( 0 );
     616    35897159 :                 Lcory2 = L_deposit_l( 0 );
     617    35897159 :                 Lcorxy = L_deposit_l( 0 );
     618             : 
     619    35897159 :                 k++;
     620             :             }
     621             : #ifdef ISSUE_1867_replace_overflow_libenc
     622   130880560 :             Lcorx2 = L_mac_sat( Lcorx2, S[i], S[i] );
     623   130880560 :             Lcory2 = L_mac_sat( Lcory2, old_S[i], old_S[i] );
     624   130880560 :             Lcorxy = L_mac_sat( Lcorxy, S[i], old_S[i] );
     625             : #else
     626             :             Lcorx2 = L_mac_o( Lcorx2, S[i], S[i], &Overflow );
     627             :             Lcory2 = L_mac_o( Lcory2, old_S[i], old_S[i], &Overflow );
     628             :             Lcorxy = L_mac_o( Lcorxy, S[i], old_S[i], &Overflow );
     629             : #endif
     630             :         }
     631             : 
     632     1068282 :         Copy( S, old_S, ind_mins[0] );
     633     1068282 :         Copy( &S[ind_mins[N_mins]], &old_S[ind_mins[N_mins]], sub( L, ind_mins[N_mins] ) );
     634             :     }
     635             :     ELSE
     636             :     {
     637       64682 :         *sp_floor = Bin_E[0];
     638       64682 :         move16();
     639             :     }
     640     1132964 :     *sp_floor = mult( *sp_floor, 14231 /* 1.0f / logf( 10.0f ) in Q15 */ );
     641     1132964 :     move16(); /* Convert to log10() */
     642             : 
     643             :     /*------------------------------------------------------------------*
     644             :      * updating of the long-term correlation map
     645             :      * summation of the long-term correlation map
     646             :      *------------------------------------------------------------------*/
     647             : 
     648     1132964 :     Lcor_map_LT_sum = L_deposit_l( 0 );
     649     1132964 :     tmp2_32 = 0;
     650     1132964 :     move16();
     651             : 
     652     1132964 :     cor_strong = 0;
     653     1132964 :     move16();
     654     1132964 :     pt1 = cor_map_LT;
     655     1132964 :     move16();
     656     1132964 :     pt2 = cor_map;
     657     1132964 :     move16();
     658   146152356 :     FOR( i = 0; i < L; i++ )
     659             :     {
     660             :         /* tmp2 += S[i]; */
     661   145019392 :         tmp2_32 = L_add( tmp2_32, cor_map[i] ); /* tmp2_32 in Q15; max value is 128) */
     662             : 
     663             :         /* *pt1 = M_ALPHA_FX * *pt1 + (1-M_ALPHA_FX) * *pt2++ */
     664   145019392 :         *pt1 = mac_r( L_mult( ONE_MINUS_M_ALPHA, *pt2 ), M_ALPHA_FX, *pt1 );
     665   145019392 :         move16();
     666             : 
     667             :         /* cor_map_LT_sum += *pt1 */
     668   145019392 :         Lcor_map_LT_sum = L_add( Lcor_map_LT_sum, *pt1 ); /* cor_map_LT_sum in Q15; max value is 128) */
     669             : 
     670   145019392 :         if ( GT_16( *pt1, 31130 ) /*0.95f*/ )
     671             :         {
     672      330219 :             cor_strong = 1;
     673      330219 :             move16();
     674             :         }
     675             : 
     676   145019392 :         pt1++;
     677   145019392 :         pt2++;
     678             :     }
     679     1132964 :     tmp2 = extract_l( L_shr_sat( tmp2_32, 7 ) ); // q15-> q8
     680             : 
     681     1132964 :     IF( ( bwidth == NB ) )
     682             :     {
     683             :         /* cor_map_LT_sum *= 1.53f; */
     684             :         /* tmp2 *= 1.53f; */
     685           0 :         Lcor_map_LT_sum = L_shl( Mult_32_16( Lcor_map_LT_sum, 25068 /* 1.53f in Q14 */ ), 1 );
     686           0 :         tmp2 = round_fx( L_mac( L_mult( tmp2, 32767 ), tmp2, 17367 /* 0.53 in Q15 */ ) );
     687             :     }
     688     1132964 :     *cor_map_sum = tmp2;
     689     1132964 :     move16();
     690             : 
     691             :     /* final decision about multi-harmonicity */
     692     1132964 :     harm = 0;
     693     1132964 :     move16();
     694     1132964 :     test();
     695     1132964 :     if ( ( L_msu0( Lcor_map_LT_sum, *multi_harm_limit, 64 ) > 0 ) || ( cor_strong != 0 ) )
     696             :     {
     697      544016 :         harm = 1;
     698      544016 :         move16();
     699             :     }
     700             : 
     701             :     /*------------------------------------------------------------------*
     702             :      * updating of the decision threshold
     703             :      *------------------------------------------------------------------*/
     704             : 
     705     1132964 :     stemp = add( *multi_harm_limit, THR_CORR_STEP_FX );
     706     1132964 :     if ( GT_32( Lcor_map_LT_sum, THR_CORR_FX ) ) /* Q15 */
     707             :     {
     708             :         /* *multi_harm_limit -= THR_CORR_STEP_FX */
     709      536109 :         stemp = sub( *multi_harm_limit, THR_CORR_STEP_FX );
     710             :     }
     711             : 
     712     1132964 :     stemp = s_min( stemp, THR_CORR_MAX_FX );
     713     1132964 :     *multi_harm_limit = s_max( stemp, THR_CORR_MIN_FX );
     714     1132964 :     move16();
     715             : 
     716     1132964 :     IF( N_mins <= 0 )
     717             :     {
     718       64682 :         set16_fx( old_S, 0, L );
     719             :     }
     720     1132964 :     IF( S_map != NULL )
     721             :     {
     722     1132964 :         Copy( S, S_map, L );
     723             :     }
     724     1132964 :     return harm;
     725             : }

Generated by: LCOV version 1.14