LCOV - code coverage report
Current view: top level - lib_enc - pitch_ol_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 1162 1217 95.5 %
Date: 2025-09-14 03:13:15 Functions: 9 10 90.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"
       7             : #include "cnst.h"
       8             : // #include "prot_fx.h"
       9             : #include "basop_util.h"
      10             : #include "rom_com_fx.h"
      11             : #include "rom_com.h"
      12             : #include "rom_enc.h"
      13             : #include "prot_fx.h"     /* Function prototypes                    */
      14             : #include "prot_fx_enc.h" /* Function prototypes                    */
      15             : 
      16             : /*-----------------------------------------------------------------*
      17             :  * Local Constants
      18             :  *-----------------------------------------------------------------*/
      19             : #define PIT_MIN2   20 /* pit_min for pitch tracking                                                  */
      20             : #define PIT_MIN_1  44 /* for second pitch track */
      21             : #define PIT_MIN2_1 24
      22             : 
      23             : #define THR_relE -2816 /* -11 (Q8) */
      24             : 
      25             : #define THRES0 4792 /* Threshold to favor smaller pitch lags; 1.17 (Q12) */
      26             : #define DELTA0 2    /* multiples' search range initial    */
      27             : #define STEP   1    /* multiples' search range increment  */
      28             : 
      29             : #define THRES1    13107 /* Threshold to favor pitch lags coherence for neighbours; 0.4 (Q15) */
      30             : #define DELTA_COH 14    /* Maximum pitch lags difference for neighbours to be considered as coherent */
      31             : #define THRES3    22938 /* Threshold to favor pitch lags coherence with previous frames; 0.7 (Q15) */
      32             : 
      33             : #define CORR_TH0 13107 /* Noise threshold for past frame correlations; 0.4 (Q15) */
      34             : #define CORR_TH1 16384 /* Noise threshold for past frame correlations; 0.5 (Q15) */
      35             : 
      36             : #define LEN_X   ( ( PIT_MAX / OPL_DECIM ) - ( PIT_MIN2 / OPL_DECIM ) + 1 ) /* Correlation buffer length */
      37             : #define COH_FAC 5734                                                       /* Factor for measuring the pitch coherence; 1.4 (Q12) */
      38             : 
      39             : #define NSUBSECT 7
      40             : #define NSECT    4
      41             : #define NHFR     3
      42             : #define L_FIR_PO 5
      43             : #define L_MEM    ( L_FIR_PO - 2 )
      44             : 
      45             : 
      46             : /*-----------------------------------------------------------------*
      47             :  * Local function prototypes
      48             :  *-----------------------------------------------------------------*/
      49             : 
      50             : static void LP_Decim2_Copy( const Word16 x[], Word16 y[], Word16 l, Word16 mem[] );
      51             : 
      52             : static void pitch_neighbour_fx( Word16 sect0, Word16 pitch_tmp[], Word16 pitch[3][2 * NSECT], Word16 corr_tmp[], Word16 corr[3][2 * NSECT], Word16 thres1[2 * NHFR], Word16 ind_tmp[2 * NHFR] );
      53             : 
      54             : static void find_mult_fx( Word16 *fac, Word16 pitch0, Word16 pitch1, Word16 pit_max0, Word16 *corr, Word16 *old_pitch, Word16 *old_corr, Word16 delta, Word16 step );
      55             : 
      56             : static Word16 pitch_coherence_fx( Word16 pitch0, Word16 pitch1, Word16 fac_max, Word16 diff_max );
      57             : 
      58             : static Word32 Dot_product12_OL( Word16 *sum1, const Word16 x[], const Word16 y[], const Word16 lg, const Word16 lg2, Word16 *exp, Word16 *exp2 );
      59             : 
      60             : static Word32 Dot_product12_OL_back( Word16 *sum1, const Word16 x[], const Word16 y[], const Word16 lg, const Word16 lg2, Word16 *exp, Word16 *exp2 );
      61             : 
      62             : /*-----------------------------------------------------------------*
      63             :  * pitch_ol_init()
      64             :  *
      65             :  * Open loop pitch variable initialization
      66             :  *-----------------------------------------------------------------*/
      67      157207 : void pitch_ol_init_fx(
      68             :     Word16 *old_thres, /* o  : threshold for reinforcement of past pitch influence */
      69             :     Word16 *old_pitch, /* o  : pitch  of the 2nd half-frame of previous frame      */
      70             :     Word16 *delta_pit, /* o  : pitch evolution extrapolation                       */
      71             :     Word16 *old_corr   /* o  : correlation                                         */
      72             : )
      73             : {
      74      157207 :     *old_thres = 0;
      75      157207 :     move16();
      76      157207 :     *old_pitch = 0;
      77      157207 :     move16();
      78      157207 :     *delta_pit = 0;
      79      157207 :     move16();
      80      157207 :     *old_corr = 0;
      81      157207 :     move16();
      82      157207 : }
      83             : 
      84             : 
      85             : /*==================================================================================*/
      86             : /* FUNCTION : pitch_ol_fx()                                       */
      87             : /*----------------------------------------------------------------------------------*/
      88             : /* PURPOSE :
      89             :  * Compute the open loop pitch lag.
      90             :  *
      91             :  * The pitch lag search is divided into two sets.
      92             :  * Each set is divided into three sections.
      93             :  * Each section cannot have a pitch multiple.
      94             :  * We find a maximum for each section.
      95             :  * We compare the maxima of each section.
      96             :  *
      97             :  *                               1st set              2nd set
      98             :  * 1st section: lag delay =  115 down to 62  and  115 down to 78
      99             :  * 2nd section: lag delay =   61 down to 32  and   77 down to 41
     100             :  * 3rd section: lag delay =   31 down to 17  and   40 down to 22
     101             :  * 4th section: lag delay =   16 down to 10  and   21 down to 12
     102             :  *
     103             :  * As there is a margin between section overlaps, especially for
     104             :  * longer delays, this section selection is more robust for not
     105             :  * to find multiples in the same section when pitch evolves rapidly.
     106             :  *
     107             :  * For each section, the length of the vectors to correlate is
     108             :  * greater/equal to the longest pitch delay.                                        */
     109             : /*----------------------------------------------------------------------------------*/
     110             : /*  INPUT ARGUMENTS :                                    */
     111             : /* _ (Word16[]) old_pitch    : OL pitch of the 2nd half-frame of the last frame Q0 */
     112             : /* _ (Word16[]) old_corr_fx    : correlation                                  Q15 */
     113             : /* _ (Word16[]) corr_shift_fx : normalized correlation correction               Q15 */
     114             : /* _ (Word16[]) old_thres_fx  : maximum correlation weighting with respect          */
     115             : /*                              to past frame pitch                             Q15 */
     116             : /* _ (Word16[]) delta_pit    : old pitch extrapolation correction               Q0 */
     117             : /* _ (Word16[]) st_old_wsp2_fx: weighted speech memory                         qwsp */
     118             : /* _ (Word16[]) wsp_fx      : weighted speech for current frame & look-ahead qwsp */
     119             : /* _ (Word16[]) mem_decim2_fx : wsp decimation filter memory                   qwsp */
     120             : /* _ (Word16[]) relE_fx      : relative frame energy                            Q8 */
     121             : /* _ (Word16[]) L_look      : look-ahead                                       Q0 */
     122             : /* _ (Word16[]) Opt_SC_VBR    : SC-VBR flag                                      Q0 */
     123             : /* _ (Word16*) qwsp        : wsp & filter memory Qformat                */
     124             : /*----------------------------------------------------------------------------------*/
     125             : /* OUTPUT ARGUMENTS :                                  */
     126             : /* _ (Word16[]) pitch        : open loop pitch lag for each half-frame          Q0 */
     127             : /* _ (Word16[]) T_op          : open loop pitch lag for each half-frm for quant  Q0 */
     128             : /* _ (Word16[]) voicing_fx    : max normalized correlation for each half-frame  QIn */
     129             : /* _ (Word16[]) old_pitch    : OL pitch of the 2nd half-frame of the last frame Q0 */
     130             : /* _ (Word16[]) old_corr_fx    : correlation                                  Q15 */
     131             : /* _ (Word16[]) old_thres_fx  : maximum correlation weighting with respect          */
     132             : /*                              to past frame pitch                             Q15 */
     133             : /* _ (Word16[]) delta_pit    : old pitch extrapolation correction               Q0 */
     134             : /* _ (Word16[]) st_old_wsp2_fx: weighted speech memory                         qwsp */
     135             : /* _ (Word16[]) mem_decim2_fx : wsp decimation filter memory                   qwsp */
     136             : /*----------------------------------------------------------------------------------*/
     137             : 
     138             : /*----------------------------------------------------------------------------------*/
     139             : /* RETURN ARGUMENTS :                                  */
     140             : /* _ None                                        */
     141             : /*==================================================================================*/
     142             : 
     143        3100 : void pitch_ol_fx(
     144             :     Word16 pitch[3],         /* o  : open loop pitch lag for each half-frame in range [29,231]      Q0  */
     145             :     Word16 voicing[3],       /* o  : maximum normalized correlation for each half-frame in [0,1.0[  Q15 */
     146             :     Word16 *old_pitch,       /* i/o: pitch of the 2nd half-frame of previous frame (i.e. pitch[1])  Q0  */
     147             :     Word16 *old_corr,        /* i/o: correlation of old_pitch (i.e. voicing[1] or corr_mean)        Q15 */
     148             :     Word16 corr_shift,       /* i  : normalized correlation correction                              Q15 */
     149             :     Word16 *old_thres,       /* i/o: maximum correlation weighting with respect to past frame pitch Q15 */
     150             :     Word16 *delta_pit,       /* i/o: old pitch extrapolation correction in range [-14,+14]          Q0  */
     151             :     Word16 *st_old_wsp2,     /* i/o: weighted speech memory                                         qwsp */
     152             :     const Word16 *wsp,       /* i  : weighted speech for current frame and look-ahead               qwsp */
     153             :     Word16 mem_decim2[3],    /* i/o: wsp decimation filter memory                                   qwsp */
     154             :     const Word16 relE,       /* i  : relative frame energy                                          Q8  */
     155             :     const Word16 last_class, /* i  : frame classification of last frame                                 */
     156             :     const Word16 bwidth,     /* i  : bandwidth                                                          */
     157             :     const Word16 Opt_SC_VBR  /* i  : SC-VBR flag                                                        */
     158             : )
     159             : {
     160             :     Word16 ftmp, old_wsp2[( L_WSP - L_INTERPOL ) / OPL_DECIM], *wsp2;
     161             :     Word16 tmp_mem[3];
     162             : 
     163             :     Word16 scale1[2 * DELTA_COH - 1];
     164             :     Word16 scaled_buf[2 * LEN_X + 3 * ( DELTA_COH - 1 )];
     165             :     Word16 scaled_buf_exp[2 * LEN_X + 3 * ( DELTA_COH - 1 )], exp_sect[8], exp_sect1[8], exp_sect0;
     166             :     Word16 cor_buf[2 * LEN_X];
     167             :     Word16 *pt_exp1, *pt_exp2, *pt_exp3, *pt_exp4;
     168             :     Word16 *pt1, *pt2, *pt3, *pt4, *pt5, *pt6;
     169             :     Word16 *pt_cor0, *pt_cor1, *pt_cor2, *pt_cor3, *pt_cor4, *pt_cor5, *pt_cor6;
     170             :     Word16 thres1[6];
     171             :     Word16 diff, cnt, ind, ind1, offset, offset1, offset_la, offset_la1, coh_flag, coh_flag1;
     172             :     Word16 ind_corX, ind1_corX;
     173             : 
     174             :     Word16 i, j, k, m, pit_min, pit_min1, sect0, subsect0, add_sect0, sub_sect0, old_tmp, old_tmp1, len_x, len_x1;
     175             :     Word16 len_temp;
     176             :     Word16 pitchX[NHFR][2 * NSECT], pitch_tmp[2 * NHFR], ind_tmp[2 * NHFR], tmp_buf[NHFR + 1];
     177             : 
     178             :     Word16 enr0[NSECT], enr0_exp[NSECT], enr0_1[NSECT], enr0_1_exp[NSECT], enr1, enr1_exp, enr2_exp;
     179             :     Word32 enr, enr2, Ltmp;
     180             :     Word16 fac, tmp16, tmp16_2;
     181             :     Word16 qCorX, qScaledX;
     182             :     Word16 scaledX[NHFR][2 * NSECT], corX[NHFR][2 * NSECT], cor_tmp[2 * NHFR], cor_mean;
     183             :     const Word16 *len, *len1, *sublen, *sublen1, *pit_max, *sec_length, *sec_length1;
     184             : 
     185             :     Word16 pit_min_coding;
     186             : #ifndef ISSUE_1867_replace_overflow_libenc
     187             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     188             :     Flag Overflow = 0;
     189             : #endif
     190             : #endif
     191             : 
     192             :     /*--------------------------------------------------------------*
     193             :      * Initialization
     194             :      *--------------------------------------------------------------*/
     195        3100 :     len = len_12k8;
     196        3100 :     len1 = len1_12k8;
     197        3100 :     sublen = sublen_12k8;
     198        3100 :     sublen1 = sublen1_12k8;
     199        3100 :     pit_max = pit_max_12k8;
     200        3100 :     sec_length = sec_length_12k8;
     201        3100 :     sec_length1 = sec_length1_12k8;
     202             : 
     203        3100 :     test();
     204        3100 :     if ( ( LT_16( last_class, VOICED_TRANSITION ) ) && ( NE_16( bwidth, NB ) ) )
     205             :     {
     206             :         /*reset last pitch reinforcement in case of unvoiced or transitions: it avoids some pitch doublings*/
     207        1560 :         *old_thres = 0;
     208        1560 :         move16();
     209             :     }
     210             : 
     211        3100 :     pit_min_coding = PIT_MIN_EXTEND;
     212        3100 :     move16();
     213        3100 :     test();
     214        3100 :     test();
     215        3100 :     test();
     216        3100 :     test();
     217        3100 :     IF( ( ( NE_16( bwidth, NB ) ) && ( GT_16( *old_pitch, PIT_MIN ) ) ) ||
     218             :         ( ( EQ_16( bwidth, NB ) ) && ( ( GT_16( *old_pitch, PIT_MIN2_1 ) ) || ( LT_16( *old_thres, 3277 ) ) ) ) ) /* 0.1 inQ15*/
     219             :     {
     220        1306 :         pit_min = PIT_MIN / OPL_DECIM;
     221        1306 :         move16();
     222        1306 :         pit_min1 = PIT_MIN_1 / OPL_DECIM;
     223        1306 :         move16();
     224        1306 :         subsect0 = 2;
     225        1306 :         move16();
     226        1306 :         sect0 = 1;
     227        1306 :         move16();
     228             :     }
     229             :     ELSE
     230             :     {
     231        1794 :         pit_min = PIT_MIN2 / OPL_DECIM;
     232        1794 :         move16();
     233        1794 :         pit_min1 = PIT_MIN2_1 / OPL_DECIM;
     234        1794 :         move16();
     235        1794 :         subsect0 = 0;
     236        1794 :         move16();
     237        1794 :         sect0 = 0;
     238        1794 :         move16();
     239             :     }
     240             : 
     241        3100 :     len_x = ( PIT_MAX / OPL_DECIM - pit_min + 1 );
     242        3100 :     move16();
     243        3100 :     len_x1 = ( PIT_MAX / OPL_DECIM - pit_min1 + 1 );
     244        3100 :     move16();
     245             : 
     246             :     /*--------------------------------------------------------------*
     247             :      * Find decimated weighted speech
     248             :      * Update wsp buffer with the memory
     249             :      * decimation of wsp[] to search pitch in LF and to reduce complexity
     250             :      * Extend the decimation of wsp to the end of the speech buffer
     251             :      * Update wsp memory
     252             :      *--------------------------------------------------------------*/
     253        3100 :     Copy( st_old_wsp2, old_wsp2, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM );
     254        3100 :     wsp2 = old_wsp2 + ( ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM );
     255             : 
     256        3100 :     LP_Decim2_Copy( wsp, wsp2, L_FRAME, mem_decim2 );
     257             : 
     258             :     /* Avoid uninitialized memory access */
     259        3100 :     set16_fx( wsp2 + L_FRAME / 2, 0, sizeof( old_wsp2 ) / sizeof( Word16 ) - ( ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ) - L_FRAME / 2 );
     260        3100 :     tmp_mem[0] = mem_decim2[0];
     261        3100 :     move16();
     262        3100 :     tmp_mem[1] = mem_decim2[1];
     263        3100 :     move16();
     264        3100 :     tmp_mem[2] = mem_decim2[2];
     265        3100 :     move16();
     266             : 
     267        3100 :     LP_Decim2_Copy( &wsp[L_FRAME], &wsp2[( L_FRAME / 2 )], L_LOOK_12k8, tmp_mem ); /* shr() used instead of division by OPL_DECIM*/
     268             : 
     269        3100 :     Copy( &old_wsp2[L_FRAME / 2], st_old_wsp2, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM );
     270             : 
     271             :     /*-----------------------------------------------------------------*
     272             :      * Attenuate the correlation correction factor due to noise.
     273             :      * Reset correlation buffer outside the useful range.
     274             :      * Find the scaling functions for immediate neigbours and
     275             :      * further ones.
     276             :      *-----------------------------------------------------------------*/
     277             : 
     278        3100 :     corr_shift = shr( corr_shift, 1 );
     279             : 
     280        3100 :     set16_fx( scaled_buf, 0, DELTA_COH - 1 );
     281        3100 :     set16_fx( scaled_buf + ( DELTA_COH - 1 ) + len_x, 0, DELTA_COH - 1 );
     282        3100 :     set16_fx( scaled_buf + 2 * ( DELTA_COH - 1 ) + len_x + len_x1, 0, DELTA_COH - 1 );
     283        3100 :     set16_fx( scaled_buf_exp, 0, len_x + len_x1 + 3 * ( DELTA_COH - 1 ) );
     284             : 
     285        3100 :     pt1 = scale1 + DELTA_COH - 1;
     286        3100 :     pt2 = pt1;
     287        3100 :     tmp16 = mult( negate( *old_thres ), MAX_16 / DELTA_COH );
     288        3100 :     k = *old_thres;
     289        3100 :     move16();
     290       46500 :     FOR( i = 0; i < DELTA_COH; i++ )
     291             :     {
     292             :         /*
     293             :          * *pt1 = ( -(*old_thres)/DELTA_COH * i + *old_thres+1.0f );
     294             :          * To keep Q15 values, the following code does not add 1 to the result.
     295             :          * A scaling factor must be applied accordingly (see next use of scale1)
     296             :          */
     297       43400 :         *pt1 = k;
     298       43400 :         move16();
     299       43400 :         k = add( k, tmp16 );
     300       43400 :         *pt2-- = *pt1++;
     301       43400 :         move16();
     302             :     }
     303             : 
     304             :     /*-----------------------------------------------------------------------------*
     305             :      * Estimate the new pitch by extrapolating the old pitch value for 2 half-frames
     306             :      *-----------------------------------------------------------------------------*/
     307        3100 :     old_tmp = add( *old_pitch, *delta_pit );
     308        3100 :     old_tmp = s_min( old_tmp, PIT_MAX / OPL_DECIM );
     309        3100 :     old_tmp = s_max( old_tmp, pit_min );
     310        3100 :     old_tmp1 = add( old_tmp, *delta_pit );
     311        3100 :     old_tmp1 = s_min( old_tmp1, PIT_MAX / OPL_DECIM );
     312        3100 :     old_tmp1 = s_max( old_tmp1, pit_min );
     313             : 
     314             :     /*-----------------------------------------------------------------*
     315             :      * Loop for all three half-frames (current frame + look-ahead)
     316             :      *-----------------------------------------------------------------*/
     317        3100 :     pt_cor0 = scaled_buf + DELTA_COH - 1;
     318             : 
     319        3100 :     pt_cor2 = pt_cor0 - pit_min + old_tmp;
     320        3100 :     pt_cor4 = pt_cor0 - pit_min1 + old_tmp + ( DELTA_COH - 1 ) + len_x;
     321             : 
     322       12400 :     FOR( i = 0; i < NHFR; i++ ) /* i = 0, 1, 2 */
     323             :     {
     324        9300 :         pt1 = wsp2 + i * 2 * ( L_SUBFR / OPL_DECIM ); /* *pt1 -> Q12 */
     325        9300 :         pt2 = pt1 - pit_min;                          /* *pt2 -> Q12 */
     326        9300 :         pt4 = pt1 - pit_min1;                         /* *pt4 -> Q12 */
     327             : 
     328        9300 :         enr = L_deposit_l( 1 );
     329             : 
     330        9300 :         pt_cor1 = pt_cor0;
     331        9300 :         pt_cor3 = pt_cor0 + ( DELTA_COH - 1 ) + len_x;
     332             : 
     333        9300 :         pt_exp1 = scaled_buf_exp + DELTA_COH - 1;
     334        9300 :         pt_exp2 = pt_exp1;
     335        9300 :         pt_exp3 = scaled_buf_exp + 2 * ( DELTA_COH - 1 ) + len_x;
     336        9300 :         pt_exp4 = pt_exp3;
     337             : 
     338        9300 :         IF( LT_16( i, NHFR - 1 ) ) /* First two half-frames (current frame) */
     339             :         {
     340        6200 :             pt3 = pt1;
     341        6200 :             pt5 = pt1;
     342             : 
     343       28388 :             FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */
     344             :             {
     345             :                 /*-----------------------------------------------------------------*
     346             :                  * Find fixed vector energy
     347             :                  *-----------------------------------------------------------------*/
     348             : 
     349             :                 /* 1st set */
     350       22188 :                 k = (Word16) ( pt1 - pt3 );
     351       22188 :                 move16();
     352             : 
     353      735188 :                 FOR( k = add( k, len[j] ); k > 0; k-- )
     354             :                 {
     355      713000 :                     enr = L_mac0( enr, *pt3, *pt3 );
     356      713000 :                     pt3++;
     357             :                 }
     358             :                 /* keep Q15 normalized result */
     359       22188 :                 cnt = norm_l( enr );
     360       22188 :                 enr0[j] = extract_h( L_shl( enr, cnt ) );
     361       22188 :                 enr0_exp[j] = sub( 30, cnt );
     362       22188 :                 move16();
     363             : 
     364             :                 /* Reduce complexity (length of 'enr2' section is equal or larger than 'enr') */
     365       22188 :                 pt5 = pt3;
     366       22188 :                 enr2 = enr; /* sets to 'enr' in 1 clock */
     367       22188 :                 move32();
     368             : 
     369             :                 /* 2nd set */
     370       22188 :                 k = (Word16) ( pt1 - pt5 );
     371       22188 :                 move16();
     372             : 
     373      195788 :                 FOR( k = add( k, len1[j] ); k > 0; k-- )
     374             :                 {
     375      173600 :                     enr2 = L_mac0( enr2, *pt5, *pt5 );
     376      173600 :                     pt5++;
     377             :                 }
     378       22188 :                 cnt = norm_l( enr2 );
     379       22188 :                 enr0_1[j] = extract_h( L_shl( enr2, cnt ) );
     380       22188 :                 enr0_1_exp[j] = sub( 30, cnt );
     381       22188 :                 move16();
     382             :             }
     383             : 
     384             :             /*----------------------------------------------------------*
     385             :              * Find correlation for the non-overlapping pitch lag values
     386             :              *----------------------------------------------------------*/
     387        6200 :             exp_sect[subsect0] = 0;
     388        6200 :             move16();
     389        6200 :             pt_cor5 = pt_cor1;
     390        6200 :             pt_cor6 = pt_cor3;
     391             : 
     392        6200 :             tmp16 = exp_sect[subsect0];
     393        6200 :             move16();
     394             : 
     395        6200 :             k = (Word16) ( pt2 - pt1 + pit_max[subsect0] );
     396             : 
     397        6200 :             IF( k >= 0 )
     398             :             {
     399        6200 :                 len_temp = sublen[0];
     400        6200 :                 move16();
     401             : 
     402       26436 :                 FOR( ; k >= 0; k-- )
     403             :                 {
     404             :                     /* Keep Q15 normalized result */
     405             :                     /* shr by 1 to make room for scaling in the neighbourhood of the extrapolated pitch */
     406             :                     /* Update exponent to reflect shr by 1 */
     407       20236 :                     *pt_cor1 = extract_h( L_shr( Dot_product12( pt1, pt2--, len_temp, pt_exp1 ), 1 ) );
     408             : 
     409             :                     /* save the biggest exponent */
     410       20236 :                     tmp16 = s_max( tmp16, *pt_exp1 );
     411             : 
     412       20236 :                     pt_cor1++;
     413       20236 :                     pt_exp1++;
     414             :                 }
     415             :             }
     416        6200 :             exp_sect[subsect0] = tmp16;
     417        6200 :             move16();
     418             : 
     419             :             /*----------------------------------------------------------*
     420             :              * For each subsection, find the correlation
     421             :              *----------------------------------------------------------*/
     422       44376 :             FOR( j = subsect0; j < NSUBSECT; j++ )
     423             :             {
     424       38176 :                 len_temp = sublen[j];
     425       38176 :                 move16();
     426             : 
     427       38176 :                 k = (Word16) ( pt2 - pt1 );
     428       38176 :                 move16();
     429       38176 :                 k = add( k, pit_max[j + 1] );
     430       38176 :                 exp_sect[j + 1] = 0;
     431       38176 :                 move16();
     432       38176 :                 exp_sect1[j] = 0;
     433       38176 :                 move16();
     434             : 
     435       38176 :                 IF( k >= 0 )
     436             :                 {
     437       38176 :                     ind = exp_sect[j + 1];
     438       38176 :                     move16();
     439       38176 :                     ind1 = exp_sect1[j];
     440       38176 :                     move16();
     441             : 
     442      656856 :                     FOR( ; k >= 0; k-- )
     443             :                     {
     444             :                         /* Keep Q15 normalized result */
     445             :                         /* shr by 1 to make room for scaling in the neighbourhood of the extrapolated pitch */
     446             :                         /* Update exponent to reflect shr by 1 (done in Dot_product12_OL() for pt_cor3/pt_exp3) */
     447      618680 :                         *pt_cor1 = extract_h( L_shr( Dot_product12_OL( pt_cor3, pt1, pt2--, sublen[j], sublen1[j], pt_exp1, pt_exp3 ), 1 ) );
     448             :                         /* The line above replaces:
     449             :                          * *pt_cor1 = shr(extract_h(Dot_product12(pt1, pt2, Sublen[j], pt_exp1)),1); move16();
     450             :                          * *pt_cor3 = shr(extract_h(Dot_product12(pt1, pt2--, Sublen1[j+i*7], pt_exp3)),1); move16();
     451             :                          */
     452             : 
     453             :                         /* save the biggest exponent */
     454      618680 :                         ind = s_max( ind, *pt_exp1 );
     455      618680 :                         ind1 = s_max( ind1, *pt_exp3 );
     456             : 
     457      618680 :                         pt_cor1++;
     458      618680 :                         pt_exp1++;
     459      618680 :                         pt_cor3++;
     460      618680 :                         pt_exp3++;
     461             :                     }
     462       38176 :                     exp_sect[j + 1] = ind;
     463       38176 :                     move16();
     464       38176 :                     exp_sect1[j] = ind1;
     465       38176 :                     move16();
     466             :                 } /* IF (k >= 0) */
     467             :             }     /* FOR (j = subsect0; ... */
     468             :         }
     469             :         ELSE /* 3rd half-frame (look-ahead) */
     470             :         {
     471        3100 :             pt6 = pt1 + L_LOOK_12k8 / OPL_DECIM - 1;
     472        3100 :             pt3 = pt6;
     473        3100 :             pt5 = pt6;
     474             : 
     475             :             /*-----------------------------------------------------------------*
     476             :              * For each section in both sets, find fixed vector energy
     477             :              *-----------------------------------------------------------------*/
     478             : 
     479       14194 :             FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */
     480             :             {
     481             :                 /* 1st set */
     482       11094 :                 k = (Word16) ( pt3 - pt6 );
     483       11094 :                 move16();
     484             : 
     485      367594 :                 FOR( k = add( k, len[j] ); k > 0; k-- )
     486             :                 {
     487      356500 :                     enr = L_mac0( enr, *pt3, *pt3 );
     488      356500 :                     pt3--;
     489             :                 }
     490             : 
     491       11094 :                 cnt = norm_l( enr );
     492       11094 :                 enr0[j] = extract_h( L_shl( enr, cnt ) ); /*qwsp+cnt-16*/
     493       11094 :                 enr0_exp[j] = sub( 30, cnt );
     494       11094 :                 move16();
     495             : 
     496             :                 /* Reduce complexity (length of 'enr2' section is equal or larger than 'enr') */
     497       11094 :                 pt5 = pt3;
     498       11094 :                 enr2 = enr;
     499       11094 :                 move16();
     500             : 
     501             :                 /* 2nd set */
     502       11094 :                 k = (Word16) ( pt5 - pt6 );
     503       11094 :                 move16();
     504             : 
     505       97894 :                 FOR( k = add( k, len1[j] ); k > 0; k-- )
     506             :                 {
     507       86800 :                     enr2 = L_mac0( enr2, *pt5, *pt5 );
     508       86800 :                     pt5--;
     509             :                 }
     510             : 
     511       11094 :                 cnt = norm_l( enr2 );
     512       11094 :                 enr0_1[j] = extract_h( L_shl( enr2, cnt ) ); /*qwsp+cnt-16*/
     513       11094 :                 enr0_1_exp[j] = sub( 30, cnt );
     514       11094 :                 move16();
     515             :             }
     516             : 
     517             :             /* Set pointers */
     518        3100 :             IF( sect0 != 0 )
     519             :             {
     520        1306 :                 pt2 = pt6 - add( pit_max[1], 1 );
     521        1306 :                 k = sub( pit_max[2], pit_max[1] );
     522        1306 :                 move16();
     523             :             }
     524             :             ELSE
     525             :             {
     526        1794 :                 pt2 = pt6 - pit_min;
     527        1794 :                 k = 2;
     528        1794 :                 move16();
     529             :             }
     530             : 
     531             :             /*-----------------------------------------------------------------*
     532             :              * Find correlation for the non-overlapping pitch lag values
     533             :              *-----------------------------------------------------------------*/
     534        3100 :             exp_sect[subsect0] = 0;
     535        3100 :             move16();
     536        3100 :             pt_cor5 = pt_cor1;
     537        3100 :             pt_cor6 = pt_cor3;
     538             : 
     539        3100 :             tmp16 = exp_sect[subsect0];
     540        3100 :             move16();
     541             : 
     542        3100 :             IF( k > 0 )
     543             :             {
     544        3100 :                 len_temp = sublen[0];
     545        3100 :                 move16();
     546             : 
     547       13218 :                 FOR( ; k > 0; k-- )
     548             :                 {
     549             :                     /* Following lines are equivalent of Dot_product12() but with a backward incrementing */
     550       10118 :                     Ltmp = L_deposit_l( 1 );
     551      414838 :                     FOR( m = 0; m < len_temp; m++ )
     552             :                     {
     553      404720 :                         Ltmp = L_mac( Ltmp, pt6[-m], pt2[-m] );
     554             :                     }
     555             : 
     556             :                     /* Normalize acc in Q31 */
     557       10118 :                     tmp16_2 = norm_l( Ltmp );
     558       10118 :                     Ltmp = L_shl( Ltmp, tmp16_2 );
     559       10118 :                     *pt_exp1 = sub( 30, tmp16_2 );
     560       10118 :                     move16(); /* exponent = 0..30 */
     561             : 
     562             :                     /* Save result */
     563       10118 :                     *pt_cor1 = extract_h( L_shr( Ltmp, 1 ) );
     564             : 
     565             :                     /* Save the biggest exponent */
     566       10118 :                     tmp16 = s_max( tmp16, *pt_exp1 );
     567             : 
     568       10118 :                     pt_cor1++;
     569       10118 :                     pt_exp1++;
     570       10118 :                     pt2--;
     571             :                 }
     572        3100 :                 exp_sect[subsect0] = tmp16;
     573        3100 :                 move16();
     574             :             }
     575             : 
     576             :             /*-----------------------------------------------------------------*
     577             :              * For each subsection, find the correlation (overlapping pitch lag values)
     578             :              *-----------------------------------------------------------------*/
     579             : 
     580       22188 :             FOR( j = subsect0; j < NSUBSECT; j++ )
     581             :             {
     582       19088 :                 exp_sect[j + 1] = 0;
     583       19088 :                 move16();
     584       19088 :                 exp_sect1[j] = 0;
     585       19088 :                 move16();
     586             : 
     587       19088 :                 ind = exp_sect[j + 1];
     588       19088 :                 move16();
     589       19088 :                 ind1 = exp_sect1[j];
     590       19088 :                 move16();
     591             : 
     592       19088 :                 k = sub( pit_max[j + 1], pit_max[j] );
     593             : 
     594      328428 :                 FOR( ; k > 0; k-- )
     595             :                 {
     596      309340 :                     *pt_cor1 = extract_h( L_shr( Dot_product12_OL_back( pt_cor3, pt6, pt2--, sublen[j], sublen1[j], pt_exp1, pt_exp3 ), 1 ) );
     597             : 
     598             :                     /* Save the biggest exponent */
     599      309340 :                     ind = s_max( ind, *pt_exp1 );
     600      309340 :                     ind1 = s_max( ind1, *pt_exp3 );
     601             : 
     602      309340 :                     pt_cor1++;
     603      309340 :                     pt_exp1++;
     604      309340 :                     pt_cor3++;
     605      309340 :                     pt_exp3++;
     606             :                 }
     607       19088 :                 exp_sect[j + 1] = ind;
     608       19088 :                 move16();
     609       19088 :                 exp_sect1[j] = ind1;
     610       19088 :                 move16();
     611             :             }
     612             :         } /* 3rd half-frame (look-ahead) */
     613             : 
     614             :         /* Scale all values in each section to the same exponent for upcoming Find_max() */
     615        9300 :         offset = 0;
     616        9300 :         move16();
     617        9300 :         offset1 = 0;
     618        9300 :         move16();
     619        9300 :         exp_sect1[7] = 0; /* padding */
     620        9300 :         move16();
     621       42582 :         FOR( j = sect0; j < NSECT; j++ )
     622             :         {
     623       33282 :             exp_sect0 = s_max( exp_sect[j * 2], exp_sect[j * 2 + 1] );
     624             : 
     625             :             /* scaling of exp for track 1 */
     626       33282 :             offset = add( offset, sec_length[j] );
     627       33282 :             k = (Word16) ( pt_cor0 - pt_cor5 );
     628       33282 :             move16();
     629      991656 :             FOR( k = add( k, offset ); k > 0; k-- )
     630             :             {
     631      958374 :                 cnt = sub( exp_sect0, *pt_exp2 );
     632      958374 :                 tmp16 = s_min( 15, cnt );
     633      958374 :                 if ( cnt > 0 )
     634             :                 {
     635      714208 :                     tmp16 = shr( *pt_cor5, tmp16 );
     636             :                 }
     637      958374 :                 if ( cnt > 0 )
     638             :                 {
     639      714208 :                     *pt_cor5 = tmp16;
     640      714208 :                     move16();
     641             :                 }
     642      958374 :                 *pt_exp2 = s_max( *pt_exp2, exp_sect0 );
     643      958374 :                 move16();
     644      958374 :                 pt_cor5++;
     645      958374 :                 pt_exp2++;
     646             :             }
     647             : 
     648       33282 :             exp_sect0 = s_max( exp_sect1[j * 2], exp_sect1[j * 2 + 1] );
     649             : 
     650             :             /* scaling of exp for track 2 */
     651       33282 :             offset1 = add( offset1, sec_length1[j] );
     652       33282 :             k = (Word16) ( pt_cor0 - pt_cor6 + ( DELTA_COH - 1 ) );
     653       33282 :             move16();
     654       33282 :             k = add( k, len_x );
     655      961302 :             FOR( k = add( k, offset1 ); k > 0; k-- )
     656             :             {
     657      928020 :                 cnt = sub( exp_sect0, *pt_exp4 );
     658      928020 :                 tmp16 = s_min( 15, cnt );
     659      928020 :                 if ( cnt > 0 )
     660             :                 {
     661      685758 :                     tmp16 = shr( *pt_cor6, tmp16 );
     662             :                 }
     663      928020 :                 if ( cnt > 0 )
     664             :                 {
     665      685758 :                     *pt_cor6 = tmp16;
     666      685758 :                     move16();
     667             :                 }
     668      928020 :                 *pt_exp4 = s_max( *pt_exp4, exp_sect0 );
     669      928020 :                 move16();
     670      928020 :                 pt_cor6++;
     671      928020 :                 pt_exp4++;
     672             :             }
     673             :         } /* FOR (j = sect0; ... */
     674             : 
     675        9300 :         Copy( pt_cor0, cor_buf, len_x ); /* Save unscaled correlation vector  */
     676        9300 :         Copy( pt_cor0 + ( DELTA_COH - 1 ) + len_x, cor_buf + len_x, len_x1 );
     677             : 
     678             :         /*-----------------------------------------------------------------*
     679             :          * Scale correlation function in the neighbourhood of
     680             :          * the extrapolated pitch
     681             :          *-----------------------------------------------------------------*/
     682        9300 :         pt_cor1 = pt_cor2 - ( DELTA_COH - 1 );
     683        9300 :         pt_cor3 = pt_cor4 - ( DELTA_COH - 1 );
     684        9300 :         pt2 = scale1;
     685             : 
     686      260400 :         FOR( k = 0; k < 2 * DELTA_COH - 1; k++ )
     687             :         {
     688             :             /* all Q15 here */
     689      251100 :             *pt_cor1 = add( *pt_cor1, mult( *pt_cor1, *pt2 ) );
     690      251100 :             move16();
     691      251100 :             *pt_cor3 = add( *pt_cor3, mult( *pt_cor3, *pt2++ ) );
     692      251100 :             move16();
     693             : 
     694      251100 :             pt_cor1++;
     695      251100 :             pt_cor3++;
     696             :         }
     697             : 
     698             :         /* Update for next half-frame & look-ahead */
     699        9300 :         pt_cor2 = pt_cor0 - pit_min + old_tmp1;
     700        9300 :         pt_cor4 = pt_cor0 - pit_min1 + old_tmp1 + ( DELTA_COH - 1 ) + len_x;
     701             : 
     702             :         /*-----------------------------------------------------------------*
     703             :          * For each section, find maximum correlation and compute
     704             :          * normalized correlation
     705             :          *-----------------------------------------------------------------*/
     706             : 
     707        9300 :         pt_cor1 = pt_cor0;
     708        9300 :         pt_exp1 = scaled_buf_exp + DELTA_COH - 1;
     709        9300 :         offset = 0;
     710        9300 :         move16();
     711        9300 :         pt_cor3 = pt_cor0 + ( DELTA_COH - 1 ) + len_x;
     712        9300 :         pt_exp3 = scaled_buf_exp + 2 * ( DELTA_COH - 1 ) + len_x;
     713        9300 :         offset1 = 0;
     714        9300 :         move16();
     715             : 
     716       42582 :         FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */
     717             :         {
     718             :             /* 1st set */
     719       33282 :             offset_la = 0;
     720       33282 :             move16();
     721       33282 :             if ( EQ_16( i, 2 ) )
     722             :             {
     723       11094 :                 offset_la = sub( L_LOOK_12k8 / OPL_DECIM, len[j] );
     724             :             }
     725             : 
     726             :             /* 2nd set */
     727       33282 :             offset_la1 = 0;
     728       33282 :             move16();
     729       33282 :             if ( EQ_16( i, 2 ) )
     730             :             {
     731       11094 :                 offset_la1 = sub( L_LOOK_12k8 / OPL_DECIM, len1[j] );
     732             :             }
     733             : 
     734             :             /* 1st set of candidates */
     735       33282 :             ind = add( maximum_fx( pt_cor1, sec_length[j], &ftmp ), offset );
     736       33282 :             pitchX[i][j] = add( ind, pit_min );
     737       33282 :             move16();
     738       33282 :             pt2 = pt1 - pitchX[i][j] + /*-*/ offset_la; /* selected moving vector  */
     739             : 
     740       33282 :             enr1_exp = 0;
     741       33282 :             move16();
     742             : #ifdef ISSUE_1867_replace_overflow_libenc
     743       33282 :             enr1 = add_sat( extract_h( dotp_fx( pt2, pt2, len[j], &enr1_exp ) ), 1 );
     744             : #else
     745             :             enr1 = add_o( extract_h( dotp_fx( pt2, pt2, len[j], &enr1_exp ) ), 1, &Overflow );
     746             : #endif
     747             : 
     748       33282 :             enr2 = L_mult( enr0[j], enr1 );
     749       33282 :             enr2_exp = norm_l( enr2 );
     750       33282 :             enr2 = L_shl( enr2, enr2_exp );
     751       33282 :             enr2_exp = sub( 31, add( sub( 28, add( enr0_exp[j], enr1_exp ) ), add( enr2_exp, 1 ) ) );
     752             : 
     753       33282 :             enr2 = Isqrt_lc( enr2, &enr2_exp ); /* 1/sqrt(energy) */ /*31-enr2_exp*/
     754       33282 :             enr1_exp = norm_l( enr2 );
     755       33282 :             enr1 = extract_h( L_shl( enr2, enr1_exp ) ); /*31-enr2_exp+enr1_exp-16*/
     756       33282 :             enr1_exp = sub( enr2_exp, enr1_exp );        /*15-enr1_exp*/
     757             : 
     758       33282 :             Ltmp = L_mult0( cor_buf[ind], enr1 );
     759       33282 :             qCorX = add( sub( 15, enr1_exp ), sub( 14, pt_exp1[ind] ) );
     760       33282 :             corX[i][j] = extract_h( L_shr_sat( Ltmp, sub( qCorX, 31 ) ) );
     761       33282 :             qCorX = 31;
     762       33282 :             move16();
     763             : 
     764       33282 :             Ltmp = L_mult0( pt_cor0[ind], enr1 );
     765       33282 :             qScaledX = add( sub( 15, enr1_exp ), sub( 14, pt_exp1[ind] ) );
     766       33282 :             scaledX[i][j] = round_fx( L_shl( Ltmp, sub( 16 + 12, qScaledX ) ) );
     767       33282 :             qScaledX = 12;
     768       33282 :             move16();
     769             : 
     770       33282 :             pt_cor1 += sec_length[j];
     771       33282 :             move16();
     772       33282 :             offset = add( offset, sec_length[j] );
     773             : 
     774             :             /* 2nd set of candidates */
     775       33282 :             ind1 = add( maximum_fx( pt_cor3, sec_length1[j], &ftmp ), offset1 );
     776       33282 :             pitchX[i][j + NSECT] = add( ind1, pit_min1 );
     777       33282 :             move16();
     778       33282 :             pt4 = pt1 - pitchX[i][j + NSECT] + /*-*/ offset_la1;
     779       33282 :             move16(); /* selected moving vector  */
     780       33282 :             enr1_exp = 0;
     781       33282 :             move16();
     782             : #ifdef ISSUE_1867_replace_overflow_libenc
     783       33282 :             enr1 = add_sat( extract_h( dotp_fx( pt4, pt4, len1[j], &enr1_exp ) ), 1 );
     784             : #else
     785             :             enr1 = add_o( extract_h( dotp_fx( pt4, pt4, len1[j], &enr1_exp ) ), 1, &Overflow );
     786             : #endif
     787             : 
     788       33282 :             enr2 = L_mult( enr0_1[j], enr1 );
     789       33282 :             enr2_exp = norm_l( enr2 );
     790       33282 :             enr2 = L_shl( enr2, enr2_exp );
     791             : 
     792       33282 :             enr2_exp = sub( 31, add( sub( 28, add( enr0_1_exp[j], enr1_exp ) ), add( enr2_exp, 1 ) ) );
     793       33282 :             enr2 = Isqrt_lc( enr2, &enr2_exp ); /* 1/sqrt(energy) */ /*31-enr2_exp*/
     794       33282 :             enr1_exp = norm_l( enr2 );
     795       33282 :             enr1 = extract_h( L_shl( enr2, enr1_exp ) ); /*31-enr2_exp+enr1_exp-16*/
     796       33282 :             enr1_exp = sub( enr2_exp, enr1_exp );        /*15-enr1_exp*/
     797             : 
     798       33282 :             Ltmp = L_mult0( cor_buf[ind1 + len_x], enr1 );
     799             : 
     800       33282 :             qCorX = add( sub( 15, enr1_exp ), sub( 14, pt_exp3[ind1] ) );
     801       33282 :             corX[i][j + NSECT] = extract_h( L_shr_sat( Ltmp, qCorX - 31 ) );
     802       33282 :             qCorX = 31;
     803       33282 :             move16();
     804             : 
     805       33282 :             Ltmp = L_mult0( pt_cor0[ind1 + ( DELTA_COH - 1 ) + len_x], enr1 );
     806       33282 :             qScaledX = add( sub( 15, enr1_exp ), sub( 14, pt_exp3[ind1] ) );
     807       33282 :             scaledX[i][j + NSECT] = round_fx( L_shl( Ltmp, sub( 16 + 12, qScaledX ) ) );
     808             :             /*scaledX[i][j+NSECT] = saturate(L_shr(Ltmp, qScaledX-12));*/
     809       33282 :             qScaledX = 12;
     810       33282 :             move16();
     811             : 
     812       33282 :             pt_cor3 += sec_length1[j];
     813       33282 :             move16();
     814       33282 :             offset1 = add( offset1, sec_length1[j] );
     815             : 
     816             :         } /* FOR j < NSECT */
     817             :     }     /* FOR i < NHFR */
     818             : 
     819             :     /*-----------------------------------------------------------------*
     820             :      * Favor a smaller delay if it happens that it has its multiple
     821             :      * in the longer-delay sections  (harmonics check)
     822             :      *-----------------------------------------------------------------*/
     823             : 
     824        9300 :     FOR( i = 0; i < 2; i++ ) /* loop for the 2 half-frames */
     825             :     {
     826        6200 :         fac = THRES0;
     827        6200 :         move16();
     828        6200 :         find_mult_fx( &fac, pitchX[i][2], pitchX[i][3], pit_max[7], &scaledX[i][2], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 3rd section */
     829        6200 :         find_mult_fx( &fac, pitchX[i][1], pitchX[i][2], pit_max[5], &scaledX[i][1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
     830        6200 :         test();
     831        6200 :         IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][0], 1 ), pit_min_coding ) )
     832             :         {
     833        3588 :             find_mult_fx( &fac, pitchX[i][0], pitchX[i][1], pit_max[3], &scaledX[i][0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
     834             :         }
     835        6200 :         fac = THRES0;
     836        6200 :         move16();
     837        6200 :         find_mult_fx( &fac, pitchX[i][NSECT + 2], pitchX[i][NSECT + 3], pit_max[7], &scaledX[i][NSECT + 2], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 3rd section */
     838        6200 :         find_mult_fx( &fac, pitchX[i][NSECT + 1], pitchX[i][NSECT + 2], pit_max[6], &scaledX[i][NSECT + 1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
     839        6200 :         test();
     840        6200 :         IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][NSECT + 0], 1 ), pit_min_coding ) )
     841             :         {
     842        3588 :             find_mult_fx( &fac, pitchX[i][NSECT + 0], pitchX[i][NSECT + 1], pit_max[4], &scaledX[i][NSECT + 0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
     843             :         }
     844             :     }
     845             : 
     846        3100 :     fac = THRES0;
     847        3100 :     move16();                                                                                                        /* the look-ahead */
     848        3100 :     find_mult_fx( &fac, pitchX[i][2], pitchX[i][3], pit_max[7], &scaledX[i][2], old_pitch, old_corr, 2, 2 );         /* Multiples in 3rd section */
     849        3100 :     find_mult_fx( &fac, pitchX[i][1], pitchX[i][2], pit_max[5], &scaledX[i][1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
     850        3100 :     test();
     851        3100 :     IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][0], 1 ), pit_min_coding ) )
     852             :     {
     853        1794 :         find_mult_fx( &fac, pitchX[i][0], pitchX[i][1], pit_max[3], &scaledX[i][0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
     854             :     }
     855        3100 :     fac = THRES0;
     856        3100 :     move16();
     857        3100 :     find_mult_fx( &fac, pitchX[i][NSECT + 2], pitchX[i][NSECT + 3], pit_max[7], &scaledX[i][NSECT + 2], old_pitch, old_corr, 2, 2 );         /* Multiples in 3rd section */
     858        3100 :     find_mult_fx( &fac, pitchX[i][NSECT + 1], pitchX[i][NSECT + 2], pit_max[6], &scaledX[i][NSECT + 1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
     859        3100 :     test();
     860        3100 :     IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][NSECT + 0], 1 ), pit_min_coding ) )
     861             :     {
     862        1794 :         find_mult_fx( &fac, pitchX[i][NSECT + 0], pitchX[i][NSECT + 1], pit_max[4], &scaledX[i][NSECT + 0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */ /* Multiples in 2nd section */
     863             :     }
     864             : 
     865             :     /*-----------------------------------------------------------------*
     866             :      * Do 1st estimate for pitch values
     867             :      * Adjust the normalized correlation using estimated noise level
     868             :      * Compute the maximum scaling for the neighbour correlation
     869             :      * reinforcement
     870             :      *-----------------------------------------------------------------*/
     871        3100 :     add_sect0 = add( NSECT, sect0 );
     872        3100 :     sub_sect0 = sub( NSECT, sect0 );
     873       12400 :     FOR( i = 0; i < NHFR; i++ )
     874             :     {
     875             :         /* 1st set of pitch candidates */
     876        9300 :         ind = add( maximum_fx( scaledX[i] + sect0, sub_sect0, &ftmp ), sect0 );
     877        9300 :         ind_tmp[i] = ind;
     878        9300 :         move16();
     879        9300 :         pitch_tmp[i] = pitchX[i][ind];
     880        9300 :         move16();
     881             : #ifdef ISSUE_1867_replace_overflow_libenc
     882        9300 :         cor_tmp[i] = add_sat( corX[i][ind], corr_shift );
     883             : #else
     884             :         cor_tmp[i] = add_o( corX[i][ind], corr_shift, &Overflow );
     885             : #endif
     886        9300 :         move16();
     887             : 
     888             :         /* Higher is the neighbour's correlation, higher is the weighting */
     889             :         /* operands are Q15, result is Q15 */
     890        9300 :         thres1[i] = mult( THRES1, cor_tmp[i] );
     891        9300 :         move16();
     892             : 
     893             :         /* 2nd set of pitch candidates */
     894        9300 :         ind1 = add( maximum_fx( scaledX[i] + add_sect0, sub_sect0, &ftmp ), add_sect0 );
     895        9300 :         ind_tmp[i + NHFR] = ind1;
     896        9300 :         move16();
     897        9300 :         pitch_tmp[i + NHFR] = pitchX[i][ind1];
     898        9300 :         move16();
     899             : #ifdef ISSUE_1867_replace_overflow_libenc
     900        9300 :         cor_tmp[i + NHFR] = add_sat( corX[i][ind1], corr_shift );
     901             : #else
     902             :         cor_tmp[i + NHFR] = add_o( corX[i][ind1], corr_shift, &Overflow );
     903             : #endif
     904        9300 :         move16();
     905             : 
     906             :         /* Higher is the neighbour's correlation, higher is the weighting */
     907             :         /* operands are Q15, result is Q15 */
     908        9300 :         thres1[i + NHFR] = mult( THRES1, cor_tmp[i + NHFR] );
     909        9300 :         move16();
     910             :     }
     911             :     /*-----------------------------------------------------------------*
     912             :      * Take into account previous and next pitch values of the present
     913             :      * frame and look-ahead. Choose the pitch lags and normalize
     914             :      * correlations for each half-frame & look-ahead
     915             :      *-----------------------------------------------------------------*/
     916             : 
     917        3100 :     pitch_neighbour_fx( sect0, pitch_tmp, pitchX, cor_tmp, scaledX, thres1, ind_tmp );
     918       12400 :     FOR( i = 0; i < NHFR; i++ )
     919             :     {
     920        9300 :         ind = add( maximum_fx( scaledX[i] + sect0, sub_sect0, &ftmp ), sect0 );
     921        9300 :         ind_corX = add( maximum_fx( corX[i] + sect0, sub_sect0, &ftmp ), sect0 );
     922             : 
     923        9300 :         ind1 = add( maximum_fx( scaledX[i] + add_sect0, sub_sect0, &ftmp ), add_sect0 );
     924        9300 :         ind1_corX = add( maximum_fx( corX[i] + add_sect0, sub_sect0, &ftmp ), add_sect0 );
     925             : 
     926        9300 :         if ( GT_16( scaledX[i][ind1], scaledX[i][ind] ) )
     927             :         {
     928        4013 :             ind = ind1;
     929        4013 :             move16();
     930             :         }
     931        9300 :         test();
     932        9300 :         if ( Opt_SC_VBR && GT_16( corX[i][ind1_corX], corX[i][ind_corX] ) )
     933             :         {
     934           0 :             ind_corX = ind1_corX;
     935           0 :             move16();
     936             :         }
     937        9300 :         test();
     938        9300 :         test();
     939        9300 :         test();
     940        9300 :         IF( Opt_SC_VBR && ( LT_16( mult( pitchX[i][ind], 13107 /*0.4 in Q15*/ ), pitchX[i][ind_corX] ) ) &&
     941             :             ( GT_16( mult( pitchX[i][ind], 19661 /*0.6 in Q15*/ ), pitchX[i][ind_corX] ) ) &&
     942             :             ( GE_16( corX[i][ind_corX], 29491 /*0.9 in Q15*/ ) ) )
     943             :         {
     944           0 :             pitch[i] = pitchX[i][ind_corX];
     945           0 :             move16();
     946           0 :             voicing[i] = corX[i][ind_corX];
     947           0 :             move16();
     948             :         }
     949             :         ELSE
     950             :         {
     951        9300 :             pitch[i] = pitchX[i][ind];
     952        9300 :             move16();
     953        9300 :             voicing[i] = corX[i][ind];
     954        9300 :             move16();
     955             :         }
     956             :     }
     957             : 
     958             :     /*-----------------------------------------------------------------*
     959             :      * Increase the threshold for correlation reinforcement with
     960             :      * the past if correlation high and pitch stable
     961             :      *-----------------------------------------------------------------*/
     962             : 
     963             :     /* all Q15 here */
     964             :     /* cor_mean = 0.5f * (voicing[0] + voicing[1]) + corr_shift; */
     965        3100 :     Ltmp = L_mult( voicing[0], 16384 );
     966        3100 :     Ltmp = L_mac( Ltmp, voicing[1], 16384 );
     967        3100 :     cor_mean = round_fx( L_add( Ltmp, corr_shift ) );
     968             : 
     969             :     /* pitch unstable in present frame or from previous frame or normalized correlation too low */
     970        3100 :     coh_flag = pitch_coherence_fx( pitch[0], pitch[1], COH_FAC, DELTA_COH );
     971        3100 :     move16();
     972        3100 :     coh_flag1 = pitch_coherence_fx( pitch[0], *old_pitch, COH_FAC, DELTA_COH );
     973        3100 :     move16();
     974             : 
     975        3100 :     test();
     976        3100 :     test();
     977        3100 :     test();
     978        3100 :     IF( ( coh_flag == 0 ) || ( coh_flag1 == 0 ) || ( LT_16( cor_mean, CORR_TH0 ) ) || ( LT_16( relE, THR_relE ) ) )
     979             :     {
     980             :         /* Reset the threshold */
     981        1309 :         *old_thres = 0;
     982        1309 :         move16();
     983             :     }
     984             :     ELSE
     985             :     {
     986             :         /* The threshold increase is directly dependent on normalized correlation */
     987             :         /* *old_thres += (0.16f * cor_mean); */
     988        1791 :         *old_thres = round_fx( L_mac( L_deposit_h( *old_thres ), 5243, cor_mean ) );
     989             :     }
     990             : 
     991        3100 :     *old_thres = s_min( *old_thres, THRES3 );
     992        3100 :     move16();
     993             : 
     994        3100 :     IF( GT_16( voicing[1], voicing[0] ) )
     995             :     {
     996        1516 :         *old_corr = voicing[1];
     997        1516 :         move16();
     998             :     }
     999             :     ELSE
    1000             :     {
    1001        1584 :         *old_corr = cor_mean;
    1002        1584 :         move16();
    1003             :     }
    1004             : 
    1005             :     /*-----------------------------------------------------------------*
    1006             :      * Extrapolate the pitch value for the next frame by estimating
    1007             :      * the pitch evolution. This value is added to the old_pitch
    1008             :      * in the next frame and is then used when the normalized
    1009             :      * correlation is reinforced by the past estimate
    1010             :      *-----------------------------------------------------------------*/
    1011        3100 :     tmp_buf[0] = *old_pitch;
    1012        3100 :     move16();
    1013       12400 :     FOR( i = 0; i < NHFR; i++ )
    1014             :     {
    1015        9300 :         tmp_buf[i + 1] = pitch[i];
    1016        9300 :         move16();
    1017             :     }
    1018             : 
    1019        3100 :     *delta_pit = 0;
    1020        3100 :     move16();
    1021        3100 :     cnt = 0;
    1022        3100 :     move16();
    1023             : 
    1024       12400 :     FOR( i = 0; i < NHFR; i++ )
    1025             :     {
    1026        9300 :         diff = sub( tmp_buf[i + 1], tmp_buf[i] );
    1027        9300 :         move16();
    1028        9300 :         coh_flag = pitch_coherence_fx( tmp_buf[i], tmp_buf[i + 1], COH_FAC, DELTA_COH );
    1029             : 
    1030        9300 :         if ( coh_flag != 0 )
    1031             :         {
    1032        7882 :             *delta_pit = add( *delta_pit, diff );
    1033        7882 :             move16();
    1034             :         }
    1035        9300 :         cnt = add( cnt, coh_flag );
    1036             :     }
    1037        3100 :     if ( EQ_16( cnt, 2 ) )
    1038             :     {
    1039             :         /* *delta_pit /= 2; */
    1040         484 :         *delta_pit = shr( *delta_pit, 1 );
    1041         484 :         move16();
    1042             :     }
    1043        3100 :     IF( EQ_16( cnt, 3 ) )
    1044             :     {
    1045        2207 :         k = *delta_pit;
    1046        2207 :         move16();
    1047             :         /* *delta_pit /= 3; */
    1048        2207 :         if ( k < 0 )
    1049             :         {
    1050         496 :             *delta_pit = mult( *delta_pit, -32768 );
    1051         496 :             move16();
    1052             :         }
    1053        2207 :         tmp16 = mult( *delta_pit, 10923 );
    1054        2207 :         if ( k < 0 )
    1055             :         {
    1056         496 :             tmp16 = mult( tmp16, -32768 );
    1057             :         }
    1058        2207 :         *delta_pit = tmp16;
    1059        2207 :         move16();
    1060             :     }
    1061             : 
    1062             :     /*--------------------------------------------------------------*
    1063             :      * Update old pitch, upsample pitch,
    1064             :      *--------------------------------------------------------------*/
    1065             : 
    1066        3100 :     *old_pitch = pitch[1];
    1067        3100 :     move16();
    1068             : 
    1069       12400 :     FOR( i = 0; i < NHFR; i++ )
    1070             :     {
    1071             :         /* compensate decimation */
    1072        9300 :         pitch[i] = i_mult2( pitch[i], OPL_DECIM );
    1073        9300 :         move16();
    1074             :     }
    1075             : 
    1076        3100 :     return;
    1077             : }
    1078             : 
    1079     1150754 : void pitch_ol_ivas_fx(
    1080             :     Word16 pitch[3],         /* o  : open loop pitch lag for each half-frame in range [29,231]      Q0  */
    1081             :     Word16 voicing[3],       /* o  : maximum normalized correlation for each half-frame in [0,1.0[  Q15 */
    1082             :     Word16 *old_pitch,       /* i/o: pitch of the 2nd half-frame of previous frame (i.e. pitch[1])  Q0  */
    1083             :     Word16 *old_corr,        /* i/o: correlation of old_pitch (i.e. voicing[1] or corr_mean)        Q15 */
    1084             :     Word16 corr_shift,       /* i  : normalized correlation correction                              Q15 */
    1085             :     Word16 *old_thres,       /* i/o: maximum correlation weighting with respect to past frame pitch Q14 */
    1086             :     Word16 *delta_pit,       /* i/o: old pitch extrapolation correction in range [-14,+14]          Q0  */
    1087             :     Word16 *st_old_wsp2,     /* i/o: weighted speech memory                                         qwsp */
    1088             :     const Word16 *wsp,       /* i  : weighted speech for current frame and look-ahead               qwsp */
    1089             :     Word16 mem_decim2[3],    /* i/o: wsp decimation filter memory                                   qwsp */
    1090             :     const Word16 relE,       /* i  : relative frame energy                                          Q8  */
    1091             :     const Word16 last_class, /* i  : frame classification of last frame                                 */
    1092             :     const Word16 bwidth,     /* i  : bandwidth                                                          */
    1093             :     const Word16 Opt_SC_VBR, /* i  : SC-VBR flag                                                        */
    1094             :     Word16 qwsp              /* i  : Q factor for wsp                                               Q0  */
    1095             : )
    1096             : {
    1097             :     Word16 ftmp, old_wsp2[( L_WSP - L_INTERPOL ) / OPL_DECIM], *wsp2;
    1098             :     Word16 tmp_mem[3];
    1099             : 
    1100             :     Word16 scale1[2 * DELTA_COH - 1];
    1101             :     Word16 scaled_buf[2 * LEN_X + 3 * ( DELTA_COH - 1 )];
    1102             :     Word16 scaled_buf_exp[2 * LEN_X + 3 * ( DELTA_COH - 1 )];
    1103             :     Word16 cor_buf[2 * LEN_X], cor_buf_exp[2 * LEN_X];
    1104             :     Word16 *pt1, *pt2, *pt3, *pt4, *pt5, *pt6;
    1105             :     Word16 *pt_cor0, *pt_cor1, *pt_cor2, *pt_cor3, *pt_cor4;
    1106             :     Word16 *pt_cor0_exp, *pt_cor1_exp, *pt_cor2_exp, *pt_cor3_exp, *pt_cor4_exp;
    1107             :     Word16 thres1[6];
    1108             :     Word16 diff, cnt, ind, ind1, offset, offset1, offset_la, offset_la1, coh_flag, coh_flag1;
    1109             :     Word16 ind_corX, ind1_corX;
    1110             : 
    1111             :     Word16 i, j, k, m, pit_min, pit_min1, sect0, subsect0, add_sect0, sub_sect0, old_tmp, old_tmp1, len_x, len_x1;
    1112             :     Word16 len_temp;
    1113             :     Word16 pitchX[NHFR][2 * NSECT], pitch_tmp[2 * NHFR], ind_tmp[2 * NHFR], tmp_buf[NHFR + 1];
    1114             : 
    1115             :     Word16 enr0_exp[NSECT], enr0_1_exp[NSECT], enr1_exp;
    1116             :     Word32 enr0[NSECT], enr0_1[NSECT], enr1;
    1117             :     Word64 temp, temp1;
    1118             :     Word32 Ltmp;
    1119             :     Word16 fac, tmp16, tmp16_2;
    1120             :     Word16 scaledX[NHFR][2 * NSECT], corX[NHFR][2 * NSECT], cor_tmp[2 * NHFR], cor_mean;
    1121             :     const Word16 *len, *len1, *sublen, *sublen1, *pit_max, *sec_length, *sec_length1;
    1122             : 
    1123             :     Word16 pit_min_coding;
    1124             : #ifndef ISSUE_1867_replace_overflow_libenc
    1125             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    1126             :     Flag Overflow = 0;
    1127             : #endif
    1128             : #endif
    1129             :     Word16 new_q;
    1130     1150754 :     new_q = sub( 63, shl( qwsp, 1 ) );
    1131             : 
    1132             :     /*--------------------------------------------------------------*
    1133             :      * Initialization
    1134             :      *--------------------------------------------------------------*/
    1135     1150754 :     len = len_12k8;
    1136     1150754 :     len1 = len1_12k8;
    1137     1150754 :     sublen = sublen_12k8;
    1138     1150754 :     sublen1 = sublen1_12k8;
    1139     1150754 :     pit_max = pit_max_12k8;
    1140     1150754 :     sec_length = sec_length_12k8;
    1141     1150754 :     sec_length1 = sec_length1_12k8;
    1142             : 
    1143     1150754 :     test();
    1144     1150754 :     if ( ( LT_16( last_class, VOICED_TRANSITION ) ) && ( NE_16( bwidth, NB ) ) )
    1145             :     {
    1146             :         /*reset last pitch reinforcement in case of unvoiced or transitions: it avoids some pitch doublings*/
    1147      662931 :         *old_thres = 0;
    1148      662931 :         move16();
    1149             :     }
    1150             : 
    1151     1150754 :     pit_min_coding = PIT_MIN_EXTEND;
    1152     1150754 :     move16();
    1153     1150754 :     test();
    1154     1150754 :     test();
    1155     1150754 :     test();
    1156     1150754 :     test();
    1157     1150754 :     IF( ( ( NE_16( bwidth, NB ) ) && ( GT_16( *old_pitch, PIT_MIN ) ) ) ||
    1158             :         ( ( EQ_16( bwidth, NB ) ) && ( ( GT_16( *old_pitch, PIT_MIN2_1 ) ) || ( LT_16( *old_thres, 1638 /* 0.1 in Q14*/ ) ) ) ) )
    1159             :     {
    1160      513572 :         pit_min = PIT_MIN / OPL_DECIM;
    1161      513572 :         move16();
    1162      513572 :         pit_min1 = PIT_MIN_1 / OPL_DECIM;
    1163      513572 :         move16();
    1164      513572 :         subsect0 = 2;
    1165      513572 :         move16();
    1166      513572 :         sect0 = 1;
    1167      513572 :         move16();
    1168             :     }
    1169             :     ELSE
    1170             :     {
    1171      637182 :         pit_min = PIT_MIN2 / OPL_DECIM;
    1172      637182 :         move16();
    1173      637182 :         pit_min1 = PIT_MIN2_1 / OPL_DECIM;
    1174      637182 :         move16();
    1175      637182 :         subsect0 = 0;
    1176      637182 :         move16();
    1177      637182 :         sect0 = 0;
    1178      637182 :         move16();
    1179             :     }
    1180             : 
    1181     1150754 :     len_x = ( PIT_MAX / OPL_DECIM - pit_min + 1 );
    1182     1150754 :     move16();
    1183     1150754 :     len_x1 = ( PIT_MAX / OPL_DECIM - pit_min1 + 1 );
    1184     1150754 :     move16();
    1185             : 
    1186             :     /*--------------------------------------------------------------*
    1187             :      * Find decimated weighted speech
    1188             :      * Update wsp buffer with the memory
    1189             :      * decimation of wsp[] to search pitch in LF and to reduce complexity
    1190             :      * Extend the decimation of wsp to the end of the speech buffer
    1191             :      * Update wsp memory
    1192             :      *--------------------------------------------------------------*/
    1193     1150754 :     Copy( st_old_wsp2, old_wsp2, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM );
    1194     1150754 :     wsp2 = old_wsp2 + ( ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM );
    1195             : 
    1196     1150754 :     LP_Decim2_Copy( wsp, wsp2, L_FRAME, mem_decim2 );
    1197             : 
    1198             :     /* Avoid uninitialized memory access */
    1199     1150754 :     set16_fx( wsp2 + L_FRAME / 2, 0, sizeof( old_wsp2 ) / sizeof( Word16 ) - ( ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ) - L_FRAME / 2 );
    1200     1150754 :     tmp_mem[0] = mem_decim2[0];
    1201     1150754 :     move16();
    1202     1150754 :     tmp_mem[1] = mem_decim2[1];
    1203     1150754 :     move16();
    1204     1150754 :     tmp_mem[2] = mem_decim2[2];
    1205     1150754 :     move16();
    1206             : 
    1207     1150754 :     LP_Decim2_Copy( &wsp[L_FRAME], &wsp2[L_FRAME / 2], L_LOOK_12k8, tmp_mem ); /* shr() used instead of division by OPL_DECIM*/
    1208             : 
    1209     1150754 :     Copy( &old_wsp2[L_FRAME / 2], st_old_wsp2, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM );
    1210             : 
    1211             :     /*-----------------------------------------------------------------*
    1212             :      * Attenuate the correlation correction factor due to noise.
    1213             :      * Reset correlation buffer outside the useful range.
    1214             :      * Find the scaling functions for immediate neigbours and
    1215             :      * further ones.
    1216             :      *-----------------------------------------------------------------*/
    1217             : 
    1218     1150754 :     corr_shift = shr( corr_shift, 1 );
    1219             : 
    1220     1150754 :     set16_fx( scaled_buf, 0, DELTA_COH - 1 );
    1221     1150754 :     set16_fx( scaled_buf + ( DELTA_COH - 1 ) + len_x, 0, DELTA_COH - 1 );
    1222     1150754 :     set16_fx( scaled_buf + 2 * ( DELTA_COH - 1 ) + len_x + len_x1, 0, DELTA_COH - 1 );
    1223     1150754 :     set16_fx( scaled_buf_exp, 0, len_x + len_x1 + 3 * ( DELTA_COH - 1 ) );
    1224             : 
    1225     1150754 :     pt1 = scale1 + DELTA_COH - 1;
    1226     1150754 :     pt2 = pt1;
    1227     1150754 :     tmp16 = mult( *old_thres, -32768 / DELTA_COH ); // Q14
    1228     1150754 :     k = add( *old_thres, ONE_IN_Q14 );              // Q14
    1229    17261310 :     FOR( i = 0; i < DELTA_COH; i++ )
    1230             :     {
    1231    16110556 :         *pt1 = k;        // Q14
    1232    16110556 :         *pt2-- = *pt1++; // Q14
    1233    16110556 :         move16();
    1234    16110556 :         move16();
    1235             : 
    1236    16110556 :         k = add( k, tmp16 ); // Q14
    1237             :     }
    1238             : 
    1239             :     /*-----------------------------------------------------------------------------*
    1240             :      * Estimate the new pitch by extrapolating the old pitch value for 2 half-frames
    1241             :      *-----------------------------------------------------------------------------*/
    1242     1150754 :     old_tmp = add( *old_pitch, *delta_pit );
    1243     1150754 :     old_tmp = s_min( old_tmp, PIT_MAX / OPL_DECIM );
    1244     1150754 :     old_tmp = s_max( old_tmp, pit_min );
    1245     1150754 :     old_tmp1 = add( old_tmp, *delta_pit );
    1246     1150754 :     old_tmp1 = s_min( old_tmp1, PIT_MAX / OPL_DECIM );
    1247     1150754 :     old_tmp1 = s_max( old_tmp1, pit_min );
    1248             : 
    1249             :     /*-----------------------------------------------------------------*
    1250             :      * Loop for all three half-frames (current frame + look-ahead)
    1251             :      *-----------------------------------------------------------------*/
    1252     1150754 :     pt_cor0 = scaled_buf + DELTA_COH - 1;
    1253     1150754 :     pt_cor0_exp = scaled_buf_exp + DELTA_COH - 1;
    1254             : 
    1255     1150754 :     pt_cor2 = pt_cor0 - pit_min + old_tmp;
    1256     1150754 :     pt_cor2_exp = pt_cor0_exp - pit_min + old_tmp;
    1257             : 
    1258     1150754 :     pt_cor4 = pt_cor0 - pit_min1 + old_tmp + ( DELTA_COH - 1 ) + len_x;
    1259     1150754 :     pt_cor4_exp = pt_cor0_exp - pit_min1 + old_tmp + ( DELTA_COH - 1 ) + len_x;
    1260             : 
    1261     4603016 :     FOR( i = 0; i < NHFR; i++ ) /* i = 0, 1, 2 */
    1262             :     {
    1263     3452262 :         pt1 = wsp2 + i * 2 * ( L_SUBFR / OPL_DECIM ); /* *pt1 -> Q12 */
    1264     3452262 :         pt2 = pt1 - pit_min;                          /* *pt2 -> Q12 */
    1265     3452262 :         pt4 = pt1 - pit_min1;                         /* *pt4 -> Q12 */
    1266             : 
    1267     3452262 :         temp = 0;
    1268     3452262 :         move64();
    1269             : 
    1270     3452262 :         pt_cor1 = pt_cor0;
    1271     3452262 :         pt_cor1_exp = pt_cor0_exp;
    1272             : 
    1273     3452262 :         pt_cor3 = pt_cor0 + ( DELTA_COH - 1 ) + len_x;
    1274     3452262 :         pt_cor3_exp = pt_cor0_exp + ( DELTA_COH - 1 ) + len_x;
    1275             : 
    1276     3452262 :         IF( LT_16( i, NHFR - 1 ) ) /* First two half-frames (current frame) */
    1277             :         {
    1278     2301508 :             pt3 = pt1;
    1279     2301508 :             pt5 = pt1;
    1280             : 
    1281    10480396 :             FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */
    1282             :             {
    1283             :                 /*-----------------------------------------------------------------*
    1284             :                  * Find fixed vector energy
    1285             :                  *-----------------------------------------------------------------*/
    1286             : 
    1287             :                 /* 1st set */
    1288     8178888 :                 k = (Word16) ( pt1 - pt3 );
    1289     8178888 :                 move16();
    1290   272852308 :                 FOR( k = add( k, len[j] ); k > 0; k-- )
    1291             :                 {
    1292   264673420 :                     temp = W_mac0_16_16( temp, *pt3, *pt3 ); // 2*qwsp
    1293   264673420 :                     pt3++;
    1294             :                 }
    1295     8178888 :                 IF( temp == 0 )
    1296             :                 {
    1297      537519 :                     enr0[j] = 21474836; // 0.01 in Q31
    1298      537519 :                     enr0_exp[j] = 0;
    1299      537519 :                     move32();
    1300      537519 :                     move16();
    1301             :                 }
    1302             :                 ELSE
    1303             :                 {
    1304     7641369 :                     cnt = W_norm( temp );
    1305     7641369 :                     enr0[j] = W_extract_h( W_shl( temp, cnt ) ); // 2*qwsp+cnt-32
    1306     7641369 :                     enr0_exp[j] = sub( new_q, cnt );             // 31-(2*qwsp+cnt-32)
    1307     7641369 :                     move32();
    1308     7641369 :                     move16();
    1309             :                 }
    1310             : 
    1311             :                 /* Reduce complexity (length of 'enr2' section is equal or larger than 'enr') */
    1312     8178888 :                 pt5 = pt3;
    1313             : 
    1314             :                 /* 2nd set */
    1315     8178888 :                 k = (Word16) ( pt1 - pt5 );
    1316     8178888 :                 move16();
    1317             : 
    1318     8178888 :                 temp1 = temp;
    1319     8178888 :                 move64();
    1320    72621112 :                 FOR( k = ( k + len1[j] ); k > 0; k-- )
    1321             :                 {
    1322    64442224 :                     temp1 = W_mac0_16_16( temp1, *pt5, *pt5 ); // 2*qwsp
    1323    64442224 :                     pt5++;
    1324             :                 }
    1325     8178888 :                 IF( temp1 == 0 )
    1326             :                 {
    1327      537018 :                     enr0_1[j] = 21474836; // 0.01 in Q31
    1328      537018 :                     enr0_1_exp[j] = 0;
    1329      537018 :                     move32();
    1330      537018 :                     move16();
    1331             :                 }
    1332             :                 ELSE
    1333             :                 {
    1334     7641870 :                     cnt = W_norm( temp1 );
    1335     7641870 :                     enr0_1[j] = W_extract_h( W_shl( temp1, cnt ) ); // 2*qwsp+cnt-32
    1336     7641870 :                     enr0_1_exp[j] = sub( new_q, cnt );              // 31-(2*qwsp+cnt-32)
    1337     7641870 :                     move32();
    1338     7641870 :                     move16();
    1339             :                 }
    1340             :             }
    1341             : 
    1342             :             /*----------------------------------------------------------*
    1343             :              * Find correlation for the non-overlapping pitch lag values
    1344             :              *----------------------------------------------------------*/
    1345             : 
    1346     2301508 :             k = (Word16) ( pt2 - pt1 + pit_max[subsect0] );
    1347     2301508 :             move16();
    1348             : 
    1349     9985956 :             FOR( ; k >= 0; k-- )
    1350             :             {
    1351     7684448 :                 temp = 0;
    1352     7684448 :                 move64();
    1353   315062368 :                 FOR( m = 0; m < sublen[0]; m++ )
    1354             :                 {
    1355   307377920 :                     temp = W_mac0_16_16( temp, pt1[m], pt2[m] ); // 2*qwsp
    1356             :                 }
    1357     7684448 :                 cnt = W_norm( temp );
    1358     7684448 :                 *pt_cor1 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
    1359     7684448 :                 *pt_cor1_exp = sub( new_q, cnt );                          // 15-(2*qwsp+cnt-32-16)
    1360     7684448 :                 move16();
    1361     7684448 :                 move16();
    1362             : 
    1363     7684448 :                 pt2--;
    1364     7684448 :                 pt_cor1++;
    1365     7684448 :                 pt_cor1_exp++;
    1366             :             }
    1367             : 
    1368             :             /*----------------------------------------------------------*
    1369             :              * For each subsection, find the correlation
    1370             :              *----------------------------------------------------------*/
    1371    16357776 :             FOR( j = subsect0; j < NSUBSECT; j++ )
    1372             :             {
    1373    14056268 :                 len_temp = sublen[j];
    1374    14056268 :                 move16();
    1375             : 
    1376    14056268 :                 k = (Word16) ( pt2 - pt1 );
    1377    14056268 :                 move16();
    1378    14056268 :                 k = add( k, pit_max[j + 1] );
    1379             : 
    1380             :                 /* Keep Q15 normalized result */
    1381    14056268 :                 IF( LT_16( sublen[j], sublen1[j] ) )
    1382             :                 {
    1383    75949764 :                     FOR( ; k >= 0; k-- )
    1384             :                     {
    1385    71346748 :                         temp = W_mult0_16_16( pt1[0], pt2[0] ); // 2*qwsp
    1386  3917166616 :                         FOR( m = 1; m < sublen[j]; m++ )
    1387             :                         {
    1388  3845819868 :                             temp = W_mac0_16_16( temp, pt1[m], pt2[m] ); // 2*qwsp
    1389             :                         }
    1390    71346748 :                         cnt = W_norm( temp );
    1391    71346748 :                         *pt_cor1 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
    1392    71346748 :                         *pt_cor1_exp = sub( new_q, cnt );
    1393    71346748 :                         move16();
    1394    71346748 :                         move16();
    1395             : 
    1396  1171467572 :                         FOR( ; m < sublen1[j]; m++ )
    1397             :                         {
    1398  1100120824 :                             temp = W_mac0_16_16( temp, pt1[m], pt2[m] ); // 2*qwsp
    1399             :                         }
    1400    71346748 :                         cnt = W_norm( temp );
    1401    71346748 :                         *pt_cor3 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
    1402    71346748 :                         *pt_cor3_exp = sub( new_q, cnt );
    1403    71346748 :                         move16();
    1404    71346748 :                         move16();
    1405             : 
    1406    71346748 :                         pt_cor1++;
    1407    71346748 :                         pt_cor1_exp++;
    1408    71346748 :                         pt_cor3++;
    1409    71346748 :                         pt_cor3_exp++;
    1410    71346748 :                         pt2--;
    1411             :                     }
    1412             :                 }
    1413             :                 ELSE
    1414             :                 {
    1415   167191896 :                     FOR( ; k >= 0; k-- )
    1416             :                     {
    1417   157738644 :                         temp = W_mult0_16_16( pt1[0], pt2[0] ); // 2*qwsp
    1418 14548944400 :                         FOR( m = 1; m < sublen1[j]; m++ )
    1419             :                         {
    1420 14391205756 :                             temp = W_mac0_16_16( temp, pt1[m], pt2[m] ); // 2*qwsp
    1421             :                         }
    1422   157738644 :                         cnt = W_norm( temp );
    1423   157738644 :                         *pt_cor3 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
    1424   157738644 :                         *pt_cor3_exp = sub( new_q, cnt );
    1425   157738644 :                         move16();
    1426   157738644 :                         move16();
    1427             : 
    1428  1695145988 :                         FOR( ; m < sublen[j]; m++ )
    1429             :                         {
    1430  1537407344 :                             temp = W_mac0_16_16( temp, pt1[m], pt2[m] ); // 2*qwsp
    1431             :                         }
    1432   157738644 :                         cnt = W_norm( temp );
    1433   157738644 :                         *pt_cor1 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
    1434   157738644 :                         *pt_cor1_exp = sub( new_q, cnt );
    1435   157738644 :                         move16();
    1436   157738644 :                         move16();
    1437             : 
    1438   157738644 :                         pt_cor1++;
    1439   157738644 :                         pt_cor1_exp++;
    1440   157738644 :                         pt_cor3++;
    1441   157738644 :                         pt_cor3_exp++;
    1442   157738644 :                         pt2--;
    1443             :                     }
    1444             :                 }
    1445             :             } /* FOR (j = subsect0; ... */
    1446             :         }
    1447             :         ELSE /* 3rd half-frame (look-ahead) */
    1448             :         {
    1449     1150754 :             pt6 = pt1 + L_LOOK_12k8 / OPL_DECIM - 1;
    1450     1150754 :             pt3 = pt6;
    1451     1150754 :             pt5 = pt6;
    1452             : 
    1453             :             /*-----------------------------------------------------------------*
    1454             :              * For each section in both sets, find fixed vector energy
    1455             :              *-----------------------------------------------------------------*/
    1456     5240198 :             FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */
    1457             :             {
    1458             :                 /* 1st set */
    1459     4089444 :                 k = (Word16) ( pt3 - pt6 );
    1460     4089444 :                 move16();
    1461             : 
    1462   136426154 :                 FOR( k = add( k, len[j] ); k > 0; k-- )
    1463             :                 {
    1464   132336710 :                     temp = W_mac0_16_16( temp, *pt3, *pt3 );
    1465   132336710 :                     pt3--;
    1466             :                 }
    1467     4089444 :                 IF( temp == 0 )
    1468             :                 {
    1469      260275 :                     enr0[j] = 21474836; // 0.01 in Q31
    1470      260275 :                     enr0_exp[j] = 0;
    1471      260275 :                     move32();
    1472      260275 :                     move16();
    1473             :                 }
    1474             :                 ELSE
    1475             :                 {
    1476     3829169 :                     cnt = W_norm( temp );
    1477     3829169 :                     enr0[j] = W_extract_h( W_shl( temp, cnt ) ); // 2*qwsp+cnt-32
    1478     3829169 :                     enr0_exp[j] = sub( new_q, cnt );             // 31-(2*qwsp+cnt-32)
    1479     3829169 :                     move32();
    1480     3829169 :                     move16();
    1481             :                 }
    1482             : 
    1483             :                 /* Reduce complexity (length of 'enr2' section is equal or larger than 'enr') */
    1484     4089444 :                 pt5 = pt3;
    1485     4089444 :                 temp1 = temp;
    1486     4089444 :                 move64();
    1487             : 
    1488             :                 /* 2nd set */
    1489     4089444 :                 k = (Word16) ( pt5 - pt6 );
    1490     4089444 :                 move16();
    1491    36310556 :                 FOR( k = add( k, len1[j] ); k > 0; k-- )
    1492             :                 {
    1493    32221112 :                     temp1 = W_mac0_16_16( temp1, *pt5, *pt5 ); // 2*qwsp
    1494    32221112 :                     pt5--;
    1495             :                 }
    1496     4089444 :                 IF( temp1 == 0 )
    1497             :                 {
    1498      260068 :                     enr0_1[j] = 21474836; // 0.01 in Q31
    1499      260068 :                     enr0_1_exp[j] = 0;
    1500      260068 :                     move32();
    1501      260068 :                     move16();
    1502             :                 }
    1503             :                 ELSE
    1504             :                 {
    1505     3829376 :                     cnt = W_norm( temp1 );
    1506     3829376 :                     temp1 = W_shl( temp1, cnt );       // 2*qwsp+cnt
    1507     3829376 :                     enr0_1[j] = W_extract_h( temp1 );  // 2*qwsp+cnt-32
    1508     3829376 :                     enr0_1_exp[j] = sub( new_q, cnt ); // 31-(2*qwsp+cnt-32)
    1509     3829376 :                     move32();
    1510     3829376 :                     move16();
    1511             :                 }
    1512             :             }
    1513             : 
    1514             :             /* Set pointers: same as IF/ELSE block */
    1515     1150754 :             pt2 = pt6 - pit_min;
    1516     1150754 :             k = 2;
    1517     1150754 :             move16();
    1518     1150754 :             IF( sect0 != 0 )
    1519             :             {
    1520      513572 :                 pt2 = pt6 - add( pit_max[1], 1 );
    1521      513572 :                 k = sub( pit_max[2], pit_max[1] );
    1522      513572 :                 move16();
    1523             :             }
    1524             : 
    1525             :             /*-----------------------------------------------------------------*
    1526             :              * Find correlation for the non-overlapping pitch lag values
    1527             :              *-----------------------------------------------------------------*/
    1528             : 
    1529     1150754 :             len_temp = sublen[0];
    1530     1150754 :             move16();
    1531             : 
    1532     4992978 :             FOR( ; k > 0; k-- )
    1533             :             {
    1534     3842224 :                 temp = 0;
    1535     3842224 :                 move64();
    1536   157531184 :                 FOR( m = 0; m < len_temp; m++ )
    1537             :                 {
    1538   153688960 :                     temp = W_mac0_16_16( temp, pt6[-m], pt2[-m] ); // 2*qwsp
    1539             :                 }
    1540     3842224 :                 tmp16_2 = W_norm( temp );
    1541     3842224 :                 *pt_cor1 = extract_h( W_extract_h( W_shl( temp, tmp16_2 ) ) ); // 2*qwsp+tmp16_2
    1542     3842224 :                 *pt_cor1_exp = sub( new_q, tmp16_2 );                          // 2*qwsp+tmp16_2-32-16
    1543     3842224 :                 move16();
    1544     3842224 :                 move16();
    1545             : 
    1546     3842224 :                 pt_cor1++;
    1547     3842224 :                 pt_cor1_exp++;
    1548     3842224 :                 pt2--;
    1549             :             }
    1550             : 
    1551             :             /*-----------------------------------------------------------------*
    1552             :              * For each subsection, find the correlation (overlapping pitch lag values)
    1553             :              *-----------------------------------------------------------------*/
    1554             : 
    1555     8178888 :             FOR( j = subsect0; j < NSUBSECT; j++ )
    1556             :             {
    1557     7028134 :                 k = sub( pit_max[j + 1], pit_max[j] );
    1558             : 
    1559     7028134 :                 IF( LT_16( sublen[j], sublen1[j] ) )
    1560             :                 {
    1561    37974882 :                     FOR( ; k > 0; k-- )
    1562             :                     {
    1563    35673374 :                         temp = W_mult0_16_16( pt6[0], pt2[0] ); // 2*qwsp
    1564  1958583308 :                         FOR( m = 1; m < sublen[j]; m++ )
    1565             :                         {
    1566  1922909934 :                             temp = W_mac0_16_16( temp, pt6[-m], pt2[-m] ); // 2*qwsp
    1567             :                         }
    1568    35673374 :                         cnt = W_norm( temp );
    1569    35673374 :                         *pt_cor1 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
    1570    35673374 :                         *pt_cor1_exp = sub( new_q, cnt );
    1571    35673374 :                         move16();
    1572    35673374 :                         move16();
    1573             : 
    1574   585733786 :                         FOR( ; m < sublen1[j]; m++ )
    1575             :                         {
    1576   550060412 :                             temp = W_mac0_16_16( temp, pt6[-m], pt2[-m] ); // 2*qwsp
    1577             :                         }
    1578    35673374 :                         cnt = W_norm( temp );
    1579    35673374 :                         *pt_cor3 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
    1580    35673374 :                         *pt_cor3_exp = sub( new_q, cnt );
    1581    35673374 :                         move16();
    1582    35673374 :                         move16();
    1583             : 
    1584    35673374 :                         pt_cor1++;
    1585    35673374 :                         pt_cor1_exp++;
    1586    35673374 :                         pt_cor3++;
    1587    35673374 :                         pt_cor3_exp++;
    1588    35673374 :                         pt2--;
    1589             :                     }
    1590             :                 }
    1591             :                 ELSE
    1592             :                 {
    1593    83595948 :                     FOR( ; k > 0; k-- )
    1594             :                     {
    1595    78869322 :                         temp = W_mult0_16_16( pt6[0], pt2[0] ); // 2*qwsp
    1596  7274472200 :                         FOR( m = 1; m < sublen1[j]; m++ )
    1597             :                         {
    1598  7195602878 :                             temp = W_mac0_16_16( temp, pt6[-m], pt2[-m] ); // 2*qwsp
    1599             :                         }
    1600    78869322 :                         cnt = W_norm( temp );
    1601    78869322 :                         *pt_cor3 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
    1602    78869322 :                         *pt_cor3_exp = sub( new_q, cnt );
    1603    78869322 :                         move16();
    1604    78869322 :                         move16();
    1605             : 
    1606   847572994 :                         FOR( ; m < sublen[j]; m++ )
    1607             :                         {
    1608   768703672 :                             temp = W_mac0_16_16( temp, pt6[-m], pt2[-m] ); // 2*qwsp
    1609             :                         }
    1610    78869322 :                         cnt = W_norm( temp );
    1611    78869322 :                         *pt_cor1 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
    1612    78869322 :                         *pt_cor1_exp = sub( new_q, cnt );
    1613    78869322 :                         move16();
    1614    78869322 :                         move16();
    1615             : 
    1616    78869322 :                         pt_cor1++;
    1617    78869322 :                         pt_cor1_exp++;
    1618    78869322 :                         pt_cor3++;
    1619    78869322 :                         pt_cor3_exp++;
    1620    78869322 :                         pt2--;
    1621             :                     }
    1622             :                 }
    1623             :             }
    1624             :         } /* 3rd half-frame (look-ahead) */
    1625             : 
    1626             :         /* Scale all values in each section to the same exponent for upcoming Find_max() */
    1627     3452262 :         Copy( pt_cor0, cor_buf, len_x );         /* Save unscaled correlation vector  */
    1628     3452262 :         Copy( pt_cor0_exp, cor_buf_exp, len_x ); /* Save unscaled correlation vector  */
    1629     3452262 :         Copy( pt_cor0 + ( DELTA_COH - 1 ) + len_x, cor_buf + len_x, len_x1 );
    1630     3452262 :         Copy( pt_cor0_exp + ( DELTA_COH - 1 ) + len_x, cor_buf_exp + len_x, len_x1 );
    1631             : 
    1632             :         /*-----------------------------------------------------------------*
    1633             :          * Scale correlation function in the neighbourhood of
    1634             :          * the extrapolated pitch
    1635             :          *-----------------------------------------------------------------*/
    1636     3452262 :         pt_cor1 = pt_cor2 - ( DELTA_COH - 1 );
    1637     3452262 :         pt_cor1_exp = pt_cor2_exp - ( DELTA_COH - 1 );
    1638     3452262 :         pt_cor3 = pt_cor4 - ( DELTA_COH - 1 );
    1639     3452262 :         pt_cor3_exp = pt_cor4_exp - ( DELTA_COH - 1 );
    1640     3452262 :         pt2 = scale1;
    1641             : 
    1642    96663336 :         FOR( k = 0; k < 2 * DELTA_COH - 1; k++ )
    1643             :         {
    1644    93211074 :             *pt_cor1 = mult( *pt_cor1, *pt2 );     // *pt_cor1_exp+1
    1645    93211074 :             *pt_cor1_exp = add( *pt_cor1_exp, 1 ); // *pt_cor1_exp+1
    1646    93211074 :             move16();
    1647    93211074 :             move16();
    1648             : 
    1649    93211074 :             *pt_cor3 = mult( *pt_cor3, *pt2++ );   // *pt_cor3_exp+1
    1650    93211074 :             *pt_cor3_exp = add( *pt_cor3_exp, 1 ); // *pt_cor1_exp+1
    1651    93211074 :             move16();
    1652    93211074 :             move16();
    1653             : 
    1654    93211074 :             pt_cor1++;
    1655    93211074 :             pt_cor1_exp++;
    1656    93211074 :             pt_cor3++;
    1657    93211074 :             pt_cor3_exp++;
    1658             :         }
    1659             : 
    1660             :         /* Update for next half-frame & look-ahead */
    1661     3452262 :         pt_cor2 = pt_cor0 - pit_min + old_tmp1;
    1662     3452262 :         pt_cor2_exp = pt_cor0_exp - pit_min + old_tmp1;
    1663             : 
    1664     3452262 :         pt_cor4 = pt_cor0 - pit_min1 + old_tmp1 + ( DELTA_COH - 1 ) + len_x;
    1665     3452262 :         pt_cor4_exp = pt_cor0_exp - pit_min1 + old_tmp1 + ( DELTA_COH - 1 ) + len_x;
    1666             : 
    1667             :         /*-----------------------------------------------------------------*
    1668             :          * For each section, find maximum correlation and compute
    1669             :          * normalized correlation
    1670             :          *-----------------------------------------------------------------*/
    1671             : 
    1672     3452262 :         pt_cor1 = pt_cor0;
    1673     3452262 :         pt_cor1_exp = pt_cor0_exp;
    1674     3452262 :         offset = 0;
    1675     3452262 :         move16();
    1676     3452262 :         pt_cor3 = pt_cor0 + ( DELTA_COH - 1 ) + len_x;
    1677     3452262 :         pt_cor3_exp = pt_cor0_exp + ( DELTA_COH - 1 ) + len_x;
    1678     3452262 :         offset1 = 0;
    1679     3452262 :         move16();
    1680             : 
    1681    15720594 :         FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */
    1682             :         {
    1683             :             /* 1st set */
    1684    12268332 :             offset_la = 0;
    1685    12268332 :             move16();
    1686    12268332 :             if ( EQ_16( i, 2 ) )
    1687             :             {
    1688     4089444 :                 offset_la = sub( L_LOOK_12k8 / OPL_DECIM, len[j] );
    1689             :             }
    1690             : 
    1691             :             /* 2nd set */
    1692    12268332 :             offset_la1 = 0;
    1693    12268332 :             move16();
    1694    12268332 :             if ( EQ_16( i, 2 ) )
    1695             :             {
    1696     4089444 :                 offset_la1 = sub( L_LOOK_12k8 / OPL_DECIM, len1[j] );
    1697             :             }
    1698             : 
    1699             :             /* 1st set of candidates */
    1700    12268332 :             ind = add( maximum_exp_fx( pt_cor1, pt_cor1_exp, sec_length[j] ), offset );
    1701    12268332 :             pitchX[i][j] = add( ind, pit_min );
    1702    12268332 :             move16();
    1703    12268332 :             pt2 = pt1 - pitchX[i][j] + /*-*/ offset_la; /* selected moving vector  */
    1704             : 
    1705    12268332 :             enr1_exp = 0;
    1706    12268332 :             move16();
    1707             : 
    1708             :             /* enr1 = dotp( pt2, pt2, len[j] ) + 0.01f; */
    1709    12268332 :             temp = 0;
    1710    12268332 :             move64();
    1711   837871026 :             FOR( m = 0; m < len[j]; m++ )
    1712             :             {
    1713   825602694 :                 temp = W_mac0_16_16( temp, pt2[m], pt2[m] ); // 2*qwsp
    1714             :             }
    1715             : 
    1716    12268332 :             temp = W_shl( temp, sub( Q24, shl( qwsp, 1 ) ) ); // Q24
    1717             : 
    1718    12268332 :             temp = W_add( temp, 167772 ); /*0.01f in Q24*/
    1719             : 
    1720    12268332 :             enr1_exp = W_norm( temp );
    1721    12268332 :             enr1 = W_extract_h( W_shl( temp, enr1_exp ) ); // enr1_exp+24-32
    1722    12268332 :             enr1_exp = sub( 39, enr1_exp );                // 31-(enr1_exp+24-32)
    1723             : 
    1724    12268332 :             enr1 = Mpy_32_32( enr0[j], enr1 );
    1725    12268332 :             enr1_exp = add( enr0_exp[j], enr1_exp );
    1726             : 
    1727    12268332 :             enr1 = ISqrt32( enr1, &enr1_exp ); /* 1/sqrt(energy) */ /*31-enr2_exp*/
    1728             : 
    1729    12268332 :             Ltmp = Mpy_32_16_1( enr1, cor_buf[ind] );
    1730             : #ifdef ISSUE_1867_replace_overflow_libenc
    1731    12268332 :             corX[i][j] = extract_h( L_shl_sat( Ltmp, add( enr1_exp, cor_buf_exp[ind] ) ) ); // Q15
    1732             : #else
    1733             : 
    1734             :             corX[i][j] = extract_h( L_shl_o( Ltmp, add( enr1_exp, cor_buf_exp[ind] ), &Overflow ) );                  // Q15
    1735             : #endif
    1736    12268332 :             move16();
    1737             : 
    1738    12268332 :             Ltmp = Mpy_32_16_1( enr1, pt_cor0[ind] );
    1739    12268332 :             scaledX[i][j] = round_fx( L_shl( Ltmp, sub( add( enr1_exp, pt_cor0_exp[ind] ), 3 ) ) ); // Q12
    1740    12268332 :             move16();
    1741             : 
    1742    12268332 :             pt_cor1 += sec_length[j];
    1743    12268332 :             pt_cor1_exp += sec_length[j];
    1744    12268332 :             offset = add( offset, sec_length[j] );
    1745             : 
    1746             :             /* 2nd set of candidates */
    1747    12268332 :             ind1 = add( maximum_exp_fx( pt_cor3, pt_cor3_exp, sec_length1[j] ), offset1 );
    1748    12268332 :             pitchX[i][j + NSECT] = add( ind1, pit_min1 );
    1749    12268332 :             move16();
    1750    12268332 :             pt4 = pt1 - pitchX[i][j + NSECT] + /*-*/ offset_la1;
    1751    12268332 :             move16(); /* selected moving vector  */
    1752    12268332 :             enr1_exp = 0;
    1753    12268332 :             move16();
    1754             : 
    1755             :             /* enr1 = dotp(pt4, pt4, len1[j]) + 0.01f; */
    1756    12268332 :             temp = 0;
    1757    12268332 :             move64();
    1758    12268332 :             move64();
    1759   934534362 :             FOR( m = 0; m < len1[j]; m++ )
    1760             :             {
    1761   922266030 :                 temp = W_mac0_16_16( temp, pt4[m], pt4[m] ); // 2*qwsp
    1762             :             }
    1763             : 
    1764    12268332 :             temp = W_shl( temp, sub( Q24, shl( qwsp, 1 ) ) ); // Q24
    1765             : 
    1766    12268332 :             temp = W_add( temp, 167772 ); /*0.01f in Q24*/
    1767             : 
    1768    12268332 :             enr1_exp = W_norm( temp );
    1769    12268332 :             enr1 = W_extract_h( W_shl( temp, enr1_exp ) ); // enr1_exp+24-32
    1770    12268332 :             enr1_exp = sub( 39, enr1_exp );                // 31-(enr1_exp+24-32)
    1771             : 
    1772    12268332 :             enr1 = Mpy_32_32( enr0_1[j], enr1 );
    1773    12268332 :             enr1_exp = add( enr0_1_exp[j], enr1_exp );
    1774             : 
    1775    12268332 :             enr1 = ISqrt32( enr1, &enr1_exp ); /* 1/sqrt(energy) */ /*31-enr1_exp*/
    1776             : 
    1777    12268332 :             Ltmp = Mpy_32_16_1( enr1, cor_buf[ind1 + len_x] );
    1778             : #ifdef ISSUE_1867_replace_overflow_libenc
    1779    12268332 :             corX[i][j + NSECT] = extract_h( L_shl_sat( Ltmp, add( enr1_exp, cor_buf_exp[ind1 + len_x] ) ) ); // Q15
    1780             : #else
    1781             :             corX[i][j + NSECT] = extract_h( L_shl_o( Ltmp, add( enr1_exp, cor_buf_exp[ind1 + len_x] ), &Overflow ) ); // Q15
    1782             : #endif
    1783    12268332 :             move16();
    1784             : 
    1785    12268332 :             Ltmp = Mpy_32_16_1( enr1, pt_cor0[ind1 + ( DELTA_COH - 1 ) + len_x] );
    1786    12268332 :             scaledX[i][j + NSECT] = round_fx( L_shl( Ltmp, sub( add( enr1_exp, pt_cor0_exp[ind1 + ( DELTA_COH - 1 ) + len_x] ), 3 ) ) ); // Q12
    1787    12268332 :             move16();
    1788             :             /*scaledX[i][j+NSECT] = saturate(L_shr(Ltmp, qScaledX-12));*/
    1789             : 
    1790    12268332 :             pt_cor3 += sec_length1[j];
    1791    12268332 :             pt_cor3_exp += sec_length1[j];
    1792    12268332 :             offset1 = add( offset1, sec_length1[j] );
    1793             : 
    1794             :         } /* FOR j < NSECT */
    1795             :     }     /* FOR i < NHFR */
    1796             : 
    1797             :     /*-----------------------------------------------------------------*
    1798             :      * Favor a smaller delay if it happens that it has its multiple
    1799             :      * in the longer-delay sections  (harmonics check)
    1800             :      *-----------------------------------------------------------------*/
    1801             : 
    1802     3452262 :     FOR( i = 0; i < 2; i++ ) /* loop for the 2 half-frames */
    1803             :     {
    1804     2301508 :         fac = THRES0;
    1805     2301508 :         move16();
    1806     2301508 :         find_mult_fx( &fac, pitchX[i][2], pitchX[i][3], pit_max[7], &scaledX[i][2], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 3rd section */
    1807     2301508 :         find_mult_fx( &fac, pitchX[i][1], pitchX[i][2], pit_max[5], &scaledX[i][1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
    1808     2301508 :         test();
    1809     2301508 :         IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][0], 1 ), pit_min_coding ) )
    1810             :         {
    1811     1274364 :             find_mult_fx( &fac, pitchX[i][0], pitchX[i][1], pit_max[3], &scaledX[i][0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
    1812             :         }
    1813     2301508 :         fac = THRES0;
    1814     2301508 :         move16();
    1815     2301508 :         find_mult_fx( &fac, pitchX[i][NSECT + 2], pitchX[i][NSECT + 3], pit_max[7], &scaledX[i][NSECT + 2], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 3rd section */
    1816     2301508 :         find_mult_fx( &fac, pitchX[i][NSECT + 1], pitchX[i][NSECT + 2], pit_max[6], &scaledX[i][NSECT + 1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
    1817     2301508 :         test();
    1818     2301508 :         IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][NSECT + 0], 1 ), pit_min_coding ) )
    1819             :         {
    1820     1274364 :             find_mult_fx( &fac, pitchX[i][NSECT + 0], pitchX[i][NSECT + 1], pit_max[4], &scaledX[i][NSECT + 0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
    1821             :         }
    1822             :     }
    1823             : 
    1824     1150754 :     fac = THRES0;
    1825     1150754 :     move16();                                                                                                        /* the look-ahead */
    1826     1150754 :     find_mult_fx( &fac, pitchX[i][2], pitchX[i][3], pit_max[7], &scaledX[i][2], old_pitch, old_corr, 2, 2 );         /* Multiples in 3rd section */
    1827     1150754 :     find_mult_fx( &fac, pitchX[i][1], pitchX[i][2], pit_max[5], &scaledX[i][1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
    1828     1150754 :     test();
    1829     1150754 :     IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][0], 1 ), pit_min_coding ) )
    1830             :     {
    1831      637182 :         find_mult_fx( &fac, pitchX[i][0], pitchX[i][1], pit_max[3], &scaledX[i][0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
    1832             :     }
    1833     1150754 :     fac = THRES0;
    1834     1150754 :     move16();
    1835     1150754 :     find_mult_fx( &fac, pitchX[i][NSECT + 2], pitchX[i][NSECT + 3], pit_max[7], &scaledX[i][NSECT + 2], old_pitch, old_corr, 2, 2 );         /* Multiples in 3rd section */
    1836     1150754 :     find_mult_fx( &fac, pitchX[i][NSECT + 1], pitchX[i][NSECT + 2], pit_max[6], &scaledX[i][NSECT + 1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
    1837     1150754 :     test();
    1838     1150754 :     IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][NSECT + 0], 1 ), pit_min_coding ) )
    1839             :     {
    1840      637182 :         find_mult_fx( &fac, pitchX[i][NSECT + 0], pitchX[i][NSECT + 1], pit_max[4], &scaledX[i][NSECT + 0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */ /* Multiples in 2nd section */
    1841             :     }
    1842             : 
    1843             :     /*-----------------------------------------------------------------*
    1844             :      * Do 1st estimate for pitch values
    1845             :      * Adjust the normalized correlation using estimated noise level
    1846             :      * Compute the maximum scaling for the neighbour correlation
    1847             :      * reinforcement
    1848             :      *-----------------------------------------------------------------*/
    1849     1150754 :     add_sect0 = add( NSECT, sect0 );
    1850     1150754 :     sub_sect0 = sub( NSECT, sect0 );
    1851     4603016 :     FOR( i = 0; i < NHFR; i++ )
    1852             :     {
    1853             :         /* 1st set of pitch candidates */
    1854     3452262 :         ind = add( maximum_fx( scaledX[i] + sect0, sub_sect0, &ftmp ), sect0 );
    1855     3452262 :         ind_tmp[i] = ind;
    1856     3452262 :         move16();
    1857     3452262 :         pitch_tmp[i] = pitchX[i][ind];
    1858     3452262 :         move16();
    1859             : #ifdef ISSUE_1867_replace_overflow_libenc
    1860     3452262 :         cor_tmp[i] = add_sat( corX[i][ind], corr_shift );
    1861             : #else
    1862             :         cor_tmp[i] = add_o( corX[i][ind], corr_shift, &Overflow );
    1863             : #endif
    1864     3452262 :         move16();
    1865             : 
    1866             :         /* Higher is the neighbour's correlation, higher is the weighting */
    1867             :         /* operands are Q15, result is Q15 */
    1868     3452262 :         thres1[i] = mult( THRES1, cor_tmp[i] );
    1869     3452262 :         move16();
    1870             : 
    1871             :         /* 2nd set of pitch candidates */
    1872     3452262 :         ind1 = add( maximum_fx( scaledX[i] + add_sect0, sub_sect0, &ftmp ), add_sect0 );
    1873     3452262 :         ind_tmp[i + NHFR] = ind1;
    1874     3452262 :         move16();
    1875     3452262 :         pitch_tmp[i + NHFR] = pitchX[i][ind1];
    1876     3452262 :         move16();
    1877             : #ifdef ISSUE_1867_replace_overflow_libenc
    1878     3452262 :         cor_tmp[i + NHFR] = add_sat( corX[i][ind1], corr_shift );
    1879             : #else
    1880             :         cor_tmp[i + NHFR] = add_o( corX[i][ind1], corr_shift, &Overflow );
    1881             : #endif
    1882     3452262 :         move16();
    1883             : 
    1884             :         /* Higher is the neighbour's correlation, higher is the weighting */
    1885             :         /* operands are Q15, result is Q15 */
    1886     3452262 :         thres1[i + NHFR] = mult( THRES1, cor_tmp[i + NHFR] );
    1887     3452262 :         move16();
    1888             :     }
    1889             :     /*-----------------------------------------------------------------*
    1890             :      * Take into account previous and next pitch values of the present
    1891             :      * frame and look-ahead. Choose the pitch lags and normalize
    1892             :      * correlations for each half-frame & look-ahead
    1893             :      *-----------------------------------------------------------------*/
    1894             : 
    1895     1150754 :     pitch_neighbour_fx( sect0, pitch_tmp, pitchX, cor_tmp, scaledX, thres1, ind_tmp );
    1896     4603016 :     FOR( i = 0; i < NHFR; i++ )
    1897             :     {
    1898     3452262 :         ind = add( maximum_fx( scaledX[i] + sect0, sub_sect0, &ftmp ), sect0 );
    1899     3452262 :         ind_corX = add( maximum_fx( corX[i] + sect0, sub_sect0, &ftmp ), sect0 );
    1900             : 
    1901     3452262 :         ind1 = add( maximum_fx( scaledX[i] + add_sect0, sub_sect0, &ftmp ), add_sect0 );
    1902     3452262 :         ind1_corX = add( maximum_fx( corX[i] + add_sect0, sub_sect0, &ftmp ), add_sect0 );
    1903             : 
    1904     3452262 :         if ( GT_16( scaledX[i][ind1], scaledX[i][ind] ) )
    1905             :         {
    1906     1380056 :             ind = ind1;
    1907     1380056 :             move16();
    1908             :         }
    1909     3452262 :         test();
    1910     3452262 :         if ( Opt_SC_VBR && GT_16( corX[i][ind1_corX], corX[i][ind_corX] ) )
    1911             :         {
    1912           0 :             ind_corX = ind1_corX;
    1913           0 :             move16();
    1914             :         }
    1915     3452262 :         test();
    1916     3452262 :         test();
    1917     3452262 :         test();
    1918     3452262 :         IF( Opt_SC_VBR && ( LT_16( mult( pitchX[i][ind], 13107 /*0.4 in Q15*/ ), pitchX[i][ind_corX] ) ) &&
    1919             :             ( GT_16( mult( pitchX[i][ind], 19661 /*0.6 in Q15*/ ), pitchX[i][ind_corX] ) ) &&
    1920             :             ( GE_16( corX[i][ind_corX], 29491 /*0.9 in Q15*/ ) ) )
    1921             :         {
    1922           0 :             pitch[i] = pitchX[i][ind_corX];
    1923           0 :             move16();
    1924           0 :             voicing[i] = corX[i][ind_corX];
    1925           0 :             move16();
    1926             :         }
    1927             :         ELSE
    1928             :         {
    1929     3452262 :             pitch[i] = pitchX[i][ind];
    1930     3452262 :             move16();
    1931     3452262 :             voicing[i] = corX[i][ind];
    1932     3452262 :             move16();
    1933             :         }
    1934             :     }
    1935             : 
    1936             :     /*-----------------------------------------------------------------*
    1937             :      * Increase the threshold for correlation reinforcement with
    1938             :      * the past if correlation high and pitch stable
    1939             :      *-----------------------------------------------------------------*/
    1940             : 
    1941             :     /* all Q15 here */
    1942             :     /* cor_mean = 0.5f * (voicing[0] + voicing[1]) + corr_shift; */
    1943     1150754 :     Ltmp = L_mult( voicing[0], 16384 /*.5 Q15*/ );
    1944     1150754 :     Ltmp = L_mac( Ltmp, voicing[1], 16384 /*.5 Q15*/ );
    1945     1150754 :     cor_mean = round_fx( L_add( Ltmp, corr_shift ) );
    1946             : 
    1947             :     /* pitch unstable in present frame or from previous frame or normalized correlation too low */
    1948     1150754 :     coh_flag = pitch_coherence_fx( pitch[0], pitch[1], COH_FAC, DELTA_COH );
    1949     1150754 :     move16();
    1950     1150754 :     coh_flag1 = pitch_coherence_fx( pitch[0], *old_pitch, COH_FAC, DELTA_COH );
    1951     1150754 :     move16();
    1952             : 
    1953     1150754 :     test();
    1954     1150754 :     test();
    1955     1150754 :     test();
    1956     1150754 :     IF( ( coh_flag == 0 ) || ( coh_flag1 == 0 ) || ( LT_16( cor_mean, CORR_TH0 ) ) || ( LT_16( relE, THR_relE ) ) )
    1957             :     {
    1958             :         /* Reset the threshold */
    1959      632984 :         *old_thres = 0;
    1960      632984 :         move16();
    1961             :     }
    1962             :     ELSE
    1963             :     {
    1964             :         /* The threshold increase is directly dependent on normalized correlation */
    1965             :         /* *old_thres += (0.16f * cor_mean); */
    1966      517770 :         *old_thres = round_fx( L_mac0( L_deposit_h( *old_thres ), 5243 /* 0.16f in Q15 */, cor_mean ) ); // Q14
    1967      517770 :         move16();
    1968             :     }
    1969             : 
    1970     1150754 :     *old_thres = s_min( *old_thres, 11469 /* 0.7f in Q14 */ ); // Q14
    1971     1150754 :     move16();
    1972             : 
    1973     1150754 :     IF( GT_16( voicing[1], voicing[0] ) )
    1974             :     {
    1975      552809 :         *old_corr = voicing[1];
    1976      552809 :         move16();
    1977             :     }
    1978             :     ELSE
    1979             :     {
    1980      597945 :         *old_corr = cor_mean;
    1981      597945 :         move16();
    1982             :     }
    1983             : 
    1984             :     /*-----------------------------------------------------------------*
    1985             :      * Extrapolate the pitch value for the next frame by estimating
    1986             :      * the pitch evolution. This value is added to the old_pitch
    1987             :      * in the next frame and is then used when the normalized
    1988             :      * correlation is reinforced by the past estimate
    1989             :      *-----------------------------------------------------------------*/
    1990     1150754 :     tmp_buf[0] = *old_pitch;
    1991     1150754 :     move16();
    1992     4603016 :     FOR( i = 0; i < NHFR; i++ )
    1993             :     {
    1994     3452262 :         tmp_buf[i + 1] = pitch[i];
    1995     3452262 :         move16();
    1996             :     }
    1997             : 
    1998     1150754 :     *delta_pit = 0;
    1999     1150754 :     move16();
    2000     1150754 :     cnt = 0;
    2001     1150754 :     move16();
    2002             : 
    2003     4603016 :     FOR( i = 0; i < NHFR; i++ )
    2004             :     {
    2005     3452262 :         diff = sub( tmp_buf[i + 1], tmp_buf[i] );
    2006     3452262 :         move16();
    2007     3452262 :         coh_flag = pitch_coherence_fx( tmp_buf[i], tmp_buf[i + 1], COH_FAC, DELTA_COH );
    2008             : 
    2009     3452262 :         if ( coh_flag != 0 )
    2010             :         {
    2011     2523586 :             *delta_pit = add( *delta_pit, diff );
    2012     2523586 :             move16();
    2013             :         }
    2014     3452262 :         cnt = add( cnt, coh_flag );
    2015             :     }
    2016     1150754 :     if ( EQ_16( cnt, 2 ) )
    2017             :     {
    2018             :         /* *delta_pit /= 2; */
    2019      268276 :         *delta_pit = shr( *delta_pit, 1 );
    2020      268276 :         move16();
    2021             :     }
    2022     1150754 :     IF( EQ_16( cnt, 3 ) )
    2023             :     {
    2024      600408 :         k = *delta_pit;
    2025      600408 :         move16();
    2026             :         /* *delta_pit /= 3; */
    2027      600408 :         if ( k < 0 )
    2028             :         {
    2029      139175 :             *delta_pit = mult( *delta_pit, -32768 /*-1 Q15*/ );
    2030      139175 :             move16();
    2031             :         }
    2032      600408 :         tmp16 = mult( *delta_pit, 10923 /*1/3 Q15*/ );
    2033      600408 :         if ( k < 0 )
    2034             :         {
    2035      139175 :             tmp16 = mult( tmp16, -32768 /*-1 Q15*/ );
    2036             :         }
    2037      600408 :         *delta_pit = tmp16;
    2038      600408 :         move16();
    2039             :     }
    2040             : 
    2041             :     /*--------------------------------------------------------------*
    2042             :      * Update old pitch, upsample pitch,
    2043             :      *--------------------------------------------------------------*/
    2044             : 
    2045     1150754 :     *old_pitch = pitch[1];
    2046     1150754 :     move16();
    2047             : 
    2048     4603016 :     FOR( i = 0; i < NHFR; i++ )
    2049             :     {
    2050             :         /* compensate decimation */
    2051     3452262 :         pitch[i] = i_mult2( pitch[i], OPL_DECIM );
    2052     3452262 :         move16();
    2053             :     }
    2054             : 
    2055     1150754 :     return;
    2056             : }
    2057             : 
    2058             : 
    2059             : /*-----------------------------------------------------------------*
    2060             :  * find_mult_fx
    2061             :  *
    2062             :  * Verifies whether max pitch delays in higher sections have multiples
    2063             :  * in lower sections
    2064             :  *-----------------------------------------------------------------*/
    2065    17680104 : static void find_mult_fx(
    2066             :     Word16 *fac,       /* i/o: correlation scaling factor Q12              */
    2067             :     Word16 pitch0,     /* i  : pitch of max correlation in the c section   */
    2068             :     Word16 pitch1,     /* i  : pitch of max correlation in the longer-delay section*/
    2069             :     Word16 pit_max0,   /* i  : max pitch delay in the longer-delay section */
    2070             :     Word16 *corr,      /* i/o: max correlation in the shorter-delay section Q12    */
    2071             :     Word16 *old_pitch, /* i  : pitch from previous frame                   */
    2072             :     Word16 *old_corr,  /* i  : max correlation from previous frame         */
    2073             :     Word16 delta,      /* i  : initial multiples search range              */
    2074             :     Word16 step        /* i  : increment in range of multiples search      */
    2075             : )
    2076             : {
    2077             :     Word16 pit_min;
    2078             :     Word32 L_tmp;
    2079             : 
    2080    17680104 :     pit_min = shl( pitch0, 1 ); /* double the higher section pitch */
    2081             : 
    2082    38780401 :     WHILE( LE_16( pit_min, add( pit_max0, delta ) ) ) /* check for section boundary */
    2083             :     {
    2084    21100297 :         IF( LE_16( abs_s( sub( pit_min, pitch1 ) ), delta ) ) /* if multiple in the allowed range */
    2085             :         {
    2086     6342259 :             L_tmp = L_shl( L_mult( *corr, *fac ), 3 );
    2087             : 
    2088             :             /* if ( *old_corr < 0.6f || (float)pitch0 > (float)*old_pitch * 0.4f ) */
    2089     6342259 :             IF( s_max( sub( 19660 /*.6 Q15*/, *old_corr ), sub( pitch0, mult( *old_pitch, 13107 /*.4 Q15*/ ) ) ) > 0 )
    2090             :             {
    2091             :                 /* reinforce the normalized correlation */
    2092             :                 /* operands are Q12, result is Q12 */
    2093     5854454 :                 *corr = extract_h( L_tmp );
    2094             :             }
    2095             :             /* operands are Q12, result is Q12 */
    2096     6342259 :             *fac = extract_h( L_shl( L_mult( *fac, THRES0 ), 3 ) );
    2097             :         }
    2098    21100297 :         pit_min = add( pit_min, pitch0 ); /* next multiple */
    2099    21100297 :         delta = add( delta, step );       /* the incertitude to the allowed range */
    2100             :     }
    2101    17680104 : }
    2102             : 
    2103             : /*---------------------------------------------------------------------------*
    2104             :  * pitch_neighbour_fx
    2105             :  *
    2106             :  * Verifies if the maximum correlation pitch lag is coherent with neighbour
    2107             :  * values
    2108             :  *---------------------------------------------------------------------------*/
    2109     1153854 : static void pitch_neighbour_fx(
    2110             :     Word16 sect0,               /* i  : indicates whether section 0 (below PIT_MIN) is used       */
    2111             :     Word16 pitch_tmp[],         /* i  : estimated pitch values for each half-frame & look-ahead   */
    2112             :     Word16 pitch[3][2 * NSECT], /* i  : tested pitch values for each half-frame & look-ahead      */
    2113             :     Word16 corr_tmp[],          /* i  : raw normalized correlation (before different scalings) Q15*/
    2114             :     Word16 corr[3][2 * NSECT],  /* i/o: normalized correlation for each half-frame & look-ahead Q12 */
    2115             :     Word16 thres1[2 * NHFR],    /* i  : maximum scaling for the immediate neighbours Q15          */
    2116             :     Word16 ind_tmp[2 * NHFR]    /* i  : best section index for each half-frame & look-ahead       */
    2117             : )
    2118             : {
    2119             :     Word16 delta, i, j, k, K, coh_flag, fac;
    2120             : 
    2121             :     /*---------------------
    2122             :      * 1st set of sections
    2123             :      ---------------------*/
    2124     5254392 :     FOR( k = sect0; k < NSECT; k++ ) /* loop for each section */
    2125             :     {
    2126     4100538 :         K = 3;
    2127     4100538 :         move16();
    2128     4100538 :         if ( EQ_16( k, ( NSECT - 1 ) ) ) /* the number of tests depends on the section */
    2129             :         {
    2130     1153854 :             K = 2;
    2131     1153854 :             move16();
    2132             :         }
    2133             :         /*pt = &pitch[i][k] and pt = &corr[i][k]*/
    2134    15248298 :         FOR( i = 0; i < K; i++ ) /* for the 2 half-frames and look-ahead */
    2135             :         {
    2136             :             /* Compare pitch values of the present frame */
    2137    42283332 :             FOR( j = 0; j < K; j++ ) /* Verify pitch coherence with neighbours (including past pitch) */
    2138             :             {
    2139    31135572 :                 IF( NE_16( j, i ) ) /* Exclude itself, of course */
    2140             :                 {
    2141    19987812 :                     IF( GE_16( corr_tmp[j], CORR_TH1 ) ) /* reinforcement can happen only if the correlation is high enough */
    2142             :                     {
    2143    15078095 :                         delta = abs_s( sub( pitch[i][k], pitch_tmp[j] ) ); /* Find difference of pitch values */
    2144    15078095 :                         coh_flag = pitch_coherence_fx( pitch[i][k], pitch_tmp[j], COH_FAC, DELTA_COH );
    2145             : 
    2146    15078095 :                         IF( coh_flag != 0 )
    2147             :                         {
    2148             :                             /* Favour stability across sections, favour closer values */
    2149     5433433 :                             IF( EQ_16( ind_tmp[j], k ) )
    2150             :                             {
    2151             :                                 /* corr[i][k] *= ( -thres1[j]/DELTA1 * delta + thres1[j]+1 ); */
    2152             :                                 /* operands are Q15, except corr[i][k] which is Q12 */
    2153     4110052 :                                 fac = mult( negate( thres1[j] ), MAX_16 / DELTA_COH );
    2154     4110052 :                                 fac = add( i_mult2( fac, delta ), thres1[j] );
    2155             :                             }
    2156             :                             ELSE
    2157             :                             {
    2158             :                                 /* corr[i][k] *= ( -thres1[j]/DELTA1 * 0.625f * delta + 0.625f * thres1[j] +1.0f ); */
    2159     1323381 :                                 fac = mult( negate( thres1[j] ), 20479 / DELTA_COH );
    2160     1323381 :                                 fac = add( i_mult2( fac, delta ), mult( 20479 /*.625 Q15*/, thres1[j] ) );
    2161             :                             }
    2162     5433433 :                             corr[i][k] = add_sat( corr[i][k], mult( fac, corr[i][k] ) );
    2163     5433433 :                             move16();
    2164             :                         }
    2165             :                     }
    2166             :                 }
    2167             :             }
    2168             :         }
    2169             :     }
    2170             : 
    2171             :     /*---------------------
    2172             :      * 2nd set of sections
    2173             :      ---------------------*/
    2174     5254392 :     FOR( k = sect0; k < NSECT; k++ ) /* loop for each section */
    2175             :     {
    2176     4100538 :         K = 3;
    2177     4100538 :         move16();
    2178     4100538 :         if ( EQ_16( k, ( NSECT - 1 ) ) ) /* the number of tests depends on the section */
    2179             :         {
    2180     1153854 :             K = 2;
    2181     1153854 :             move16();
    2182             :         }
    2183             :         /*pt = &pitch[i][k] and pt = &corr[i][k]*/
    2184    15248298 :         FOR( i = 0; i < K; i++ ) /* BRANCH(1); for the 2 half-frames and look-ahead */
    2185             :         {
    2186             :             /* Compare pitch values of the present frame */
    2187    42283332 :             FOR( j = 0; j < K; j++ ) /* Verify pitch coherence with neighbours (including past pitch) */
    2188             :             {
    2189    31135572 :                 IF( NE_16( j, i ) ) /* Exclude itself, of course */
    2190             :                 {
    2191    19987812 :                     IF( GE_16( corr_tmp[j + NHFR], CORR_TH1 ) ) /* reinforcement can happen only if the correlation is high enough */
    2192             :                     {
    2193    14752928 :                         delta = abs_s( sub( pitch[i][NSECT + k], pitch_tmp[j + NHFR] ) ); /* Find difference of pitch values */
    2194    14752928 :                         coh_flag = pitch_coherence_fx( pitch[i][NSECT + k], pitch_tmp[j + NHFR], COH_FAC, DELTA_COH );
    2195             : 
    2196    14752928 :                         IF( coh_flag != 0 )
    2197             :                         {
    2198             :                             /* Favour stability across sections, favour closer values */
    2199     5552681 :                             IF( EQ_16( ind_tmp[j + NHFR], add( NSECT, k ) ) )
    2200             :                             {
    2201             :                                 /* corr[i][k] *= ( -thres1[j+NHFR]/DELTA1 * delta + thres1[j+NHFR]+1 ); */
    2202             :                                 /* operands are Q15, except corr[i][NSECT+k] which is Q12 */
    2203     4212061 :                                 fac = mult( negate( thres1[j + NHFR] ), MAX_16 / DELTA_COH );
    2204     4212061 :                                 fac = add( extract_l( L_shr( L_mult( fac, delta ), 1 ) ), thres1[j + NHFR] );
    2205     4212061 :                                 corr[i][NSECT + k] = add_sat( corr[i][NSECT + k], mult( fac, corr[i][NSECT + k] ) );
    2206     4212061 :                                 move16();
    2207             :                             }
    2208             :                             ELSE
    2209             :                             {
    2210             :                                 /* corr[i][k] *= ( -thres1[j+NHFR]/DELTA1 * 0.625f * delta + 0.625f * thres1[j+NHFR] +1.0f ); */
    2211     1340620 :                                 fac = mult( negate( thres1[j + NHFR] ), 20479 / DELTA_COH );
    2212     1340620 :                                 fac = add( extract_l( L_shr( L_mult( fac, delta ), 1 ) ), mult( 20479, thres1[j + NHFR] ) );
    2213     1340620 :                                 corr[i][NSECT + k] = add( corr[i][NSECT + k], mult( fac, corr[i][NSECT + k] ) );
    2214     1340620 :                                 move16();
    2215             :                             }
    2216             :                         }
    2217             :                     }
    2218             :                 }
    2219             :             }
    2220             :         }
    2221             :     }
    2222     1153854 : }
    2223             : 
    2224             : /*-----------------------------------------------------------------*
    2225             :  * pitch_coherence_fx
    2226             :  *
    2227             :  * Verify if pitch evolution is smooth
    2228             :  *-----------------------------------------------------------------*/
    2229    35600293 : static Word16 pitch_coherence_fx(
    2230             :     Word16 pitch0,  /* i  : first pitch to compare        */
    2231             :     Word16 pitch1,  /* i  : 2nd pitch to compare          */
    2232             :     Word16 fac_max, /* i  : max ratio of both values Q12  */
    2233             :     Word16 diff_max /* i  : max difference of both values */
    2234             : )
    2235             : {
    2236             :     Word16 smaller, larger;
    2237             :     Word16 pc;
    2238             : 
    2239    35600293 :     smaller = s_min( pitch0, pitch1 );
    2240    35600293 :     larger = s_max( pitch0, pitch1 );
    2241             : 
    2242    35600293 :     pc = 0;
    2243    35600293 :     move16();
    2244    35600293 :     test();
    2245    51372819 :     if ( ( LE_16( larger, extract_h( L_shl( L_mult( fac_max, smaller ), 3 ) ) ) ) && /* Changed to <= to keep BE */
    2246    15772526 :          ( LT_16( sub( larger, smaller ), diff_max ) ) )
    2247             :     {
    2248    15143629 :         pc = 1;
    2249    15143629 :         move16();
    2250             :     }
    2251             : 
    2252    35600293 :     return pc;
    2253             : }
    2254             : 
    2255             : /*-----------------------------------------------------------------*
    2256             :  * LP_Decim2_Copy:
    2257             :  *
    2258             :  * Decimate a vector by 2 with 2nd order fir filter.
    2259             :  *-----------------------------------------------------------------*/
    2260     2307708 : static void LP_Decim2_Copy(
    2261             :     const Word16 x[], /* i:   signal to process */
    2262             :     Word16 y[],       /* o:   signal to process */
    2263             :     Word16 l,         /* i  : size of filtering */
    2264             :     Word16 mem[]      /* i/o: memory (size=3)   */
    2265             : )
    2266             : {
    2267             :     Word16 *p_x, x_buf[L_FRAME + L_MEM];
    2268             :     Word16 i, j, k;
    2269             :     Word32 L_tmp;
    2270             : 
    2271             :     /* copy initial filter states into buffer */
    2272     2307708 :     p_x = x_buf;
    2273     9230832 :     FOR( i = 0; i < L_MEM; i++ )
    2274             :     {
    2275     6923124 :         *p_x++ = mem[i];
    2276     6923124 :         move16();
    2277             :     }
    2278   426925980 :     FOR( i = 0; i < l; i++ )
    2279             :     {
    2280   424618272 :         *p_x++ = x[i];
    2281   424618272 :         move16();
    2282             :     }
    2283     2307708 :     if ( s_and( l, 1 ) ) /* Fix for valgrind error in case l is odd. Anyway this function will be removed. */
    2284             :     {
    2285           0 :         *p_x = *( p_x - 1 );
    2286           0 :         move16();
    2287             :     }
    2288             : 
    2289     9230832 :     FOR( i = 0; i < L_MEM; i++ )
    2290             :     {
    2291     6923124 :         mem[i] = x[l - L_MEM + i];
    2292     6923124 :         move16();
    2293             :     }
    2294     2307708 :     p_x = x_buf;
    2295     2307708 :     j = 0;
    2296     2307708 :     move16();
    2297   214616844 :     FOR( i = 0; i < l; i += 2 )
    2298             :     {
    2299   212309136 :         L_tmp = L_mult( *p_x, h_fir_fx[0] );
    2300  1061545680 :         FOR( k = 1; k < L_FIR_PO; k++ )
    2301             :         {
    2302   849236544 :             L_tmp = L_mac( L_tmp, p_x[k], h_fir_fx[k] );
    2303             :         }
    2304   212309136 :         p_x += 2;
    2305             : 
    2306   212309136 :         y[j++] = round_fx( L_tmp );
    2307   212309136 :         move16();
    2308             :     }
    2309     2307708 : }
    2310             : /*---------------------------------------------------------------------*
    2311             :  * Dot_product12_OL
    2312             :  *
    2313             :  * two different length dot products of x and y
    2314             :  *---------------------------------------------------------------------*/
    2315      618680 : static Word32 Dot_product12_OL(                   /* o  : Q31: normalized result (1 < val <= -1) */
    2316             :                                 Word16 *sum1,     /* o  : Q31: normalized result 2 */
    2317             :                                 const Word16 x[], /* i  : 12bits: x vector */
    2318             :                                 const Word16 y[], /* i  : 12bits: y vector */
    2319             :                                 const Word16 lg,  /* i  : vector length */
    2320             :                                 const Word16 lg2, /* i  : vector length 2 */
    2321             :                                 Word16 *exp,      /* o  : exponent of result (0..+30) */
    2322             :                                 Word16 *exp2      /* o  : exponent of result 2 (0..+30) */
    2323             : )
    2324             : {
    2325             :     Word16 i, sft;
    2326             :     Word32 L_sum, L_sum2;
    2327             : 
    2328      618680 :     L_sum = L_mac( 1, x[0], y[0] );
    2329      618680 :     IF( LE_16( lg, lg2 ) )
    2330             :     {
    2331    39081600 :         FOR( i = 1; i < lg; i++ )
    2332             :         {
    2333    38617920 :             L_sum = L_mac( L_sum, x[i], y[i] );
    2334             :         }
    2335             :         /* sets to 'L_sum' in 1 clock */
    2336      463680 :         L_sum2 = L_sum;
    2337      463680 :         move32();
    2338     3427280 :         FOR( ; i < lg2; i++ )
    2339             :         {
    2340     2963600 :             L_sum2 = L_mac( L_sum2, x[i], y[i] );
    2341             :         }
    2342             :     }
    2343             :     ELSE
    2344             :     {
    2345    10726000 :         FOR( i = 1; i < lg2; i++ )
    2346             :         {
    2347    10571000 :             L_sum = L_mac( L_sum, x[i], y[i] );
    2348             :         }
    2349             :         /* sets to 'L_sum' in 1 clock */
    2350      155000 :         L_sum2 = L_sum;
    2351      155000 :         move32();
    2352     4296600 :         FOR( ; i < lg; i++ )
    2353             :         {
    2354     4141600 :             L_sum = L_mac( L_sum, x[i], y[i] );
    2355             :         }
    2356             :     }
    2357             : 
    2358             :     /* Q31 */
    2359      618680 :     sft = norm_l( L_sum );
    2360      618680 :     L_sum = L_shl( L_sum, sft );
    2361      618680 :     *exp = sub( 30, sft );
    2362      618680 :     move16(); /* exponent = 0..30 */
    2363             : 
    2364      618680 :     sft = norm_l( L_sum2 );
    2365      618680 :     L_sum2 = L_shl( L_sum2, sft );
    2366      618680 :     *exp2 = sub( 30, sft );
    2367      618680 :     move16(); /* exponent = 0..30 */
    2368             : 
    2369      618680 :     *sum1 = extract_h( L_shr( L_sum2, 1 ) );
    2370      618680 :     move16();
    2371      618680 :     return L_sum;
    2372             : }
    2373             : 
    2374             : /*---------------------------------------------------------------------*
    2375             :  * Dot_product12_OL_back()
    2376             :  *
    2377             :  * two different length dot products of x and y, computed backward
    2378             :  *---------------------------------------------------------------------*/
    2379      309340 : static Word32 Dot_product12_OL_back(                   /* o  : Q31: normalized result (1 < val <= -1) */
    2380             :                                      Word16 *sum1,     /* o  : Q31: normalized result 2 */
    2381             :                                      const Word16 x[], /* i  : 12bits: x vector */
    2382             :                                      const Word16 y[], /* i  : 12bits: y vector */
    2383             :                                      const Word16 lg,  /* i  : vector length */
    2384             :                                      const Word16 lg2, /* i  : vector length 2 */
    2385             :                                      Word16 *exp,      /* o  : exponent of result (0..+30) */
    2386             :                                      Word16 *exp2      /* o  : exponent of result 2 (0..+30) */
    2387             : )
    2388             : {
    2389             :     Word16 i, sft;
    2390             :     Word32 L_sum, L_sum2;
    2391             : 
    2392      309340 :     L_sum = L_mac( 1, x[0], y[0] );
    2393      309340 :     IF( LE_16( lg, lg2 ) )
    2394             :     {
    2395    19540800 :         FOR( i = 1; i < lg; i++ )
    2396             :         {
    2397    19308960 :             L_sum = L_mac( L_sum, x[-i], y[-i] );
    2398             :         }
    2399             :         /* sets to 'L_sum' in 1 clock */
    2400      231840 :         L_sum2 = L_sum;
    2401      231840 :         move32();
    2402     1713640 :         FOR( ; i < lg2; i++ )
    2403             :         {
    2404     1481800 :             L_sum2 = L_mac( L_sum2, x[-i], y[-i] );
    2405             :         }
    2406             :     }
    2407             :     ELSE
    2408             :     {
    2409     5363000 :         FOR( i = 1; i < lg2; i++ )
    2410             :         {
    2411     5285500 :             L_sum = L_mac( L_sum, x[-i], y[-i] );
    2412             :         }
    2413             :         /* sets to 'L_sum' in 1 clock */
    2414       77500 :         L_sum2 = L_sum;
    2415       77500 :         move32();
    2416     2148300 :         FOR( ; i < lg; i++ )
    2417             :         {
    2418     2070800 :             L_sum = L_mac( L_sum, x[-i], y[-i] );
    2419             :         }
    2420             :     }
    2421             : 
    2422             :     /* Q31 */
    2423      309340 :     sft = norm_l( L_sum );
    2424      309340 :     L_sum = L_shl( L_sum, sft );
    2425      309340 :     *exp = sub( 30, sft );
    2426      309340 :     move16(); /* exponent = 0..30 */
    2427             : 
    2428      309340 :     sft = norm_l( L_sum2 );
    2429      309340 :     L_sum2 = L_shl( L_sum2, sft );
    2430      309340 :     *exp2 = sub( 30, sft );
    2431      309340 :     move16(); /* exponent = 0..30 */
    2432             : 
    2433      309340 :     *sum1 = extract_h( L_shr( L_sum2, 1 ) );
    2434      309340 :     move16();
    2435      309340 :     return L_sum;
    2436             : }
    2437             : 
    2438           0 : void pitchDoubling_det_fx(
    2439             :     Word16 *wspeech,
    2440             :     Word16 *pitch_ol,
    2441             :     Word16 *T_op_fr,
    2442             :     Word16 *voicing_fr )
    2443             : {
    2444             :     Word16 new_op_fr[2];
    2445             :     Word16 new_voicing[2];
    2446             :     Word16 new_Top[2];
    2447             :     Word16 m, T;
    2448             : 
    2449             : 
    2450             :     /*save initial values*/
    2451             : 
    2452           0 :     new_Top[0] = pitch_ol[0];
    2453           0 :     move16();
    2454           0 :     new_Top[1] = pitch_ol[1];
    2455           0 :     move16();
    2456             : 
    2457           0 :     FOR( m = 2; m < 5; m++ )
    2458             :     {
    2459             : 
    2460             :         /* T= pitch_ol[0]/m; */
    2461           0 :         T = mult( pitch_ol[0], One_div_fx[m - 1] );
    2462             : 
    2463           0 :         IF( GE_16( T, PIT_MIN_12k8 ) )
    2464             :         {
    2465           0 :             pitch_ol2_fx( PIT_MIN_SHORTER, T, &( new_op_fr[0] ), &new_voicing[0], 0, wspeech, 2, EVS_MONO );
    2466           0 :             pitch_ol2_fx( PIT_MIN_SHORTER, T, &( new_op_fr[1] ), &new_voicing[1], L_SUBFR, wspeech, 2, EVS_MONO );
    2467             :             /* IF(sub(add(new_voicing[0],new_voicing[1]),add(voicing_fr[0],voicing_fr[1]))>0 */
    2468           0 :             IF( L_msu( L_msu( L_mac( L_mult( new_voicing[0], 8192 ), new_voicing[1], 8192 ), voicing_fr[0], 8192 ), voicing_fr[1], 8192 ) > 0 )
    2469             :             {
    2470           0 :                 new_Top[0] = T;
    2471           0 :                 move16();
    2472           0 :                 T_op_fr[0] = new_op_fr[0];
    2473           0 :                 move16();
    2474           0 :                 T_op_fr[1] = new_op_fr[1];
    2475           0 :                 move16();
    2476           0 :                 voicing_fr[0] = new_voicing[0];
    2477           0 :                 move16();
    2478           0 :                 voicing_fr[1] = new_voicing[1];
    2479           0 :                 move16();
    2480             :             }
    2481             :         }
    2482             : 
    2483             :         /* T= pitch_ol[1]/m; */
    2484           0 :         T = mult( pitch_ol[1], One_div_fx[m - 1] );
    2485             : 
    2486           0 :         IF( GE_16( T, PIT_MIN_12k8 ) )
    2487             :         {
    2488           0 :             pitch_ol2_fx( PIT_MIN_SHORTER, T, &( new_op_fr[0] ), &new_voicing[0], 2 * L_SUBFR, wspeech, 2, EVS_MONO );
    2489           0 :             pitch_ol2_fx( PIT_MIN_SHORTER, T, &( new_op_fr[1] ), &new_voicing[1], 3 * L_SUBFR, wspeech, 2, EVS_MONO );
    2490             :             /* IF(sub(add(new_voicing[0],new_voicing[1]),add(voicing_fr[2],voicing_fr[3]))>0) */
    2491           0 :             IF( L_msu( L_msu( L_mac( L_mult( new_voicing[0], 8192 ), new_voicing[1], 8192 ), voicing_fr[2], 8192 ), voicing_fr[3], 8192 ) > 0 )
    2492             :             {
    2493           0 :                 new_Top[1] = T;
    2494           0 :                 move16();
    2495           0 :                 T_op_fr[2] = new_op_fr[0];
    2496           0 :                 move16();
    2497           0 :                 T_op_fr[3] = new_op_fr[1];
    2498           0 :                 move16();
    2499           0 :                 voicing_fr[2] = new_voicing[0];
    2500           0 :                 move16();
    2501           0 :                 voicing_fr[3] = new_voicing[1];
    2502           0 :                 move16();
    2503             :             }
    2504             :         }
    2505             :     }
    2506             : 
    2507           0 :     pitch_ol[0] = new_Top[0];
    2508           0 :     move16();
    2509           0 :     pitch_ol[1] = new_Top[1];
    2510           0 :     move16();
    2511             : 
    2512           0 : } /*end of pitch doubling detection*/

Generated by: LCOV version 1.14