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

Generated by: LCOV version 1.14