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

Generated by: LCOV version 1.14